From 3bebf172a0bb8a92b04894407ddaa437850b8d3b Mon Sep 17 00:00:00 2001 From: Cem Kocagil Date: Tue, 3 Dec 2013 22:15:39 +0200 Subject: [PATCH 1/2] Hitbox helper tool --- tools/HitboxExpander/.gitignore | 3 + tools/HitboxExpander/hitbox_expander.py | 107 + .../third_party/Imaging-1.1.7/BUILDME | 11 + .../third_party/Imaging-1.1.7/CHANGES | 1767 +++++++++ .../third_party/Imaging-1.1.7/CONTENTS | 299 ++ .../third_party/Imaging-1.1.7/Docs/effbot.css | 118 + .../third_party/Imaging-1.1.7/Docs/index.html | 103 + .../Imaging-1.1.7/Images/courB08.bdf | 2676 ++++++++++++++ .../Imaging-1.1.7/Images/courB08.pbm | Bin 0 -> 1273 bytes .../Imaging-1.1.7/Images/courB08.pil | Bin 0 -> 5143 bytes .../third_party/Imaging-1.1.7/Images/lena.gif | Bin 0 -> 16336 bytes .../third_party/Imaging-1.1.7/Images/lena.jpg | Bin 0 -> 4788 bytes .../third_party/Imaging-1.1.7/Images/lena.png | Bin 0 -> 37723 bytes .../third_party/Imaging-1.1.7/Images/lena.ppm | 4 + .../third_party/Imaging-1.1.7/MANIFEST | 279 ++ .../third_party/Imaging-1.1.7/PIL.pth | 1 + .../Imaging-1.1.7/PIL/ArgImagePlugin.py | 504 +++ .../Imaging-1.1.7/PIL/BdfFontFile.py | 133 + .../Imaging-1.1.7/PIL/BmpImagePlugin.py | 251 ++ .../Imaging-1.1.7/PIL/BufrStubImagePlugin.py | 68 + .../Imaging-1.1.7/PIL/ContainerIO.py | 116 + .../Imaging-1.1.7/PIL/CurImagePlugin.py | 88 + .../Imaging-1.1.7/PIL/DcxImagePlugin.py | 78 + .../Imaging-1.1.7/PIL/EpsImagePlugin.py | 349 ++ .../third_party/Imaging-1.1.7/PIL/ExifTags.py | 157 + .../Imaging-1.1.7/PIL/FitsStubImagePlugin.py | 73 + .../Imaging-1.1.7/PIL/FliImagePlugin.py | 142 + .../third_party/Imaging-1.1.7/PIL/FontFile.py | 146 + .../Imaging-1.1.7/PIL/FpxImagePlugin.py | 224 ++ .../Imaging-1.1.7/PIL/GbrImagePlugin.py | 70 + .../Imaging-1.1.7/PIL/GdImageFile.py | 85 + .../Imaging-1.1.7/PIL/GifImagePlugin.py | 407 ++ .../Imaging-1.1.7/PIL/GimpGradientFile.py | 124 + .../Imaging-1.1.7/PIL/GimpPaletteFile.py | 61 + .../Imaging-1.1.7/PIL/GribStubImagePlugin.py | 68 + .../Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py | 70 + .../Imaging-1.1.7/PIL/IcnsImagePlugin.py | 211 ++ .../Imaging-1.1.7/PIL/IcoImagePlugin.py | 86 + .../Imaging-1.1.7/PIL/ImImagePlugin.py | 336 ++ .../third_party/Imaging-1.1.7/PIL/Image.py | 2127 +++++++++++ .../Imaging-1.1.7/PIL/ImageChops.py | 302 ++ .../third_party/Imaging-1.1.7/PIL/ImageCms.py | 786 ++++ .../Imaging-1.1.7/PIL/ImageColor.py | 263 ++ .../Imaging-1.1.7/PIL/ImageDraw.py | 378 ++ .../Imaging-1.1.7/PIL/ImageDraw2.py | 105 + .../Imaging-1.1.7/PIL/ImageEnhance.py | 90 + .../Imaging-1.1.7/PIL/ImageFile.py | 528 +++ .../Imaging-1.1.7/PIL/ImageFileIO.py | 39 + .../Imaging-1.1.7/PIL/ImageFilter.py | 289 ++ .../Imaging-1.1.7/PIL/ImageFont.py | 390 ++ .../third_party/Imaging-1.1.7/PIL/ImageGL.py | 28 + .../Imaging-1.1.7/PIL/ImageGrab.py | 71 + .../Imaging-1.1.7/PIL/ImageMath.py | 207 ++ .../Imaging-1.1.7/PIL/ImageMode.py | 50 + .../third_party/Imaging-1.1.7/PIL/ImageOps.py | 439 +++ .../Imaging-1.1.7/PIL/ImagePalette.py | 184 + .../Imaging-1.1.7/PIL/ImagePath.py | 71 + .../third_party/Imaging-1.1.7/PIL/ImageQt.py | 84 + .../Imaging-1.1.7/PIL/ImageSequence.py | 38 + .../Imaging-1.1.7/PIL/ImageShow.py | 163 + .../Imaging-1.1.7/PIL/ImageStat.py | 164 + .../third_party/Imaging-1.1.7/PIL/ImageTk.py | 296 ++ .../Imaging-1.1.7/PIL/ImageTransform.py | 95 + .../third_party/Imaging-1.1.7/PIL/ImageWin.py | 215 ++ .../Imaging-1.1.7/PIL/ImtImagePlugin.py | 93 + .../Imaging-1.1.7/PIL/IptcImagePlugin.py | 288 ++ .../Imaging-1.1.7/PIL/JpegImagePlugin.py | 492 +++ .../Imaging-1.1.7/PIL/McIdasImagePlugin.py | 70 + .../Imaging-1.1.7/PIL/MicImagePlugin.py | 95 + .../Imaging-1.1.7/PIL/MpegImagePlugin.py | 82 + .../Imaging-1.1.7/PIL/MspImagePlugin.py | 103 + .../Imaging-1.1.7/PIL/OleFileIO.py | 528 +++ .../third_party/Imaging-1.1.7/PIL/PSDraw.py | 199 + .../Imaging-1.1.7/PIL/PaletteFile.py | 55 + .../Imaging-1.1.7/PIL/PalmImagePlugin.py | 225 ++ .../Imaging-1.1.7/PIL/PcdImagePlugin.py | 76 + .../Imaging-1.1.7/PIL/PcfFontFile.py | 256 ++ .../Imaging-1.1.7/PIL/PcxImagePlugin.py | 167 + .../Imaging-1.1.7/PIL/PdfImagePlugin.py | 211 ++ .../Imaging-1.1.7/PIL/PixarImagePlugin.py | 71 + .../Imaging-1.1.7/PIL/PngImagePlugin.py | 620 ++++ .../Imaging-1.1.7/PIL/PpmImagePlugin.py | 131 + .../Imaging-1.1.7/PIL/PsdImagePlugin.py | 291 ++ .../Imaging-1.1.7/PIL/SgiImagePlugin.py | 92 + .../Imaging-1.1.7/PIL/SpiderImagePlugin.py | 294 ++ .../Imaging-1.1.7/PIL/SunImagePlugin.py | 86 + .../third_party/Imaging-1.1.7/PIL/TarIO.py | 57 + .../Imaging-1.1.7/PIL/TgaImagePlugin.py | 201 + .../Imaging-1.1.7/PIL/TiffImagePlugin.py | 860 +++++ .../third_party/Imaging-1.1.7/PIL/TiffTags.py | 209 ++ .../Imaging-1.1.7/PIL/WalImageFile.py | 126 + .../Imaging-1.1.7/PIL/WmfImagePlugin.py | 167 + .../Imaging-1.1.7/PIL/XVThumbImagePlugin.py | 73 + .../Imaging-1.1.7/PIL/XbmImagePlugin.py | 94 + .../Imaging-1.1.7/PIL/XpmImagePlugin.py | 129 + .../third_party/Imaging-1.1.7/PIL/__init__.py | 12 + .../Imaging-1.1.7/PIL/_imaging.pyd | Bin 0 -> 193536 bytes .../Imaging-1.1.7/PIL/_imagingmath.pyd | Bin 0 -> 14848 bytes .../third_party/Imaging-1.1.7/README | 300 ++ .../third_party/Imaging-1.1.7/Sane/CHANGES | 34 + .../third_party/Imaging-1.1.7/Sane/README | 22 + .../third_party/Imaging-1.1.7/Sane/_sane.c | 1325 +++++++ .../Imaging-1.1.7/Sane/demo_numarray.py | 39 + .../Imaging-1.1.7/Sane/demo_pil.py | 33 + .../third_party/Imaging-1.1.7/Sane/sane.py | 289 ++ .../Imaging-1.1.7/Sane/sanedoc.txt | 294 ++ .../third_party/Imaging-1.1.7/Sane/setup.py | 24 + .../third_party/Imaging-1.1.7/Scripts/README | 83 + .../Imaging-1.1.7/Scripts/enhancer.py | 53 + .../Imaging-1.1.7/Scripts/explode.py | 107 + .../Imaging-1.1.7/Scripts/gifmaker.py | 135 + .../Imaging-1.1.7/Scripts/painter.py | 72 + .../Imaging-1.1.7/Scripts/pilconvert.py | 96 + .../Imaging-1.1.7/Scripts/pildriver.py | 524 +++ .../Imaging-1.1.7/Scripts/pilfile.py | 94 + .../Imaging-1.1.7/Scripts/pilfont.py | 54 + .../Imaging-1.1.7/Scripts/pilprint.py | 93 + .../Imaging-1.1.7/Scripts/player.py | 121 + .../Imaging-1.1.7/Scripts/thresholder.py | 68 + .../Imaging-1.1.7/Scripts/viewer.py | 46 + .../third_party/Imaging-1.1.7/Tk/booster.txt | 108 + .../third_party/Imaging-1.1.7/Tk/install.txt | 41 + .../Imaging-1.1.7/Tk/pilbitmap.txt | 149 + .../third_party/Imaging-1.1.7/Tk/tkImaging.c | 265 ++ .../third_party/Imaging-1.1.7/_imaging.c | 3281 +++++++++++++++++ .../third_party/Imaging-1.1.7/_imagingcms.c | 608 +++ .../third_party/Imaging-1.1.7/_imagingft.c | 502 +++ .../third_party/Imaging-1.1.7/_imagingmath.c | 284 ++ .../third_party/Imaging-1.1.7/_imagingtk.c | 70 + .../build/temp.win32-2.7/Release/_imaging.exp | Bin 0 -> 670 bytes .../build/temp.win32-2.7/Release/_imaging.lib | Bin 0 -> 1736 bytes .../temp.win32-2.7/Release/_imagingmath.exp | Bin 0 -> 690 bytes .../temp.win32-2.7/Release/_imagingmath.lib | Bin 0 -> 1882 bytes .../third_party/Imaging-1.1.7/decode.c | 689 ++++ .../third_party/Imaging-1.1.7/display.c | 836 +++++ .../third_party/Imaging-1.1.7/doctest.py | 1111 ++++++ .../third_party/Imaging-1.1.7/encode.c | 540 +++ .../Imaging-1.1.7/libImaging/Access.c | 255 ++ .../Imaging-1.1.7/libImaging/Antialias.c | 307 ++ .../Imaging-1.1.7/libImaging/Bands.c | 129 + .../Imaging-1.1.7/libImaging/Bit.h | 30 + .../Imaging-1.1.7/libImaging/BitDecode.c | 138 + .../Imaging-1.1.7/libImaging/Blend.c | 79 + .../Imaging-1.1.7/libImaging/Chops.c | 148 + .../Imaging-1.1.7/libImaging/Convert.c | 1132 ++++++ .../Imaging-1.1.7/libImaging/ConvertYCbCr.c | 387 ++ .../Imaging-1.1.7/libImaging/Copy.c | 58 + .../Imaging-1.1.7/libImaging/Crc32.c | 87 + .../Imaging-1.1.7/libImaging/Crop.c | 61 + .../Imaging-1.1.7/libImaging/Dib.c | 311 ++ .../Imaging-1.1.7/libImaging/Draw.c | 1167 ++++++ .../Imaging-1.1.7/libImaging/Effects.c | 373 ++ .../Imaging-1.1.7/libImaging/EpsEncode.c | 80 + .../Imaging-1.1.7/libImaging/Except.c | 83 + .../Imaging-1.1.7/libImaging/File.c | 193 + .../Imaging-1.1.7/libImaging/Fill.c | 101 + .../Imaging-1.1.7/libImaging/Filter.c | 179 + .../Imaging-1.1.7/libImaging/FliDecode.c | 205 + .../Imaging-1.1.7/libImaging/Geometry.c | 959 +++++ .../Imaging-1.1.7/libImaging/GetBBox.c | 316 ++ .../Imaging-1.1.7/libImaging/Gif.h | 109 + .../Imaging-1.1.7/libImaging/GifDecode.c | 297 ++ .../Imaging-1.1.7/libImaging/GifEncode.c | 319 ++ .../Imaging-1.1.7/libImaging/HexDecode.c | 67 + .../Imaging-1.1.7/libImaging/Histo.c | 169 + .../Imaging-1.1.7/libImaging/ImDib.h | 64 + .../Imaging-1.1.7/libImaging/ImPlatform.h | 72 + .../Imaging-1.1.7/libImaging/Imaging.h | 497 +++ .../Imaging-1.1.7/libImaging/Jpeg.h | 104 + .../Imaging-1.1.7/libImaging/JpegDecode.c | 267 ++ .../Imaging-1.1.7/libImaging/JpegEncode.c | 284 ++ .../Imaging-1.1.7/libImaging/Lzw.h | 52 + .../Imaging-1.1.7/libImaging/LzwDecode.c | 230 ++ .../Imaging-1.1.7/libImaging/Matrix.c | 74 + .../Imaging-1.1.7/libImaging/ModeFilter.c | 78 + .../Imaging-1.1.7/libImaging/MspDecode.c | 91 + .../Imaging-1.1.7/libImaging/Negative.c | 42 + .../Imaging-1.1.7/libImaging/Offset.c | 61 + .../Imaging-1.1.7/libImaging/Pack.c | 566 +++ .../Imaging-1.1.7/libImaging/PackDecode.c | 92 + .../Imaging-1.1.7/libImaging/Palette.c | 316 ++ .../Imaging-1.1.7/libImaging/Paste.c | 555 +++ .../Imaging-1.1.7/libImaging/PcdDecode.c | 78 + .../Imaging-1.1.7/libImaging/PcxDecode.c | 75 + .../Imaging-1.1.7/libImaging/PcxEncode.c | 148 + .../Imaging-1.1.7/libImaging/Point.c | 263 ++ .../Imaging-1.1.7/libImaging/Quant.c | 1610 ++++++++ .../Imaging-1.1.7/libImaging/Quant.h | 40 + .../Imaging-1.1.7/libImaging/QuantDefines.h | 25 + .../Imaging-1.1.7/libImaging/QuantHash.c | 477 +++ .../Imaging-1.1.7/libImaging/QuantHash.h | 36 + .../Imaging-1.1.7/libImaging/QuantHeap.c | 150 + .../Imaging-1.1.7/libImaging/QuantHeap.h | 23 + .../Imaging-1.1.7/libImaging/QuantTypes.h | 28 + .../Imaging-1.1.7/libImaging/RankFilter.c | 105 + .../Imaging-1.1.7/libImaging/Raw.h | 15 + .../Imaging-1.1.7/libImaging/RawDecode.c | 89 + .../Imaging-1.1.7/libImaging/RawEncode.c | 89 + .../Imaging-1.1.7/libImaging/Storage.c | 413 +++ .../Imaging-1.1.7/libImaging/SunRleDecode.c | 112 + .../Imaging-1.1.7/libImaging/TgaRleDecode.c | 118 + .../Imaging-1.1.7/libImaging/Unpack.c | 1028 ++++++ .../Imaging-1.1.7/libImaging/UnpackYCC.c | 162 + .../Imaging-1.1.7/libImaging/UnsharpMask.c | 398 ++ .../Imaging-1.1.7/libImaging/XbmDecode.c | 81 + .../Imaging-1.1.7/libImaging/XbmEncode.c | 106 + .../Imaging-1.1.7/libImaging/Zip.h | 57 + .../Imaging-1.1.7/libImaging/ZipDecode.c | 271 ++ .../Imaging-1.1.7/libImaging/ZipEncode.c | 341 ++ .../third_party/Imaging-1.1.7/map.c | 379 ++ .../third_party/Imaging-1.1.7/outline.c | 179 + .../third_party/Imaging-1.1.7/path.c | 587 +++ .../third_party/Imaging-1.1.7/selftest.py | 202 + .../third_party/Imaging-1.1.7/setup.py | 487 +++ .../third_party/zlib/DLL_FAQ.txt | 397 ++ .../third_party/zlib/README.txt | 60 + .../HitboxExpander/third_party/zlib/USAGE.txt | 89 + .../third_party/zlib/include/zconf.h | 511 +++ .../third_party/zlib/include/zlib.h | 1768 +++++++++ .../third_party/zlib/lib/zdll.lib | Bin 0 -> 15256 bytes .../third_party/zlib/lib/zlib.def | 86 + .../third_party/zlib/test/example_d.exe | Bin 0 -> 38912 bytes .../third_party/zlib/test/minigzip_d.exe | Bin 0 -> 35840 bytes .../HitboxExpander/third_party/zlib/zlib1.dll | Bin 0 -> 107520 bytes 224 files changed, 57727 insertions(+) create mode 100644 tools/HitboxExpander/.gitignore create mode 100755 tools/HitboxExpander/hitbox_expander.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pbm create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pil create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.gif create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.jpg create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.png create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.ppm create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/MANIFEST create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL.pth create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ArgImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imaging.pyd create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imagingmath.pyd create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/README create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.exp create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.lib create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.exp create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.lib create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/decode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/display.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/LzwDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/map.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/path.c create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py create mode 100755 tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt create mode 100755 tools/HitboxExpander/third_party/zlib/README.txt create mode 100755 tools/HitboxExpander/third_party/zlib/USAGE.txt create mode 100755 tools/HitboxExpander/third_party/zlib/include/zconf.h create mode 100755 tools/HitboxExpander/third_party/zlib/include/zlib.h create mode 100755 tools/HitboxExpander/third_party/zlib/lib/zdll.lib create mode 100755 tools/HitboxExpander/third_party/zlib/lib/zlib.def create mode 100755 tools/HitboxExpander/third_party/zlib/test/example_d.exe create mode 100755 tools/HitboxExpander/third_party/zlib/test/minigzip_d.exe create mode 100755 tools/HitboxExpander/third_party/zlib/zlib1.dll diff --git a/tools/HitboxExpander/.gitignore b/tools/HitboxExpander/.gitignore new file mode 100644 index 00000000000..8e987a0b84b --- /dev/null +++ b/tools/HitboxExpander/.gitignore @@ -0,0 +1,3 @@ +*.obj +pythondoc-PIL.*.html + diff --git a/tools/HitboxExpander/hitbox_expander.py b/tools/HitboxExpander/hitbox_expander.py new file mode 100755 index 00000000000..063e423bf91 --- /dev/null +++ b/tools/HitboxExpander/hitbox_expander.py @@ -0,0 +1,107 @@ +import os +import sys +import inspect +import shutil + +def AddToPath(path): + if path not in sys.path: + sys.path.insert(0, path) + delimeter = ':' if os.name == "posix" else ";" + os.environ['PATH'] = path + delimeter + os.environ['PATH'] + +current_dir = os.path.split(inspect.getfile(inspect.currentframe()))[0] + +AddToPath(os.path.abspath(os.path.join(current_dir, "third_party/Imaging-1.1.7/PIL"))) +AddToPath(os.path.abspath(os.path.join(current_dir, "third_party/zlib"))) + +import Image +import _imaging + +def PngSave(im, file): + # From http://blog.client9.com/2007/08/28/python-pil-and-png-metadata-take-2.html + + # these can be automatically added to Image.info dict + # they are not user-added metadata + reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect') + + # undocumented class + import PngImagePlugin + meta = PngImagePlugin.PngInfo() + + # copy metadata into new object + for k,v in im.info.iteritems(): + if k in reserved: continue + meta.add_text(k, v, 0) + + # and save + im.save(file, "PNG", pnginfo=meta) + +def ProcessFile(path): + name, ext = os.path.splitext(path) + ext = ext.lower() + if (ext != ".dmi" and ext != ".png") or os.path.splitext(name)[1] == ".new": + return + + try: + im = Image.open(path) + print name + ": " + im.format, im.size, im.mode + if im.mode != "RGBA": + return + width, height = im.size + pix = im.load() + + n_transparent = 0 + + make_opaque = [] + + def add(x, y): + if pix[x, y][3] == 0: + make_opaque.append((x, y)) + + for x in range(0, width): + for y in range(0, height): + if pix[x, y][3] > 0: + if x > 0: + add(x - 1, y) + if x < width - 1: + add(x + 1, y) + if y > 0: + add(x, y - 1) + if y < height - 1: + add(x, y + 1) + else: + n_transparent += 1 + + for coords in make_opaque: + pix[coords] = (0, 0, 0, 1) + + PngSave(im, path) + except: + print "Could not process " + name + +root_dir = os.path.abspath(os.path.join(current_dir, "../../")) +icons_dir = os.path.join(root_dir, "icons") + +def Main(): + if len(sys.argv) != 2: + print "Usage: hitbox_expander.py filename.dmi" + return 0 + + try: + with open(sys.argv[1]): + ProcessFile(os.path.abspath(sys.argv[1])) + return 0 + except IOError: + pass + + for root, subdirs, files in os.walk(icons_dir): + for file in files: + if file == sys.argv[1]: + path = os.path.join(root, file) + ProcessFile(path) + return 0 + + print "File not found: " + sys.argv[1] + +if __name__ == "__main__": + Main() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME b/tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME new file mode 100755 index 00000000000..a3c6295376f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME @@ -0,0 +1,11 @@ +# $Id$ +# quick build (for lazy programmers). for more information on the +# build process, see the README file. + +if [ "$1" = "clean" ]; then + python setup.py clean + rm -f *.so PIL/*.so +fi + +python setup.py build_ext -i +python selftest.py diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES b/tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES new file mode 100755 index 00000000000..b516d32bbd8 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES @@ -0,0 +1,1767 @@ +-*- coding: utf-8 -*- + +The Python Imaging Library +$Id$ + +ACKNOWLEDGEMENTS: PIL wouldn't be what it is without the help of: +David Ascher, Phil Austin, Douglas Bagnall, Larry Bates, Anthony +Baxter, William Baxter, Denis Benoit, Jan Blom, Duncan Booth, Alexey +Borzenkov, Jeff Breidenbach, Roger Burnham, Zac Burns, Gene Cash, +Kevin Cazabon, Fred Clare, Greg Coats, Chris Cogdon, Greg Couch, Bill +Crutchfield, Abel Deuring, Tim Docker, Fred Drake, Graham Dumpleton, +Matthew Ellis, Eric Etheridge, Daniel Fetchinson, Robin Friedrich, +Pier Paolo Glave, Federico Di Gregorio, Markus Gritsch, Daniel +Haertle, Greg Hamilton, Mark Hammond, Bernhard Herzog, Rob Hooft, Bob +Ippolito, Jack Jansen, Bill Janssen, Edward Jones, Richard Jones, +Håkan Karlsson, Robert Kern, David Kirtley, Bob Klimek, Matthias +Klose, Andrew Kuchling, Magnus Källström, Victor Lacina, Ben Last, +Hamish Lawson, Cesare Leonardi, Andrew MacIntyre, Jan Matejek, Naveen +Michaud-Agrawal, Gordon McMillan, Skip Montanaro, Fredrik Nehr, +Russell Nelson, Luciano Nocera, Travis Oliphant, Piet van Oostrum, +Richard Oudkerk, Paul Pharr, Andres Polit, Conrado Porto Lopes Gouvêa, +Eric Raymond, Victor Reijs, Bertil Reinhammar, Nicholas Riley, Don +Rozenberg, Toby Sargeant, Barry Scott, Les Schaffer, Joel Shprentz, +Klamer Shutte, Gene Skonicki, Niki Spahiev, D. Alan Stewart, Perry +Stoll, Paul Svensson, Ulrik Svensson, Miki Tebeka, Michael van +Tellingen, Ivan Tkatchev, Dan Torop, Adam Twardoch, Rune Uhlin, Dmitry +Vasiliev, Sasha Voynow, Charles Waldman, Collin Winter, Dan Wolfe, +Ka-Ping Yee, and many others (if your name should be on this list, let +me know.) + +*** Changes from release 1.1.6 to 1.1.7 *** + +This section may not be fully complete. For changes since this file +was last updated, see the repository revision history: + + http://bitbucket.org/effbot/pil-2009-raclette/changesets/ + +(1.1.7 final) + ++ Set GIF loop info property to the number of iterations if a NETSCAPE + loop extension is present, instead of always setting it to 1 (from + Valentino Volonghi). + +(1.1.7c1 released) + ++ Improved PNG compression (from Alexey Borzenkov). + ++ Read interlaced PNG files (from Conrado Porto Lopes Gouvêa) + ++ Added various TGA improvements from Alexey Borzenkov, including + support for specifying image orientation. + ++ Bumped block threshold to 16 megabytes, made size estimation a bit + more accurate. This speeds up allocation of large images. + ++ Fixed rounding error in ImagingDrawWideLine. + + "gormish" writes: ImagingDrawWideLine() in Draw.c has a bug in every + version I've seen, which leads to different width lines depending on + the order of the points in the line. This is especially bad at some + angles where a 'width=2' line can completely disappear. + ++ Added support for RGBA mode to the SGI module (based on code by + Karsten Hiddemann). + ++ Handle repeated IPTC tags (adapted from a patch by Eric Bruning). + + Eric writes: According to the specification, some IPTC tags can be + repeated, e.g., tag 2:25 (keywords). PIL 1.1.6 only retained the last + instance of that tag. Below is a patch to store all tags. If there are + multiple tag instances, they are stored in a (python) list. Single tag + instances remain as strings. + ++ Fixed potential crash in ImageFilter for small target images + (reported by Zac Burns and Daniel Fetchinson). + ++ Use BMP instead of JPEG as temporary show format on Mac OS X. + ++ Fixed putpixel/new for I;16 with colors > 255. + ++ Added integer power support to ImagingMath. + ++ Added limited support for I;16L mode (explicit little endian). + ++ Moved WMF support into Image.core; enable WMF rendering by default + if renderer is available. + ++ Mark the ARG plugin as obsolete. + ++ Added version query mechanism to ImageCms and ImageFont, for + debugging. + ++ Added (experimental) ImageCms function for fetching the ICC profile + for the current display (currently Windows only). + + Added HWND/HDC support to ImageCms.get_display_profile(). + ++ Added WMF renderer (Windows only). + ++ Added ImagePointHandler and ImageTransformHandler mixins; made + ImageCmsTransform work with im.point. + ++ Fixed potential endless loop in the XVThumbnail reader (from Nikolai + Ugelvik). + ++ Added Kevin Cazabon's pyCMS package. + + The C code has been moved to _imagingcms.c, the Python interface + module is installed as PIL.ImageCMS. + + Added support for in-memory ICC profiles. + + Unified buildTransform and buildTransformFromOpenProfiles. + + The profile can now be either a filename, a profile object, or a + file-like object containing an in-memory profile. + + Additional fixes from Florian Böch: + + Very nice - it just needs LCMS flags support so we can use black + point compensation and softproofing :) See attached patches. They + also fix a naming issue which could cause confusion - display + profile (ImageCms wording) actually means proof profile (lcms + wording), so I changed variable names and docstrings where + applicable. Patches are tested under Python 2.6. + ++ Improved support for layer names in PSD files (from Sylvain Baubeau) + + Sylvain writes: I needed to be able to retrieve the names of the + layers in a PSD files. But PsdImagePlugin.py didn't do the job so I + wrote this very small patch. + ++ Improved RGBA support for ImageTk for 8.4 and newer (from Con + Radchenko). + + This replaces the slow run-length based encoding model with true + compositing at the Tk level. + ++ Added support for 16- and 32-bit images to McIdas loader. + + Based on file samples and stand-alone reader code provided by Craig + Swank. + ++ Added ImagePalette support to putpalette. + ++ Fixed problem with incremental parsing of PNG files. + ++ Make selftest.py report non-zero status on failure (from Mark + Sienkiewicz) + ++ Add big endian save support and multipage infrastructure to the TIFF + writer (from Sebastian Haase). + ++ Handle files with GPS IFD but no basic EXIF IFD (reported by Kurt + Schwehr). + ++ Added zTXT support (from Andrew Kuchling via Lowell Alleman). + ++ Fixed potential infinite loop bug in ImageFont (from Guilherme Polo). + ++ Added sample ICC profiles (from Kevin Cazabon) + ++ Fixed array interface for I, F, and RGBA/RGBX images. + ++ Added Chroma subsampling support for JPEG (from Justin Huff). + + Justin writes: Attached is a patch (against PIL 1.1.6) to provide + control over the chroma subsampling done by the JPEG encoder. This + is often useful for reducing compression artifacts around edges of + clipart and text. + ++ Added USM/Gaussian Blur code from Kevin Cazabon. + ++ Fixed bug w. uninitialized image data when cropping outside the + source image. + ++ Use ImageShow to implement the Image.show method. + + Most notably, this picks the 'display' utility when available. It + also allows application code to register new display utilities via + the ImageShow registry. + ++ Release the GIL in the PNG compressor (from Michael van Tellingen). + ++ Revised JPEG CMYK handling. + + Always assume Adobe behaviour, both when reading and writing (based on + a patch by Kevin Cazabon, and test data by Tim V. and Charlie Clark, and + additional debugging by Michael van Tellingen). + ++ Support for preserving ICC profiles (by Florian Böch via Tim Hatch). + + Florian writes: + + It's a beta, so still needs some testing, but should allow you to: + - retain embedded ICC profiles when saving from/to JPEG, PNG, TIFF. + Existing code doesn't need to be changed. + - access embedded profiles in JPEG, PNG, PSD, TIFF. + + It also includes patches for TIFF to retain IPTC, Photoshop and XMP + metadata when saving as TIFF again, read/write TIFF resolution + information correctly, and to correct inverted CMYK JPEG files. + ++ Fixed potential memory leak in median cut quantizer (from Evgeny Salmin). + ++ Fixed OverflowError when reading upside-down BMP images. + ++ Added resolution save option for PDF files. + + Andreas Kostyrka writes: I've included a patched PdfImagePlugin.py + based on 1.1.6 as included in Ubuntu, that supports a "resolution" + save option. Not great, but it makes the PDF saving more useful by + allowing PDFs that are not exactly 72dpi. + ++ Look for Tcl/Tk include files in version-specific include directory + (from Encolpe Degoute). + ++ Fixed grayscale rounding error in ImageColor.getcolor (from Tim + Hatch). + ++ Fixed calculation of mean value in ImageEnhance.Contrast (reported + by "roop" and Scott David Daniels). + ++ Fixed truetype positioning when first character has a negative left + bearing (from Ned Batchelder): + + Ned writes: In PIL 1.1.6, ImageDraw.text will position the string + incorrectly if the first character has a negative left bearing. To + see the problem, show a string like "///" in an italic font. The + first slash will be clipped at the left, and the string will be + mis-positioned. + ++ Fixed resolution unit bug in tiff reader/writer (based on code by + Florian Höch, Gary Bloom, and others). + ++ Added simple transparency support for RGB images (reported by + Sebastian Spaeth). + ++ Added support for Unicode filenames in ImageFont.truetype (from Donn + Ingle). + ++ Fixed potential crash in ImageFont.getname method (from Donn Ingle). + ++ Fixed encoding issue in PIL/WalImageFile (from Santiago M. Mola). + +*** Changes from release 1.1.5 to 1.1.6 *** + +(1.1.6 released) + ++ Fixed some 64-bit compatibility warnings for Python 2.5. + ++ Added threading support for the Sane driver (from Abel Deuring). + +(1.1.6b2 released) + ++ Added experimental "floodfill" function to the ImageDraw module + (based on code by Eric Raymond). + ++ The default arguments for "frombuffer" doesn't match "fromstring" + and the documentation; this is a bug, and will most likely be fixed + in a future version. In this release, PIL prints a warning message + instead. To silence the warning, change any calls of the form + "frombuffer(mode, size, data)" to + + frombuffer(mode, size, data, "raw", mode, 0, 1) + ++ Added "fromarray" function, which takes an object implementing the + NumPy array interface and creates a PIL Image from it. (from Travis + Oliphant). + ++ Added NumPy array interface support (__array_interface__) to the + Image class (based on code by Travis Oliphant). + + This allows you to easily convert between PIL image memories and + NumPy arrays: + + import numpy, Image + + im = Image.open('lena.jpg') + + a = numpy.asarray(im) # a is readonly + + im = Image.fromarray(a) + ++ Fixed CMYK polarity for JPEG images, by treating all images as + "Adobe CMYK" images. (thanks to Cesare Leonardi and Kevin Cazabon + for samples, debugging, and patches). + +(1.1.6b1 released) + ++ Added 'expand' option to the Image 'rotate' method. If true, the + output image is made large enough to hold the entire rotated image. + ++ Changed the ImageDraw 'line' method to always draw the last pixel in + a polyline, independent of line angle. + ++ Fixed bearing calculation and clipping in the ImageFont truetype + renderer; this could lead to clipped text, or crashes in the low- + level _imagingft module. (based on input from Adam Twardoch and + others). + ++ Added ImageQt wrapper module, for converting PIL Image objects to + QImage objects in an efficient way. + ++ Fixed 'getmodebands' to return the number of bands also for "PA" + and "LA" modes. Added 'getmodebandnames' helper that return the + band names. + +(1.1.6a2 released) + ++ Added float/double support to the TIFF loader (from Russell + Nelson). + ++ Fixed broken use of realloc() in path.c (from Jan Matejek) + ++ Added save support for Spider images (from William Baxter). + ++ Fixed broken 'paste' and 'resize' operations in pildriver + (from Bill Janssen). + ++ Added support for duplex scanning to the Sane interface (Abel + Deuring). + +(1.1.6a1 released) + ++ Fixed a memory leak in "convert(mode)", when converting from + L to P. + ++ Added pixel access object. The "load" method now returns a + access object that can be used to directly get and set pixel + values, using ordinary [x, y] notation: + + pixel = im.load() + v = pixel[x, y] + pixel[x, y] = v + + If you're accessing more than a few pixels, this is a lot + faster than using getpixel/putpixel. + ++ Fixed building on Cygwin (from Miki Tebeka). + ++ Fixed "point(callable)" on unloaded images (reported by Håkan + Karlsson). + ++ Fixed size bug in ImageWin.ImageWindow constructor (from Victor + Reijs) + ++ Fixed ImageMath float() and int() operations for Python 2.4 + (reported by Don Rozenberg). + ++ Fixed "RuntimeError: encoder error -8 in tostring" problem for + wide "RGB", "I", and "F" images. + ++ Fixed line width calculation. + +(1.1.6a0 released) + ++ Fixed byte order issue in Image.paste(ink) (from Ka-Ping Yee). + ++ Fixed off-by-0.5 errors in the ANTIALIAS code (based on input + from Douglas Bagnall). + ++ Added buffer interface support to the Path constructor. If + a buffer is provided, it is assumed to contain a flat array + of float coordinates (e.g. array.array('f', seq)). + ++ Added new ImageMath module. + ++ Fixed ImageOps.equalize when used with a small number of distinct + values (reported by David Kirtley). + ++ Fixed potential integer division in PSDraw.image (from Eric Etheridge). + +*** Changes from release 1.1 to 1.1.5 *** + +(1.1.5c2 and 1.1.5 final released) + ++ Added experimental PERSPECTIVE transform method (from Jeff Breiden- + bach). + +(1.1.5c1 released) + ++ Make sure "thumbnail" never generates zero-wide or zero-high images + (reported by Gene Skonicki) + ++ Fixed a "getcolors" bug that could result in a zero count for some + colors (reported by Richard Oudkerk). + ++ Changed default "convert" palette to avoid "rounding errors" when + round-tripping white source pixels (reported by Henryk Gerlach and + Jeff Epler). + +(1.1.5b3 released) + ++ Don't crash in "quantize" method if the number of colors requested + is larger than 256. This release raises a ValueError exception; + future versions may return a mode "RGB" image instead (reported + by Richard Oudkerk). + ++ Added WBMP read/write support (based on code by Duncan Booth). + +(1.1.5b2 released) + ++ Added DPI read/write support to the PNG codec. The decoder sets + the info["dpi"] attribute for PNG files with appropriate resolution + settings. The encoder uses the "dpi" option (based on code by Niki + Spahiev). + ++ Added limited support for "point" mappings from mode "I" to mode "L". + Only 16-bit values are supported (other values are clipped), the lookup + table must contain exactly 65536 entries, and the mode argument must be + set to "L". + ++ Added support for Mac OS X icns files (based on code by Bob Ippolito). + ++ Added "ModeFilter" support to the ImageFilter module. + ++ Added support for Spider images (from William Baxter). See the + comments in PIL/SpiderImagePlugin.py for more information on this + format. + +(1.1.5b1 released) + ++ Added new Sane release (from Ralph Heinkel). See the Sane/README + and Sane/CHANGES files for more information. + ++ Added experimental PngInfo chunk container to the PngImageFile + module. This can be used to add arbitrary chunks to a PNG file. + Create a PngInfo instance, use "add" or "add_text" to add chunks, + and pass the instance as the "pnginfo" option when saving the + file. + ++ Added "getpalette" method. This returns the palette as a list, + or None if the image has no palette. To modify the palette, use + "getpalette" to fetch the current palette, modify the list, and + put it back using "putpalette". + ++ Added optional flattening to the ImagePath "tolist" method. + tolist() or tolist(0) returns a list of 2-tuples, as before. + tolist(1) returns a flattened list instead. + +(1.1.5a5 released) + ++ Fixed BILINEAR/BICUBIC/ANTIALIAS filtering for mode "LA". + ++ Added "getcolors()" method. This is similar to the existing histo- + gram method, but looks at color values instead of individual layers, + and returns an unsorted list of (count, color) tuples. + + By default, the method returns None if finds more than 256 colors. + If you need to look for more colors, you can pass in a limit (this + is used to allocate internal tables, so you probably don't want to + pass in too large values). + ++ Build improvements: Fixed building under AIX, improved detection of + FreeType2 and Mac OS X framework libraries, and more. Many thanks + to everyone who helped test the new "setup.py" script! + +(1.1.5a4 released) + ++ The "save" method now looks for a file format driver before + creating the file. + ++ Don't use antialiased truetype fonts when drawing in mode "P", "I", + and "F" images. + ++ Rewrote the "setup.py" file. The new version scans for available + support libraries, and configures both the libImaging core library + and the bindings in one step. + + To use specific versions of the libraries, edit the ROOT variables + in the setup.py file. + ++ Removed threaded "show" viewer; use the old "show" implementation + instead (Windows). + ++ Added deprecation warnings to Image.offset, ImageDraw.setink, and + ImageDraw.setfill. + ++ Added width option to ImageDraw.line(). The current implementation + works best for straight lines; it does not support line joins, so + polylines won't look good. + ++ ImageDraw.Draw is now a factory function instead of a class. If + you need to create custom draw classes, inherit from the ImageDraw + class. All other code should use the factory function. + ++ Fixed loading of certain PCX files (problem reported by Greg + Hamilton, who also provided samples). + ++ Changed _imagingft.c to require FreeType 2.1 or newer. The + module can still be built with earlier versions; see comments + in _imagingft.c for details. + +(1.1.5a3 released) + ++ Added 'getim' method, which returns a PyCObject wrapping an + Imaging pointer. The description string is set to IMAGING_MAGIC. + See Imaging.h for pointer and string declarations. + ++ Fixed reading of TIFF JPEG images (problem reported by Ulrik + Svensson). + ++ Made ImageColor work under Python 1.5.2 + ++ Fixed division by zero "equalize" on very small images (from + Douglas Bagnall). + +(1.1.5a2 released) + ++ The "paste" method now supports the alternative "paste(im, mask)" + syntax (in this case, the box defaults to im's bounding box). + ++ The "ImageFile.Parser" class now works also for PNG files with + more than one IDAT block. + ++ Added DPI read/write to the TIFF codec, and fixed writing of + rational values. The decoder sets the info["dpi"] attribute + for TIFF files with appropriate resolution settings. The + encoder uses the "dpi" option. + ++ Disable interlacing for small (or narrow) GIF images, to + work around what appears to be a hard-to-find bug in PIL's + GIF encoder. + ++ Fixed writing of mode "P" PDF images. Made mode "1" PDF + images smaller. + ++ Made the XBM reader a bit more robust; the file may now start + with a few whitespace characters. + ++ Added support for enhanced metafiles to the WMF driver. The + separate PILWMF kit lets you render both placeable WMF files + and EMF files as raster images. See + + http://effbot.org/downloads#pilwmf + +(1.1.5a1 released) + ++ Replaced broken WMF driver with a WMF stub plugin (see below). + ++ Fixed writing of mode "1", "L", and "CMYK" PDF images (based on + input from Nicholas Riley and others). + ++ Fixed adaptive palette conversion for zero-width or zero-height + images (from Chris Cogdon) + ++ Fixed reading of PNG images from QuickTime 6 (from Paul Pharr) + ++ Added support for StubImageFile plugins, including stub plugins + for BUFR, FITS, GRIB, and HDF5 files. A stub plugin can identify + a given file format, but relies on application code to open and + save files in that format. + ++ Added optional "encoding" argument to the ImageFont.truetype + factory. This argument can be used to specify non-Unicode character + maps for fonts that support that. For example, to draw text using + the Microsoft Symbol font, use: + + font = ImageFont.truetype("symbol.ttf", 16, encoding="symb") + draw.text((0, 0), unichr(0xF000 + 0xAA)) + + (note that the symbol font uses characters in the 0xF000-0xF0FF + range) + + Common encodings are "unic" (Unicode), "symb" (Microsoft Symbol), + "ADOB" (Adobe Standard), "ADBE" (Adobe Expert), and "armn" (Apple + Roman). See the FreeType documentation for more information. + ++ Made "putalpha" a bit more robust; you can now attach an alpha + layer to a plain "L" or "RGB" image, and you can also specify + constant alphas instead of alpha layers (using integers or colour + names). + ++ Added experimental "LA" mode support. + + An "LA" image is an "L" image with an attached transparency layer. + Note that support for "LA" is not complete; some operations may + fail or produce unexpected results. + ++ Added "RankFilter", "MinFilter", "MedianFilter", and "MaxFilter" + classes to the ImageFilter module. + ++ Improved support for applications using multiple threads; PIL + now releases the global interpreter lock for many CPU-intensive + operations (based on work by Kevin Cazabon). + ++ Ignore Unicode characters in the PCF loader (from Andres Polit) + ++ Fixed typo in OleFileIO.loadfat, which could affect loading of + FlashPix and Image Composer images (Daniel Haertle) + ++ Fixed building on platforms that have Freetype but don't have + Tcl/Tk (Jack Jansen, Luciano Nocera, Piet van Oostrum and others) + ++ Added EXIF GPSInfo read support for JPEG files. To extract + GPSInfo information, open the file, extract the exif dictionary, + and check for the key 0x8825 (GPSInfo). If present, it contains + a dictionary mapping GPS keys to GPS values. For a list of keys, + see the EXIF specification. + + The "ExifTags" module contains a GPSTAGS dictionary mapping GPS + tags to tag names. + ++ Added DPI read support to the PCX and DCX codecs (info["dpi"]). + ++ The "show" methods now uses a built-in image viewer on Windows. + This viewer creates an instance of the ImageWindow class (see + below) and keeps it running in a separate thread. NOTE: This + was disabled in 1.1.5a4. + ++ Added experimental "Window" and "ImageWindow" classes to the + ImageWin module. These classes allow you to create a WCK-style + toplevel window, and use it to display raster data. + ++ Fixed some Python 1.5.2 issues (to build under 1.5.2, use the + Makefile.pre.in/Setup.in approach) + ++ Added support for the TIFF FillOrder tag. PIL can read mode "1", + "L", "P" and "RGB" images with non-standard FillOrder (based on + input from Jeff Breidenbach). + +(1.1.4 final released) + ++ Fixed ImageTk build problem on Unix. + +(1.1.4b2 released) + ++ Improved building on Mac OS X (from Jack Jansen). + ++ Improved building on Windows with MinGW (from Klamer Shutte). + ++ If no font is specified, ImageDraw now uses the embedded default + font. Use the "load" or "truetype" methods to load a real font. + ++ Added embedded default font to the ImageFont module (currently + an 8-pixel Courier font, taken from the X window distribution). + +(1.1.4b1 released) + ++ Added experimental EXIF support for JPEG files. To extract EXIF + information from a JPEG file, open the file as usual, and call the + "_getexif" method. If successful, this method returns a dictionary + mapping EXIF TIFF tags to values. If the file does not contain EXIF + data, the "_getexif" method returns None. + + The "ExifTags" module contains a dictionary mapping tags to tag + names. + + This interface will most likely change in future versions. + ++ Fixed a bug when using the "transparency" option with the GIF + writer. + ++ Added limited support for "bitfield compression" in BMP files + and DIB buffers, for 15-bit, 16-bit, and 32-bit images. This + also fixes a problem with ImageGrab module when copying screen- + dumps from the clipboard on 15/16/32-bit displays. + ++ Added experimental WAL (Quake 2 textures) loader. To use this + loader, import WalImageFile and call the "open" method in that + module. + +(1.1.4a4 released) + ++ Added updated SANE driver (Andrew Kuchling, Abel Deuring) + ++ Use Python's "mmap" module on non-Windows platforms to read some + uncompressed formats using memory mapping. Also added a "frombuffer" + function that allows you to access the contents of an existing string + or buffer object as if it were an image object. + ++ Fixed a memory leak that could appear when processing mode "P" + images (from Pier Paolo Glave) + ++ Ignore Unicode characters in the BDF loader (from Graham Dumpleton) + +(1.1.4a3 released; windows only) + ++ Added experimental RGBA-on-RGB drawing support. To use RGBA + colours on an RGB image, pass "RGBA" as the second string to + the ImageDraw.Draw constructor. + ++ Added support for non-ASCII strings (Latin-1) and Unicode + to the truetype font renderer. + ++ The ImageWin "Dib" object can now be constructed directly from + an image object. + ++ The ImageWin module now allows you use window handles as well + as device contexts. To use a window handle, wrap the handle in + an ImageWin.HWND object, and pass in this object instead of the + device context. + +(1.1.4a2 released) + ++ Improved support for 16-bit unsigned integer images (mode "I;16"). + This includes TIFF reader support, and support for "getextrema" + and "point" (from Klamer Shutte). + ++ Made the BdfFontFile reader a bit more robust (from Kevin Cazabon + and Dmitry Vasiliev) + ++ Changed TIFF writer to always write Compression tag, even when + using the default compression (from Greg Couch). + ++ Added "show" support for Mac OS X (from Dan Wolfe). + ++ Added clipboard support to the "ImageGrab" module (Windows only). + The "grabclipboard" function returns an Image object, a list of + filenames (not in 1.1.4), or None if neither was found. + +(1.1.4a1 released) + ++ Improved support for drawing RGB data in palette images. You can + now use RGB tuples or colour names (see below) when drawing in a + mode "P" image. The drawing layer automatically assigns color + indexes, as long as you don't use more than 256 unique colours. + ++ Moved self test from MiniTest/test.py to ./selftest.py. + ++ Added support for CSS3-style color strings to most places that + accept colour codes/tuples. This includes the "ImageDraw" module, + the Image "new" function, and the Image "paste" method. + + Colour strings can use one of the following formats: "#f00", + "#ff0000", "rgb(255,0,0)", "rgb(100%,0%,0%)", "hsl(0, 100%, 50%)", + or "red" (most X11-style colour names are supported). See the + documentation for the "ImageColor" module for more information. + ++ Fixed DCX decoder (based on input from Larry Bates) + ++ Added "IptcImagePlugin.getiptcinfo" helper to extract IPTC/NAA + newsphoto properties from JPEG, TIFF, or IPTC files. + ++ Support for TrueType/OpenType fonts has been added to + the standard distribution. You need the freetype 2.0 + library. + ++ Made the PCX reader a bit more robust when reading 2-bit + and 4-bit PCX images with odd image sizes. + ++ Added "Kernel" class to the ImageFilter module. This class + allows you to filter images with user-defined 3x3 and 5x5 + convolution kernels. + ++ Added "putdata" support for mode "I", "F" and "RGB". + ++ The GIF writer now supports the transparency option (from + Denis Benoit). + ++ A HTML version of the module documentation is now shipped + with the source code distribution. You'll find the files in + the Doc subdirectory. + ++ Added support for Palm pixmaps (from Bill Janssen). This + change was listed for 1.1.3, but the "PalmImagePlugin" driver + didn't make it into the distribution. + ++ Improved decoder error messages. + +(1.1.3 final released) + ++ Made setup.py look for old versions of zlib. For some back- + ground, see: http://www.gzip.org/zlib/advisory-2002-03-11.txt + +(1.1.3c2 released) + ++ Added setup.py file (tested on Unix and Windows). You still + need to build libImaging/imaging.lib in the traditional way, + but the setup.py script takes care of the rest. + + The old Setup.in/Makefile.pre.in build method is still + supported. + ++ Fixed segmentation violation in ANTIALIAS filter (an internal + buffer wasn't properly allocated). + +(1.1.3c1 released) + ++ Added ANTIALIAS downsampling filter for high-quality "resize" + and "thumbnail" operations. Also added filter option to the + "thumbnail" operation; the default value is NEAREST, but this + will most likely change in future versions. + ++ Fixed plugin loader to be more robust if the __file__ + variable isn't set. + ++ Added seek/tell support (for layers) to the PhotoShop + loader. Layer 0 is the main image. + ++ Added new (but experimental) "ImageOps" module, which provides + shortcuts for commonly used operations on entire images. + ++ Don't mess up when loading PNG images if the decoder leaves + data in the output buffer. This could cause internal errors + on some PNG images, with some versions of ZLIB. (Bug report + and patch provided by Bernhard Herzog.) + ++ Don't mess up on Unicode filenames. + ++ Don't mess up when drawing on big endian platforms. + ++ Made the TIFF loader a bit more robust; it can now read some + more slightly broken TIFF files (based on input from Ted Wright, + Bob Klimek, and D. Alan Stewart) + ++ Added OS/2 EMX build files (from Andrew MacIntyre) + ++ Change "ImageFont" to reject image files if they don't have the + right mode. Older versions could leak memory for "P" images. + (Bug reported by Markus Gritsch). + ++ Renamed some internal functions to avoid potential build + problem on Mac OS X. + ++ Added DL_EXPORT where relevant (for Cygwin, based on input + from Robert Yodlowski) + ++ (re)moved bogus __init__ call in BdfFontFile (bug spotted + by Fred Clare) + ++ Added "ImageGrab" support (Windows only) + ++ Added support for XBM hotspots (based on code contributed by + Bernhard Herzog). + ++ Added write support for more TIFF tags, namely the Artist, + Copyright, DateTime, ResolutionUnit, Software, XResolution and + YResolution tags (from Greg Couch) + ++ Added TransposedFont wrapper to ImageFont module + ++ Added "optimize" flag to GIF encoder. If optimize is present + and non-zero, PIL will work harder to create a small file. + ++ Raise "EOFError" (not IndexError) when reading beyond the + end of a TIFF sequence. + ++ Support rewind ("seek(0)") for GIF and TIFF sequences. + ++ Load grayscale GIF images as mode "L" + ++ Added DPI read/write support to the JPEG codec. The decoder + sets the info["dpi"] attribute for JPEG files with JFIF dpi + settings. The encoder uses the "dpi" option: + + im = Image.open("file.jpg") + dpi = im.info["dpi"] # raises KeyError if DPI not known + im.save("out.jpg", dpi=dpi) + + Note that PIL doesn't always preserve the "info" attribute + for normal image operations. + +(1.1.2c1 and 1.1.2 final released) + ++ Adapted to Python 2.1. Among other things, all uses of the + "regex" module has been repleased with "re". + ++ Fixed attribute error when reading large PNG files (this bug + was introduced in maintenance code released after the 1.1.1 + release) + ++ Ignore non-string objects in sys.path + ++ Fixed Image.transform(EXTENT) for negative xoffsets + ++ Fixed loading of image plugins if PIL is installed as a package. + (The plugin loader now always looks in the directory where the + Image.py module itself is found, even if that directory isn't on + the standard search path) + ++ The Png plugin has been added to the list of preloaded standard + formats + ++ Fixed bitmap/text drawing in fill mode. + ++ Fixed "getextrema" to work also for multiband images. + ++ Added transparency support for L and P images to the PNG codec. + ++ Improved support for read-only images. The "load" method now + sets the "readonly" attribute for memory-mapped images. Operations + that modifies an image in place (such as "paste" and drawing operations) + creates an in-memory copy of the image, if necessary. (before this + change, any attempt to modify a memory-mapped image resulted in a + core dump...) + ++ Added special cases for lists everywhere PIL expects a sequence. + This should speed up things like "putdata" and drawing operations. + ++ The Image.offset method is deprecated. Use the ImageChops.offset + function instead. + ++ Changed ImageChops operators to copy palette and info dictionary + from the first image argument. + +(1.1.1 released) + ++ Additional fixes for Python 1.6/2.0, including TIFF "save" bug. + ++ Changed "init" to properly load plugins when PIL is used as a + package. + ++ Fixed broken "show" method (on Unix) + +*** Changes from release 1.0 to 1.1 *** + ++ Adapted to Python 1.6 ("append" and other method changes) + ++ Fixed Image.paste when pasting with solid colour and matte + layers ("L" or "RGBA" masks) (bug reported by Robert Kern) + ++ To make it easier to distribute prebuilt versions of PIL, + the tkinit binding stuff has been moved to a separate + extension module, named "_imagingtk". + +*** Changes from release 0.3b2 to 1.0 final *** + ++ If there's no 16-bit integer (like on a Cray T3E), set + INT16 to the smallest integer available. Most of the + library works just fine anyway (from Bill Crutchfield) + ++ Tweaks to make drawing work on big-endian platforms. + +(1.0c2 released) + ++ If PIL is built with the WITH_TKINTER flag, ImageTk can + automatically hook into a standard Tkinter build. You + no longer need to build your own Tkinter to use the + ImageTk module. + + The old way still works, though. For more information, + see Tk/install.txt. + ++ Some tweaks to ImageTk to support multiple Tk interpreters + (from Greg Couch). + ++ ImageFont "load_path" now scans directory mentioned in .pth + files (from Richard Jones). + +(1.0c1 released) + ++ The TIFF plugin has been rewritten. The new plugin fully + supports all major PIL image modes (including F and I). + ++ The ImageFile module now includes a Parser class, which can + be used to incrementally decode an image file (while down- + loading it from the net, for example). See the handbook for + details. + ++ "show" now converts non-standard modes to "L" or "RGB" (as + appropriate), rather than writing weird things to disk for + "xv" to choke upon. (bug reported by Les Schaffer). + +(1.0b2 released) + ++ Major speedups for rotate, transform(EXTENT), and transform(AFFINE) + when using nearest neighbour resampling. + ++ Modified ImageDraw to be compatible with the Arrow graphics + interface. See the handbook for details. + ++ PIL now automatically loads file codecs when used as a package + (from The Dragon De Monsyne). Also included an __init__.py file + in the standard distribution. + ++ The GIF encoder has been modified to produce much smaller files. + + PIL now uses a run-length encoding method to encode GIF files. + On a random selection of GIF images grabbed from the web, this + version makes the images about twice as large as the original + LZW files, where the earlier version made them over 5 times + larger. YMMV, of course. + ++ Added PCX write support (works with "1", "P", "L", and "RGB") + ++ Added "bitmap" and "textsize" methods to ImageDraw. + ++ Improved font rendering code. Fixed a bug or two, and moved + most of the time critical stuff to C. + ++ Removed "bdf2pil.py". Use "pilfont.py" instead! + ++ Improved 16-bit support (still experimental, though). + + The following methods now support "I;16" and "I;16B" images: + "getpixel", "copy", "convert" (to and from mode "I"), "resize", + "rotate", and "transform" with nearest neighbour filters, and + "save" using the IM format. The "new" and "open" functions + also work as expected. On Windows, 16-bit files are memory + mapped. + + NOTE: ALL other operations are still UNDEFINED on 16-bit images. + ++ The "paste" method now supports constant sources. + + Just pass a colour value (a number or a tuple, depending on + the target image mode) instead of the source image. + + This was in fact implemented in an inefficient way in + earlier versions (the "paste" method generated a temporary + source image if you passed it a colour instead of an image). + In this version, this is handled on the C level instead. + ++ Added experimental "RGBa" mode support. + + An "RGBa" image is an RGBA image where the colour components + have have been premultipled with the alpha value. PIL allows + you to convert an RGBA image to an RGBa image, and to paste + RGBa images on top of RGB images. Since this saves a bunch + of multiplications and shifts, it is typically about twice + as fast an ordinary RGBA paste. + ++ Eliminated extra conversion step when pasting "RGBA" or "RGBa" + images on top of "RGB" images. + ++ Fixed Image.BICUBIC resampling for "RGB" images. + ++ Fixed PCX image file handler to properly read 8-bit PCX + files (bug introduced in 1.0b1, reported by Bernhard + Herzog) + ++ Fixed PSDraw "image" method to restore the coordinate + system. + ++ Fixed "blend" problem when applied to images that was + not already loaded (reported by Edward C. Jones) + ++ Fixed -f option to "pilconvert.py" (from Anthony Baxter) + +(1.0b1 released) + ++ Added Toby J. Sargeant's quantization package. To enable + quantization, use the "palette" option to "convert": + + imOut = im.convert("P", palette=Image.ADAPTIVE) + + This can be used with "L", "P", and "RGB" images. In this + version, dithering cannot be used with adaptive palettes. + + Note: ADAPTIVE currently maps to median cut quantization + with 256 colours. The quantization package also contains + a maximum coverage quantizer, which will be supported by + future versions of PIL. + ++ Added Eric S. Raymond's "pildriver" image calculator to the + distribution. See the docstring for more information. + ++ The "offset" method no longer dumps core if given positive + offsets (from Charles Waldman). + ++ Fixed a resource leak that could cause ImageWin to run out of + GDI resources (from Roger Burnham). + ++ Added "arc", "chord", and "pieslice" methods to ImageDraw (inspired + by code contributed by Richard Jones). + ++ Added experimental 16-bit support, via modes "I;16" (little endian + data) and "I;16B" (big endian). Only a few methods properly support + such images (see above). + ++ Added XV thumbnail file handler (from Gene Cash). + ++ Fixed BMP image file handler to handle palette images with small + palettes (from Rob Hooft). + ++ Fixed Sun raster file handler for palette images (from Charles + Waldman). + ++ Improved various internal error messages. + ++ Fixed Path constructor to handle arbitrary sequence objects. This + also affects the ImageDraw class (from Richard Jones). + ++ Fixed a bug in JpegDecode that caused PIL to report "decoder error + -2" for some progressive JPEG files (reported by Magnus Källström, + who also provided samples). + ++ Fixed a bug in JpegImagePlugin that caused PIL to hang when loading + JPEG files using 16-bit quantization tables. + ++ The Image "transform" method now supports Image.QUAD transforms. + The data argument is an 8-tuple giving the upper left, lower + left, lower right, and upper right corner of the source quadri- + lateral. Also added Image.MESH transform which takes a list + of quadrilaterals. + ++ The Image "resize", "rotate", and "transform" methods now support + Image.BILINEAR (2x2) and Image.BICUBIC (4x4) resampling filters. + Filters can be used with all transform methods. + ++ The ImageDraw "rectangle" method now includes both the right + and the bottom edges when drawing filled rectangles. + ++ The TGA decoder now works properly for runlength encoded images + which have more than one byte per pixel. + ++ "getbands" on an YCbCr image now returns ("Y", "Cb", "Cr") + ++ Some file drivers didn't handle the optional "modify" argument + to the load method. This resulted in exceptions when you used + "paste" (and other methods that modify an image in place) on a + newly opened file. + +*** Changes from release 0.2 (b5) to 0.3 (b2) *** + +(0.3b2 released) + +The test suite includes 825 individual tests. + ++ An Image "getbands" method has been added. It returns a tuple + containing the individual band names for this image. To figure + out how many bands an image has, use "len(im.getbands())". + ++ An Image "putpixel" method has been added. + ++ The Image "point" method can now be used to convert "L" images + to any other format, via a lookup table. That table should + contain 256 values for each band in the output image. + ++ Some file drivers (including FLI/FLC, GIF, and IM) accidently + overwrote the offset method with an internal attribute. All + drivers have been updated to use private attributes where + possible. + ++ The Image "histogram" method now works for "I" and "F" images. + For these modes, PIL divides the range between the min and + max values used in the image into 256 bins. You can also + pass in your own min and max values via the "extrema" option: + + h = im.histogram(extrema=(0, 255)) + ++ An Image "getextrema" method has been added. It returns the + min and max values used in the image. In this release, this + works for single band images only. + ++ Changed the PNG driver to load and save mode "I" images as + 16-bit images. When saving, values outside the range 0..65535 + are clipped. + ++ Fixed ImageFont.py to work with the new "pilfont" compiler. + ++ Added JPEG "save" and "draft" support for mode "YCbCr" images. + Note that if you save an "YCbCr" image as a JPEG file and read + it back, it is read as an RGB file. To get around this, you + can use the "draft" method: + + im = Image.open("color.jpg") + im.draft("YCbCr", im.size) + ++ Read "RGBA" TGA images. Also fixed the orientation bug; all + images should now come out the right way. + ++ Changed mode name (and internal representation) from "YCrCb" + to "YCbCr" (!) + *** WARNING: MAY BREAK EXISTING CODE *** + +(0.3b1 released) + +The test suite includes 750 individual tests. + ++ The "pilfont" package is now included in the standard PIL + distribution. The pilfont utility can be used to convert + X BDF and PCF raster font files to a format understood by + the ImageFont module. + ++ GIF files are now interlaced by default. To write a + non-interlaced file, pass interlace=0 to the "save" + method. + ++ The default string format has changed for the "fromstring" + and "tostring" methods. + *** WARNING: MAY BREAK EXISTING CODE *** + + NOTE: If no extra arguments are given, the first line in + the string buffer is the top line of the image, instead of + the bottom line. For RGB images, the string now contains + 3 bytes per pixel instead of 4. These changes were made + to make the methods compatible with the "fromstring" + factory function. + + To get the old behaviour, use the following syntax: + + data = im.tostring("raw", "RGBX", 0, -1) + im.fromstring(data, "raw", "RGBX", 0, -1) + ++ "new" no longer gives a MemoryError if the width or height + is zero (this only happened on platforms where malloc(0) + or calloc(0) returns NULL). + ++ "new" now adds a default palette object to "P" images. + ++ You can now convert directly between all modes supported by + PIL. When converting colour images to "P", PIL defaults to + a "web" palette and dithering. When converting greyscale + images to "1", PIL uses a thresholding and dithering. + ++ Added a "dither" option to "convert". By default, "convert" + uses floyd-steinberg error diffusion for "P" and "1" targets, + so this option is only used to *disable* dithering. Allowed + values are NONE (no dithering) or FLOYDSTEINBERG (default). + + imOut = im.convert("P", dither=Image.NONE) + ++ Added a full set of "I" decoders. You can use "fromstring" + (and file decoders) to read any standard integer type as an + "I" image. + ++ Added some support for "YCbCr" images (creation, conversion + from/to "L" and "RGB", IM YCC load/save) + ++ "getpixel" now works properly with fractional coordinates. + ++ ImageDraw "setink" now works with "I", "F", "RGB", "RGBA", + "RGBX", "CMYK", and "YCbCr" images. + ++ ImImagePlugin no longer attaches palettes to "RGB" images. + ++ Various minor fixes. + +(0.3a4 released) + ++ Added experimental IPTC/NAA support. + ++ Eliminated AttributeError exceptions after "crop" (from + Skip Montanaro) + ++ Reads some uncompressed formats via memory mapping (this + is currently supported on Win32 only) + ++ Fixed some last minute glitches in the last alpha release + (Types instead of types in Image.py, version numbers, etc.) + ++ Eliminated some more bogus compiler warnings. + ++ Various fixes to make PIL compile and run smoother on Macs + (from Jack Jansen). + ++ Fixed "fromstring" and "tostring" for mode "I" images. + +(0.3a3 released) + +The test suite includes 530 individual tests. + ++ Eliminated unexpected side-effect in "paste" with matte. "paste" + now works properly also if compiled with "gcc". + ++ Adapted to Python 1.5 (build issues only) + ++ Fixed the ImageDraw "point" method to draw also the last + point (!). + ++ Added "I" and "RGBX" support to Image.new. + ++ The plugin path is now properly prepended to the module search + path when a plugin module is imported. + ++ Added "draw" method to the ImageWin.Dib class. This is used by + Topaz to print images on Windows printers. + ++ "convert" now supports conversions from "P" to "1" and "F". + ++ "paste" can now take a colour instead of an image as the first argument. + The colour must match the colour argument given to the new function, and + match the mode of the target image. + ++ Fixed "paste" to allow a mask also for mode "F" images. + ++ The BMP driver now saves mode "1" images. When loading images, the mode + is set to "L" for 8-bit files with greyscale palettes, and to "P" for + other 8-bit files. + ++ The IM driver now reads and saves "1" images (file modes "0 1" or "L 1"). + ++ The JPEG and GIF drivers now saves "1" images. For JPEG, the image + is saved as 8-bit greyscale (it will load as mode "L"). For GIF, the + image will be loaded as a "P" image. + ++ Fixed a potential buffer overrun in the GIF encoder. + +(0.3a2 released) + +The test suite includes 400 individual tests. + ++ Improvements to the test suite revealed a number of minor bugs, which + are all fixed. Note that crop/paste, 32-bit ImageDraw, and ImageFont + are still weak spots in this release. + ++ Added "putpalette" method to the Image class. You can use this + to add or modify the palette for "P" and "L" images. If a palette + is added to an "L" image, it is automatically converted to a "P" + image. + ++ Fixed ImageDraw to properly handle 32-bit image memories + ("RGB", "RGBA", "CMYK", "F") + ++ Fixed "fromstring" and "tostring" not to mess up the mode attribute + in default mode. + ++ Changed ImPlatform.h to work on CRAY's (don't have one at home, so I + haven't tried it). The previous version assumed that either "short" + or "int" were 16-bit wide. PIL still won't compile on platforms where + neither "short", "int" nor "long" are 32-bit wide. + ++ Added file= and data= keyword arguments to PhotoImage and BitmapImage. + This allows you to use them as drop-in replacements for the corre- + sponding Tkinter classes. + ++ Removed bogus references to the crack coder (ImagingCrack). + +(0.3a1 released) + ++ Make sure image is loaded in "tostring". + ++ Added floating point packer (native 32-bit floats only). + +*** Changes from release 0.1b1 to 0.2 (b5) *** + ++ Modified "fromstring" and "tostring" methods to use file codecs. + Also added "fromstring" factory method to create an image directly + from data in a string. + ++ Added support for 32-bit floating point images (mode "F"). You + can convert between "L" and "F" images, and apply a subset of the + available image processing methods on the "F" image. You can also + read virtually any data format into a floating point image memory; + see the section on "Decoding Floating Point Data" in the handbook + for more information. + +(0.2b5 released; on windows only) + ++ Fixed the tobitmap() method to work properly for small bitmaps. + ++ Added RMS and standard deviation to the ImageStat.Stat class. Also + modified the constructor to take an optional feature mask, and also + to accept either an image or a list containing the histogram data. + ++ The BitmapImage code in ImageTk can now use a special bitmap + decoder, which has to be patched into Tk. See the "Tk/pilbitmap.txt" + file for details. If not installed, bitmaps are transferred to Tk as + XBM strings. + ++ The PhotoImage code in ImageTk now uses a Tcl command ("PyImagingPaste") + instead of a special image type. This gives somewhat better performance, + and also allows PIL to support transparency. + *** WARNING: TKAPPINIT MUST BE MODIFIED *** + ++ ImageTk now honours the alpha layer in RGBA images. Only fully + transparent pixels are made transparent (that is, the alpha layer + is treated as a mask). To treat the alpha laters as a matte, you + must paste the image on the background before handing it over to + ImageTk. + ++ Added McIdas reader (supports 8-bit images only). + ++ PIL now preloads drivers for BMP, GIF, JPEG, PPM, and TIFF. As + long as you only load and save these formats, you don't have to + wait for a full scan for drivers. To force scanning, call the + Image.init() function. + ++ The "seek" and "tell" methods are now always available, also for + single-frame images. + ++ Added optional mask argument to histogram method. The mask may + be an "1" or "L" image with the same size as the original image. + Only pixels where the mask is non-zero are included in the + histogram. + ++ The "paste" method now allows you to specify only the lower left + corner (a 2-tuple), instead of the full region (a 4-tuple). + ++ Reverted to old plugin scanning model; now scans all directory + names in the path when looking for plugins. + ++ Added PIXAR raster support. Only uncompressed ("dumped") RGB + images can currently be read (based on information provided + by Greg Coats). + ++ Added FlashPix (FPX) read support. Reads all pixel formats, but + only the highest resolution is read, and the viewing transform is + currently ignored. + ++ Made PNG encoding somewhat more efficient in "optimize" mode; a + bug in 0.2b4 didn't enable all predictor filters when optimized + storage were requested. + ++ Added Microsoft Image Composer (MIC) read support. When opened, + the first sprite in the file is loaded. You can use the seek method + to load additional sprites from the file. + ++ Properly reads "P" and "CMYK" PSD images. + ++ "pilconvert" no longer optimizes by default; use the -o option to + make the file as small as possible (at the expense of speed); use + the -q option to set the quality when compressing to JPEG. + ++ Fixed "crop" not to drop the palette for "P" images. + ++ Added and verified FLC support. + ++ Paste with "L" or "RGBA" alpha is now several times faster on most + platforms. + ++ Changed Image.new() to initialize the image to black, as described + in the handbook. To get an uninitialized image, use None as the + colour. + ++ Fixed the PDF encoder to produce a valid header; Acrobat no longer + complains when you load PDF images created by PIL. + ++ PIL only scans fully-qualified directory names in the path when + looking for plugins. + *** WARNING: MAY BREAK EXISTING CODE *** + ++ Faster implementation of "save" used when filename is given, + or when file object has "fileno" and "flush" methods. + ++ Don't crash in "crop" if region extends outside the source image. + ++ Eliminated a massive memory leak in the "save" function. + ++ The GIF decoder doesn't crash if the code size is set to an illegal + value. This could happen since another bug didn't handle local + palettes properly if they didn't have the same size as the + global palette (not very common). + ++ Added predictor support (TIFF 6.0 section 14) to the TIFF decoder. + ++ Fixed palette and padding problems in BMP driver. Now properly + writes "1", "L", "P" and "RGB" images. + ++ Fixed getpixel()/getdata() to return correct pixel values. + ++ Added PSD (PhotoShop) read support. Reads both uncompressed + and compressed images of most types. + ++ Added GIF write support (writes "uncompressed" GIF files only, + due to unresolvable licensing issues). The "gifmaker.py" script + can be used to create GIF animations. + ++ Reads 8-bit "L" and "P" TGA images. Also reads 16-bit "RGB" + images. + ++ Added FLI read support. This driver has only been tested + on a few FLI samples. + ++ Reads 2-bit and 4-bit PCX images. + ++ Added MSP read and write support. Both version 1 and 2 can be + read, but only version 1 (uncompressed) files are written. + ++ Fixed a bug in the FLI/FLC identification code that caused the + driver to raise an exception when parsing valid FLI/FLC files. + ++ Improved performance when loading file format plugins, and when + opening files. + ++ Added GIF animation support, via the "seek" and "tell" methods. + You can use "player.py" to play an animated GIF file. + ++ Removed MNG support, since the spec is changing faster than I + can change the code. I've added support for the experimental + ARG format instead. Contact me for more information on this + format. + ++ Added keyword options to the "save" method. The following options + are currently supported: + + format option description + -------------------------------------------------------- + JPEG optimize minimize output file at the + expense of compression speed. + + JPEG progressive enable progressive output. the + option value is ignored. + + JPEG quality set compression quality (1-100). + the default value is 75. + + JPEG smooth smooth dithered images. value + is strengh (1-100). default is + off (0). + + PNG optimize minimize output file at the + expense of compression speed. + + Expect more options in future releases. Also note that + file writers silently ignore unknown options. + ++ Plugged memory leaks in the PNG and TIFF decoders. + ++ Added PNG write support. + ++ (internal) RGB unpackers and converters now set the pad byte + to 255 (full opacity). + ++ Properly handles the "transparency" property for GIF, PNG + and XPM files. + ++ Added a "putalpha" method, allowing you to attach a "1" or "L" + image as the alpha layer to an "RGBA" image. + ++ Various improvements to the sample scripts: + + "pilconvert" Carries out some extra tricks in order to make + the resulting file as small as possible. + + "explode" (NEW) Split an image sequence into individual frames. + + "gifmaker" (NEW) Convert a sequence file into a GIF animation. + Note that the GIF encoder create "uncompressed" GIF + files, so animations created by this script are + rather large (typically 2-5 times the compressed + sizes). + + "image2py" (NEW) Convert a single image to a python module. See + comments in this script for details. + + "player" If multiple images are given on the command line, + they are interpreted as frames in a sequence. The + script assumes that they all have the same size. + Also note that this script now can play FLI/FLC + and GIF animations. + + This player can also execute embedded Python + animation applets (ARG format only). + + "viewer" Transparent images ("P" with transparency property, + and "RGBA") are superimposed on the standard Tk back- + ground. + ++ Fixed colour argument to "new". For multilayer images, pass a + tuple: (Red, Green, Blue), (Red, Green, Blue, Alpha), or (Cyan, + Magenta, Yellow, Black). + ++ Added XPM (X pixmap) read support. + +(0.2b3 released) + ++ Added MNG (multi-image network graphics) read support. "Ming" + is a proposed animation standard, based on the PNG file format. + + You can use the "player" sample script to display some flavours + of this format. The MNG standard is still under development, + as is this driver. More information, including sample files, + can be found at + ++ Added a "verify" method to images loaded from file. This method + scans the file for errors, without actually decoding the image + data, and raises a suitable exception if it finds any problems. + Currently implemented for PNG and MNG files only. + ++ Added support for interlaced GIF images. + ++ Added PNG read support -- if linked with the ZLIB compression library, + PIL reads all kinds of PNG images, except interlaced files. + ++ Improved PNG identification support -- doesn't mess up on unknown + chunks, identifies all possible PNG modes, and verifies checksum + on PNG header chunks. + ++ Added an experimental reader for placable Windows Meta Files (WMF). + This reader is still very incomplete, but it illustrates how PIL's + drawing capabilities can be used to render vector and metafile + formats. + ++ Added restricted drivers for images from Image Tools (greyscale + only) and LabEye/IFUNC (common interchange modes only). + ++ Some minor improvements to the sample scripts provided in the + "Scripts" directory. + ++ The test images have been moved to the "Images" directory. + +(0.2b2 released) +(0.2b1 released; Windows only) + ++ Fixed filling of complex polygons. The ImageDraw "line" and + "polygon" methods also accept Path objects. + ++ The ImageTk "PhotoImage" object can now be constructed directly + from an image. You can also pass the object itself to Tkinter, + instead of using the "image" attribute. Finally, using "paste" + on a displayed image automatically updates the display. + ++ The ImageTk "BitmapImage" object allows you to create transparent + overlays from 1-bit images. You can pass the object itself to + Tkinter. The constructor takes the same arguments as the Tkinter + BitmapImage class; use the "foreground" option to set the colour + of the overlay. + ++ Added a "putdata" method to the Image class. This can be used to + load a 1-layer image with data from a sequence object or a string. + An optional floating point scale and offset can be used to adjust + the data to fit into the 8-bit pixel range. Also see the "getdata" + method. + ++ Added the EXTENT method to the Image "transform" method. This can + be used to quickly crop, stretch, shrink, or mirror a subregion + from another image. + ++ Adapted to Python 1.4. + ++ Added a project makefile for Visual C++ 4.x. This allows you to + easily build a dynamically linked version of PIL for Windows 95 + and NT. + ++ A Tk "booster" patch for Windows is available. It gives dramatic + performance improvements for some displays. Has been tested with + Tk 4.2 only, but is likely to work with Tk 4.1 as well. See the Tk + subdirectory for details. + ++ You can now save 1-bit images in the XBM format. In addition, the + Image class now provides a "tobitmap" method which returns a string + containing an XBM representation of the image. Quite handy to use + with Tk. + ++ More conversions, including "RGB" to "1" and more. + +(0.2a1 released) + ++ Where earlier versions accepted lists, this version accepts arbitrary + Python sequences (including strings, in some cases). A few resource + leaks were plugged in the process. + ++ The Image "paste" method now allows the box to extend outside + the target image. The size of the box, the image to be pasted, + and the optional mask must still match. + ++ The ImageDraw module now supports filled polygons, outlined and + filled ellipses, and text. Font support is rudimentary, though. + ++ The Image "point" method now takes an optional mode argument, + allowing you to convert the image while translating it. Currently, + this can only be used to convert "L" or "P" images to "1" images + (creating thresholded images or "matte" masks). + ++ An Image "getpixel" method has been added. For single band images, + it returns the pixel value at a given position as an integer. + For n-band images, it returns an n-tuple of integers. + ++ An Image "getdata" method has been added. It returns a sequence + object representing the image as a 1-dimensional array. Only len() + and [] can be used with this sequence. This method returns a + reference to the existing image data, so changes in the image + will be immediately reflected in the sequence object. + ++ Fixed alignment problems in the Windows BMP writer. + ++ If converting an "RGB" image to "RGB" or "L", you can give a second + argument containing a colour conversion matrix. + ++ An Image "getbbox" method has been added. It returns the bounding + box of data in an image, considering the value 0 as background. + ++ An Image "offset" method has been added. It returns a new image + where the contents of the image have been offset the given distance + in X and/or Y direction. Data wraps between edges. + ++ Saves PDF images. The driver creates a binary PDF 1.1 files, using + JPEG compression for "L", "RGB", and "CMYK" images, and hex encoding + (same as for PostScript) for other formats. + ++ The "paste" method now accepts "1" masks. Zero means transparent, + any other pixel value means opaque. This is faster than using an + "L" transparency mask. + ++ Properly writes EPS files (and properly prints images to postscript + printers as well). + ++ Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR + files. Cursor animations are not supported. + ++ Fixed alignment problems in the Sun raster loader. + ++ Added "draft" and "thumbnail" methods. The draft method is used + to optimize loading of JPEG and PCD files, the thumbnail method is + used to create a thumbnail representation of an image. + ++ Added Windows display support, via the ImageWin class (see the + handbook for details). + ++ Added raster conversion for EPS files. This requires GNU or Aladdin + Ghostscript, and probably works on UNIX only. + ++ Reads PhotoCD (PCD) images. The base resolution (768x512) can be + read from a PhotoCD file. + ++ Eliminated some compiler warnings. Bindings now compile cleanly in C++ + mode. Note that the Imaging library itself must be compiled in C mode. + ++ Added "bdf2pil.py", which converts BDF fonts into images with associated + metrics. This is definitely work in progress. For info, see description + in script for details. + ++ Fixed a bug in the "ImageEnhance.py" module. + ++ Fixed a bug in the netpbm save hack in "GifImagePlugin.py" + ++ Fixed 90 and 270 degree rotation of rectangular images. + ++ Properly reads 8-bit TIFF palette-color images. + ++ Reads plane separated RGB and CMYK TIFF images. + ++ Added driver debug mode. This is enabled by setting Image.DEBUG + to a non-zero value. Try the -D option to "pilfile.py" and see what + happens. + ++ Don't crash on "atend" constructs in PostScript files. + ++ Only the Image module imports _imaging directly. Other modules + should refer to the binding module as "Image.core". + +*** Changes from release 0.0 to 0.1 (b1) *** + ++ A handbook is available (distributed separately). + ++ The coordinate system is changed so that (0,0) is now located + in the upper left corner. This is in compliancy with ISO 12087 + and 90% of all other image processing and graphics libraries. + ++ Modes "1" (bilevel) and "P" (palette) have been introduced. Note + that bilevel images are stored with one byte per pixel. + ++ The Image "crop" and "paste" methods now accepts None as the + box argument, to refer to the full image (self, that is). + ++ The Image "crop" method now works properly. + ++ The Image "point" method is now available. You can use either a + lookup table or a function taking one argument. + ++ The Image join function has been renamed to "merge". + ++ An Image "composite" function has been added. It is identical + to copy() followed by paste(mask). + ++ An Image "eval" function has been added. It is currently identical + to point(function); that is, only a single image can be processed. + ++ A set of channel operations has been added. See the "ImageChops" + module, test_chops.py, and the handbook for details. + ++ Added the "pilconvert" utility, which converts image files. Note + that the number of output formats are still quite restricted. + ++ Added the "pilfile" utility, which quickly identifies image files + (without loading them, in most cases). + ++ Added the "pilprint" utility, which prints image files to Postscript + printers. + ++ Added a rudimentary version of the "pilview" utility, which is + simple image viewer based on Tk. Only File/Exit and Image/Next + works properly. + ++ An interface to Tk has been added. See "Lib/ImageTk.py" and README + for details. + ++ An interface to Jack Jansen's Img library has been added (thanks to + Jack). This allows you to read images through the Img extensions file + format handlers. See the file "Lib/ImgExtImagePlugin.py" for details. + ++ Postscript printing is provided through the PSDraw module. See the + handbook for details. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS b/tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS new file mode 100755 index 00000000000..8846fb94547 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS @@ -0,0 +1,299 @@ +Imaging/README + +Imaging/CHANGES + +Imaging/CONTENTS +Imaging/MANIFEST + +Imaging/BUILDME + +Imaging/setup.py + +Imaging/selftest.py +Imaging/doctest.py + +Imaging/libImaging/Imaging.h +Imaging/libImaging/ImDib.h +Imaging/libImaging/ImPlatform.h + +Imaging/libImaging/Quant.h +Imaging/libImaging/QuantHash.h +Imaging/libImaging/QuantHeap.h +Imaging/libImaging/QuantDefines.h +Imaging/libImaging/QuantTypes.h + +Imaging/libImaging/Access.c +Imaging/libImaging/Antialias.c +Imaging/libImaging/Bands.c +Imaging/libImaging/Blend.c +Imaging/libImaging/Chops.c +Imaging/libImaging/Convert.c +Imaging/libImaging/ConvertYCbCr.c +Imaging/libImaging/Copy.c +Imaging/libImaging/Crc32.c +Imaging/libImaging/Crop.c +Imaging/libImaging/Dib.c +Imaging/libImaging/Draw.c +Imaging/libImaging/Effects.c +Imaging/libImaging/Except.c +Imaging/libImaging/File.c +Imaging/libImaging/Fill.c +Imaging/libImaging/Filter.c +Imaging/libImaging/Geometry.c +Imaging/libImaging/GetBBox.c +Imaging/libImaging/Histo.c +Imaging/libImaging/Matrix.c +Imaging/libImaging/ModeFilter.c +Imaging/libImaging/Negative.c +Imaging/libImaging/Offset.c +Imaging/libImaging/Pack.c +Imaging/libImaging/Palette.c +Imaging/libImaging/Paste.c +Imaging/libImaging/Point.c +Imaging/libImaging/Quant.c +Imaging/libImaging/QuantHash.c +Imaging/libImaging/QuantHeap.c +Imaging/libImaging/RankFilter.c +Imaging/libImaging/Storage.c +Imaging/libImaging/Unpack.c +Imaging/libImaging/UnpackYCC.c +Imaging/libImaging/UnsharpMask.c + +Imaging/libImaging/Bit.h +Imaging/libImaging/Gif.h +Imaging/libImaging/Jpeg.h +Imaging/libImaging/Lzw.h +Imaging/libImaging/Raw.h +Imaging/libImaging/Zip.h +Imaging/libImaging/BitDecode.c +Imaging/libImaging/EpsEncode.c +Imaging/libImaging/FliDecode.c +Imaging/libImaging/GifDecode.c +Imaging/libImaging/GifEncode.c +Imaging/libImaging/HexDecode.c +Imaging/libImaging/JpegDecode.c +Imaging/libImaging/JpegEncode.c +Imaging/libImaging/LzwDecode.c +Imaging/libImaging/MspDecode.c +Imaging/libImaging/PackDecode.c +Imaging/libImaging/PcdDecode.c +Imaging/libImaging/PcxEncode.c +Imaging/libImaging/PcxDecode.c +Imaging/libImaging/RawDecode.c +Imaging/libImaging/RawEncode.c +Imaging/libImaging/SunRleDecode.c +Imaging/libImaging/TgaRleDecode.c +Imaging/libImaging/XbmDecode.c +Imaging/libImaging/XbmEncode.c +Imaging/libImaging/ZipDecode.c +Imaging/libImaging/ZipEncode.c + +Imaging/_imaging.c +Imaging/decode.c +Imaging/encode.c +Imaging/display.c +Imaging/map.c +Imaging/outline.c +Imaging/path.c + +Imaging/_imagingtk.c +Imaging/_imagingft.c +Imaging/_imagingcms.c +Imaging/_imagingmath.c + +Imaging/PIL.pth +Imaging/PIL/__init__.py +Imaging/PIL/ArgImagePlugin.py +Imaging/PIL/BdfFontFile.py +Imaging/PIL/BmpImagePlugin.py +Imaging/PIL/BufrStubImagePlugin.py +Imaging/PIL/ContainerIO.py +Imaging/PIL/CurImagePlugin.py +Imaging/PIL/DcxImagePlugin.py +Imaging/PIL/EpsImagePlugin.py +Imaging/PIL/ExifTags.py +Imaging/PIL/FitsStubImagePlugin.py +Imaging/PIL/FliImagePlugin.py +Imaging/PIL/FontFile.py +Imaging/PIL/FpxImagePlugin.py +Imaging/PIL/GbrImagePlugin.py +Imaging/PIL/GdImageFile.py +Imaging/PIL/GifImagePlugin.py +Imaging/PIL/GimpGradientFile.py +Imaging/PIL/GimpPaletteFile.py +Imaging/PIL/GribStubImagePlugin.py +Imaging/PIL/Hdf5StubImagePlugin.py +Imaging/PIL/IcoImagePlugin.py +Imaging/PIL/IcnsImagePlugin.py +Imaging/PIL/Image.py +Imaging/PIL/ImageChops.py +Imaging/PIL/ImageCms.py +Imaging/PIL/ImageColor.py +Imaging/PIL/ImageDraw.py +Imaging/PIL/ImageDraw2.py +Imaging/PIL/ImageEnhance.py +Imaging/PIL/ImageFile.py +Imaging/PIL/ImageFileIO.py +Imaging/PIL/ImageFilter.py +Imaging/PIL/ImageFont.py +Imaging/PIL/ImageGL.py +Imaging/PIL/ImageGrab.py +Imaging/PIL/ImageMath.py +Imaging/PIL/ImageMode.py +Imaging/PIL/ImageOps.py +Imaging/PIL/ImagePalette.py +Imaging/PIL/ImagePath.py +Imaging/PIL/ImageQt.py +Imaging/PIL/ImageSequence.py +Imaging/PIL/ImageShow.py +Imaging/PIL/ImageStat.py +Imaging/PIL/ImageTk.py +Imaging/PIL/ImageTransform.py +Imaging/PIL/ImageWin.py +Imaging/PIL/ImImagePlugin.py +Imaging/PIL/ImtImagePlugin.py +Imaging/PIL/IptcImagePlugin.py +Imaging/PIL/JpegImagePlugin.py +Imaging/PIL/McIdasImagePlugin.py +Imaging/PIL/MicImagePlugin.py +Imaging/PIL/MpegImagePlugin.py +Imaging/PIL/MspImagePlugin.py +Imaging/PIL/OleFileIO.py +Imaging/PIL/PaletteFile.py +Imaging/PIL/PalmImagePlugin.py +Imaging/PIL/PcdImagePlugin.py +Imaging/PIL/PcfFontFile.py +Imaging/PIL/PcxImagePlugin.py +Imaging/PIL/PdfImagePlugin.py +Imaging/PIL/PixarImagePlugin.py +Imaging/PIL/PngImagePlugin.py +Imaging/PIL/PpmImagePlugin.py +Imaging/PIL/PsdImagePlugin.py +Imaging/PIL/PSDraw.py +Imaging/PIL/SgiImagePlugin.py +Imaging/PIL/SpiderImagePlugin.py +Imaging/PIL/SunImagePlugin.py +Imaging/PIL/TarIO.py +Imaging/PIL/TgaImagePlugin.py +Imaging/PIL/TiffImagePlugin.py +Imaging/PIL/TiffTags.py +Imaging/PIL/WalImageFile.py +Imaging/PIL/WmfImagePlugin.py +Imaging/PIL/XbmImagePlugin.py +Imaging/PIL/XpmImagePlugin.py +Imaging/PIL/XVThumbImagePlugin.py + +Imaging/Docs/index.html +Imaging/Docs/effbot.css +Imaging/Docs/pythondoc-PIL.ArgImagePlugin.html +Imaging/Docs/pythondoc-PIL.BdfFontFile.html +Imaging/Docs/pythondoc-PIL.BmpImagePlugin.html +Imaging/Docs/pythondoc-PIL.BufrStubImagePlugin.html +Imaging/Docs/pythondoc-PIL.ContainerIO.html +Imaging/Docs/pythondoc-PIL.CurImagePlugin.html +Imaging/Docs/pythondoc-PIL.DcxImagePlugin.html +Imaging/Docs/pythondoc-PIL.EpsImagePlugin.html +Imaging/Docs/pythondoc-PIL.ExifTags.html +Imaging/Docs/pythondoc-PIL.FitsStubImagePlugin.html +Imaging/Docs/pythondoc-PIL.FliImagePlugin.html +Imaging/Docs/pythondoc-PIL.FontFile.html +Imaging/Docs/pythondoc-PIL.FpxImagePlugin.html +Imaging/Docs/pythondoc-PIL.GbrImagePlugin.html +Imaging/Docs/pythondoc-PIL.GdImageFile.html +Imaging/Docs/pythondoc-PIL.GifImagePlugin.html +Imaging/Docs/pythondoc-PIL.GimpGradientFile.html +Imaging/Docs/pythondoc-PIL.GimpPaletteFile.html +Imaging/Docs/pythondoc-PIL.GribStubImagePlugin.html +Imaging/Docs/pythondoc-PIL.Hdf5StubImagePlugin.html +Imaging/Docs/pythondoc-PIL.IcoImagePlugin.html +Imaging/Docs/pythondoc-PIL.IcnsImagePlugin.html +Imaging/Docs/pythondoc-PIL.Image.html +Imaging/Docs/pythondoc-PIL.ImageChops.html +Imaging/Docs/pythondoc-PIL.ImageColor.html +Imaging/Docs/pythondoc-PIL.ImageDraw.html +Imaging/Docs/pythondoc-PIL.ImageEnhance.html +Imaging/Docs/pythondoc-PIL.ImageFile.html +Imaging/Docs/pythondoc-PIL.ImageFileIO.html +Imaging/Docs/pythondoc-PIL.ImageFilter.html +Imaging/Docs/pythondoc-PIL.ImageFont.html +Imaging/Docs/pythondoc-PIL.ImageGL.html +Imaging/Docs/pythondoc-PIL.ImageGrab.html +Imaging/Docs/pythondoc-PIL.ImageOps.html +Imaging/Docs/pythondoc-PIL.ImagePalette.html +Imaging/Docs/pythondoc-PIL.ImagePath.html +Imaging/Docs/pythondoc-PIL.ImageSequence.html +Imaging/Docs/pythondoc-PIL.ImageStat.html +Imaging/Docs/pythondoc-PIL.ImageTk.html +Imaging/Docs/pythondoc-PIL.ImageTransform.html +Imaging/Docs/pythondoc-PIL.ImageWin.html +Imaging/Docs/pythondoc-PIL.ImImagePlugin.html +Imaging/Docs/pythondoc-PIL.ImtImagePlugin.html +Imaging/Docs/pythondoc-PIL.IptcImagePlugin.html +Imaging/Docs/pythondoc-PIL.JpegImagePlugin.html +Imaging/Docs/pythondoc-PIL.McIdasImagePlugin.html +Imaging/Docs/pythondoc-PIL.MicImagePlugin.html +Imaging/Docs/pythondoc-PIL.MpegImagePlugin.html +Imaging/Docs/pythondoc-PIL.MspImagePlugin.html +Imaging/Docs/pythondoc-PIL.OleFileIO.html +Imaging/Docs/pythondoc-PIL.PaletteFile.html +Imaging/Docs/pythondoc-PIL.PalmImagePlugin.html +Imaging/Docs/pythondoc-PIL.PcdImagePlugin.html +Imaging/Docs/pythondoc-PIL.PcfFontFile.html +Imaging/Docs/pythondoc-PIL.PcxImagePlugin.html +Imaging/Docs/pythondoc-PIL.PdfImagePlugin.html +Imaging/Docs/pythondoc-PIL.PixarImagePlugin.html +Imaging/Docs/pythondoc-PIL.PngImagePlugin.html +Imaging/Docs/pythondoc-PIL.PpmImagePlugin.html +Imaging/Docs/pythondoc-PIL.PsdImagePlugin.html +Imaging/Docs/pythondoc-PIL.PSDraw.html +Imaging/Docs/pythondoc-PIL.SgiImagePlugin.html +Imaging/Docs/pythondoc-PIL.SpiderImagePlugin.html +Imaging/Docs/pythondoc-PIL.SunImagePlugin.html +Imaging/Docs/pythondoc-PIL.TarIO.html +Imaging/Docs/pythondoc-PIL.TgaImagePlugin.html +Imaging/Docs/pythondoc-PIL.TiffImagePlugin.html +Imaging/Docs/pythondoc-PIL.TiffTags.html +Imaging/Docs/pythondoc-PIL.WalImageFile.html +Imaging/Docs/pythondoc-PIL.WmfImagePlugin.html +Imaging/Docs/pythondoc-PIL.XbmImagePlugin.html +Imaging/Docs/pythondoc-PIL.XpmImagePlugin.html +Imaging/Docs/pythondoc-PIL.XVThumbImagePlugin.html + +Imaging/Scripts/pilconvert.py +Imaging/Scripts/pildriver.py +Imaging/Scripts/pilfile.py +Imaging/Scripts/pilfont.py +Imaging/Scripts/pilprint.py + +Imaging/Images/lena.gif +Imaging/Images/lena.png +Imaging/Images/lena.ppm +Imaging/Images/lena.jpg + +Imaging/Images/courB08.bdf +Imaging/Images/courB08.pbm +Imaging/Images/courB08.pil + +Imaging/Sane/README +Imaging/Sane/CHANGES +Imaging/Sane/setup.py +Imaging/Sane/sanedoc.txt +Imaging/Sane/_sane.c +Imaging/Sane/sane.py +Imaging/Sane/demo_numarray.py +Imaging/Sane/demo_pil.py + +Imaging/Scripts/README +Imaging/Scripts/enhancer.py +Imaging/Scripts/explode.py +Imaging/Scripts/gifmaker.py +Imaging/Scripts/painter.py +Imaging/Scripts/player.py +Imaging/Scripts/viewer.py +Imaging/Scripts/thresholder.py + +Imaging/Tk/tkImaging.c +Imaging/Tk/install.txt +Imaging/Tk/booster.txt +Imaging/Tk/pilbitmap.txt + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css b/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css new file mode 100755 index 00000000000..b03ae458cdc --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css @@ -0,0 +1,118 @@ +/* effbot.css */ + +BODY { + font: 100% Georgia, Times, serif; + color: black; + margin: 0px 20px 0px 20px; +} + +#effbot-body { + background: white; + padding: 10px 40px 10px 40px; + max-width: 50em; +} + +#effbot-menu { + display: none; +} + +.adsense { + background: #f8fff8; + border: 1px solid #084; + padding: 10px 4px 4px 4px; +} + +.sidebar { + border: 1px solid #000; + float: right; clear: right; + width: 200px; + background: white; + padding: 10px; + margin: 0px -25px 10px 0px; +} + +/* visual style */ + +P { + line-height: 1.3em; +} + +CODE, PRE { + font: 100% "Courier New", Courier, Monaco, monospace; + color: #042; margin-left: 20px; +} + +H1, H2, H3 { + font-family: Georgia, Times, serif; + color: #084; margin-top: 30px; +} + +H1, H2, { border-top: 1px solid #084; } + +H4, H5, H6 { + font-family: Georgia, Times, serif; + color: #084; margin-top: 15px; +} + +A:link, A:hover { color: #084; } +A:visited { color: #404040; } + +UL LI { list-style-type: square; } + +.title { margin-bottom: 2px; color: #084; } +.info { font-size: 80%; color: #084; margin-top: 0px; } + +.bluebox { color: #084; margin-top: 10px; } + +.highlight { background: #cfc; } +.mark { color: #084; } +.small { font-size: 80%; } +.display { background: #eee; padding: 20px; } + +.note { + background: #efe; + border-top: 1px solid #084; + border-bottom: 1px solid #084; + padding: 2px 20px; +} + +.example { + border-top: medium solid #084; + border-bottom: medium solid #084; + padding: 5px; +} + +.figure { + border-top: medium solid #084; + border-bottom: medium solid #084; + padding: 5px; +} + +.fixme { + background: #eee; + border: 1px solid #084; + padding: 2x 20px; +} + +.simpletable { + border: 1px solid #084; + border-collapse: collapse; +} + +.simpletable TH { + text-align: left; + background: #cfc; + border: 1px solid #084; + margin: 0px; + padding: 1px 5px; +} + +.simpletable TD { + border: 1px solid #084; + margin: 0px; + padding: 5px; +} + +/* xmldiff markup */ +.new { text-decoration: underline; color: red; background: #fff0f0; } +.old { text-decoration: line-through; color: blue; background: #f0f0ff; } diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html b/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html new file mode 100755 index 00000000000..fbc76a99dfb --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html @@ -0,0 +1,103 @@ + + + + + +The Python Imaging Library + + + +

The Python Imaging Library

+ +

Online Resources

+ +
+
Python Imaging Library (official product page at pythonware.com)
+
Python Imaging Library (development page at effbot.org)
+
+ +

Package Contents

+ +

The following pages are generated from pythondoc markup in the source files.

+ +
+
The PIL.Image Module
+
The PIL.ImageChops Module
+
The PIL.ImageColor Module
+
The PIL.ImageDraw Module
+
The PIL.ImageEnhance Module
+
The PIL.ImageFile Module
+
The PIL.ImageFileIO Module
+
The PIL.ImageFilter Module
+
The PIL.ImageFont Module
+
The PIL.ImageGL Module
+
The PIL.ImageGrab Module
+
The PIL.ImageMath Module
+
The PIL.ImageMode Module
+
The PIL.ImageOps Module
+
The PIL.ImagePalette Module
+
The PIL.ImagePath Module
+
The PIL.ImageQt Module
+
The PIL.ImageSequence Module
+
The PIL.ImageStat Module
+
The PIL.ImageTk Module
+
The PIL.ImageTransform Module
+
The PIL.ImageWin Module
+
 
+
The PIL.ArgImagePlugin Module
+
The PIL.BdfFontFile Module
+
The PIL.BmpImagePlugin Module
+
The PIL.BufrStubImagePlugin Module
+
The PIL.ContainerIO Module
+
The PIL.CurImagePlugin Module
+
The PIL.DcxImagePlugin Module
+
The PIL.EpsImagePlugin Module
+
The PIL.ExifTags Module
+
The PIL.FitsStubImagePlugin Module
+
The PIL.FliImagePlugin Module
+
The PIL.FontFile Module
+
The PIL.FpxImagePlugin Module
+
The PIL.GbrImagePlugin Module
+
The PIL.GdImageFile Module
+
The PIL.GifImagePlugin Module
+
The PIL.GimpGradientFile Module
+
The PIL.GimpPaletteFile Module
+
The PIL.GribStubImagePlugin Module
+
The PIL.Hdf5StubImagePlugin Module
+
The PIL.IcnsImagePlugin Module
+
The PIL.IcoImagePlugin Module
+
The PIL.ImImagePlugin Module
+
The PIL.ImtImagePlugin Module
+
The PIL.IptcImagePlugin Module
+
The PIL.JpegImagePlugin Module
+
The PIL.McIdasImagePlugin Module
+
The PIL.MicImagePlugin Module
+
The PIL.MpegImagePlugin Module
+
The PIL.MspImagePlugin Module
+
The PIL.OleFileIO Module
+
The PIL.PSDraw Module
+
The PIL.PaletteFile Module
+
The PIL.PalmImagePlugin Module
+
The PIL.PcdImagePlugin Module
+
The PIL.PcfFontFile Module
+
The PIL.PcxImagePlugin Module
+
The PIL.PdfImagePlugin Module
+
The PIL.PixarImagePlugin Module
+
The PIL.PngImagePlugin Module
+
The PIL.PpmImagePlugin Module
+
The PIL.PsdImagePlugin Module
+
The PIL.SgiImagePlugin Module
+
The PIL.SunImagePlugin Module
+
The PIL.TarIO Module
+
The PIL.TgaImagePlugin Module
+
The PIL.TiffImagePlugin Module
+
The PIL.TiffTags Module
+
The PIL.WalImageFile Module
+
The PIL.WbmpImagePlugin Module
+
The PIL.WmfImagePlugin Module
+
The PIL.XVThumbImagePlugin Module
+
The PIL.XbmImagePlugin Module
+
The PIL.XpmImagePlugin Module
+
+ + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf new file mode 100755 index 00000000000..5a48895d1de --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf @@ -0,0 +1,2676 @@ +STARTFONT 2.1 +COMMENT $XConsortium: courB08.bdf,v 1.5 94/04/10 21:46:11 gildea Exp $ +COMMENT +COMMENT Copyright 1984, 1987 Adobe Systems, Inc. +COMMENT Portions Copyright 1988 Digital Equipment Corporation +COMMENT +COMMENT Adobe is a registered trademark of Adobe Systems, Inc. Permission +COMMENT to use these trademarks is hereby granted only in association with the +COMMENT images described in this file. +COMMENT +COMMENT Permission to use, copy, modify, and distribute this software and +COMMENT its documentation for any purpose and without fee is hereby granted, +COMMENT provided that the above copyright notices appear in all copies and +COMMENT that both those copyright notices and this permission notice appear +COMMENT in supporting documentation, and that the names of Adobe Systems and +COMMENT Digital Equipment Corporation not be used in advertising or +COMMENT publicity pertaining to distribution of the software without +COMMENT specific, written prior permission. Adobe Systems and Digital +COMMENT Equipment Corporation make no representations about the suitability +COMMENT of this software for any purpose. It is provided "as is" without +COMMENT express or implied warranty. +COMMENT +COMMENT ADOBE SYSTEMS AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL +COMMENT WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +COMMENT WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ADOBE +COMMENT SYSTEMS AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, +COMMENT INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +COMMENT RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +COMMENT CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +COMMENT CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +COMMENT +COMMENT +FONT -Adobe-Courier-Bold-R-Normal--11-80-100-100-M-60-ISO8859-1 +SIZE 8 100 100 +FONTBOUNDINGBOX 8 11 -1 -2 +STARTPROPERTIES 22 +COMMENT Begin LogicalFontDescription +FONTNAME_REGISTRY "" +FAMILY_NAME "Courier" +FOUNDRY "Adobe" +WEIGHT_NAME "Bold" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 11 +POINT_SIZE 80 +RESOLUTION_X 100 +RESOLUTION_Y 100 +SPACING "M" +AVERAGE_WIDTH 60 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "1" +COMMENT END LogicalFontDescription +CHARSET_COLLECTIONS "ASCII ISO8859-1 ADOBE-STANDARD" +FACE_NAME "Courier Bold" +COPYRIGHT "Copyright (c) 1987 Adobe Systems, Inc., Portions Copyright 1988 Digital Equipment Corp." +COMMENT ***** end of inserted font properties +FONT_ASCENT 8 +FONT_DESCENT 2 +CAP_HEIGHT 6 +X_HEIGHT 5 +ENDPROPERTIES +CHARS 194 +STARTCHAR space +ENCODING 32 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 2 6 1 0 +BITMAP +C0 +C0 +C0 +C0 +00 +C0 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 3 1 3 +BITMAP +A0 +A0 +A0 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +F8 +50 +50 +F8 +50 +50 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 9 0 -1 +BITMAP +20 +78 +C8 +F0 +78 +18 +D8 +F0 +20 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +E0 +A8 +F0 +20 +78 +A8 +38 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +38 +60 +30 +7C +D8 +7C +ENDCHAR +STARTCHAR quoteright +ENCODING 39 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 3 1 4 +BITMAP +60 +40 +80 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 8 1 -1 +BITMAP +20 +40 +C0 +C0 +C0 +C0 +40 +20 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 8 1 -1 +BITMAP +80 +40 +60 +60 +60 +60 +40 +80 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 4 0 3 +BITMAP +20 +F0 +60 +90 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 1 +BITMAP +20 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 3 1 -2 +BITMAP +60 +40 +80 +ENDCHAR +STARTCHAR minus +ENCODING 45 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 1 0 3 +BITMAP +F8 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 2 1 1 0 +BITMAP +C0 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 8 1 -1 +BITMAP +10 +10 +20 +20 +40 +40 +80 +80 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +D8 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +30 +F0 +30 +30 +30 +30 +FC +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +D8 +18 +30 +60 +D8 +F8 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +D8 +18 +70 +18 +D8 +70 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +18 +38 +58 +D8 +FC +18 +18 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +F8 +C0 +F0 +D8 +18 +98 +F0 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +D8 +C0 +F0 +D8 +D8 +70 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +F8 +D8 +18 +30 +30 +60 +60 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +D8 +D8 +70 +D8 +D8 +70 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +70 +D8 +D8 +78 +18 +D8 +70 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 2 4 1 0 +BITMAP +C0 +00 +00 +C0 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 6 0 -2 +BITMAP +60 +00 +00 +60 +40 +80 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 5 0 1 +BITMAP +30 +60 +C0 +60 +30 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 3 0 2 +BITMAP +F0 +00 +F0 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 5 1 1 +BITMAP +C0 +60 +30 +60 +C0 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +98 +30 +60 +00 +60 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +70 +C8 +98 +A8 +A8 +9C +C0 +70 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +F8 +6C +78 +6C +6C +F8 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +D8 +C0 +C0 +D8 +70 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +F8 +6C +6C +6C +6C +F8 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +FC +60 +78 +60 +6C +FC +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +FC +60 +78 +60 +60 +F0 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +D8 +C0 +F8 +D8 +78 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +EE +6C +7C +6C +6C +EE +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 6 0 0 +BITMAP +F0 +60 +60 +60 +60 +F0 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +3C +18 +18 +D8 +D8 +70 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +EC +68 +70 +78 +6C +F6 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +F0 +60 +60 +60 +6C +FC +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +C4 +6C +6C +7C +54 +D4 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +EE +74 +74 +6C +6C +E4 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +F8 +6C +6C +78 +60 +F0 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +70 +D8 +D8 +D8 +D8 +70 +18 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +F8 +6C +6C +78 +6C +F6 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +78 +C8 +F0 +38 +98 +F0 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +FC +B4 +30 +30 +30 +78 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +EE +6C +6C +6C +6C +38 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +EE +6C +28 +38 +38 +10 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +D6 +54 +54 +7C +38 +28 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 0 0 +BITMAP +CC +78 +30 +30 +78 +CC +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +E6 +66 +3C +18 +18 +3C +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +F8 +D8 +30 +60 +D8 +F8 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 8 1 -1 +BITMAP +E0 +C0 +C0 +C0 +C0 +C0 +C0 +E0 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 8 0 -1 +BITMAP +80 +80 +40 +40 +20 +20 +10 +10 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 8 1 -1 +BITMAP +E0 +60 +60 +60 +60 +60 +60 +E0 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 3 0 4 +BITMAP +20 +70 +D8 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 1 0 -2 +BITMAP +FC +ENDCHAR +STARTCHAR quoteleft +ENCODING 96 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 3 1 4 +BITMAP +C0 +40 +20 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +70 +D8 +78 +D8 +FC +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 -1 0 +BITMAP +E0 +60 +78 +6C +6C +6C +F8 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +D8 +C0 +D8 +70 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +38 +18 +78 +D8 +D8 +D8 +7C +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +D8 +F8 +C0 +78 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +38 +60 +F8 +60 +60 +60 +F8 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 -2 +BITMAP +6C +D8 +D8 +D8 +78 +18 +F0 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 -1 0 +BITMAP +E0 +60 +78 +6C +6C +6C +6C +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +30 +00 +F0 +30 +30 +30 +FC +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 9 0 -2 +BITMAP +30 +00 +F0 +30 +30 +30 +30 +30 +E0 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 0 +BITMAP +E0 +60 +6C +78 +70 +78 +6E +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +F0 +30 +30 +30 +30 +30 +FC +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 -1 0 +BITMAP +F8 +7C +54 +54 +54 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 -1 0 +BITMAP +D8 +6C +6C +6C +6C +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +70 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 -1 -2 +BITMAP +F8 +6C +6C +6C +78 +60 +F0 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 -2 +BITMAP +6C +D8 +D8 +D8 +78 +18 +3C +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +DC +74 +60 +60 +F0 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +78 +E0 +78 +1C +F8 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +60 +60 +F8 +60 +60 +6C +38 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 5 -1 0 +BITMAP +EC +6C +6C +6C +3E +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 -1 0 +BITMAP +EC +6C +38 +38 +10 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 5 -1 0 +BITMAP +D6 +54 +7C +3C +28 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +EC +78 +30 +78 +DC +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 -2 +BITMAP +EE +6C +6C +28 +38 +30 +E0 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +F8 +B0 +60 +D8 +F8 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 8 1 -1 +BITMAP +30 +60 +60 +C0 +60 +60 +60 +30 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 1 7 2 -1 +BITMAP +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 8 0 -1 +BITMAP +C0 +60 +60 +30 +60 +60 +60 +C0 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 2 0 3 +BITMAP +68 +B0 +ENDCHAR +STARTCHAR exclamdown +ENCODING 161 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 2 7 1 -2 +BITMAP +C0 +00 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR cent +ENCODING 162 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +78 +C8 +C0 +78 +20 +20 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +38 +68 +20 +F8 +20 +64 +F8 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 1 +BITMAP +88 +70 +50 +70 +88 +ENDCHAR +STARTCHAR yen +ENCODING 165 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +CC +48 +FC +30 +FC +30 +78 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 1 9 2 -2 +BITMAP +80 +80 +80 +80 +00 +80 +80 +80 +80 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 -1 +BITMAP +78 +48 +60 +90 +48 +30 +90 +F0 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 1 1 5 +BITMAP +A0 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +30 +48 +B4 +A4 +B4 +48 +30 +ENDCHAR +STARTCHAR ordfeminine +ENCODING 170 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 5 1 2 +BITMAP +E0 +10 +D0 +00 +F0 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 5 -1 0 +BITMAP +36 +6C +D8 +6C +36 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 3 0 2 +BITMAP +F8 +08 +08 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 1 0 3 +BITMAP +F8 +ENDCHAR +STARTCHAR registered +ENCODING 174 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 0 0 +BITMAP +38 +44 +BA +B2 +AA +44 +38 +ENDCHAR +STARTCHAR macron +ENCODING 175 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 1 0 5 +BITMAP +F0 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 3 0 4 +BITMAP +60 +90 +60 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 6 0 0 +BITMAP +20 +20 +F8 +20 +00 +F8 +ENDCHAR +STARTCHAR twosuperior +ENCODING 178 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 4 1 3 +BITMAP +60 +A0 +40 +E0 +ENDCHAR +STARTCHAR threesuperior +ENCODING 179 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 4 1 3 +BITMAP +E0 +40 +20 +C0 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 2 2 2 5 +BITMAP +40 +80 +ENDCHAR +STARTCHAR mu +ENCODING 181 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 -2 +BITMAP +EC +6C +6C +6C +7E +40 +40 +ENDCHAR +STARTCHAR paragraph +ENCODING 182 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 -1 +BITMAP +7C +A8 +A8 +68 +28 +28 +28 +6C +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 2 1 1 3 +BITMAP +C0 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 3 1 -2 +BITMAP +40 +20 +C0 +ENDCHAR +STARTCHAR onesuperior +ENCODING 185 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 3 4 1 3 +BITMAP +C0 +40 +40 +E0 +ENDCHAR +STARTCHAR ordmasculine +ENCODING 186 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 5 1 2 +BITMAP +60 +90 +60 +00 +F0 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 5 -1 0 +BITMAP +D8 +6C +36 +6C +D8 +ENDCHAR +STARTCHAR onequarter +ENCODING 188 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 0 +BITMAP +C0 +44 +48 +F4 +2C +5E +04 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 0 +BITMAP +C0 +44 +48 +F6 +2A +44 +0E +ENDCHAR +STARTCHAR threequarters +ENCODING 190 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 0 +BITMAP +E0 +44 +28 +D4 +2C +5E +04 +ENDCHAR +STARTCHAR questiondown +ENCODING 191 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 -2 +BITMAP +30 +00 +30 +30 +60 +C8 +70 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +20 +10 +00 +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +10 +20 +00 +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +10 +28 +00 +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR Atilde +ENCODING 195 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +34 +48 +00 +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 8 -1 0 +BITMAP +28 +00 +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR Aring +ENCODING 197 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +30 +48 +30 +78 +38 +28 +7C +6C +EE +ENDCHAR +STARTCHAR AE +ENCODING 198 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +7E +3A +6C +78 +DA +DE +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 -2 +BITMAP +78 +D8 +C0 +C0 +D8 +70 +10 +60 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 9 -1 0 +BITMAP +20 +10 +00 +FC +64 +78 +60 +6C +FC +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 9 -1 0 +BITMAP +10 +20 +00 +FC +64 +78 +60 +6C +FC +ENDCHAR +STARTCHAR Ecircumflex +ENCODING 202 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 9 -1 0 +BITMAP +20 +50 +00 +FC +64 +78 +60 +6C +FC +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 -1 0 +BITMAP +50 +00 +FC +64 +78 +60 +6C +FC +ENDCHAR +STARTCHAR Igrave +ENCODING 204 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 9 0 0 +BITMAP +40 +20 +00 +F0 +60 +60 +60 +60 +F0 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 9 0 0 +BITMAP +20 +40 +00 +F0 +60 +60 +60 +60 +F0 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 9 0 0 +BITMAP +40 +A0 +00 +F0 +60 +60 +60 +60 +F0 +ENDCHAR +STARTCHAR Idieresis +ENCODING 207 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 4 8 0 0 +BITMAP +A0 +00 +F0 +60 +60 +60 +60 +F0 +ENDCHAR +STARTCHAR Eth +ENCODING 208 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +F8 +6C +F4 +64 +6C +F8 +ENDCHAR +STARTCHAR Ntilde +ENCODING 209 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +34 +48 +00 +EE +64 +74 +7C +6C +EC +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +40 +20 +00 +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +40 +00 +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +20 +50 +00 +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR Otilde +ENCODING 213 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +68 +90 +00 +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +50 +00 +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 1 +BITMAP +88 +50 +20 +50 +88 +ENDCHAR +STARTCHAR Oslash +ENCODING 216 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +3A +6C +7C +6C +6C +B8 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +20 +10 +00 +EE +6C +6C +6C +6C +38 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +08 +10 +00 +EE +6C +6C +6C +6C +38 +ENDCHAR +STARTCHAR Ucircumflex +ENCODING 219 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +10 +28 +00 +EE +6C +6C +6C +6C +38 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 8 -1 0 +BITMAP +28 +00 +EE +6C +6C +6C +6C +38 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 0 +BITMAP +04 +08 +00 +E6 +66 +3C +18 +18 +3C +ENDCHAR +STARTCHAR Thorn +ENCODING 222 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 6 -1 0 +BITMAP +E0 +78 +6C +6C +78 +E0 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 6 -1 0 +BITMAP +38 +68 +7C +66 +66 +EC +ENDCHAR +STARTCHAR agrave +ENCODING 224 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +20 +10 +00 +70 +98 +78 +D8 +FC +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +10 +20 +00 +70 +98 +78 +D8 +FC +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +20 +50 +00 +70 +98 +78 +D8 +FC +ENDCHAR +STARTCHAR atilde +ENCODING 227 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +68 +90 +00 +70 +98 +78 +D8 +FC +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +50 +00 +70 +98 +78 +D8 +FC +ENDCHAR +STARTCHAR aring +ENCODING 229 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 9 0 0 +BITMAP +30 +48 +30 +00 +70 +98 +78 +D8 +FC +ENDCHAR +STARTCHAR ae +ENCODING 230 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 -1 0 +BITMAP +6C +B4 +7C +B0 +DC +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 -2 +BITMAP +70 +D8 +C0 +D8 +70 +10 +60 +ENDCHAR +STARTCHAR egrave +ENCODING 232 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +40 +20 +00 +70 +D8 +F8 +C0 +78 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +20 +40 +00 +70 +D8 +F8 +C0 +78 +ENDCHAR +STARTCHAR ecircumflex +ENCODING 234 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +20 +50 +00 +70 +D8 +F8 +C0 +78 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +00 +70 +D8 +F8 +C0 +78 +ENDCHAR +STARTCHAR igrave +ENCODING 236 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +20 +10 +00 +70 +30 +30 +30 +FC +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +10 +20 +00 +70 +30 +30 +30 +FC +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 8 0 0 +BITMAP +20 +50 +00 +70 +30 +30 +30 +FC +ENDCHAR +STARTCHAR idieresis +ENCODING 239 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +50 +00 +70 +30 +30 +30 +FC +ENDCHAR +STARTCHAR eth +ENCODING 240 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +D0 +60 +B0 +78 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR ntilde +ENCODING 241 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 8 -1 0 +BITMAP +34 +48 +00 +D8 +6C +6C +6C +6E +ENDCHAR +STARTCHAR ograve +ENCODING 242 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +40 +20 +00 +70 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +20 +40 +00 +70 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +20 +50 +00 +70 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR otilde +ENCODING 245 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 8 0 0 +BITMAP +68 +90 +00 +70 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +50 +00 +70 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 5 0 1 +BITMAP +20 +00 +F8 +00 +20 +ENDCHAR +STARTCHAR oslash +ENCODING 248 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 5 7 0 -1 +BITMAP +08 +70 +D8 +F8 +D8 +70 +80 +ENDCHAR +STARTCHAR ugrave +ENCODING 249 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 8 -1 0 +BITMAP +20 +10 +00 +EC +6C +6C +6C +3E +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 8 -1 0 +BITMAP +10 +20 +00 +EC +6C +6C +6C +3E +ENDCHAR +STARTCHAR ucircumflex +ENCODING 251 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 8 -1 0 +BITMAP +10 +28 +00 +EC +6C +6C +6C +3E +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 0 +BITMAP +28 +00 +EC +6C +6C +6C +3E +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 10 -1 -2 +BITMAP +08 +10 +00 +EE +6C +6C +28 +38 +30 +F0 +ENDCHAR +STARTCHAR thorn +ENCODING 254 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 9 -1 -2 +BITMAP +E0 +60 +78 +6C +6C +6C +78 +60 +F0 +ENDCHAR +STARTCHAR ydieresis +ENCODING 255 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 9 -1 -2 +BITMAP +28 +00 +EE +6C +6C +28 +38 +30 +F0 +ENDCHAR +STARTCHAR trademark +ENCODING 8482 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 4 -1 3 +BITMAP +F6 +5E +5A +5A +ENDCHAR +STARTCHAR perthousand +ENCODING 8240 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +60 +A8 +D0 +60 +6C +B4 +D8 +ENDCHAR +STARTCHAR oe +ENCODING 339 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 6 5 0 0 +BITMAP +6C +B4 +BC +B0 +6C +ENDCHAR +STARTCHAR fl +ENCODING 64258 +SWIDTH 600 0 +DWIDTH 6 0 +BBX 7 7 -1 0 +BITMAP +3C +6C +FC +6C +6C +6C +FE +ENDCHAR +ENDFONT diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pbm b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pbm new file mode 100755 index 0000000000000000000000000000000000000000..aedce1a3117bc80edcc8edb5ec92ece84639a346 GIT binary patch literal 1273 zcmYk5e@s(X6vxlwcCS?m)FA;WunHK-h+0JLlwU<)$^=ALGhr@!fS|@8I>IQMSQ>flgW=L;}wQD6p*-~ZbHkd!pQhF+*+XR-D8N^`QzrClkYj7b8_!J z8XvdGVWIm%0C0%j9Jw6;d2#+?f;+%}b?;sP9vdAQu27zbR4Buc6*+LP#mBZXpi4YD zbD`Ffc`}sN+eU44M!@LUg$ZmLs|lqiezIj2c^K<;MXlX+*`1@4o;M%rX^psKXiyb+ z91n&ZnR#qYd#vUokx0@L;nXiL@GJOy;*#jNBCbRr;m{cWhqD9wj*xV0=g@LZvcj0~ z?n3{DzFo%y?{t0taJZ;FVOZ9zny$3yoq1{Gp$9i`j@7(ucXjOjaf52{pJz_xHHY4H z>3VHxlrDj|7;&1k_cV(Fw(69n1BH*;uKrQJsI59yDUkjTXIJ%hG5=SPgbYcVgssp%O&Q#7fQmZ6%rFCxBXP0-_)gOY z?*ohjlq#Ydrq_+!$?svOzI@i;e4W8y68V5;fBM~4153kUVbr}93px$Ly1Hw2Y_p21 zp2zW$nL83N0N9zmlB814zTM}DoR5}};4YM8+Yh?zi+v&9{_QjFfz^PB1P~c6qY`WJ z2f?tJz7f+W5WAjg0D;`rQXrY|YuYhf`kA3c)0pOZG3h+v#?5MZAmCuLxMb>B9i^bC zr!zQide>hbB)N|C1*69XmbI`aaJzMnDNL%Zmr1=SirOPhKW||_&L7YG!LA#9?t`UG7G0hW`@PWwDq!A?Ng|?SXLlA+n7f<2Zu6g{)jX68Z{sz->>M< zY=qPaU7aJTeBT3uwxGrJXGf=fBf_n>siesL1@O7_U@RWwcW_2@RnVjM zy}sH@;cLet{ne)hDa$uq_n2;@V0B=f`HRmDdX}#{d=+?lF**H2XF0y(fmH#g*nk|w5 literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pil b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pil new file mode 100755 index 0000000000000000000000000000000000000000..28982c0fa7339e8c3bbb2bbdd5b08663bfcbcc49 GIT binary patch literal 5143 zcmeH~-;0(-6vxlZuDU&fmSz%)uox(YX@)Gih%1y(N-8XBD5l^KSTKziEfiVASWpoa z6hVbTL=?q~wHv)qFT_AgP(!=0AcU}s^}@(q*Y)XhW}f#j@B9N1?830`_w$}P=ggU( z@6wMKZ`|@lXVDt|-k;f8e7K-}K_NqbLlyWhD==Jxm!-HW3CAa8u6!X4`k&SSsjT?br774+*%#PIzJ6U^tC-rU78xfal$9khl#QcJfW#R6(pbJki%hCw zIASysV-l>nicw?Duy-u3_8mlvOr?kV6OF<6rt)z*(PE5}Z#`OMrj6qzc7te<*;a!x zjCD4w#aJ9~3#>JXtK(>;wZ*Z8x@fF6+QNjX-9p-;j4gsKO_=swN?V>V?Yo?|Dr2i) zYcsYMwjpC1U>zCjfNiOmqwYHATWDWe{gipMNM|)iTGK{q+6nu*s;QI%uvci2o%D!x zjoU7I=UuRG&0jyC99m>wtZ7&q>SG`6aI~}aau{~Z`bK}pU?(%Xldw}6I|VzN zv9qv?nZJv$ONpK4a*1{&v1<%kx&kryF6u0u+bSC z4SOrHkTdpZaT7DUiLl9u9pgZYn_97IpQFXSo9s8v1GKmq6|33JfXzzmhLtbT;##UT z$wxeUw77Z6p61L!i)*Xdv7R;OHrm3tcBw%)!_eXu+ddlLTh-#0*&5gNtXkZP%x(p2 zbz-M|SJT!dcADQh*e08|7I^o^>nkNwUUuFFb+u+8U30wHNlc z*@b%_Elzij`qOu!?#q5!S=o7*#wbNMNBT~5x>@|NDu%vA8_NN-_@?U2uKc0JkE;BI zy;{CPiyu?B&sB?m+j7x;`3fz*_Qn+6KI~Pr_{m9(5kZTemW)kvnFfC^vE%+gi=Sop zM|hW@#kVl>Skv%6MT?(Xy|2Q(Mclctc@@*TXbkQnKcCXjmvcOvr)cr%dy;n(TKr+)b1Iy`09=_ z#vSE5t$uocc(nL$tnYIjBU*fy-CL1$!MZcn4Lgvr1F$2;`hq|1BYz^+gl<_Co#>xrj6LmpGu8`x zma%8BK4WogeXv0rTiE+(Y4EmQLY>jlpu3zp*YZP4L-iZc7{3u4#>W`O#=|BV3-ill z6|A5!sXuffqhxHwLS4{>yvZ-m7&qjCF8GZZ7}-RB6JX8JpRs1xl#ES*P0!eL*aybK z{y-NpN8Zr5VSe@h9N2uzFTADDg?uFXf>yh*KhTAIVtqrM(S!=E%B!@w!wBpJLWC=+X35cePhnMVci+) zhV9STe%PUm9fBP-7RPoJcHD9a>knPXcUDtf2M%4x>1b#9orax{{*0Z6^<=CEcG+00 j!DZO>I)5Hr$d9Zp>We?k&!Y?Z+2&mPdUPSb$k=}Y_2lj% literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.gif b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.gif new file mode 100755 index 0000000000000000000000000000000000000000..64a9b93c89b6a22d4760777b34790a57344da9cd GIT binary patch literal 16336 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 JABO>={vU+{Ez$r0 literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.jpg b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.jpg new file mode 100755 index 0000000000000000000000000000000000000000..ed01c4e6769b3f01b13d78c6ee4e99e123d36464 GIT binary patch literal 4788 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 su#|>TAcLF_$&DnbW):V1EW/>e7Eޘkqrdpom|uwphp]݋Yr[XF[L`LhOgOhPmUgRiQmPoWsR{WxTxT~^Ё[[Wρ]ρZӄ]˅n~\ԁZҁV҃]؁VӃ^~VЁ[ςa҆e҂[ց^}VyU~Ẃc~YӁX|\́Z|[~^υgՀYЂ^σ_΂aЁ\}XЀ[Ђb}Z̀cЁb~W}Ý`{Z{bybnZlSh\wlψnٓquwzz~ndhߘgޝjcoޚpۛmޘfۖiٗo֓kޝmˁ٢ݟ֕ץjdMkXvWy[|Tx`zZt]k}_Ҁ`ԋg^RgIYW'7X/DZ-8a1:f6=hfzkjvmrmwijo`ٍ_pMYM\J`LjQlQiMeIeMfPjPgNrQwPxT{\ǁ]YyR͂]΁ZЃÝaȀĝdσaӁYтZцfֆc}X{UӂaуcЅl{V}TxS|\{^^}_|\|W|Xр^^ԁ]́`ρ]чez]ɀZ΄bρ\}Y}]W}\^Ѕ`}]w`{bnWpZlZsbσhהyݜ|w{ysޟrrnfgnkߝvۜvژlڕcהfّl֔ky՘ٟޤˌnNkTuTuUz\xdxVx]|`ȃ`ъgYIT/DW-D^3D\*7e5Bj5A^2Y-?Z,>e6Ba.:`3Bd4=Z,6hgxzyxoirndlja؈\fKSDZGYJpedLePeQeQbPcHkMrRx\x[}_vWxW{WȀf{[yU|c}\|\{W~Ỳ^c|X}Wуbс^υmԁczW}[zT~YzPtRySvVxQsTyV~[a̓f́dρc~Y~`̀dρd|VˁdzZUˁ]{WxVx_uYu^t^lVr^̂iԋlԓzٕsܞ{xޟwݚsrtߚhgߙlޚkߙfߙmݘlڕkِjڏ`׌]֍_ˈڤާޥƅdOkRqYoS|`ʃaaQ[.>W-AW*:\3C`3B`4@`7Ib,:_-:Z);ljyt|gqfwefkk]ۈYjQRE`O`LcOjUbJbIfMfOhRkSw^xSvSY{Zc|[ʂg{WÝeщsZh}\Ѕg~YҀbԃdҁ]|Vфc~U~]Y~bzfɃuȫȨyhvX|UvTz\z]y[ǀac]͂b|[^΁d}Pʂdσà_y`w]nToRk\s_ƁkӊkՒtؘyۘtܖmޝxߜ|ܛsjߜqmhcߝqߙhdٕo֌aڐdڎ]ُcԐmmЋݦ߫י՚bjSkSo]}[^OY+:U+;U)?`1D\1Bk>Jb3Ci7H_/;_/;]1?rnprua[ޓbmemsshߋ\oR[PWG_LdPeOhQeOjNeMkMsUpRvSxUxV}W}VV~]ρ^~Z]҅hYyZҁb{]τd[ЄbՄX}V}eˑ̟ΡղѴضƴԼԯջs[sYʁgyY{Xǃl~g΂a}]{XЁi~a~_~`xRw\s\rckWpa|^؊gבn֑s׏nܗrۖqݙspܕhmޖilegۖlߖgۏ^֏a׏fڏ\֌]ԍgՑdă٨ޤˉkQpW|`\LT%8X1HX0D`0>c7Ab6@a8Gf>La-:[):c/b2;i;H_-8d3?^4F\+8c1:\*6],9gruqYفN{LيZhdmolg܄VkOM@UG[FaM_H_IdMbLgOfOkRpQtUzTyRyZzV~[~]zYX|[ҁ\\}Z{^фkɄq͕x_ĉqƏz~Ȕ˔|͔tɓŐʑv͞Ӣ{ղׯҺҷլټջȥİoUsZ|ce{_x_ЀcwXw]y[oSrXpQiSm]oS`׌iٓlܕw֒oۓoڔs֕w٘uܝmܔhܔiڒhܗkّb܎`ݑhڑm؍g،aَ`َdٍ^Ջ_х^uکާڗxXX,AQ';U&8W0Ae9Ce1>h8G`3<[2E`/Ag9Fa8L[,=_.:jhkgYnBlKۇ[fsmnknXoOYKLHVK\SngdJaLaIfKhTnUqPvRv[|\zZyPzQzVЀ_сiс_̀ayWӇk֕qʐuj„n~mvhj|srƐ̤ǜǬѦұɧԩװѶܷįůjZlRpVzcy]zas[zav^t]sUp_lYfNpZ}j׈gܒnޔmُjۓj۔kۓuۓnܗokٍaۍ`׏fܒfېfܑaڑh׍e،eڍ]ێZ܍]ڏ_։_؎dɊܠ孾pLT-AY-EX/?a2@j8Gc4Ei=K`.?X+@d3Ac5Fb1A^-:g29roa_xIRAqKی\erjmm_܌^lIJDTIVG]K]NaJjNfOfPjUoZsZsLrSrRuR{]}`vY|\}azWz\ymRzevUzg|hzf|ąlt‹włeńkͥǟԡyӰ׷ۺԽڹ޿ִŸٿǫlYkTubvWs]uWs[sVpTpWjPh^lU`،mߔmܔnݓjܐmڒkגqےoݓlޙoېdهZ`ތ\ۗlލ]َ`ڍiՊ`ێbՌdؒjّj،`؏_mۥwK&=U*=W*:Z.?j;Gc5Ag4@\,:T(=^->^/:V+7_.;f6AW'4uhڄR^EJDqMۉVmmiuel߇YjOF>M?[NZKbRaNaOeReMdIjOqZrStZuSxWw_v[π^b}[{ZyWrPoZv\u\pxmzd}lÈvt̑xĉtɉkNJq˗~ӣ}ӲҳԦ|ӸֶܾٷབྷڿãźìǺȰӽfTjYiRoUpXr\r_p[iYjNaPoY_ߎcnݘtiۏm֎jӎi֏l܍iڔqߓfڏfޏdސcݐaۑiٍeސc،cُeܐhݏ_܎`܎aޔjޕfˆuU';V*@T,CZ.d3>f4>g6A_1>Q(;e;Ga1?U,?c5En@LkNHULWKYJfX~bܐllohmjӇji\f19^0EaXwZۋfnޑlߎbߏc_ݍ`ߎhfmxAET%9\3AY*Y,@n:BY.;X5D].<]4EmHYR`ytȑwјunԞy[JWNYH^QVCZPjNڊ[ftxv}cوjjPNJKFWIaN`QdRcN`HdOiYgRq[sSsPt[wZ{_uZ{XsXnTnUpWrWoRn`}tpuygye^Ҋfǐ|ǎqёnŇlϏjˑx΋tΑzݲĕŦʪʰʴͼϰŨþ̼̯Ǧıǚj\JAM?YM_L}[܍hznlnj؈fdKk08R)dQԈkݑjdaَhތ`ލhihftRX+j5\0Di9OjeȑwƍsɒuО֥٣~UG[H^N]LVH]UudڈUio}zpa݄UhTLFKA\QaKe]hZhMcObNaMpWmTnPwTvWoXrP|W^JaMkQsWlUjVtXmYulx_~dȏnǍ{ΆkʉkҔxȆlǀpÅhχg͉brܲ޿ƴƵݺùİ®пѽŰ̼Ͷϸʱкпt;SIvX܍grlouݗuՆciUw:?]-=_.;[(7s45aJ{SՎkڊ\ކU܌`iyLW)9V+<_0Aa2=f0=c6i5@c7AP(?}KU̖ĊpǓ{ӡzӟvԢ}أyYHXIZO[NXFQEjOؑkdjrsvi܋\nVOFOKVH]NaK`GeOaPgTm]mSmYoRtYmPk^Ȁ`TiYfUsYnSsTlTu^vZ}Wi̅lυeЎiƂh΀]щnďyyhn^zpߵ⽙߼ผݯշǰŷɽ۽ʶȷʾ̹κֿθнȚXPJFpL܈afkߗqguևdgRx>K`.C](4^,6S".p=EϿչپӿؓob/AU*<[.@^1=f1=h9Ff;Gh9K`8H^-8^0Gh8Hb1;[/=d7KyїyŇpÍwԣӠxӟ|ҟ՞yXK\LYK[O]RUFkOՌhlww䦈mc؉^fHEBPGVFXG^J^NbL]IeWmVeOjOmSpOeOϊ`efUiPmUq]|UmWsW{jiZʁi΁_ώn~nЈap̆jxWyfrfʙܲݯ亓جׯƱԯţŰīIJ˸¦ŷ̻ܿòн϶ȼ̹úGAnWԇlqlhskֈhkSr;A[)7Z'8U'8Q.AγմնпԱL&AQ,CZ-Ah3@d3?gAKa2?`1?d5Cb4Dc4Gja3>d1=V.A_0[2Dd5Cc0:_/9\.=d6Jm8Cf3^.8[,=d2Cf4?W*6Z-BuӛȏzЙףzҠ՝|֞јzӝ֛yјzҙvdM`FcOdPaH`IqHߌ]ߘipsssmߎ]nKOCMCYKbTbKaG`IhP`IeLkOlLlRYKڥ᥄zThQmVbMaPqQqZ_YyY|cfU{[ubД֚ښnғqЗxxl۠ئ؟رۤӢפ׼޸Ӕ{ۻ۩ү࿪ڲױܼ׮߿۬װ׵߽ػԷپĶ׼įĸӵѼƽرߓ`iïԫֵױԿϴȴʸDZʷιͼѿ޺L'@W2G\2Da2A^0>]+:Z-:d3@c8Io>N^cϓ|Д~Βx֞}֠֠}֞~ӟ~֠{њ}̖јzіxgNdPgQgKaH`HqMۊ_lgkuushoQJc3A^->k>Pj7?a3].Aa5Aa2?[)7a0;Y-=Pay|ӗ{Ғr͗Ԟ֠ӢٟաҜҞҝ~ѝԞ}ԛs֚qbI_LWHaLbMbLpKۊXfvuuvi`jMMENG\FdSdTbI^IbOaM`FhMfF`GeM{{cݒjٌe}Xk\]NhQkMˌqՍkρ`Їgϋc~f֏q֐n̑ϏvԜuʘۢx֕~Ӓw٦ڞxܚۭڟ~إ۠Օ}ݱۣ՝f̞׫֮٨ܯث۸دէҬԭմʠѧʥбܺIJαȶñܾİűȲȵ̺ͼͺϻșׯ}kҡܷ˹N%9W)5c8D^0:U+:f6>\-:n?R`hՕxԗ˓؞գӟ~֚wӝҝ՞zҙx՜rМ~ҟ{Ӝ~њ{^G]I]J^H[HaOnLߍ[fuppqkekRSKRNXK`K\L^J^HcMaDgNdHcM]I}Q}ޛzڑqyVчfv[cIdN׋iՎpԇhʃgǃdɂfוxևa͎zՑjʋsАxԖxҐuӔ|ܡyٙ~ٕ֝t՞ћѢۥ۫юpŕ׬ۭۡӟٱخӤק֢֨ӜǗʟݭ⼋è͵Ǭî­ŰŪȵʺ̸˵ʹҺʛШĉt٩͗иS.@Y1K[1=a8@];MY*;c2@\/EyG\v֚|ΐ{ΖӞ}ӠОқњxӞӡ՞Л}ϝwΚyΙv՚w]FcO_JbNaJfIvVߌ\mtsx{hkqRK@J@XG_NfRaK]D`HcMbMcL`FWG^~s]RڂS_uObGэi֊j˃hǁd|`~kٓoυcזuВv|pĉ~Ӗyьjؔuڡڙ~ԕɏϝuvX^˖ך{ݣ٢ؤ|ќݥ؛ҠӢТЫј{ėڹٲ̳ãڻոۿůDzƯ˷̺˺ʴͽǴΥŌzϚjl`بI$=V+?a8J]3AX.?iBPc1=d6Jae֘yє̓yҝנؠy՞Ӛzњtԛ~՞}ӜК|П{Ӝ}НԜs]JbNcJdPcLhQuRZospxluZkKKAPGZFbS_K^F_F`LfN_GbH]FTFؒNÇnTY[^ۈVoa΁ax_̃iˑ|ňuڎkъqҏl{fDŽn͌vЊ`ԖyҔ}ӖSZ}mgUYjj_aʐ̙\ct٠ة‰~ררxh7LʛƎڪڻdzȪƭڽİƲȳưȴ͸ɲ̹йҿһҧƙzQJcWտoL"6Y-?`18[(7_0Cl9?\1Ei7Ltٜw̒ϗ~ԟ{٢|֠ӚzНњ|Ԝzҟ|Ӝ~Ԛ|Лwѝ|ϜΜ|dTcTdSbLaPeLwRWisqw|ncqRLCKATEbQ^HcLdOeLhOaGbJ`BVDPËe\YcXo^t\{er{oȉuЇcЇi͏u}n΂eɇtʆmύtהzӑsq͊qxmjk]hZeoE\֦أqE_\krqai_2KlEb^nR,I̜彙СԵŪܾƬñõŭɺɸʲɶη̻˵θϳΞXDTH\NxkڹT,AT)<_/=a.9X)7f3=^/:X0FdgҖЕ͔֢ӟ֝Ӟ՟zКwќ|Ӛ{Ϝ|ҜzΛЛ~̙ЙyԚy^KgQbQ_MeMmEtL[brlspgisOPHK@TJ]JdP_GcMfRaL`JbHdMXDcExjjVً\[vaq_tYÀljaȂj͉nȄnҎqʀdȄm҈iȅlȉwӑzʎemĉ~q{dityegpYpmHed;\c;ZtNoX.?P'AS4VL,NԘtӥȸȫèìūįDZȴȯɺмͻϿȫ|PRF`RZI`Pq_ݴѲD5R-@[0Bb3Ba3>V+8i9CY.Ve^3Id]5M?1E&Bͳu̱ũĦƪ©ĩݾåñ׿ۿī°͸ɬһͮ\MRGTEVH\Niaʗ湘˨a03U'=X,=c3A`.=^-?c2_1?`4A`5Cd3>_,;[-SfA[U_c@RZ-EqFYX+@oFjM\a1Ec8UsgQ'Ata@4_lٝlnݴǦٷԱջ׵ѵЯմظ°Ĥг~PSpBJv~xަyvr鷒͟a.1U';\-8_.;l8Ab7?a1;^-7d4>`>O\7KpmғsϒxӞף~֥ԤӦ֣ԣҞҟѝΟ͝Μ͝˛ʙ}Ζt͖ykViWfRdKdGfGrNVjrotuyauPNFGCWH\IcObJ_KbMaJeM`KfLeF`FZLܱڥ䭄qYIӌo̅oʉ{b^zh{bzny`σkՊoϊv|h:Gc4Ad5D]+6f28X0Ae:N|Ǐxʑ|֤|ڧ~ק֤بסѣҢӡ~Ѡ͜ҝΜ̙͛͟͝ΘjSmWiPgUbL\CoNۊ^aw|son`uRJ?NGNH[J_NaJgQaKbM^GcPiLhNiQbLWKݵ}谀}wS{_͆prf{c΀d~jvcrq̇w|vpfg[ii>XZlY.EQ&AoB`huP$8a2P^1=[.@a/Db5Nf>TW-NpQWn~⼒Ῡª׺ѵϱԷԮѨ׷պչֻ׵Ī竉SRooRTezkvǓ婁 ⷃV,<\.9U%4b3?h5@k9Ap?G^1;U)8\+>c6Bb8NXXsqК֨٨ע~ԥբ֢ԣ֡ўңҢНќ|Ϛ͝}ʘ{Ǖ~˖|jWjViRcMgS_NiM֊`mypuqkgxYKCF[/CqH_vkm~ӣ٦գףץաԣ֣ա|Ӡϛ|ќyџ~͝Нx̝˘zϛ|ȕqXkVkS_J`KZFgJڃUgxkxyvdwVIDHDXJUGeObP_L_J^MbLcLjPqXyeoS_OЂPٔčwwd|d_T{hzg}yȇpτkqr̃nqusAVf;Qh9SaqCZ\2KZ3PpB^evK_X-?]/@`4FZ.>W1D\4Mh|}XjҪխֵҰ̩ѴϮӰײаͪĥ뿩ĭŮġwaHHSmvP_ÊzSBT$5S):^/@f;Ji8?m;Bi6Ba0W+AU]plјo4AY,<[/i4;rDRe8Dj4@]-;_0>`/=e5D_.Ftnv}q–ӤդץԤզ}Πՠѣ֥ӣ}ҡҟzӣџѠѝzНИq͗vjVhRbOfUdQ]JjOه_j{uzvuhuQRJK=OC]N_JbQeNfW_KiSeNlRnTsRmUgIcK͍֚gSgNoZwmp]΄qmY{g{hhnR%;[oZ.>W)@].B]5OwPlqHZb8SSo`9\|Pi~W{O);F!7e_ĞӤ׮ڿҪ΢ɟѵհߢ笉컞ǪäȩǨ˭϶ͳ촏lJJE\/APQwDQ͝]0HY3E]-:c1:f1>f6Ej8Bh3;g6F\'4f19X1?uHTuuƐx˛}ēv˘Ԥ֩ӥӤ|Ң~գҤբԠћyРҠ~ϝ{͟~Ιz̖wʔ{cNlXiVdNbO[EcN؆^hrz|srdzZPJQITD]MeOkUl[cJhOhYfMgT{RrXvTlN`P贃jPwimQh^͂dw\PSxHQIQ[_\.D[nU*Ea2>_0A`4Af69Z-EhiĐo|iΘwўʗyė˓~˘}͜ϞѢ}ӟzԣСңРԤ~М{ћzҜwҝ}Θ~̕}lTgQeOgRgT[EfHԅajzwusnepWSMSJUE^ScOfUjWgQbJaQcNԆbrQqQtWsSmZS伕tPoPr\}hȄyׅkg[Y[`4GT&:f9Wo@K[.Ik>QlAUa7KX)AqG_g7SfX{[,?k@_C9Y]Єl̒ܪۭ׫ѦؾӳѬ̦ؑn訄䮑ĪɹʲͱһѷӺɨzWBa.;Q":vJRϤ]6IfI`i8Di:Fh=Fl>Gr^/X-;RWȓrɘ~צ|ңѣϜ}ɜ~̜{ɗ}ɛs~ŒuǑuǓxʚ~͟Ϛyʙ|Ν~Λ֛{ϔwfPcQfQcN]H[BdK؊ag}쫀ꮆtuuvWTLOHYR_OgSgZeSmXeSgRlSpZsWpTkIoLfGӌfʁQtQXՌxlmr8DXrO$Ck?TmIrf;VU(>l=VSgZ(;a7Mf?Td:L_1EoEl}RuH7a}ڠpsbzۜzۯֹں׷˧Νܝែ䥂鮑笄賙붛Ůɵǩ˪ͯϴҴѮ︗tTPFU,BR(APZ٭HO_,:d=Ok<@m?Ji?Ja5]3AnASsmŒ}ԣsئԢНuΠԤҦӥϡ͞|ǘvwsÓz|ēДqɚ|dQfP_LdPeM`F_KՂYrw{뱂xplwUPJRNZO`ShQfV`OcM_QgYkQrPuWuYwYٖpݥ[S#4U&:mgy]qRb.FpFRN$@\4MqS&4h8H]0Ch?UV)=[,C`3Kf6IX/Bi8T[wQ(?yr_Pŷۥܹ̙ӤܿͯG@eQtc|hؓ䥍뵘뵒걎벑췚áᄀšȦɨͰ̪뮈oRt7?Y&3P%9_tݹ^Zn>Gc8Ji=LrIRh[2J]a|jȗzѢҝzԞyϝ}Ϟ|ϝzӠў~С̚z͛͞vǙĕy|v‰qiTfPfPaF`C^K\HՄ[wv{o{pkv^RNOHRK]LeTbKbPeTjMfHkRsXoUrSz[ooVo=G[(AڃPUISRb5LT.S}YzoS'=g;XmLZc:NW0AV'9P%8lnMr[T)D`:EĀeʛݪܹཛྷ͚ػíɑoֈkޖzהx}eKB=;XMҍt鯐紘箌쯊¨ęß鹏f^UH@C=X'6O*AsCU٬ÌwY-?}HLm;Cn>I\4C]0vKgS(?^7HyL_P!0\)6U*ClqX1=E 8Ҟsz߲ƭҨֱƩlO~_Ҋnӊn{^ӉldXVGYNw]壁骊ꮍ칚춙궏mY_[h^lVrNZCs:@Q(sHUÙp_yDLf;@me1;c0;S&>RXr̘|֤}ՠ~ӜϚv՜r͜zјvΞΝxϝ|ИrϘzʘwʜxə}ʛʚƖ~zÕ}`J_P^Q\LZLQCXIт\jzvnv{ezTMEOGTETE^JcJ_H_JaJ\HaZӥfސ[uizb2AIHH"CxY|NmfeA:|Wtg>R}^rV,EL#6U)BxS&:]'7K);K#:ɕg۹ܤ|߷̷޿۽Jh.5l29h5Ac-8rNano[-9\(9V=ׇ`Ղc܍pu꧄レ̰ʥuXf4A_2CGHv=@d/=kJQ(AmdŠnvՠҞvМϗxϗyΗtәnԢӞϛyΝ}ЙwƖxΜ|Ȗv˖{ȚǙ}|z{x{dM\K]F`LYGPES?ׂVgol~]yOHCNFYIePaI^HgPdJ\EWH~Ić~fܑkd][̐sGOK*EoPtb=V}_L&@nHlbpQ)=Z->]7Mf>HW,AV(6d2C^.>Z,@b8WQ&Eul`ܤtීڸȶŠPIN?i6e19j7Ce1a-5h/7f6AW*RX}t̗ћ}ӞҞ}ΘoМ{ϙx͖~Ҝ}њuʗxϚ|Ηy̗ʔnÔyÒwyz|ru~w~ɣdLdQaK`O[MM@QF|Optyz{zkyRVGYLaJhMjSnThOC5n4BUiӯ캎^3JO&M`/:g6EM#4W8[̛{ԖtٹƺeO{]}j׋oʅtZOn`Œκ綋ܑmpX}Wx\Ձcލs驈ʰYKǀty״ҏD<{>Eq5>Z/Bb3EW_Z`ˢ}JTSW`1>[-8[0>j9?\/Bf_kÌwԞΛ|ϜzϗwЛ{ӘsϗyϙwИvћs̘v˘zΕw̒sĕÔ{{qqxyϢڭ}෌hPhUfOXCVHRGK<ՁUhv}﹂voӀUVJYIdKiLpTqSӛxV'9ni֙{ƊƓtOa`/b4EtBG|hčpϝ|ѝz͚ЗxǗ{ϖ|ϗuʝʗy͖t̜͗wʓmƌvvzutx֧ݴ丄潄辉iVbPaNXKUFMAH:|Sjxv|wmՁOSCS@`JdHnOiNՊTƋȨxERmE[~RcT';[3OZ6\ĜpZ5R`:NlEc[jva4?W-CX);`2@[-:^.?X+9G0J":ӛsŌzڦٱȱ\GcHӄgيtݒy{ܑqݏp۔yݐoԉtؔ|ەzܟڔ؜{b؉pׁdقm祍һҹڪڕ{Ӈpςo}dgR_J[D|?@W(9b2BOUNXbktAAl8?X&6pDEY)4KPËsuϜzѡ˔tΘy͖yʕ|ʖx˓r͗zȓw͖xȓrʓwȒwǑtwluvϜy߳缅亄齀鼀aM^HWIPGREC=D;|UctwaQVJZG^EiLnQmPoWיxpgjgc8Qfc>VP.Ni:Y\|uiF^uPoT+H`7TuRunNbwpm_0@X,Dܹjv\__1;U%4e:?T(=f\{u͜Н}ϛx͖pΘw˗|͘xʕw̕yɕwǔȕwvď}opجŒ鿄羇~꽂YEWJTJODM?A9EBzNnuwu{riҁ]VDP?YAcFpYoXufk˪iC]`9Qe9S{MnhXL"9Q+F^8Z{zWgDg{i@Xp@JY+>`3BX,9T,CU,CU(;|RÌ㴌ѻD;jNxZҀh܋rᖁ}檋奇豖䫒嬒魑橐⭔ޜ~ܓ~ێoډjbz[}˷⸝ݨݚ}ݍmۆj~cz`dMo/5f-6j06zBFm:C߯ux{IIpAOW)8c1:_->ziqɏtӟxΝϖv̕u˚ȕ|ȗ|ɒxŒx˔vƒuÐru}uvuتčŃ}꿄}VHWLOIROK>~>;A?zWc諁}w|mӀYPGN?YDkfщkŀotBK`Rh?Xc7OtQwvNmtQuaT*D[6Ih?[rsLTK'Fzuh]4G\.>W/FT.DO*Cvplٴ¬ϱT%7MAoKy`ׄgوir{处讓벓笔簕簌鲗孌ᥐۓxޕy܌u܅a܃iߑvʶ㸛ऎកܐyچvՄk}^gMt>Gm;Eh4Bm7Bc/Dⴕf6Bg4:`5@`/9h4?Žuuјyӡz͞zʙzɗɓv͕sȔxÔwĒxÑzwđtÑytpqեzʼnć€|迅’ƘUJOEIDOIJCy;6>?{Uptvy{ﰁ_|QXHQG]HnamVo`ytxMaXv^|rF\^6R`^6Um]8UY0HZ.E[/HV)@_4LyIWi:Me5>P'Dlcic\/BY4JS)AN&7[2GÃfÄtὣM'Cr=Cl9?k5?c-?ڬ˨a/:[)7e5?_1=VNɓn‡oԠzРzΘtɜƖw˗~ɒvĖ~ǑuɓÏyyusΞ纃|}Ą‚鿎Ɛɞ˩JGFBOKJDC`3B_3C[0DX5I\.C~C?p:EqcXzuN+DH 6M!9csdĩĮvP(;k17UHtRx\ڂh݅aqzm袀겒鰄筑筋{㟃ݎhތhۉe{Y݀Xې|麧㻦ުߞڐrىoۄjvZTGg3>g1;m3R&6uADr9o3:o/3vXj{x{we~OQAMCZGdbzWisGh\|^d8Zbu^{\Y5@J$8W-Ha2CV.Da2H^o[ZznuZt;^,|?=i.;i/6wYlux{c}WPAKI|ofljuluE`[s\vNizPoa:^yX5Y_^0Qi>SY0LkDRS*EBMD}\rt}|{oՃ`TGMCYGcIoajqan^u}xxMmI&N__yUzyW}}b~L#;f`dojtYsmJ$9S)dXYCoRx[~[ځ`ކkދqpruw|堁{ttoڎz܀[߀ZցfՎ߾缡䦆ݛՑ}ӄmxXX,;X1GU-D]3AIHs=Aj6ҠzTQcґbʔrԜu̝˜~͘}ΝŐwÔwȖȒoʓp~rxz̗s뼁z{ȏќќΘ͚ѝӧҧҭӧԱLAI@E?I@|>=GCh`ьsz詁jx~tmԃ\VHSFTE\Kӗ|mPk|Rll>M[0B[0Ra9Ng@awQseyVnyk>X`rRYL%5M'@Ɛ~ϴͬZNuem?9W(<^+9h3>k:@mmL|`؁\~]߅gfmߊmblqޕwsvܓuݓoږyࠃ宔ͳ婒ξ绖ܜڌpΉvofZ->V0FW.?a5Jj=KPIJB{DAe2>X'>IH^Vˈtݜvz뱄~|o؃SSFFEsn^ZiRjyqDWkg:I_2JaAVw\sQe]yhGhuMrqV2Rw@)EqCRņyϼȫ¯O=\PȵT/FT)>k`e2?m9>f4>UM]*3a*:VKSJ`CyQ}WXރ`^gg܆erݏo݈`܋k܏oِtݑrtjly砇夈Ջj΄rΉvY/FX.>a6DX/C_3@v>CPHF>}ABd/8X&<zub|`Ր_̔lϚuϚu̚x˛~Ǖ}ƓvɘxÓ|wƑtƓ{tvooڦtzʈѠӛњӤЙϠҤѪծӫԬѪm5=q78x<V,?PH]*7b.:n=>{B=a+4_/>FCNF`IwW؁]ڄa|R߃Xއchik]=YAqF|MyOuNqGjEnO|K؉gC8jNlTےu|fT/JW-AX,?W-;b8Fh3>x<:ROk2=zC@\&8e`̓Zّ\͐o͚uΚu͜}ɕyǕ{Ɣv’}yŔvur’t‘ysiުsƅΔӤԢѝљНџҥӧձԮԯ٪j:Eo:@z<;|A@z?DYTfWЎo}ux{{j҅aTQ˗NGe`ĉSd}Tq]7LkCW\9RnF`{T`=[c|Xuj^}uaB^|Rnݑeۄjټj^thsW/=_-7V3Bi58_,9i39i68p>Cx=@d.Bw8:VQ[CpRwTzPրW܃`݇`fnsفb؁[sWnLvW|X݁ezZ}n吀囑݅vԋu܊n֌j\0FV3I`7CV-Fa2=zFIk7?LLRIe0@a]X+;PPԈVَ`̗|МvΘtɗuǕxɗ|}Ó•~x|vnvy̐ӘңјНњӢҤҦԯ֧լթԪh8Dp7<{@@A>x:?SPbRΊnrꮌsrzp}}vǖHDQMƍgXcla1MnASO&8P'D|Piw]`EcV3Tlk^z\7YbcsYÝ[NɌyټP-C[9Kc5CW,=\-8s<=a.;i58t?CHGd0;D?RIGAgKtUuQ|S~Tڄfۋjksm܂Z؀\ނXy]kꝆﱔقwՐx܌i[JY.GX.?e4@Z):d5l9>h6A~LI_4FVSOH}EE`DnNrPwP`Ӂd؁eއbދkp܋i܆a]|Tރab|꓁upԕܗyʆmW*@U/FV-A_0C\,=b-4f17E=w=CRLDC^Yh8CuFTΝ֡ؓfʚv̞yʛz͛xȖx˛|Ț}ĕyy~~srr{c}֣֢ԡћ֨֨ը֧֮Оϛ͔ˑΙc3?g5>p::o9=q69]LUKτdܘs|x|lՁTREEQѦ`Ynl_1Nq|Y+?X2Ng[0NnOv}Vuza>[cChxpwާk穈m9FY5L\4Gf6Ag4:X-Bj58c4@r=Cf9CvBEq?B_/>QRRMw@CT>eIeEnLvZ{W؂`׃cۇhޏrގqۅhۂ]V~WuVv[rX{\ࠅڏ{Ӑor6:U+CQ%<\/Be6CyDEk7=o9>WIEB]Qt>=UGl6Bj;IҫڡՔiʛtřt͜˙vȗuǖvΝvƘ|Řyxw{y}lwdÅکأ՟թ֧٫ٴңΗ͔̗МРϚ_2Bg1Ag1:e/9}?>iPfZ΃iۓin검zxyׂUVO?HabT^g:Ur]1DE"A|_~iA]O0\ߔvbHb`[wqvoi–w{]S.DZ4HX->g7i7A\5Gg6?e0:`.=^,;k9i7@j;Bm6=I>:2WCbGjP{[\ֆe؋pىgڎlq{ݖs~䥌魐x䢄ޕ{ӕsV&9I@W0IY1E]6In[,Bծܥz̛|ˠ~ǜyɜȖy|țŖƘy{Ŕxq{kugǑ۬ڣ֤եԥԟӥ֧ԦңϗΑС͘\2@d7C[-?U0DXPgTeUІcޓjzzv찅|rրSTHIFdZ[\`8IW0LzQ_e:LO1RWp\:TiCegAW_=Y”|v[˕hD_kktCRg7JW/E\3G\1El;Ek9AZ/Bk9BW(7m=@^.=`/>n8;v:9h7>l8D?u99u4.K=[=nP|W~Y׉kڐwۓ|z{穉壇穈奋樊अړyNJuS';r>FS3HT/J\4Ip>A\,;m7;`/:aTNNI@OHSCYUZ+F׮ٝwȕ|ˢ˛vŚŖxĕ|ēv“yĘ~ŕuzz|xt{lrϜܯؠԢӠ֧բ֢ԠН͗Θ̘͙Ǝ],?d5A^1B\->yCDaLrS҆`ߖmu{w}~lօXNE|BF\Yb:Ic8JQ1Hesb8O[0Ki@[S.GD!JimGhkiqsSek`qERZ8L[0D[0CV/Dj;D{BDV-?F@a2=`2@[,:]-7h6@c2:d2;md)1??\HtTtU}aтkގlܒoޓt~奊簗䥄妌}ՓvmRW*>Y3M_h^MKHCLAXJYV\,CڭڢƖÕzƘ}ęęŘxww{xuvj}՞ݮ֞ѓԟצئԟџΐʑǏ꾌{qFZ+?].@W+?v@>C=<3QD`Kj`y`ыsՏuܔw|~ݘ{ޖu֎nłgYDR-<\4EX3N];Q]4IsCGg8Dg5?i:E`[]XPMNK_SVG]1Gڰҕk}f}gjx~}Ŕz}x}yxvwqfد~ףڨ֜՛ӞԗЗϓϑČw͇Ku:8Y+9R+>f5@`3BV)W+@PMNLR)=}DAW-=]2Cb0>^0=[-=a.:m=Aj5:m9Dj5:s;;NAPBmVzgԅh׆j֐uЉpܒuِqߜ|ޠߞ۠{ߥ⪉߰޻{QZU9NW1IY4H\5FoAM^4Bc7EJI\QRIUOLLZQICj:Dөcz^mWsfz]itnvŒww{urpzotoŒעӘҙϗҝѕϖʊ渇ΙtHCQ#7Q*=d2>u<He5@_-BY.?a.D^3DQK\-@Z+?c4B_/:a1Ae4Ad6Bu@Gu@Dg4Ai6CTI`OxYσe~_~_҄cȄmчi؍oۓvٔp֖yבrוyנ߯âɤūuW?U_;LfI)?R+D}N^b9MV/HlHTQgnBXN(C[}ob?[|]ksvOxytZ=Q^0Ax@Fh;HV2GTNX.=Y+Dm8Bc3=h5>UThMz_|_~a{`΄lЊqډf܊aِr׊j׉iאrڗy{㳍忝ĝƟȡ̪ΪwM-=M)>Q'9k:CIE~GILITQQI~EDMP֕g~gɏqjaqxctfiZfWg[j_sni_obiXlcj^ĊэȉЖҗИї٫|QFZ.Y0>_3HvG!;j9PiyK[L%>S)Kw\qTmfkmj~c4Eg7CCBa3CS&U';f6?_3GX-Bg9Ci=GKJk6Aa0EyDFc7@PKfVtWvZ`ρaʂeڊh؍lܓuٍnوlْtەxݟ᫄崌鿙徚žɠ̦ͪҮֵya6=e9G{GLyGHQG{CCk4:zmЕu͒sȔywmw}{r{kxmnaqdZUt`ƂYbRVPĆҘВ֜қ͖؛jszUgm?RlE[c<[ikoM&F`9UkEbb@\yX}k|K#CP*Id2GR.FN)BOJf3Bd9KR1Fb2@g=Ib1>]4Ii4At?FcI`0>WRo\qWф^~]{d֋o܆aَi،n؆dىgڑlܜ{䧃⭉嵐溘弗澘şɢͣϫӱ׷_6MtAIsBC~JFw>@\(=Ȏ{ΔuϚyė}zswxxpu|pxpyqnfyVȄXj[ʈ\˓՞Ԡ֠ˉ뿃gOW*>PGYLXKRLgW_N\S\Iut{ZNa,9PB҉hpxwostuiE Ewg{_z^x`׈k܍i׈lێmڊfݍgڏlݕwxݟ}⩇~孂䱍渌뻑뿑Ɲ̦Τӷֺؽfi}C>r;;~FAHHP(C٪ˑpœvȖtrtnzwuuonoyizYȆYuNިuӟ՚ԗ՜ňןiB?zDG^N_SZLjUz`MQL`UsEQ~tna.9SC׌`z뱀~wj݌Zy~g6>P(@P&;b6AV,8W0Bk8FS.BQ*Gc{sJbK(A\6@O&BY;X|VfQ.HnFalJpxu}j<;a8[ͺM&8M$7w@Eh8Ab0@S)@^2E~MO_0Q1G^1C[/Jp^:LX&3J!=aP-GoEeanMd{XhDeolp{D#@H%q;@~DFa-h{W{sMpalnuVxa~c3K]3OszN+EP&9}CAOEc4AU.@Y3GvACb.:_2?l6>`NpIZG`,;bSqOف\؀bۇ_܅_܇eݑm܋eݐkݒkiޘtuݜy}㬄届沉溗꽐ĚʨдҴ־߻k:;e/9^,7a+7՚rËjɖxʑlǔwl{rvtuqzhyfːls{ϗ٥֚Ә~͊OXQ`MVOfToVmZ^NYNgYkdi_R):a3F«{O&;G<ٌ`xs}vjߋa~{M)Ce7MX-Cc:Jb;HV.C]7LS-JZnbxH"=qJT]/DQ%;[7RaP%:iCO_6GY*ԏiƔyȓxrsƑspsmmn|syezcܩvԛՠΑ՜١ԙȁُX]I\K_PfOsXu\ZNZLk[dW`X_^G3U%:zȭ}[)3z88هWw||x}pۉYrV.Ie>LN$9T*9[,?]3JR-Hyl>Ie7IK'@S*@vJ\bf5@c05f2@o;Dj?Id09_-=v=BrQ^|^[DyCAiXzP׃g܈gވiߊcډdۇ`݌f߅^݌hݐnڝ~rߜxwߡ᧊㯎䳍帎彝åɬϱϴӻھ߼scF0kYϋdϟzȕurÏnqqptnmrzhw[꾆١ԗѕ֠ؤҐ}uK_HXE_LlWoPcQ^P`Pg[khaZVVJ!4U(>|ªh4:|>BڈZr{ypvrؑlsg?PU-BQ-CU,9[)9V,JwReO1SoxSeZ/BW.?d:HP(ՃWx~~}kیb~xNXW)=\8IV*=_7FV1DQ/AZ4G\muFYS,>mKY[6GV-A_8OU1?V-Hqd>WL*IknU(;V+0L':\39j;=`.9f8DmՃZmxutzpօ`mrk8EfpH^W,KnFVB!;g@]`zvpU/GO&9m6m@LvLPq?E}bi7?c2Y\wGI}>?҃^n~讁곃fڒkÇ|vGRd=NW.BO)EY4Peq]5ET,CkCWc9M\0?X/AL(?{WxX->a=VzUq[6SbV;L|frkDhrmW-=L#8tBFc6>s>Ei4QkCVc:Qc?Te8LW3Hc8OY2Gy]xgCi^>Uz`xh<[hHo}H$8j:@S(Y2DR+<\6IoJ_rGXZk;DR'5`09Z'5Z,:_05k7?SGnKvS}]xXi7IWKӂ[ڈeهdݐuߋggݐqߍdhi݊_ۉ`݊`ލbߐeߕoߕquޛq~ᩃ᫆⮅縒佛ɮɭռտӼڹͅU[GVHWGcMp[w`xpnupǎnӜfђ^ˇV͈XÑۣՒaxNfJSGUGfOMBTIlf`WbZYXkh^YVUu>?N(:N#5^1CƱoju<=}Omwy{wmakkR]Q)@V*;[-=U+MV/Eg?SZ6Ke8F`6DX,AO$5Q(>X.?iRu~[\:TbnF]c;SjXrl>G^0X)8V(8g26KGeFxVsRvN]Ae9MeVWڈh؆_ސqݑnbފjdZhۈ^څ[ވ^ڌgފ]ݓlvޚvݚsߞpx੄~߱廘ƩϷжӸӸ۾ʏwSIaXF@GBQ@]M]QcTnbsfqʖ}ԢrɒiŇ_՘hђަېWjPS@MCZPSIMEaX`T_[_W`\jfa]~JGm59N%9E0^4Iȯ|mz=;uRn~y{tޓ`psYcM%?f;LQ0JP(AU/Ci>KU4Kc9HW3Gj@Mg:QgNAMFKCbZncUP[TZRf``^WWk;@k7@_/:nS);V.@]2E]4G_8MW2Jd;T[4Hi=Qf=I^/CjBSR+?X1@`S'4X)7h.8F?hKxNvU{U{6/g3>mYӃZ݋_߆`ڈhލaދ_aߎinސk_ߋcۅY݆[܊[ۅYۍeܒnەomޙnwzঃⴑ㳉世ĪǬ̳ϾԿپدNC`KhZfU^SQEIFp;Ae38Z+5U+6xBI߯Ƃ]}ӍωܖSRAs9;JFWLIGYSlh^N[Y\SYSli]ZxJIs>>g2<\VPK\`~ƳͷxBAsHy}}{qoXzKYR%7W0GgAPX0FR(<\2@X7Oc`5GsL]S)>I(Iksb}V0EW0?V+5R&6R%8U0?Z*?PEYHrNtUwPC6W'9XMӀY؄Wن[݊e܋f݆]]ifߓo\fۊ_ݍjڍh݈\ފc݊^ڎfߒekܘqݛy|ߥyߩ崏㺕ƭɳͻҾԻսٸeX^Mk[o\gZ_U]VGEtEM_/9O'=DDƋ́ݙ[yԏqP?m57{@>LCHHQPi_cWPOTJTJf`ttYWzIJr@Dk6>[VZRlj­ƷFAsSpttwlcN{jQ_Z1EU,C[3BV-=X+=Y5IW1DV0DR*=pGYX0Be=RU-CW0He9JN$8j?MZ6MhCVn@U^:Sh}wT/E`1>T)r0P!3WE~W~Vׄ^نc߉aӆeߎaދ\cݍdݏq݋_ޒo\ފcߋh݋^ݏh،iډ^da۔itޟ|ߣާ{㱒㶗㽠çȳ͹ѽѸٿԵWMj`m[dUaR\QUJyF@k:?`,9IL|{uƄgYCg3;j5=LFz?CNJbV^RROOOLFZWqrfaUWSRo:BrBKQMqnroŮȯPFqRoxq봂vvcSrm_3Eb9JT3GZ1C^6HV,@a8HQ)@X4LcF]iBQT,CrK[g=R\6GV/Gf}^8TnB^a:UoOfxl?S[4@p?HV+=R);X-;O)7S%,a1:MAhKiJeIO!,a-7cEtOxQ؄W؄Wۉ]܈Wۍkދa܊eތhލcߋaސifݑjߌecߌ\ޏbމ^ڋgݐiۑiܒeܙtޟwߤ}|ᧀ௑⸖你ŭͰϸҽԻծMBf^hYeUg\bUbWUUNJVO\K}՗}גZ]Lw@?m5;LGE@I@aVlcZX}KPNL[Wkgmj^^XXtDGwGIg6_3HoFXY/Dc;P`=QU0GyVrvP`O(~`hW3JjIhsNx\6GfE\O*FX/6Q)9Z.:\*4}B;Q=i29O&4j6>T@cGuSxW~U؃ZԁZ؆_܌^ۅ[ߒkގoߊaefߑdjjݒiߍb܌gފXۍe݌a݋\݌]ܓklޙrޡ|ृz⯋ඕ忢ìǭϸѽҿհRIZPeYl\g\g^dY^Ya]\SbZwƈؖTRHLFz>C~F>GBLKb^ph_WNMu>ALM`Xoeida`yDGp>Fb2:~W[]dz~Ưi_pJޛjv|}l΍oNVN'@S+@T1?a9Mo?Q\6J`6F[1Ha3IW/HuZsR/G]usJ^I)@aqM#2pLsx_:Xbuo~T2GQ*>V-?\1>Z)7X(6U'5l7>NCYDeMqSwQyRрU~T|QԂ\׆bڊgۈ[݈_݅Y݋dbߍ`݌gߒnkސgݎdލaތb܉[`ޑi܏dޒiouࣁ⩄ⱏ亘亥俣ū̳лؼyRJb[eUgZqccbf\t`lXnV{WxTUKPGUI[PPFFEaZga^TJF{IMwBHc^pnrqccZ`vGLq=Aq>A_0;d:DiXb=WvM(Fmew@8tI]U.?gGbysRhiCSL$6Z7ER&5a,/t95Ni8Aa3>`4:`1:g@H_hκ˰ƯrrYޚs}x}}wQZh?K]3IV*?O(6_4FjAOb8Pg?Ua@NO)@S+LnQ/DmF^sC_[>QhGdV0FgCf39}AjDkHrHyWuM{MҁZ}S|Q؃SـS؃XڂX܆\ވ[ކ[ۅ^W݊^߉[ސonjjݐiihjkmߐ`ߗlutvޟqyߦ~ⱈ೏以㾡ŮɴϸмһԳLGUQYKf^g\sgt\~_~buYqSoQ~WwPiS`^g][[SVMPNIMFbYzkysh`W[r??c1= 2: + self.id = i16(s) + if len(s) >= 4: + self.count = i16(s[2:4]) + if len(s) >= 6: + self.repair = i16(s[4:6]) + else: + self.repair = None + + if Image.DEBUG: + print "AFRM", self.id, self.count + + return s + + def chunk_ADEF(self, offset, bytes): + "ADEF -- store image" + + # assertions + if self.count != 0: + raise SyntaxError, "misplaced ADEF chunk" + + self.show = 0 + self.id = 0 + self.count = 1 + self.repair = None + + s = self.fp.read(bytes) + if len(s) >= 2: + self.id = i16(s) + if len(s) >= 4: + self.count = i16(s[2:4]) + + if Image.DEBUG: + print "ADEF", self.id, self.count + + return s + + def chunk_NAME(self, offset, bytes): + "NAME -- name the current image" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced NAME chunk" + + name = self.fp.read(bytes) + self.names[self.id] = name + + return name + + def chunk_AEND(self, offset, bytes): + "AEND -- end of animation" + + if Image.DEBUG: + print "AEND" + + self.eof = 1 + + raise EOFError, "end of ARG file" + + def __getmodesize(self, s, full=1): + + size = i32(s), i32(s[4:]) + + try: + mode, rawmode = _MODES[(ord(s[8]), ord(s[9]))] + except: + raise SyntaxError, "unknown image mode" + + if full: + if ord(s[12]): + pass # interlace not yet supported + if ord(s[11]): + raise SyntaxError, "unknown filter category" + + return size, mode, rawmode + + def chunk_PAST(self, offset, bytes): + "PAST -- paste one image into another" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced PAST chunk" + + if self.repair is not None: + # we must repair the target image before we + # start pasting + + # brute force; a better solution would be to + # update only the dirty rectangles in images[id]. + # note that if images[id] doesn't exist, it must + # be created + + self.images[self.id] = self.images[self.repair].copy() + self.repair = None + + s = self.fp.read(bytes) + im = self.images[i16(s)] + x, y = i32(s[2:6]), i32(s[6:10]) + bbox = x, y, im.size[0]+x, im.size[1]+y + + if im.mode in ["RGBA"]: + # paste with transparency + # FIXME: should handle P+transparency as well + self.images[self.id].paste(im, bbox, im) + else: + # paste without transparency + self.images[self.id].paste(im, bbox) + + self.action = ("PAST",) + self.__store() + + return s + + def chunk_BLNK(self, offset, bytes): + "BLNK -- create blank image" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced BLNK chunk" + + s = self.fp.read(bytes) + size, mode, rawmode = self.__getmodesize(s, 0) + + # store image (FIXME: handle colour) + self.action = ("BLNK",) + self.im = Image.core.fill(mode, size, 0) + self.__store() + + return s + + def chunk_IHDR(self, offset, bytes): + "IHDR -- full image follows" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced IHDR chunk" + + # image header + s = self.fp.read(bytes) + size, mode, rawmode = self.__getmodesize(s) + + # decode and store image + self.action = ("IHDR",) + self.im = Image.core.new(mode, size) + self.decoder = Image.core.zip_decoder(rawmode) + self.decoder.setimage(self.im, (0,0) + size) + self.data = "" + + return s + + def chunk_DHDR(self, offset, bytes): + "DHDR -- delta image follows" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced DHDR chunk" + + s = self.fp.read(bytes) + + size, mode, rawmode = self.__getmodesize(s) + + # delta header + diff = ord(s[13]) + offs = i32(s[14:18]), i32(s[18:22]) + + bbox = offs + (offs[0]+size[0], offs[1]+size[1]) + + if Image.DEBUG: + print "DHDR", diff, bbox + + # FIXME: decode and apply image + self.action = ("DHDR", diff, bbox) + + # setup decoder + self.im = Image.core.new(mode, size) + + self.decoder = Image.core.zip_decoder(rawmode) + self.decoder.setimage(self.im, (0,0) + size) + + self.data = "" + + return s + + def chunk_JHDR(self, offset, bytes): + "JHDR -- JPEG image follows" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced JHDR chunk" + + # image header + s = self.fp.read(bytes) + size, mode, rawmode = self.__getmodesize(s, 0) + + # decode and store image + self.action = ("JHDR",) + self.im = Image.core.new(mode, size) + self.decoder = Image.core.jpeg_decoder(rawmode) + self.decoder.setimage(self.im, (0,0) + size) + self.data = "" + + return s + + def chunk_UHDR(self, offset, bytes): + "UHDR -- uncompressed image data follows (EXPERIMENTAL)" + + # assertions + if self.count == 0: + raise SyntaxError, "misplaced UHDR chunk" + + # image header + s = self.fp.read(bytes) + size, mode, rawmode = self.__getmodesize(s, 0) + + # decode and store image + self.action = ("UHDR",) + self.im = Image.core.new(mode, size) + self.decoder = Image.core.raw_decoder(rawmode) + self.decoder.setimage(self.im, (0,0) + size) + self.data = "" + + return s + + def chunk_IDAT(self, offset, bytes): + "IDAT -- image data block" + + # pass compressed chunks through the decoder + s = self.fp.read(bytes) + self.data = self.data + s + n, e = self.decoder.decode(self.data) + if n < 0: + # end of image + if e < 0: + raise IOError, "decoder error %d" % e + else: + self.data = self.data[n:] + + return s + + def chunk_DEND(self, offset, bytes): + return self.chunk_IEND(offset, bytes) + + def chunk_JEND(self, offset, bytes): + return self.chunk_IEND(offset, bytes) + + def chunk_UEND(self, offset, bytes): + return self.chunk_IEND(offset, bytes) + + def chunk_IEND(self, offset, bytes): + "IEND -- end of image" + + # we now have a new image. carry out the operation + # defined by the image header. + + # won't need these anymore + del self.decoder + del self.data + + self.__store() + + return self.fp.read(bytes) + + def __store(self): + + # apply operation + cid = self.action[0] + + if cid in ["BLNK", "IHDR", "JHDR", "UHDR"]: + # store + self.images[self.id] = self.im + + elif cid == "DHDR": + # paste + cid, mode, bbox = self.action + im0 = self.images[self.id] + im1 = self.im + if mode == 0: + im1 = im1.chop_add_modulo(im0.crop(bbox)) + im0.paste(im1, bbox) + + self.count = self.count - 1 + + if self.count == 0 and self.show: + self.im = self.images[self.id] + raise EOFError # end of this frame + + def chunk_PLTE(self, offset, bytes): + "PLTE -- palette data" + + s = self.fp.read(bytes) + if self.mode == "P": + self.palette = ImagePalette.raw("RGB", s) + return s + + def chunk_sYNC(self, offset, bytes): + "SYNC -- reset decoder" + + if self.count != 0: + raise SyntaxError, "misplaced sYNC chunk" + + s = self.fp.read(bytes) + self.__reset() + return s + + +# -------------------------------------------------------------------- +# ARG reader + +def _accept(prefix): + return prefix[:8] == MAGIC + +## +# Image plugin for the experimental Animated Raster Graphics format. + +class ArgImageFile(ImageFile.ImageFile): + + format = "ARG" + format_description = "Animated raster graphics" + + def _open(self): + + if Image.warnings: + Image.warnings.warn( + "The ArgImagePlugin driver is obsolete, and will be removed " + "from a future release of PIL. If you rely on this module, " + "please contact the PIL authors.", + RuntimeWarning + ) + + if self.fp.read(8) != MAGIC: + raise SyntaxError, "not an ARG file" + + self.arg = ArgStream(self.fp) + + # read and process the first chunk (AHDR) + + cid, offset, bytes = self.arg.read() + + if cid != "AHDR": + raise SyntaxError, "expected an AHDR chunk" + + s = self.arg.call(cid, offset, bytes) + + self.arg.crc(cid, s) + + # image characteristics + self.mode = self.arg.mode + self.size = self.arg.size + + def load(self): + + if self.arg.im is None: + self.seek(0) + + # image data + self.im = self.arg.im + self.palette = self.arg.palette + + # set things up for further processing + Image.Image.load(self) + + def seek(self, frame): + + if self.arg.eof: + raise EOFError, "end of animation" + + self.fp = self.arg.fp + + while 1: + + # + # process chunks + + cid, offset, bytes = self.arg.read() + + if self.arg.eof: + raise EOFError, "end of animation" + + try: + s = self.arg.call(cid, offset, bytes) + except EOFError: + break + + except "glurk": # AttributeError + if Image.DEBUG: + print cid, bytes, "(unknown)" + s = self.fp.read(bytes) + + self.arg.crc(cid, s) + + self.fp.read(4) # ship extra CRC + + def tell(self): + return 0 + + def verify(self): + "Verify ARG file" + + # back up to first chunk + self.fp.seek(8) + + self.arg.verify(self) + self.arg.close() + + self.fp = None + +# +# -------------------------------------------------------------------- + +Image.register_open("ARG", ArgImageFile, _accept) + +Image.register_extension("ARG", ".arg") + +Image.register_mime("ARG", "video/x-arg") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py new file mode 100755 index 00000000000..47b5f05c84a --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py @@ -0,0 +1,133 @@ +# +# The Python Imaging Library +# $Id$ +# +# bitmap distribution font (bdf) file parser +# +# history: +# 1996-05-16 fl created (as bdf2pil) +# 1997-08-25 fl converted to FontFile driver +# 2001-05-25 fl removed bogus __init__ call +# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev) +# 2003-04-22 fl more robustification (from Graham Dumpleton) +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1997-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +import Image +import FontFile + +import string + +# -------------------------------------------------------------------- +# parse X Bitmap Distribution Format (BDF) +# -------------------------------------------------------------------- + +bdf_slant = { + "R": "Roman", + "I": "Italic", + "O": "Oblique", + "RI": "Reverse Italic", + "RO": "Reverse Oblique", + "OT": "Other" +} + +bdf_spacing = { + "P": "Proportional", + "M": "Monospaced", + "C": "Cell" +} + +def bdf_char(f): + + # skip to STARTCHAR + while 1: + s = f.readline() + if not s: + return None + if s[:9] == "STARTCHAR": + break + id = string.strip(s[9:]) + + # load symbol properties + props = {} + while 1: + s = f.readline() + if not s or s[:6] == "BITMAP": + break + i = string.find(s, " ") + props[s[:i]] = s[i+1:-1] + + # load bitmap + bitmap = [] + while 1: + s = f.readline() + if not s or s[:7] == "ENDCHAR": + break + bitmap.append(s[:-1]) + bitmap = string.join(bitmap, "") + + [x, y, l, d] = map(int, string.split(props["BBX"])) + [dx, dy] = map(int, string.split(props["DWIDTH"])) + + bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y) + + try: + im = Image.fromstring("1", (x, y), bitmap, "hex", "1") + except ValueError: + # deal with zero-width characters + im = Image.new("1", (x, y)) + + return id, int(props["ENCODING"]), bbox, im + +## +# Font file plugin for the X11 BDF format. + +class BdfFontFile(FontFile.FontFile): + + def __init__(self, fp): + + FontFile.FontFile.__init__(self) + + s = fp.readline() + if s[:13] != "STARTFONT 2.1": + raise SyntaxError, "not a valid BDF file" + + props = {} + comments = [] + + while 1: + s = fp.readline() + if not s or s[:13] == "ENDPROPERTIES": + break + i = string.find(s, " ") + props[s[:i]] = s[i+1:-1] + if s[:i] in ["COMMENT", "COPYRIGHT"]: + if string.find(s, "LogicalFontDescription") < 0: + comments.append(s[i+1:-1]) + + font = string.split(props["FONT"], "-") + + font[4] = bdf_slant[string.upper(font[4])] + font[11] = bdf_spacing[string.upper(font[11])] + + ascent = int(props["FONT_ASCENT"]) + descent = int(props["FONT_DESCENT"]) + + fontname = string.join(font[1:], ";") + + # print "#", fontname + # for i in comments: + # print "#", i + + font = [] + while 1: + c = bdf_char(fp) + if not c: + break + id, ch, (xy, dst, src), im = c + if ch >= 0 and ch < len(self.glyph): + self.glyph[ch] = xy, dst, src, im diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py new file mode 100755 index 00000000000..09c0a2141d3 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py @@ -0,0 +1,251 @@ +# +# The Python Imaging Library. +# $Id$ +# +# BMP file handler +# +# Windows (and OS/2) native bitmap storage format. +# +# history: +# 1995-09-01 fl Created +# 1996-04-30 fl Added save +# 1997-08-27 fl Fixed save of 1-bit images +# 1998-03-06 fl Load P images as L where possible +# 1998-07-03 fl Load P images as 1 where possible +# 1998-12-29 fl Handle small palettes +# 2002-12-30 fl Fixed load of 1-bit palette images +# 2003-04-21 fl Fixed load of 1-bit monochrome images +# 2003-04-23 fl Added limited support for BI_BITFIELDS compression +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1995-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.7" + + +import string +import Image, ImageFile, ImagePalette + + +# +# -------------------------------------------------------------------- +# Read BMP file + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + + +BIT2MODE = { + # bits => mode, rawmode + 1: ("P", "P;1"), + 4: ("P", "P;4"), + 8: ("P", "P"), + 16: ("RGB", "BGR;15"), + 24: ("RGB", "BGR"), + 32: ("RGB", "BGRX") +} + +def _accept(prefix): + return prefix[:2] == "BM" + +## +# Image plugin for the Windows BMP format. + +class BmpImageFile(ImageFile.ImageFile): + + format = "BMP" + format_description = "Windows Bitmap" + + def _bitmap(self, header = 0, offset = 0): + + if header: + self.fp.seek(header) + + read = self.fp.read + + # CORE/INFO + s = read(4) + s = s + ImageFile._safe_read(self.fp, i32(s)-4) + + if len(s) == 12: + + # OS/2 1.0 CORE + bits = i16(s[10:]) + self.size = i16(s[4:]), i16(s[6:]) + compression = 0 + lutsize = 3 + colors = 0 + direction = -1 + + elif len(s) in [40, 64]: + + # WIN 3.1 or OS/2 2.0 INFO + bits = i16(s[14:]) + self.size = i32(s[4:]), i32(s[8:]) + compression = i32(s[16:]) + lutsize = 4 + colors = i32(s[32:]) + direction = -1 + if s[11] == '\xff': + # upside-down storage + self.size = self.size[0], 2**32 - self.size[1] + direction = 0 + + else: + raise IOError("Unsupported BMP header type (%d)" % len(s)) + + if not colors: + colors = 1 << bits + + # MODE + try: + self.mode, rawmode = BIT2MODE[bits] + except KeyError: + raise IOError("Unsupported BMP pixel depth (%d)" % bits) + + if compression == 3: + # BI_BITFIELDS compression + mask = i32(read(4)), i32(read(4)), i32(read(4)) + if bits == 32 and mask == (0xff0000, 0x00ff00, 0x0000ff): + rawmode = "BGRX" + elif bits == 16 and mask == (0x00f800, 0x0007e0, 0x00001f): + rawmode = "BGR;16" + elif bits == 16 and mask == (0x007c00, 0x0003e0, 0x00001f): + rawmode = "BGR;15" + else: + # print bits, map(hex, mask) + raise IOError("Unsupported BMP bitfields layout") + elif compression != 0: + raise IOError("Unsupported BMP compression (%d)" % compression) + + # LUT + if self.mode == "P": + palette = [] + greyscale = 1 + if colors == 2: + indices = (0, 255) + else: + indices = range(colors) + for i in indices: + rgb = read(lutsize)[:3] + if rgb != chr(i)*3: + greyscale = 0 + palette.append(rgb) + if greyscale: + if colors == 2: + self.mode = rawmode = "1" + else: + self.mode = rawmode = "L" + else: + self.mode = "P" + self.palette = ImagePalette.raw( + "BGR", string.join(palette, "") + ) + + if not offset: + offset = self.fp.tell() + + self.tile = [("raw", + (0, 0) + self.size, + offset, + (rawmode, ((self.size[0]*bits+31)>>3)&(~3), direction))] + + self.info["compression"] = compression + + def _open(self): + + # HEAD + s = self.fp.read(14) + if s[:2] != "BM": + raise SyntaxError("Not a BMP file") + offset = i32(s[10:]) + + self._bitmap(offset=offset) + + +class DibImageFile(BmpImageFile): + + format = "DIB" + format_description = "Windows Bitmap" + + def _open(self): + self._bitmap() + +# +# -------------------------------------------------------------------- +# Write BMP file + +def o16(i): + return chr(i&255) + chr(i>>8&255) + +def o32(i): + return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) + +SAVE = { + "1": ("1", 1, 2), + "L": ("L", 8, 256), + "P": ("P", 8, 256), + "RGB": ("BGR", 24, 0), +} + +def _save(im, fp, filename, check=0): + + try: + rawmode, bits, colors = SAVE[im.mode] + except KeyError: + raise IOError("cannot write mode %s as BMP" % im.mode) + + if check: + return check + + stride = ((im.size[0]*bits+7)/8+3)&(~3) + header = 40 # or 64 for OS/2 version 2 + offset = 14 + header + colors * 4 + image = stride * im.size[1] + + # bitmap header + fp.write("BM" + # file type (magic) + o32(offset+image) + # file size + o32(0) + # reserved + o32(offset)) # image data offset + + # bitmap info header + fp.write(o32(header) + # info header size + o32(im.size[0]) + # width + o32(im.size[1]) + # height + o16(1) + # planes + o16(bits) + # depth + o32(0) + # compression (0=uncompressed) + o32(image) + # size of bitmap + o32(1) + o32(1) + # resolution + o32(colors) + # colors used + o32(colors)) # colors important + + fp.write("\000" * (header - 40)) # padding (for OS/2 format) + + if im.mode == "1": + for i in (0, 255): + fp.write(chr(i) * 4) + elif im.mode == "L": + for i in range(256): + fp.write(chr(i) * 4) + elif im.mode == "P": + fp.write(im.im.getpalette("RGB", "BGRX")) + + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))]) + +# +# -------------------------------------------------------------------- +# Registry + +Image.register_open(BmpImageFile.format, BmpImageFile, _accept) +Image.register_save(BmpImageFile.format, _save) + +Image.register_extension(BmpImageFile.format, ".bmp") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py new file mode 100755 index 00000000000..4b111b393ab --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py @@ -0,0 +1,68 @@ +# +# The Python Imaging Library +# $Id$ +# +# BUFR stub adapter +# +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFile + +_handler = None + +## +# Install application-specific BUFR image handler. +# +# @param handler Handler object. + +def register_handler(handler): + global _handler + _handler = handler + +# -------------------------------------------------------------------- +# Image adapter + +def _accept(prefix): + return prefix[:4] == "BUFR" or prefix[:4] == "ZCZC" + +class BufrStubImageFile(ImageFile.StubImageFile): + + format = "BUFR" + format_description = "BUFR" + + def _open(self): + + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + raise SyntaxError("Not a BUFR file") + + self.fp.seek(offset) + + # make something up + self.mode = "F" + self.size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + +def _save(im, fp, filename): + if _handler is None or not hasattr("_handler", "save"): + raise IOError("BUFR save handler not installed") + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept) +Image.register_save(BufrStubImageFile.format, _save) + +Image.register_extension(BufrStubImageFile.format, ".bufr") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py new file mode 100755 index 00000000000..dff50e6bfda --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py @@ -0,0 +1,116 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a class to read from a container file +# +# History: +# 1995-06-18 fl Created +# 1995-09-07 fl Added readline(), readlines() +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1995 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +## +# A file object that provides read access to a part of an existing +# file (for example a TAR file). + +class ContainerIO: + + ## + # Create file object. + # + # @param file Existing file. + # @param offset Start of region, in bytes. + # @param length Size of region, in bytes. + + def __init__(self, file, offset, length): + self.fh = file + self.pos = 0 + self.offset = offset + self.length = length + self.fh.seek(offset) + + ## + # Always false. + + def isatty(self): + return 0 + + ## + # Move file pointer. + # + # @param offset Offset in bytes. + # @param mode Starting position. Use 0 for beginning of region, 1 + # for current offset, and 2 for end of region. You cannot move + # the pointer outside the defined region. + + def seek(self, offset, mode = 0): + if mode == 1: + self.pos = self.pos + offset + elif mode == 2: + self.pos = self.length + offset + else: + self.pos = offset + # clamp + self.pos = max(0, min(self.pos, self.length)) + self.fh.seek(self.offset + self.pos) + + ## + # Get current file pointer. + # + # @return Offset from start of region, in bytes. + + def tell(self): + return self.pos + + ## + # Read data. + # + # @def read(bytes=0) + # @param bytes Number of bytes to read. If omitted or zero, + # read until end of region. + # @return An 8-bit string. + + def read(self, n = 0): + if n: + n = min(n, self.length - self.pos) + else: + n = self.length - self.pos + if not n: # EOF + return "" + self.pos = self.pos + n + return self.fh.read(n) + + ## + # Read a line of text. + # + # @return An 8-bit string. + + def readline(self): + s = "" + while 1: + c = self.read(1) + if not c: + break + s = s + c + if c == "\n": + break + return s + + ## + # Read multiple lines of text. + # + # @return A list of 8-bit strings. + + def readlines(self): + l = [] + while 1: + s = self.readline() + if not s: + break + l.append(s) + return l diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py new file mode 100755 index 00000000000..6a126e701c5 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py @@ -0,0 +1,88 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Cursor support for PIL +# +# notes: +# uses BmpImagePlugin.py to read the bitmap data. +# +# history: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.1" + +import Image, BmpImagePlugin + + +# +# -------------------------------------------------------------------- + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + + +def _accept(prefix): + return prefix[:4] == "\0\0\2\0" + +## +# Image plugin for Windows Cursor files. + +class CurImageFile(BmpImagePlugin.BmpImageFile): + + format = "CUR" + format_description = "Windows Cursor" + + def _open(self): + + offset = self.fp.tell() + + # check magic + s = self.fp.read(6) + if not _accept(s): + raise SyntaxError, "not an CUR file" + + # pick the largest cursor in the file + m = "" + for i in range(i16(s[4:])): + s = self.fp.read(16) + if not m: + m = s + elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]): + m = s + #print "width", ord(s[0]) + #print "height", ord(s[1]) + #print "colors", ord(s[2]) + #print "reserved", ord(s[3]) + #print "hotspot x", i16(s[4:]) + #print "hotspot y", i16(s[6:]) + #print "bytes", i32(s[8:]) + #print "offset", i32(s[12:]) + + # load as bitmap + self._bitmap(i32(m[12:]) + offset) + + # patch up the bitmap height + self.size = self.size[0], self.size[1]/2 + d, e, o, a = self.tile[0] + self.tile[0] = d, (0,0)+self.size, o, a + + return + + +# +# -------------------------------------------------------------------- + +Image.register_open("CUR", CurImageFile, _accept) + +Image.register_extension("CUR", ".cur") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py new file mode 100755 index 00000000000..32da7d831a6 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py @@ -0,0 +1,78 @@ +# +# The Python Imaging Library. +# $Id$ +# +# DCX file handling +# +# DCX is a container file format defined by Intel, commonly used +# for fax applications. Each DCX file consists of a directory +# (a list of file offsets) followed by a set of (usually 1-bit) +# PCX files. +# +# History: +# 1995-09-09 fl Created +# 1996-03-20 fl Properly derived from PcxImageFile. +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 2002-07-30 fl Fixed file handling +# +# Copyright (c) 1997-98 by Secret Labs AB. +# Copyright (c) 1995-96 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.2" + +import Image + +from PcxImagePlugin import PcxImageFile + +MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then? + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + +def _accept(prefix): + return i32(prefix) == MAGIC + +## +# Image plugin for the Intel DCX format. + +class DcxImageFile(PcxImageFile): + + format = "DCX" + format_description = "Intel DCX" + + def _open(self): + + # Header + s = self.fp.read(4) + if i32(s) != MAGIC: + raise SyntaxError, "not a DCX file" + + # Component directory + self._offset = [] + for i in range(1024): + offset = i32(self.fp.read(4)) + if not offset: + break + self._offset.append(offset) + + self.__fp = self.fp + self.seek(0) + + def seek(self, frame): + if frame >= len(self._offset): + raise EOFError("attempt to seek outside DCX directory") + self.frame = frame + self.fp = self.__fp + self.fp.seek(self._offset[frame]) + PcxImageFile._open(self) + + def tell(self): + return self.frame + + +Image.register_open("DCX", DcxImageFile, _accept) + +Image.register_extension("DCX", ".dcx") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py new file mode 100755 index 00000000000..1927b32276b --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py @@ -0,0 +1,349 @@ +# +# The Python Imaging Library. +# $Id$ +# +# EPS file handling +# +# History: +# 1995-09-01 fl Created (0.1) +# 1996-05-18 fl Don't choke on "atend" fields, Ghostscript interface (0.2) +# 1996-08-22 fl Don't choke on floating point BoundingBox values +# 1996-08-23 fl Handle files from Macintosh (0.3) +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) +# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5) +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.5" + +import re, string +import Image, ImageFile + +# +# -------------------------------------------------------------------- + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + +def o32(i): + return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) + +split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$") +field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$") + +def Ghostscript(tile, size, fp): + """Render an image using Ghostscript (Unix only)""" + + # Unpack decoder tile + decoder, tile, offset, data = tile[0] + length, bbox = data + + import tempfile, os + + file = tempfile.mktemp() + + # Build ghostscript command + command = ["gs", + "-q", # quite mode + "-g%dx%d" % size, # set output geometry (pixels) + "-dNOPAUSE -dSAFER", # don't pause between pages, safe mode + "-sDEVICE=ppmraw", # ppm driver + "-sOutputFile=%s" % file,# output file + "- >/dev/null 2>/dev/null"] + + command = string.join(command) + + # push data through ghostscript + try: + gs = os.popen(command, "w") + # adjust for image origin + if bbox[0] != 0 or bbox[1] != 0: + gs.write("%d %d translate\n" % (-bbox[0], -bbox[1])) + fp.seek(offset) + while length > 0: + s = fp.read(8192) + if not s: + break + length = length - len(s) + gs.write(s) + status = gs.close() + if status: + raise IOError("gs failed (status %d)" % status) + im = Image.core.open_ppm(file) + finally: + try: os.unlink(file) + except: pass + + return im + + +class PSFile: + """Wrapper that treats either CR or LF as end of line.""" + def __init__(self, fp): + self.fp = fp + self.char = None + def __getattr__(self, id): + v = getattr(self.fp, id) + setattr(self, id, v) + return v + def seek(self, offset, whence=0): + self.char = None + self.fp.seek(offset, whence) + def tell(self): + pos = self.fp.tell() + if self.char: + pos = pos - 1 + return pos + def readline(self): + s = "" + if self.char: + c = self.char + self.char = None + else: + c = self.fp.read(1) + while c not in "\r\n": + s = s + c + c = self.fp.read(1) + if c == "\r": + self.char = self.fp.read(1) + if self.char == "\n": + self.char = None + return s + "\n" + + +def _accept(prefix): + return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5L + +## +# Image plugin for Encapsulated Postscript. This plugin supports only +# a few variants of this format. + +class EpsImageFile(ImageFile.ImageFile): + """EPS File Parser for the Python Imaging Library""" + + format = "EPS" + format_description = "Encapsulated Postscript" + + def _open(self): + + # FIXME: should check the first 512 bytes to see if this + # really is necessary (platform-dependent, though...) + + fp = PSFile(self.fp) + + # HEAD + s = fp.read(512) + if s[:4] == "%!PS": + offset = 0 + fp.seek(0, 2) + length = fp.tell() + elif i32(s) == 0xC6D3D0C5L: + offset = i32(s[4:]) + length = i32(s[8:]) + fp.seek(offset) + else: + raise SyntaxError, "not an EPS file" + + fp.seek(offset) + + box = None + + self.mode = "RGB" + self.size = 1, 1 # FIXME: huh? + + # + # Load EPS header + + s = fp.readline() + + while s: + + if len(s) > 255: + raise SyntaxError, "not an EPS file" + + if s[-2:] == '\r\n': + s = s[:-2] + elif s[-1:] == '\n': + s = s[:-1] + + try: + m = split.match(s) + except re.error, v: + raise SyntaxError, "not an EPS file" + + if m: + k, v = m.group(1, 2) + self.info[k] = v + if k == "BoundingBox": + try: + # Note: The DSC spec says that BoundingBox + # fields should be integers, but some drivers + # put floating point values there anyway. + box = map(int, map(float, string.split(v))) + self.size = box[2] - box[0], box[3] - box[1] + self.tile = [("eps", (0,0) + self.size, offset, + (length, box))] + except: + pass + + else: + + m = field.match(s) + + if m: + k = m.group(1) + if k == "EndComments": + break + if k[:8] == "PS-Adobe": + self.info[k[:8]] = k[9:] + else: + self.info[k] = "" + else: + raise IOError, "bad EPS header" + + s = fp.readline() + + if s[:1] != "%": + break + + + # + # Scan for an "ImageData" descriptor + + while s[0] == "%": + + if len(s) > 255: + raise SyntaxError, "not an EPS file" + + if s[-2:] == '\r\n': + s = s[:-2] + elif s[-1:] == '\n': + s = s[:-1] + + if s[:11] == "%ImageData:": + + [x, y, bi, mo, z3, z4, en, id] =\ + string.split(s[11:], maxsplit=7) + + x = int(x); y = int(y) + + bi = int(bi) + mo = int(mo) + + en = int(en) + + if en == 1: + decoder = "eps_binary" + elif en == 2: + decoder = "eps_hex" + else: + break + if bi != 8: + break + if mo == 1: + self.mode = "L" + elif mo == 2: + self.mode = "LAB" + elif mo == 3: + self.mode = "RGB" + else: + break + + if id[:1] == id[-1:] == '"': + id = id[1:-1] + + # Scan forward to the actual image data + while 1: + s = fp.readline() + if not s: + break + if s[:len(id)] == id: + self.size = x, y + self.tile2 = [(decoder, + (0, 0, x, y), + fp.tell(), + 0)] + return + + s = fp.readline() + if not s: + break + + if not box: + raise IOError, "cannot determine EPS bounding box" + + def load(self): + # Load EPS via Ghostscript + if not self.tile: + return + self.im = Ghostscript(self.tile, self.size, self.fp) + self.mode = self.im.mode + self.size = self.im.size + self.tile = [] + +# +# -------------------------------------------------------------------- + +def _save(im, fp, filename, eps=1): + """EPS Writer for the Python Imaging Library.""" + + # + # make sure image data is available + im.load() + + # + # determine postscript image mode + if im.mode == "L": + operator = (8, 1, "image") + elif im.mode == "RGB": + operator = (8, 3, "false 3 colorimage") + elif im.mode == "CMYK": + operator = (8, 4, "false 4 colorimage") + else: + raise ValueError, "image mode is not supported" + + if eps: + # + # write EPS header + fp.write("%!PS-Adobe-3.0 EPSF-3.0\n") + fp.write("%%Creator: PIL 0.1 EpsEncode\n") + #fp.write("%%CreationDate: %s"...) + fp.write("%%%%BoundingBox: 0 0 %d %d\n" % im.size) + fp.write("%%Pages: 1\n") + fp.write("%%EndComments\n") + fp.write("%%Page: 1 1\n") + fp.write("%%ImageData: %d %d " % im.size) + fp.write("%d %d 0 1 1 \"%s\"\n" % operator) + + # + # image header + fp.write("gsave\n") + fp.write("10 dict begin\n") + fp.write("/buf %d string def\n" % (im.size[0] * operator[1])) + fp.write("%d %d scale\n" % im.size) + fp.write("%d %d 8\n" % im.size) # <= bits + fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])) + fp.write("{ currentfile buf readhexstring pop } bind\n") + fp.write("%s\n" % operator[2]) + + ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)]) + + fp.write("\n%%%%EndBinary\n") + fp.write("grestore end\n") + fp.flush() + +# +# -------------------------------------------------------------------- + +Image.register_open(EpsImageFile.format, EpsImageFile, _accept) + +Image.register_save(EpsImageFile.format, _save) + +Image.register_extension(EpsImageFile.format, ".ps") +Image.register_extension(EpsImageFile.format, ".eps") + +Image.register_mime(EpsImageFile.format, "application/postscript") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py new file mode 100755 index 00000000000..b033aad35e8 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py @@ -0,0 +1,157 @@ +# +# The Python Imaging Library. +# $Id$ +# +# EXIF tags +# +# Copyright (c) 2003 by Secret Labs AB +# +# See the README file for information on usage and redistribution. +# + +## +# This module provides constants and clear-text names for various +# well-known EXIF tags. +## + +## +# Maps EXIF tags to tag names. + +TAGS = { + + # possibly incomplete + 0x0100: "ImageWidth", + 0x0101: "ImageLength", + 0x0102: "BitsPerSample", + 0x0103: "Compression", + 0x0106: "PhotometricInterpretation", + 0x010e: "ImageDescription", + 0x010f: "Make", + 0x0110: "Model", + 0x0111: "StripOffsets", + 0x0112: "Orientation", + 0x0115: "SamplesPerPixel", + 0x0116: "RowsPerStrip", + 0x0117: "StripByteConunts", + 0x011a: "XResolution", + 0x011a: "XResolution", + 0x011b: "YResolution", + 0x011b: "YResolution", + 0x011c: "PlanarConfiguration", + 0x0128: "ResolutionUnit", + 0x0128: "ResolutionUnit", + 0x012d: "TransferFunction", + 0x0131: "Software", + 0x0132: "DateTime", + 0x013b: "Artist", + 0x013e: "WhitePoint", + 0x013f: "PrimaryChromaticities", + 0x0201: "JpegIFOffset", + 0x0202: "JpegIFByteCount", + 0x0211: "YCbCrCoefficients", + 0x0211: "YCbCrCoefficients", + 0x0212: "YCbCrSubSampling", + 0x0213: "YCbCrPositioning", + 0x0213: "YCbCrPositioning", + 0x0214: "ReferenceBlackWhite", + 0x0214: "ReferenceBlackWhite", + 0x1000: "RelatedImageFileFormat", + 0x1001: "RelatedImageLength", + 0x1001: "RelatedImageWidth", + 0x828d: "CFARepeatPatternDim", + 0x828e: "CFAPattern", + 0x828f: "BatteryLevel", + 0x8298: "Copyright", + 0x829a: "ExposureTime", + 0x829d: "FNumber", + 0x8769: "ExifOffset", + 0x8773: "InterColorProfile", + 0x8822: "ExposureProgram", + 0x8824: "SpectralSensitivity", + 0x8825: "GPSInfo", + 0x8827: "ISOSpeedRatings", + 0x8828: "OECF", + 0x8829: "Interlace", + 0x882a: "TimeZoneOffset", + 0x882b: "SelfTimerMode", + 0x9000: "ExifVersion", + 0x9003: "DateTimeOriginal", + 0x9004: "DateTimeDigitized", + 0x9101: "ComponentsConfiguration", + 0x9102: "CompressedBitsPerPixel", + 0x9201: "ShutterSpeedValue", + 0x9202: "ApertureValue", + 0x9203: "BrightnessValue", + 0x9204: "ExposureBiasValue", + 0x9205: "MaxApertureValue", + 0x9206: "SubjectDistance", + 0x9207: "MeteringMode", + 0x9208: "LightSource", + 0x9209: "Flash", + 0x920a: "FocalLength", + 0x920b: "FlashEnergy", + 0x920c: "SpatialFrequencyResponse", + 0x920d: "Noise", + 0x9211: "ImageNumber", + 0x9212: "SecurityClassification", + 0x9213: "ImageHistory", + 0x9214: "SubjectLocation", + 0x9215: "ExposureIndex", + 0x9216: "TIFF/EPStandardID", + 0x927c: "MakerNote", + 0x9286: "UserComment", + 0x9290: "SubsecTime", + 0x9291: "SubsecTimeOriginal", + 0x9292: "SubsecTimeDigitized", + 0xa000: "FlashPixVersion", + 0xa001: "ColorSpace", + 0xa002: "ExifImageWidth", + 0xa003: "ExifImageHeight", + 0xa004: "RelatedSoundFile", + 0xa005: "ExifInteroperabilityOffset", + 0xa20b: "FlashEnergy", + 0xa20c: "SpatialFrequencyResponse", + 0xa20e: "FocalPlaneXResolution", + 0xa20f: "FocalPlaneYResolution", + 0xa210: "FocalPlaneResolutionUnit", + 0xa214: "SubjectLocation", + 0xa215: "ExposureIndex", + 0xa217: "SensingMethod", + 0xa300: "FileSource", + 0xa301: "SceneType", + 0xa302: "CFAPattern", + +} + +## +# Maps EXIF GSP tags to tag names. + +GPSTAGS = { + 0: "GPSVersionID", + 1: "GPSLatitudeRef", + 2: "GPSLatitude", + 3: "GPSLongitudeRef", + 4: "GPSLongitude", + 5: "GPSAltitudeRef", + 6: "GPSAltitude", + 7: "GPSTimeStamp", + 8: "GPSSatellites", + 9: "GPSStatus", + 10: "GPSMeasureMode", + 11: "GPSDOP", + 12: "GPSSpeedRef", + 13: "GPSSpeed", + 14: "GPSTrackRef", + 15: "GPSTrack", + 16: "GPSImgDirectionRef", + 17: "GPSImgDirection", + 18: "GPSMapDatum", + 19: "GPSDestLatitudeRef", + 20: "GPSDestLatitude", + 21: "GPSDestLongitudeRef", + 22: "GPSDestLongitude", + 23: "GPSDestBearingRef", + 24: "GPSDestBearing", + 25: "GPSDestDistanceRef", + 26: "GPSDestDistance" +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py new file mode 100755 index 00000000000..ac8be80a908 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py @@ -0,0 +1,73 @@ +# +# The Python Imaging Library +# $Id$ +# +# FITS stub adapter +# +# Copyright (c) 1998-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFile + +_handler = None + +## +# Install application-specific FITS image handler. +# +# @param handler Handler object. + +def register_handler(handler): + global _handler + _handler = handler + +# -------------------------------------------------------------------- +# Image adapter + +def _accept(prefix): + return prefix[:6] == "SIMPLE" + +class FITSStubImageFile(ImageFile.StubImageFile): + + format = "FITS" + format_description = "FITS" + + def _open(self): + + offset = self.fp.tell() + + if not _accept(self.fp.read(6)): + raise SyntaxError("Not a FITS file") + + # FIXME: add more sanity checks here; mandatory header items + # include SIMPLE, BITPIX, NAXIS, etc. + + self.fp.seek(offset) + + # make something up + self.mode = "F" + self.size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + +def _save(im, fp, filename): + if _handler is None or not hasattr("_handler", "save"): + raise IOError("FITS save handler not installed") + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(FITSStubImageFile.format, FITSStubImageFile, _accept) +Image.register_save(FITSStubImageFile.format, _save) + +Image.register_extension(FITSStubImageFile.format, ".fit") +Image.register_extension(FITSStubImageFile.format, ".fits") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py new file mode 100755 index 00000000000..706c36a7f68 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py @@ -0,0 +1,142 @@ +# +# The Python Imaging Library. +# $Id$ +# +# FLI/FLC file handling. +# +# History: +# 95-09-01 fl Created +# 97-01-03 fl Fixed parser, setup decoder tile +# 98-07-15 fl Renamed offset attribute to avoid name clash +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.2" + +import Image, ImageFile, ImagePalette +import string + + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + +# +# decoder + +def _accept(prefix): + return i16(prefix[4:6]) in [0xAF11, 0xAF12] + +## +# Image plugin for the FLI/FLC animation format. Use the seek +# method to load individual frames. + +class FliImageFile(ImageFile.ImageFile): + + format = "FLI" + format_description = "Autodesk FLI/FLC Animation" + + def _open(self): + + # HEAD + s = self.fp.read(128) + magic = i16(s[4:6]) + if magic not in [0xAF11, 0xAF12]: + raise SyntaxError, "not an FLI/FLC file" + + # image characteristics + self.mode = "P" + self.size = i16(s[8:10]), i16(s[10:12]) + + # animation speed + duration = i32(s[16:20]) + if magic == 0xAF11: + duration = (duration * 1000) / 70 + self.info["duration"] = duration + + # look for palette + palette = map(lambda a: (a,a,a), range(256)) + + s = self.fp.read(16) + + self.__offset = 128 + + if i16(s[4:6]) == 0xF100: + # prefix chunk; ignore it + self.__offset = self.__offset + i32(s) + s = self.fp.read(16) + + if i16(s[4:6]) == 0xF1FA: + # look for palette chunk + s = self.fp.read(6) + if i16(s[4:6]) == 11: + self._palette(palette, 2) + elif i16(s[4:6]) == 4: + self._palette(palette, 0) + + palette = map(lambda (r,g,b): chr(r)+chr(g)+chr(b), palette) + self.palette = ImagePalette.raw("RGB", string.join(palette, "")) + + # set things up to decode first frame + self.frame = -1 + self.__fp = self.fp + + self.seek(0) + + def _palette(self, palette, shift): + # load palette + + i = 0 + for e in range(i16(self.fp.read(2))): + s = self.fp.read(2) + i = i + ord(s[0]) + n = ord(s[1]) + if n == 0: + n = 256 + s = self.fp.read(n * 3) + for n in range(0, len(s), 3): + r = ord(s[n]) << shift + g = ord(s[n+1]) << shift + b = ord(s[n+2]) << shift + palette[i] = (r, g, b) + i = i + 1 + + def seek(self, frame): + + if frame != self.frame + 1: + raise ValueError, "cannot seek to frame %d" % frame + self.frame = frame + + # move to next frame + self.fp = self.__fp + self.fp.seek(self.__offset) + + s = self.fp.read(4) + if not s: + raise EOFError + + framesize = i32(s) + + self.decodermaxblock = framesize + self.tile = [("fli", (0,0)+self.size, self.__offset, None)] + + self.__offset = self.__offset + framesize + + def tell(self): + + return self.frame + +# +# registry + +Image.register_open("FLI", FliImageFile, _accept) + +Image.register_extension("FLI", ".fli") +Image.register_extension("FLI", ".flc") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py new file mode 100755 index 00000000000..d9d8eb38a69 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py @@ -0,0 +1,146 @@ +# +# The Python Imaging Library +# $Id$ +# +# base class for raster font file parsers +# +# history: +# 1997-06-05 fl created +# 1997-08-19 fl restrict image width +# +# Copyright (c) 1997-1998 by Secret Labs AB +# Copyright (c) 1997-1998 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import os +import Image + +import marshal + +try: + import zlib +except ImportError: + zlib = None + +WIDTH = 800 + +def puti16(fp, values): + # write network order (big-endian) 16-bit sequence + for v in values: + if v < 0: + v = v + 65536 + fp.write(chr(v>>8&255) + chr(v&255)) + +## +# Base class for raster font file handlers. + +class FontFile: + + bitmap = None + + def __init__(self): + + self.info = {} + self.glyph = [None] * 256 + + def __getitem__(self, ix): + return self.glyph[ix] + + def compile(self): + "Create metrics and bitmap" + + if self.bitmap: + return + + # create bitmap large enough to hold all data + h = w = maxwidth = 0 + lines = 1 + for glyph in self: + if glyph: + d, dst, src, im = glyph + h = max(h, src[3] - src[1]) + w = w + (src[2] - src[0]) + if w > WIDTH: + lines = lines + 1 + w = (src[2] - src[0]) + maxwidth = max(maxwidth, w) + + xsize = maxwidth + ysize = lines * h + + if xsize == 0 and ysize == 0: + return "" + + self.ysize = h + + # paste glyphs into bitmap + self.bitmap = Image.new("1", (xsize, ysize)) + self.metrics = [None] * 256 + x = y = 0 + for i in range(256): + glyph = self[i] + if glyph: + d, dst, src, im = glyph + xx, yy = src[2] - src[0], src[3] - src[1] + x0, y0 = x, y + x = x + xx + if x > WIDTH: + x, y = 0, y + h + x0, y0 = x, y + x = xx + s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0 + self.bitmap.paste(im.crop(src), s) + # print chr(i), dst, s + self.metrics[i] = d, dst, s + + + def save1(self, filename): + "Save font in version 1 format" + + self.compile() + + # font data + self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG") + + # font metrics + fp = open(os.path.splitext(filename)[0] + ".pil", "wb") + fp.write("PILfont\n") + fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!! + fp.write("DATA\n") + for id in range(256): + m = self.metrics[id] + if not m: + puti16(fp, [0] * 10) + else: + puti16(fp, m[0] + m[1] + m[2]) + fp.close() + + + def save2(self, filename): + "Save font in version 2 format" + + # THIS IS WORK IN PROGRESS + + self.compile() + + data = marshal.dumps((self.metrics, self.info)) + + if zlib: + data = "z" + zlib.compress(data, 9) + else: + data = "u" + data + + fp = open(os.path.splitext(filename)[0] + ".pil", "wb") + + fp.write("PILfont2\n" + self.name + "\n" + "DATA\n") + + fp.write(data) + + self.bitmap.save(fp, "PNG") + + fp.close() + + + save = save1 # for now diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py new file mode 100755 index 00000000000..b78fe8c70e9 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py @@ -0,0 +1,224 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library. +# $Id$ +# +# FlashPix support for PIL +# +# History: +# 97-01-25 fl Created (reads uncompressed RGB images only) +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.1" + + +import Image, ImageFile +from OleFileIO import * + + +# we map from colour field tuples to (mode, rawmode) descriptors +MODES = { + # opacity + (0x00007ffe): ("A", "L"), + # monochrome + (0x00010000,): ("L", "L"), + (0x00018000, 0x00017ffe): ("RGBA", "LA"), + # photo YCC + (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"), + (0x00028000, 0x00028001, 0x00028002, 0x00027ffe): ("RGBA", "YCCA;P"), + # standard RGB (NIFRGB) + (0x00030000, 0x00030001, 0x00030002): ("RGB","RGB"), + (0x00038000, 0x00038001, 0x00038002, 0x00037ffe): ("RGBA","RGBA"), +} + +# +# -------------------------------------------------------------------- + +def _accept(prefix): + return prefix[:8] == MAGIC + +## +# Image plugin for the FlashPix images. + +class FpxImageFile(ImageFile.ImageFile): + + format = "FPX" + format_description = "FlashPix" + + def _open(self): + # + # read the OLE directory and see if this is a likely + # to be a FlashPix file + + try: + self.ole = OleFileIO(self.fp) + except IOError: + raise SyntaxError, "not an FPX file; invalid OLE file" + + if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": + raise SyntaxError, "not an FPX file; bad root CLSID" + + self._open_index(1) + + def _open_index(self, index = 1): + # + # get the Image Contents Property Set + + prop = self.ole.getproperties([ + "Data Object Store %06d" % index, + "\005Image Contents" + ]) + + # size (highest resolution) + + self.size = prop[0x1000002], prop[0x1000003] + + size = max(self.size) + i = 1 + while size > 64: + size = size / 2 + i = i + 1 + self.maxid = i - 1 + + # mode. instead of using a single field for this, flashpix + # requires you to specify the mode for each channel in each + # resolution subimage, and leaves it to the decoder to make + # sure that they all match. for now, we'll cheat and assume + # that this is always the case. + + id = self.maxid << 16 + + s = prop[0x2000002|id] + + colors = [] + for i in range(i32(s, 4)): + # note: for now, we ignore the "uncalibrated" flag + colors.append(i32(s, 8+i*4) & 0x7fffffff) + + self.mode, self.rawmode = MODES[tuple(colors)] + + # load JPEG tables, if any + self.jpeg = {} + for i in range(256): + id = 0x3000001|(i << 16) + if prop.has_key(id): + self.jpeg[i] = prop[id] + + # print len(self.jpeg), "tables loaded" + + self._open_subimage(1, self.maxid) + + def _open_subimage(self, index = 1, subimage = 0): + # + # setup tile descriptors for a given subimage + + stream = [ + "Data Object Store %06d" % index, + "Resolution %04d" % subimage, + "Subimage 0000 Header" + ] + + fp = self.ole.openstream(stream) + + # skip prefix + p = fp.read(28) + + # header stream + s = fp.read(36) + + size = i32(s, 4), i32(s, 8) + tilecount = i32(s, 12) + tilesize = i32(s, 16), i32(s, 20) + channels = i32(s, 24) + offset = i32(s, 28) + length = i32(s, 32) + + # print size, self.mode, self.rawmode + + if size != self.size: + raise IOError, "subimage mismatch" + + # get tile descriptors + fp.seek(28 + offset) + s = fp.read(i32(s, 12) * length) + + x = y = 0 + xsize, ysize = size + xtile, ytile = tilesize + self.tile = [] + + for i in range(0, len(s), length): + + compression = i32(s, i+8) + + if compression == 0: + self.tile.append(("raw", (x,y,x+xtile,y+ytile), + i32(s, i) + 28, (self.rawmode))) + + elif compression == 1: + + # FIXME: the fill decoder is not implemented + self.tile.append(("fill", (x,y,x+xtile,y+ytile), + i32(s, i) + 28, (self.rawmode, s[12:16]))) + + elif compression == 2: + + internal_color_conversion = ord(s[14]) + jpeg_tables = ord(s[15]) + rawmode = self.rawmode + + if internal_color_conversion: + # The image is stored as usual (usually YCbCr). + if rawmode == "RGBA": + # For "RGBA", data is stored as YCbCrA based on + # negative RGB. The following trick works around + # this problem : + jpegmode, rawmode = "YCbCrK", "CMYK" + else: + jpegmode = None # let the decoder decide + + else: + # The image is stored as defined by rawmode + jpegmode = rawmode + + self.tile.append(("jpeg", (x,y,x+xtile,y+ytile), + i32(s, i) + 28, (rawmode, jpegmode))) + + # FIXME: jpeg tables are tile dependent; the prefix + # data must be placed in the tile descriptor itself! + + if jpeg_tables: + self.tile_prefix = self.jpeg[jpeg_tables] + + else: + raise IOError, "unknown/invalid compression" + + x = x + xtile + if x >= xsize: + x, y = 0, y + ytile + if y >= ysize: + break # isn't really required + + self.stream = stream + self.fp = None + + def load(self): + + if not self.fp: + self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"]) + + ImageFile.ImageFile.load(self) + +# +# -------------------------------------------------------------------- + +Image.register_open("FPX", FpxImageFile, _accept) + +Image.register_extension("FPX", ".fpx") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py new file mode 100755 index 00000000000..c71a0f77f9c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py @@ -0,0 +1,70 @@ +# +# The Python Imaging Library +# $Id$ +# +# load a GIMP brush file +# +# History: +# 96-03-14 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFile + +def i32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24L) + +def _accept(prefix): + return i32(prefix) >= 20 and i32(prefix[4:8]) == 1 + +## +# Image plugin for the GIMP brush format. + +class GbrImageFile(ImageFile.ImageFile): + + format = "GBR" + format_description = "GIMP brush file" + + def _open(self): + + header_size = i32(self.fp.read(4)) + version = i32(self.fp.read(4)) + if header_size < 20 or version != 1: + raise SyntaxError, "not a GIMP brush" + + width = i32(self.fp.read(4)) + height = i32(self.fp.read(4)) + bytes = i32(self.fp.read(4)) + if width <= 0 or height <= 0 or bytes != 1: + raise SyntaxError, "not a GIMP brush" + + comment = self.fp.read(header_size - 20)[:-1] + + self.mode = "L" + self.size = width, height + + self.info["comment"] = comment + + # Since the brush is so small, we read the data immediately + self.data = self.fp.read(width * height) + + def load(self): + + if not self.data: + return + + # create an image out of the brush data block + self.im = Image.core.new(self.mode, self.size) + self.im.fromstring(self.data) + self.data = "" + +# +# registry + +Image.register_open("GBR", GbrImageFile, _accept) + +Image.register_extension("GBR", ".gbr") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py new file mode 100755 index 00000000000..b5f1dd25d79 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py @@ -0,0 +1,85 @@ +# +# The Python Imaging Library. +# $Id$ +# +# GD file handling +# +# History: +# 1996-04-12 fl Created +# +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + + +# NOTE: This format cannot be automatically recognized, so the +# class is not registered for use with Image.open(). To open a +# gd file, use the GdImageFile.open() function instead. + +# THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This +# implementation is provided for convenience and demonstrational +# purposes only. + + +__version__ = "0.1" + +import ImageFile, ImagePalette + +def i16(c): + return ord(c[1]) + (ord(c[0])<<8) + +## +# Image plugin for the GD uncompressed format. Note that this format +# is not supported by the standard Image.open function. To use +# this plugin, you have to import the GdImageFile module and +# use the GdImageFile.open function. + +class GdImageFile(ImageFile.ImageFile): + + format = "GD" + format_description = "GD uncompressed images" + + def _open(self): + + # Header + s = self.fp.read(775) + + self.mode = "L" # FIXME: "P" + self.size = i16(s[0:2]), i16(s[2:4]) + + # transparency index + tindex = i16(s[5:7]) + if tindex < 256: + self.info["transparent"] = tindex + + self.palette = ImagePalette.raw("RGB", s[7:]) + + self.tile = [("raw", (0,0)+self.size, 775, ("L", 0, -1))] + +## +# Load texture from a GD image file. +# +# @param filename GD file name, or an opened file handle. +# @param mode Optional mode. In this version, if the mode argument +# is given, it must be "r". +# @return An image instance. +# @exception IOError If the image could not be read. + +def open(fp, mode = "r"): + + if mode != "r": + raise ValueError("bad mode") + + if type(fp) == type(""): + import __builtin__ + filename = fp + fp = __builtin__.open(fp, "rb") + else: + filename = "" + + try: + return GdImageFile(fp, filename) + except SyntaxError: + raise IOError("cannot identify this image file") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py new file mode 100755 index 00000000000..4d03493b544 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py @@ -0,0 +1,407 @@ +# +# The Python Imaging Library. +# $Id$ +# +# GIF file handling +# +# History: +# 1995-09-01 fl Created +# 1996-12-14 fl Added interlace support +# 1996-12-30 fl Added animation support +# 1997-01-05 fl Added write support, fixed local colour map bug +# 1997-02-23 fl Make sure to load raster data in getdata() +# 1997-07-05 fl Support external decoder (0.4) +# 1998-07-09 fl Handle all modes when saving (0.5) +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 2001-04-16 fl Added rewind support (seek to frame 0) (0.6) +# 2001-04-17 fl Added palette optimization (0.7) +# 2002-06-06 fl Added transparency support for save (0.8) +# 2004-02-24 fl Disable interlacing for small images +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1995-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.9" + + +import Image, ImageFile, ImagePalette + + +# -------------------------------------------------------------------- +# Helpers + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def o16(i): + return chr(i&255) + chr(i>>8&255) + + +# -------------------------------------------------------------------- +# Identify/read GIF files + +def _accept(prefix): + return prefix[:6] in ["GIF87a", "GIF89a"] + +## +# Image plugin for GIF images. This plugin supports both GIF87 and +# GIF89 images. + +class GifImageFile(ImageFile.ImageFile): + + format = "GIF" + format_description = "Compuserve GIF" + + global_palette = None + + def data(self): + s = self.fp.read(1) + if s and ord(s): + return self.fp.read(ord(s)) + return None + + def _open(self): + + # Screen + s = self.fp.read(13) + if s[:6] not in ["GIF87a", "GIF89a"]: + raise SyntaxError, "not a GIF file" + + self.info["version"] = s[:6] + + self.size = i16(s[6:]), i16(s[8:]) + + self.tile = [] + + flags = ord(s[10]) + + bits = (flags & 7) + 1 + + if flags & 128: + # get global palette + self.info["background"] = ord(s[11]) + # check if palette contains colour indices + p = self.fp.read(3<= 3 and ord(block[0]) == 1: + self.info["loop"] = i16(block[1:3]) + while self.data(): + pass + + elif s == ",": + # + # local image + # + s = self.fp.read(9) + + # extent + x0, y0 = i16(s[0:]), i16(s[2:]) + x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:]) + flags = ord(s[8]) + + interlace = (flags & 64) != 0 + + if flags & 128: + bits = (flags & 7) + 1 + self.palette =\ + ImagePalette.raw("RGB", self.fp.read(3<%s" % (file, filename)) + else: + os.system("ppmquant 256 %s | ppmtogif >%s" % (file, filename)) + try: os.unlink(file) + except: pass + + +# -------------------------------------------------------------------- +# GIF utilities + +def getheader(im, info=None): + """Return a list of strings representing a GIF header""" + + optimize = info and info.get("optimize", 0) + + s = [ + "GIF87a" + # magic + o16(im.size[0]) + # size + o16(im.size[1]) + + chr(7 + 128) + # flags: bits + palette + chr(0) + # background + chr(0) # reserved/aspect + ] + + if optimize: + # minimize color palette + i = 0 + maxcolor = 0 + for count in im.histogram(): + if count: + maxcolor = i + i = i + 1 + else: + maxcolor = 256 + + # global palette + if im.mode == "P": + # colour palette + s.append(im.im.getpalette("RGB")[:maxcolor*3]) + else: + # greyscale + for i in range(maxcolor): + s.append(chr(i) * 3) + + return s + +def getdata(im, offset = (0, 0), **params): + """Return a list of strings representing this image. + The first string is a local image header, the rest contains + encoded image data.""" + + class collector: + data = [] + def write(self, data): + self.data.append(data) + + im.load() # make sure raster data is available + + fp = collector() + + try: + im.encoderinfo = params + + # local image header + fp.write("," + + o16(offset[0]) + # offset + o16(offset[1]) + + o16(im.size[0]) + # size + o16(im.size[1]) + + chr(0) + # flags + chr(8)) # bits + + ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])]) + + fp.write("\0") # end of image data + + finally: + del im.encoderinfo + + return fp.data + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(GifImageFile.format, GifImageFile, _accept) +Image.register_save(GifImageFile.format, _save) +Image.register_extension(GifImageFile.format, ".gif") +Image.register_mime(GifImageFile.format, "image/gif") + +# +# Uncomment the following line if you wish to use NETPBM/PBMPLUS +# instead of the built-in "uncompressed" GIF encoder + +# Image.register_save(GifImageFile.format, _save_netpbm) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py new file mode 100755 index 00000000000..1a850dc53f7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py @@ -0,0 +1,124 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read (and render) GIMP gradient files +# +# History: +# 97-08-23 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +from math import pi, log, sin, sqrt +import string + +# -------------------------------------------------------------------- +# Stuff to translate curve segments to palette values (derived from +# the corresponding code in GIMP, written by Federico Mena Quintero. +# See the GIMP distribution for more information.) +# + +EPSILON = 1e-10 + +def linear(middle, pos): + if pos <= middle: + if middle < EPSILON: + return 0.0 + else: + return 0.5 * pos / middle + else: + pos = pos - middle + middle = 1.0 - middle + if middle < EPSILON: + return 1.0 + else: + return 0.5 + 0.5 * pos / middle + +def curved(middle, pos): + return pos ** (log(0.5) / log(max(middle, EPSILON))) + +def sine(middle, pos): + return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0 + +def sphere_increasing(middle, pos): + return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2) + +def sphere_decreasing(middle, pos): + return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2) + +SEGMENTS = [ linear, curved, sine, sphere_increasing, sphere_decreasing ] + +class GradientFile: + + gradient = None + + def getpalette(self, entries = 256): + + palette = [] + + ix = 0 + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] + + for i in range(entries): + + x = i / float(entries-1) + + while x1 < x: + ix = ix + 1 + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] + + w = x1 - x0 + + if w < EPSILON: + scale = segment(0.5, 0.5) + else: + scale = segment((xm - x0) / w, (x - x0) / w) + + # expand to RGBA + r = chr(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5)) + g = chr(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5)) + b = chr(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5)) + a = chr(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5)) + + # add to palette + palette.append(r + g + b + a) + + return string.join(palette, ""), "RGBA" + +## +# File handler for GIMP's gradient format. + +class GimpGradientFile(GradientFile): + + def __init__(self, fp): + + if fp.readline()[:13] != "GIMP Gradient": + raise SyntaxError, "not a GIMP gradient file" + + count = int(fp.readline()) + + gradient = [] + + for i in range(count): + + s = string.split(fp.readline()) + w = map(float, s[:11]) + + x0, x1 = w[0], w[2] + xm = w[1] + rgb0 = w[3:7] + rgb1 = w[7:11] + + segment = SEGMENTS[int(s[11])] + cspace = int(s[12]) + + if cspace != 0: + raise IOError, "cannot handle HSV colour space" + + gradient.append((x0, x1, xm, rgb0, rgb1, segment)) + + self.gradient = gradient diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py new file mode 100755 index 00000000000..aba85b71f33 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py @@ -0,0 +1,61 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read GIMP palette files +# +# History: +# 1997-08-23 fl Created +# 2004-09-07 fl Support GIMP 2.0 palette files. +# +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. +# Copyright (c) Fredrik Lundh 1997-2004. +# +# See the README file for information on usage and redistribution. +# + +import re, string + +## +# File handler for GIMP's palette format. + +class GimpPaletteFile: + + rawmode = "RGB" + + def __init__(self, fp): + + self.palette = map(lambda i: chr(i)*3, range(256)) + + if fp.readline()[:12] != "GIMP Palette": + raise SyntaxError, "not a GIMP palette file" + + i = 0 + + while i <= 255: + + s = fp.readline() + + if not s: + break + # skip fields and comment lines + if re.match("\w+:|#", s): + continue + if len(s) > 100: + raise SyntaxError, "bad palette file" + + v = tuple(map(int, string.split(s)[:3])) + if len(v) != 3: + raise ValueError, "bad palette entry" + + if 0 <= i <= 255: + self.palette[i] = chr(v[0]) + chr(v[1]) + chr(v[2]) + + i = i + 1 + + self.palette = string.join(self.palette, "") + + + def getpalette(self): + + return self.palette, self.rawmode diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py new file mode 100755 index 00000000000..e232f90db7e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py @@ -0,0 +1,68 @@ +# +# The Python Imaging Library +# $Id$ +# +# GRIB stub adapter +# +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFile + +_handler = None + +## +# Install application-specific GRIB image handler. +# +# @param handler Handler object. + +def register_handler(handler): + global _handler + _handler = handler + +# -------------------------------------------------------------------- +# Image adapter + +def _accept(prefix): + return prefix[0:4] == "GRIB" and prefix[7] == chr(1) + +class GribStubImageFile(ImageFile.StubImageFile): + + format = "GRIB" + format_description = "GRIB" + + def _open(self): + + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + raise SyntaxError("Not a GRIB file") + + self.fp.seek(offset) + + # make something up + self.mode = "F" + self.size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + +def _save(im, fp, filename): + if _handler is None or not hasattr("_handler", "save"): + raise IOError("GRIB save handler not installed") + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept) +Image.register_save(GribStubImageFile.format, _save) + +Image.register_extension(GribStubImageFile.format, ".grib") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py new file mode 100755 index 00000000000..bc5e3743339 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py @@ -0,0 +1,70 @@ +# +# The Python Imaging Library +# $Id$ +# +# HDF5 stub adapter +# +# Copyright (c) 2000-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFile + +_handler = None + +## +# Install application-specific HDF5 image handler. +# +# @param handler Handler object. + +def register_handler(handler): + global _handler + _handler = handler + +# -------------------------------------------------------------------- +# Image adapter + +def _accept(prefix): + return prefix[:8] == "\x89HDF\r\n\x1a\n" + +class HDF5StubImageFile(ImageFile.StubImageFile): + + format = "HDF5" + format_description = "HDF5" + + def _open(self): + + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + raise SyntaxError("Not an HDF file") + + self.fp.seek(offset) + + # make something up + self.mode = "F" + self.size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + +def _save(im, fp, filename): + if _handler is None or not hasattr("_handler", "save"): + raise IOError("HDF5 save handler not installed") + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept) +Image.register_save(HDF5StubImageFile.format, _save) + +Image.register_extension(HDF5StubImageFile.format, ".h5") +Image.register_extension(HDF5StubImageFile.format, ".hdf") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py new file mode 100755 index 00000000000..4d68fa232f9 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py @@ -0,0 +1,211 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Mac OS X icns file decoder, based on icns.py by Bob Ippolito. +# +# history: +# 2004-10-09 fl Turned into a PIL plugin; removed 2.3 dependencies. +# +# Copyright (c) 2004 by Bob Ippolito. +# Copyright (c) 2004 by Secret Labs. +# Copyright (c) 2004 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFile +import string, struct + +HEADERSIZE = 8 + +def nextheader(fobj): + return struct.unpack('>4sI', fobj.read(HEADERSIZE)) + +def read_32t(fobj, (start, length), (width, height)): + # The 128x128 icon seems to have an extra header for some reason. + fobj.seek(start) + sig = fobj.read(4) + if sig != '\x00\x00\x00\x00': + raise SyntaxError, 'Unknown signature, expecting 0x00000000' + return read_32(fobj, (start + 4, length - 4), (width, height)) + +def read_32(fobj, (start, length), size): + """ + Read a 32bit RGB icon resource. Seems to be either uncompressed or + an RLE packbits-like scheme. + """ + fobj.seek(start) + sizesq = size[0] * size[1] + if length == sizesq * 3: + # uncompressed ("RGBRGBGB") + indata = fobj.read(length) + im = Image.frombuffer("RGB", size, indata, "raw", "RGB", 0, 1) + else: + # decode image + im = Image.new("RGB", size, None) + for band_ix in range(3): + data = [] + bytesleft = sizesq + while bytesleft > 0: + byte = fobj.read(1) + if not byte: + break + byte = ord(byte) + if byte & 0x80: + blocksize = byte - 125 + byte = fobj.read(1) + for i in range(blocksize): + data.append(byte) + else: + blocksize = byte + 1 + data.append(fobj.read(blocksize)) + bytesleft = bytesleft - blocksize + if bytesleft <= 0: + break + if bytesleft != 0: + raise SyntaxError( + "Error reading channel [%r left]" % bytesleft + ) + band = Image.frombuffer( + "L", size, string.join(data, ""), "raw", "L", 0, 1 + ) + im.im.putband(band.im, band_ix) + return {"RGB": im} + +def read_mk(fobj, (start, length), size): + # Alpha masks seem to be uncompressed + fobj.seek(start) + band = Image.frombuffer( + "L", size, fobj.read(size[0]*size[1]), "raw", "L", 0, 1 + ) + return {"A": band} + +class IcnsFile: + + SIZES = { + (128, 128): [ + ('it32', read_32t), + ('t8mk', read_mk), + ], + (48, 48): [ + ('ih32', read_32), + ('h8mk', read_mk), + ], + (32, 32): [ + ('il32', read_32), + ('l8mk', read_mk), + ], + (16, 16): [ + ('is32', read_32), + ('s8mk', read_mk), + ], + } + + def __init__(self, fobj): + """ + fobj is a file-like object as an icns resource + """ + # signature : (start, length) + self.dct = dct = {} + self.fobj = fobj + sig, filesize = nextheader(fobj) + if sig != 'icns': + raise SyntaxError, 'not an icns file' + i = HEADERSIZE + while i < filesize: + sig, blocksize = nextheader(fobj) + i = i + HEADERSIZE + blocksize = blocksize - HEADERSIZE + dct[sig] = (i, blocksize) + fobj.seek(blocksize, 1) + i = i + blocksize + + def itersizes(self): + sizes = [] + for size, fmts in self.SIZES.items(): + for (fmt, reader) in fmts: + if self.dct.has_key(fmt): + sizes.append(size) + break + return sizes + + def bestsize(self): + sizes = self.itersizes() + if not sizes: + raise SyntaxError, "No 32bit icon resources found" + return max(sizes) + + def dataforsize(self, size): + """ + Get an icon resource as {channel: array}. Note that + the arrays are bottom-up like windows bitmaps and will likely + need to be flipped or transposed in some way. + """ + dct = {} + for code, reader in self.SIZES[size]: + desc = self.dct.get(code) + if desc is not None: + dct.update(reader(self.fobj, desc, size)) + return dct + + def getimage(self, size=None): + if size is None: + size = self.bestsize() + channels = self.dataforsize(size) + im = channels.get("RGB").copy() + try: + im.putalpha(channels["A"]) + except KeyError: + pass + return im + +## +# Image plugin for Mac OS icons. + +class IcnsImageFile(ImageFile.ImageFile): + """ + PIL read-only image support for Mac OS .icns files. + Chooses the best resolution, but will possibly load + a different size image if you mutate the size attribute + before calling 'load'. + + The info dictionary has a key 'sizes' that is a list + of sizes that the icns file has. + """ + + format = "ICNS" + format_description = "Mac OS icns resource" + + def _open(self): + self.icns = IcnsFile(self.fp) + self.mode = 'RGBA' + self.size = self.icns.bestsize() + self.info['sizes'] = self.icns.itersizes() + # Just use this to see if it's loaded or not yet. + self.tile = ('',) + + def load(self): + Image.Image.load(self) + if not self.tile: + return + self.load_prepare() + # This is likely NOT the best way to do it, but whatever. + im = self.icns.getimage(self.size) + self.im = im.im + self.mode = im.mode + self.size = im.size + self.fp = None + self.icns = None + self.tile = () + self.load_end() + + +Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == 'icns') +Image.register_extension("ICNS", '.icns') + +if __name__ == '__main__': + import os, sys + im = Image.open(open(sys.argv[1], "rb")) + im.save("out.png") + os.startfile("out.png") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py new file mode 100755 index 00000000000..94846dc0ca0 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py @@ -0,0 +1,86 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Icon support for PIL +# +# Notes: +# uses BmpImagePlugin.py to read the bitmap data. +# +# History: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.1" + +import Image, BmpImagePlugin + + +# +# -------------------------------------------------------------------- + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + + +def _accept(prefix): + return prefix[:4] == "\0\0\1\0" + +## +# Image plugin for Windows Icon files. + +class IcoImageFile(BmpImagePlugin.BmpImageFile): + + format = "ICO" + format_description = "Windows Icon" + + def _open(self): + + # check magic + s = self.fp.read(6) + if not _accept(s): + raise SyntaxError, "not an ICO file" + + # pick the largest icon in the file + m = "" + for i in range(i16(s[4:])): + s = self.fp.read(16) + if not m: + m = s + elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]): + m = s + #print "width", ord(s[0]) + #print "height", ord(s[1]) + #print "colors", ord(s[2]) + #print "reserved", ord(s[3]) + #print "planes", i16(s[4:]) + #print "bitcount", i16(s[6:]) + #print "bytes", i32(s[8:]) + #print "offset", i32(s[12:]) + + # load as bitmap + self._bitmap(i32(m[12:])) + + # patch up the bitmap height + self.size = self.size[0], self.size[1]/2 + d, e, o, a = self.tile[0] + self.tile[0] = d, (0,0)+self.size, o, a + + return + + +# +# -------------------------------------------------------------------- + +Image.register_open("ICO", IcoImageFile, _accept) + +Image.register_extension("ICO", ".ico") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py new file mode 100755 index 00000000000..a76dcf04ed3 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py @@ -0,0 +1,336 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IFUNC IM file handling for PIL +# +# history: +# 1995-09-01 fl Created. +# 1997-01-03 fl Save palette images +# 1997-01-08 fl Added sequence support +# 1997-01-23 fl Added P and RGB save support +# 1997-05-31 fl Read floating point images +# 1997-06-22 fl Save floating point images +# 1997-08-27 fl Read and save 1-bit images +# 1998-06-25 fl Added support for RGB+LUT images +# 1998-07-02 fl Added support for YCC images +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 1998-12-29 fl Added I;16 support +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) +# 2003-09-26 fl Added LA/PA support +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2001 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.7" + +import re, string +import Image, ImageFile, ImagePalette + + +# -------------------------------------------------------------------- +# Standard tags + +COMMENT = "Comment" +DATE = "Date" +EQUIPMENT = "Digitalization equipment" +FRAMES = "File size (no of images)" +LUT = "Lut" +NAME = "Name" +SCALE = "Scale (x,y)" +SIZE = "Image size (x*y)" +MODE = "Image type" + +TAGS = { COMMENT:0, DATE:0, EQUIPMENT:0, FRAMES:0, LUT:0, NAME:0, + SCALE:0, SIZE:0, MODE:0 } + +OPEN = { + # ifunc93/p3cfunc formats + "0 1 image": ("1", "1"), + "L 1 image": ("1", "1"), + "Greyscale image": ("L", "L"), + "Grayscale image": ("L", "L"), + "RGB image": ("RGB", "RGB;L"), + "RLB image": ("RGB", "RLB"), + "RYB image": ("RGB", "RLB"), + "B1 image": ("1", "1"), + "B2 image": ("P", "P;2"), + "B4 image": ("P", "P;4"), + "X 24 image": ("RGB", "RGB"), + "L 32 S image": ("I", "I;32"), + "L 32 F image": ("F", "F;32"), + # old p3cfunc formats + "RGB3 image": ("RGB", "RGB;T"), + "RYB3 image": ("RGB", "RYB;T"), + # extensions + "LA image": ("LA", "LA;L"), + "RGBA image": ("RGBA", "RGBA;L"), + "RGBX image": ("RGBX", "RGBX;L"), + "CMYK image": ("CMYK", "CMYK;L"), + "YCC image": ("YCbCr", "YCbCr;L"), +} + +# ifunc95 extensions +for i in ["8", "8S", "16", "16S", "32", "32F"]: + OPEN["L %s image" % i] = ("F", "F;%s" % i) + OPEN["L*%s image" % i] = ("F", "F;%s" % i) +for i in ["16", "16L", "16B"]: + OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i) + OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i) +for i in ["32S"]: + OPEN["L %s image" % i] = ("I", "I;%s" % i) + OPEN["L*%s image" % i] = ("I", "I;%s" % i) +for i in range(2, 33): + OPEN["L*%s image" % i] = ("F", "F;%s" % i) + + +# -------------------------------------------------------------------- +# Read IM directory + +split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$") + +def number(s): + try: + return int(s) + except ValueError: + return float(s) + +## +# Image plugin for the IFUNC IM file format. + +class ImImageFile(ImageFile.ImageFile): + + format = "IM" + format_description = "IFUNC Image Memory" + + def _open(self): + + # Quick rejection: if there's not an LF among the first + # 100 bytes, this is (probably) not a text header. + + if not "\n" in self.fp.read(100): + raise SyntaxError, "not an IM file" + self.fp.seek(0) + + n = 0 + + # Default values + self.info[MODE] = "L" + self.info[SIZE] = (512, 512) + self.info[FRAMES] = 1 + + self.rawmode = "L" + + while 1: + + s = self.fp.read(1) + + # Some versions of IFUNC uses \n\r instead of \r\n... + if s == "\r": + continue + + if not s or s[0] == chr(0) or s[0] == chr(26): + break + + # FIXME: this may read whole file if not a text file + s = s + self.fp.readline() + + if len(s) > 100: + raise SyntaxError, "not an IM file" + + if s[-2:] == '\r\n': + s = s[:-2] + elif s[-1:] == '\n': + s = s[:-1] + + try: + m = split.match(s) + except re.error, v: + raise SyntaxError, "not an IM file" + + if m: + + k, v = m.group(1,2) + + # Convert value as appropriate + if k in [FRAMES, SCALE, SIZE]: + v = string.replace(v, "*", ",") + v = tuple(map(number, string.split(v, ","))) + if len(v) == 1: + v = v[0] + elif k == MODE and OPEN.has_key(v): + v, self.rawmode = OPEN[v] + + # Add to dictionary. Note that COMMENT tags are + # combined into a list of strings. + if k == COMMENT: + if self.info.has_key(k): + self.info[k].append(v) + else: + self.info[k] = [v] + else: + self.info[k] = v + + if TAGS.has_key(k): + n = n + 1 + + else: + + raise SyntaxError, "Syntax error in IM header: " + s + + if not n: + raise SyntaxError, "Not an IM file" + + # Basic attributes + self.size = self.info[SIZE] + self.mode = self.info[MODE] + + # Skip forward to start of image data + while s and s[0] != chr(26): + s = self.fp.read(1) + if not s: + raise SyntaxError, "File truncated" + + if self.info.has_key(LUT): + # convert lookup table to palette or lut attribute + palette = self.fp.read(768) + greyscale = 1 # greyscale palette + linear = 1 # linear greyscale palette + for i in range(256): + if palette[i] == palette[i+256] == palette[i+512]: + if palette[i] != chr(i): + linear = 0 + else: + greyscale = 0 + if self.mode == "L" or self.mode == "LA": + if greyscale: + if not linear: + self.lut = map(ord, palette[:256]) + else: + if self.mode == "L": + self.mode = self.rawmode = "P" + elif self.mode == "LA": + self.mode = self.rawmode = "PA" + self.palette = ImagePalette.raw("RGB;L", palette) + elif self.mode == "RGB": + if not greyscale or not linear: + self.lut = map(ord, palette) + + self.frame = 0 + + self.__offset = offs = self.fp.tell() + + self.__fp = self.fp # FIXME: hack + + if self.rawmode[:2] == "F;": + + # ifunc95 formats + try: + # use bit decoder (if necessary) + bits = int(self.rawmode[2:]) + if bits not in [8, 16, 32]: + self.tile = [("bit", (0,0)+self.size, offs, + (bits, 8, 3, 0, -1))] + return + except ValueError: + pass + + if self.rawmode in ["RGB;T", "RYB;T"]: + # Old LabEye/3PC files. Would be very surprised if anyone + # ever stumbled upon such a file ;-) + size = self.size[0] * self.size[1] + self.tile = [("raw", (0,0)+self.size, offs, ("G", 0, -1)), + ("raw", (0,0)+self.size, offs+size, ("R", 0, -1)), + ("raw", (0,0)+self.size, offs+2*size, ("B", 0, -1))] + else: + # LabEye/IFUNC files + self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))] + + def seek(self, frame): + + if frame < 0 or frame >= self.info[FRAMES]: + raise EOFError, "seek outside sequence" + + if self.frame == frame: + return + + self.frame = frame + + if self.mode == "1": + bits = 1 + else: + bits = 8 * len(self.mode) + + size = ((self.size[0] * bits + 7) / 8) * self.size[1] + offs = self.__offset + frame * size + + self.fp = self.__fp + + self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))] + + def tell(self): + + return self.frame + +# +# -------------------------------------------------------------------- +# Save IM files + +SAVE = { + # mode: (im type, raw mode) + "1": ("0 1", "1"), + "L": ("Greyscale", "L"), + "LA": ("LA", "LA;L"), + "P": ("Greyscale", "P"), + "PA": ("LA", "PA;L"), + "I": ("L 32S", "I;32S"), + "I;16": ("L 16", "I;16"), + "I;16L": ("L 16L", "I;16L"), + "I;16B": ("L 16B", "I;16B"), + "F": ("L 32F", "F;32F"), + "RGB": ("RGB", "RGB;L"), + "RGBA": ("RGBA", "RGBA;L"), + "RGBX": ("RGBX", "RGBX;L"), + "CMYK": ("CMYK", "CMYK;L"), + "YCbCr": ("YCC", "YCbCr;L") +} + +def _save(im, fp, filename, check=0): + + try: + type, rawmode = SAVE[im.mode] + except KeyError: + raise ValueError, "Cannot save %s images as IM" % im.mode + + try: + frames = im.encoderinfo["frames"] + except KeyError: + frames = 1 + + if check: + return check + + fp.write("Image type: %s image\r\n" % type) + if filename: + fp.write("Name: %s\r\n" % filename) + fp.write("Image size (x*y): %d*%d\r\n" % im.size) + fp.write("File size (no of images): %d\r\n" % frames) + if im.mode == "P": + fp.write("Lut: 1\r\n") + fp.write("\000" * (511-fp.tell()) + "\032") + if im.mode == "P": + fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))]) + +# +# -------------------------------------------------------------------- +# Registry + +Image.register_open("IM", ImImageFile) +Image.register_save("IM", _save) + +Image.register_extension("IM", ".im") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py new file mode 100755 index 00000000000..77a532afad0 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py @@ -0,0 +1,2127 @@ +# +# The Python Imaging Library. +# $Id$ +# +# the Image class wrapper +# +# partial release history: +# 1995-09-09 fl Created +# 1996-03-11 fl PIL release 0.0 (proof of concept) +# 1996-04-30 fl PIL release 0.1b1 +# 1999-07-28 fl PIL release 1.0 final +# 2000-06-07 fl PIL release 1.1 +# 2000-10-20 fl PIL release 1.1.1 +# 2001-05-07 fl PIL release 1.1.2 +# 2002-03-15 fl PIL release 1.1.3 +# 2003-05-10 fl PIL release 1.1.4 +# 2005-03-28 fl PIL release 1.1.5 +# 2006-12-02 fl PIL release 1.1.6 +# 2009-11-15 fl PIL release 1.1.7 +# +# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-2009 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +VERSION = "1.1.7" + +try: + import warnings +except ImportError: + warnings = None + +class _imaging_not_installed: + # module placeholder + def __getattr__(self, id): + raise ImportError("The _imaging C module is not installed") + +try: + # give Tk a chance to set up the environment, in case we're + # using an _imaging module linked against libtcl/libtk (use + # __import__ to hide this from naive packagers; we don't really + # depend on Tk unless ImageTk is used, and that module already + # imports Tkinter) + __import__("FixTk") +except ImportError: + pass + +try: + # If the _imaging C module is not present, you can still use + # the "open" function to identify files, but you cannot load + # them. Note that other modules should not refer to _imaging + # directly; import Image and use the Image.core variable instead. + import _imaging + core = _imaging + del _imaging +except ImportError, v: + core = _imaging_not_installed() + if str(v)[:20] == "Module use of python" and warnings: + # The _imaging C module is present, but not compiled for + # the right version (windows only). Print a warning, if + # possible. + warnings.warn( + "The _imaging extension was built for another version " + "of Python; most PIL functions will be disabled", + RuntimeWarning + ) + +import ImageMode +import ImagePalette + +import os, string, sys + +# type stuff +from types import IntType, StringType, TupleType + +try: + UnicodeStringType = type(unicode("")) + ## + # (Internal) Checks if an object is a string. If the current + # Python version supports Unicode, this checks for both 8-bit + # and Unicode strings. + def isStringType(t): + return isinstance(t, StringType) or isinstance(t, UnicodeStringType) +except NameError: + def isStringType(t): + return isinstance(t, StringType) + +## +# (Internal) Checks if an object is a tuple. + +def isTupleType(t): + return isinstance(t, TupleType) + +## +# (Internal) Checks if an object is an image object. + +def isImageType(t): + return hasattr(t, "im") + +## +# (Internal) Checks if an object is a string, and that it points to a +# directory. + +def isDirectory(f): + return isStringType(f) and os.path.isdir(f) + +from operator import isNumberType, isSequenceType + +# +# Debug level + +DEBUG = 0 + +# +# Constants (also defined in _imagingmodule.c!) + +NONE = 0 + +# transpose +FLIP_LEFT_RIGHT = 0 +FLIP_TOP_BOTTOM = 1 +ROTATE_90 = 2 +ROTATE_180 = 3 +ROTATE_270 = 4 + +# transforms +AFFINE = 0 +EXTENT = 1 +PERSPECTIVE = 2 +QUAD = 3 +MESH = 4 + +# resampling filters +NONE = 0 +NEAREST = 0 +ANTIALIAS = 1 # 3-lobed lanczos +LINEAR = BILINEAR = 2 +CUBIC = BICUBIC = 3 + +# dithers +NONE = 0 +NEAREST = 0 +ORDERED = 1 # Not yet implemented +RASTERIZE = 2 # Not yet implemented +FLOYDSTEINBERG = 3 # default + +# palettes/quantizers +WEB = 0 +ADAPTIVE = 1 + +# categories +NORMAL = 0 +SEQUENCE = 1 +CONTAINER = 2 + +# -------------------------------------------------------------------- +# Registries + +ID = [] +OPEN = {} +MIME = {} +SAVE = {} +EXTENSION = {} + +# -------------------------------------------------------------------- +# Modes supported by this version + +_MODEINFO = { + # NOTE: this table will be removed in future versions. use + # getmode* functions or ImageMode descriptors instead. + + # official modes + "1": ("L", "L", ("1",)), + "L": ("L", "L", ("L",)), + "I": ("L", "I", ("I",)), + "F": ("L", "F", ("F",)), + "P": ("RGB", "L", ("P",)), + "RGB": ("RGB", "L", ("R", "G", "B")), + "RGBX": ("RGB", "L", ("R", "G", "B", "X")), + "RGBA": ("RGB", "L", ("R", "G", "B", "A")), + "CMYK": ("RGB", "L", ("C", "M", "Y", "K")), + "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr")), + + # Experimental modes include I;16, I;16L, I;16B, RGBa, BGR;15, and + # BGR;24. Use these modes only if you know exactly what you're + # doing... + +} + +try: + byteorder = sys.byteorder +except AttributeError: + import struct + if struct.unpack("h", "\0\1")[0] == 1: + byteorder = "big" + else: + byteorder = "little" + +if byteorder == 'little': + _ENDIAN = '<' +else: + _ENDIAN = '>' + +_MODE_CONV = { + # official modes + "1": ('|b1', None), # broken + "L": ('|u1', None), + "I": (_ENDIAN + 'i4', None), + "F": (_ENDIAN + 'f4', None), + "P": ('|u1', None), + "RGB": ('|u1', 3), + "RGBX": ('|u1', 4), + "RGBA": ('|u1', 4), + "CMYK": ('|u1', 4), + "YCbCr": ('|u1', 4), +} + +def _conv_type_shape(im): + shape = im.size[1], im.size[0] + typ, extra = _MODE_CONV[im.mode] + if extra is None: + return shape, typ + else: + return shape+(extra,), typ + + +MODES = _MODEINFO.keys() +MODES.sort() + +# raw modes that may be memory mapped. NOTE: if you change this, you +# may have to modify the stride calculation in map.c too! +_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B") + +## +# Gets the "base" mode for given mode. This function returns "L" for +# images that contain grayscale data, and "RGB" for images that +# contain color data. +# +# @param mode Input mode. +# @return "L" or "RGB". +# @exception KeyError If the input mode was not a standard mode. + +def getmodebase(mode): + return ImageMode.getmode(mode).basemode + +## +# Gets the storage type mode. Given a mode, this function returns a +# single-layer mode suitable for storing individual bands. +# +# @param mode Input mode. +# @return "L", "I", or "F". +# @exception KeyError If the input mode was not a standard mode. + +def getmodetype(mode): + return ImageMode.getmode(mode).basetype + +## +# Gets a list of individual band names. Given a mode, this function +# returns a tuple containing the names of individual bands (use +# {@link #getmodetype} to get the mode used to store each individual +# band. +# +# @param mode Input mode. +# @return A tuple containing band names. The length of the tuple +# gives the number of bands in an image of the given mode. +# @exception KeyError If the input mode was not a standard mode. + +def getmodebandnames(mode): + return ImageMode.getmode(mode).bands + +## +# Gets the number of individual bands for this mode. +# +# @param mode Input mode. +# @return The number of bands in this mode. +# @exception KeyError If the input mode was not a standard mode. + +def getmodebands(mode): + return len(ImageMode.getmode(mode).bands) + +# -------------------------------------------------------------------- +# Helpers + +_initialized = 0 + +## +# Explicitly loads standard file format drivers. + +def preinit(): + "Load standard file format drivers." + + global _initialized + if _initialized >= 1: + return + + try: + import BmpImagePlugin + except ImportError: + pass + try: + import GifImagePlugin + except ImportError: + pass + try: + import JpegImagePlugin + except ImportError: + pass + try: + import PpmImagePlugin + except ImportError: + pass + try: + import PngImagePlugin + except ImportError: + pass +# try: +# import TiffImagePlugin +# except ImportError: +# pass + + _initialized = 1 + +## +# Explicitly initializes the Python Imaging Library. This function +# loads all available file format drivers. + +def init(): + "Load all file format drivers." + + global _initialized + if _initialized >= 2: + return 0 + + visited = {} + + directories = sys.path + + try: + directories = directories + [os.path.dirname(__file__)] + except NameError: + pass + + # only check directories (including current, if present in the path) + for directory in filter(isDirectory, directories): + fullpath = os.path.abspath(directory) + if visited.has_key(fullpath): + continue + for file in os.listdir(directory): + if file[-14:] == "ImagePlugin.py": + f, e = os.path.splitext(file) + try: + sys.path.insert(0, directory) + try: + __import__(f, globals(), locals(), []) + finally: + del sys.path[0] + except ImportError: + if DEBUG: + print "Image: failed to import", + print f, ":", sys.exc_value + visited[fullpath] = None + + if OPEN or SAVE: + _initialized = 2 + return 1 + +# -------------------------------------------------------------------- +# Codec factories (used by tostring/fromstring and ImageFile.load) + +def _getdecoder(mode, decoder_name, args, extra=()): + + # tweak arguments + if args is None: + args = () + elif not isTupleType(args): + args = (args,) + + try: + # get decoder + decoder = getattr(core, decoder_name + "_decoder") + # print decoder, (mode,) + args + extra + return apply(decoder, (mode,) + args + extra) + except AttributeError: + raise IOError("decoder %s not available" % decoder_name) + +def _getencoder(mode, encoder_name, args, extra=()): + + # tweak arguments + if args is None: + args = () + elif not isTupleType(args): + args = (args,) + + try: + # get encoder + encoder = getattr(core, encoder_name + "_encoder") + # print encoder, (mode,) + args + extra + return apply(encoder, (mode,) + args + extra) + except AttributeError: + raise IOError("encoder %s not available" % encoder_name) + + +# -------------------------------------------------------------------- +# Simple expression analyzer + +class _E: + def __init__(self, data): self.data = data + def __coerce__(self, other): return self, _E(other) + def __add__(self, other): return _E((self.data, "__add__", other.data)) + def __mul__(self, other): return _E((self.data, "__mul__", other.data)) + +def _getscaleoffset(expr): + stub = ["stub"] + data = expr(_E(stub)).data + try: + (a, b, c) = data # simplified syntax + if (a is stub and b == "__mul__" and isNumberType(c)): + return c, 0.0 + if (a is stub and b == "__add__" and isNumberType(c)): + return 1.0, c + except TypeError: pass + try: + ((a, b, c), d, e) = data # full syntax + if (a is stub and b == "__mul__" and isNumberType(c) and + d == "__add__" and isNumberType(e)): + return c, e + except TypeError: pass + raise ValueError("illegal expression") + + +# -------------------------------------------------------------------- +# Implementation wrapper + +## +# This class represents an image object. To create Image objects, use +# the appropriate factory functions. There's hardly ever any reason +# to call the Image constructor directly. +# +# @see #open +# @see #new +# @see #fromstring + +class Image: + + format = None + format_description = None + + def __init__(self): + # FIXME: take "new" parameters / other image? + # FIXME: turn mode and size into delegating properties? + self.im = None + self.mode = "" + self.size = (0, 0) + self.palette = None + self.info = {} + self.category = NORMAL + self.readonly = 0 + + def _new(self, im): + new = Image() + new.im = im + new.mode = im.mode + new.size = im.size + new.palette = self.palette + if im.mode == "P": + new.palette = ImagePalette.ImagePalette() + try: + new.info = self.info.copy() + except AttributeError: + # fallback (pre-1.5.2) + new.info = {} + for k, v in self.info: + new.info[k] = v + return new + + _makeself = _new # compatibility + + def _copy(self): + self.load() + self.im = self.im.copy() + self.readonly = 0 + + def _dump(self, file=None, format=None): + import tempfile + if not file: + file = tempfile.mktemp() + self.load() + if not format or format == "PPM": + self.im.save_ppm(file) + else: + file = file + "." + format + self.save(file, format) + return file + + def __repr__(self): + return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % ( + self.__class__.__module__, self.__class__.__name__, + self.mode, self.size[0], self.size[1], + id(self) + ) + + def __getattr__(self, name): + if name == "__array_interface__": + # numpy array interface support + new = {} + shape, typestr = _conv_type_shape(self) + new['shape'] = shape + new['typestr'] = typestr + new['data'] = self.tostring() + return new + raise AttributeError(name) + + ## + # Returns a string containing pixel data. + # + # @param encoder_name What encoder to use. The default is to + # use the standard "raw" encoder. + # @param *args Extra arguments to the encoder. + # @return An 8-bit string. + + def tostring(self, encoder_name="raw", *args): + "Return image as a binary string" + + # may pass tuple instead of argument list + if len(args) == 1 and isTupleType(args[0]): + args = args[0] + + if encoder_name == "raw" and args == (): + args = self.mode + + self.load() + + # unpack data + e = _getencoder(self.mode, encoder_name, args) + e.setimage(self.im) + + bufsize = max(65536, self.size[0] * 4) # see RawEncode.c + + data = [] + while 1: + l, s, d = e.encode(bufsize) + data.append(d) + if s: + break + if s < 0: + raise RuntimeError("encoder error %d in tostring" % s) + + return string.join(data, "") + + ## + # Returns the image converted to an X11 bitmap. This method + # only works for mode "1" images. + # + # @param name The name prefix to use for the bitmap variables. + # @return A string containing an X11 bitmap. + # @exception ValueError If the mode is not "1" + + def tobitmap(self, name="image"): + "Return image as an XBM bitmap" + + self.load() + if self.mode != "1": + raise ValueError("not a bitmap") + data = self.tostring("xbm") + return string.join(["#define %s_width %d\n" % (name, self.size[0]), + "#define %s_height %d\n"% (name, self.size[1]), + "static char %s_bits[] = {\n" % name, data, "};"], "") + + ## + # Loads this image with pixel data from a string. + #

+ # This method is similar to the {@link #fromstring} function, but + # loads data into this image instead of creating a new image + # object. + + def fromstring(self, data, decoder_name="raw", *args): + "Load data to image from binary string" + + # may pass tuple instead of argument list + if len(args) == 1 and isTupleType(args[0]): + args = args[0] + + # default format + if decoder_name == "raw" and args == (): + args = self.mode + + # unpack data + d = _getdecoder(self.mode, decoder_name, args) + d.setimage(self.im) + s = d.decode(data) + + if s[0] >= 0: + raise ValueError("not enough image data") + if s[1] != 0: + raise ValueError("cannot decode image data") + + ## + # Allocates storage for the image and loads the pixel data. In + # normal cases, you don't need to call this method, since the + # Image class automatically loads an opened image when it is + # accessed for the first time. + # + # @return An image access object. + + def load(self): + "Explicitly load pixel data." + if self.im and self.palette and self.palette.dirty: + # realize palette + apply(self.im.putpalette, self.palette.getdata()) + self.palette.dirty = 0 + self.palette.mode = "RGB" + self.palette.rawmode = None + if self.info.has_key("transparency"): + self.im.putpalettealpha(self.info["transparency"], 0) + self.palette.mode = "RGBA" + if self.im: + return self.im.pixel_access(self.readonly) + + ## + # Verifies the contents of a file. For data read from a file, this + # method attempts to determine if the file is broken, without + # actually decoding the image data. If this method finds any + # problems, it raises suitable exceptions. If you need to load + # the image after using this method, you must reopen the image + # file. + + def verify(self): + "Verify file contents." + pass + + ## + # Returns a converted copy of this image. For the "P" mode, this + # method translates pixels through the palette. If mode is + # omitted, a mode is chosen so that all information in the image + # and the palette can be represented without a palette. + #

+ # The current version supports all possible conversions between + # "L", "RGB" and "CMYK." + #

+ # When translating a colour image to black and white (mode "L"), + # the library uses the ITU-R 601-2 luma transform: + #

+ # L = R * 299/1000 + G * 587/1000 + B * 114/1000 + #

+ # When translating a greyscale image into a bilevel image (mode + # "1"), all non-zero values are set to 255 (white). To use other + # thresholds, use the {@link #Image.point} method. + # + # @def convert(mode, matrix=None, **options) + # @param mode The requested mode. + # @param matrix An optional conversion matrix. If given, this + # should be 4- or 16-tuple containing floating point values. + # @param options Additional options, given as keyword arguments. + # @keyparam dither Dithering method, used when converting from + # mode "RGB" to "P". + # Available methods are NONE or FLOYDSTEINBERG (default). + # @keyparam palette Palette to use when converting from mode "RGB" + # to "P". Available palettes are WEB or ADAPTIVE. + # @keyparam colors Number of colors to use for the ADAPTIVE palette. + # Defaults to 256. + # @return An Image object. + + def convert(self, mode=None, data=None, dither=None, + palette=WEB, colors=256): + "Convert to other pixel format" + + if not mode: + # determine default mode + if self.mode == "P": + self.load() + if self.palette: + mode = self.palette.mode + else: + mode = "RGB" + else: + return self.copy() + + self.load() + + if data: + # matrix conversion + if mode not in ("L", "RGB"): + raise ValueError("illegal conversion") + im = self.im.convert_matrix(mode, data) + return self._new(im) + + if mode == "P" and palette == ADAPTIVE: + im = self.im.quantize(colors) + return self._new(im) + + # colourspace conversion + if dither is None: + dither = FLOYDSTEINBERG + + try: + im = self.im.convert(mode, dither) + except ValueError: + try: + # normalize source image and try again + im = self.im.convert(getmodebase(self.mode)) + im = im.convert(mode, dither) + except KeyError: + raise ValueError("illegal conversion") + + return self._new(im) + + def quantize(self, colors=256, method=0, kmeans=0, palette=None): + + # methods: + # 0 = median cut + # 1 = maximum coverage + + # NOTE: this functionality will be moved to the extended + # quantizer interface in a later version of PIL. + + self.load() + + if palette: + # use palette from reference image + palette.load() + if palette.mode != "P": + raise ValueError("bad mode for palette image") + if self.mode != "RGB" and self.mode != "L": + raise ValueError( + "only RGB or L mode images can be quantized to a palette" + ) + im = self.im.convert("P", 1, palette.im) + return self._makeself(im) + + im = self.im.quantize(colors, method, kmeans) + return self._new(im) + + ## + # Copies this image. Use this method if you wish to paste things + # into an image, but still retain the original. + # + # @return An Image object. + + def copy(self): + "Copy raster data" + + self.load() + im = self.im.copy() + return self._new(im) + + ## + # Returns a rectangular region from this image. The box is a + # 4-tuple defining the left, upper, right, and lower pixel + # coordinate. + #

+ # This is a lazy operation. Changes to the source image may or + # may not be reflected in the cropped image. To break the + # connection, call the {@link #Image.load} method on the cropped + # copy. + # + # @param The crop rectangle, as a (left, upper, right, lower)-tuple. + # @return An Image object. + + def crop(self, box=None): + "Crop region from image" + + self.load() + if box is None: + return self.copy() + + # lazy operation + return _ImageCrop(self, box) + + ## + # Configures the image file loader so it returns a version of the + # image that as closely as possible matches the given mode and + # size. For example, you can use this method to convert a colour + # JPEG to greyscale while loading it, or to extract a 128x192 + # version from a PCD file. + #

+ # Note that this method modifies the Image object in place. If + # the image has already been loaded, this method has no effect. + # + # @param mode The requested mode. + # @param size The requested size. + + def draft(self, mode, size): + "Configure image decoder" + + pass + + def _expand(self, xmargin, ymargin=None): + if ymargin is None: + ymargin = xmargin + self.load() + return self._new(self.im.expand(xmargin, ymargin, 0)) + + ## + # Filters this image using the given filter. For a list of + # available filters, see the ImageFilter module. + # + # @param filter Filter kernel. + # @return An Image object. + # @see ImageFilter + + def filter(self, filter): + "Apply environment filter to image" + + self.load() + + if callable(filter): + filter = filter() + if not hasattr(filter, "filter"): + raise TypeError("filter argument should be ImageFilter.Filter instance or class") + + if self.im.bands == 1: + return self._new(filter.filter(self.im)) + # fix to handle multiband images since _imaging doesn't + ims = [] + for c in range(self.im.bands): + ims.append(self._new(filter.filter(self.im.getband(c)))) + return merge(self.mode, ims) + + ## + # Returns a tuple containing the name of each band in this image. + # For example, getbands on an RGB image returns ("R", "G", "B"). + # + # @return A tuple containing band names. + + def getbands(self): + "Get band names" + + return ImageMode.getmode(self.mode).bands + + ## + # Calculates the bounding box of the non-zero regions in the + # image. + # + # @return The bounding box is returned as a 4-tuple defining the + # left, upper, right, and lower pixel coordinate. If the image + # is completely empty, this method returns None. + + def getbbox(self): + "Get bounding box of actual data (non-zero pixels) in image" + + self.load() + return self.im.getbbox() + + ## + # Returns a list of colors used in this image. + # + # @param maxcolors Maximum number of colors. If this number is + # exceeded, this method returns None. The default limit is + # 256 colors. + # @return An unsorted list of (count, pixel) values. + + def getcolors(self, maxcolors=256): + "Get colors from image, up to given limit" + + self.load() + if self.mode in ("1", "L", "P"): + h = self.im.histogram() + out = [] + for i in range(256): + if h[i]: + out.append((h[i], i)) + if len(out) > maxcolors: + return None + return out + return self.im.getcolors(maxcolors) + + ## + # Returns the contents of this image as a sequence object + # containing pixel values. The sequence object is flattened, so + # that values for line one follow directly after the values of + # line zero, and so on. + #

+ # Note that the sequence object returned by this method is an + # internal PIL data type, which only supports certain sequence + # operations. To convert it to an ordinary sequence (e.g. for + # printing), use list(im.getdata()). + # + # @param band What band to return. The default is to return + # all bands. To return a single band, pass in the index + # value (e.g. 0 to get the "R" band from an "RGB" image). + # @return A sequence-like object. + + def getdata(self, band = None): + "Get image data as sequence object." + + self.load() + if band is not None: + return self.im.getband(band) + return self.im # could be abused + + ## + # Gets the the minimum and maximum pixel values for each band in + # the image. + # + # @return For a single-band image, a 2-tuple containing the + # minimum and maximum pixel value. For a multi-band image, + # a tuple containing one 2-tuple for each band. + + def getextrema(self): + "Get min/max value" + + self.load() + if self.im.bands > 1: + extrema = [] + for i in range(self.im.bands): + extrema.append(self.im.getband(i).getextrema()) + return tuple(extrema) + return self.im.getextrema() + + ## + # Returns a PyCObject that points to the internal image memory. + # + # @return A PyCObject object. + + def getim(self): + "Get PyCObject pointer to internal image memory" + + self.load() + return self.im.ptr + + + ## + # Returns the image palette as a list. + # + # @return A list of color values [r, g, b, ...], or None if the + # image has no palette. + + def getpalette(self): + "Get palette contents." + + self.load() + try: + return map(ord, self.im.getpalette()) + except ValueError: + return None # no palette + + + ## + # Returns the pixel value at a given position. + # + # @param xy The coordinate, given as (x, y). + # @return The pixel value. If the image is a multi-layer image, + # this method returns a tuple. + + def getpixel(self, xy): + "Get pixel value" + + self.load() + return self.im.getpixel(xy) + + ## + # Returns the horizontal and vertical projection. + # + # @return Two sequences, indicating where there are non-zero + # pixels along the X-axis and the Y-axis, respectively. + + def getprojection(self): + "Get projection to x and y axes" + + self.load() + x, y = self.im.getprojection() + return map(ord, x), map(ord, y) + + ## + # Returns a histogram for the image. The histogram is returned as + # a list of pixel counts, one for each pixel value in the source + # image. If the image has more than one band, the histograms for + # all bands are concatenated (for example, the histogram for an + # "RGB" image contains 768 values). + #

+ # A bilevel image (mode "1") is treated as a greyscale ("L") image + # by this method. + #

+ # If a mask is provided, the method returns a histogram for those + # parts of the image where the mask image is non-zero. The mask + # image must have the same size as the image, and be either a + # bi-level image (mode "1") or a greyscale image ("L"). + # + # @def histogram(mask=None) + # @param mask An optional mask. + # @return A list containing pixel counts. + + def histogram(self, mask=None, extrema=None): + "Take histogram of image" + + self.load() + if mask: + mask.load() + return self.im.histogram((0, 0), mask.im) + if self.mode in ("I", "F"): + if extrema is None: + extrema = self.getextrema() + return self.im.histogram(extrema) + return self.im.histogram() + + ## + # (Deprecated) Returns a copy of the image where the data has been + # offset by the given distances. Data wraps around the edges. If + # yoffset is omitted, it is assumed to be equal to xoffset. + #

+ # This method is deprecated. New code should use the offset + # function in the ImageChops module. + # + # @param xoffset The horizontal distance. + # @param yoffset The vertical distance. If omitted, both + # distances are set to the same value. + # @return An Image object. + + def offset(self, xoffset, yoffset=None): + "(deprecated) Offset image in horizontal and/or vertical direction" + if warnings: + warnings.warn( + "'offset' is deprecated; use 'ImageChops.offset' instead", + DeprecationWarning, stacklevel=2 + ) + import ImageChops + return ImageChops.offset(self, xoffset, yoffset) + + ## + # Pastes another image into this image. The box argument is either + # a 2-tuple giving the upper left corner, a 4-tuple defining the + # left, upper, right, and lower pixel coordinate, or None (same as + # (0, 0)). If a 4-tuple is given, the size of the pasted image + # must match the size of the region. + #

+ # If the modes don't match, the pasted image is converted to the + # mode of this image (see the {@link #Image.convert} method for + # details). + #

+ # Instead of an image, the source can be a integer or tuple + # containing pixel values. The method then fills the region + # with the given colour. When creating RGB images, you can + # also use colour strings as supported by the ImageColor module. + #

+ # If a mask is given, this method updates only the regions + # indicated by the mask. You can use either "1", "L" or "RGBA" + # images (in the latter case, the alpha band is used as mask). + # Where the mask is 255, the given image is copied as is. Where + # the mask is 0, the current value is preserved. Intermediate + # values can be used for transparency effects. + #

+ # Note that if you paste an "RGBA" image, the alpha band is + # ignored. You can work around this by using the same image as + # both source image and mask. + # + # @param im Source image or pixel value (integer or tuple). + # @param box An optional 4-tuple giving the region to paste into. + # If a 2-tuple is used instead, it's treated as the upper left + # corner. If omitted or None, the source is pasted into the + # upper left corner. + #

+ # If an image is given as the second argument and there is no + # third, the box defaults to (0, 0), and the second argument + # is interpreted as a mask image. + # @param mask An optional mask image. + # @return An Image object. + + def paste(self, im, box=None, mask=None): + "Paste other image into region" + + if isImageType(box) and mask is None: + # abbreviated paste(im, mask) syntax + mask = box; box = None + + if box is None: + # cover all of self + box = (0, 0) + self.size + + if len(box) == 2: + # lower left corner given; get size from image or mask + if isImageType(im): + size = im.size + elif isImageType(mask): + size = mask.size + else: + # FIXME: use self.size here? + raise ValueError( + "cannot determine region size; use 4-item box" + ) + box = box + (box[0]+size[0], box[1]+size[1]) + + if isStringType(im): + import ImageColor + im = ImageColor.getcolor(im, self.mode) + + elif isImageType(im): + im.load() + if self.mode != im.mode: + if self.mode != "RGB" or im.mode not in ("RGBA", "RGBa"): + # should use an adapter for this! + im = im.convert(self.mode) + im = im.im + + self.load() + if self.readonly: + self._copy() + + if mask: + mask.load() + self.im.paste(im, box, mask.im) + else: + self.im.paste(im, box) + + ## + # Maps this image through a lookup table or function. + # + # @param lut A lookup table, containing 256 values per band in the + # image. A function can be used instead, it should take a single + # argument. The function is called once for each possible pixel + # value, and the resulting table is applied to all bands of the + # image. + # @param mode Output mode (default is same as input). In the + # current version, this can only be used if the source image + # has mode "L" or "P", and the output has mode "1". + # @return An Image object. + + def point(self, lut, mode=None): + "Map image through lookup table" + + self.load() + + if isinstance(lut, ImagePointHandler): + return lut.point(self) + + if not isSequenceType(lut): + # if it isn't a list, it should be a function + if self.mode in ("I", "I;16", "F"): + # check if the function can be used with point_transform + scale, offset = _getscaleoffset(lut) + return self._new(self.im.point_transform(scale, offset)) + # for other modes, convert the function to a table + lut = map(lut, range(256)) * self.im.bands + + if self.mode == "F": + # FIXME: _imaging returns a confusing error message for this case + raise ValueError("point operation not supported for this mode") + + return self._new(self.im.point(lut, mode)) + + ## + # Adds or replaces the alpha layer in this image. If the image + # does not have an alpha layer, it's converted to "LA" or "RGBA". + # The new layer must be either "L" or "1". + # + # @param im The new alpha layer. This can either be an "L" or "1" + # image having the same size as this image, or an integer or + # other color value. + + def putalpha(self, alpha): + "Set alpha layer" + + self.load() + if self.readonly: + self._copy() + + if self.mode not in ("LA", "RGBA"): + # attempt to promote self to a matching alpha mode + try: + mode = getmodebase(self.mode) + "A" + try: + self.im.setmode(mode) + except (AttributeError, ValueError): + # do things the hard way + im = self.im.convert(mode) + if im.mode not in ("LA", "RGBA"): + raise ValueError # sanity check + self.im = im + self.mode = self.im.mode + except (KeyError, ValueError): + raise ValueError("illegal image mode") + + if self.mode == "LA": + band = 1 + else: + band = 3 + + if isImageType(alpha): + # alpha layer + if alpha.mode not in ("1", "L"): + raise ValueError("illegal image mode") + alpha.load() + if alpha.mode == "1": + alpha = alpha.convert("L") + else: + # constant alpha + try: + self.im.fillband(band, alpha) + except (AttributeError, ValueError): + # do things the hard way + alpha = new("L", self.size, alpha) + else: + return + + self.im.putband(alpha.im, band) + + ## + # Copies pixel data to this image. This method copies data from a + # sequence object into the image, starting at the upper left + # corner (0, 0), and continuing until either the image or the + # sequence ends. The scale and offset values are used to adjust + # the sequence values: pixel = value*scale + offset. + # + # @param data A sequence object. + # @param scale An optional scale value. The default is 1.0. + # @param offset An optional offset value. The default is 0.0. + + def putdata(self, data, scale=1.0, offset=0.0): + "Put data from a sequence object into an image." + + self.load() + if self.readonly: + self._copy() + + self.im.putdata(data, scale, offset) + + ## + # Attaches a palette to this image. The image must be a "P" or + # "L" image, and the palette sequence must contain 768 integer + # values, where each group of three values represent the red, + # green, and blue values for the corresponding pixel + # index. Instead of an integer sequence, you can use an 8-bit + # string. + # + # @def putpalette(data) + # @param data A palette sequence (either a list or a string). + + def putpalette(self, data, rawmode="RGB"): + "Put palette data into an image." + + if self.mode not in ("L", "P"): + raise ValueError("illegal image mode") + self.load() + if isinstance(data, ImagePalette.ImagePalette): + palette = ImagePalette.raw(data.rawmode, data.palette) + else: + if not isStringType(data): + data = string.join(map(chr, data), "") + palette = ImagePalette.raw(rawmode, data) + self.mode = "P" + self.palette = palette + self.palette.mode = "RGB" + self.load() # install new palette + + ## + # Modifies the pixel at the given position. The colour is given as + # a single numerical value for single-band images, and a tuple for + # multi-band images. + #

+ # Note that this method is relatively slow. For more extensive + # changes, use {@link #Image.paste} or the ImageDraw module + # instead. + # + # @param xy The pixel coordinate, given as (x, y). + # @param value The pixel value. + # @see #Image.paste + # @see #Image.putdata + # @see ImageDraw + + def putpixel(self, xy, value): + "Set pixel value" + + self.load() + if self.readonly: + self._copy() + + return self.im.putpixel(xy, value) + + ## + # Returns a resized copy of this image. + # + # @def resize(size, filter=NEAREST) + # @param size The requested size in pixels, as a 2-tuple: + # (width, height). + # @param filter An optional resampling filter. This can be + # one of NEAREST (use nearest neighbour), BILINEAR + # (linear interpolation in a 2x2 environment), BICUBIC + # (cubic spline interpolation in a 4x4 environment), or + # ANTIALIAS (a high-quality downsampling filter). + # If omitted, or if the image has mode "1" or "P", it is + # set NEAREST. + # @return An Image object. + + def resize(self, size, resample=NEAREST): + "Resize image" + + if resample not in (NEAREST, BILINEAR, BICUBIC, ANTIALIAS): + raise ValueError("unknown resampling filter") + + self.load() + + if self.mode in ("1", "P"): + resample = NEAREST + + if resample == ANTIALIAS: + # requires stretch support (imToolkit & PIL 1.1.3) + try: + im = self.im.stretch(size, resample) + except AttributeError: + raise ValueError("unsupported resampling filter") + else: + im = self.im.resize(size, resample) + + return self._new(im) + + ## + # Returns a rotated copy of this image. This method returns a + # copy of this image, rotated the given number of degrees counter + # clockwise around its centre. + # + # @def rotate(angle, filter=NEAREST) + # @param angle In degrees counter clockwise. + # @param filter An optional resampling filter. This can be + # one of NEAREST (use nearest neighbour), BILINEAR + # (linear interpolation in a 2x2 environment), or BICUBIC + # (cubic spline interpolation in a 4x4 environment). + # If omitted, or if the image has mode "1" or "P", it is + # set NEAREST. + # @param expand Optional expansion flag. If true, expands the output + # image to make it large enough to hold the entire rotated image. + # If false or omitted, make the output image the same size as the + # input image. + # @return An Image object. + + def rotate(self, angle, resample=NEAREST, expand=0): + "Rotate image. Angle given as degrees counter-clockwise." + + if expand: + import math + angle = -angle * math.pi / 180 + matrix = [ + math.cos(angle), math.sin(angle), 0.0, + -math.sin(angle), math.cos(angle), 0.0 + ] + def transform(x, y, (a, b, c, d, e, f)=matrix): + return a*x + b*y + c, d*x + e*y + f + + # calculate output size + w, h = self.size + xx = [] + yy = [] + for x, y in ((0, 0), (w, 0), (w, h), (0, h)): + x, y = transform(x, y) + xx.append(x) + yy.append(y) + w = int(math.ceil(max(xx)) - math.floor(min(xx))) + h = int(math.ceil(max(yy)) - math.floor(min(yy))) + + # adjust center + x, y = transform(w / 2.0, h / 2.0) + matrix[2] = self.size[0] / 2.0 - x + matrix[5] = self.size[1] / 2.0 - y + + return self.transform((w, h), AFFINE, matrix, resample) + + if resample not in (NEAREST, BILINEAR, BICUBIC): + raise ValueError("unknown resampling filter") + + self.load() + + if self.mode in ("1", "P"): + resample = NEAREST + + return self._new(self.im.rotate(angle, resample)) + + ## + # Saves this image under the given filename. If no format is + # specified, the format to use is determined from the filename + # extension, if possible. + #

+ # Keyword options can be used to provide additional instructions + # to the writer. If a writer doesn't recognise an option, it is + # silently ignored. The available options are described later in + # this handbook. + #

+ # You can use a file object instead of a filename. In this case, + # you must always specify the format. The file object must + # implement the seek, tell, and write + # methods, and be opened in binary mode. + # + # @def save(file, format=None, **options) + # @param file File name or file object. + # @param format Optional format override. If omitted, the + # format to use is determined from the filename extension. + # If a file object was used instead of a filename, this + # parameter should always be used. + # @param **options Extra parameters to the image writer. + # @return None + # @exception KeyError If the output format could not be determined + # from the file name. Use the format option to solve this. + # @exception IOError If the file could not be written. The file + # may have been created, and may contain partial data. + + def save(self, fp, format=None, **params): + "Save image to file or stream" + + if isStringType(fp): + filename = fp + else: + if hasattr(fp, "name") and isStringType(fp.name): + filename = fp.name + else: + filename = "" + + # may mutate self! + self.load() + + self.encoderinfo = params + self.encoderconfig = () + + preinit() + + ext = string.lower(os.path.splitext(filename)[1]) + + if not format: + try: + format = EXTENSION[ext] + except KeyError: + init() + try: + format = EXTENSION[ext] + except KeyError: + raise KeyError(ext) # unknown extension + + try: + save_handler = SAVE[string.upper(format)] + except KeyError: + init() + save_handler = SAVE[string.upper(format)] # unknown format + + if isStringType(fp): + import __builtin__ + fp = __builtin__.open(fp, "wb") + close = 1 + else: + close = 0 + + try: + save_handler(self, fp, filename) + finally: + # do what we can to clean up + if close: + fp.close() + + ## + # Seeks to the given frame in this sequence file. If you seek + # beyond the end of the sequence, the method raises an + # EOFError exception. When a sequence file is opened, the + # library automatically seeks to frame 0. + #

+ # Note that in the current version of the library, most sequence + # formats only allows you to seek to the next frame. + # + # @param frame Frame number, starting at 0. + # @exception EOFError If the call attempts to seek beyond the end + # of the sequence. + # @see #Image.tell + + def seek(self, frame): + "Seek to given frame in sequence file" + + # overridden by file handlers + if frame != 0: + raise EOFError + + ## + # Displays this image. This method is mainly intended for + # debugging purposes. + #

+ # On Unix platforms, this method saves the image to a temporary + # PPM file, and calls the xv utility. + #

+ # On Windows, it saves the image to a temporary BMP file, and uses + # the standard BMP display utility to show it (usually Paint). + # + # @def show(title=None) + # @param title Optional title to use for the image window, + # where possible. + + def show(self, title=None, command=None): + "Display image (for debug purposes only)" + + _show(self, title=title, command=command) + + ## + # Split this image into individual bands. This method returns a + # tuple of individual image bands from an image. For example, + # splitting an "RGB" image creates three new images each + # containing a copy of one of the original bands (red, green, + # blue). + # + # @return A tuple containing bands. + + def split(self): + "Split image into bands" + + if self.im.bands == 1: + ims = [self.copy()] + else: + ims = [] + self.load() + for i in range(self.im.bands): + ims.append(self._new(self.im.getband(i))) + return tuple(ims) + + ## + # Returns the current frame number. + # + # @return Frame number, starting with 0. + # @see #Image.seek + + def tell(self): + "Return current frame number" + + return 0 + + ## + # Make this image into a thumbnail. This method modifies the + # image to contain a thumbnail version of itself, no larger than + # the given size. This method calculates an appropriate thumbnail + # size to preserve the aspect of the image, calls the {@link + # #Image.draft} method to configure the file reader (where + # applicable), and finally resizes the image. + #

+ # Note that the bilinear and bicubic filters in the current + # version of PIL are not well-suited for thumbnail generation. + # You should use ANTIALIAS unless speed is much more + # important than quality. + #

+ # Also note that this function modifies the Image object in place. + # If you need to use the full resolution image as well, apply this + # method to a {@link #Image.copy} of the original image. + # + # @param size Requested size. + # @param resample Optional resampling filter. This can be one + # of NEAREST, BILINEAR, BICUBIC, or + # ANTIALIAS (best quality). If omitted, it defaults + # to NEAREST (this will be changed to ANTIALIAS in a + # future version). + # @return None + + def thumbnail(self, size, resample=NEAREST): + "Create thumbnail representation (modifies image in place)" + + # FIXME: the default resampling filter will be changed + # to ANTIALIAS in future versions + + # preserve aspect ratio + x, y = self.size + if x > size[0]: y = max(y * size[0] / x, 1); x = size[0] + if y > size[1]: x = max(x * size[1] / y, 1); y = size[1] + size = x, y + + if size == self.size: + return + + self.draft(None, size) + + self.load() + + try: + im = self.resize(size, resample) + except ValueError: + if resample != ANTIALIAS: + raise + im = self.resize(size, NEAREST) # fallback + + self.im = im.im + self.mode = im.mode + self.size = size + + self.readonly = 0 + + # FIXME: the different tranform methods need further explanation + # instead of bloating the method docs, add a separate chapter. + + ## + # Transforms this image. This method creates a new image with the + # given size, and the same mode as the original, and copies data + # to the new image using the given transform. + #

+ # @def transform(size, method, data, resample=NEAREST) + # @param size The output size. + # @param method The transformation method. This is one of + # EXTENT (cut out a rectangular subregion), AFFINE + # (affine transform), PERSPECTIVE (perspective + # transform), QUAD (map a quadrilateral to a + # rectangle), or MESH (map a number of source quadrilaterals + # in one operation). + # @param data Extra data to the transformation method. + # @param resample Optional resampling filter. It can be one of + # NEAREST (use nearest neighbour), BILINEAR + # (linear interpolation in a 2x2 environment), or + # BICUBIC (cubic spline interpolation in a 4x4 + # environment). If omitted, or if the image has mode + # "1" or "P", it is set to NEAREST. + # @return An Image object. + + def transform(self, size, method, data=None, resample=NEAREST, fill=1): + "Transform image" + + if isinstance(method, ImageTransformHandler): + return method.transform(size, self, resample=resample, fill=fill) + if hasattr(method, "getdata"): + # compatibility w. old-style transform objects + method, data = method.getdata() + if data is None: + raise ValueError("missing method data") + im = new(self.mode, size, None) + if method == MESH: + # list of quads + for box, quad in data: + im.__transformer(box, self, QUAD, quad, resample, fill) + else: + im.__transformer((0, 0)+size, self, method, data, resample, fill) + + return im + + def __transformer(self, box, image, method, data, + resample=NEAREST, fill=1): + + # FIXME: this should be turned into a lazy operation (?) + + w = box[2]-box[0] + h = box[3]-box[1] + + if method == AFFINE: + # change argument order to match implementation + data = (data[2], data[0], data[1], + data[5], data[3], data[4]) + elif method == EXTENT: + # convert extent to an affine transform + x0, y0, x1, y1 = data + xs = float(x1 - x0) / w + ys = float(y1 - y0) / h + method = AFFINE + data = (x0 + xs/2, xs, 0, y0 + ys/2, 0, ys) + elif method == PERSPECTIVE: + # change argument order to match implementation + data = (data[2], data[0], data[1], + data[5], data[3], data[4], + data[6], data[7]) + elif method == QUAD: + # quadrilateral warp. data specifies the four corners + # given as NW, SW, SE, and NE. + nw = data[0:2]; sw = data[2:4]; se = data[4:6]; ne = data[6:8] + x0, y0 = nw; As = 1.0 / w; At = 1.0 / h + data = (x0, (ne[0]-x0)*As, (sw[0]-x0)*At, + (se[0]-sw[0]-ne[0]+x0)*As*At, + y0, (ne[1]-y0)*As, (sw[1]-y0)*At, + (se[1]-sw[1]-ne[1]+y0)*As*At) + else: + raise ValueError("unknown transformation method") + + if resample not in (NEAREST, BILINEAR, BICUBIC): + raise ValueError("unknown resampling filter") + + image.load() + + self.load() + + if image.mode in ("1", "P"): + resample = NEAREST + + self.im.transform2(box, image.im, method, data, resample, fill) + + ## + # Returns a flipped or rotated copy of this image. + # + # @param method One of FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, + # ROTATE_90, ROTATE_180, or ROTATE_270. + + def transpose(self, method): + "Transpose image (flip or rotate in 90 degree steps)" + + self.load() + im = self.im.transpose(method) + return self._new(im) + +# -------------------------------------------------------------------- +# Lazy operations + +class _ImageCrop(Image): + + def __init__(self, im, box): + + Image.__init__(self) + + x0, y0, x1, y1 = box + if x1 < x0: + x1 = x0 + if y1 < y0: + y1 = y0 + + self.mode = im.mode + self.size = x1-x0, y1-y0 + + self.__crop = x0, y0, x1, y1 + + self.im = im.im + + def load(self): + + # lazy evaluation! + if self.__crop: + self.im = self.im.crop(self.__crop) + self.__crop = None + + if self.im: + return self.im.pixel_access(self.readonly) + + # FIXME: future versions should optimize crop/paste + # sequences! + +# -------------------------------------------------------------------- +# Abstract handlers. + +class ImagePointHandler: + # used as a mixin by point transforms (for use with im.point) + pass + +class ImageTransformHandler: + # used as a mixin by geometry transforms (for use with im.transform) + pass + +# -------------------------------------------------------------------- +# Factories + +# +# Debugging + +def _wedge(): + "Create greyscale wedge (for debugging only)" + + return Image()._new(core.wedge("L")) + +## +# Creates a new image with the given mode and size. +# +# @param mode The mode to use for the new image. +# @param size A 2-tuple, containing (width, height) in pixels. +# @param color What colour to use for the image. Default is black. +# If given, this should be a single integer or floating point value +# for single-band modes, and a tuple for multi-band modes (one value +# per band). When creating RGB images, you can also use colour +# strings as supported by the ImageColor module. If the colour is +# None, the image is not initialised. +# @return An Image object. + +def new(mode, size, color=0): + "Create a new image" + + if color is None: + # don't initialize + return Image()._new(core.new(mode, size)) + + if isStringType(color): + # css3-style specifier + + import ImageColor + color = ImageColor.getcolor(color, mode) + + return Image()._new(core.fill(mode, size, color)) + +## +# Creates an image memory from pixel data in a string. +#

+# In its simplest form, this function takes three arguments +# (mode, size, and unpacked pixel data). +#

+# Note that this function decodes pixel data only, not entire images. +# If you have an entire image in a string, wrap it in a +# StringIO object, and use {@link #open} to load it. +# +# @param mode The image mode. +# @param size The image size. +# @param data An 8-bit string containing raw data for the given mode. +# @param decoder_name What decoder to use. +# @param *args Additional parameters for the given decoder. +# @return An Image object. + +def fromstring(mode, size, data, decoder_name="raw", *args): + "Load image from string" + + # may pass tuple instead of argument list + if len(args) == 1 and isTupleType(args[0]): + args = args[0] + + if decoder_name == "raw" and args == (): + args = mode + + im = new(mode, size) + im.fromstring(data, decoder_name, args) + return im + +## +# (New in 1.1.4) Creates an image memory from pixel data in a string +# or byte buffer. +#

+# This function is similar to {@link #fromstring}, but uses data in +# the byte buffer, where possible. This means that changes to the +# original buffer object are reflected in this image). Not all modes +# can share memory; supported modes include "L", "RGBX", "RGBA", and +# "CMYK". +#

+# Note that this function decodes pixel data only, not entire images. +# If you have an entire image file in a string, wrap it in a +# StringIO object, and use {@link #open} to load it. +#

+# In the current version, the default parameters used for the "raw" +# decoder differs from that used for {@link fromstring}. This is a +# bug, and will probably be fixed in a future release. The current +# release issues a warning if you do this; to disable the warning, +# you should provide the full set of parameters. See below for +# details. +# +# @param mode The image mode. +# @param size The image size. +# @param data An 8-bit string or other buffer object containing raw +# data for the given mode. +# @param decoder_name What decoder to use. +# @param *args Additional parameters for the given decoder. For the +# default encoder ("raw"), it's recommended that you provide the +# full set of parameters: +# frombuffer(mode, size, data, "raw", mode, 0, 1). +# @return An Image object. +# @since 1.1.4 + +def frombuffer(mode, size, data, decoder_name="raw", *args): + "Load image from string or buffer" + + # may pass tuple instead of argument list + if len(args) == 1 and isTupleType(args[0]): + args = args[0] + + if decoder_name == "raw": + if args == (): + if warnings: + warnings.warn( + "the frombuffer defaults may change in a future release; " + "for portability, change the call to read:\n" + " frombuffer(mode, size, data, 'raw', mode, 0, 1)", + RuntimeWarning, stacklevel=2 + ) + args = mode, 0, -1 # may change to (mode, 0, 1) post-1.1.6 + if args[0] in _MAPMODES: + im = new(mode, (1,1)) + im = im._new( + core.map_buffer(data, size, decoder_name, None, 0, args) + ) + im.readonly = 1 + return im + + return fromstring(mode, size, data, decoder_name, args) + + +## +# (New in 1.1.6) Creates an image memory from an object exporting +# the array interface (using the buffer protocol). +# +# If obj is not contiguous, then the tostring method is called +# and {@link frombuffer} is used. +# +# @param obj Object with array interface +# @param mode Mode to use (will be determined from type if None) +# @return An image memory. + +def fromarray(obj, mode=None): + arr = obj.__array_interface__ + shape = arr['shape'] + ndim = len(shape) + try: + strides = arr['strides'] + except KeyError: + strides = None + if mode is None: + try: + typekey = (1, 1) + shape[2:], arr['typestr'] + mode, rawmode = _fromarray_typemap[typekey] + except KeyError: + # print typekey + raise TypeError("Cannot handle this data type") + else: + rawmode = mode + if mode in ["1", "L", "I", "P", "F"]: + ndmax = 2 + elif mode == "RGB": + ndmax = 3 + else: + ndmax = 4 + if ndim > ndmax: + raise ValueError("Too many dimensions.") + + size = shape[1], shape[0] + if strides is not None: + obj = obj.tostring() + + return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) + +_fromarray_typemap = { + # (shape, typestr) => mode, rawmode + # first two members of shape are set to one + # ((1, 1), "|b1"): ("1", "1"), # broken + ((1, 1), "|u1"): ("L", "L"), + ((1, 1), "|i1"): ("I", "I;8"), + ((1, 1), "i2"): ("I", "I;16B"), + ((1, 1), "i4"): ("I", "I;32B"), + ((1, 1), "f4"): ("F", "F;32BF"), + ((1, 1), "f8"): ("F", "F;64BF"), + ((1, 1, 3), "|u1"): ("RGB", "RGB"), + ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), + } + +# shortcuts +_fromarray_typemap[((1, 1), _ENDIAN + "i4")] = ("I", "I") +_fromarray_typemap[((1, 1), _ENDIAN + "f4")] = ("F", "F") + +## +# Opens and identifies the given image file. +#

+# This is a lazy operation; this function identifies the file, but the +# actual image data is not read from the file until you try to process +# the data (or call the {@link #Image.load} method). +# +# @def open(file, mode="r") +# @param file A filename (string) or a file object. The file object +# must implement read, seek, and tell methods, +# and be opened in binary mode. +# @param mode The mode. If given, this argument must be "r". +# @return An Image object. +# @exception IOError If the file cannot be found, or the image cannot be +# opened and identified. +# @see #new + +def open(fp, mode="r"): + "Open an image file, without loading the raster data" + + if mode != "r": + raise ValueError("bad mode") + + if isStringType(fp): + import __builtin__ + filename = fp + fp = __builtin__.open(fp, "rb") + else: + filename = "" + + prefix = fp.read(16) + + preinit() + + for i in ID: + try: + factory, accept = OPEN[i] + if not accept or accept(prefix): + fp.seek(0) + return factory(fp, filename) + except (SyntaxError, IndexError, TypeError): + pass + + if init(): + + for i in ID: + try: + factory, accept = OPEN[i] + if not accept or accept(prefix): + fp.seek(0) + return factory(fp, filename) + except (SyntaxError, IndexError, TypeError): + pass + + raise IOError("cannot identify image file") + +# +# Image processing. + +## +# Creates a new image by interpolating between two input images, using +# a constant alpha. +# +#

+#    out = image1 * (1.0 - alpha) + image2 * alpha
+# 
+# +# @param im1 The first image. +# @param im2 The second image. Must have the same mode and size as +# the first image. +# @param alpha The interpolation alpha factor. If alpha is 0.0, a +# copy of the first image is returned. If alpha is 1.0, a copy of +# the second image is returned. There are no restrictions on the +# alpha value. If necessary, the result is clipped to fit into +# the allowed output range. +# @return An Image object. + +def blend(im1, im2, alpha): + "Interpolate between images." + + im1.load() + im2.load() + return im1._new(core.blend(im1.im, im2.im, alpha)) + +## +# Creates a new image by interpolating between two input images, +# using the mask as alpha. +# +# @param image1 The first image. +# @param image2 The second image. Must have the same mode and +# size as the first image. +# @param mask A mask image. This image can can have mode +# "1", "L", or "RGBA", and must have the same size as the +# other two images. + +def composite(image1, image2, mask): + "Create composite image by blending images using a transparency mask" + + image = image2.copy() + image.paste(image1, None, mask) + return image + +## +# Applies the function (which should take one argument) to each pixel +# in the given image. If the image has more than one band, the same +# function is applied to each band. Note that the function is +# evaluated once for each possible pixel value, so you cannot use +# random components or other generators. +# +# @def eval(image, function) +# @param image The input image. +# @param function A function object, taking one integer argument. +# @return An Image object. + +def eval(image, *args): + "Evaluate image expression" + + return image.point(args[0]) + +## +# Creates a new image from a number of single-band images. +# +# @param mode The mode to use for the output image. +# @param bands A sequence containing one single-band image for +# each band in the output image. All bands must have the +# same size. +# @return An Image object. + +def merge(mode, bands): + "Merge a set of single band images into a new multiband image." + + if getmodebands(mode) != len(bands) or "*" in mode: + raise ValueError("wrong number of bands") + for im in bands[1:]: + if im.mode != getmodetype(mode): + raise ValueError("mode mismatch") + if im.size != bands[0].size: + raise ValueError("size mismatch") + im = core.new(mode, bands[0].size) + for i in range(getmodebands(mode)): + bands[i].load() + im.putband(bands[i].im, i) + return bands[0]._new(im) + +# -------------------------------------------------------------------- +# Plugin registry + +## +# Register an image file plugin. This function should not be used +# in application code. +# +# @param id An image format identifier. +# @param factory An image file factory method. +# @param accept An optional function that can be used to quickly +# reject images having another format. + +def register_open(id, factory, accept=None): + id = string.upper(id) + ID.append(id) + OPEN[id] = factory, accept + +## +# Registers an image MIME type. This function should not be used +# in application code. +# +# @param id An image format identifier. +# @param mimetype The image MIME type for this format. + +def register_mime(id, mimetype): + MIME[string.upper(id)] = mimetype + +## +# Registers an image save function. This function should not be +# used in application code. +# +# @param id An image format identifier. +# @param driver A function to save images in this format. + +def register_save(id, driver): + SAVE[string.upper(id)] = driver + +## +# Registers an image extension. This function should not be +# used in application code. +# +# @param id An image format identifier. +# @param extension An extension used for this format. + +def register_extension(id, extension): + EXTENSION[string.lower(extension)] = string.upper(id) + + +# -------------------------------------------------------------------- +# Simple display support. User code may override this. + +def _show(image, **options): + # override me, as necessary + apply(_showxv, (image,), options) + +def _showxv(image, title=None, **options): + import ImageShow + apply(ImageShow.show, (image, title), options) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py new file mode 100755 index 00000000000..82861fc7a2c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py @@ -0,0 +1,302 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard channel operations +# +# History: +# 1996-03-24 fl Created +# 1996-08-13 fl Added logical operations (for "1" images) +# 2000-10-12 fl Added offset method (from Image.py) +# +# Copyright (c) 1997-2000 by Secret Labs AB +# Copyright (c) 1996-2000 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image + +## +# The ImageChops module contains a number of arithmetical image +# operations, called channel operations ("chops"). These can be +# used for various purposes, including special effects, image +# compositions, algorithmic painting, and more. +#

+# At this time, channel operations are only implemented for 8-bit +# images (e.g. "L" and "RGB"). +#

+# Most channel operations take one or two image arguments and returns +# a new image. Unless otherwise noted, the result of a channel +# operation is always clipped to the range 0 to MAX (which is 255 for +# all modes supported by the operations in this module). +## + +## +# Return an image with the same size as the given image, but filled +# with the given pixel value. +# +# @param image Reference image. +# @param value Pixel value. +# @return An image object. + +def constant(image, value): + "Fill a channel with a given grey level" + + return Image.new("L", image.size, value) + +## +# Copy image. +# +# @param image Source image. +# @return A copy of the source image. + +def duplicate(image): + "Create a copy of a channel" + + return image.copy() + +## +# Inverts an image +# (MAX - image). +# +# @param image Source image. +# @return An image object. + +def invert(image): + "Invert a channel" + + image.load() + return image._new(image.im.chop_invert()) + +## +# Compare images, and return lighter pixel value +# (max(image1, image2)). +#

+# Compares the two images, pixel by pixel, and returns a new image +# containing the lighter values. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def lighter(image1, image2): + "Select the lighter pixels from each image" + + image1.load() + image2.load() + return image1._new(image1.im.chop_lighter(image2.im)) + +## +# Compare images, and return darker pixel value +# (min(image1, image2)). +#

+# Compares the two images, pixel by pixel, and returns a new image +# containing the darker values. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def darker(image1, image2): + "Select the darker pixels from each image" + + image1.load() + image2.load() + return image1._new(image1.im.chop_darker(image2.im)) + +## +# Calculate absolute difference +# (abs(image1 - image2)). +#

+# Returns the absolute value of the difference between the two images. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def difference(image1, image2): + "Subtract one image from another" + + image1.load() + image2.load() + return image1._new(image1.im.chop_difference(image2.im)) + +## +# Superimpose positive images +# (image1 * image2 / MAX). +#

+# Superimposes two images on top of each other. If you multiply an +# image with a solid black image, the result is black. If you multiply +# with a solid white image, the image is unaffected. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def multiply(image1, image2): + "Superimpose two positive images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_multiply(image2.im)) + +## +# Superimpose negative images +# (MAX - ((MAX - image1) * (MAX - image2) / MAX)). +#

+# Superimposes two inverted images on top of each other. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def screen(image1, image2): + "Superimpose two negative images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_screen(image2.im)) + +## +# Add images +# ((image1 + image2) / scale + offset). +#

+# Adds two images, dividing the result by scale and adding the +# offset. If omitted, scale defaults to 1.0, and offset to 0.0. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def add(image1, image2, scale=1.0, offset=0): + "Add two images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_add(image2.im, scale, offset)) + +## +# Subtract images +# ((image1 - image2) / scale + offset). +#

+# Subtracts two images, dividing the result by scale and adding the +# offset. If omitted, scale defaults to 1.0, and offset to 0.0. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def subtract(image1, image2, scale=1.0, offset=0): + "Subtract two images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_subtract(image2.im, scale, offset)) + +## +# Add images without clipping +# ((image1 + image2) % MAX). +#

+# Adds two images, without clipping the result. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def add_modulo(image1, image2): + "Add two images without clipping" + + image1.load() + image2.load() + return image1._new(image1.im.chop_add_modulo(image2.im)) + +## +# Subtract images without clipping +# ((image1 - image2) % MAX). +#

+# Subtracts two images, without clipping the result. +# +# @param image1 First image. +# @param image1 Second image. +# @return An image object. + +def subtract_modulo(image1, image2): + "Subtract two images without clipping" + + image1.load() + image2.load() + return image1._new(image1.im.chop_subtract_modulo(image2.im)) + +## +# Logical AND +# (image1 and image2). + +def logical_and(image1, image2): + "Logical and between two images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_and(image2.im)) + +## +# Logical OR +# (image1 or image2). + +def logical_or(image1, image2): + "Logical or between two images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_or(image2.im)) + +## +# Logical XOR +# (image1 xor image2). + +def logical_xor(image1, image2): + "Logical xor between two images" + + image1.load() + image2.load() + return image1._new(image1.im.chop_xor(image2.im)) + +## +# Blend images using constant transparency weight. +#

+# Same as the blend function in the Image module. + +def blend(image1, image2, alpha): + "Blend two images using a constant transparency weight" + + return Image.blend(image1, image2, alpha) + +## +# Create composite using transparency mask. +#

+# Same as the composite function in the Image module. + +def composite(image1, image2, mask): + "Create composite image by blending images using a transparency mask" + + return Image.composite(image1, image2, mask) + +## +# Offset image data. +#

+# Returns a copy of the image where data has been offset by the given +# distances. Data wraps around the edges. If yoffset is omitted, it +# is assumed to be equal to xoffset. +# +# @param image Source image. +# @param xoffset The horizontal distance. +# @param yoffset The vertical distance. If omitted, both +# distances are set to the same value. +# @return An Image object. + +def offset(image, xoffset, yoffset=None): + "Offset image in horizontal and/or vertical direction" + if yoffset is None: + yoffset = xoffset + image.load() + return image._new(image.im.offset(xoffset, yoffset)) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py new file mode 100755 index 00000000000..b8a6dca71d9 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py @@ -0,0 +1,786 @@ +# +# The Python Imaging Library. +# $Id$ +# +# optional color managment support, based on Kevin Cazabon's PyCMS +# library. +# +# History: +# 2009-03-08 fl Added to PIL. +# +# Copyright (C) 2002-2003 Kevin Cazabon +# Copyright (c) 2009 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. See +# below for the original description. +# + +DESCRIPTION = """ +pyCMS + + a Python / PIL interface to the littleCMS ICC Color Management System + Copyright (C) 2002-2003 Kevin Cazabon + kevin@cazabon.com + http://www.cazabon.com + + pyCMS home page: http://www.cazabon.com/pyCMS + littleCMS home page: http://www.littlecms.com + (littleCMS is Copyright (C) 1998-2001 Marti Maria) + + Originally released under LGPL. Graciously donated to PIL in + March 2009, for distribution under the standard PIL license + + The pyCMS.py module provides a "clean" interface between Python/PIL and + pyCMSdll, taking care of some of the more complex handling of the direct + pyCMSdll functions, as well as error-checking and making sure that all + relevant data is kept together. + + While it is possible to call pyCMSdll functions directly, it's not highly + recommended. + + Version History: + + 0.1.0 pil mod March 10, 2009 + + Renamed display profile to proof profile. The proof + profile is the profile of the device that is being + simulated, not the profile of the device which is + actually used to display/print the final simulation + (that'd be the output profile) - also see LCMSAPI.txt + input colorspace -> using 'renderingIntent' -> proof + colorspace -> using 'proofRenderingIntent' -> output + colorspace + + Added LCMS FLAGS support. + Added FLAGS["SOFTPROOFING"] as default flag for + buildProofTransform (otherwise the proof profile/intent + would be ignored). + + 0.1.0 pil March 2009 - added to PIL, as PIL.ImageCms + + 0.0.2 alpha Jan 6, 2002 + + Added try/except statements arount type() checks of + potential CObjects... Python won't let you use type() + on them, and raises a TypeError (stupid, if you ask me!) + + Added buildProofTransformFromOpenProfiles() function. + Additional fixes in DLL, see DLL code for details. + + 0.0.1 alpha first public release, Dec. 26, 2002 + + Known to-do list with current version (of Python interface, not pyCMSdll): + + none + +""" + +VERSION = "0.1.0 pil" + +# --------------------------------------------------------------------. + +import Image +import _imagingcms + +core = _imagingcms + +# +# intent/direction values + +INTENT_PERCEPTUAL = 0 +INTENT_RELATIVE_COLORIMETRIC = 1 +INTENT_SATURATION = 2 +INTENT_ABSOLUTE_COLORIMETRIC = 3 + +DIRECTION_INPUT = 0 +DIRECTION_OUTPUT = 1 +DIRECTION_PROOF = 2 + +# +# flags + +FLAGS = { + "MATRIXINPUT": 1, + "MATRIXOUTPUT": 2, + "MATRIXONLY": (1|2), + "NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot + "NOPRELINEARIZATION": 16, # Don't create prelinearization tables on precalculated transforms (internal use) + "GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink) + "NOTCACHE": 64, # Inhibit 1-pixel cache + "NOTPRECALC": 256, + "NULLTRANSFORM": 512, # Don't transform anyway + "HIGHRESPRECALC": 1024, # Use more memory to give better accurancy + "LOWRESPRECALC": 2048, # Use less memory to minimize resouces + "WHITEBLACKCOMPENSATION": 8192, + "BLACKPOINTCOMPENSATION": 8192, + "GAMUTCHECK": 4096, # Out of Gamut alarm + "SOFTPROOFING": 16384, # Do softproofing + "PRESERVEBLACK": 32768, # Black preservation + "NODEFAULTRESOURCEDEF": 16777216, # CRD special + "GRIDPOINTS": lambda n: ((n) & 0xFF) << 16 # Gridpoints +} + +_MAX_FLAG = 0 +for flag in FLAGS.values(): + if isinstance(flag, type(0)): + _MAX_FLAG = _MAX_FLAG | flag + +# --------------------------------------------------------------------. +# Experimental PIL-level API +# --------------------------------------------------------------------. + +## +# Profile. + +class ImageCmsProfile: + + def __init__(self, profile): + # accepts a string (filename), a file-like object, or a low-level + # profile object + if Image.isStringType(profile): + self._set(core.profile_open(profile), profile) + elif hasattr(profile, "read"): + self._set(core.profile_fromstring(profile.read())) + else: + self._set(profile) # assume it's already a profile + + def _set(self, profile, filename=None): + self.profile = profile + self.filename = filename + if profile: + self.product_name = profile.product_name + self.product_info = profile.product_info + else: + self.product_name = None + self.product_info = None + +## +# Transform. This can be used with the procedural API, or with the +# standard {@link Image.point} method. + +class ImageCmsTransform(Image.ImagePointHandler): + + def __init__(self, input, output, input_mode, output_mode, + intent=INTENT_PERCEPTUAL, + proof=None, proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0): + if proof is None: + self.transform = core.buildTransform( + input.profile, output.profile, + input_mode, output_mode, + intent, + flags + ) + else: + self.transform = core.buildProofTransform( + input.profile, output.profile, proof.profile, + input_mode, output_mode, + intent, proof_intent, + flags + ) + # Note: inputMode and outputMode are for pyCMS compatibility only + self.input_mode = self.inputMode = input_mode + self.output_mode = self.outputMode = output_mode + + def point(self, im): + return self.apply(im) + + def apply(self, im, imOut=None): + im.load() + if imOut is None: + imOut = Image.new(self.output_mode, im.size, None) + result = self.transform.apply(im.im.id, imOut.im.id) + return imOut + + def apply_in_place(self, im): + im.load() + if im.mode != self.output_mode: + raise ValueError("mode mismatch") # wrong output mode + result = self.transform.apply(im.im.id, im.im.id) + return im + +## +# (experimental) Fetches the profile for the current display device. +# Returns None if the profile is not known. + +def get_display_profile(handle=None): + import sys + if sys.platform == "win32": + import ImageWin + if isinstance(handle, ImageWin.HDC): + profile = core.get_display_profile_win32(handle, 1) + else: + profile = core.get_display_profile_win32(handle or 0) + else: + try: + get = _imagingcms.get_display_profile + except AttributeError: + return None + else: + profile = get() + return ImageCmsProfile(profile) + +# --------------------------------------------------------------------. +# pyCMS compatible layer +# --------------------------------------------------------------------. + +## +# (pyCMS) Exception class. This is used for all errors in the pyCMS API. + +class PyCMSError(Exception): + pass + +## +# (pyCMS) Applies an ICC transformation to a given image, mapping from +# inputProfile to outputProfile. + +def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL, outputMode=None, inPlace=0, flags=0): + """ + ImageCms.profileToProfile(im, inputProfile, outputProfile, + [renderingIntent], [outputMode], [inPlace]) + + Returns either None or a new PIL image object, depending on value of + inPlace (see below). + + im = an open PIL image object (i.e. Image.new(...) or + Image.open(...), etc.) + inputProfile = string, as a valid filename path to the ICC input + profile you wish to use for this image, or a profile object + outputProfile = string, as a valid filename path to the ICC output + profile you wish to use for this image, or a profile object + renderingIntent = integer (0-3) specifying the rendering intent you + wish to use for the transform + INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) + INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) + INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) + INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) + + see the pyCMS documentation for details on rendering intents and + what they do. + outputMode = a valid PIL mode for the output image (i.e. "RGB", "CMYK", + etc.). Note: if rendering the image "inPlace", outputMode MUST be + the same mode as the input, or omitted completely. If omitted, the + outputMode will be the same as the mode of the input image (im.mode) + inPlace = BOOL (1 = TRUE, None or 0 = FALSE). If TRUE, the original + image is modified in-place, and None is returned. If FALSE + (default), a new Image object is returned with the transform + applied. + flags = integer (0-...) specifying additional flags + + If the input or output profiles specified are not valid filenames, a + PyCMSError will be raised. If inPlace == TRUE and outputMode != im.mode, + a PyCMSError will be raised. If an error occurs during application of + the profiles, a PyCMSError will be raised. If outputMode is not a mode + supported by the outputProfile (or by pyCMS), a PyCMSError will be + raised. + + This function applies an ICC transformation to im from inputProfile's + color space to outputProfile's color space using the specified rendering + intent to decide how to handle out-of-gamut colors. + + OutputMode can be used to specify that a color mode conversion is to + be done using these profiles, but the specified profiles must be able + to handle that mode. I.e., if converting im from RGB to CMYK using + profiles, the input profile must handle RGB data, and the output + profile must handle CMYK data. + + """ + + if outputMode is None: + outputMode = im.mode + + if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3): + raise PyCMSError("renderingIntent must be an integer between 0 and 3") + + if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG): + raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + transform = ImageCmsTransform( + inputProfile, outputProfile, im.mode, outputMode, renderingIntent, flags=flags + ) + if inPlace: + transform.apply_in_place(im) + imOut = None + else: + imOut = transform.apply(im) + except (IOError, TypeError, ValueError), v: + raise PyCMSError(v) + + return imOut + +## +# (pyCMS) Opens an ICC profile file. + +def getOpenProfile(profileFilename): + """ + ImageCms.getOpenProfile(profileFilename) + + Returns a CmsProfile class object. + + profileFilename = string, as a valid filename path to the ICC profile + you wish to open, or a file-like object. + + The PyCMSProfile object can be passed back into pyCMS for use in creating + transforms and such (as in ImageCms.buildTransformFromOpenProfiles()). + + If profileFilename is not a vaild filename for an ICC profile, a + PyCMSError will be raised. + + """ + + try: + return ImageCmsProfile(profileFilename) + except (IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Builds an ICC transform mapping from the inputProfile to the +# outputProfile. Use applyTransform to apply the transform to a given +# image. + +def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, flags=0): + """ + ImageCms.buildTransform(inputProfile, outputProfile, inMode, outMode, + [renderingIntent]) + + Returns a CmsTransform class object. + + inputProfile = string, as a valid filename path to the ICC input + profile you wish to use for this transform, or a profile object + outputProfile = string, as a valid filename path to the ICC output + profile you wish to use for this transform, or a profile object + inMode = string, as a valid PIL mode that the appropriate profile also + supports (i.e. "RGB", "RGBA", "CMYK", etc.) + outMode = string, as a valid PIL mode that the appropriate profile also + supports (i.e. "RGB", "RGBA", "CMYK", etc.) + renderingIntent = integer (0-3) specifying the rendering intent you + wish to use for the transform + INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) + INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) + INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) + INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) + see the pyCMS documentation for details on rendering intents and + what they do. + flags = integer (0-...) specifying additional flags + + If the input or output profiles specified are not valid filenames, a + PyCMSError will be raised. If an error occurs during creation of the + transform, a PyCMSError will be raised. + + If inMode or outMode are not a mode supported by the outputProfile (or + by pyCMS), a PyCMSError will be raised. + + This function builds and returns an ICC transform from the inputProfile + to the outputProfile using the renderingIntent to determine what to do + with out-of-gamut colors. It will ONLY work for converting images that + are in inMode to images that are in outMode color format (PIL mode, + i.e. "RGB", "RGBA", "CMYK", etc.). + + Building the transform is a fair part of the overhead in + ImageCms.profileToProfile(), so if you're planning on converting multiple + images using the same input/output settings, this can save you time. + Once you have a transform object, it can be used with + ImageCms.applyProfile() to convert images without the need to re-compute + the lookup table for the transform. + + The reason pyCMS returns a class object rather than a handle directly + to the transform is that it needs to keep track of the PIL input/output + modes that the transform is meant for. These attributes are stored in + the "inMode" and "outMode" attributes of the object (which can be + manually overridden if you really want to, but I don't know of any + time that would be of use, or would even work). + + """ + + if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3): + raise PyCMSError("renderingIntent must be an integer between 0 and 3") + + if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG): + raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags) + except (IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Builds an ICC transform mapping from the inputProfile to the +# outputProfile, but tries to simulate the result that would be +# obtained on the proofProfile device. + +def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC, flags=FLAGS["SOFTPROOFING"]): + """ + ImageCms.buildProofTransform(inputProfile, outputProfile, proofProfile, + inMode, outMode, [renderingIntent], [proofRenderingIntent]) + + Returns a CmsTransform class object. + + inputProfile = string, as a valid filename path to the ICC input + profile you wish to use for this transform, or a profile object + outputProfile = string, as a valid filename path to the ICC output + (monitor, usually) profile you wish to use for this transform, + or a profile object + proofProfile = string, as a valid filename path to the ICC proof + profile you wish to use for this transform, or a profile object + inMode = string, as a valid PIL mode that the appropriate profile also + supports (i.e. "RGB", "RGBA", "CMYK", etc.) + outMode = string, as a valid PIL mode that the appropriate profile also + supports (i.e. "RGB", "RGBA", "CMYK", etc.) + renderingIntent = integer (0-3) specifying the rendering intent you + wish to use for the input->proof (simulated) transform + INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) + INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) + INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) + INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) + see the pyCMS documentation for details on rendering intents and + what they do. + proofRenderingIntent = integer (0-3) specifying the rendering intent + you wish to use for proof->output transform + INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) + INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) + INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) + INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) + see the pyCMS documentation for details on rendering intents and + what they do. + flags = integer (0-...) specifying additional flags + + If the input, output, or proof profiles specified are not valid + filenames, a PyCMSError will be raised. + + If an error occurs during creation of the transform, a PyCMSError will + be raised. + + If inMode or outMode are not a mode supported by the outputProfile + (or by pyCMS), a PyCMSError will be raised. + + This function builds and returns an ICC transform from the inputProfile + to the outputProfile, but tries to simulate the result that would be + obtained on the proofProfile device using renderingIntent and + proofRenderingIntent to determine what to do with out-of-gamut + colors. This is known as "soft-proofing". It will ONLY work for + converting images that are in inMode to images that are in outMode + color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.). + + Usage of the resulting transform object is exactly the same as with + ImageCms.buildTransform(). + + Proof profiling is generally used when using an output device to get a + good idea of what the final printed/displayed image would look like on + the proofProfile device when it's quicker and easier to use the + output device for judging color. Generally, this means that the + output device is a monitor, or a dye-sub printer (etc.), and the simulated + device is something more expensive, complicated, or time consuming + (making it difficult to make a real print for color judgement purposes). + + Soft-proofing basically functions by adjusting the colors on the + output device to match the colors of the device being simulated. However, + when the simulated device has a much wider gamut than the output + device, you may obtain marginal results. + + """ + + if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3): + raise PyCMSError("renderingIntent must be an integer between 0 and 3") + + if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG): + raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + if not isinstance(proofProfile, ImageCmsProfile): + proofProfile = ImageCmsProfile(proofProfile) + return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags) + except (IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +buildTransformFromOpenProfiles = buildTransform +buildProofTransformFromOpenProfiles = buildProofTransform + +## +# (pyCMS) Applies a transform to a given image. + +def applyTransform(im, transform, inPlace=0): + """ + ImageCms.applyTransform(im, transform, [inPlace]) + + Returns either None, or a new PIL Image object, depending on the value + of inPlace (see below) + + im = a PIL Image object, and im.mode must be the same as the inMode + supported by the transform. + transform = a valid CmsTransform class object + inPlace = BOOL (1 == TRUE, 0 or None == FALSE). If TRUE, im is + modified in place and None is returned, if FALSE, a new Image + object with the transform applied is returned (and im is not + changed). The default is FALSE. + + If im.mode != transform.inMode, a PyCMSError is raised. + + If inPlace == TRUE and transform.inMode != transform.outMode, a + PyCMSError is raised. + + If im.mode, transfer.inMode, or transfer.outMode is not supported by + pyCMSdll or the profiles you used for the transform, a PyCMSError is + raised. + + If an error occurs while the transform is being applied, a PyCMSError + is raised. + + This function applies a pre-calculated transform (from + ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) to an + image. The transform can be used for multiple images, saving + considerable calcuation time if doing the same conversion multiple times. + + If you want to modify im in-place instead of receiving a new image as + the return value, set inPlace to TRUE. This can only be done if + transform.inMode and transform.outMode are the same, because we can't + change the mode in-place (the buffer sizes for some modes are + different). The default behavior is to return a new Image object of + the same dimensions in mode transform.outMode. + + """ + + try: + if inPlace: + transform.apply_in_place(im) + imOut = None + else: + imOut = transform.apply(im) + except (TypeError, ValueError), v: + raise PyCMSError(v) + + return imOut + +## +# (pyCMS) Creates a profile. + +def createProfile(colorSpace, colorTemp=-1): + """ + ImageCms.createProfile(colorSpace, [colorTemp]) + + Returns a CmsProfile class object + + colorSpace = string, the color space of the profile you wish to create. + Currently only "LAB", "XYZ", and "sRGB" are supported. + colorTemp = positive integer for the white point for the profile, in + degrees Kelvin (i.e. 5000, 6500, 9600, etc.). The default is for + D50 illuminant if omitted (5000k). colorTemp is ONLY applied to + LAB profiles, and is ignored for XYZ and sRGB. + + If colorSpace not in ["LAB", "XYZ", "sRGB"], a PyCMSError is raised + + If using LAB and colorTemp != a positive integer, a PyCMSError is raised. + + If an error occurs while creating the profile, a PyCMSError is raised. + + Use this function to create common profiles on-the-fly instead of + having to supply a profile on disk and knowing the path to it. It + returns a normal CmsProfile object that can be passed to + ImageCms.buildTransformFromOpenProfiles() to create a transform to apply + to images. + + """ + if colorSpace not in ["LAB", "XYZ", "sRGB"]: + raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace) + + if colorSpace == "LAB": + if type(colorTemp) == type(5000.0): + colorTemp = int(colorTemp + 0.5) + if type (colorTemp) != type (5000): + raise PyCMSError("Color temperature must be a positive integer, \"%s\" not valid" % colorTemp) + + try: + return core.createProfile(colorSpace, colorTemp) + except (TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Gets the internal product name for the given profile. + +def getProfileName(profile): + """ + ImageCms.getProfileName(profile) + + Returns a string containing the internal name of the profile as stored + in an ICC tag. + + profile = EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + + If profile isn't a valid CmsProfile object or filename to a profile, + a PyCMSError is raised If an error occurs while trying to obtain the + name tag, a PyCMSError is raised. + + Use this function to obtain the INTERNAL name of the profile (stored + in an ICC tag in the profile itself), usually the one used when the + profile was originally created. Sometimes this tag also contains + additional information supplied by the creator. + + """ + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return profile.profile.product_name + "\n" + except (AttributeError, IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Gets the internal product information for the given profile. + +def getProfileInfo(profile): + """ + ImageCms.getProfileInfo(profile) + + Returns a string containing the internal profile information stored in + an ICC tag. + + profile = EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + + If profile isn't a valid CmsProfile object or filename to a profile, + a PyCMSError is raised. + + If an error occurs while trying to obtain the info tag, a PyCMSError + is raised + + Use this function to obtain the information stored in the profile's + info tag. This often contains details about the profile, and how it + was created, as supplied by the creator. + + """ + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # add an extra newline to preserve pyCMS compatibility + return profile.product_info + "\n" + except (AttributeError, IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Gets the default intent name for the given profile. + +def getDefaultIntent(profile): + """ + ImageCms.getDefaultIntent(profile) + + Returns integer 0-3 specifying the default rendering intent for this + profile. + INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) + INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) + INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) + INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) + see the pyCMS documentation for details on rendering intents and + what they do. + + profile = EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + + If profile isn't a valid CmsProfile object or filename to a profile, + a PyCMSError is raised. + + If an error occurs while trying to obtain the default intent, a + PyCMSError is raised. + + Use this function to determine the default (and usually best optomized) + rendering intent for this profile. Most profiles support multiple + rendering intents, but are intended mostly for one type of conversion. + If you wish to use a different intent than returned, use + ImageCms.isIntentSupported() to verify it will work first. + """ + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return profile.profile.rendering_intent + except (AttributeError, IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Checks if a given intent is supported. + +def isIntentSupported(profile, intent, direction): + """ + ImageCms.isIntentSupported(profile, intent, direction) + + Returns 1 if the intent/direction are supported, -1 if they are not. + + profile = EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + intent = integer (0-3) specifying the rendering intent you wish to use + with this profile + INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) + INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) + INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) + INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) + see the pyCMS documentation for details on rendering intents and + what they do. + direction = integer specifing if the profile is to be used for input, + output, or proof + INPUT = 0 (or use ImageCms.DIRECTION_INPUT) + OUTPUT = 1 (or use ImageCms.DIRECTION_OUTPUT) + PROOF = 2 (or use ImageCms.DIRECTION_PROOF) + + Use this function to verify that you can use your desired + renderingIntent with profile, and that profile can be used for the + input/output/proof profile as you desire. + + Some profiles are created specifically for one "direction", can cannot + be used for others. Some profiles can only be used for certain + rendering intents... so it's best to either verify this before trying + to create a transform with them (using this function), or catch the + potential PyCMSError that will occur if they don't support the modes + you select. + + """ + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # FIXME: I get different results for the same data w. different + # compilers. Bug in LittleCMS or in the binding? + if profile.profile.is_intent_supported(intent, direction): + return 1 + else: + return -1 + except (AttributeError, IOError, TypeError, ValueError), v: + raise PyCMSError(v) + +## +# (pyCMS) Fetches versions. + +def versions(): + import sys + return ( + VERSION, core.littlecms_version, sys.version.split()[0], Image.VERSION + ) + +# -------------------------------------------------------------------- + +if __name__ == "__main__": + # create a cheap manual from the __doc__ strings for the functions above + + import ImageCms + import string + print __doc__ + + for f in dir(pyCMS): + print "="*80 + print "%s" %f + + try: + exec ("doc = ImageCms.%s.__doc__" %(f)) + if string.find(doc, "pyCMS") >= 0: + # so we don't get the __doc__ string for imported modules + print doc + except AttributeError: + pass diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py new file mode 100755 index 00000000000..c3cca46db8f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py @@ -0,0 +1,263 @@ +# +# The Python Imaging Library +# $Id$ +# +# map CSS3-style colour description strings to RGB +# +# History: +# 2002-10-24 fl Added support for CSS-style color strings +# 2002-12-15 fl Added RGBA support +# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2 +# 2004-07-19 fl Fixed gray/grey spelling issues +# 2009-03-05 fl Fixed rounding error in grayscale calculation +# +# Copyright (c) 2002-2004 by Secret Labs AB +# Copyright (c) 2002-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image +import re, string + +try: + x = int("a", 16) +except TypeError: + # python 1.5.2 doesn't support int(x,b) + str2int = string.atoi +else: + str2int = int + +## +# Convert color string to RGB tuple. +# +# @param color A CSS3-style colour string. +# @return An RGB-tuple. +# @exception ValueError If the color string could not be interpreted +# as an RGB value. + +def getrgb(color): + # FIXME: add RGBA support + try: + rgb = colormap[color] + except KeyError: + try: + # fall back on case-insensitive lookup + rgb = colormap[string.lower(color)] + except KeyError: + rgb = None + # found color in cache + if rgb: + if isinstance(rgb, type(())): + return rgb + colormap[color] = rgb = getrgb(rgb) + return rgb + # check for known string formats + m = re.match("#\w\w\w$", color) + if m: + return ( + str2int(color[1]*2, 16), + str2int(color[2]*2, 16), + str2int(color[3]*2, 16) + ) + m = re.match("#\w\w\w\w\w\w$", color) + if m: + return ( + str2int(color[1:3], 16), + str2int(color[3:5], 16), + str2int(color[5:7], 16) + ) + m = re.match("rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) + if m: + return ( + str2int(m.group(1)), + str2int(m.group(2)), + str2int(m.group(3)) + ) + m = re.match("rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) + if m: + return ( + int((str2int(m.group(1)) * 255) / 100.0 + 0.5), + int((str2int(m.group(2)) * 255) / 100.0 + 0.5), + int((str2int(m.group(3)) * 255) / 100.0 + 0.5) + ) + m = re.match("hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) + if m: + from colorsys import hls_to_rgb + rgb = hls_to_rgb( + float(m.group(1)) / 360.0, + float(m.group(3)) / 100.0, + float(m.group(2)) / 100.0, + ) + return ( + int(rgb[0] * 255 + 0.5), + int(rgb[1] * 255 + 0.5), + int(rgb[2] * 255 + 0.5) + ) + raise ValueError("unknown color specifier: %r" % color) + +def getcolor(color, mode): + # same as getrgb, but converts the result to the given mode + color = getrgb(color) + if mode == "RGB": + return color + if mode == "RGBA": + r, g, b = color + return r, g, b, 255 + if Image.getmodebase(mode) == "L": + r, g, b = color + return (r*299 + g*587 + b*114)/1000 + return color + +colormap = { + # X11 colour table (from "CSS3 module: Color working draft"), with + # gray/grey spelling issues fixed. This is a superset of HTML 4.0 + # colour names used in CSS 1. + "aliceblue": "#f0f8ff", + "antiquewhite": "#faebd7", + "aqua": "#00ffff", + "aquamarine": "#7fffd4", + "azure": "#f0ffff", + "beige": "#f5f5dc", + "bisque": "#ffe4c4", + "black": "#000000", + "blanchedalmond": "#ffebcd", + "blue": "#0000ff", + "blueviolet": "#8a2be2", + "brown": "#a52a2a", + "burlywood": "#deb887", + "cadetblue": "#5f9ea0", + "chartreuse": "#7fff00", + "chocolate": "#d2691e", + "coral": "#ff7f50", + "cornflowerblue": "#6495ed", + "cornsilk": "#fff8dc", + "crimson": "#dc143c", + "cyan": "#00ffff", + "darkblue": "#00008b", + "darkcyan": "#008b8b", + "darkgoldenrod": "#b8860b", + "darkgray": "#a9a9a9", + "darkgrey": "#a9a9a9", + "darkgreen": "#006400", + "darkkhaki": "#bdb76b", + "darkmagenta": "#8b008b", + "darkolivegreen": "#556b2f", + "darkorange": "#ff8c00", + "darkorchid": "#9932cc", + "darkred": "#8b0000", + "darksalmon": "#e9967a", + "darkseagreen": "#8fbc8f", + "darkslateblue": "#483d8b", + "darkslategray": "#2f4f4f", + "darkslategrey": "#2f4f4f", + "darkturquoise": "#00ced1", + "darkviolet": "#9400d3", + "deeppink": "#ff1493", + "deepskyblue": "#00bfff", + "dimgray": "#696969", + "dimgrey": "#696969", + "dodgerblue": "#1e90ff", + "firebrick": "#b22222", + "floralwhite": "#fffaf0", + "forestgreen": "#228b22", + "fuchsia": "#ff00ff", + "gainsboro": "#dcdcdc", + "ghostwhite": "#f8f8ff", + "gold": "#ffd700", + "goldenrod": "#daa520", + "gray": "#808080", + "grey": "#808080", + "green": "#008000", + "greenyellow": "#adff2f", + "honeydew": "#f0fff0", + "hotpink": "#ff69b4", + "indianred": "#cd5c5c", + "indigo": "#4b0082", + "ivory": "#fffff0", + "khaki": "#f0e68c", + "lavender": "#e6e6fa", + "lavenderblush": "#fff0f5", + "lawngreen": "#7cfc00", + "lemonchiffon": "#fffacd", + "lightblue": "#add8e6", + "lightcoral": "#f08080", + "lightcyan": "#e0ffff", + "lightgoldenrodyellow": "#fafad2", + "lightgreen": "#90ee90", + "lightgray": "#d3d3d3", + "lightgrey": "#d3d3d3", + "lightpink": "#ffb6c1", + "lightsalmon": "#ffa07a", + "lightseagreen": "#20b2aa", + "lightskyblue": "#87cefa", + "lightslategray": "#778899", + "lightslategrey": "#778899", + "lightsteelblue": "#b0c4de", + "lightyellow": "#ffffe0", + "lime": "#00ff00", + "limegreen": "#32cd32", + "linen": "#faf0e6", + "magenta": "#ff00ff", + "maroon": "#800000", + "mediumaquamarine": "#66cdaa", + "mediumblue": "#0000cd", + "mediumorchid": "#ba55d3", + "mediumpurple": "#9370db", + "mediumseagreen": "#3cb371", + "mediumslateblue": "#7b68ee", + "mediumspringgreen": "#00fa9a", + "mediumturquoise": "#48d1cc", + "mediumvioletred": "#c71585", + "midnightblue": "#191970", + "mintcream": "#f5fffa", + "mistyrose": "#ffe4e1", + "moccasin": "#ffe4b5", + "navajowhite": "#ffdead", + "navy": "#000080", + "oldlace": "#fdf5e6", + "olive": "#808000", + "olivedrab": "#6b8e23", + "orange": "#ffa500", + "orangered": "#ff4500", + "orchid": "#da70d6", + "palegoldenrod": "#eee8aa", + "palegreen": "#98fb98", + "paleturquoise": "#afeeee", + "palevioletred": "#db7093", + "papayawhip": "#ffefd5", + "peachpuff": "#ffdab9", + "peru": "#cd853f", + "pink": "#ffc0cb", + "plum": "#dda0dd", + "powderblue": "#b0e0e6", + "purple": "#800080", + "red": "#ff0000", + "rosybrown": "#bc8f8f", + "royalblue": "#4169e1", + "saddlebrown": "#8b4513", + "salmon": "#fa8072", + "sandybrown": "#f4a460", + "seagreen": "#2e8b57", + "seashell": "#fff5ee", + "sienna": "#a0522d", + "silver": "#c0c0c0", + "skyblue": "#87ceeb", + "slateblue": "#6a5acd", + "slategray": "#708090", + "slategrey": "#708090", + "snow": "#fffafa", + "springgreen": "#00ff7f", + "steelblue": "#4682b4", + "tan": "#d2b48c", + "teal": "#008080", + "thistle": "#d8bfd8", + "tomato": "#ff6347", + "turquoise": "#40e0d0", + "violet": "#ee82ee", + "wheat": "#f5deb3", + "white": "#ffffff", + "whitesmoke": "#f5f5f5", + "yellow": "#ffff00", + "yellowgreen": "#9acd32", +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py new file mode 100755 index 00000000000..5217a7366fe --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py @@ -0,0 +1,378 @@ +# +# The Python Imaging Library +# $Id$ +# +# drawing interface operations +# +# History: +# 1996-04-13 fl Created (experimental) +# 1996-08-07 fl Filled polygons, ellipses. +# 1996-08-13 fl Added text support +# 1998-06-28 fl Handle I and F images +# 1998-12-29 fl Added arc; use arc primitive to draw ellipses +# 1999-01-10 fl Added shape stuff (experimental) +# 1999-02-06 fl Added bitmap support +# 1999-02-11 fl Changed all primitives to take options +# 1999-02-20 fl Fixed backwards compatibility +# 2000-10-12 fl Copy on write, when necessary +# 2001-02-18 fl Use default ink for bitmap/text also in fill mode +# 2002-10-24 fl Added support for CSS-style color strings +# 2002-12-10 fl Added experimental support for RGBA-on-RGB drawing +# 2002-12-11 fl Refactored low-level drawing API (work in progress) +# 2004-08-26 fl Made Draw() a factory function, added getdraw() support +# 2004-09-04 fl Added width support to line primitive +# 2004-09-10 fl Added font mode handling +# 2006-06-19 fl Added font bearing support (getmask2) +# +# Copyright (c) 1997-2006 by Secret Labs AB +# Copyright (c) 1996-2006 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageColor + +try: + import warnings +except ImportError: + warnings = None + +## +# A simple 2D drawing interface for PIL images. +#

+# Application code should use the Draw factory, instead of +# directly. + +class ImageDraw: + + ## + # Create a drawing instance. + # + # @param im The image to draw in. + # @param mode Optional mode to use for color values. For RGB + # images, this argument can be RGB or RGBA (to blend the + # drawing into the image). For all other modes, this argument + # must be the same as the image mode. If omitted, the mode + # defaults to the mode of the image. + + def __init__(self, im, mode=None): + im.load() + if im.readonly: + im._copy() # make it writable + blend = 0 + if mode is None: + mode = im.mode + if mode != im.mode: + if mode == "RGBA" and im.mode == "RGB": + blend = 1 + else: + raise ValueError("mode mismatch") + if mode == "P": + self.palette = im.palette + else: + self.palette = None + self.im = im.im + self.draw = Image.core.draw(self.im, blend) + self.mode = mode + if mode in ("I", "F"): + self.ink = self.draw.draw_ink(1, mode) + else: + self.ink = self.draw.draw_ink(-1, mode) + if mode in ("1", "P", "I", "F"): + # FIXME: fix Fill2 to properly support matte for I+F images + self.fontmode = "1" + else: + self.fontmode = "L" # aliasing is okay for other modes + self.fill = 0 + self.font = None + + ## + # Set the default pen color. + + def setink(self, ink): + # compatibility + if warnings: + warnings.warn( + "'setink' is deprecated; use keyword arguments instead", + DeprecationWarning, stacklevel=2 + ) + if Image.isStringType(ink): + ink = ImageColor.getcolor(ink, self.mode) + if self.palette and not Image.isNumberType(ink): + ink = self.palette.getcolor(ink) + self.ink = self.draw.draw_ink(ink, self.mode) + + ## + # Set the default background color. + + def setfill(self, onoff): + # compatibility + if warnings: + warnings.warn( + "'setfill' is deprecated; use keyword arguments instead", + DeprecationWarning, stacklevel=2 + ) + self.fill = onoff + + ## + # Set the default font. + + def setfont(self, font): + # compatibility + self.font = font + + ## + # Get the current default font. + + def getfont(self): + if not self.font: + # FIXME: should add a font repository + import ImageFont + self.font = ImageFont.load_default() + return self.font + + def _getink(self, ink, fill=None): + if ink is None and fill is None: + if self.fill: + fill = self.ink + else: + ink = self.ink + else: + if ink is not None: + if Image.isStringType(ink): + ink = ImageColor.getcolor(ink, self.mode) + if self.palette and not Image.isNumberType(ink): + ink = self.palette.getcolor(ink) + ink = self.draw.draw_ink(ink, self.mode) + if fill is not None: + if Image.isStringType(fill): + fill = ImageColor.getcolor(fill, self.mode) + if self.palette and not Image.isNumberType(fill): + fill = self.palette.getcolor(fill) + fill = self.draw.draw_ink(fill, self.mode) + return ink, fill + + ## + # Draw an arc. + + def arc(self, xy, start, end, fill=None): + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_arc(xy, start, end, ink) + + ## + # Draw a bitmap. + + def bitmap(self, xy, bitmap, fill=None): + bitmap.load() + ink, fill = self._getink(fill) + if ink is None: + ink = fill + if ink is not None: + self.draw.draw_bitmap(xy, bitmap.im, ink) + + ## + # Draw a chord. + + def chord(self, xy, start, end, fill=None, outline=None): + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_chord(xy, start, end, fill, 1) + if ink is not None: + self.draw.draw_chord(xy, start, end, ink, 0) + + ## + # Draw an ellipse. + + def ellipse(self, xy, fill=None, outline=None): + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_ellipse(xy, fill, 1) + if ink is not None: + self.draw.draw_ellipse(xy, ink, 0) + + ## + # Draw a line, or a connected sequence of line segments. + + def line(self, xy, fill=None, width=0): + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_lines(xy, ink, width) + + ## + # (Experimental) Draw a shape. + + def shape(self, shape, fill=None, outline=None): + # experimental + shape.close() + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_outline(shape, fill, 1) + if ink is not None: + self.draw.draw_outline(shape, ink, 0) + + ## + # Draw a pieslice. + + def pieslice(self, xy, start, end, fill=None, outline=None): + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_pieslice(xy, start, end, fill, 1) + if ink is not None: + self.draw.draw_pieslice(xy, start, end, ink, 0) + + ## + # Draw one or more individual pixels. + + def point(self, xy, fill=None): + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_points(xy, ink) + + ## + # Draw a polygon. + + def polygon(self, xy, fill=None, outline=None): + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_polygon(xy, fill, 1) + if ink is not None: + self.draw.draw_polygon(xy, ink, 0) + + ## + # Draw a rectangle. + + def rectangle(self, xy, fill=None, outline=None): + ink, fill = self._getink(outline, fill) + if fill is not None: + self.draw.draw_rectangle(xy, fill, 1) + if ink is not None: + self.draw.draw_rectangle(xy, ink, 0) + + ## + # Draw text. + + def text(self, xy, text, fill=None, font=None, anchor=None): + ink, fill = self._getink(fill) + if font is None: + font = self.getfont() + if ink is None: + ink = fill + if ink is not None: + try: + mask, offset = font.getmask2(text, self.fontmode) + xy = xy[0] + offset[0], xy[1] + offset[1] + except AttributeError: + try: + mask = font.getmask(text, self.fontmode) + except TypeError: + mask = font.getmask(text) + self.draw.draw_bitmap(xy, mask, ink) + + ## + # Get the size of a given string, in pixels. + + def textsize(self, text, font=None): + if font is None: + font = self.getfont() + return font.getsize(text) + +## +# A simple 2D drawing interface for PIL images. +# +# @param im The image to draw in. +# @param mode Optional mode to use for color values. For RGB +# images, this argument can be RGB or RGBA (to blend the +# drawing into the image). For all other modes, this argument +# must be the same as the image mode. If omitted, the mode +# defaults to the mode of the image. + +def Draw(im, mode=None): + try: + return im.getdraw(mode) + except AttributeError: + return ImageDraw(im, mode) + +# experimental access to the outline API +try: + Outline = Image.core.outline +except: + Outline = None + +## +# (Experimental) A more advanced 2D drawing interface for PIL images, +# based on the WCK interface. +# +# @param im The image to draw in. +# @param hints An optional list of hints. +# @return A (drawing context, drawing resource factory) tuple. + +def getdraw(im=None, hints=None): + # FIXME: this needs more work! + # FIXME: come up with a better 'hints' scheme. + handler = None + if not hints or "nicest" in hints: + try: + import _imagingagg + handler = _imagingagg + except ImportError: + pass + if handler is None: + import ImageDraw2 + handler = ImageDraw2 + if im: + im = handler.Draw(im) + return im, handler + +## +# (experimental) Fills a bounded region with a given color. +# +# @param image Target image. +# @param xy Seed position (a 2-item coordinate tuple). +# @param value Fill color. +# @param border Optional border value. If given, the region consists of +# pixels with a color different from the border color. If not given, +# the region consists of pixels having the same color as the seed +# pixel. + +def floodfill(image, xy, value, border=None): + "Fill bounded region." + # based on an implementation by Eric S. Raymond + pixel = image.load() + x, y = xy + try: + background = pixel[x, y] + if background == value: + return # seed point already has fill color + pixel[x, y] = value + except IndexError: + return # seed point outside image + edge = [(x, y)] + if border is None: + while edge: + newedge = [] + for (x, y) in edge: + for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)): + try: + p = pixel[s, t] + except IndexError: + pass + else: + if p == background: + pixel[s, t] = value + newedge.append((s, t)) + edge = newedge + else: + while edge: + newedge = [] + for (x, y) in edge: + for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)): + try: + p = pixel[s, t] + except IndexError: + pass + else: + if p != value and p != border: + pixel[s, t] = value + newedge.append((s, t)) + edge = newedge diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py new file mode 100755 index 00000000000..dbf1a1f8893 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py @@ -0,0 +1,105 @@ +# +# The Python Imaging Library +# $Id$ +# +# WCK-style drawing interface operations +# +# History: +# 2003-12-07 fl created +# 2005-05-15 fl updated; added to PIL as ImageDraw2 +# 2005-05-15 fl added text support +# 2005-05-20 fl added arc/chord/pieslice support +# +# Copyright (c) 2003-2005 by Secret Labs AB +# Copyright (c) 2003-2005 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageColor, ImageDraw, ImageFont, ImagePath + +class Pen: + def __init__(self, color, width=1, opacity=255): + self.color = ImageColor.getrgb(color) + self.width = width + +class Brush: + def __init__(self, color, opacity=255): + self.color = ImageColor.getrgb(color) + +class Font: + def __init__(self, color, file, size=12): + # FIXME: add support for bitmap fonts + self.color = ImageColor.getrgb(color) + self.font = ImageFont.truetype(file, size) + +class Draw: + + def __init__(self, image, size=None, color=None): + if not hasattr(image, "im"): + image = Image.new(image, size, color) + self.draw = ImageDraw.Draw(image) + self.image = image + self.transform = None + + def flush(self): + return self.image + + def render(self, op, xy, pen, brush=None): + # handle color arguments + outline = fill = None; width = 1 + if isinstance(pen, Pen): + outline = pen.color + width = pen.width + elif isinstance(brush, Pen): + outline = brush.color + width = brush.width + if isinstance(brush, Brush): + fill = brush.color + elif isinstance(pen, Brush): + fill = pen.color + # handle transformation + if self.transform: + xy = ImagePath.Path(xy) + xy.transform(self.transform) + # render the item + if op == "line": + self.draw.line(xy, fill=outline, width=width) + else: + getattr(self.draw, op)(xy, fill=fill, outline=outline) + + def settransform(self, (xoffset, yoffset)): + self.transform = (1, 0, xoffset, 0, 1, yoffset) + + def arc(self, xy, start, end, *options): + self.render("arc", xy, start, end, *options) + + def chord(self, xy, start, end, *options): + self.render("chord", xy, start, end, *options) + + def ellipse(self, xy, *options): + self.render("ellipse", xy, *options) + + def line(self, xy, *options): + self.render("line", xy, *options) + + def pieslice(self, xy, start, end, *options): + self.render("pieslice", xy, start, end, *options) + + def polygon(self, xy, *options): + self.render("polygon", xy, *options) + + def rectangle(self, xy, *options): + self.render("rectangle", xy, *options) + + def symbol(self, xy, symbol, *options): + raise NotImplementedError("not in this version") + + def text(self, xy, text, font): + if self.transform: + xy = ImagePath.Path(xy) + xy.transform(self.transform) + self.draw.text(xy, text, font=font.font, fill=font.color) + + def textsize(self, text, font): + return self.draw.textsize(text, font=font.font) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py new file mode 100755 index 00000000000..86a19e650e2 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py @@ -0,0 +1,90 @@ +# +# The Python Imaging Library. +# $Id$ +# +# image enhancement classes +# +# For a background, see "Image Processing By Interpolation and +# Extrapolation", Paul Haeberli and Douglas Voorhies. Available +# at http://www.sgi.com/grafica/interp/index.html +# +# History: +# 1996-03-23 fl Created +# 2009-06-16 fl Fixed mean calculation +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +import Image, ImageFilter, ImageStat + +class _Enhance: + + ## + # Returns an enhanced image. The enhancement factor is a floating + # point value controlling the enhancement. Factor 1.0 always + # returns a copy of the original image, lower factors mean less + # colour (brightness, contrast, etc), and higher values more. + # There are no restrictions on this value. + # + # @param factor Enhancement factor. + # @return An enhanced image. + + def enhance(self, factor): + return Image.blend(self.degenerate, self.image, factor) + +## +# Color enhancement object. +#

+# This class can be used to adjust the colour balance of an image, in +# a manner similar to the controls on a colour TV set. An enhancement +# factor of 0.0 gives a black and white image, a factor of 1.0 gives +# the original image. + +class Color(_Enhance): + "Adjust image colour balance" + def __init__(self, image): + self.image = image + self.degenerate = image.convert("L").convert(image.mode) + +## +# Contrast enhancement object. +#

+# This class can be used to control the contrast of an image, similar +# to the contrast control on a TV set. An enhancement factor of 0.0 +# gives a solid grey image, factor 1.0 gives the original image. + +class Contrast(_Enhance): + "Adjust image contrast" + def __init__(self, image): + self.image = image + mean = int(ImageStat.Stat(image.convert("L")).mean[0] + 0.5) + self.degenerate = Image.new("L", image.size, mean).convert(image.mode) + +## +# Brightness enhancement object. +#

+# This class can be used to control the brighntess of an image. An +# enhancement factor of 0.0 gives a black image, factor 1.0 gives the +# original image. + +class Brightness(_Enhance): + "Adjust image brightness" + def __init__(self, image): + self.image = image + self.degenerate = Image.new(image.mode, image.size, 0) + +## +# Sharpness enhancement object. +#

+# This class can be used to adjust the sharpness of an image. The +# enhancement factor 0.0 gives a blurred image, 1.0 gives the original +# image, and a factor of 2.0 gives a sharpened image. + +class Sharpness(_Enhance): + "Adjust image sharpness" + def __init__(self, image): + self.image = image + self.degenerate = image.filter(ImageFilter.SMOOTH) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py new file mode 100755 index 00000000000..8a97c1b5b34 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py @@ -0,0 +1,528 @@ +# +# The Python Imaging Library. +# $Id$ +# +# base class for image file handlers +# +# history: +# 1995-09-09 fl Created +# 1996-03-11 fl Fixed load mechanism. +# 1996-04-15 fl Added pcx/xbm decoders. +# 1996-04-30 fl Added encoders. +# 1996-12-14 fl Added load helpers +# 1997-01-11 fl Use encode_to_file where possible +# 1997-08-27 fl Flush output in _save +# 1998-03-05 fl Use memory mapping for some modes +# 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B" +# 1999-05-31 fl Added image parser +# 2000-10-12 fl Set readonly flag on memory-mapped images +# 2002-03-20 fl Use better messages for common decoder errors +# 2003-04-21 fl Fall back on mmap/map_buffer if map is not available +# 2003-10-30 fl Added StubImageFile class +# 2004-02-25 fl Made incremental parser more robust +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1995-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image +import traceback, string, os + +MAXBLOCK = 65536 + +SAFEBLOCK = 1024*1024 + +ERRORS = { + -1: "image buffer overrun error", + -2: "decoding error", + -3: "unknown error", + -8: "bad configuration", + -9: "out of memory error" +} + +def raise_ioerror(error): + try: + message = Image.core.getcodecstatus(error) + except AttributeError: + message = ERRORS.get(error) + if not message: + message = "decoder error %d" % error + raise IOError(message + " when reading image file") + +# +# -------------------------------------------------------------------- +# Helpers + +def _tilesort(t1, t2): + # sort on offset + return cmp(t1[2], t2[2]) + +# +# -------------------------------------------------------------------- +# ImageFile base class + +## +# Base class for image file handlers. + +class ImageFile(Image.Image): + "Base class for image file format handlers." + + def __init__(self, fp=None, filename=None): + Image.Image.__init__(self) + + self.tile = None + self.readonly = 1 # until we know better + + self.decoderconfig = () + self.decodermaxblock = MAXBLOCK + + if Image.isStringType(fp): + # filename + self.fp = open(fp, "rb") + self.filename = fp + else: + # stream + self.fp = fp + self.filename = filename + + try: + self._open() + except IndexError, v: # end of data + if Image.DEBUG > 1: + traceback.print_exc() + raise SyntaxError, v + except TypeError, v: # end of data (ord) + if Image.DEBUG > 1: + traceback.print_exc() + raise SyntaxError, v + except KeyError, v: # unsupported mode + if Image.DEBUG > 1: + traceback.print_exc() + raise SyntaxError, v + except EOFError, v: # got header but not the first frame + if Image.DEBUG > 1: + traceback.print_exc() + raise SyntaxError, v + + if not self.mode or self.size[0] <= 0: + raise SyntaxError, "not identified by this driver" + + def draft(self, mode, size): + "Set draft mode" + + pass + + def verify(self): + "Check file integrity" + + # raise exception if something's wrong. must be called + # directly after open, and closes file when finished. + self.fp = None + + def load(self): + "Load image data based on tile list" + + pixel = Image.Image.load(self) + + if self.tile is None: + raise IOError("cannot load this image") + if not self.tile: + return pixel + + self.map = None + + readonly = 0 + + if self.filename and len(self.tile) == 1: + # try memory mapping + d, e, o, a = self.tile[0] + if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES: + try: + if hasattr(Image.core, "map"): + # use built-in mapper + self.map = Image.core.map(self.filename) + self.map.seek(o) + self.im = self.map.readimage( + self.mode, self.size, a[1], a[2] + ) + else: + # use mmap, if possible + import mmap + file = open(self.filename, "r+") + size = os.path.getsize(self.filename) + # FIXME: on Unix, use PROT_READ etc + self.map = mmap.mmap(file.fileno(), size) + self.im = Image.core.map_buffer( + self.map, self.size, d, e, o, a + ) + readonly = 1 + except (AttributeError, EnvironmentError, ImportError): + self.map = None + + self.load_prepare() + + # look for read/seek overrides + try: + read = self.load_read + except AttributeError: + read = self.fp.read + + try: + seek = self.load_seek + except AttributeError: + seek = self.fp.seek + + if not self.map: + + # sort tiles in file order + self.tile.sort(_tilesort) + + try: + # FIXME: This is a hack to handle TIFF's JpegTables tag. + prefix = self.tile_prefix + except AttributeError: + prefix = "" + + for d, e, o, a in self.tile: + d = Image._getdecoder(self.mode, d, a, self.decoderconfig) + seek(o) + try: + d.setimage(self.im, e) + except ValueError: + continue + b = prefix + t = len(b) + while 1: + s = read(self.decodermaxblock) + if not s: + self.tile = [] + raise IOError("image file is truncated (%d bytes not processed)" % len(b)) + b = b + s + n, e = d.decode(b) + if n < 0: + break + b = b[n:] + t = t + n + + self.tile = [] + self.readonly = readonly + + self.fp = None # might be shared + + if not self.map and e < 0: + raise_ioerror(e) + + # post processing + if hasattr(self, "tile_post_rotate"): + # FIXME: This is a hack to handle rotated PCD's + self.im = self.im.rotate(self.tile_post_rotate) + self.size = self.im.size + + self.load_end() + + return Image.Image.load(self) + + def load_prepare(self): + # create image memory if necessary + if not self.im or\ + self.im.mode != self.mode or self.im.size != self.size: + self.im = Image.core.new(self.mode, self.size) + # create palette (optional) + if self.mode == "P": + Image.Image.load(self) + + def load_end(self): + # may be overridden + pass + + # may be defined for contained formats + # def load_seek(self, pos): + # pass + + # may be defined for blocked formats (e.g. PNG) + # def load_read(self, bytes): + # pass + +## +# Base class for stub image loaders. +#

+# A stub loader is an image loader that can identify files of a +# certain format, but relies on external code to load the file. + +class StubImageFile(ImageFile): + "Base class for stub image loaders." + + def _open(self): + raise NotImplementedError( + "StubImageFile subclass must implement _open" + ) + + def load(self): + loader = self._load() + if loader is None: + raise IOError("cannot find loader for this %s file" % self.format) + image = loader.load(self) + assert image is not None + # become the other object (!) + self.__class__ = image.__class__ + self.__dict__ = image.__dict__ + + ## + # (Hook) Find actual image loader. + + def _load(self): + raise NotImplementedError( + "StubImageFile subclass must implement _load" + ) + +## +# (Internal) Support class for the Parser file. + +class _ParserFile: + # parser support class. + + def __init__(self, data): + self.data = data + self.offset = 0 + + def close(self): + self.data = self.offset = None + + def tell(self): + return self.offset + + def seek(self, offset, whence=0): + if whence == 0: + self.offset = offset + elif whence == 1: + self.offset = self.offset + offset + else: + # force error in Image.open + raise IOError("illegal argument to seek") + + def read(self, bytes=0): + pos = self.offset + if bytes: + data = self.data[pos:pos+bytes] + else: + data = self.data[pos:] + self.offset = pos + len(data) + return data + + def readline(self): + # FIXME: this is slow! + s = "" + while 1: + c = self.read(1) + if not c: + break + s = s + c + if c == "\n": + break + return s + +## +# Incremental image parser. This class implements the standard +# feed/close consumer interface. + +class Parser: + + incremental = None + image = None + data = None + decoder = None + finished = 0 + + ## + # (Consumer) Reset the parser. Note that you can only call this + # method immediately after you've created a parser; parser + # instances cannot be reused. + + def reset(self): + assert self.data is None, "cannot reuse parsers" + + ## + # (Consumer) Feed data to the parser. + # + # @param data A string buffer. + # @exception IOError If the parser failed to parse the image file. + + def feed(self, data): + # collect data + + if self.finished: + return + + if self.data is None: + self.data = data + else: + self.data = self.data + data + + # parse what we have + if self.decoder: + + if self.offset > 0: + # skip header + skip = min(len(self.data), self.offset) + self.data = self.data[skip:] + self.offset = self.offset - skip + if self.offset > 0 or not self.data: + return + + n, e = self.decoder.decode(self.data) + + if n < 0: + # end of stream + self.data = None + self.finished = 1 + if e < 0: + # decoding error + self.image = None + raise_ioerror(e) + else: + # end of image + return + self.data = self.data[n:] + + elif self.image: + + # if we end up here with no decoder, this file cannot + # be incrementally parsed. wait until we've gotten all + # available data + pass + + else: + + # attempt to open this file + try: + try: + fp = _ParserFile(self.data) + im = Image.open(fp) + finally: + fp.close() # explicitly close the virtual file + except IOError: + pass # not enough data + else: + flag = hasattr(im, "load_seek") or hasattr(im, "load_read") + if flag or len(im.tile) != 1: + # custom load code, or multiple tiles + self.decode = None + else: + # initialize decoder + im.load_prepare() + d, e, o, a = im.tile[0] + im.tile = [] + self.decoder = Image._getdecoder( + im.mode, d, a, im.decoderconfig + ) + self.decoder.setimage(im.im, e) + + # calculate decoder offset + self.offset = o + if self.offset <= len(self.data): + self.data = self.data[self.offset:] + self.offset = 0 + + self.image = im + + ## + # (Consumer) Close the stream. + # + # @return An image object. + # @exception IOError If the parser failed to parse the image file. + + def close(self): + # finish decoding + if self.decoder: + # get rid of what's left in the buffers + self.feed("") + self.data = self.decoder = None + if not self.finished: + raise IOError("image was incomplete") + if not self.image: + raise IOError("cannot parse this image") + if self.data: + # incremental parsing not possible; reopen the file + # not that we have all data + try: + fp = _ParserFile(self.data) + self.image = Image.open(fp) + finally: + self.image.load() + fp.close() # explicitly close the virtual file + return self.image + +# -------------------------------------------------------------------- + +## +# (Helper) Save image body to file. +# +# @param im Image object. +# @param fp File object. +# @param tile Tile list. + +def _save(im, fp, tile): + "Helper to save image based on tile list" + + im.load() + if not hasattr(im, "encoderconfig"): + im.encoderconfig = () + tile.sort(_tilesort) + # FIXME: make MAXBLOCK a configuration parameter + bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c + try: + fh = fp.fileno() + fp.flush() + except AttributeError: + # compress to Python file-compatible object + for e, b, o, a in tile: + e = Image._getencoder(im.mode, e, a, im.encoderconfig) + if o > 0: + fp.seek(o, 0) + e.setimage(im.im, b) + while 1: + l, s, d = e.encode(bufsize) + fp.write(d) + if s: + break + if s < 0: + raise IOError("encoder error %d when writing image file" % s) + else: + # slight speedup: compress to real file object + for e, b, o, a in tile: + e = Image._getencoder(im.mode, e, a, im.encoderconfig) + if o > 0: + fp.seek(o, 0) + e.setimage(im.im, b) + s = e.encode_to_file(fh, bufsize) + if s < 0: + raise IOError("encoder error %d when writing image file" % s) + try: + fp.flush() + except: pass + + +## +# Reads large blocks in a safe way. Unlike fp.read(n), this function +# doesn't trust the user. If the requested size is larger than +# SAFEBLOCK, the file is read block by block. +# +# @param fp File handle. Must implement a read method. +# @param size Number of bytes to read. +# @return A string containing up to size bytes of data. + +def _safe_read(fp, size): + if size <= 0: + return "" + if size <= SAFEBLOCK: + return fp.read(size) + data = [] + while size > 0: + block = fp.read(min(size, SAFEBLOCK)) + if not block: + break + data.append(block) + size = size - len(block) + return string.join(data, "") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py new file mode 100755 index 00000000000..c12a25738c1 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py @@ -0,0 +1,39 @@ +# +# The Python Imaging Library. +# $Id$ +# +# kludge to get basic ImageFileIO functionality +# +# History: +# 1998-08-06 fl Recreated +# +# Copyright (c) Secret Labs AB 1998-2002. +# +# See the README file for information on usage and redistribution. +# + +from StringIO import StringIO + +## +# The ImageFileIO module can be used to read an image from a +# socket, or any other stream device. +#

+# This module is deprecated. New code should use the Parser +# class in the ImageFile module instead. +# +# @see ImageFile#Parser + +class ImageFileIO(StringIO): + + ## + # Adds buffering to a stream file object, in order to + # provide seek and tell methods required + # by the Image.open method. The stream object must + # implement read and close methods. + # + # @param fp Stream file handle. + # @see Image#open + + def __init__(self, fp): + data = fp.read() + StringIO.__init__(self, data) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py new file mode 100755 index 00000000000..918bab177c1 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py @@ -0,0 +1,289 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard filters +# +# History: +# 1995-11-27 fl Created +# 2002-06-08 fl Added rank and mode filters +# 2003-09-15 fl Fixed rank calculation in rank filter; added expand call +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2002 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +class Filter: + pass + +## +# Convolution filter kernel. + +class Kernel(Filter): + + ## + # Create a convolution kernel. The current version only + # supports 3x3 and 5x5 integer and floating point kernels. + #

+ # In the current version, kernels can only be applied to + # "L" and "RGB" images. + # + # @def __init__(size, kernel, **options) + # @param size Kernel size, given as (width, height). In + # the current version, this must be (3,3) or (5,5). + # @param kernel A sequence containing kernel weights. + # @param **options Optional keyword arguments. + # @keyparam scale Scale factor. If given, the result for each + # pixel is divided by this value. The default is the sum + # of the kernel weights. + # @keyparam offset Offset. If given, this value is added to the + # result, after it has been divided by the scale factor. + + def __init__(self, size, kernel, scale=None, offset=0): + if scale is None: + # default scale is sum of kernel + scale = reduce(lambda a,b: a+b, kernel) + if size[0] * size[1] != len(kernel): + raise ValueError("not enough coefficients in kernel") + self.filterargs = size, scale, offset, kernel + + def filter(self, image): + if image.mode == "P": + raise ValueError("cannot filter palette images") + return apply(image.filter, self.filterargs) + +class BuiltinFilter(Kernel): + def __init__(self): + pass + +## +# Rank filter. + +class RankFilter(Filter): + name = "Rank" + + ## + # Create a rank filter. The rank filter sorts all pixels in + # a window of the given size, and returns the rank'th value. + # + # @param size The kernel size, in pixels. + # @param rank What pixel value to pick. Use 0 for a min filter, + # size*size/2 for a median filter, size*size-1 for a max filter, + # etc. + + def __init__(self, size, rank): + self.size = size + self.rank = rank + + def filter(self, image): + if image.mode == "P": + raise ValueError("cannot filter palette images") + image = image.expand(self.size/2, self.size/2) + return image.rankfilter(self.size, self.rank) + +## +# Median filter. Picks the median pixel value in a window with the +# given size. + +class MedianFilter(RankFilter): + name = "Median" + + ## + # Create a median filter. + # + # @param size The kernel size, in pixels. + + def __init__(self, size=3): + self.size = size + self.rank = size*size/2 + +## +# Min filter. Picks the lowest pixel value in a window with the given +# size. + +class MinFilter(RankFilter): + name = "Min" + + ## + # Create a min filter. + # + # @param size The kernel size, in pixels. + + def __init__(self, size=3): + self.size = size + self.rank = 0 + +## +# Max filter. Picks the largest pixel value in a window with the +# given size. + +class MaxFilter(RankFilter): + name = "Max" + + ## + # Create a max filter. + # + # @param size The kernel size, in pixels. + + def __init__(self, size=3): + self.size = size + self.rank = size*size-1 + +## +# Mode filter. Picks the most frequent pixel value in a box with the +# given size. Pixel values that occur only once or twice are ignored; +# if no pixel value occurs more than twice, the original pixel value +# is preserved. + +class ModeFilter(Filter): + name = "Mode" + + ## + # Create a mode filter. + # + # @param size The kernel size, in pixels. + + def __init__(self, size=3): + self.size = size + def filter(self, image): + return image.modefilter(self.size) + +## +# Gaussian blur filter. + +class GaussianBlur(Filter): + name = "GaussianBlur" + + def __init__(self, radius=2): + self.radius = 2 + def filter(self, image): + return image.gaussian_blur(self.radius) + +## +# Unsharp mask filter. + +class UnsharpMask(Filter): + name = "UnsharpMask" + + def __init__(self, radius=2, percent=150, threshold=3): + self.radius = 2 + self.percent = percent + self.threshold = threshold + def filter(self, image): + return image.unsharp_mask(self.radius, self.percent, self.threshold) + +## +# Simple blur filter. + +class BLUR(BuiltinFilter): + name = "Blur" + filterargs = (5, 5), 16, 0, ( + 1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1 + ) + +## +# Simple contour filter. + +class CONTOUR(BuiltinFilter): + name = "Contour" + filterargs = (3, 3), 1, 255, ( + -1, -1, -1, + -1, 8, -1, + -1, -1, -1 + ) + +## +# Simple detail filter. + +class DETAIL(BuiltinFilter): + name = "Detail" + filterargs = (3, 3), 6, 0, ( + 0, -1, 0, + -1, 10, -1, + 0, -1, 0 + ) + +## +# Simple edge enhancement filter. + +class EDGE_ENHANCE(BuiltinFilter): + name = "Edge-enhance" + filterargs = (3, 3), 2, 0, ( + -1, -1, -1, + -1, 10, -1, + -1, -1, -1 + ) + +## +# Simple stronger edge enhancement filter. + +class EDGE_ENHANCE_MORE(BuiltinFilter): + name = "Edge-enhance More" + filterargs = (3, 3), 1, 0, ( + -1, -1, -1, + -1, 9, -1, + -1, -1, -1 + ) + +## +# Simple embossing filter. + +class EMBOSS(BuiltinFilter): + name = "Emboss" + filterargs = (3, 3), 1, 128, ( + -1, 0, 0, + 0, 1, 0, + 0, 0, 0 + ) + +## +# Simple edge-finding filter. + +class FIND_EDGES(BuiltinFilter): + name = "Find Edges" + filterargs = (3, 3), 1, 0, ( + -1, -1, -1, + -1, 8, -1, + -1, -1, -1 + ) + +## +# Simple smoothing filter. + +class SMOOTH(BuiltinFilter): + name = "Smooth" + filterargs = (3, 3), 13, 0, ( + 1, 1, 1, + 1, 5, 1, + 1, 1, 1 + ) + +## +# Simple stronger smoothing filter. + +class SMOOTH_MORE(BuiltinFilter): + name = "Smooth More" + filterargs = (5, 5), 100, 0, ( + 1, 1, 1, 1, 1, + 1, 5, 5, 5, 1, + 1, 5, 44, 5, 1, + 1, 5, 5, 5, 1, + 1, 1, 1, 1, 1 + ) + +## +# Simple sharpening filter. + +class SHARPEN(BuiltinFilter): + name = "Sharpen" + filterargs = (3, 3), 16, 0, ( + -2, -2, -2, + -2, 32, -2, + -2, -2, -2 + ) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py new file mode 100755 index 00000000000..3ea2f2f8efd --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py @@ -0,0 +1,390 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PIL raster font management +# +# History: +# 1996-08-07 fl created (experimental) +# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3 +# 1999-02-06 fl rewrote most font management stuff in C +# 1999-03-17 fl take pth files into account in load_path (from Richard Jones) +# 2001-02-17 fl added freetype support +# 2001-05-09 fl added TransposedFont wrapper class +# 2002-03-04 fl make sure we have a "L" or "1" font +# 2002-12-04 fl skip non-directory entries in the system path +# 2003-04-29 fl add embedded default font +# 2003-09-27 fl added support for truetype charmap encodings +# +# Todo: +# Adapt to PILFONT2 format (16-bit fonts, compressed, single file) +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image +import os, string, sys + +class _imagingft_not_installed: + # module placeholder + def __getattr__(self, id): + raise ImportError("The _imagingft C module is not installed") + +try: + import _imagingft + core = _imagingft + del _imagingft +except ImportError: + core = _imagingft_not_installed() + +# FIXME: add support for pilfont2 format (see FontFile.py) + +# -------------------------------------------------------------------- +# Font metrics format: +# "PILfont" LF +# fontdescriptor LF +# (optional) key=value... LF +# "DATA" LF +# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox) +# +# To place a character, cut out srcbox and paste at dstbox, +# relative to the character position. Then move the character +# position according to dx, dy. +# -------------------------------------------------------------------- + +## +# The ImageFont module defines a class with the same name. +# Instances of this class store bitmap fonts, and are used with the +# text method of the ImageDraw class. +#

+# PIL uses it's own font file format to store bitmap fonts. You can +# use the pilfont utility to convert BDF and PCF font +# descriptors (X window font formats) to this format. +#

+# Starting with version 1.1.4, PIL can be configured to support +# TrueType and OpenType fonts. For earlier version, TrueType +# support is only available as part of the imToolkit package +# +# @see ImageDraw#ImageDraw.text +# @see pilfont + +class ImageFont: + "PIL font wrapper" + + def _load_pilfont(self, filename): + + file = open(filename, "rb") + + for ext in (".png", ".gif", ".pbm"): + try: + fullname = os.path.splitext(filename)[0] + ext + image = Image.open(fullname) + except: + pass + else: + if image and image.mode in ("1", "L"): + break + else: + raise IOError("cannot find glyph data file") + + self.file = fullname + + return self._load_pilfont_data(file, image) + + def _load_pilfont_data(self, file, image): + + # read PILfont header + if file.readline() != "PILfont\n": + raise SyntaxError("Not a PILfont file") + d = string.split(file.readline(), ";") + self.info = [] # FIXME: should be a dictionary + while True: + s = file.readline() + if not s or s == "DATA\n": + break + self.info.append(s) + + # read PILfont metrics + data = file.read(256*20) + + # check image + if image.mode not in ("1", "L"): + raise TypeError("invalid font image mode") + + image.load() + + self.font = Image.core.font(image.im, data) + + # delegate critical operations to internal type + self.getsize = self.font.getsize + self.getmask = self.font.getmask + +## +# Wrapper for FreeType fonts. Application code should use the +# truetype factory function to create font objects. + +class FreeTypeFont: + "FreeType font wrapper (requires _imagingft service)" + + def __init__(self, file, size, index=0, encoding=""): + # FIXME: use service provider instead + self.font = core.getfont(file, size, index, encoding) + + def getname(self): + return self.font.family, self.font.style + + def getmetrics(self): + return self.font.ascent, self.font.descent + + def getsize(self, text): + return self.font.getsize(text)[0] + + def getmask(self, text, mode=""): + return self.getmask2(text, mode)[0] + + def getmask2(self, text, mode="", fill=Image.core.fill): + size, offset = self.font.getsize(text) + im = fill("L", size, 0) + self.font.render(text, im.id, mode=="1") + return im, offset + +## +# Wrapper that creates a transposed font from any existing font +# object. +# +# @param font A font object. +# @param orientation An optional orientation. If given, this should +# be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM, +# Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270. + +class TransposedFont: + "Wrapper for writing rotated or mirrored text" + + def __init__(self, font, orientation=None): + self.font = font + self.orientation = orientation # any 'transpose' argument, or None + + def getsize(self, text): + w, h = self.font.getsize(text) + if self.orientation in (Image.ROTATE_90, Image.ROTATE_270): + return h, w + return w, h + + def getmask(self, text, mode=""): + im = self.font.getmask(text, mode) + if self.orientation is not None: + return im.transpose(self.orientation) + return im + +## +# Load font file. This function loads a font object from the given +# bitmap font file, and returns the corresponding font object. +# +# @param filename Name of font file. +# @return A font object. +# @exception IOError If the file could not be read. + +def load(filename): + "Load a font file." + f = ImageFont() + f._load_pilfont(filename) + return f + +## +# Load a TrueType or OpenType font file, and create a font object. +# This function loads a font object from the given file, and creates +# a font object for a font of the given size. +#

+# This function requires the _imagingft service. +# +# @param filename A truetype font file. Under Windows, if the file +# is not found in this filename, the loader also looks in Windows +# fonts directory +# @param size The requested size, in points. +# @param index Which font face to load (default is first available face). +# @param encoding Which font encoding to use (default is Unicode). Common +# encodings are "unic" (Unicode), "symb" (Microsoft Symbol), "ADOB" +# (Adobe Standard), "ADBE" (Adobe Expert), and "armn" (Apple Roman). +# See the FreeType documentation for more information. +# @return A font object. +# @exception IOError If the file could not be read. + +def truetype(filename, size, index=0, encoding=""): + "Load a truetype font file." + try: + return FreeTypeFont(filename, size, index, encoding) + except IOError: + if sys.platform == "win32": + # check the windows font repository + # NOTE: must use uppercase WINDIR, to work around bugs in + # 1.5.2's os.environ.get() + windir = os.environ.get("WINDIR") + if windir: + filename = os.path.join(windir, "fonts", filename) + return FreeTypeFont(filename, size, index, encoding) + raise + +## +# Load font file. Same as load, but searches for a bitmap font along +# the Python path. +# +# @param filename Name of font file. +# @return A font object. +# @exception IOError If the file could not be read. +# @see #load + +def load_path(filename): + "Load a font file, searching along the Python path." + for dir in sys.path: + if Image.isDirectory(dir): + try: + return load(os.path.join(dir, filename)) + except IOError: + pass + raise IOError("cannot find font file") + +## +# Load a (probably rather ugly) default font. +# +# @return A font object. + +def load_default(): + "Load a default font." + from StringIO import StringIO + import base64 + f = ImageFont() + f._load_pilfont_data( + # courB08 + StringIO(base64.decodestring(''' +UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA +BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL +AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA +AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB +ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A +BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB +//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA +AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH +AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA +ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv +AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/ +/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 +AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA +AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG +AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA +BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA +AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA +2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF +AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// ++gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA +////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA +BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv +AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA +AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA +AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA +BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// +//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA +AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF +AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB +mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn +AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA +AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 +AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA +Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB +//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA +AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ +AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC +DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ +AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/ ++wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5 +AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/ +///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG +AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA +BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA +Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC +eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG +AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// ++gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA +////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA +BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT +AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A +AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA +Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA +Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// +//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA +AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ +AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA +LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 +AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA +AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 +AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA +AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG +AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA +EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK +AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA +pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG +AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// ++QAGAAIAzgAKANUAEw== +''')), Image.open(StringIO(base64.decodestring(''' +iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u +Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9 +M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g +LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F +IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA +Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 +NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx +in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 +SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY +AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt +y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG +ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY +lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H +/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 +AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 +c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ +/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw +pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv +oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR +evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA +AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v// +Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR +w7IkEbzhVQAAAABJRU5ErkJggg== +''')))) + return f + +if __name__ == "__main__": + # create font data chunk for embedding + import base64, os, sys + font = "../Images/courB08" + print " f._load_pilfont_data(" + print " # %s" % os.path.basename(font) + print " StringIO(base64.decodestring('''" + base64.encode(open(font + ".pil", "rb"), sys.stdout) + print "''')), Image.open(StringIO(base64.decodestring('''" + base64.encode(open(font + ".pbm", "rb"), sys.stdout) + print "'''))))" diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py new file mode 100755 index 00000000000..5c58b6ca918 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py @@ -0,0 +1,28 @@ +# +# The Python Imaging Library. +# $Id$ +# +# OpenGL pixmap/texture interface (requires imToolkit OpenGL extensions) +# +# History: +# 2003-09-13 fl Added +# +# Copyright (c) Secret Labs AB 2003. +# +# See the README file for information on usage and redistribution. +# + +## +# OpenGL pixmap/texture interface (requires imToolkit OpenGL +# extensions.) +## + +import _imaginggl + +## +# Texture factory. + +class TextureFactory: + pass # overwritten by the _imaginggl module + +from _imaginggl import * diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py new file mode 100755 index 00000000000..9bcd804d3a3 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py @@ -0,0 +1,71 @@ +# +# The Python Imaging Library +# $Id$ +# +# screen grabber (windows only) +# +# History: +# 2001-04-26 fl created +# 2001-09-17 fl use builtin driver, if present +# 2002-11-19 fl added grabclipboard support +# +# Copyright (c) 2001-2002 by Secret Labs AB +# Copyright (c) 2001-2002 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image + +## +# (New in 1.1.3) The ImageGrab module can be used to copy +# the contents of the screen to a PIL image memory. +#

+# The current version works on Windows only.

+# +# @since 1.1.3 +## + +try: + # built-in driver (1.1.3 and later) + grabber = Image.core.grabscreen +except AttributeError: + # stand-alone driver (pil plus) + import _grabscreen + grabber = _grabscreen.grab + +## +# (New in 1.1.3) Take a snapshot of the screen. The pixels inside the +# bounding box are returned as an "RGB" image. If the bounding box is +# omitted, the entire screen is copied. +# +# @param bbox What region to copy. Default is the entire screen. +# @return An image +# @since 1.1.3 + +def grab(bbox=None): + size, data = grabber() + im = Image.fromstring( + "RGB", size, data, + # RGB, 32-bit line padding, origo in lower left corner + "raw", "BGR", (size[0]*3 + 3) & -4, -1 + ) + if bbox: + im = im.crop(bbox) + return im + +## +# (New in 1.1.4) Take a snapshot of the clipboard image, if any. +# +# @return An image, a list of filenames, or None if the clipboard does +# not contain image data or filenames. Note that if a list is +# returned, the filenames may not represent image files. +# @since 1.1.4 + +def grabclipboard(): + debug = 0 # temporary interface + data = Image.core.grabclipboard(debug) + if Image.isStringType(data): + import BmpImagePlugin, StringIO + return BmpImagePlugin.DibImageFile(StringIO.StringIO(data)) + return data diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py new file mode 100755 index 00000000000..56c42a45a9d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py @@ -0,0 +1,207 @@ +# +# The Python Imaging Library +# $Id$ +# +# a simple math add-on for the Python Imaging Library +# +# History: +# 1999-02-15 fl Original PIL Plus release +# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 +# 2005-09-12 fl Fixed int() and float() for Python 2.4.1 +# +# Copyright (c) 1999-2005 by Secret Labs AB +# Copyright (c) 2005 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image +import _imagingmath + +VERBOSE = 0 + +def _isconstant(v): + return isinstance(v, type(0)) or isinstance(v, type(0.0)) + +class _Operand: + # wraps an image operand, providing standard operators + + def __init__(self, im): + self.im = im + + def __fixup(self, im1): + # convert image to suitable mode + if isinstance(im1, _Operand): + # argument was an image. + if im1.im.mode in ("1", "L"): + return im1.im.convert("I") + elif im1.im.mode in ("I", "F"): + return im1.im + else: + raise ValueError, "unsupported mode: %s" % im1.im.mode + else: + # argument was a constant + if _isconstant(im1) and self.im.mode in ("1", "L", "I"): + return Image.new("I", self.im.size, im1) + else: + return Image.new("F", self.im.size, im1) + + def apply(self, op, im1, im2=None, mode=None): + im1 = self.__fixup(im1) + if im2 is None: + # unary operation + out = Image.new(mode or im1.mode, im1.size, None) + im1.load() + try: + op = getattr(_imagingmath, op+"_"+im1.mode) + except AttributeError: + raise TypeError, "bad operand type for '%s'" % op + _imagingmath.unop(op, out.im.id, im1.im.id) + else: + # binary operation + im2 = self.__fixup(im2) + if im1.mode != im2.mode: + # convert both arguments to floating point + if im1.mode != "F": im1 = im1.convert("F") + if im2.mode != "F": im2 = im2.convert("F") + if im1.mode != im2.mode: + raise ValueError, "mode mismatch" + if im1.size != im2.size: + # crop both arguments to a common size + size = (min(im1.size[0], im2.size[0]), + min(im1.size[1], im2.size[1])) + if im1.size != size: im1 = im1.crop((0, 0) + size) + if im2.size != size: im2 = im2.crop((0, 0) + size) + out = Image.new(mode or im1.mode, size, None) + else: + out = Image.new(mode or im1.mode, im1.size, None) + im1.load(); im2.load() + try: + op = getattr(_imagingmath, op+"_"+im1.mode) + except AttributeError: + raise TypeError, "bad operand type for '%s'" % op + _imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id) + return _Operand(out) + + # unary operators + def __nonzero__(self): + # an image is "true" if it contains at least one non-zero pixel + return self.im.getbbox() is not None + def __abs__(self): + return self.apply("abs", self) + def __pos__(self): + return self + def __neg__(self): + return self.apply("neg", self) + + # binary operators + def __add__(self, other): + return self.apply("add", self, other) + def __radd__(self, other): + return self.apply("add", other, self) + def __sub__(self, other): + return self.apply("sub", self, other) + def __rsub__(self, other): + return self.apply("sub", other, self) + def __mul__(self, other): + return self.apply("mul", self, other) + def __rmul__(self, other): + return self.apply("mul", other, self) + def __div__(self, other): + return self.apply("div", self, other) + def __rdiv__(self, other): + return self.apply("div", other, self) + def __mod__(self, other): + return self.apply("mod", self, other) + def __rmod__(self, other): + return self.apply("mod", other, self) + def __pow__(self, other): + return self.apply("pow", self, other) + def __rpow__(self, other): + return self.apply("pow", other, self) + + # bitwise + def __invert__(self): + return self.apply("invert", self) + def __and__(self, other): + return self.apply("and", self, other) + def __rand__(self, other): + return self.apply("and", other, self) + def __or__(self, other): + return self.apply("or", self, other) + def __ror__(self, other): + return self.apply("or", other, self) + def __xor__(self, other): + return self.apply("xor", self, other) + def __rxor__(self, other): + return self.apply("xor", other, self) + def __lshift__(self, other): + return self.apply("lshift", self, other) + def __rshift__(self, other): + return self.apply("rshift", self, other) + + # logical + def __eq__(self, other): + return self.apply("eq", self, other) + def __ne__(self, other): + return self.apply("ne", self, other) + def __lt__(self, other): + return self.apply("lt", self, other) + def __le__(self, other): + return self.apply("le", self, other) + def __gt__(self, other): + return self.apply("gt", self, other) + def __ge__(self, other): + return self.apply("ge", self, other) + +# conversions +def imagemath_int(self): + return _Operand(self.im.convert("I")) +def imagemath_float(self): + return _Operand(self.im.convert("F")) + +# logical +def imagemath_equal(self, other): + return self.apply("eq", self, other, mode="I") +def imagemath_notequal(self, other): + return self.apply("ne", self, other, mode="I") + +def imagemath_min(self, other): + return self.apply("min", self, other) +def imagemath_max(self, other): + return self.apply("max", self, other) + +def imagemath_convert(self, mode): + return _Operand(self.im.convert(mode)) + +ops = {} +for k, v in globals().items(): + if k[:10] == "imagemath_": + ops[k[10:]] = v + +## +# Evaluates an image expression. +# +# @param expression A string containing a Python-style expression. +# @keyparam options Values to add to the evaluation context. You +# can either use a dictionary, or one or more keyword arguments. +# @return The evaluated expression. This is usually an image object, +# but can also be an integer, a floating point value, or a pixel +# tuple, depending on the expression. + +def eval(expression, _dict={}, **kw): + + # build execution namespace + args = ops.copy() + args.update(_dict) + args.update(kw) + for k, v in args.items(): + if hasattr(v, "im"): + args[k] = _Operand(v) + + import __builtin__ + out =__builtin__.eval(expression, args) + try: + return out.im + except AttributeError: + return out diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py new file mode 100755 index 00000000000..1d5df1c6dca --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py @@ -0,0 +1,50 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard mode descriptors +# +# History: +# 2006-03-20 fl Added +# +# Copyright (c) 2006 by Secret Labs AB. +# Copyright (c) 2006 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +# mode descriptor cache +_modes = {} + +## +# Wrapper for mode strings. + +class ModeDescriptor: + + def __init__(self, mode, bands, basemode, basetype): + self.mode = mode + self.bands = bands + self.basemode = basemode + self.basetype = basetype + + def __str__(self): + return self.mode + +## +# Gets a mode descriptor for the given mode. + +def getmode(mode): + if not _modes: + # initialize mode cache + import Image + # core modes + for m, (basemode, basetype, bands) in Image._MODEINFO.items(): + _modes[m] = ModeDescriptor(m, bands, basemode, basetype) + # extra experimental modes + _modes["LA"] = ModeDescriptor("LA", ("L", "A"), "L", "L") + _modes["PA"] = ModeDescriptor("PA", ("P", "A"), "RGB", "L") + # mapping modes + _modes["I;16"] = ModeDescriptor("I;16", "I", "L", "L") + _modes["I;16L"] = ModeDescriptor("I;16L", "I", "L", "L") + _modes["I;16B"] = ModeDescriptor("I;16B", "I", "L", "L") + return _modes[mode] diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py new file mode 100755 index 00000000000..b51d78e258b --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py @@ -0,0 +1,439 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard image operations +# +# History: +# 2001-10-20 fl Created +# 2001-10-23 fl Added autocontrast operator +# 2001-12-18 fl Added Kevin's fit operator +# 2004-03-14 fl Fixed potential division by zero in equalize +# 2005-05-05 fl Fixed equalize for low number of values +# +# Copyright (c) 2001-2004 by Secret Labs AB +# Copyright (c) 2001-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image +import operator + +## +# (New in 1.1.3) The ImageOps module contains a number of +# 'ready-made' image processing operations. This module is somewhat +# experimental, and most operators only work on L and RGB images. +# +# @since 1.1.3 +## + +# +# helpers + +def _border(border): + if type(border) is type(()): + if len(border) == 2: + left, top = right, bottom = border + elif len(border) == 4: + left, top, right, bottom = border + else: + left = top = right = bottom = border + return left, top, right, bottom + +def _color(color, mode): + if Image.isStringType(color): + import ImageColor + color = ImageColor.getcolor(color, mode) + return color + +def _lut(image, lut): + if image.mode == "P": + # FIXME: apply to lookup table, not image data + raise NotImplementedError("mode P support coming soon") + elif image.mode in ("L", "RGB"): + if image.mode == "RGB" and len(lut) == 256: + lut = lut + lut + lut + return image.point(lut) + else: + raise IOError, "not supported for this image mode" + +# +# actions + +## +# Maximize (normalize) image contrast. This function calculates a +# histogram of the input image, removes cutoff percent of the +# lightest and darkest pixels from the histogram, and remaps the image +# so that the darkest pixel becomes black (0), and the lightest +# becomes white (255). +# +# @param image The image to process. +# @param cutoff How many percent to cut off from the histogram. +# @param ignore The background pixel value (use None for no background). +# @return An image. + +def autocontrast(image, cutoff=0, ignore=None): + "Maximize image contrast, based on histogram" + histogram = image.histogram() + lut = [] + for layer in range(0, len(histogram), 256): + h = histogram[layer:layer+256] + if ignore is not None: + # get rid of outliers + try: + h[ignore] = 0 + except TypeError: + # assume sequence + for ix in ignore: + h[ix] = 0 + if cutoff: + # cut off pixels from both ends of the histogram + # get number of pixels + n = 0 + for ix in range(256): + n = n + h[ix] + # remove cutoff% pixels from the low end + cut = n * cutoff / 100 + for lo in range(256): + if cut > h[lo]: + cut = cut - h[lo] + h[lo] = 0 + else: + h[lo] = h[lo] - cut + cut = 0 + if cut <= 0: + break + # remove cutoff% samples from the hi end + cut = n * cutoff / 100 + for hi in range(255, -1, -1): + if cut > h[hi]: + cut = cut - h[hi] + h[hi] = 0 + else: + h[hi] = h[hi] - cut + cut = 0 + if cut <= 0: + break + # find lowest/highest samples after preprocessing + for lo in range(256): + if h[lo]: + break + for hi in range(255, -1, -1): + if h[hi]: + break + if hi <= lo: + # don't bother + lut.extend(range(256)) + else: + scale = 255.0 / (hi - lo) + offset = -lo * scale + for ix in range(256): + ix = int(ix * scale + offset) + if ix < 0: + ix = 0 + elif ix > 255: + ix = 255 + lut.append(ix) + return _lut(image, lut) + +## +# Colorize grayscale image. The black and white +# arguments should be RGB tuples; this function calculates a colour +# wedge mapping all black pixels in the source image to the first +# colour, and all white pixels to the second colour. +# +# @param image The image to colourize. +# @param black The colour to use for black input pixels. +# @param white The colour to use for white input pixels. +# @return An image. + +def colorize(image, black, white): + "Colorize a grayscale image" + assert image.mode == "L" + black = _color(black, "RGB") + white = _color(white, "RGB") + red = []; green = []; blue = [] + for i in range(256): + red.append(black[0]+i*(white[0]-black[0])/255) + green.append(black[1]+i*(white[1]-black[1])/255) + blue.append(black[2]+i*(white[2]-black[2])/255) + image = image.convert("RGB") + return _lut(image, red + green + blue) + +## +# Remove border from image. The same amount of pixels are removed +# from all four sides. This function works on all image modes. +# +# @param image The image to crop. +# @param border The number of pixels to remove. +# @return An image. +# @see Image#Image.crop + +def crop(image, border=0): + "Crop border off image" + left, top, right, bottom = _border(border) + return image.crop( + (left, top, image.size[0]-right, image.size[1]-bottom) + ) + +## +# Deform the image. +# +# @param image The image to deform. +# @param deformer A deformer object. Any object that implements a +# getmesh method can be used. +# @param resample What resampling filter to use. +# @return An image. + +def deform(image, deformer, resample=Image.BILINEAR): + "Deform image using the given deformer" + return image.transform( + image.size, Image.MESH, deformer.getmesh(image), resample + ) + +## +# Equalize the image histogram. This function applies a non-linear +# mapping to the input image, in order to create a uniform +# distribution of grayscale values in the output image. +# +# @param image The image to equalize. +# @param mask An optional mask. If given, only the pixels selected by +# the mask are included in the analysis. +# @return An image. + +def equalize(image, mask=None): + "Equalize image histogram" + if image.mode == "P": + image = image.convert("RGB") + h = image.histogram(mask) + lut = [] + for b in range(0, len(h), 256): + histo = filter(None, h[b:b+256]) + if len(histo) <= 1: + lut.extend(range(256)) + else: + step = (reduce(operator.add, histo) - histo[-1]) / 255 + if not step: + lut.extend(range(256)) + else: + n = step / 2 + for i in range(256): + lut.append(n / step) + n = n + h[i+b] + return _lut(image, lut) + +## +# Add border to the image +# +# @param image The image to expand. +# @param border Border width, in pixels. +# @param fill Pixel fill value (a colour value). Default is 0 (black). +# @return An image. + +def expand(image, border=0, fill=0): + "Add border to image" + left, top, right, bottom = _border(border) + width = left + image.size[0] + right + height = top + image.size[1] + bottom + out = Image.new(image.mode, (width, height), _color(fill, image.mode)) + out.paste(image, (left, top)) + return out + +## +# Returns a sized and cropped version of the image, cropped to the +# requested aspect ratio and size. +#

+# The fit function was contributed by Kevin Cazabon. +# +# @param size The requested output size in pixels, given as a +# (width, height) tuple. +# @param method What resampling method to use. Default is Image.NEAREST. +# @param bleed Remove a border around the outside of the image (from all +# four edges. The value is a decimal percentage (use 0.01 for one +# percent). The default value is 0 (no border). +# @param centering Control the cropping position. Use (0.5, 0.5) for +# center cropping (e.g. if cropping the width, take 50% off of the +# left side, and therefore 50% off the right side). (0.0, 0.0) +# will crop from the top left corner (i.e. if cropping the width, +# take all of the crop off of the right side, and if cropping the +# height, take all of it off the bottom). (1.0, 0.0) will crop +# from the bottom left corner, etc. (i.e. if cropping the width, +# take all of the crop off the left side, and if cropping the height +# take none from the top, and therefore all off the bottom). +# @return An image. + +def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)): + """ + This method returns a sized and cropped version of the image, + cropped to the aspect ratio and size that you request. + """ + + # by Kevin Cazabon, Feb 17/2000 + # kevin@cazabon.com + # http://www.cazabon.com + + # ensure inputs are valid + if type(centering) != type([]): + centering = [centering[0], centering[1]] + + if centering[0] > 1.0 or centering[0] < 0.0: + centering [0] = 0.50 + if centering[1] > 1.0 or centering[1] < 0.0: + centering[1] = 0.50 + + if bleed > 0.49999 or bleed < 0.0: + bleed = 0.0 + + # calculate the area to use for resizing and cropping, subtracting + # the 'bleed' around the edges + + # number of pixels to trim off on Top and Bottom, Left and Right + bleedPixels = ( + int((float(bleed) * float(image.size[0])) + 0.5), + int((float(bleed) * float(image.size[1])) + 0.5) + ) + + liveArea = ( + bleedPixels[0], bleedPixels[1], image.size[0] - bleedPixels[0] - 1, + image.size[1] - bleedPixels[1] - 1 + ) + + liveSize = (liveArea[2] - liveArea[0], liveArea[3] - liveArea[1]) + + # calculate the aspect ratio of the liveArea + liveAreaAspectRatio = float(liveSize[0])/float(liveSize[1]) + + # calculate the aspect ratio of the output image + aspectRatio = float(size[0]) / float(size[1]) + + # figure out if the sides or top/bottom will be cropped off + if liveAreaAspectRatio >= aspectRatio: + # liveArea is wider than what's needed, crop the sides + cropWidth = int((aspectRatio * float(liveSize[1])) + 0.5) + cropHeight = liveSize[1] + else: + # liveArea is taller than what's needed, crop the top and bottom + cropWidth = liveSize[0] + cropHeight = int((float(liveSize[0])/aspectRatio) + 0.5) + + # make the crop + leftSide = int(liveArea[0] + (float(liveSize[0]-cropWidth) * centering[0])) + if leftSide < 0: + leftSide = 0 + topSide = int(liveArea[1] + (float(liveSize[1]-cropHeight) * centering[1])) + if topSide < 0: + topSide = 0 + + out = image.crop( + (leftSide, topSide, leftSide + cropWidth, topSide + cropHeight) + ) + + # resize the image and return it + return out.resize(size, method) + +## +# Flip the image vertically (top to bottom). +# +# @param image The image to flip. +# @return An image. + +def flip(image): + "Flip image vertically" + return image.transpose(Image.FLIP_TOP_BOTTOM) + +## +# Convert the image to grayscale. +# +# @param image The image to convert. +# @return An image. + +def grayscale(image): + "Convert to grayscale" + return image.convert("L") + +## +# Invert (negate) the image. +# +# @param image The image to invert. +# @return An image. + +def invert(image): + "Invert image (negate)" + lut = [] + for i in range(256): + lut.append(255-i) + return _lut(image, lut) + +## +# Flip image horizontally (left to right). +# +# @param image The image to mirror. +# @return An image. + +def mirror(image): + "Flip image horizontally" + return image.transpose(Image.FLIP_LEFT_RIGHT) + +## +# Reduce the number of bits for each colour channel. +# +# @param image The image to posterize. +# @param bits The number of bits to keep for each channel (1-8). +# @return An image. + +def posterize(image, bits): + "Reduce the number of bits per color channel" + lut = [] + mask = ~(2**(8-bits)-1) + for i in range(256): + lut.append(i & mask) + return _lut(image, lut) + +## +# Invert all pixel values above a threshold. +# +# @param image The image to posterize. +# @param threshold All pixels above this greyscale level are inverted. +# @return An image. + +def solarize(image, threshold=128): + "Invert all values above threshold" + lut = [] + for i in range(256): + if i < threshold: + lut.append(i) + else: + lut.append(255-i) + return _lut(image, lut) + +# -------------------------------------------------------------------- +# PIL USM components, from Kevin Cazabon. + +def gaussian_blur(im, radius=None): + """ PIL_usm.gblur(im, [radius])""" + + if radius is None: + radius = 5.0 + + im.load() + + return im.im.gaussian_blur(radius) + +gblur = gaussian_blur + +def unsharp_mask(im, radius=None, percent=None, threshold=None): + """ PIL_usm.usm(im, [radius, percent, threshold])""" + + if radius is None: + radius = 5.0 + if percent is None: + percent = 150 + if threshold is None: + threshold = 3 + + im.load() + + return im.im.unsharp_mask(radius, percent, threshold) + +usm = unsharp_mask diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py new file mode 100755 index 00000000000..6efee299891 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py @@ -0,0 +1,184 @@ +# +# The Python Imaging Library. +# $Id$ +# +# image palette object +# +# History: +# 1996-03-11 fl Rewritten. +# 1997-01-03 fl Up and running. +# 1997-08-23 fl Added load hack +# 2001-04-16 fl Fixed randint shadow bug in random() +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import array +import Image, ImageColor + +## +# Colour palette wrapper for palette mapped images. + +class ImagePalette: + "Colour palette for palette mapped images" + + def __init__(self, mode = "RGB", palette = None): + self.mode = mode + self.rawmode = None # if set, palette contains raw data + self.palette = palette or range(256)*len(self.mode) + self.colors = {} + self.dirty = None + if len(self.mode)*256 != len(self.palette): + raise ValueError, "wrong palette size" + + def getdata(self): + # experimental: get palette contents in format suitable + # for the low-level im.putpalette primitive + if self.rawmode: + return self.rawmode, self.palette + return self.mode + ";L", self.tostring() + + def tostring(self): + # experimental: convert palette to string + if self.rawmode: + raise ValueError("palette contains raw palette data") + if Image.isStringType(self.palette): + return self.palette + return array.array("B", self.palette).tostring() + + def getcolor(self, color): + # experimental: given an rgb tuple, allocate palette entry + if self.rawmode: + raise ValueError("palette contains raw palette data") + if Image.isTupleType(color): + try: + return self.colors[color] + except KeyError: + # allocate new color slot + if Image.isStringType(self.palette): + self.palette = map(int, self.palette) + index = len(self.colors) + if index >= 256: + raise ValueError("cannot allocate more than 256 colors") + self.colors[color] = index + self.palette[index] = color[0] + self.palette[index+256] = color[1] + self.palette[index+512] = color[2] + self.dirty = 1 + return index + else: + raise ValueError("unknown color specifier: %r" % color) + + def save(self, fp): + # (experimental) save palette to text file + if self.rawmode: + raise ValueError("palette contains raw palette data") + if type(fp) == type(""): + fp = open(fp, "w") + fp.write("# Palette\n") + fp.write("# Mode: %s\n" % self.mode) + for i in range(256): + fp.write("%d" % i) + for j in range(i, len(self.palette), 256): + fp.write(" %d" % self.palette[j]) + fp.write("\n") + fp.close() + +# -------------------------------------------------------------------- +# Internal + +def raw(rawmode, data): + palette = ImagePalette() + palette.rawmode = rawmode + palette.palette = data + palette.dirty = 1 + return palette + +# -------------------------------------------------------------------- +# Factories + +def _make_linear_lut(black, white): + lut = [] + if black == 0: + for i in range(256): + lut.append(white*i/255) + else: + raise NotImplementedError # FIXME + return lut + +def _make_gamma_lut(exp, mode="RGB"): + lut = [] + for i in range(256): + lut.append(int(((i / 255.0) ** exp) * 255.0 + 0.5)) + return lut + +def new(mode, data): + return Image.core.new_palette(mode, data) + +def negative(mode="RGB"): + palette = range(256) + palette.reverse() + return ImagePalette(mode, palette * len(mode)) + +def random(mode="RGB"): + from random import randint + palette = [] + for i in range(256*len(mode)): + palette.append(randint(0, 255)) + return ImagePalette(mode, palette) + +def sepia(white="#fff0c0"): + r, g, b = ImageColor.getrgb(white) + r = _make_linear_lut(0, r) + g = _make_linear_lut(0, g) + b = _make_linear_lut(0, b) + return ImagePalette("RGB", r + g + b) + +def wedge(mode="RGB"): + return ImagePalette(mode, range(256) * len(mode)) + +def load(filename): + + # FIXME: supports GIMP gradients only + + fp = open(filename, "rb") + + lut = None + + if not lut: + try: + import GimpPaletteFile + fp.seek(0) + p = GimpPaletteFile.GimpPaletteFile(fp) + lut = p.getpalette() + except (SyntaxError, ValueError): + pass + + if not lut: + try: + import GimpGradientFile + fp.seek(0) + p = GimpGradientFile.GimpGradientFile(fp) + lut = p.getpalette() + except (SyntaxError, ValueError): + pass + + if not lut: + try: + import PaletteFile + fp.seek(0) + p = PaletteFile.PaletteFile(fp) + lut = p.getpalette() + except (SyntaxError, ValueError): + pass + + if not lut: + raise IOError, "cannot load palette" + + return lut # data, rawmode + + +# add some psuedocolour palettes as well diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py new file mode 100755 index 00000000000..721fd944998 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py @@ -0,0 +1,71 @@ +# +# The Python Imaging Library +# $Id$ +# +# path interface +# +# History: +# 1996-11-04 fl Created +# 2002-04-14 fl Added documentation stub class +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +import Image + +## +# Path wrapper. + +class Path: + + ## + # Creates a path object. + # + # @param xy Sequence. The sequence can contain 2-tuples [(x, y), ...] + # or a flat list of numbers [x, y, ...]. + + def __init__(self, xy): + pass + + ## + # Compacts the path, by removing points that are close to each + # other. This method modifies the path in place. + + def compact(self, distance=2): + pass + + ## + # Gets the bounding box. + + def getbbox(self): + pass + + ## + # Maps the path through a function. + + def map(self, function): + pass + + ## + # Converts the path to Python list. + # + # @param flat By default, this function returns a list of 2-tuples + # [(x, y), ...]. If this argument is true, it returns a flat + # list [x, y, ...] instead. + # @return A list of coordinates. + + def tolist(self, flat=0): + pass + + ## + # Transforms the path. + + def transform(self, matrix): + pass + + +# override with C implementation +Path = Image.core.path diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py new file mode 100755 index 00000000000..50ee07d6c12 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py @@ -0,0 +1,84 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a simple Qt image interface. +# +# history: +# 2006-06-03 fl: created +# 2006-06-04 fl: inherit from QImage instead of wrapping it +# 2006-06-05 fl: removed toimage helper; move string support to ImageQt +# +# Copyright (c) 2006 by Secret Labs AB +# Copyright (c) 2006 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image + +from PyQt4.QtGui import QImage, qRgb + +## +# (Internal) Turns an RGB color into a Qt compatible color integer. + +def rgb(r, g, b): + # use qRgb to pack the colors, and then turn the resulting long + # into a negative integer with the same bitpattern. + return (qRgb(r, g, b) & 0xffffff) - 0x1000000 + +## +# An PIL image wrapper for Qt. This is a subclass of PyQt4's QImage +# class. +# +# @param im A PIL Image object, or a file name (given either as Python +# string or a PyQt string object). + +class ImageQt(QImage): + + def __init__(self, im): + + data = None + colortable = None + + # handle filename, if given instead of image name + if hasattr(im, "toUtf8"): + # FIXME - is this really the best way to do this? + im = unicode(im.toUtf8(), "utf-8") + if Image.isStringType(im): + im = Image.open(im) + + if im.mode == "1": + format = QImage.Format_Mono + elif im.mode == "L": + format = QImage.Format_Indexed8 + colortable = [] + for i in range(256): + colortable.append(rgb(i, i, i)) + elif im.mode == "P": + format = QImage.Format_Indexed8 + colortable = [] + palette = im.getpalette() + for i in range(0, len(palette), 3): + colortable.append(rgb(*palette[i:i+3])) + elif im.mode == "RGB": + data = im.tostring("raw", "BGRX") + format = QImage.Format_RGB32 + elif im.mode == "RGBA": + try: + data = im.tostring("raw", "BGRA") + except SystemError: + # workaround for earlier versions + r, g, b, a = im.split() + im = Image.merge("RGBA", (b, g, r, a)) + format = QImage.Format_ARGB32 + else: + raise ValueError("unsupported image mode %r" % im.mode) + + # must keep a reference, or Qt will crash! + self.__data = data or im.tostring() + + QImage.__init__(self, self.__data, im.size[0], im.size[1], format) + + if colortable: + self.setColorTable(colortable) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py new file mode 100755 index 00000000000..e94ca0b1ebc --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py @@ -0,0 +1,38 @@ +# +# The Python Imaging Library. +# $Id$ +# +# sequence support classes +# +# history: +# 1997-02-20 fl Created +# +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1997 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +## +# This class implements an iterator object that can be used to loop +# over an image sequence. + +class Iterator: + + ## + # Create an iterator. + # + # @param im An image object. + + def __init__(self, im): + if not hasattr(im, "seek"): + raise AttributeError("im must have seek method") + self.im = im + + def __getitem__(self, ix): + try: + if ix: + self.im.seek(ix) + return self.im + except EOFError: + raise IndexError # end of sequence diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py new file mode 100755 index 00000000000..05270f440f2 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py @@ -0,0 +1,163 @@ +# +# The Python Imaging Library. +# $Id$ +# +# im.show() drivers +# +# History: +# 2008-04-06 fl Created +# +# Copyright (c) Secret Labs AB 2008. +# +# See the README file for information on usage and redistribution. +# + +import Image +import os, sys + +_viewers = [] + +def register(viewer, order=1): + try: + if issubclass(viewer, Viewer): + viewer = viewer() + except TypeError: + pass # raised if viewer wasn't a class + if order > 0: + _viewers.append(viewer) + elif order < 0: + _viewers.insert(0, viewer) + +## +# Displays a given image. +# +# @param image An image object. +# @param title Optional title. Not all viewers can display the title. +# @param **options Additional viewer options. +# @return True if a suitable viewer was found, false otherwise. + +def show(image, title=None, **options): + for viewer in _viewers: + if viewer.show(image, title=title, **options): + return 1 + return 0 + +## +# Base class for viewers. + +class Viewer: + + # main api + + def show(self, image, **options): + + # save temporary image to disk + if image.mode[:4] == "I;16": + # @PIL88 @PIL101 + # "I;16" isn't an 'official' mode, but we still want to + # provide a simple way to show 16-bit images. + base = "L" + # FIXME: auto-contrast if max() > 255? + else: + base = Image.getmodebase(image.mode) + if base != image.mode and image.mode != "1": + image = image.convert(base) + + self.show_image(image, **options) + + # hook methods + + format = None + + def get_format(self, image): + # return format name, or None to save as PGM/PPM + return self.format + + def get_command(self, file, **options): + raise NotImplementedError + + def save_image(self, image): + # save to temporary file, and return filename + return image._dump(format=self.get_format(image)) + + def show_image(self, image, **options): + # display given image + return self.show_file(self.save_image(image), **options) + + def show_file(self, file, **options): + # display given file + os.system(self.get_command(file, **options)) + return 1 + +# -------------------------------------------------------------------- + +if sys.platform == "win32": + + class WindowsViewer(Viewer): + format = "BMP" + def get_command(self, file, **options): + return "start /wait %s && del /f %s" % (file, file) + + register(WindowsViewer) + +elif sys.platform == "darwin": + + class MacViewer(Viewer): + format = "BMP" + def get_command(self, file, **options): + # on darwin open returns immediately resulting in the temp + # file removal while app is opening + command = "open -a /Applications/Preview.app" + command = "(%s %s; sleep 20; rm -f %s)&" % (command, file, file) + return command + + register(MacViewer) + +else: + + # unixoids + + def which(executable): + path = os.environ.get("PATH") + if not path: + return None + for dirname in path.split(os.pathsep): + filename = os.path.join(dirname, executable) + if os.path.isfile(filename): + # FIXME: make sure it's executable + return filename + return None + + class UnixViewer(Viewer): + def show_file(self, file, **options): + command, executable = self.get_command_ex(file, **options) + command = "(%s %s; rm -f %s)&" % (command, file, file) + os.system(command) + return 1 + + # implementations + + class DisplayViewer(UnixViewer): + def get_command_ex(self, file, **options): + command = executable = "display" + return command, executable + + if which("display"): + register(DisplayViewer) + + class XVViewer(UnixViewer): + def get_command_ex(self, file, title=None, **options): + # note: xv is pretty outdated. most modern systems have + # imagemagick's display command instead. + command = executable = "xv" + if title: + # FIXME: do full escaping + command = command + " -name \"%s\"" % title + return command, executable + + if which("xv"): + register(XVViewer) + +if __name__ == "__main__": + # usage: python ImageShow.py imagefile [title] + print show(Image.open(sys.argv[1]), *sys.argv[2:]) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py new file mode 100755 index 00000000000..9ebdab03018 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py @@ -0,0 +1,164 @@ +# +# The Python Imaging Library. +# $Id$ +# +# global image statistics +# +# History: +# 1996-04-05 fl Created +# 1997-05-21 fl Added mask; added rms, var, stddev attributes +# 1997-08-05 fl Added median +# 1998-07-05 hk Fixed integer overflow error +# +# Notes: +# This class shows how to implement delayed evaluation of attributes. +# To get a certain value, simply access the corresponding attribute. +# The __getattr__ dispatcher takes care of the rest. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996-97. +# +# See the README file for information on usage and redistribution. +# + +import Image +import operator, math + +## +# The ImageStat module calculates global statistics for an +# image, or a region of an image. +## + +## +# Calculate statistics for the given image. If a mask is included, +# only the regions covered by that mask are included in the +# statistics. + +class Stat: + "Get image or feature statistics" + + ## + # Create a statistics object. + # + # @def __init__(image, mask=None) + # @param image A PIL image, or a precalculate histogram. + # @param mask An optional mask. + + def __init__(self, image_or_list, mask = None): + try: + if mask: + self.h = image_or_list.histogram(mask) + else: + self.h = image_or_list.histogram() + except AttributeError: + self.h = image_or_list # assume it to be a histogram list + if type(self.h) != type([]): + raise TypeError, "first argument must be image or list" + self.bands = range(len(self.h) / 256) + + def __getattr__(self, id): + "Calculate missing attribute" + if id[:4] == "_get": + raise AttributeError, id + # calculate missing attribute + v = getattr(self, "_get" + id)() + setattr(self, id, v) + return v + + def _getextrema(self): + "Get min/max values for each band in the image" + + def minmax(histogram): + n = 255 + x = 0 + for i in range(256): + if histogram[i]: + n = min(n, i) + x = max(x, i) + return n, x # returns (255, 0) if there's no data in the histogram + + v = [] + for i in range(0, len(self.h), 256): + v.append(minmax(self.h[i:])) + return v + + def _getcount(self): + "Get total number of pixels in each layer" + + v = [] + for i in range(0, len(self.h), 256): + v.append(reduce(operator.add, self.h[i:i+256])) + return v + + def _getsum(self): + "Get sum of all pixels in each layer" + + v = [] + for i in range(0, len(self.h), 256): + sum = 0.0 + for j in range(256): + sum = sum + j * self.h[i+j] + v.append(sum) + return v + + def _getsum2(self): + "Get squared sum of all pixels in each layer" + + v = [] + for i in range(0, len(self.h), 256): + sum2 = 0.0 + for j in range(256): + sum2 = sum2 + (j ** 2) * float(self.h[i+j]) + v.append(sum2) + return v + + def _getmean(self): + "Get average pixel level for each layer" + + v = [] + for i in self.bands: + v.append(self.sum[i] / self.count[i]) + return v + + def _getmedian(self): + "Get median pixel level for each layer" + + v = [] + for i in self.bands: + s = 0 + l = self.count[i]/2 + b = i * 256 + for j in range(256): + s = s + self.h[b+j] + if s > l: + break + v.append(j) + return v + + def _getrms(self): + "Get RMS for each layer" + + v = [] + for i in self.bands: + v.append(math.sqrt(self.sum2[i] / self.count[i])) + return v + + + def _getvar(self): + "Get variance for each layer" + + v = [] + for i in self.bands: + n = self.count[i] + v.append((self.sum2[i]-(self.sum[i]**2.0)/n)/n) + return v + + def _getstddev(self): + "Get standard deviation for each layer" + + v = [] + for i in self.bands: + v.append(math.sqrt(self.var[i])) + return v + +Global = Stat # compatibility diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py new file mode 100755 index 00000000000..8618139a538 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py @@ -0,0 +1,296 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a Tk display interface +# +# History: +# 96-04-08 fl Created +# 96-09-06 fl Added getimage method +# 96-11-01 fl Rewritten, removed image attribute and crop method +# 97-05-09 fl Use PyImagingPaste method instead of image type +# 97-05-12 fl Minor tweaks to match the IFUNC95 interface +# 97-05-17 fl Support the "pilbitmap" booster patch +# 97-06-05 fl Added file= and data= argument to image constructors +# 98-03-09 fl Added width and height methods to Image classes +# 98-07-02 fl Use default mode for "P" images without palette attribute +# 98-07-02 fl Explicitly destroy Tkinter image objects +# 99-07-24 fl Support multiple Tk interpreters (from Greg Couch) +# 99-07-26 fl Automatically hook into Tkinter (if possible) +# 99-08-15 fl Hook uses _imagingtk instead of _imaging +# +# Copyright (c) 1997-1999 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Tkinter, Image + +## +# The ImageTk module contains support to create and modify +# Tkinter BitmapImage and PhotoImage objects. +#

+# For examples, see the demo programs in the Scripts +# directory. +## + +# -------------------------------------------------------------------- +# Check for Tkinter interface hooks + +_pilbitmap_ok = None + +def _pilbitmap_check(): + global _pilbitmap_ok + if _pilbitmap_ok is None: + try: + im = Image.new("1", (1,1)) + Tkinter.BitmapImage(data="PIL:%d" % im.im.id) + _pilbitmap_ok = 1 + except Tkinter.TclError: + _pilbitmap_ok = 0 + return _pilbitmap_ok + +# -------------------------------------------------------------------- +# PhotoImage + +## +# Creates a Tkinter-compatible photo image. This can be used +# everywhere Tkinter expects an image object. If the image is an RGBA +# image, pixels having alpha 0 are treated as transparent. + +class PhotoImage: + + ## + # Create a photo image object. The constructor takes either + # a PIL image, or a mode and a size. Alternatively, you can + # use the file or data options to initialize + # the photo image object. + #

+ # @def __init__(image=None, size=None, **options) + # @param image Either a PIL image, or a mode string. If a + # mode string is used, a size must also be given. + # @param size If the first argument is a mode string, this + # defines the size of the image. + # @keyparam file A filename to load the image from (using + # Image.open(file)). + # @keyparam data An 8-bit string containing image data (as + # loaded from an image file). + + def __init__(self, image=None, size=None, **kw): + + # Tk compatibility: file or data + if image is None: + if kw.has_key("file"): + image = Image.open(kw["file"]) + del kw["file"] + elif kw.has_key("data"): + from StringIO import StringIO + image = Image.open(StringIO(kw["data"])) + del kw["data"] + + if hasattr(image, "mode") and hasattr(image, "size"): + # got an image instead of a mode + mode = image.mode + if mode == "P": + # palette mapped data + image.load() + try: + mode = image.palette.mode + except AttributeError: + mode = "RGB" # default + size = image.size + kw["width"], kw["height"] = size + else: + mode = image + image = None + + if mode not in ["1", "L", "RGB", "RGBA"]: + mode = Image.getmodebase(mode) + + self.__mode = mode + self.__size = size + self.__photo = apply(Tkinter.PhotoImage, (), kw) + self.tk = self.__photo.tk + if image: + self.paste(image) + + def __del__(self): + name = self.__photo.name + self.__photo.name = None + try: + self.__photo.tk.call("image", "delete", name) + except: + pass # ignore internal errors + + ## + # Get the Tkinter photo image identifier. This method is + # automatically called by Tkinter whenever a PhotoImage object is + # passed to a Tkinter method. + # + # @return A Tkinter photo image identifier (a string). + + def __str__(self): + return str(self.__photo) + + ## + # Get the width of the image. + # + # @return The width, in pixels. + + def width(self): + return self.__size[0] + + ## + # Get the height of the image. + # + # @return The height, in pixels. + + def height(self): + return self.__size[1] + + ## + # Paste a PIL image into the photo image. Note that this can + # be very slow if the photo image is displayed. + # + # @param im A PIL image. The size must match the target region. + # If the mode does not match, the image is converted to the + # mode of the bitmap image. + # @param box A 4-tuple defining the left, upper, right, and + # lower pixel coordinate. If None is given instead of a + # tuple, all of the image is assumed. + + def paste(self, im, box=None): + + # convert to blittable + im.load() + image = im.im + if image.isblock() and im.mode == self.__mode: + block = image + else: + block = image.new_block(self.__mode, im.size) + image.convert2(block, image) # convert directly between buffers + + tk = self.__photo.tk + + try: + tk.call("PyImagingPhoto", self.__photo, block.id) + except Tkinter.TclError, v: + # activate Tkinter hook + try: + import _imagingtk + try: + _imagingtk.tkinit(tk.interpaddr(), 1) + except AttributeError: + _imagingtk.tkinit(id(tk), 0) + tk.call("PyImagingPhoto", self.__photo, block.id) + except (ImportError, AttributeError, Tkinter.TclError): + raise # configuration problem; cannot attach to Tkinter + +# -------------------------------------------------------------------- +# BitmapImage + +## +# Create a Tkinter-compatible bitmap image. This can be used +# everywhere Tkinter expects an image object. + +class BitmapImage: + + ## + # Create a Tkinter-compatible bitmap image. + #

+ # The given image must have mode "1". Pixels having value 0 are + # treated as transparent. Options, if any, are passed on to + # Tkinter. The most commonly used option is foreground, + # which is used to specify the colour for the non-transparent + # parts. See the Tkinter documentation for information on how to + # specify colours. + # + # @def __init__(image=None, **options) + # @param image A PIL image. + + def __init__(self, image=None, **kw): + + # Tk compatibility: file or data + if image is None: + if kw.has_key("file"): + image = Image.open(kw["file"]) + del kw["file"] + elif kw.has_key("data"): + from StringIO import StringIO + image = Image.open(StringIO(kw["data"])) + del kw["data"] + + self.__mode = image.mode + self.__size = image.size + + if _pilbitmap_check(): + # fast way (requires the pilbitmap booster patch) + image.load() + kw["data"] = "PIL:%d" % image.im.id + self.__im = image # must keep a reference + else: + # slow but safe way + kw["data"] = image.tobitmap() + self.__photo = apply(Tkinter.BitmapImage, (), kw) + + def __del__(self): + name = self.__photo.name + self.__photo.name = None + try: + self.__photo.tk.call("image", "delete", name) + except: + pass # ignore internal errors + + ## + # Get the width of the image. + # + # @return The width, in pixels. + + def width(self): + return self.__size[0] + + ## + # Get the height of the image. + # + # @return The height, in pixels. + + def height(self): + return self.__size[1] + + ## + # Get the Tkinter bitmap image identifier. This method is + # automatically called by Tkinter whenever a BitmapImage object + # is passed to a Tkinter method. + # + # @return A Tkinter bitmap image identifier (a string). + + def __str__(self): + return str(self.__photo) + +## +# Copies the contents of a PhotoImage to a PIL image memory. + +def getimage(photo): + photo.tk.call("PyImagingPhotoGet", photo) + +# -------------------------------------------------------------------- +# Helper for the Image.show method. + +def _show(image, title): + + class UI(Tkinter.Label): + def __init__(self, master, im): + if im.mode == "1": + self.image = BitmapImage(im, foreground="white", master=master) + else: + self.image = PhotoImage(im, master=master) + Tkinter.Label.__init__(self, master, image=self.image, + bg="black", bd=0) + + if not Tkinter._default_root: + raise IOError, "tkinter not initialized" + top = Tkinter.Toplevel() + if title: + top.title(title) + UI(top, image).pack() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py new file mode 100755 index 00000000000..cc323d3b990 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py @@ -0,0 +1,95 @@ +# +# The Python Imaging Library. +# $Id$ +# +# transform wrappers +# +# History: +# 2002-04-08 fl Created +# +# Copyright (c) 2002 by Secret Labs AB +# Copyright (c) 2002 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +import Image + +class Transform(Image.ImageTransformHandler): + def __init__(self, data): + self.data = data + def getdata(self): + return self.method, self.data + def transform(self, size, image, **options): + # can be overridden + method, data = self.getdata() + return image.transform(size, method, data, **options) + +## +# Define an affine image transform. +#

+# This function takes a 6-tuple (a, b, c, d, e, f) which +# contain the first two rows from an affine transform matrix. For +# each pixel (x, y) in the output image, the new value is +# taken from a position (a x + b y + c, +# d x + e y + f) in the input image, rounded to +# nearest pixel. +#

+# This function can be used to scale, translate, rotate, and shear the +# original image. +# +# @def AffineTransform(matrix) +# @param matrix A 6-tuple (a, b, c, d, e, f) containing +# the first two rows from an affine transform matrix. +# @see Image#Image.transform + +class AffineTransform(Transform): + method = Image.AFFINE + +## +# Define a transform to extract a subregion from an image. +#

+# Maps a rectangle (defined by two corners) from the image to a +# rectangle of the given size. The resulting image will contain +# data sampled from between the corners, such that (x0, y0) +# in the input image will end up at (0,0) in the output image, +# and (x1, y1) at size. +#

+# This method can be used to crop, stretch, shrink, or mirror an +# arbitrary rectangle in the current image. It is slightly slower than +# crop, but about as fast as a corresponding resize +# operation. +# +# @def ExtentTransform(bbox) +# @param bbox A 4-tuple (x0, y0, x1, y1) which specifies +# two points in the input image's coordinate system. +# @see Image#Image.transform + +class ExtentTransform(Transform): + method = Image.EXTENT + +## +# Define an quad image transform. +#

+# Maps a quadrilateral (a region defined by four corners) from the +# image to a rectangle of the given size. +# +# @def QuadTransform(xy) +# @param xy An 8-tuple (x0, y0, x1, y1, x2, y2, y3, y3) which +# contain the upper left, lower left, lower right, and upper right +# corner of the source quadrilateral. +# @see Image#Image.transform + +class QuadTransform(Transform): + method = Image.QUAD + +## +# Define an mesh image transform. A mesh transform consists of one +# or more individual quad transforms. +# +# @def MeshTransform(data) +# @param data A list of (bbox, quad) tuples. +# @see Image#Image.transform + +class MeshTransform(Transform): + method = Image.MESH diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py new file mode 100755 index 00000000000..f98725f74ac --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py @@ -0,0 +1,215 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a Windows DIB display interface +# +# History: +# 1996-05-20 fl Created +# 1996-09-20 fl Fixed subregion exposure +# 1997-09-21 fl Added draw primitive (for tzPrint) +# 2003-05-21 fl Added experimental Window/ImageWindow classes +# 2003-09-05 fl Added fromstring/tostring methods +# +# Copyright (c) Secret Labs AB 1997-2003. +# Copyright (c) Fredrik Lundh 1996-2003. +# +# See the README file for information on usage and redistribution. +# + +import Image + +## +# The ImageWin module contains support to create and display +# images under Windows 95/98, NT, 2000 and later. + +class HDC: + def __init__(self, dc): + self.dc = dc + def __int__(self): + return self.dc + +class HWND: + def __init__(self, wnd): + self.wnd = wnd + def __int__(self): + return self.wnd + +## +# Create a Windows bitmap with the given mode and size. The mode can +# be one of "1", "L", "P", or "RGB". +# +# If the display requires a palette, this constructor creates a +# suitable palette and associates it with the image. For an "L" image, +# 128 greylevels are allocated. For an "RGB" image, a 6x6x6 colour +# cube is used, together with 20 greylevels. +# +# To make sure that palettes work properly under Windows, you must +# call the palette method upon certain events from Windows. + +class Dib: + + ## + # Create Windows bitmap. + # + # @param image Either a PIL image, or a mode string. If a + # mode string is used, a size must also be given. The + # mode can be one of "1", "L", "P", or "RGB". + # @param size If the first argument is a mode string, this + # defines the size of the image. + + def __init__(self, image, size=None): + if hasattr(image, "mode") and hasattr(image, "size"): + mode = image.mode + size = image.size + else: + mode = image + image = None + if mode not in ["1", "L", "P", "RGB"]: + mode = Image.getmodebase(mode) + self.image = Image.core.display(mode, size) + self.mode = mode + self.size = size + if image: + self.paste(image) + + ## + # Copy the bitmap contents to a device context. + # + # @param handle Device context (HDC), cast to a Python integer, + # or a HDC or HWND instance. In PythonWin, you can use the + # GetHandleAttrib method of the CDC class to get + # a suitable handle. + + def expose(self, handle): + if isinstance(handle, HWND): + dc = self.image.getdc(handle) + try: + result = self.image.expose(dc) + finally: + self.image.releasedc(handle, dc) + else: + result = self.image.expose(handle) + return result + + def draw(self, handle, dst, src=None): + if not src: + src = (0,0) + self.size + if isinstance(handle, HWND): + dc = self.image.getdc(handle) + try: + result = self.image.draw(dc, dst, src) + finally: + self.image.releasedc(handle, dc) + else: + result = self.image.draw(handle, dst, src) + return result + + ## + # Installs the palette associated with the image in the + # given device context. + #

+ # This method should be called upon QUERYNEWPALETTE + # and PALETTECHANGED events from Windows. If this + # method returns a non-zero value, one or more display + # palette entries were changed, and the image should be + # redrawn. + # + # @param handle Device context (HDC), cast to a Python integer, + # or an HDC or HWND instance. + # @return A true value if one or more entries were changed + # (this indicates that the image should be redrawn). + + def query_palette(self, handle): + if isinstance(handle, HWND): + handle = self.image.getdc(handle) + try: + result = self.image.query_palette(handle) + finally: + self.image.releasedc(handle, handle) + else: + result = self.image.query_palette(handle) + return result + + ## + # Paste a PIL image into the bitmap image. + # + # @param im A PIL image. The size must match the target region. + # If the mode does not match, the image is converted to the + # mode of the bitmap image. + # @param box A 4-tuple defining the left, upper, right, and + # lower pixel coordinate. If None is given instead of a + # tuple, all of the image is assumed. + + def paste(self, im, box=None): + im.load() + if self.mode != im.mode: + im = im.convert(self.mode) + if box: + self.image.paste(im.im, box) + else: + self.image.paste(im.im) + + ## + # Load display memory contents from string buffer. + # + # @param buffer A string buffer containing display data (usually + # data returned from tostring) + + def fromstring(self, buffer): + return self.image.fromstring(buffer) + + ## + # Copy display memory contents to string buffer. + # + # @return A string buffer containing display data. + + def tostring(self): + return self.image.tostring() + + +## +# Create a Window with the given title size. + +class Window: + + def __init__(self, title="PIL", width=None, height=None): + self.hwnd = Image.core.createwindow( + title, self.__dispatcher, width or 0, height or 0 + ) + + def __dispatcher(self, action, *args): + return apply(getattr(self, "ui_handle_" + action), args) + + def ui_handle_clear(self, dc, x0, y0, x1, y1): + pass + + def ui_handle_damage(self, x0, y0, x1, y1): + pass + + def ui_handle_destroy(self): + pass + + def ui_handle_repair(self, dc, x0, y0, x1, y1): + pass + + def ui_handle_resize(self, width, height): + pass + + def mainloop(self): + Image.core.eventloop() + +## +# Create an image window which displays the given image. + +class ImageWindow(Window): + + def __init__(self, image, title="PIL"): + if not isinstance(image, Dib): + image = Dib(image) + self.image = image + width, height = image.size + Window.__init__(self, title, width=width, height=height) + + def ui_handle_repair(self, dc, x0, y0, x1, y1): + self.image.draw(dc, (x0, y0, x1, y1)) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py new file mode 100755 index 00000000000..bf5611b8a63 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py @@ -0,0 +1,93 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IM Tools support for PIL +# +# history: +# 1996-05-27 fl Created (read 8-bit images only) +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.2) +# +# Copyright (c) Secret Labs AB 1997-2001. +# Copyright (c) Fredrik Lundh 1996-2001. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.2" + +import re + +import Image, ImageFile + +# +# -------------------------------------------------------------------- + +field = re.compile(r"([a-z]*) ([^ \r\n]*)") + +## +# Image plugin for IM Tools images. + +class ImtImageFile(ImageFile.ImageFile): + + format = "IMT" + format_description = "IM Tools" + + def _open(self): + + # Quick rejection: if there's not a LF among the first + # 100 bytes, this is (probably) not a text header. + + if not "\n" in self.fp.read(100): + raise SyntaxError, "not an IM file" + self.fp.seek(0) + + xsize = ysize = 0 + + while 1: + + s = self.fp.read(1) + if not s: + break + + if s == chr(12): + + # image data begins + self.tile = [("raw", (0,0)+self.size, + self.fp.tell(), + (self.mode, 0, 1))] + + break + + else: + + # read key/value pair + # FIXME: dangerous, may read whole file + s = s + self.fp.readline() + if len(s) == 1 or len(s) > 100: + break + if s[0] == "*": + continue # comment + + m = field.match(s) + if not m: + break + k, v = m.group(1,2) + if k == "width": + xsize = int(v) + self.size = xsize, ysize + elif k == "height": + ysize = int(v) + self.size = xsize, ysize + elif k == "pixel" and v == "n8": + self.mode = "L" + + +# +# -------------------------------------------------------------------- + +Image.register_open("IMT", ImtImageFile) + +# +# no extension registered (".im" is simply too common) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py new file mode 100755 index 00000000000..acea5d18b40 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py @@ -0,0 +1,288 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IPTC/NAA file handling +# +# history: +# 1995-10-01 fl Created +# 1998-03-09 fl Cleaned up and added to PIL +# 2002-06-18 fl Added getiptcinfo helper +# +# Copyright (c) Secret Labs AB 1997-2002. +# Copyright (c) Fredrik Lundh 1995. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.3" + + +import Image, ImageFile +import os, tempfile + + +COMPRESSION = { + 1: "raw", + 5: "jpeg" +} + +PAD = chr(0) * 4 + +# +# Helpers + +def i16(c): + return ord(c[1]) + (ord(c[0])<<8) + +def i32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) + +def i(c): + return i32((PAD + c)[-4:]) + +def dump(c): + for i in c: + print "%02x" % ord(i), + print + +## +# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields +# from TIFF and JPEG files, use the getiptcinfo function. + +class IptcImageFile(ImageFile.ImageFile): + + format = "IPTC" + format_description = "IPTC/NAA" + + def getint(self, key): + return i(self.info[key]) + + def field(self): + # + # get a IPTC field header + s = self.fp.read(5) + if not len(s): + return None, 0 + + tag = ord(s[1]), ord(s[2]) + + # syntax + if ord(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9: + raise SyntaxError, "invalid IPTC/NAA file" + + # field size + size = ord(s[3]) + if size > 132: + raise IOError, "illegal field length in IPTC/NAA file" + elif size == 128: + size = 0 + elif size > 128: + size = i(self.fp.read(size-128)) + else: + size = i16(s[3:]) + + return tag, size + + def _is_raw(self, offset, size): + # + # check if the file can be mapped + + # DISABLED: the following only slows things down... + return 0 + + self.fp.seek(offset) + t, sz = self.field() + if sz != size[0]: + return 0 + y = 1 + while 1: + self.fp.seek(sz, 1) + t, s = self.field() + if t != (8, 10): + break + if s != sz: + return 0 + y = y + 1 + return y == size[1] + + def _open(self): + + # load descriptive fields + while 1: + offset = self.fp.tell() + tag, size = self.field() + if not tag or tag == (8,10): + break + if size: + tagdata = self.fp.read(size) + else: + tagdata = None + if tag in self.info.keys(): + if isinstance(self.info[tag], list): + self.info[tag].append(tagdata) + else: + self.info[tag] = [self.info[tag], tagdata] + else: + self.info[tag] = tagdata + + # print tag, self.info[tag] + + # mode + layers = ord(self.info[(3,60)][0]) + component = ord(self.info[(3,60)][1]) + if self.info.has_key((3,65)): + id = ord(self.info[(3,65)][0])-1 + else: + id = 0 + if layers == 1 and not component: + self.mode = "L" + elif layers == 3 and component: + self.mode = "RGB"[id] + elif layers == 4 and component: + self.mode = "CMYK"[id] + + # size + self.size = self.getint((3,20)), self.getint((3,30)) + + # compression + try: + compression = COMPRESSION[self.getint((3,120))] + except KeyError: + raise IOError, "Unknown IPTC image compression" + + # tile + if tag == (8,10): + if compression == "raw" and self._is_raw(offset, self.size): + self.tile = [(compression, (offset, size + 5, -1), + (0, 0, self.size[0], self.size[1]))] + else: + self.tile = [("iptc", (compression, offset), + (0, 0, self.size[0], self.size[1]))] + + def load(self): + + if len(self.tile) != 1 or self.tile[0][0] != "iptc": + return ImageFile.ImageFile.load(self) + + type, tile, box = self.tile[0] + + encoding, offset = tile + + self.fp.seek(offset) + + # Copy image data to temporary file + outfile = tempfile.mktemp() + o = open(outfile, "wb") + if encoding == "raw": + # To simplify access to the extracted file, + # prepend a PPM header + o.write("P5\n%d %d\n255\n" % self.size) + while 1: + type, size = self.field() + if type != (8, 10): + break + while size > 0: + s = self.fp.read(min(size, 8192)) + if not s: + break + o.write(s) + size = size - len(s) + o.close() + + try: + try: + # fast + self.im = Image.core.open_ppm(outfile) + except: + # slightly slower + im = Image.open(outfile) + im.load() + self.im = im.im + finally: + try: os.unlink(outfile) + except: pass + + +Image.register_open("IPTC", IptcImageFile) + +Image.register_extension("IPTC", ".iim") + +## +# Get IPTC information from TIFF, JPEG, or IPTC file. +# +# @param im An image containing IPTC data. +# @return A dictionary containing IPTC information, or None if +# no IPTC information block was found. + +def getiptcinfo(im): + + import TiffImagePlugin, JpegImagePlugin + import StringIO + + data = None + + if isinstance(im, IptcImageFile): + # return info dictionary right away + return im.info + + elif isinstance(im, JpegImagePlugin.JpegImageFile): + # extract the IPTC/NAA resource + try: + app = im.app["APP13"] + if app[:14] == "Photoshop 3.0\x00": + app = app[14:] + # parse the image resource block + offset = 0 + while app[offset:offset+4] == "8BIM": + offset = offset + 4 + # resource code + code = JpegImagePlugin.i16(app, offset) + offset = offset + 2 + # resource name (usually empty) + name_len = ord(app[offset]) + name = app[offset+1:offset+1+name_len] + offset = 1 + offset + name_len + if offset & 1: + offset = offset + 1 + # resource data block + size = JpegImagePlugin.i32(app, offset) + offset = offset + 4 + if code == 0x0404: + # 0x0404 contains IPTC/NAA data + data = app[offset:offset+size] + break + offset = offset + size + if offset & 1: + offset = offset + 1 + except (AttributeError, KeyError): + pass + + elif isinstance(im, TiffImagePlugin.TiffImageFile): + # get raw data from the IPTC/NAA tag (PhotoShop tags the data + # as 4-byte integers, so we cannot use the get method...) + try: + type, data = im.tag.tagdata[TiffImagePlugin.IPTC_NAA_CHUNK] + except (AttributeError, KeyError): + pass + + if data is None: + return None # no properties + + # create an IptcImagePlugin object without initializing it + class FakeImage: + pass + im = FakeImage() + im.__class__ = IptcImageFile + + # parse the IPTC information chunk + im.info = {} + im.fp = StringIO.StringIO(data) + + try: + im._open() + except (IndexError, KeyError): + pass # expected failure + + return im.info diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py new file mode 100755 index 00000000000..933abf3c244 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py @@ -0,0 +1,492 @@ +# +# The Python Imaging Library. +# $Id$ +# +# JPEG (JFIF) file handling +# +# See "Digital Compression and Coding of Continous-Tone Still Images, +# Part 1, Requirements and Guidelines" (CCITT T.81 / ISO 10918-1) +# +# History: +# 1995-09-09 fl Created +# 1995-09-13 fl Added full parser +# 1996-03-25 fl Added hack to use the IJG command line utilities +# 1996-05-05 fl Workaround Photoshop 2.5 CMYK polarity bug +# 1996-05-28 fl Added draft support, JFIF version (0.1) +# 1996-12-30 fl Added encoder options, added progression property (0.2) +# 1997-08-27 fl Save mode 1 images as BW (0.3) +# 1998-07-12 fl Added YCbCr to draft and save methods (0.4) +# 1998-10-19 fl Don't hang on files using 16-bit DQT's (0.4.1) +# 2001-04-16 fl Extract DPI settings from JFIF files (0.4.2) +# 2002-07-01 fl Skip pad bytes before markers; identify Exif files (0.4.3) +# 2003-04-25 fl Added experimental EXIF decoder (0.5) +# 2003-06-06 fl Added experimental EXIF GPSinfo decoder +# 2003-09-13 fl Extract COM markers +# 2009-09-06 fl Added icc_profile support (from Florian Hoech) +# 2009-03-06 fl Changed CMYK handling; always use Adobe polarity (0.6) +# 2009-03-08 fl Added subsampling support (from Justin Huff). +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.6" + +import array, struct +import string +import Image, ImageFile + +def i16(c,o=0): + return ord(c[o+1]) + (ord(c[o])<<8) + +def i32(c,o=0): + return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24) + +# +# Parser + +def Skip(self, marker): + n = i16(self.fp.read(2))-2 + ImageFile._safe_read(self.fp, n) + +def APP(self, marker): + # + # Application marker. Store these in the APP dictionary. + # Also look for well-known application markers. + + n = i16(self.fp.read(2))-2 + s = ImageFile._safe_read(self.fp, n) + + app = "APP%d" % (marker&15) + + self.app[app] = s # compatibility + self.applist.append((app, s)) + + if marker == 0xFFE0 and s[:4] == "JFIF": + # extract JFIF information + self.info["jfif"] = version = i16(s, 5) # version + self.info["jfif_version"] = divmod(version, 256) + # extract JFIF properties + try: + jfif_unit = ord(s[7]) + jfif_density = i16(s, 8), i16(s, 10) + except: + pass + else: + if jfif_unit == 1: + self.info["dpi"] = jfif_density + self.info["jfif_unit"] = jfif_unit + self.info["jfif_density"] = jfif_density + elif marker == 0xFFE1 and s[:5] == "Exif\0": + # extract Exif information (incomplete) + self.info["exif"] = s # FIXME: value will change + elif marker == 0xFFE2 and s[:5] == "FPXR\0": + # extract FlashPix information (incomplete) + self.info["flashpix"] = s # FIXME: value will change + elif marker == 0xFFE2 and s[:12] == "ICC_PROFILE\0": + # Since an ICC profile can be larger than the maximum size of + # a JPEG marker (64K), we need provisions to split it into + # multiple markers. The format defined by the ICC specifies + # one or more APP2 markers containing the following data: + # Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + # Marker sequence number 1, 2, etc (1 byte) + # Number of markers Total of APP2's used (1 byte) + # Profile data (remainder of APP2 data) + # Decoders should use the marker sequence numbers to + # reassemble the profile, rather than assuming that the APP2 + # markers appear in the correct sequence. + self.icclist.append(s) + elif marker == 0xFFEE and s[:5] == "Adobe": + self.info["adobe"] = i16(s, 5) + # extract Adobe custom properties + try: + adobe_transform = ord(s[1]) + except: + pass + else: + self.info["adobe_transform"] = adobe_transform + +def COM(self, marker): + # + # Comment marker. Store these in the APP dictionary. + + n = i16(self.fp.read(2))-2 + s = ImageFile._safe_read(self.fp, n) + + self.app["COM"] = s # compatibility + self.applist.append(("COM", s)) + +def SOF(self, marker): + # + # Start of frame marker. Defines the size and mode of the + # image. JPEG is colour blind, so we use some simple + # heuristics to map the number of layers to an appropriate + # mode. Note that this could be made a bit brighter, by + # looking for JFIF and Adobe APP markers. + + n = i16(self.fp.read(2))-2 + s = ImageFile._safe_read(self.fp, n) + self.size = i16(s[3:]), i16(s[1:]) + + self.bits = ord(s[0]) + if self.bits != 8: + raise SyntaxError("cannot handle %d-bit layers" % self.bits) + + self.layers = ord(s[5]) + if self.layers == 1: + self.mode = "L" + elif self.layers == 3: + self.mode = "RGB" + elif self.layers == 4: + self.mode = "CMYK" + else: + raise SyntaxError("cannot handle %d-layer images" % self.layers) + + if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]: + self.info["progressive"] = self.info["progression"] = 1 + + if self.icclist: + # fixup icc profile + self.icclist.sort() # sort by sequence number + if ord(self.icclist[0][13]) == len(self.icclist): + profile = [] + for p in self.icclist: + profile.append(p[14:]) + icc_profile = string.join(profile, "") + else: + icc_profile = None # wrong number of fragments + self.info["icc_profile"] = icc_profile + self.icclist = None + + for i in range(6, len(s), 3): + t = s[i:i+3] + # 4-tuples: id, vsamp, hsamp, qtable + self.layer.append((t[0], ord(t[1])/16, ord(t[1])&15, ord(t[2]))) + +def DQT(self, marker): + # + # Define quantization table. Support baseline 8-bit tables + # only. Note that there might be more than one table in + # each marker. + + # FIXME: The quantization tables can be used to estimate the + # compression quality. + + n = i16(self.fp.read(2))-2 + s = ImageFile._safe_read(self.fp, n) + while len(s): + if len(s) < 65: + raise SyntaxError("bad quantization table marker") + v = ord(s[0]) + if v/16 == 0: + self.quantization[v&15] = array.array("b", s[1:65]) + s = s[65:] + else: + return # FIXME: add code to read 16-bit tables! + # raise SyntaxError, "bad quantization table element size" + + +# +# JPEG marker table + +MARKER = { + 0xFFC0: ("SOF0", "Baseline DCT", SOF), + 0xFFC1: ("SOF1", "Extended Sequential DCT", SOF), + 0xFFC2: ("SOF2", "Progressive DCT", SOF), + 0xFFC3: ("SOF3", "Spatial lossless", SOF), + 0xFFC4: ("DHT", "Define Huffman table", Skip), + 0xFFC5: ("SOF5", "Differential sequential DCT", SOF), + 0xFFC6: ("SOF6", "Differential progressive DCT", SOF), + 0xFFC7: ("SOF7", "Differential spatial", SOF), + 0xFFC8: ("JPG", "Extension", None), + 0xFFC9: ("SOF9", "Extended sequential DCT (AC)", SOF), + 0xFFCA: ("SOF10", "Progressive DCT (AC)", SOF), + 0xFFCB: ("SOF11", "Spatial lossless DCT (AC)", SOF), + 0xFFCC: ("DAC", "Define arithmetic coding conditioning", Skip), + 0xFFCD: ("SOF13", "Differential sequential DCT (AC)", SOF), + 0xFFCE: ("SOF14", "Differential progressive DCT (AC)", SOF), + 0xFFCF: ("SOF15", "Differential spatial (AC)", SOF), + 0xFFD0: ("RST0", "Restart 0", None), + 0xFFD1: ("RST1", "Restart 1", None), + 0xFFD2: ("RST2", "Restart 2", None), + 0xFFD3: ("RST3", "Restart 3", None), + 0xFFD4: ("RST4", "Restart 4", None), + 0xFFD5: ("RST5", "Restart 5", None), + 0xFFD6: ("RST6", "Restart 6", None), + 0xFFD7: ("RST7", "Restart 7", None), + 0xFFD8: ("SOI", "Start of image", None), + 0xFFD9: ("EOI", "End of image", None), + 0xFFDA: ("SOS", "Start of scan", Skip), + 0xFFDB: ("DQT", "Define quantization table", DQT), + 0xFFDC: ("DNL", "Define number of lines", Skip), + 0xFFDD: ("DRI", "Define restart interval", Skip), + 0xFFDE: ("DHP", "Define hierarchical progression", SOF), + 0xFFDF: ("EXP", "Expand reference component", Skip), + 0xFFE0: ("APP0", "Application segment 0", APP), + 0xFFE1: ("APP1", "Application segment 1", APP), + 0xFFE2: ("APP2", "Application segment 2", APP), + 0xFFE3: ("APP3", "Application segment 3", APP), + 0xFFE4: ("APP4", "Application segment 4", APP), + 0xFFE5: ("APP5", "Application segment 5", APP), + 0xFFE6: ("APP6", "Application segment 6", APP), + 0xFFE7: ("APP7", "Application segment 7", APP), + 0xFFE8: ("APP8", "Application segment 8", APP), + 0xFFE9: ("APP9", "Application segment 9", APP), + 0xFFEA: ("APP10", "Application segment 10", APP), + 0xFFEB: ("APP11", "Application segment 11", APP), + 0xFFEC: ("APP12", "Application segment 12", APP), + 0xFFED: ("APP13", "Application segment 13", APP), + 0xFFEE: ("APP14", "Application segment 14", APP), + 0xFFEF: ("APP15", "Application segment 15", APP), + 0xFFF0: ("JPG0", "Extension 0", None), + 0xFFF1: ("JPG1", "Extension 1", None), + 0xFFF2: ("JPG2", "Extension 2", None), + 0xFFF3: ("JPG3", "Extension 3", None), + 0xFFF4: ("JPG4", "Extension 4", None), + 0xFFF5: ("JPG5", "Extension 5", None), + 0xFFF6: ("JPG6", "Extension 6", None), + 0xFFF7: ("JPG7", "Extension 7", None), + 0xFFF8: ("JPG8", "Extension 8", None), + 0xFFF9: ("JPG9", "Extension 9", None), + 0xFFFA: ("JPG10", "Extension 10", None), + 0xFFFB: ("JPG11", "Extension 11", None), + 0xFFFC: ("JPG12", "Extension 12", None), + 0xFFFD: ("JPG13", "Extension 13", None), + 0xFFFE: ("COM", "Comment", COM) +} + + +def _accept(prefix): + return prefix[0] == "\377" + +## +# Image plugin for JPEG and JFIF images. + +class JpegImageFile(ImageFile.ImageFile): + + format = "JPEG" + format_description = "JPEG (ISO 10918)" + + def _open(self): + + s = self.fp.read(1) + + if ord(s[0]) != 255: + raise SyntaxError("not a JPEG file") + + # Create attributes + self.bits = self.layers = 0 + + # JPEG specifics (internal) + self.layer = [] + self.huffman_dc = {} + self.huffman_ac = {} + self.quantization = {} + self.app = {} # compatibility + self.applist = [] + self.icclist = [] + + while 1: + + s = s + self.fp.read(1) + + i = i16(s) + + if MARKER.has_key(i): + name, description, handler = MARKER[i] + # print hex(i), name, description + if handler is not None: + handler(self, i) + if i == 0xFFDA: # start of scan + rawmode = self.mode + if self.mode == "CMYK": + rawmode = "CMYK;I" # assume adobe conventions + self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))] + # self.__offset = self.fp.tell() + break + s = self.fp.read(1) + elif i == 0 or i == 65535: + # padded marker or junk; move on + s = "\xff" + else: + raise SyntaxError("no marker found") + + def draft(self, mode, size): + + if len(self.tile) != 1: + return + + d, e, o, a = self.tile[0] + scale = 0 + + if a[0] == "RGB" and mode in ["L", "YCbCr"]: + self.mode = mode + a = mode, "" + + if size: + scale = max(self.size[0] / size[0], self.size[1] / size[1]) + for s in [8, 4, 2, 1]: + if scale >= s: + break + e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1] + self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s) + scale = s + + self.tile = [(d, e, o, a)] + self.decoderconfig = (scale, 1) + + return self + + def load_djpeg(self): + + # ALTERNATIVE: handle JPEGs via the IJG command line utilities + + import tempfile, os + file = tempfile.mktemp() + os.system("djpeg %s >%s" % (self.filename, file)) + + try: + self.im = Image.core.open_ppm(file) + finally: + try: os.unlink(file) + except: pass + + self.mode = self.im.mode + self.size = self.im.size + + self.tile = [] + + def _getexif(self): + # Extract EXIF information. This method is highly experimental, + # and is likely to be replaced with something better in a future + # version. + import TiffImagePlugin, StringIO + def fixup(value): + if len(value) == 1: + return value[0] + return value + # The EXIF record consists of a TIFF file embedded in a JPEG + # application marker (!). + try: + data = self.info["exif"] + except KeyError: + return None + file = StringIO.StringIO(data[6:]) + head = file.read(8) + exif = {} + # process dictionary + info = TiffImagePlugin.ImageFileDirectory(head) + info.load(file) + for key, value in info.items(): + exif[key] = fixup(value) + # get exif extension + try: + file.seek(exif[0x8769]) + except KeyError: + pass + else: + info = TiffImagePlugin.ImageFileDirectory(head) + info.load(file) + for key, value in info.items(): + exif[key] = fixup(value) + # get gpsinfo extension + try: + file.seek(exif[0x8825]) + except KeyError: + pass + else: + info = TiffImagePlugin.ImageFileDirectory(head) + info.load(file) + exif[0x8825] = gps = {} + for key, value in info.items(): + gps[key] = fixup(value) + return exif + +# -------------------------------------------------------------------- +# stuff to save JPEG files + +RAWMODE = { + "1": "L", + "L": "L", + "RGB": "RGB", + "RGBA": "RGB", + "RGBX": "RGB", + "CMYK": "CMYK;I", # assume adobe conventions + "YCbCr": "YCbCr", +} + +def _save(im, fp, filename): + + try: + rawmode = RAWMODE[im.mode] + except KeyError: + raise IOError("cannot write mode %s as JPEG" % im.mode) + + info = im.encoderinfo + + dpi = info.get("dpi", (0, 0)) + + subsampling = info.get("subsampling", -1) + if subsampling == "4:4:4": + subsampling = 0 + elif subsampling == "4:2:2": + subsampling = 1 + elif subsampling == "4:1:1": + subsampling = 2 + + extra = "" + + icc_profile = info.get("icc_profile") + if icc_profile: + ICC_OVERHEAD_LEN = 14 + MAX_BYTES_IN_MARKER = 65533 + MAX_DATA_BYTES_IN_MARKER = MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN + markers = [] + while icc_profile: + markers.append(icc_profile[:MAX_DATA_BYTES_IN_MARKER]) + icc_profile = icc_profile[MAX_DATA_BYTES_IN_MARKER:] + i = 1 + for marker in markers: + size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker)) + extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker) + i = i + 1 + + # get keyword arguments + im.encoderconfig = ( + info.get("quality", 0), + # "progressive" is the official name, but older documentation + # says "progression" + # FIXME: issue a warning if the wrong form is used (post-1.1.7) + info.has_key("progressive") or info.has_key("progression"), + info.get("smooth", 0), + info.has_key("optimize"), + info.get("streamtype", 0), + dpi[0], dpi[1], + subsampling, + extra, + ) + + ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)]) + +def _save_cjpeg(im, fp, filename): + # ALTERNATIVE: handle JPEGs via the IJG command line utilities. + import os + file = im._dump() + os.system("cjpeg %s >%s" % (file, filename)) + try: os.unlink(file) + except: pass + +# -------------------------------------------------------------------q- +# Registry stuff + +Image.register_open("JPEG", JpegImageFile, _accept) +Image.register_save("JPEG", _save) + +Image.register_extension("JPEG", ".jfif") +Image.register_extension("JPEG", ".jpe") +Image.register_extension("JPEG", ".jpg") +Image.register_extension("JPEG", ".jpeg") + +Image.register_mime("JPEG", "image/jpeg") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py new file mode 100755 index 00000000000..62ee52cf8ff --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py @@ -0,0 +1,70 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Basic McIdas support for PIL +# +# History: +# 1997-05-05 fl Created (8-bit images only) +# 2009-03-08 fl Added 16/32-bit support. +# +# Thanks to Richard Jones and Craig Swank for specs and samples. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.2" + +import struct +import Image, ImageFile + +def _accept(s): + return s[:8] == "\x00\x00\x00\x00\x00\x00\x00\x04" + +## +# Image plugin for McIdas area images. + +class McIdasImageFile(ImageFile.ImageFile): + + format = "MCIDAS" + format_description = "McIdas area file" + + def _open(self): + + # parse area file directory + s = self.fp.read(256) + if not _accept(s) or len(s) != 256: + raise SyntaxError("not an McIdas area file") + + self.area_descriptor_raw = s + self.area_descriptor = w = [0] + list(struct.unpack("!64i", s)) + + # get mode + if w[11] == 1: + mode = rawmode = "L" + elif w[11] == 2: + # FIXME: add memory map support + mode = "I"; rawmode = "I;16B" + elif w[11] == 4: + # FIXME: add memory map support + mode = "I"; rawmode = "I;32B" + else: + raise SyntaxError("unsupported McIdas format") + + self.mode = mode + self.size = w[10], w[9] + + offset = w[34] + w[15] + stride = w[15] + w[10]*w[11]*w[14] + + self.tile = [("raw", (0, 0) + self.size, offset, (rawmode, stride, 1))] + +# -------------------------------------------------------------------- +# registry + +Image.register_open("MCIDAS", McIdasImageFile, _accept) + +# no default extension diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py new file mode 100755 index 00000000000..b1a3bba79f7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py @@ -0,0 +1,95 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Microsoft Image Composer support for PIL +# +# Notes: +# uses TiffImagePlugin.py to read the actual image streams +# +# History: +# 97-01-20 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.1" + + +import Image, TiffImagePlugin +from OleFileIO import * + + +# +# -------------------------------------------------------------------- + + +def _accept(prefix): + return prefix[:8] == MAGIC + +## +# Image plugin for Microsoft's Image Composer file format. + +class MicImageFile(TiffImagePlugin.TiffImageFile): + + format = "MIC" + format_description = "Microsoft Image Composer" + + def _open(self): + + # read the OLE directory and see if this is a likely + # to be a Microsoft Image Composer file + + try: + self.ole = OleFileIO(self.fp) + except IOError: + raise SyntaxError, "not an MIC file; invalid OLE file" + + # find ACI subfiles with Image members (maybe not the + # best way to identify MIC files, but what the... ;-) + + self.images = [] + for file in self.ole.listdir(): + if file[1:] and file[0][-4:] == ".ACI" and file[1] == "Image": + self.images.append(file) + + # if we didn't find any images, this is probably not + # an MIC file. + if not self.images: + raise SyntaxError, "not an MIC file; no image entries" + + self.__fp = self.fp + self.frame = 0 + + if len(self.images) > 1: + self.category = Image.CONTAINER + + self.seek(0) + + def seek(self, frame): + + try: + filename = self.images[frame] + except IndexError: + raise EOFError, "no such frame" + + self.fp = self.ole.openstream(filename) + + TiffImagePlugin.TiffImageFile._open(self) + + self.frame = frame + + def tell(self): + + return self.frame + +# +# -------------------------------------------------------------------- + +Image.register_open("MIC", MicImageFile, _accept) + +Image.register_extension("MIC", ".mic") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py new file mode 100755 index 00000000000..c02edee8267 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py @@ -0,0 +1,82 @@ +# +# The Python Imaging Library. +# $Id$ +# +# MPEG file handling +# +# History: +# 95-09-09 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.1" + +import Image, ImageFile + +# +# Bitstream parser + +class BitStream: + + def __init__(self, fp): + self.fp = fp + self.bits = 0 + self.bitbuffer = 0 + + def next(self): + return ord(self.fp.read(1)) + + def peek(self, bits): + while self.bits < bits: + c = self.next() + if c < 0: + self.bits = 0 + continue + self.bitbuffer = (self.bitbuffer << 8) + c + self.bits = self.bits + 8 + return self.bitbuffer >> (self.bits - bits) & (1L << bits) - 1 + + def skip(self, bits): + while self.bits < bits: + self.bitbuffer = (self.bitbuffer << 8) + ord(self.fp.read(1)) + self.bits = self.bits + 8 + self.bits = self.bits - bits + + def read(self, bits): + v = self.peek(bits) + self.bits = self.bits - bits + return v + +## +# Image plugin for MPEG streams. This plugin can identify a stream, +# but it cannot read it. + +class MpegImageFile(ImageFile.ImageFile): + + format = "MPEG" + format_description = "MPEG" + + def _open(self): + + s = BitStream(self.fp) + + if s.read(32) != 0x1B3: + raise SyntaxError, "not an MPEG file" + + self.mode = "RGB" + self.size = s.read(12), s.read(12) + + +# -------------------------------------------------------------------- +# Registry stuff + +Image.register_open("MPEG", MpegImageFile) + +Image.register_extension("MPEG", ".mpg") +Image.register_extension("MPEG", ".mpeg") + +Image.register_mime("MPEG", "video/mpeg") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py new file mode 100755 index 00000000000..9dac36b47b7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py @@ -0,0 +1,103 @@ +# +# The Python Imaging Library. +# $Id$ +# +# MSP file handling +# +# This is the format used by the Paint program in Windows 1 and 2. +# +# History: +# 95-09-05 fl Created +# 97-01-03 fl Read/write MSP images +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.1" + +import Image, ImageFile + + +# +# read MSP files + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def _accept(prefix): + return prefix[:4] in ["DanM", "LinS"] + +## +# Image plugin for Windows MSP images. This plugin supports both +# uncompressed (Windows 1.0). + +class MspImageFile(ImageFile.ImageFile): + + format = "MSP" + format_description = "Windows Paint" + + def _open(self): + + # Header + s = self.fp.read(32) + if s[:4] not in ["DanM", "LinS"]: + raise SyntaxError, "not an MSP file" + + # Header checksum + sum = 0 + for i in range(0, 32, 2): + sum = sum ^ i16(s[i:i+2]) + if sum != 0: + raise SyntaxError, "bad MSP checksum" + + self.mode = "1" + self.size = i16(s[4:]), i16(s[6:]) + + if s[:4] == "DanM": + self.tile = [("raw", (0,0)+self.size, 32, ("1", 0, 1))] + else: + self.tile = [("msp", (0,0)+self.size, 32+2*self.size[1], None)] + +# +# write MSP files (uncompressed only) + +def o16(i): + return chr(i&255) + chr(i>>8&255) + +def _save(im, fp, filename): + + if im.mode != "1": + raise IOError, "cannot write mode %s as MSP" % im.mode + + # create MSP header + header = [0] * 16 + + header[0], header[1] = i16("Da"), i16("nM") # version 1 + header[2], header[3] = im.size + header[4], header[5] = 1, 1 + header[6], header[7] = 1, 1 + header[8], header[9] = im.size + + sum = 0 + for h in header: + sum = sum ^ h + header[12] = sum # FIXME: is this the right field? + + # header + for h in header: + fp.write(o16(h)) + + # image body + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 32, ("1", 0, 1))]) + +# +# registry + +Image.register_open("MSP", MspImageFile, _accept) +Image.register_save("MSP", _save) + +Image.register_extension("MSP", ".msp") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py new file mode 100755 index 00000000000..36e598a9be3 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py @@ -0,0 +1,528 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library +# $Id$ +# +# stuff to deal with OLE2 Structured Storage files. this module is +# used by PIL to read Image Composer and FlashPix files, but can also +# be used to read other files of this type. +# +# History: +# 1997-01-20 fl Created +# 1997-01-22 fl Fixed 64-bit portability quirk +# 2003-09-09 fl Fixed typo in OleFileIO.loadfat (noted by Daniel Haertle) +# 2004-02-29 fl Changed long hex constants to signed integers +# +# Notes: +# FIXME: sort out sign problem (eliminate long hex constants) +# FIXME: change filename to use "a/b/c" instead of ["a", "b", "c"] +# FIXME: provide a glob mechanism function (using fnmatchcase) +# +# Literature: +# +# "FlashPix Format Specification, Appendix A", Kodak and Microsoft, +# September 1996. +# +# Quotes: +# +# "If this document and functionality of the Software conflict, +# the actual functionality of the Software represents the correct +# functionality" -- Microsoft, in the OLE format specification +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +import string, StringIO + + +def i16(c, o = 0): + return ord(c[o])+(ord(c[o+1])<<8) + +def i32(c, o = 0): + return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24) + + +MAGIC = '\320\317\021\340\241\261\032\341' + +# +# -------------------------------------------------------------------- +# property types + +VT_EMPTY=0; VT_NULL=1; VT_I2=2; VT_I4=3; VT_R4=4; VT_R8=5; VT_CY=6; +VT_DATE=7; VT_BSTR=8; VT_DISPATCH=9; VT_ERROR=10; VT_BOOL=11; +VT_VARIANT=12; VT_UNKNOWN=13; VT_DECIMAL=14; VT_I1=16; VT_UI1=17; +VT_UI2=18; VT_UI4=19; VT_I8=20; VT_UI8=21; VT_INT=22; VT_UINT=23; +VT_VOID=24; VT_HRESULT=25; VT_PTR=26; VT_SAFEARRAY=27; VT_CARRAY=28; +VT_USERDEFINED=29; VT_LPSTR=30; VT_LPWSTR=31; VT_FILETIME=64; +VT_BLOB=65; VT_STREAM=66; VT_STORAGE=67; VT_STREAMED_OBJECT=68; +VT_STORED_OBJECT=69; VT_BLOB_OBJECT=70; VT_CF=71; VT_CLSID=72; +VT_VECTOR=0x1000; + +# map property id to name (for debugging purposes) + +VT = {} +for k, v in vars().items(): + if k[:3] == "VT_": + VT[v] = k + +# +# -------------------------------------------------------------------- +# Some common document types (root.clsid fields) + +WORD_CLSID = "00020900-0000-0000-C000-000000000046" + + +# +# -------------------------------------------------------------------- + +class _OleStream(StringIO.StringIO): + + """OLE2 Stream + + Returns a read-only file object which can be used to read + the contents of a OLE stream. To open a stream, use the + openstream method in the OleFile class. + + This function can be used with either ordinary streams, + or ministreams, depending on the offset, sectorsize, and + fat table arguments. + """ + + # FIXME: should store the list of sects obtained by following + # the fat chain, and load new sectors on demand instead of + # loading it all in one go. + + def __init__(self, fp, sect, size, offset, sectorsize, fat): + + data = [] + + while sect != -2: # 0xFFFFFFFEL: + fp.seek(offset + sectorsize * sect) + data.append(fp.read(sectorsize)) + sect = fat[sect] + + data = string.join(data, "") + + # print len(data), size + + StringIO.StringIO.__init__(self, data[:size]) + +# +# -------------------------------------------------------------------- + +# FIXME: should add a counter in here to avoid looping forever +# if the tree is broken. + +class _OleDirectoryEntry: + + """OLE2 Directory Entry + + Encapsulates a stream directory entry. Note that the + constructor builds a tree of all subentries, so we only + have to call it with the root object. + """ + + def __init__(self, sidlist, sid): + + # store directory parameters. the caller provides + # a complete list of directory entries, as read from + # the directory stream. + + name, type, sect, size, sids, clsid = sidlist[sid] + + self.sid = sid + self.name = name + self.type = type # 1=storage 2=stream + self.sect = sect + self.size = size + self.clsid = clsid + + # process child nodes, if any + + self.kids = [] + + sid = sidlist[sid][4][2] + + if sid != -1: + + # the directory entries are organized as a red-black tree. + # the following piece of code does an ordered traversal of + # such a tree (at least that's what I hope ;-) + + stack = [self.sid] + + # start at leftmost position + + left, right, child = sidlist[sid][4] + + while left != -1: # 0xFFFFFFFFL: + stack.append(sid) + sid = left + left, right, child = sidlist[sid][4] + + while sid != self.sid: + + self.kids.append(_OleDirectoryEntry(sidlist, sid)) + + # try to move right + left, right, child = sidlist[sid][4] + if right != -1: # 0xFFFFFFFFL: + # and then back to the left + sid = right + while 1: + left, right, child = sidlist[sid][4] + if left == -1: # 0xFFFFFFFFL: + break + stack.append(sid) + sid = left + else: + # couldn't move right; move up instead + while 1: + ptr = stack[-1] + del stack[-1] + left, right, child = sidlist[ptr][4] + if right != sid: + break + sid = right + left, right, child = sidlist[sid][4] + if right != ptr: + sid = ptr + + # in the OLE file, entries are sorted on (length, name). + # for convenience, we sort them on name instead. + + self.kids.sort() + + def __cmp__(self, other): + "Compare entries by name" + + return cmp(self.name, other.name) + + def dump(self, tab = 0): + "Dump this entry, and all its subentries (for debug purposes only)" + + TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)", + "(property)", "(root)"] + + print " "*tab + repr(self.name), TYPES[self.type], + if self.type in (2, 5): + print self.size, "bytes", + print + if self.type in (1, 5) and self.clsid: + print " "*tab + "{%s}" % self.clsid + + for kid in self.kids: + kid.dump(tab + 2) + +# +# -------------------------------------------------------------------- + +## +# This class encapsulates the interface to an OLE 2 structured +# storage file. Use the {@link listdir} and {@link openstream} +# methods to access the contents of this file. + +class OleFileIO: + """OLE container object + + This class encapsulates the interface to an OLE 2 structured + storage file. Use the listdir and openstream methods to access + the contents of this file. + + Object names are given as a list of strings, one for each subentry + level. The root entry should be omitted. For example, the following + code extracts all image streams from a Microsoft Image Composer file: + + ole = OleFileIO("fan.mic") + + for entry in ole.listdir(): + if entry[1:2] == "Image": + fin = ole.openstream(entry) + fout = open(entry[0:1], "wb") + while 1: + s = fin.read(8192) + if not s: + break + fout.write(s) + + You can use the viewer application provided with the Python Imaging + Library to view the resulting files (which happens to be standard + TIFF files). + """ + + def __init__(self, filename = None): + + if filename: + self.open(filename) + + ## + # Open an OLE2 file. + + def open(self, filename): + """Open an OLE2 file""" + + if type(filename) == type(""): + self.fp = open(filename, "rb") + else: + self.fp = filename + + header = self.fp.read(512) + + if len(header) != 512 or header[:8] != MAGIC: + raise IOError, "not an OLE2 structured storage file" + + # file clsid (probably never used, so we don't store it) + clsid = self._clsid(header[8:24]) + + # FIXME: could check version and byte order fields + + self.sectorsize = 1 << i16(header, 30) + self.minisectorsize = 1 << i16(header, 32) + + self.minisectorcutoff = i32(header, 56) + + # Load file allocation tables + self.loadfat(header) + + # Load direcory. This sets both the sidlist (ordered by id) + # and the root (ordered by hierarchy) members. + self.loaddirectory(i32(header, 48)) + + self.ministream = None + self.minifatsect = i32(header, 60) + + def loadfat(self, header): + # Load the FAT table. The header contains a sector numbers + # for the first 109 FAT sectors. Additional sectors are + # described by DIF blocks (FIXME: not yet implemented) + + sect = header[76:512] + fat = [] + for i in range(0, len(sect), 4): + ix = i32(sect, i) + if ix == -2 or ix == -1: # ix == 0xFFFFFFFEL or ix == 0xFFFFFFFFL: + break + s = self.getsect(ix) + fat = fat + map(lambda i, s=s: i32(s, i), range(0, len(s), 4)) + self.fat = fat + + def loadminifat(self): + # Load the MINIFAT table. This is stored in a standard sub- + # stream, pointed to by a header field. + + s = self._open(self.minifatsect).read() + + self.minifat = map(lambda i, s=s: i32(s, i), range(0, len(s), 4)) + + def getsect(self, sect): + # Read given sector + + self.fp.seek(512 + self.sectorsize * sect) + return self.fp.read(self.sectorsize) + + def _unicode(self, s): + # Map unicode string to Latin 1 + + # FIXME: some day, Python will provide an official way to handle + # Unicode strings, but until then, this will have to do... + return filter(ord, s) + + def loaddirectory(self, sect): + # Load the directory. The directory is stored in a standard + # substream, independent of its size. + + # read directory stream + fp = self._open(sect) + + # create list of sid entries + self.sidlist = [] + while 1: + entry = fp.read(128) + if not entry: + break + type = ord(entry[66]) + name = self._unicode(entry[0:0+i16(entry, 64)]) + ptrs = i32(entry, 68), i32(entry, 72), i32(entry, 76) + sect, size = i32(entry, 116), i32(entry, 120) + clsid = self._clsid(entry[80:96]) + self.sidlist.append((name, type, sect, size, ptrs, clsid)) + + # create hierarchical list of directory entries + self.root = _OleDirectoryEntry(self.sidlist, 0) + + def dumpdirectory(self): + # Dump directory (for debugging only) + + self.root.dump() + + def _clsid(self, clsid): + if clsid == "\0" * len(clsid): + return "" + return (("%08X-%04X-%04X-%02X%02X-" + "%02X" * 6) % + ((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) + + tuple(map(ord, clsid[8:16])))) + + def _list(self, files, prefix, node): + # listdir helper + + prefix = prefix + [node.name] + for entry in node.kids: + if entry.kids: + self._list(files, prefix, entry) + else: + files.append(prefix[1:] + [entry.name]) + + def _find(self, filename): + # openstream helper + + node = self.root + for name in filename: + for kid in node.kids: + if kid.name == name: + break + else: + raise IOError, "file not found" + node = kid + return node.sid + + def _open(self, start, size = 0x7FFFFFFF): + # openstream helper. + + if size < self.minisectorcutoff: + # ministream object + if not self.ministream: + self.loadminifat() + self.ministream = self._open(self.sidlist[0][2]) + return _OleStream(self.ministream, start, size, 0, + self.minisectorsize, self.minifat) + + # standard stream + return _OleStream(self.fp, start, size, 512, + self.sectorsize, self.fat) + + ## + # Returns a list of streams stored in this file. + + def listdir(self): + """Return a list of streams stored in this file""" + + files = [] + self._list(files, [], self.root) + return files + + ## + # Opens a stream as a read-only file object. + + def openstream(self, filename): + """Open a stream as a read-only file object""" + + slot = self._find(filename) + name, type, sect, size, sids, clsid = self.sidlist[slot] + if type != 2: + raise IOError, "this file is not a stream" + return self._open(sect, size) + + ## + # Gets a list of properties described in substream. + + def getproperties(self, filename): + """Return properties described in substream""" + + fp = self.openstream(filename) + + data = {} + + # header + s = fp.read(28) + clsid = self._clsid(s[8:24]) + + # format id + s = fp.read(20) + fmtid = self._clsid(s[:16]) + fp.seek(i32(s, 16)) + + # get section + s = "****" + fp.read(i32(fp.read(4))-4) + + for i in range(i32(s, 4)): + + id = i32(s, 8+i*8) + offset = i32(s, 12+i*8) + type = i32(s, offset) + + # test for common types first (should perhaps use + # a dictionary instead?) + + if type == VT_I2: + value = i16(s, offset+4) + if value >= 32768: + value = value - 65536 + elif type == VT_UI2: + value = i16(s, offset+4) + elif type in (VT_I4, VT_ERROR): + value = i32(s, offset+4) + elif type == VT_UI4: + value = i32(s, offset+4) # FIXME + elif type in (VT_BSTR, VT_LPSTR): + count = i32(s, offset+4) + value = s[offset+8:offset+8+count-1] + elif type == VT_BLOB: + count = i32(s, offset+4) + value = s[offset+8:offset+8+count] + elif type == VT_LPWSTR: + count = i32(s, offset+4) + value = self._unicode(s[offset+8:offset+8+count*2]) + elif type == VT_FILETIME: + value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32) + # FIXME: this is a 64-bit int: "number of 100ns periods + # since Jan 1,1601". Should map this to Python time + value = value / 10000000L # seconds + elif type == VT_UI1: + value = ord(s[offset+4]) + elif type == VT_CLSID: + value = self._clsid(s[offset+4:offset+20]) + elif type == VT_CF: + count = i32(s, offset+4) + value = s[offset+8:offset+8+count] + else: + value = None # everything else yields "None" + + # FIXME: add support for VT_VECTOR + + #print "%08x" % id, repr(value), + #print "(%s)" % VT[i32(s, offset) & 0xFFF] + + data[id] = value + + return data + +# +# -------------------------------------------------------------------- +# This script can be used to dump the directory of any OLE2 structured +# storage file. + +if __name__ == "__main__": + + import sys + + for file in sys.argv[1:]: + try: + ole = OleFileIO(file) + print "-" * 68 + print file + print "-" * 68 + ole.dumpdirectory() + for file in ole.listdir(): + if file[-1][0] == "\005": + print file + props = ole.getproperties(file) + props = props.items() + props.sort() + for k, v in props: + print " ", k, v + except IOError, v: + print "***", "cannot read", file, "-", v diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py new file mode 100755 index 00000000000..7309e17b3e2 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py @@ -0,0 +1,199 @@ +# +# The Python Imaging Library +# $Id$ +# +# simple postscript graphics interface +# +# History: +# 1996-04-20 fl Created +# 1999-01-10 fl Added gsave/grestore to image method +# 2005-05-04 fl Fixed floating point issue in image (from Eric Etheridge) +# +# Copyright (c) 1997-2005 by Secret Labs AB. All rights reserved. +# Copyright (c) 1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +import EpsImagePlugin +import string + +## +# Simple Postscript graphics interface. + +class PSDraw: + + def __init__(self, fp=None): + if not fp: + import sys + fp = sys.stdout + self.fp = fp + + def begin_document(self, id = None): + "Write Postscript DSC header" + # FIXME: incomplete + self.fp.write("%!PS-Adobe-3.0\n" + "save\n" + "/showpage { } def\n" + "%%EndComments\n" + "%%BeginDocument\n") + #self.fp.write(ERROR_PS) # debugging! + self.fp.write(EDROFF_PS) + self.fp.write(VDI_PS) + self.fp.write("%%EndProlog\n") + self.isofont = {} + + def end_document(self): + "Write Postscript DSC footer" + self.fp.write("%%EndDocument\n" + "restore showpage\n" + "%%End\n") + if hasattr(self.fp, "flush"): + self.fp.flush() + + def setfont(self, font, size): + if not self.isofont.has_key(font): + # reencode font + self.fp.write("/PSDraw-%s ISOLatin1Encoding /%s E\n" %\ + (font, font)) + self.isofont[font] = 1 + # rough + self.fp.write("/F0 %d /PSDraw-%s F\n" % (size, font)) + + def setink(self, ink): + print "*** NOT YET IMPLEMENTED ***" + + def line(self, xy0, xy1): + xy = xy0 + xy1 + self.fp.write("%d %d %d %d Vl\n" % xy) + + def rectangle(self, box): + self.fp.write("%d %d M %d %d 0 Vr\n" % box) + + def text(self, xy, text): + text = string.joinfields(string.splitfields(text, "("), "\\(") + text = string.joinfields(string.splitfields(text, ")"), "\\)") + xy = xy + (text,) + self.fp.write("%d %d M (%s) S\n" % xy) + + def image(self, box, im, dpi = None): + "Write an PIL image" + # default resolution depends on mode + if not dpi: + if im.mode == "1": + dpi = 200 # fax + else: + dpi = 100 # greyscale + # image size (on paper) + x = float(im.size[0] * 72) / dpi + y = float(im.size[1] * 72) / dpi + # max allowed size + xmax = float(box[2] - box[0]) + ymax = float(box[3] - box[1]) + if x > xmax: + y = y * xmax / x; x = xmax + if y > ymax: + x = x * ymax / y; y = ymax + dx = (xmax - x) / 2 + box[0] + dy = (ymax - y) / 2 + box[1] + self.fp.write("gsave\n%f %f translate\n" % (dx, dy)) + if (x, y) != im.size: + # EpsImagePlugin._save prints the image at (0,0,xsize,ysize) + sx = x / im.size[0] + sy = y / im.size[1] + self.fp.write("%f %f scale\n" % (sx, sy)) + EpsImagePlugin._save(im, self.fp, None, 0) + self.fp.write("\ngrestore\n") + +# -------------------------------------------------------------------- +# Postscript driver + +# +# EDROFF.PS -- Postscript driver for Edroff 2 +# +# History: +# 94-01-25 fl: created (edroff 2.04) +# +# Copyright (c) Fredrik Lundh 1994. +# + +EDROFF_PS = """\ +/S { show } bind def +/P { moveto show } bind def +/M { moveto } bind def +/X { 0 rmoveto } bind def +/Y { 0 exch rmoveto } bind def +/E { findfont + dup maxlength dict begin + { + 1 index /FID ne { def } { pop pop } ifelse + } forall + /Encoding exch def + dup /FontName exch def + currentdict end definefont pop +} bind def +/F { findfont exch scalefont dup setfont + [ exch /setfont cvx ] cvx bind def +} bind def +""" + +# +# VDI.PS -- Postscript driver for VDI meta commands +# +# History: +# 94-01-25 fl: created (edroff 2.04) +# +# Copyright (c) Fredrik Lundh 1994. +# + +VDI_PS = """\ +/Vm { moveto } bind def +/Va { newpath arcn stroke } bind def +/Vl { moveto lineto stroke } bind def +/Vc { newpath 0 360 arc closepath } bind def +/Vr { exch dup 0 rlineto + exch dup neg 0 exch rlineto + exch neg 0 rlineto + 0 exch rlineto + 100 div setgray fill 0 setgray } bind def +/Tm matrix def +/Ve { Tm currentmatrix pop + translate scale newpath 0 0 .5 0 360 arc closepath + Tm setmatrix +} bind def +/Vf { currentgray exch setgray fill setgray } bind def +""" + +# +# ERROR.PS -- Error handler +# +# History: +# 89-11-21 fl: created (pslist 1.10) +# + +ERROR_PS = """\ +/landscape false def +/errorBUF 200 string def +/errorNL { currentpoint 10 sub exch pop 72 exch moveto } def +errordict begin /handleerror { + initmatrix /Courier findfont 10 scalefont setfont + newpath 72 720 moveto $error begin /newerror false def + (PostScript Error) show errorNL errorNL + (Error: ) show + /errorname load errorBUF cvs show errorNL errorNL + (Command: ) show + /command load dup type /stringtype ne { errorBUF cvs } if show + errorNL errorNL + (VMstatus: ) show + vmstatus errorBUF cvs show ( bytes available, ) show + errorBUF cvs show ( bytes used at level ) show + errorBUF cvs show errorNL errorNL + (Operand stargck: ) show errorNL /ostargck load { + dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL + } forall errorNL + (Execution stargck: ) show errorNL /estargck load { + dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL + } forall + end showpage +} def end +""" diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py new file mode 100755 index 00000000000..3bbd9132778 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py @@ -0,0 +1,55 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read simple, teragon-style palette files +# +# History: +# 97-08-23 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +import string + +## +# File handler for Teragon-style palette files. + +class PaletteFile: + + rawmode = "RGB" + + def __init__(self, fp): + + self.palette = map(lambda i: (i, i, i), range(256)) + + while 1: + + s = fp.readline() + + if not s: + break + if s[0] == "#": + continue + if len(s) > 100: + raise SyntaxError, "bad palette file" + + v = map(int, string.split(s)) + try: + [i, r, g, b] = v + except ValueError: + [i, r] = v + g = b = r + + if 0 <= i <= 255: + self.palette[i] = chr(r) + chr(g) + chr(b) + + self.palette = string.join(self.palette, "") + + + def getpalette(self): + + return self.palette, self.rawmode diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py new file mode 100755 index 00000000000..78502313007 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py @@ -0,0 +1,225 @@ +# +# The Python Imaging Library. +# $Id$ +# + +## +# Image plugin for Palm pixmap images (output only). +## + +__version__ = "1.0" + +import Image, ImageFile + +_Palm8BitColormapValues = ( + ( 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 )) + +# so build a prototype image to be used for palette resampling +def build_prototype_image(): + image = Image.new("L", (1,len(_Palm8BitColormapValues),)) + image.putdata(range(len(_Palm8BitColormapValues))) + palettedata = () + for i in range(len(_Palm8BitColormapValues)): + palettedata = palettedata + _Palm8BitColormapValues[i] + for i in range(256 - len(_Palm8BitColormapValues)): + palettedata = palettedata + (0, 0, 0) + image.putpalette(palettedata) + return image + +Palm8BitColormapImage = build_prototype_image() + +# OK, we now have in Palm8BitColormapImage, a "P"-mode image with the right palette +# +# -------------------------------------------------------------------- + +_FLAGS = { + "custom-colormap": 0x4000, + "is-compressed": 0x8000, + "has-transparent": 0x2000, + } + +_COMPRESSION_TYPES = { + "none": 0xFF, + "rle": 0x01, + "scanline": 0x00, + } + +def o16b(i): + return chr(i>>8&255) + chr(i&255) + +# +# -------------------------------------------------------------------- + +## +# (Internal) Image save plugin for the Palm format. + +def _save(im, fp, filename, check=0): + + if im.mode == "P": + + # we assume this is a color Palm image with the standard colormap, + # unless the "info" dict has a "custom-colormap" field + + rawmode = "P" + bpp = 8 + version = 1 + + elif im.mode == "L" and im.encoderinfo.has_key("bpp") and im.encoderinfo["bpp"] in (1, 2, 4): + + # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because + # Palm does greyscale from white (0) to black (1) + bpp = im.encoderinfo["bpp"] + im = im.point(lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift)) + # we ignore the palette here + im.mode = "P" + rawmode = "P;" + str(bpp) + version = 1 + + elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4): + + # here we assume that even though the inherent mode is 8-bit grayscale, only + # the lower bpp bits are significant. We invert them to match the Palm. + bpp = im.info["bpp"] + im = im.point(lambda x, maxval=(1 << bpp)-1: maxval - (x & maxval)) + # we ignore the palette here + im.mode = "P" + rawmode = "P;" + str(bpp) + version = 1 + + elif im.mode == "1": + + # monochrome -- write it inverted, as is the Palm standard + rawmode = "1;I" + bpp = 1 + version = 0 + + else: + + raise IOError, "cannot write mode %s as Palm" % im.mode + + if check: + return check + + # + # make sure image data is available + im.load() + + # write header + + cols = im.size[0] + rows = im.size[1] + + rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2; + transparent_index = 0 + compression_type = _COMPRESSION_TYPES["none"] + + flags = 0; + if im.mode == "P" and im.info.has_key("custom-colormap"): + flags = flags & _FLAGS["custom-colormap"] + colormapsize = 4 * 256 + 2; + colormapmode = im.palette.mode + colormap = im.getdata().getpalette() + else: + colormapsize = 0 + + if im.info.has_key("offset"): + offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4; + else: + offset = 0 + + fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) + fp.write(chr(bpp)) + fp.write(chr(version)) + fp.write(o16b(offset)) + fp.write(chr(transparent_index)) + fp.write(chr(compression_type)) + fp.write(o16b(0)) # reserved by Palm + + # now write colormap if necessary + + if colormapsize > 0: + fp.write(o16b(256)) + for i in range(256): + fp.write(chr(i)) + if colormapmode == 'RGB': + fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2])) + elif colormapmode == 'RGBA': + fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2])) + + # now convert data to raw form + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))]) + + fp.flush() + + +# +# -------------------------------------------------------------------- + +Image.register_save("Palm", _save) + +Image.register_extension("Palm", ".palm") + +Image.register_mime("Palm", "image/palm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py new file mode 100755 index 00000000000..07bd27e9af3 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py @@ -0,0 +1,76 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PCD file handling +# +# History: +# 96-05-10 fl Created +# 96-05-27 fl Added draft mode (128x192, 256x384) +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.1" + + +import Image, ImageFile + +## +# Image plugin for PhotoCD images. This plugin only reads the 768x512 +# image from the file; higher resolutions are encoded in a proprietary +# encoding. + +class PcdImageFile(ImageFile.ImageFile): + + format = "PCD" + format_description = "Kodak PhotoCD" + + def _open(self): + + # rough + self.fp.seek(2048) + s = self.fp.read(2048) + + if s[:4] != "PCD_": + raise SyntaxError, "not a PCD file" + + orientation = ord(s[1538]) & 3 + if orientation == 1: + self.tile_post_rotate = 90 # hack + elif orientation == 3: + self.tile_post_rotate = -90 + + self.mode = "RGB" + self.size = 768, 512 # FIXME: not correct for rotated images! + self.tile = [("pcd", (0,0)+self.size, 96*2048, None)] + + def draft(self, mode, size): + + if len(self.tile) != 1: + return + + d, e, o, a = self.tile[0] + + if size: + scale = max(self.size[0] / size[0], self.size[1] / size[1]) + for s, o in [(4,0*2048), (2,0*2048), (1,96*2048)]: + if scale >= s: + break + # e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1] + # self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s) + + self.tile = [(d, e, o, a)] + + return self + +# +# registry + +Image.register_open("PCD", PcdImageFile) + +Image.register_extension("PCD", ".pcd") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py new file mode 100755 index 00000000000..bec39e3a034 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py @@ -0,0 +1,256 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library +# $Id$ +# +# portable compiled font file parser +# +# history: +# 1997-08-19 fl created +# 2003-09-13 fl fixed loading of unicode fonts +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1997-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +import Image +import FontFile + +import string + +# -------------------------------------------------------------------- +# declarations + +PCF_MAGIC = 0x70636601 # "\x01fcp" + +PCF_PROPERTIES = (1<<0) +PCF_ACCELERATORS = (1<<1) +PCF_METRICS = (1<<2) +PCF_BITMAPS = (1<<3) +PCF_INK_METRICS = (1<<4) +PCF_BDF_ENCODINGS = (1<<5) +PCF_SWIDTHS = (1<<6) +PCF_GLYPH_NAMES = (1<<7) +PCF_BDF_ACCELERATORS = (1<<8) + +BYTES_PER_ROW = [ + lambda bits: ((bits+7) >> 3), + lambda bits: ((bits+15) >> 3) & ~1, + lambda bits: ((bits+31) >> 3) & ~3, + lambda bits: ((bits+63) >> 3) & ~7, +] + + +def l16(c): + return ord(c[0]) + (ord(c[1])<<8) +def l32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + +def b16(c): + return ord(c[1]) + (ord(c[0])<<8) +def b32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) + +def sz(s, o): + return s[o:string.index(s, "\0", o)] + +## +# Font file plugin for the X11 PCF format. + +class PcfFontFile(FontFile.FontFile): + + name = "name" + + def __init__(self, fp): + + magic = l32(fp.read(4)) + if magic != PCF_MAGIC: + raise SyntaxError, "not a PCF file" + + FontFile.FontFile.__init__(self) + + count = l32(fp.read(4)) + self.toc = {} + for i in range(count): + type = l32(fp.read(4)) + self.toc[type] = l32(fp.read(4)), l32(fp.read(4)), l32(fp.read(4)) + + self.fp = fp + + self.info = self._load_properties() + + metrics = self._load_metrics() + bitmaps = self._load_bitmaps(metrics) + encoding = self._load_encoding() + + # + # create glyph structure + + for ch in range(256): + ix = encoding[ch] + if ix is not None: + x, y, l, r, w, a, d, f = metrics[ix] + glyph = (w, 0), (l, d-y, x+l, d), (0, 0, x, y), bitmaps[ix] + self.glyph[ch] = glyph + + def _getformat(self, tag): + + format, size, offset = self.toc[tag] + + fp = self.fp + fp.seek(offset) + + format = l32(fp.read(4)) + + if format & 4: + i16, i32 = b16, b32 + else: + i16, i32 = l16, l32 + + return fp, format, i16, i32 + + def _load_properties(self): + + # + # font properties + + properties = {} + + fp, format, i16, i32 = self._getformat(PCF_PROPERTIES) + + nprops = i32(fp.read(4)) + + # read property description + p = [] + for i in range(nprops): + p.append((i32(fp.read(4)), ord(fp.read(1)), i32(fp.read(4)))) + if nprops & 3: + fp.seek(4 - (nprops & 3), 1) # pad + + data = fp.read(i32(fp.read(4))) + + for k, s, v in p: + k = sz(data, k) + if s: + v = sz(data, v) + properties[k] = v + + return properties + + def _load_metrics(self): + + # + # font metrics + + metrics = [] + + fp, format, i16, i32 = self._getformat(PCF_METRICS) + + append = metrics.append + + if (format & 0xff00) == 0x100: + + # "compressed" metrics + for i in range(i16(fp.read(2))): + left = ord(fp.read(1)) - 128 + right = ord(fp.read(1)) - 128 + width = ord(fp.read(1)) - 128 + ascent = ord(fp.read(1)) - 128 + descent = ord(fp.read(1)) - 128 + xsize = right - left + ysize = ascent + descent + append( + (xsize, ysize, left, right, width, + ascent, descent, 0) + ) + + else: + + # "jumbo" metrics + for i in range(i32(fp.read(4))): + left = i16(fp.read(2)) + right = i16(fp.read(2)) + width = i16(fp.read(2)) + ascent = i16(fp.read(2)) + descent = i16(fp.read(2)) + attributes = i16(fp.read(2)) + xsize = right - left + ysize = ascent + descent + append( + (xsize, ysize, left, right, width, + ascent, descent, attributes) + ) + + return metrics + + def _load_bitmaps(self, metrics): + + # + # bitmap data + + bitmaps = [] + + fp, format, i16, i32 = self._getformat(PCF_BITMAPS) + + nbitmaps = i32(fp.read(4)) + + if nbitmaps != len(metrics): + raise IOError, "Wrong number of bitmaps" + + offsets = [] + for i in range(nbitmaps): + offsets.append(i32(fp.read(4))) + + bitmapSizes = [] + for i in range(4): + bitmapSizes.append(i32(fp.read(4))) + + byteorder = format & 4 # non-zero => MSB + bitorder = format & 8 # non-zero => MSB + padindex = format & 3 + + bitmapsize = bitmapSizes[padindex] + offsets.append(bitmapsize) + + data = fp.read(bitmapsize) + + pad = BYTES_PER_ROW[padindex] + mode = "1;R" + if bitorder: + mode = "1" + + for i in range(nbitmaps): + x, y, l, r, w, a, d, f = metrics[i] + b, e = offsets[i], offsets[i+1] + bitmaps.append( + Image.fromstring("1", (x, y), data[b:e], "raw", mode, pad(x)) + ) + + return bitmaps + + def _load_encoding(self): + + # map character code to bitmap index + encoding = [None] * 256 + + fp, format, i16, i32 = self._getformat(PCF_BDF_ENCODINGS) + + firstCol, lastCol = i16(fp.read(2)), i16(fp.read(2)) + firstRow, lastRow = i16(fp.read(2)), i16(fp.read(2)) + + default = i16(fp.read(2)) + + nencoding = (lastCol - firstCol + 1) * (lastRow - firstRow + 1) + + for i in range(nencoding): + encodingOffset = i16(fp.read(2)) + if encodingOffset != 0xFFFF: + try: + encoding[i+firstCol] = encodingOffset + except IndexError: + break # only load ISO-8859-1 glyphs + + return encoding diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py new file mode 100755 index 00000000000..15012d51ccd --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py @@ -0,0 +1,167 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PCX file handling +# +# This format was originally used by ZSoft's popular PaintBrush +# program for the IBM PC. It is also supported by many MS-DOS and +# Windows applications, including the Windows PaintBrush program in +# Windows 3. +# +# history: +# 1995-09-01 fl Created +# 1996-05-20 fl Fixed RGB support +# 1997-01-03 fl Fixed 2-bit and 4-bit support +# 1999-02-03 fl Fixed 8-bit support (broken in 1.0b1) +# 1999-02-07 fl Added write support +# 2002-06-09 fl Made 2-bit and 4-bit support a bit more robust +# 2002-07-30 fl Seek from to current position, not beginning of file +# 2003-06-03 fl Extract DPI settings (info["dpi"]) +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.6" + +import Image, ImageFile, ImagePalette + +def i16(c,o): + return ord(c[o]) + (ord(c[o+1])<<8) + +def _accept(prefix): + return ord(prefix[0]) == 10 and ord(prefix[1]) in [0, 2, 3, 5] + +## +# Image plugin for Paintbrush images. + +class PcxImageFile(ImageFile.ImageFile): + + format = "PCX" + format_description = "Paintbrush" + + def _open(self): + + # header + s = self.fp.read(128) + if not _accept(s): + raise SyntaxError, "not a PCX file" + + # image + bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1 + if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]: + raise SyntaxError, "bad PCX image size" + + # format + version = ord(s[1]) + bits = ord(s[3]) + planes = ord(s[65]) + stride = i16(s,66) + + self.info["dpi"] = i16(s,12), i16(s,14) + + if bits == 1 and planes == 1: + mode = rawmode = "1" + + elif bits == 1 and planes in (2, 4): + mode = "P" + rawmode = "P;%dL" % planes + self.palette = ImagePalette.raw("RGB", s[16:64]) + + elif version == 5 and bits == 8 and planes == 1: + mode = rawmode = "L" + # FIXME: hey, this doesn't work with the incremental loader !!! + self.fp.seek(-769, 2) + s = self.fp.read(769) + if len(s) == 769 and ord(s[0]) == 12: + # check if the palette is linear greyscale + for i in range(256): + if s[i*3+1:i*3+4] != chr(i)*3: + mode = rawmode = "P" + break + if mode == "P": + self.palette = ImagePalette.raw("RGB", s[1:]) + self.fp.seek(128) + + elif version == 5 and bits == 8 and planes == 3: + mode = "RGB" + rawmode = "RGB;L" + + else: + raise IOError, "unknown PCX mode" + + self.mode = mode + self.size = bbox[2]-bbox[0], bbox[3]-bbox[1] + + bbox = (0, 0) + self.size + + self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))] + +# -------------------------------------------------------------------- +# save PCX files + +SAVE = { + # mode: (version, bits, planes, raw mode) + "1": (2, 1, 1, "1"), + "L": (5, 8, 1, "L"), + "P": (5, 8, 1, "P"), + "RGB": (5, 8, 3, "RGB;L"), +} + +def o16(i): + return chr(i&255) + chr(i>>8&255) + +def _save(im, fp, filename, check=0): + + try: + version, bits, planes, rawmode = SAVE[im.mode] + except KeyError: + raise ValueError, "Cannot save %s images as PCX" % im.mode + + if check: + return check + + # bytes per plane + stride = (im.size[0] * bits + 7) / 8 + + # under windows, we could determine the current screen size with + # "Image.core.display_mode()[1]", but I think that's overkill... + + screen = im.size + + dpi = 100, 100 + + # PCX header + fp.write( + chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) + + o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) + + o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) + + o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) + + chr(0)*54 + ) + + assert fp.tell() == 128 + + ImageFile._save(im, fp, [("pcx", (0,0)+im.size, 0, + (rawmode, bits*planes))]) + + if im.mode == "P": + # colour palette + fp.write(chr(12)) + fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes + elif im.mode == "L": + # greyscale palette + fp.write(chr(12)) + for i in range(256): + fp.write(chr(i)*3) + +# -------------------------------------------------------------------- +# registry + +Image.register_open("PCX", PcxImageFile, _accept) +Image.register_save("PCX", _save) + +Image.register_extension("PCX", ".pcx") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py new file mode 100755 index 00000000000..4f957765ca6 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py @@ -0,0 +1,211 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PDF (Acrobat) file handling +# +# History: +# 1996-07-16 fl Created +# 1997-01-18 fl Fixed header +# 2004-02-21 fl Fixes for 1/L/CMYK images, etc. +# 2004-02-24 fl Fixes for 1 and P images. +# +# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved. +# Copyright (c) 1996-1997 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +## +# Image plugin for PDF images (output only). +## + +__version__ = "0.4" + +import Image, ImageFile +import StringIO + + +# +# -------------------------------------------------------------------- + +# object ids: +# 1. catalogue +# 2. pages +# 3. image +# 4. page +# 5. page contents + +def _obj(fp, obj, **dict): + fp.write("%d 0 obj\n" % obj) + if dict: + fp.write("<<\n") + for k, v in dict.items(): + if v is not None: + fp.write("/%s %s\n" % (k, v)) + fp.write(">>\n") + +def _endobj(fp): + fp.write("endobj\n") + +## +# (Internal) Image save plugin for the PDF format. + +def _save(im, fp, filename): + resolution = im.encoderinfo.get("resolution", 72.0) + + # + # make sure image data is available + im.load() + + xref = [0]*(5+1) # placeholders + + fp.write("%PDF-1.2\n") + fp.write("% created by PIL PDF driver " + __version__ + "\n") + + # + # Get image characteristics + + width, height = im.size + + # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits) + # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports + # Flatedecode (zip compression). + + bits = 8 + params = None + + if im.mode == "1": + filter = "/ASCIIHexDecode" + colorspace = "/DeviceGray" + procset = "/ImageB" # grayscale + bits = 1 + elif im.mode == "L": + filter = "/DCTDecode" + # params = "<< /Predictor 15 /Columns %d >>" % (width-2) + colorspace = "/DeviceGray" + procset = "/ImageB" # grayscale + elif im.mode == "P": + filter = "/ASCIIHexDecode" + colorspace = "[ /Indexed /DeviceRGB 255 <" + palette = im.im.getpalette("RGB") + for i in range(256): + r = ord(palette[i*3]) + g = ord(palette[i*3+1]) + b = ord(palette[i*3+2]) + colorspace = colorspace + "%02x%02x%02x " % (r, g, b) + colorspace = colorspace + "> ]" + procset = "/ImageI" # indexed color + elif im.mode == "RGB": + filter = "/DCTDecode" + colorspace = "/DeviceRGB" + procset = "/ImageC" # color images + elif im.mode == "CMYK": + filter = "/DCTDecode" + colorspace = "/DeviceCMYK" + procset = "/ImageC" # color images + else: + raise ValueError("cannot save mode %s" % im.mode) + + # + # catalogue + + xref[1] = fp.tell() + _obj(fp, 1, Type = "/Catalog", + Pages = "2 0 R") + _endobj(fp) + + # + # pages + + xref[2] = fp.tell() + _obj(fp, 2, Type = "/Pages", + Count = 1, + Kids = "[4 0 R]") + _endobj(fp) + + # + # image + + op = StringIO.StringIO() + + if filter == "/ASCIIHexDecode": + if bits == 1: + # FIXME: the hex encoder doesn't support packed 1-bit + # images; do things the hard way... + data = im.tostring("raw", "1") + im = Image.new("L", (len(data), 1), None) + im.putdata(data) + ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)]) + elif filter == "/DCTDecode": + ImageFile._save(im, op, [("jpeg", (0,0)+im.size, 0, im.mode)]) + elif filter == "/FlateDecode": + ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)]) + elif filter == "/RunLengthDecode": + ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)]) + else: + raise ValueError("unsupported PDF filter (%s)" % filter) + + xref[3] = fp.tell() + _obj(fp, 3, Type = "/XObject", + Subtype = "/Image", + Width = width, # * 72.0 / resolution, + Height = height, # * 72.0 / resolution, + Length = len(op.getvalue()), + Filter = filter, + BitsPerComponent = bits, + DecodeParams = params, + ColorSpace = colorspace) + + fp.write("stream\n") + fp.write(op.getvalue()) + fp.write("\nendstream\n") + + _endobj(fp) + + # + # page + + xref[4] = fp.tell() + _obj(fp, 4) + fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\ + "/Resources <<\n/ProcSet [ /PDF %s ]\n"\ + "/XObject << /image 3 0 R >>\n>>\n"\ + "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\ + (procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution))) + _endobj(fp) + + # + # page contents + + op = StringIO.StringIO() + + op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution))) + + xref[5] = fp.tell() + _obj(fp, 5, Length = len(op.getvalue())) + + fp.write("stream\n") + fp.write(op.getvalue()) + fp.write("\nendstream\n") + + _endobj(fp) + + # + # trailer + startxref = fp.tell() + fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref)) + for x in xref[1:]: + fp.write("%010d 00000 n \n" % x) + fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref)) + fp.write("startxref\n%d\n%%%%EOF\n" % startxref) + fp.flush() + +# +# -------------------------------------------------------------------- + +Image.register_save("PDF", _save) + +Image.register_extension("PDF", ".pdf") + +Image.register_mime("PDF", "application/pdf") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py new file mode 100755 index 00000000000..d4c597b6186 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py @@ -0,0 +1,71 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PIXAR raster support for PIL +# +# history: +# 97-01-29 fl Created +# +# notes: +# This is incomplete; it is based on a few samples created with +# Photoshop 2.5 and 3.0, and a summary description provided by +# Greg Coats . Hopefully, "L" and +# "RGBA" support will be added in future versions. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.1" + +import Image, ImageFile + +# +# helpers + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + +## +# Image plugin for PIXAR raster images. + +class PixarImageFile(ImageFile.ImageFile): + + format = "PIXAR" + format_description = "PIXAR raster image" + + def _open(self): + + # assuming a 4-byte magic label (FIXME: add "_accept" hook) + s = self.fp.read(4) + if s != "\200\350\000\000": + raise SyntaxError, "not a PIXAR file" + + # read rest of header + s = s + self.fp.read(508) + + self.size = i16(s[418:420]), i16(s[416:418]) + + # get channel/depth descriptions + mode = i16(s[424:426]), i16(s[426:428]) + + if mode == (14, 2): + self.mode = "RGB" + # FIXME: to be continued... + + # create tile descriptor (assuming "dumped") + self.tile = [("raw", (0,0)+self.size, 1024, (self.mode, 0, 1))] + +# +# -------------------------------------------------------------------- + +Image.register_open("PIXAR", PixarImageFile) + +# +# FIXME: what's the standard extension? diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py new file mode 100755 index 00000000000..0ee8589a536 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py @@ -0,0 +1,620 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PNG support code +# +# See "PNG (Portable Network Graphics) Specification, version 1.0; +# W3C Recommendation", 1996-10-01, Thomas Boutell (ed.). +# +# history: +# 1996-05-06 fl Created (couldn't resist it) +# 1996-12-14 fl Upgraded, added read and verify support (0.2) +# 1996-12-15 fl Separate PNG stream parser +# 1996-12-29 fl Added write support, added getchunks +# 1996-12-30 fl Eliminated circular references in decoder (0.3) +# 1998-07-12 fl Read/write 16-bit images as mode I (0.4) +# 2001-02-08 fl Added transparency support (from Zircon) (0.5) +# 2001-04-16 fl Don't close data source in "open" method (0.6) +# 2004-02-24 fl Don't even pretend to support interlaced files (0.7) +# 2004-08-31 fl Do basic sanity check on chunk identifiers (0.8) +# 2004-09-20 fl Added PngInfo chunk container +# 2004-12-18 fl Added DPI read support (based on code by Niki Spahiev) +# 2008-08-13 fl Added tRNS support for RGB images +# 2009-03-06 fl Support for preserving ICC profiles (by Florian Hoech) +# 2009-03-08 fl Added zTXT support (from Lowell Alleman) +# 2009-03-29 fl Read interlaced PNG files (from Conrado Porto Lopes Gouvua) +# +# Copyright (c) 1997-2009 by Secret Labs AB +# Copyright (c) 1996 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.9" + +import re, string + +import Image, ImageFile, ImagePalette, zlib + + +def i16(c): + return ord(c[1]) + (ord(c[0])<<8) +def i32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) + +is_cid = re.compile("\w\w\w\w").match + + +_MAGIC = "\211PNG\r\n\032\n" + + +_MODES = { + # supported bits/color combinations, and corresponding modes/rawmodes + (1, 0): ("1", "1"), + (2, 0): ("L", "L;2"), + (4, 0): ("L", "L;4"), + (8, 0): ("L", "L"), + (16,0): ("I", "I;16B"), + (8, 2): ("RGB", "RGB"), + (16,2): ("RGB", "RGB;16B"), + (1, 3): ("P", "P;1"), + (2, 3): ("P", "P;2"), + (4, 3): ("P", "P;4"), + (8, 3): ("P", "P"), + (8, 4): ("LA", "LA"), + (16,4): ("RGBA", "LA;16B"), # LA;16B->LA not yet available + (8, 6): ("RGBA", "RGBA"), + (16,6): ("RGBA", "RGBA;16B"), +} + + +# -------------------------------------------------------------------- +# Support classes. Suitable for PNG and related formats like MNG etc. + +class ChunkStream: + + def __init__(self, fp): + + self.fp = fp + self.queue = [] + + if not hasattr(Image.core, "crc32"): + self.crc = self.crc_skip + + def read(self): + "Fetch a new chunk. Returns header information." + + if self.queue: + cid, pos, len = self.queue[-1] + del self.queue[-1] + self.fp.seek(pos) + else: + s = self.fp.read(8) + cid = s[4:] + pos = self.fp.tell() + len = i32(s) + + if not is_cid(cid): + raise SyntaxError, "broken PNG file (chunk %s)" % repr(cid) + + return cid, pos, len + + def close(self): + self.queue = self.crc = self.fp = None + + def push(self, cid, pos, len): + + self.queue.append((cid, pos, len)) + + def call(self, cid, pos, len): + "Call the appropriate chunk handler" + + if Image.DEBUG: + print "STREAM", cid, pos, len + return getattr(self, "chunk_" + cid)(pos, len) + + def crc(self, cid, data): + "Read and verify checksum" + + crc1 = Image.core.crc32(data, Image.core.crc32(cid)) + crc2 = i16(self.fp.read(2)), i16(self.fp.read(2)) + if crc1 != crc2: + raise SyntaxError, "broken PNG file"\ + "(bad header checksum in %s)" % cid + + def crc_skip(self, cid, data): + "Read checksum. Used if the C module is not present" + + self.fp.read(4) + + def verify(self, endchunk = "IEND"): + + # Simple approach; just calculate checksum for all remaining + # blocks. Must be called directly after open. + + cids = [] + + while 1: + cid, pos, len = self.read() + if cid == endchunk: + break + self.crc(cid, ImageFile._safe_read(self.fp, len)) + cids.append(cid) + + return cids + + +# -------------------------------------------------------------------- +# PNG chunk container (for use with save(pnginfo=)) + +class PngInfo: + + def __init__(self): + self.chunks = [] + + def add(self, cid, data): + self.chunks.append((cid, data)) + + def add_text(self, key, value, zip=0): + if zip: + import zlib + self.add("zTXt", key + "\0\0" + zlib.compress(value)) + else: + self.add("tEXt", key + "\0" + value) + +# -------------------------------------------------------------------- +# PNG image stream (IHDR/IEND) + +class PngStream(ChunkStream): + + def __init__(self, fp): + + ChunkStream.__init__(self, fp) + + # local copies of Image attributes + self.im_info = {} + self.im_text = {} + self.im_size = (0,0) + self.im_mode = None + self.im_tile = None + self.im_palette = None + + def chunk_iCCP(self, pos, len): + + # ICC profile + s = ImageFile._safe_read(self.fp, len) + # according to PNG spec, the iCCP chunk contains: + # Profile name 1-79 bytes (character string) + # Null separator 1 byte (null character) + # Compression method 1 byte (0) + # Compressed profile n bytes (zlib with deflate compression) + i = string.find(s, chr(0)) + if Image.DEBUG: + print "iCCP profile name", s[:i] + print "Compression method", ord(s[i]) + comp_method = ord(s[i]) + if comp_method != 0: + raise SyntaxError("Unknown compression method %s in iCCP chunk" % comp_method) + try: + icc_profile = zlib.decompress(s[i+2:]) + except zlib.error: + icc_profile = None # FIXME + self.im_info["icc_profile"] = icc_profile + return s + + def chunk_IHDR(self, pos, len): + + # image header + s = ImageFile._safe_read(self.fp, len) + self.im_size = i32(s), i32(s[4:]) + try: + self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))] + except: + pass + if ord(s[12]): + self.im_info["interlace"] = 1 + if ord(s[11]): + raise SyntaxError, "unknown filter category" + return s + + def chunk_IDAT(self, pos, len): + + # image data + self.im_tile = [("zip", (0,0)+self.im_size, pos, self.im_rawmode)] + self.im_idat = len + raise EOFError + + def chunk_IEND(self, pos, len): + + # end of PNG image + raise EOFError + + def chunk_PLTE(self, pos, len): + + # palette + s = ImageFile._safe_read(self.fp, len) + if self.im_mode == "P": + self.im_palette = "RGB", s + return s + + def chunk_tRNS(self, pos, len): + + # transparency + s = ImageFile._safe_read(self.fp, len) + if self.im_mode == "P": + i = string.find(s, chr(0)) + if i >= 0: + self.im_info["transparency"] = i + elif self.im_mode == "L": + self.im_info["transparency"] = i16(s) + elif self.im_mode == "RGB": + self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:]) + return s + + def chunk_gAMA(self, pos, len): + + # gamma setting + s = ImageFile._safe_read(self.fp, len) + self.im_info["gamma"] = i32(s) / 100000.0 + return s + + def chunk_pHYs(self, pos, len): + + # pixels per unit + s = ImageFile._safe_read(self.fp, len) + px, py = i32(s), i32(s[4:]) + unit = ord(s[8]) + if unit == 1: # meter + dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5) + self.im_info["dpi"] = dpi + elif unit == 0: + self.im_info["aspect"] = px, py + return s + + def chunk_tEXt(self, pos, len): + + # text + s = ImageFile._safe_read(self.fp, len) + try: + k, v = string.split(s, "\0", 1) + except ValueError: + k = s; v = "" # fallback for broken tEXt tags + if k: + self.im_info[k] = self.im_text[k] = v + return s + + def chunk_zTXt(self, pos, len): + + # compressed text + s = ImageFile._safe_read(self.fp, len) + k, v = string.split(s, "\0", 1) + comp_method = ord(v[0]) + if comp_method != 0: + raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method) + import zlib + self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:]) + return s + +# -------------------------------------------------------------------- +# PNG reader + +def _accept(prefix): + return prefix[:8] == _MAGIC + +## +# Image plugin for PNG images. + +class PngImageFile(ImageFile.ImageFile): + + format = "PNG" + format_description = "Portable network graphics" + + def _open(self): + + if self.fp.read(8) != _MAGIC: + raise SyntaxError, "not a PNG file" + + # + # Parse headers up to the first IDAT chunk + + self.png = PngStream(self.fp) + + while 1: + + # + # get next chunk + + cid, pos, len = self.png.read() + + try: + s = self.png.call(cid, pos, len) + except EOFError: + break + except AttributeError: + if Image.DEBUG: + print cid, pos, len, "(unknown)" + s = ImageFile._safe_read(self.fp, len) + + self.png.crc(cid, s) + + # + # Copy relevant attributes from the PngStream. An alternative + # would be to let the PngStream class modify these attributes + # directly, but that introduces circular references which are + # difficult to break if things go wrong in the decoder... + # (believe me, I've tried ;-) + + self.mode = self.png.im_mode + self.size = self.png.im_size + self.info = self.png.im_info + self.text = self.png.im_text # experimental + self.tile = self.png.im_tile + + if self.png.im_palette: + rawmode, data = self.png.im_palette + self.palette = ImagePalette.raw(rawmode, data) + + self.__idat = len # used by load_read() + + + def verify(self): + "Verify PNG file" + + if self.fp is None: + raise RuntimeError("verify must be called directly after open") + + # back up to beginning of IDAT block + self.fp.seek(self.tile[0][2] - 8) + + self.png.verify() + self.png.close() + + self.fp = None + + def load_prepare(self): + "internal: prepare to read PNG file" + + if self.info.get("interlace"): + self.decoderconfig = self.decoderconfig + (1,) + + ImageFile.ImageFile.load_prepare(self) + + def load_read(self, bytes): + "internal: read more image data" + + while self.__idat == 0: + # end of chunk, skip forward to next one + + self.fp.read(4) # CRC + + cid, pos, len = self.png.read() + + if cid not in ["IDAT", "DDAT"]: + self.png.push(cid, pos, len) + return "" + + self.__idat = len # empty chunks are allowed + + # read more data from this chunk + if bytes <= 0: + bytes = self.__idat + else: + bytes = min(bytes, self.__idat) + + self.__idat = self.__idat - bytes + + return self.fp.read(bytes) + + + def load_end(self): + "internal: finished reading image data" + + self.png.close() + self.png = None + + +# -------------------------------------------------------------------- +# PNG writer + +def o16(i): + return chr(i>>8&255) + chr(i&255) + +def o32(i): + return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255) + +_OUTMODES = { + # supported PIL modes, and corresponding rawmodes/bits/color combinations + "1": ("1", chr(1)+chr(0)), + "L;1": ("L;1", chr(1)+chr(0)), + "L;2": ("L;2", chr(2)+chr(0)), + "L;4": ("L;4", chr(4)+chr(0)), + "L": ("L", chr(8)+chr(0)), + "LA": ("LA", chr(8)+chr(4)), + "I": ("I;16B", chr(16)+chr(0)), + "P;1": ("P;1", chr(1)+chr(3)), + "P;2": ("P;2", chr(2)+chr(3)), + "P;4": ("P;4", chr(4)+chr(3)), + "P": ("P", chr(8)+chr(3)), + "RGB": ("RGB", chr(8)+chr(2)), + "RGBA":("RGBA", chr(8)+chr(6)), +} + +def putchunk(fp, cid, *data): + "Write a PNG chunk (including CRC field)" + + data = string.join(data, "") + + fp.write(o32(len(data)) + cid) + fp.write(data) + hi, lo = Image.core.crc32(data, Image.core.crc32(cid)) + fp.write(o16(hi) + o16(lo)) + +class _idat: + # wrap output from the encoder in IDAT chunks + + def __init__(self, fp, chunk): + self.fp = fp + self.chunk = chunk + def write(self, data): + self.chunk(self.fp, "IDAT", data) + +def _save(im, fp, filename, chunk=putchunk, check=0): + # save an image to disk (called by the save method) + + mode = im.mode + + if mode == "P": + + # + # attempt to minimize storage requirements for palette images + + if im.encoderinfo.has_key("bits"): + + # number of bits specified by user + n = 1 << im.encoderinfo["bits"] + + else: + + # check palette contents + n = 256 # FIXME + + if n <= 2: + bits = 1 + elif n <= 4: + bits = 2 + elif n <= 16: + bits = 4 + else: + bits = 8 + + if bits != 8: + mode = "%s;%d" % (mode, bits) + + # encoder options + if im.encoderinfo.has_key("dictionary"): + dictionary = im.encoderinfo["dictionary"] + else: + dictionary = "" + + im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary) + + # get the corresponding PNG mode + try: + rawmode, mode = _OUTMODES[mode] + except KeyError: + raise IOError, "cannot write mode %s as PNG" % mode + + if check: + return check + + # + # write minimal PNG file + + fp.write(_MAGIC) + + chunk(fp, "IHDR", + o32(im.size[0]), o32(im.size[1]), # 0: size + mode, # 8: depth/type + chr(0), # 10: compression + chr(0), # 11: filter category + chr(0)) # 12: interlace flag + + if im.mode == "P": + chunk(fp, "PLTE", im.im.getpalette("RGB")) + + if im.encoderinfo.has_key("transparency"): + if im.mode == "P": + transparency = max(0, min(255, im.encoderinfo["transparency"])) + chunk(fp, "tRNS", chr(255) * transparency + chr(0)) + elif im.mode == "L": + transparency = max(0, min(65535, im.encoderinfo["transparency"])) + chunk(fp, "tRNS", o16(transparency)) + elif im.mode == "RGB": + red, green, blue = im.encoderinfo["transparency"] + chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue)) + else: + raise IOError("cannot use transparency for this mode") + + if 0: + # FIXME: to be supported some day + chunk(fp, "gAMA", o32(int(gamma * 100000.0))) + + dpi = im.encoderinfo.get("dpi") + if dpi: + chunk(fp, "pHYs", + o32(int(dpi[0] / 0.0254 + 0.5)), + o32(int(dpi[1] / 0.0254 + 0.5)), + chr(1)) + + info = im.encoderinfo.get("pnginfo") + if info: + for cid, data in info.chunks: + chunk(fp, cid, data) + + # ICC profile writing support -- 2008-06-06 Florian Hoech + if im.info.has_key("icc_profile"): + # ICC profile + # according to PNG spec, the iCCP chunk contains: + # Profile name 1-79 bytes (character string) + # Null separator 1 byte (null character) + # Compression method 1 byte (0) + # Compressed profile n bytes (zlib with deflate compression) + try: + import ICCProfile + p = ICCProfile.ICCProfile(im.info["icc_profile"]) + name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79] + except ImportError: + name = "ICC Profile" + data = name + "\0\0" + zlib.compress(im.info["icc_profile"]) + chunk(fp, "iCCP", data) + + ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)]) + + chunk(fp, "IEND", "") + + try: + fp.flush() + except: + pass + + +# -------------------------------------------------------------------- +# PNG chunk converter + +def getchunks(im, **params): + """Return a list of PNG chunks representing this image.""" + + class collector: + data = [] + def write(self, data): + pass + def append(self, chunk): + self.data.append(chunk) + + def append(fp, cid, *data): + data = string.join(data, "") + hi, lo = Image.core.crc32(data, Image.core.crc32(cid)) + crc = o16(hi) + o16(lo) + fp.append((cid, data, crc)) + + fp = collector() + + try: + im.encoderinfo = params + _save(im, fp, None, append) + finally: + del im.encoderinfo + + return fp.data + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open("PNG", PngImageFile, _accept) +Image.register_save("PNG", _save) + +Image.register_extension("PNG", ".png") + +Image.register_mime("PNG", "image/png") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py new file mode 100755 index 00000000000..e86146c1050 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py @@ -0,0 +1,131 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PPM support for PIL +# +# History: +# 96-03-24 fl Created +# 98-03-06 fl Write RGBA images (as RGB, that is) +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.2" + +import string + +import Image, ImageFile + +# +# -------------------------------------------------------------------- + +MODES = { + # standard + "P4": "1", + "P5": "L", + "P6": "RGB", + # extensions + "P0CMYK": "CMYK", + # PIL extensions (for test purposes only) + "PyP": "P", + "PyRGBA": "RGBA", + "PyCMYK": "CMYK" +} + +def _accept(prefix): + return prefix[0] == "P" and prefix[1] in "0456y" + +## +# Image plugin for PBM, PGM, and PPM images. + +class PpmImageFile(ImageFile.ImageFile): + + format = "PPM" + format_description = "Pbmplus image" + + def _token(self, s = ""): + while 1: # read until next whitespace + c = self.fp.read(1) + if not c or c in string.whitespace: + break + s = s + c + return s + + def _open(self): + + # check magic + s = self.fp.read(1) + if s != "P": + raise SyntaxError, "not a PPM file" + mode = MODES[self._token(s)] + + if mode == "1": + self.mode = "1" + rawmode = "1;I" + else: + self.mode = rawmode = mode + + for ix in range(3): + while 1: + while 1: + s = self.fp.read(1) + if s not in string.whitespace: + break + if s != "#": + break + s = self.fp.readline() + s = int(self._token(s)) + if ix == 0: + xsize = s + elif ix == 1: + ysize = s + if mode == "1": + break + + self.size = xsize, ysize + self.tile = [("raw", + (0, 0, xsize, ysize), + self.fp.tell(), + (rawmode, 0, 1))] + + # ALTERNATIVE: load via builtin debug function + # self.im = Image.core.open_ppm(self.filename) + # self.mode = self.im.mode + # self.size = self.im.size + +# +# -------------------------------------------------------------------- + +def _save(im, fp, filename): + if im.mode == "1": + rawmode, head = "1;I", "P4" + elif im.mode == "L": + rawmode, head = "L", "P5" + elif im.mode == "RGB": + rawmode, head = "RGB", "P6" + elif im.mode == "RGBA": + rawmode, head = "RGB", "P6" + else: + raise IOError, "cannot write mode %s as PPM" % im.mode + fp.write(head + "\n%d %d\n" % im.size) + if head != "P4": + fp.write("255\n") + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))]) + + # ALTERNATIVE: save via builtin debug function + # im._dump(filename) + +# +# -------------------------------------------------------------------- + +Image.register_open("PPM", PpmImageFile, _accept) +Image.register_save("PPM", _save) + +Image.register_extension("PPM", ".pbm") +Image.register_extension("PPM", ".pgm") +Image.register_extension("PPM", ".ppm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py new file mode 100755 index 00000000000..9d1b17a3632 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py @@ -0,0 +1,291 @@ +# +# The Python Imaging Library +# $Id$ +# +# Adobe PSD 2.5/3.0 file handling +# +# History: +# 1995-09-01 fl Created +# 1997-01-03 fl Read most PSD images +# 1997-01-18 fl Fixed P and CMYK support +# 2001-10-21 fl Added seek/tell support (for layers) +# +# Copyright (c) 1997-2001 by Secret Labs AB. +# Copyright (c) 1995-2001 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.4" + +import Image, ImageFile, ImagePalette + +MODES = { + # (photoshop mode, bits) -> (pil mode, required channels) + (0, 1): ("1", 1), + (0, 8): ("L", 1), + (1, 8): ("L", 1), + (2, 8): ("P", 1), + (3, 8): ("RGB", 3), + (4, 8): ("CMYK", 4), + (7, 8): ("L", 1), # FIXME: multilayer + (8, 8): ("L", 1), # duotone + (9, 8): ("LAB", 3) +} + +# +# helpers + +def i16(c): + return ord(c[1]) + (ord(c[0])<<8) + +def i32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) + +# --------------------------------------------------------------------. +# read PSD images + +def _accept(prefix): + return prefix[:4] == "8BPS" + +## +# Image plugin for Photoshop images. + +class PsdImageFile(ImageFile.ImageFile): + + format = "PSD" + format_description = "Adobe Photoshop" + + def _open(self): + + read = self.fp.read + + # + # header + + s = read(26) + if s[:4] != "8BPS" or i16(s[4:]) != 1: + raise SyntaxError, "not a PSD file" + + psd_bits = i16(s[22:]) + psd_channels = i16(s[12:]) + psd_mode = i16(s[24:]) + + mode, channels = MODES[(psd_mode, psd_bits)] + + if channels > psd_channels: + raise IOError, "not enough channels" + + self.mode = mode + self.size = i32(s[18:]), i32(s[14:]) + + # + # color mode data + + size = i32(read(4)) + if size: + data = read(size) + if mode == "P" and size == 768: + self.palette = ImagePalette.raw("RGB;L", data) + + # + # image resources + + self.resources = [] + + size = i32(read(4)) + if size: + # load resources + end = self.fp.tell() + size + while self.fp.tell() < end: + signature = read(4) + id = i16(read(2)) + name = read(ord(read(1))) + if not (len(name) & 1): + read(1) # padding + data = read(i32(read(4))) + if (len(data) & 1): + read(1) # padding + self.resources.append((id, name, data)) + if id == 1039: # ICC profile + self.info["icc_profile"] = data + + # + # layer and mask information + + self.layers = [] + + size = i32(read(4)) + if size: + end = self.fp.tell() + size + size = i32(read(4)) + if size: + self.layers = _layerinfo(self.fp) + self.fp.seek(end) + + # + # image descriptor + + self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels) + + # keep the file open + self._fp = self.fp + self.frame = 0 + + def seek(self, layer): + # seek to given layer (1..max) + if layer == self.frame: + return + try: + if layer <= 0: + raise IndexError + name, mode, bbox, tile = self.layers[layer-1] + self.mode = mode + self.tile = tile + self.frame = layer + self.fp = self._fp + return name, bbox + except IndexError: + raise EOFError, "no such layer" + + def tell(self): + # return layer number (0=image, 1..max=layers) + return self.frame + + def load_prepare(self): + # create image memory if necessary + if not self.im or\ + self.im.mode != self.mode or self.im.size != self.size: + self.im = Image.core.fill(self.mode, self.size, 0) + # create palette (optional) + if self.mode == "P": + Image.Image.load(self) + +def _layerinfo(file): + # read layerinfo block + layers = [] + read = file.read + + for i in range(abs(i16(read(2)))): + + # bounding box + y0 = i32(read(4)); x0 = i32(read(4)) + y1 = i32(read(4)); x1 = i32(read(4)) + + # image info + info = [] + mode = [] + for i in range(i16(read(2))): + type = i16(read(2)) + if type == 65535: + m = "A" + else: + m = "RGB"[type] + mode.append(m) + size = i32(read(4)) + info.append((m, size)) + + # figure out the image mode + mode.sort() + if mode == ["R"]: + mode = "L" + elif mode == ["B", "G", "R"]: + mode = "RGB" + elif mode == ["A", "B", "G", "R"]: + mode = "RGBA" + else: + mode = None # unknown + + # skip over blend flags and extra information + filler = read(12) + name = "" + size = i32(read(4)) + combined = 0 + if size: + length = i32(read(4)) + if length: + mask_y = i32(read(4)); mask_x = i32(read(4)) + mask_h = i32(read(4)) - mask_y; mask_w = i32(read(4)) - mask_x + file.seek(length - 16, 1) + combined += length + 4 + + length = i32(read(4)) + if length: + file.seek(length, 1) + combined += length + 4 + + length = ord(read(1)) + if length: + name = read(length) + combined += length + 1 + + file.seek(size - combined, 1) + layers.append((name, mode, (x0, y0, x1, y1))) + + # get tiles + i = 0 + for name, mode, bbox in layers: + tile = [] + for m in mode: + t = _maketile(file, m, bbox, 1) + if t: + tile.extend(t) + layers[i] = name, mode, bbox, tile + i = i + 1 + + return layers + +def _maketile(file, mode, bbox, channels): + + tile = None + read = file.read + + compression = i16(read(2)) + + xsize = bbox[2] - bbox[0] + ysize = bbox[3] - bbox[1] + + offset = file.tell() + + if compression == 0: + # + # raw compression + tile = [] + for channel in range(channels): + layer = mode[channel] + if mode == "CMYK": + layer = layer + ";I" + tile.append(("raw", bbox, offset, layer)) + offset = offset + xsize*ysize + + elif compression == 1: + # + # packbits compression + i = 0 + tile = [] + bytecount = read(channels * ysize * 2) + offset = file.tell() + for channel in range(channels): + layer = mode[channel] + if mode == "CMYK": + layer = layer + ";I" + tile.append( + ("packbits", bbox, offset, layer) + ) + for y in range(ysize): + offset = offset + i16(bytecount[i:i+2]) + i = i + 2 + + file.seek(offset) + + if offset & 1: + read(1) # padding + + return tile + +# -------------------------------------------------------------------- +# registry + +Image.register_open("PSD", PsdImageFile, _accept) + +Image.register_extension("PSD", ".psd") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py new file mode 100755 index 00000000000..c65b91acaf2 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py @@ -0,0 +1,92 @@ +# +# The Python Imaging Library. +# $Id$ +# +# SGI image file handling +# +# See "The SGI Image File Format (Draft version 0.97)", Paul Haeberli. +# +# +# History: +# 1995-09-10 fl Created +# +# Copyright (c) 2008 by Karsten Hiddemann. +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1995 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.2" + + +import Image, ImageFile + + +def i16(c): + return ord(c[1]) + (ord(c[0])<<8) + +def i32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) + + +def _accept(prefix): + return i16(prefix) == 474 + +## +# Image plugin for SGI images. + +class SgiImageFile(ImageFile.ImageFile): + + format = "SGI" + format_description = "SGI Image File Format" + + def _open(self): + + # HEAD + s = self.fp.read(512) + if i16(s) != 474: + raise SyntaxError("not an SGI image file") + + # relevant header entries + compression = ord(s[2]) + + # bytes, dimension, zsize + layout = ord(s[3]), i16(s[4:]), i16(s[10:]) + + # determine mode from bytes/zsize + if layout == (1, 2, 1) or layout == (1, 1, 1): + self.mode = "L" + elif layout == (1, 3, 3): + self.mode = "RGB" + elif layout == (1, 3, 4): + self.mode = "RGBA" + else: + raise SyntaxError("unsupported SGI image mode") + + # size + self.size = i16(s[6:]), i16(s[8:]) + + + # decoder info + if compression == 0: + offset = 512 + pagesize = self.size[0]*self.size[1]*layout[0] + self.tile = [] + for layer in self.mode: + self.tile.append(("raw", (0,0)+self.size, offset, (layer,0,-1))) + offset = offset + pagesize + elif compression == 1: + self.tile = [("sgi_rle", (0,0)+self.size, 512, (self.mode, 0, -1))] + +# +# registry + +Image.register_open("SGI", SgiImageFile, _accept) + +Image.register_extension("SGI", ".bw") +Image.register_extension("SGI", ".rgb") +Image.register_extension("SGI", ".rgba") + +Image.register_extension("SGI", ".sgi") # really? diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py new file mode 100755 index 00000000000..e73d55918c8 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py @@ -0,0 +1,294 @@ +# +# The Python Imaging Library. +# +# SPIDER image file handling +# +# History: +# 2004-08-02 Created BB +# 2006-03-02 added save method +# 2006-03-13 added support for stack images +# +# Copyright (c) 2004 by Health Research Inc. (HRI) RENSSELAER, NY 12144. +# Copyright (c) 2004 by William Baxter. +# Copyright (c) 2004 by Secret Labs AB. +# Copyright (c) 2004 by Fredrik Lundh. +# + +## +# Image plugin for the Spider image format. This format is is used +# by the SPIDER software, in processing image data from electron +# microscopy and tomography. +## + +# +# SpiderImagePlugin.py +# +# The Spider image format is used by SPIDER software, in processing +# image data from electron microscopy and tomography. +# +# Spider home page: +# http://www.wadsworth.org/spider_doc/spider/docs/spider.html +# +# Details about the Spider image format: +# http://www.wadsworth.org/spider_doc/spider/docs/image_doc.html +# + +import Image, ImageFile +import os, struct, sys + +def isInt(f): + try: + i = int(f) + if f-i == 0: return 1 + else: return 0 + except: + return 0 + +iforms = [1,3,-11,-12,-21,-22] + +# There is no magic number to identify Spider files, so just check a +# series of header locations to see if they have reasonable values. +# Returns no.of bytes in the header, if it is a valid Spider header, +# otherwise returns 0 + +def isSpiderHeader(t): + h = (99,) + t # add 1 value so can use spider header index start=1 + # header values 1,2,5,12,13,22,23 should be integers + for i in [1,2,5,12,13,22,23]: + if not isInt(h[i]): return 0 + # check iform + iform = int(h[5]) + if not iform in iforms: return 0 + # check other header values + labrec = int(h[13]) # no. records in file header + labbyt = int(h[22]) # total no. of bytes in header + lenbyt = int(h[23]) # record length in bytes + #print "labrec = %d, labbyt = %d, lenbyt = %d" % (labrec,labbyt,lenbyt) + if labbyt != (labrec * lenbyt): return 0 + # looks like a valid header + return labbyt + +def isSpiderImage(filename): + fp = open(filename,'rb') + f = fp.read(92) # read 23 * 4 bytes + fp.close() + bigendian = 1 + t = struct.unpack('>23f',f) # try big-endian first + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + bigendian = 0 + t = struct.unpack('<23f',f) # little-endian + hdrlen = isSpiderHeader(t) + return hdrlen + + +class SpiderImageFile(ImageFile.ImageFile): + + format = "SPIDER" + format_description = "Spider 2D image" + + def _open(self): + # check header + n = 27 * 4 # read 27 float values + f = self.fp.read(n) + + try: + self.bigendian = 1 + t = struct.unpack('>27f',f) # try big-endian first + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + self.bigendian = 0 + t = struct.unpack('<27f',f) # little-endian + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + raise SyntaxError, "not a valid Spider file" + except struct.error: + raise SyntaxError, "not a valid Spider file" + + h = (99,) + t # add 1 value : spider header index starts at 1 + iform = int(h[5]) + if iform != 1: + raise SyntaxError, "not a Spider 2D image" + + self.size = int(h[12]), int(h[2]) # size in pixels (width, height) + self.istack = int(h[24]) + self.imgnumber = int(h[27]) + + if self.istack == 0 and self.imgnumber == 0: + # stk=0, img=0: a regular 2D image + offset = hdrlen + self.nimages = 1 + elif self.istack > 0 and self.imgnumber == 0: + # stk>0, img=0: Opening the stack for the first time + self.imgbytes = int(h[12]) * int(h[2]) * 4 + self.hdrlen = hdrlen + self.nimages = int(h[26]) + # Point to the first image in the stack + offset = hdrlen * 2 + self.imgnumber = 1 + elif self.istack == 0 and self.imgnumber > 0: + # stk=0, img>0: an image within the stack + offset = hdrlen + self.stkoffset + self.istack = 2 # So Image knows it's still a stack + else: + raise SyntaxError, "inconsistent stack header values" + + if self.bigendian: + self.rawmode = "F;32BF" + else: + self.rawmode = "F;32F" + self.mode = "F" + + self.tile = [("raw", (0, 0) + self.size, offset, + (self.rawmode, 0, 1))] + self.__fp = self.fp # FIXME: hack + + # 1st image index is zero (although SPIDER imgnumber starts at 1) + def tell(self): + if self.imgnumber < 1: + return 0 + else: + return self.imgnumber - 1 + + def seek(self, frame): + if self.istack == 0: + return + if frame >= self.nimages: + raise EOFError, "attempt to seek past end of file" + self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes) + self.fp = self.__fp + self.fp.seek(self.stkoffset) + self._open() + + # returns a byte image after rescaling to 0..255 + def convert2byte(self, depth=255): + (min, max) = self.getextrema() + m = 1 + if max != min: + m = depth / (max-min) + b = -m * min + return self.point(lambda i, m=m, b=b: i * m + b).convert("L") + + # returns a ImageTk.PhotoImage object, after rescaling to 0..255 + def tkPhotoImage(self): + import ImageTk + return ImageTk.PhotoImage(self.convert2byte(), palette=256) + +# -------------------------------------------------------------------- +# Image series + +# given a list of filenames, return a list of images +def loadImageSeries(filelist=None): + " create a list of Image.images for use in montage " + if filelist == None or len(filelist) < 1: + return + + imglist = [] + for img in filelist: + if not os.path.exists(img): + print "unable to find %s" % img + continue + try: + im = Image.open(img).convert2byte() + except: + if not isSpiderImage(img): + print img + " is not a Spider image file" + continue + im.info['filename'] = img + imglist.append(im) + return imglist + +# -------------------------------------------------------------------- +# For saving images in Spider format + +def makeSpiderHeader(im): + nsam,nrow = im.size + lenbyt = nsam * 4 # There are labrec records in the header + labrec = 1024 / lenbyt + if 1024%lenbyt != 0: labrec += 1 + labbyt = labrec * lenbyt + hdr = [] + nvalues = labbyt / 4 + for i in range(nvalues): + hdr.append(0.0) + + if len(hdr) < 23: + return [] + + # NB these are Fortran indices + hdr[1] = 1.0 # nslice (=1 for an image) + hdr[2] = float(nrow) # number of rows per slice + hdr[5] = 1.0 # iform for 2D image + hdr[12] = float(nsam) # number of pixels per line + hdr[13] = float(labrec) # number of records in file header + hdr[22] = float(labbyt) # total number of bytes in header + hdr[23] = float(lenbyt) # record length in bytes + + # adjust for Fortran indexing + hdr = hdr[1:] + hdr.append(0.0) + # pack binary data into a string + hdrstr = [] + for v in hdr: + hdrstr.append(struct.pack('f',v)) + return hdrstr + +def _save(im, fp, filename): + if im.mode[0] != "F": + im = im.convert('F') + + hdr = makeSpiderHeader(im) + if len(hdr) < 256: + raise IOError, "Error creating Spider header" + + # write the SPIDER header + try: + fp = open(filename, 'wb') + except: + raise IOError, "Unable to open %s for writing" % filename + fp.writelines(hdr) + + rawmode = "F;32NF" #32-bit native floating point + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode,0,1))]) + + fp.close() + +def _save_spider(im, fp, filename): + # get the filename extension and register it with Image + fn, ext = os.path.splitext(filename) + Image.register_extension("SPIDER", ext) + _save(im, fp, filename) + +# -------------------------------------------------------------------- + +Image.register_open("SPIDER", SpiderImageFile) +Image.register_save("SPIDER", _save_spider) + +if __name__ == "__main__": + + if not sys.argv[1:]: + print "Syntax: python SpiderImagePlugin.py Spiderimage [outfile]" + sys.exit() + + filename = sys.argv[1] + if not isSpiderImage(filename): + print "input image must be in Spider format" + sys.exit() + + outfile = "" + if len(sys.argv[1:]) > 1: + outfile = sys.argv[2] + + im = Image.open(filename) + print "image: " + str(im) + print "format: " + str(im.format) + print "size: " + str(im.size) + print "mode: " + str(im.mode) + print "max, min: ", + print im.getextrema() + + if outfile != "": + # perform some image operation + im = im.transpose(Image.FLIP_LEFT_RIGHT) + print "saving a flipped version of %s as %s " % (os.path.basename(filename), outfile) + im.save(outfile, "SPIDER") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py new file mode 100755 index 00000000000..d189562a483 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py @@ -0,0 +1,86 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Sun image file handling +# +# History: +# 1995-09-10 fl Created +# 1996-05-28 fl Fixed 32-bit alignment +# 1998-12-29 fl Import ImagePalette module +# 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault) +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1995-1996 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.3" + + +import Image, ImageFile, ImagePalette + + +def i16(c): + return ord(c[1]) + (ord(c[0])<<8) + +def i32(c): + return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) + + +def _accept(prefix): + return i32(prefix) == 0x59a66a95 + +## +# Image plugin for Sun raster files. + +class SunImageFile(ImageFile.ImageFile): + + format = "SUN" + format_description = "Sun Raster File" + + def _open(self): + + # HEAD + s = self.fp.read(32) + if i32(s) != 0x59a66a95: + raise SyntaxError, "not an SUN raster file" + + offset = 32 + + self.size = i32(s[4:8]), i32(s[8:12]) + + depth = i32(s[12:16]) + if depth == 1: + self.mode, rawmode = "1", "1;I" + elif depth == 8: + self.mode = rawmode = "L" + elif depth == 24: + self.mode, rawmode = "RGB", "BGR" + else: + raise SyntaxError, "unsupported mode" + + compression = i32(s[20:24]) + + if i32(s[24:28]) != 0: + length = i32(s[28:32]) + offset = offset + length + self.palette = ImagePalette.raw("RGB;L", self.fp.read(length)) + if self.mode == "L": + self.mode = rawmode = "P" + + stride = (((self.size[0] * depth + 7) / 8) + 3) & (~3) + + if compression == 1: + self.tile = [("raw", (0,0)+self.size, offset, (rawmode, stride))] + elif compression == 2: + self.tile = [("sun_rle", (0,0)+self.size, offset, rawmode)] + +# +# registry + +Image.register_open("SUN", SunImageFile, _accept) + +Image.register_extension("SUN", ".ras") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py new file mode 100755 index 00000000000..d5de729cd36 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py @@ -0,0 +1,57 @@ +# +# The Python Imaging Library. +# $Id$ +# +# read files from within a tar file +# +# History: +# 95-06-18 fl Created +# 96-05-28 fl Open files in binary mode +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995-96. +# +# See the README file for information on usage and redistribution. +# + +import ContainerIO +import string + +## +# A file object that provides read access to a given member of a TAR +# file. + +class TarIO(ContainerIO.ContainerIO): + + ## + # Create file object. + # + # @param tarfile Name of TAR file. + # @param file Name of member file. + + def __init__(self, tarfile, file): + + fh = open(tarfile, "rb") + + while 1: + + s = fh.read(512) + if len(s) != 512: + raise IOError, "unexpected end of tar file" + + name = s[:100] + i = string.find(name, chr(0)) + if i == 0: + raise IOError, "cannot find subfile" + if i > 0: + name = name[:i] + + size = string.atoi(s[124:136], 8) + + if file == name: + break + + fh.seek((size + 511) & (~511), 1) + + # Open region + ContainerIO.ContainerIO.__init__(self, fh, fh.tell(), size) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py new file mode 100755 index 00000000000..3375991ca9e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py @@ -0,0 +1,201 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TGA file handling +# +# History: +# 95-09-01 fl created (reads 24-bit files only) +# 97-01-04 fl support more TGA versions, including compressed images +# 98-07-04 fl fixed orientation and alpha layer bugs +# 98-09-11 fl fixed orientation for runlength decoder +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.3" + +import Image, ImageFile, ImagePalette + + +# +# -------------------------------------------------------------------- +# Read RGA file + +def i16(c): + return ord(c[0]) + (ord(c[1])<<8) + +def i32(c): + return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) + + +MODES = { + # map imagetype/depth to rawmode + (1, 8): "P", + (3, 1): "1", + (3, 8): "L", + (2, 16): "BGR;5", + (2, 24): "BGR", + (2, 32): "BGRA", +} + + +def _accept(prefix): + return prefix[0] == "\0" + +## +# Image plugin for Targa files. + +class TgaImageFile(ImageFile.ImageFile): + + format = "TGA" + format_description = "Targa" + + def _open(self): + + # process header + s = self.fp.read(18) + + id = ord(s[0]) + + colormaptype = ord(s[1]) + imagetype = ord(s[2]) + + depth = ord(s[16]) + + flags = ord(s[17]) + + self.size = i16(s[12:]), i16(s[14:]) + + # validate header fields + if id != 0 or colormaptype not in (0, 1) or\ + self.size[0] <= 0 or self.size[1] <= 0 or\ + depth not in (1, 8, 16, 24, 32): + raise SyntaxError, "not a TGA file" + + # image mode + if imagetype in (3, 11): + self.mode = "L" + if depth == 1: + self.mode = "1" # ??? + elif imagetype in (1, 9): + self.mode = "P" + elif imagetype in (2, 10): + self.mode = "RGB" + if depth == 32: + self.mode = "RGBA" + else: + raise SyntaxError, "unknown TGA mode" + + # orientation + orientation = flags & 0x30 + if orientation == 0x20: + orientation = 1 + elif not orientation: + orientation = -1 + else: + raise SyntaxError, "unknown TGA orientation" + + self.info["orientation"] = orientation + + if imagetype & 8: + self.info["compression"] = "tga_rle" + + if colormaptype: + # read palette + start, size, mapdepth = i16(s[3:]), i16(s[5:]), i16(s[7:]) + if mapdepth == 16: + self.palette = ImagePalette.raw("BGR;16", + "\0"*2*start + self.fp.read(2*size)) + elif mapdepth == 24: + self.palette = ImagePalette.raw("BGR", + "\0"*3*start + self.fp.read(3*size)) + elif mapdepth == 32: + self.palette = ImagePalette.raw("BGRA", + "\0"*4*start + self.fp.read(4*size)) + + # setup tile descriptor + try: + rawmode = MODES[(imagetype&7, depth)] + if imagetype & 8: + # compressed + self.tile = [("tga_rle", (0, 0)+self.size, + self.fp.tell(), (rawmode, orientation, depth))] + else: + self.tile = [("raw", (0, 0)+self.size, + self.fp.tell(), (rawmode, 0, orientation))] + except KeyError: + pass # cannot decode + +# +# -------------------------------------------------------------------- +# Write TGA file + +def o16(i): + return chr(i&255) + chr(i>>8&255) + +def o32(i): + return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) + +SAVE = { + "1": ("1", 1, 0, 3), + "L": ("L", 8, 0, 3), + "P": ("P", 8, 1, 1), + "RGB": ("BGR", 24, 0, 2), + "RGBA": ("BGRA", 32, 0, 2), +} + +def _save(im, fp, filename, check=0): + + try: + rawmode, bits, colormaptype, imagetype = SAVE[im.mode] + except KeyError: + raise IOError("cannot write mode %s as TGA" % im.mode) + + if check: + return check + + if colormaptype: + colormapfirst, colormaplength, colormapentry = 0, 256, 24 + else: + colormapfirst, colormaplength, colormapentry = 0, 0, 0 + + if im.mode == "RGBA": + flags = 8 + else: + flags = 0 + + orientation = im.info.get("orientation", -1) + if orientation > 0: + flags = flags | 0x20 + + fp.write("\000" + + chr(colormaptype) + + chr(imagetype) + + o16(colormapfirst) + + o16(colormaplength) + + chr(colormapentry) + + o16(0) + + o16(0) + + o16(im.size[0]) + + o16(im.size[1]) + + chr(bits) + + chr(flags)) + + if colormaptype: + fp.write(im.im.getpalette("RGB", "BGR")) + + ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, orientation))]) + +# +# -------------------------------------------------------------------- +# Registry + +Image.register_open("TGA", TgaImageFile, _accept) +Image.register_save("TGA", _save) + +Image.register_extension("TGA", ".tga") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py new file mode 100755 index 00000000000..8a0fde9cd86 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py @@ -0,0 +1,860 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TIFF file handling +# +# TIFF is a flexible, if somewhat aged, image file format originally +# defined by Aldus. Although TIFF supports a wide variety of pixel +# layouts and compression methods, the name doesn't really stand for +# "thousands of incompatible file formats," it just feels that way. +# +# To read TIFF data from a stream, the stream must be seekable. For +# progressive decoding, make sure to use TIFF files where the tag +# directory is placed first in the file. +# +# History: +# 1995-09-01 fl Created +# 1996-05-04 fl Handle JPEGTABLES tag +# 1996-05-18 fl Fixed COLORMAP support +# 1997-01-05 fl Fixed PREDICTOR support +# 1997-08-27 fl Added support for rational tags (from Perry Stoll) +# 1998-01-10 fl Fixed seek/tell (from Jan Blom) +# 1998-07-15 fl Use private names for internal variables +# 1999-06-13 fl Rewritten for PIL 1.0 (1.0) +# 2000-10-11 fl Additional fixes for Python 2.0 (1.1) +# 2001-04-17 fl Fixed rewind support (seek to frame 0) (1.2) +# 2001-05-12 fl Added write support for more tags (from Greg Couch) (1.3) +# 2001-12-18 fl Added workaround for broken Matrox library +# 2002-01-18 fl Don't mess up if photometric tag is missing (D. Alan Stewart) +# 2003-05-19 fl Check FILLORDER tag +# 2003-09-26 fl Added RGBa support +# 2004-02-24 fl Added DPI support; fixed rational write support +# 2005-02-07 fl Added workaround for broken Corel Draw 10 files +# 2006-01-09 fl Added support for float/double tags (from Russell Nelson) +# +# Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +__version__ = "1.3.5" + +import Image, ImageFile +import ImagePalette + +import array, string, sys + +II = "II" # little-endian (intel-style) +MM = "MM" # big-endian (motorola-style) + +try: + if sys.byteorder == "little": + native_prefix = II + else: + native_prefix = MM +except AttributeError: + if ord(array.array("i",[1]).tostring()[0]): + native_prefix = II + else: + native_prefix = MM + +# +# -------------------------------------------------------------------- +# Read TIFF files + +def il16(c,o=0): + return ord(c[o]) + (ord(c[o+1])<<8) +def il32(c,o=0): + return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24) +def ol16(i): + return chr(i&255) + chr(i>>8&255) +def ol32(i): + return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) + +def ib16(c,o=0): + return ord(c[o+1]) + (ord(c[o])<<8) +def ib32(c,o=0): + return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24) +def ob16(i): + return chr(i>>8&255) + chr(i&255) +def ob32(i): + return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255) + +# a few tag names, just to make the code below a bit more readable +IMAGEWIDTH = 256 +IMAGELENGTH = 257 +BITSPERSAMPLE = 258 +COMPRESSION = 259 +PHOTOMETRIC_INTERPRETATION = 262 +FILLORDER = 266 +IMAGEDESCRIPTION = 270 +STRIPOFFSETS = 273 +SAMPLESPERPIXEL = 277 +ROWSPERSTRIP = 278 +STRIPBYTECOUNTS = 279 +X_RESOLUTION = 282 +Y_RESOLUTION = 283 +PLANAR_CONFIGURATION = 284 +RESOLUTION_UNIT = 296 +SOFTWARE = 305 +DATE_TIME = 306 +ARTIST = 315 +PREDICTOR = 317 +COLORMAP = 320 +TILEOFFSETS = 324 +EXTRASAMPLES = 338 +SAMPLEFORMAT = 339 +JPEGTABLES = 347 +COPYRIGHT = 33432 +IPTC_NAA_CHUNK = 33723 # newsphoto properties +PHOTOSHOP_CHUNK = 34377 # photoshop properties +ICCPROFILE = 34675 +EXIFIFD = 34665 +XMP = 700 + +COMPRESSION_INFO = { + # Compression => pil compression name + 1: "raw", + 2: "tiff_ccitt", + 3: "group3", + 4: "group4", + 5: "tiff_lzw", + 6: "tiff_jpeg", # obsolete + 7: "jpeg", + 32771: "tiff_raw_16", # 16-bit padding + 32773: "packbits" +} + +OPEN_INFO = { + # (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample, + # ExtraSamples) => mode, rawmode + (II, 0, 1, 1, (1,), ()): ("1", "1;I"), + (II, 0, 1, 2, (1,), ()): ("1", "1;IR"), + (II, 0, 1, 1, (8,), ()): ("L", "L;I"), + (II, 0, 1, 2, (8,), ()): ("L", "L;IR"), + (II, 1, 1, 1, (1,), ()): ("1", "1"), + (II, 1, 1, 2, (1,), ()): ("1", "1;R"), + (II, 1, 1, 1, (8,), ()): ("L", "L"), + (II, 1, 1, 1, (8,8), (2,)): ("LA", "LA"), + (II, 1, 1, 2, (8,), ()): ("L", "L;R"), + (II, 1, 1, 1, (16,), ()): ("I;16", "I;16"), + (II, 1, 2, 1, (16,), ()): ("I;16S", "I;16S"), + (II, 1, 2, 1, (32,), ()): ("I", "I;32S"), + (II, 1, 3, 1, (32,), ()): ("F", "F;32F"), + (II, 2, 1, 1, (8,8,8), ()): ("RGB", "RGB"), + (II, 2, 1, 2, (8,8,8), ()): ("RGB", "RGB;R"), + (II, 2, 1, 1, (8,8,8,8), (0,)): ("RGBX", "RGBX"), + (II, 2, 1, 1, (8,8,8,8), (1,)): ("RGBA", "RGBa"), + (II, 2, 1, 1, (8,8,8,8), (2,)): ("RGBA", "RGBA"), + (II, 2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10 + (II, 3, 1, 1, (1,), ()): ("P", "P;1"), + (II, 3, 1, 2, (1,), ()): ("P", "P;1R"), + (II, 3, 1, 1, (2,), ()): ("P", "P;2"), + (II, 3, 1, 2, (2,), ()): ("P", "P;2R"), + (II, 3, 1, 1, (4,), ()): ("P", "P;4"), + (II, 3, 1, 2, (4,), ()): ("P", "P;4R"), + (II, 3, 1, 1, (8,), ()): ("P", "P"), + (II, 3, 1, 1, (8,8), (2,)): ("PA", "PA"), + (II, 3, 1, 2, (8,), ()): ("P", "P;R"), + (II, 5, 1, 1, (8,8,8,8), ()): ("CMYK", "CMYK"), + (II, 6, 1, 1, (8,8,8), ()): ("YCbCr", "YCbCr"), + (II, 8, 1, 1, (8,8,8), ()): ("LAB", "LAB"), + + (MM, 0, 1, 1, (1,), ()): ("1", "1;I"), + (MM, 0, 1, 2, (1,), ()): ("1", "1;IR"), + (MM, 0, 1, 1, (8,), ()): ("L", "L;I"), + (MM, 0, 1, 2, (8,), ()): ("L", "L;IR"), + (MM, 1, 1, 1, (1,), ()): ("1", "1"), + (MM, 1, 1, 2, (1,), ()): ("1", "1;R"), + (MM, 1, 1, 1, (8,), ()): ("L", "L"), + (MM, 1, 1, 1, (8,8), (2,)): ("LA", "LA"), + (MM, 1, 1, 2, (8,), ()): ("L", "L;R"), + (MM, 1, 1, 1, (16,), ()): ("I;16B", "I;16B"), + (MM, 1, 2, 1, (16,), ()): ("I;16BS", "I;16BS"), + (MM, 1, 2, 1, (32,), ()): ("I;32BS", "I;32BS"), + (MM, 1, 3, 1, (32,), ()): ("F;32BF", "F;32BF"), + (MM, 2, 1, 1, (8,8,8), ()): ("RGB", "RGB"), + (MM, 2, 1, 2, (8,8,8), ()): ("RGB", "RGB;R"), + (MM, 2, 1, 1, (8,8,8,8), (0,)): ("RGBX", "RGBX"), + (MM, 2, 1, 1, (8,8,8,8), (1,)): ("RGBA", "RGBa"), + (MM, 2, 1, 1, (8,8,8,8), (2,)): ("RGBA", "RGBA"), + (MM, 2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10 + (MM, 3, 1, 1, (1,), ()): ("P", "P;1"), + (MM, 3, 1, 2, (1,), ()): ("P", "P;1R"), + (MM, 3, 1, 1, (2,), ()): ("P", "P;2"), + (MM, 3, 1, 2, (2,), ()): ("P", "P;2R"), + (MM, 3, 1, 1, (4,), ()): ("P", "P;4"), + (MM, 3, 1, 2, (4,), ()): ("P", "P;4R"), + (MM, 3, 1, 1, (8,), ()): ("P", "P"), + (MM, 3, 1, 1, (8,8), (2,)): ("PA", "PA"), + (MM, 3, 1, 2, (8,), ()): ("P", "P;R"), + (MM, 5, 1, 1, (8,8,8,8), ()): ("CMYK", "CMYK"), + (MM, 6, 1, 1, (8,8,8), ()): ("YCbCr", "YCbCr"), + (MM, 8, 1, 1, (8,8,8), ()): ("LAB", "LAB"), + +} + +PREFIXES = ["MM\000\052", "II\052\000", "II\xBC\000"] + +def _accept(prefix): + return prefix[:4] in PREFIXES + +## +# Wrapper for TIFF IFDs. + +class ImageFileDirectory: + + # represents a TIFF tag directory. to speed things up, + # we don't decode tags unless they're asked for. + + def __init__(self, prefix): + self.prefix = prefix[:2] + if self.prefix == MM: + self.i16, self.i32 = ib16, ib32 + self.o16, self.o32 = ob16, ob32 + elif self.prefix == II: + self.i16, self.i32 = il16, il32 + self.o16, self.o32 = ol16, ol32 + else: + raise SyntaxError("not a TIFF IFD") + self.reset() + + def reset(self): + self.tags = {} + self.tagdata = {} + self.tagtype = {} # added 2008-06-05 by Florian Hoech + self.next = None + + # dictionary API (sort of) + + def keys(self): + return self.tagdata.keys() + self.tags.keys() + + def items(self): + items = self.tags.items() + for tag in self.tagdata.keys(): + items.append((tag, self[tag])) + return items + + def __len__(self): + return len(self.tagdata) + len(self.tags) + + def __getitem__(self, tag): + try: + return self.tags[tag] + except KeyError: + type, data = self.tagdata[tag] # unpack on the fly + size, handler = self.load_dispatch[type] + self.tags[tag] = data = handler(self, data) + del self.tagdata[tag] + return data + + def get(self, tag, default=None): + try: + return self[tag] + except KeyError: + return default + + def getscalar(self, tag, default=None): + try: + value = self[tag] + if len(value) != 1: + if tag == SAMPLEFORMAT: + # work around broken (?) matrox library + # (from Ted Wright, via Bob Klimek) + raise KeyError # use default + raise ValueError, "not a scalar" + return value[0] + except KeyError: + if default is None: + raise + return default + + def has_key(self, tag): + return self.tags.has_key(tag) or self.tagdata.has_key(tag) + + def __setitem__(self, tag, value): + if type(value) is not type(()): + value = (value,) + self.tags[tag] = value + + # load primitives + + load_dispatch = {} + + def load_byte(self, data): + l = [] + for i in range(len(data)): + l.append(ord(data[i])) + return tuple(l) + load_dispatch[1] = (1, load_byte) + + def load_string(self, data): + if data[-1:] == '\0': + data = data[:-1] + return data + load_dispatch[2] = (1, load_string) + + def load_short(self, data): + l = [] + for i in range(0, len(data), 2): + l.append(self.i16(data, i)) + return tuple(l) + load_dispatch[3] = (2, load_short) + + def load_long(self, data): + l = [] + for i in range(0, len(data), 4): + l.append(self.i32(data, i)) + return tuple(l) + load_dispatch[4] = (4, load_long) + + def load_rational(self, data): + l = [] + for i in range(0, len(data), 8): + l.append((self.i32(data, i), self.i32(data, i+4))) + return tuple(l) + load_dispatch[5] = (8, load_rational) + + def load_float(self, data): + a = array.array("f", data) + if self.prefix != native_prefix: + a.byteswap() + return tuple(a) + load_dispatch[11] = (4, load_float) + + def load_double(self, data): + a = array.array("d", data) + if self.prefix != native_prefix: + a.byteswap() + return tuple(a) + load_dispatch[12] = (8, load_double) + + def load_undefined(self, data): + # Untyped data + return data + load_dispatch[7] = (1, load_undefined) + + def load(self, fp): + # load tag dictionary + + self.reset() + + i16 = self.i16 + i32 = self.i32 + + for i in range(i16(fp.read(2))): + + ifd = fp.read(12) + + tag, typ = i16(ifd), i16(ifd, 2) + + if Image.DEBUG: + import TiffTags + tagname = TiffTags.TAGS.get(tag, "unknown") + typname = TiffTags.TYPES.get(typ, "unknown") + print "tag: %s (%d)" % (tagname, tag), + print "- type: %s (%d)" % (typname, typ), + + try: + dispatch = self.load_dispatch[typ] + except KeyError: + if Image.DEBUG: + print "- unsupported type", typ + continue # ignore unsupported type + + size, handler = dispatch + + size = size * i32(ifd, 4) + + # Get and expand tag value + if size > 4: + here = fp.tell() + fp.seek(i32(ifd, 8)) + data = ImageFile._safe_read(fp, size) + fp.seek(here) + else: + data = ifd[8:8+size] + + if len(data) != size: + raise IOError, "not enough data" + + self.tagdata[tag] = typ, data + self.tagtype[tag] = typ + + if Image.DEBUG: + if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP): + print "- value: " % size + else: + print "- value:", self[tag] + + self.next = i32(fp.read(4)) + + # save primitives + + def save(self, fp): + + o16 = self.o16 + o32 = self.o32 + + fp.write(o16(len(self.tags))) + + # always write in ascending tag order + tags = self.tags.items() + tags.sort() + + directory = [] + append = directory.append + + offset = fp.tell() + len(self.tags) * 12 + 4 + + stripoffsets = None + + # pass 1: convert tags to binary format + for tag, value in tags: + + typ = None + + if self.tagtype.has_key(tag): + typ = self.tagtype[tag] + + if typ == 1: + # byte data + data = value = string.join(map(chr, value), "") + elif typ == 7: + # untyped data + data = value = string.join(value, "") + elif type(value[0]) is type(""): + # string data + typ = 2 + data = value = string.join(value, "\0") + "\0" + else: + # integer data + if tag == STRIPOFFSETS: + stripoffsets = len(directory) + typ = 4 # to avoid catch-22 + elif tag in (X_RESOLUTION, Y_RESOLUTION): + # identify rational data fields + typ = 5 + elif not typ: + typ = 3 + for v in value: + if v >= 65536: + typ = 4 + if typ == 3: + data = string.join(map(o16, value), "") + else: + data = string.join(map(o32, value), "") + + if Image.DEBUG: + import TiffTags + tagname = TiffTags.TAGS.get(tag, "unknown") + typname = TiffTags.TYPES.get(typ, "unknown") + print "save: %s (%d)" % (tagname, tag), + print "- type: %s (%d)" % (typname, typ), + if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP): + size = len(data) + print "- value: " % size + else: + print "- value:", value + + # figure out if data fits into the directory + if len(data) == 4: + append((tag, typ, len(value), data, "")) + elif len(data) < 4: + append((tag, typ, len(value), data + (4-len(data))*"\0", "")) + else: + count = len(value) + if typ == 5: + count = count / 2 # adjust for rational data field + append((tag, typ, count, o32(offset), data)) + offset = offset + len(data) + if offset & 1: + offset = offset + 1 # word padding + + # update strip offset data to point beyond auxiliary data + if stripoffsets is not None: + tag, typ, count, value, data = directory[stripoffsets] + assert not data, "multistrip support not yet implemented" + value = o32(self.i32(value) + offset) + directory[stripoffsets] = tag, typ, count, value, data + + # pass 2: write directory to file + for tag, typ, count, value, data in directory: + if Image.DEBUG > 1: + print tag, typ, count, repr(value), repr(data) + fp.write(o16(tag) + o16(typ) + o32(count) + value) + + # -- overwrite here for multi-page -- + fp.write("\0\0\0\0") # end of directory + + # pass 3: write auxiliary data to file + for tag, typ, count, value, data in directory: + fp.write(data) + if len(data) & 1: + fp.write("\0") + + return offset + +## +# Image plugin for TIFF files. + +class TiffImageFile(ImageFile.ImageFile): + + format = "TIFF" + format_description = "Adobe TIFF" + + def _open(self): + "Open the first image in a TIFF file" + + # Header + ifh = self.fp.read(8) + + if ifh[:4] not in PREFIXES: + raise SyntaxError, "not a TIFF file" + + # image file directory (tag dictionary) + self.tag = self.ifd = ImageFileDirectory(ifh[:2]) + + # setup frame pointers + self.__first = self.__next = self.ifd.i32(ifh, 4) + self.__frame = -1 + self.__fp = self.fp + + # and load the first frame + self._seek(0) + + def seek(self, frame): + "Select a given frame as current image" + + if frame < 0: + frame = 0 + self._seek(frame) + + def tell(self): + "Return the current frame number" + + return self._tell() + + def _seek(self, frame): + + self.fp = self.__fp + if frame < self.__frame: + # rewind file + self.__frame = -1 + self.__next = self.__first + while self.__frame < frame: + if not self.__next: + raise EOFError, "no more images in TIFF file" + self.fp.seek(self.__next) + self.tag.load(self.fp) + self.__next = self.tag.next + self.__frame = self.__frame + 1 + self._setup() + + def _tell(self): + + return self.__frame + + def _decoder(self, rawmode, layer): + "Setup decoder contexts" + + args = None + if rawmode == "RGB" and self._planar_configuration == 2: + rawmode = rawmode[layer] + compression = self._compression + if compression == "raw": + args = (rawmode, 0, 1) + elif compression == "jpeg": + args = rawmode, "" + if self.tag.has_key(JPEGTABLES): + # Hack to handle abbreviated JPEG headers + self.tile_prefix = self.tag[JPEGTABLES] + elif compression == "packbits": + args = rawmode + elif compression == "tiff_lzw": + args = rawmode + if self.tag.has_key(317): + # Section 14: Differencing Predictor + self.decoderconfig = (self.tag[PREDICTOR][0],) + + if self.tag.has_key(ICCPROFILE): + self.info['icc_profile'] = self.tag[ICCPROFILE] + + return args + + def _setup(self): + "Setup this image object based on current tags" + + if self.tag.has_key(0xBC01): + raise IOError, "Windows Media Photo files not yet supported" + + getscalar = self.tag.getscalar + + # extract relevant tags + self._compression = COMPRESSION_INFO[getscalar(COMPRESSION, 1)] + self._planar_configuration = getscalar(PLANAR_CONFIGURATION, 1) + + # photometric is a required tag, but not everyone is reading + # the specification + photo = getscalar(PHOTOMETRIC_INTERPRETATION, 0) + + fillorder = getscalar(FILLORDER, 1) + + if Image.DEBUG: + print "*** Summary ***" + print "- compression:", self._compression + print "- photometric_interpretation:", photo + print "- planar_configuration:", self._planar_configuration + print "- fill_order:", fillorder + + # size + xsize = getscalar(IMAGEWIDTH) + ysize = getscalar(IMAGELENGTH) + self.size = xsize, ysize + + if Image.DEBUG: + print "- size:", self.size + + format = getscalar(SAMPLEFORMAT, 1) + + # mode: check photometric interpretation and bits per pixel + key = ( + self.tag.prefix, photo, format, fillorder, + self.tag.get(BITSPERSAMPLE, (1,)), + self.tag.get(EXTRASAMPLES, ()) + ) + if Image.DEBUG: + print "format key:", key + try: + self.mode, rawmode = OPEN_INFO[key] + except KeyError: + if Image.DEBUG: + print "- unsupported format" + raise SyntaxError, "unknown pixel mode" + + if Image.DEBUG: + print "- raw mode:", rawmode + print "- pil mode:", self.mode + + self.info["compression"] = self._compression + + xres = getscalar(X_RESOLUTION, (1, 1)) + yres = getscalar(Y_RESOLUTION, (1, 1)) + + if xres and yres: + xres = xres[0] / (xres[1] or 1) + yres = yres[0] / (yres[1] or 1) + resunit = getscalar(RESOLUTION_UNIT, 1) + if resunit == 2: # dots per inch + self.info["dpi"] = xres, yres + elif resunit == 3: # dots per centimeter. convert to dpi + self.info["dpi"] = xres * 2.54, yres * 2.54 + else: # No absolute unit of measurement + self.info["resolution"] = xres, yres + + # build tile descriptors + x = y = l = 0 + self.tile = [] + if self.tag.has_key(STRIPOFFSETS): + # striped image + h = getscalar(ROWSPERSTRIP, ysize) + w = self.size[0] + a = None + for o in self.tag[STRIPOFFSETS]: + if not a: + a = self._decoder(rawmode, l) + self.tile.append( + (self._compression, + (0, min(y, ysize), w, min(y+h, ysize)), + o, a)) + y = y + h + if y >= self.size[1]: + x = y = 0 + l = l + 1 + a = None + elif self.tag.has_key(TILEOFFSETS): + # tiled image + w = getscalar(322) + h = getscalar(323) + a = None + for o in self.tag[TILEOFFSETS]: + if not a: + a = self._decoder(rawmode, l) + # FIXME: this doesn't work if the image size + # is not a multiple of the tile size... + self.tile.append( + (self._compression, + (x, y, x+w, y+h), + o, a)) + x = x + w + if x >= self.size[0]: + x, y = 0, y + h + if y >= self.size[1]: + x = y = 0 + l = l + 1 + a = None + else: + if Image.DEBUG: + print "- unsupported data organization" + raise SyntaxError("unknown data organization") + + # fixup palette descriptor + + if self.mode == "P": + palette = map(lambda a: chr(a / 256), self.tag[COLORMAP]) + self.palette = ImagePalette.raw("RGB;L", string.join(palette, "")) +# +# -------------------------------------------------------------------- +# Write TIFF files + +# little endian is default except for image modes with explict big endian byte-order + +SAVE_INFO = { + # mode => rawmode, byteorder, photometrics, sampleformat, bitspersample, extra + "1": ("1", II, 1, 1, (1,), None), + "L": ("L", II, 1, 1, (8,), None), + "LA": ("LA", II, 1, 1, (8,8), 2), + "P": ("P", II, 3, 1, (8,), None), + "PA": ("PA", II, 3, 1, (8,8), 2), + "I": ("I;32S", II, 1, 2, (32,), None), + "I;16": ("I;16", II, 1, 1, (16,), None), + "I;16S": ("I;16S", II, 1, 2, (16,), None), + "F": ("F;32F", II, 1, 3, (32,), None), + "RGB": ("RGB", II, 2, 1, (8,8,8), None), + "RGBX": ("RGBX", II, 2, 1, (8,8,8,8), 0), + "RGBA": ("RGBA", II, 2, 1, (8,8,8,8), 2), + "CMYK": ("CMYK", II, 5, 1, (8,8,8,8), None), + "YCbCr": ("YCbCr", II, 6, 1, (8,8,8), None), + "LAB": ("LAB", II, 8, 1, (8,8,8), None), + + "I;32BS": ("I;32BS", MM, 1, 2, (32,), None), + "I;16B": ("I;16B", MM, 1, 1, (16,), None), + "I;16BS": ("I;16BS", MM, 1, 2, (16,), None), + "F;32BF": ("F;32BF", MM, 1, 3, (32,), None), +} + +def _cvt_res(value): + # convert value to TIFF rational number -- (numerator, denominator) + if type(value) in (type([]), type(())): + assert(len(value) % 2 == 0) + return value + if type(value) == type(1): + return (value, 1) + value = float(value) + return (int(value * 65536), 65536) + +def _save(im, fp, filename): + + try: + rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] + except KeyError: + raise IOError, "cannot write mode %s as TIFF" % im.mode + + ifd = ImageFileDirectory(prefix) + + # -- multi-page -- skip TIFF header on subsequent pages + if fp.tell() == 0: + # tiff header (write via IFD to get everything right) + # PIL always starts the first IFD at offset 8 + fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8)) + + ifd[IMAGEWIDTH] = im.size[0] + ifd[IMAGELENGTH] = im.size[1] + + # additions written by Greg Couch, gregc@cgl.ucsf.edu + # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com + if hasattr(im, 'tag'): + # preserve tags from original TIFF image file + for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION): + if im.tag.tagdata.has_key(key): + ifd[key] = im.tag.tagdata.get(key) + # preserve some more tags from original TIFF image file + # -- 2008-06-06 Florian Hoech + ifd.tagtype = im.tag.tagtype + for key in (IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, XMP): + if im.tag.has_key(key): + ifd[key] = im.tag[key] + # preserve ICC profile (should also work when saving other formats + # which support profiles as TIFF) -- 2008-06-06 Florian Hoech + if im.info.has_key("icc_profile"): + ifd[ICCPROFILE] = im.info["icc_profile"] + if im.encoderinfo.has_key("description"): + ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"] + if im.encoderinfo.has_key("resolution"): + ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \ + = _cvt_res(im.encoderinfo["resolution"]) + if im.encoderinfo.has_key("x resolution"): + ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"]) + if im.encoderinfo.has_key("y resolution"): + ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"]) + if im.encoderinfo.has_key("resolution unit"): + unit = im.encoderinfo["resolution unit"] + if unit == "inch": + ifd[RESOLUTION_UNIT] = 2 + elif unit == "cm" or unit == "centimeter": + ifd[RESOLUTION_UNIT] = 3 + else: + ifd[RESOLUTION_UNIT] = 1 + if im.encoderinfo.has_key("software"): + ifd[SOFTWARE] = im.encoderinfo["software"] + if im.encoderinfo.has_key("date time"): + ifd[DATE_TIME] = im.encoderinfo["date time"] + if im.encoderinfo.has_key("artist"): + ifd[ARTIST] = im.encoderinfo["artist"] + if im.encoderinfo.has_key("copyright"): + ifd[COPYRIGHT] = im.encoderinfo["copyright"] + + dpi = im.encoderinfo.get("dpi") + if dpi: + ifd[RESOLUTION_UNIT] = 2 + ifd[X_RESOLUTION] = _cvt_res(dpi[0]) + ifd[Y_RESOLUTION] = _cvt_res(dpi[1]) + + if bits != (1,): + ifd[BITSPERSAMPLE] = bits + if len(bits) != 1: + ifd[SAMPLESPERPIXEL] = len(bits) + if extra is not None: + ifd[EXTRASAMPLES] = extra + if format != 1: + ifd[SAMPLEFORMAT] = format + + ifd[PHOTOMETRIC_INTERPRETATION] = photo + + if im.mode == "P": + lut = im.im.getpalette("RGB", "RGB;L") + ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut)) + + # data orientation + stride = len(bits) * ((im.size[0]*bits[0]+7)/8) + ifd[ROWSPERSTRIP] = im.size[1] + ifd[STRIPBYTECOUNTS] = stride * im.size[1] + ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer + ifd[COMPRESSION] = 1 # no compression + + offset = ifd.save(fp) + + ImageFile._save(im, fp, [ + ("raw", (0,0)+im.size, offset, (rawmode, stride, 1)) + ]) + + + # -- helper for multi-page save -- + if im.encoderinfo.has_key("_debug_multipage"): + #just to access o32 and o16 (using correct byte order) + im._debug_multipage = ifd + +# +# -------------------------------------------------------------------- +# Register + +Image.register_open("TIFF", TiffImageFile, _accept) +Image.register_save("TIFF", _save) + +Image.register_extension("TIFF", ".tif") +Image.register_extension("TIFF", ".tiff") + +Image.register_mime("TIFF", "image/tiff") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py new file mode 100755 index 00000000000..33fd209411c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py @@ -0,0 +1,209 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TIFF tags +# +# This module provides clear-text names for various well-known +# TIFF tags. the TIFF codec works just fine without it. +# +# Copyright (c) Secret Labs AB 1999. +# +# See the README file for information on usage and redistribution. +# + +## +# This module provides constants and clear-text names for various +# well-known TIFF tags. +## + +## +# Map tag numbers (or tag number, tag value tuples) to tag names. + +TAGS = { + + 254: "NewSubfileType", + 255: "SubfileType", + 256: "ImageWidth", + 257: "ImageLength", + 258: "BitsPerSample", + + 259: "Compression", + (259, 1): "Uncompressed", + (259, 2): "CCITT 1d", + (259, 3): "Group 3 Fax", + (259, 4): "Group 4 Fax", + (259, 5): "LZW", + (259, 6): "JPEG", + (259, 32773): "PackBits", + + 262: "PhotometricInterpretation", + (262, 0): "WhiteIsZero", + (262, 1): "BlackIsZero", + (262, 2): "RGB", + (262, 3): "RGB Palette", + (262, 4): "Transparency Mask", + (262, 5): "CMYK", + (262, 6): "YCbCr", + (262, 8): "CieLAB", + (262, 32803): "CFA", # TIFF/EP, Adobe DNG + (262, 32892): "LinearRaw", # Adobe DNG + + 263: "Thresholding", + 264: "CellWidth", + 265: "CellHeight", + 266: "FillOrder", + 269: "DocumentName", + + 270: "ImageDescription", + 271: "Make", + 272: "Model", + 273: "StripOffsets", + 274: "Orientation", + 277: "SamplesPerPixel", + 278: "RowsPerStrip", + 279: "StripByteCounts", + + 280: "MinSampleValue", + 281: "MaxSampleValue", + 282: "XResolution", + 283: "YResolution", + 284: "PlanarConfiguration", + (284, 1): "Contigous", + (284, 2): "Separate", + + 285: "PageName", + 286: "XPosition", + 287: "YPosition", + 288: "FreeOffsets", + 289: "FreeByteCounts", + + 290: "GrayResponseUnit", + 291: "GrayResponseCurve", + 292: "T4Options", + 293: "T6Options", + 296: "ResolutionUnit", + 297: "PageNumber", + + 301: "TransferFunction", + 305: "Software", + 306: "DateTime", + + 315: "Artist", + 316: "HostComputer", + 317: "Predictor", + 318: "WhitePoint", + 319: "PrimaryChromaticies", + + 320: "ColorMap", + 321: "HalftoneHints", + 322: "TileWidth", + 323: "TileLength", + 324: "TileOffsets", + 325: "TileByteCounts", + + 332: "InkSet", + 333: "InkNames", + 334: "NumberOfInks", + 336: "DotRange", + 337: "TargetPrinter", + 338: "ExtraSamples", + 339: "SampleFormat", + + 340: "SMinSampleValue", + 341: "SMaxSampleValue", + 342: "TransferRange", + + 347: "JPEGTables", + + # obsolete JPEG tags + 512: "JPEGProc", + 513: "JPEGInterchangeFormat", + 514: "JPEGInterchangeFormatLength", + 515: "JPEGRestartInterval", + 517: "JPEGLosslessPredictors", + 518: "JPEGPointTransforms", + 519: "JPEGQTables", + 520: "JPEGDCTables", + 521: "JPEGACTables", + + 529: "YCbCrCoefficients", + 530: "YCbCrSubSampling", + 531: "YCbCrPositioning", + 532: "ReferenceBlackWhite", + + # XMP + 700: "XMP", + + 33432: "Copyright", + + # various extensions (should check specs for "official" names) + 33723: "IptcNaaInfo", + 34377: "PhotoshopInfo", + + # Exif IFD + 34665: "ExifIFD", + + # ICC Profile + 34675: "ICCProfile", + + # Adobe DNG + 50706: "DNGVersion", + 50707: "DNGBackwardVersion", + 50708: "UniqueCameraModel", + 50709: "LocalizedCameraModel", + 50710: "CFAPlaneColor", + 50711: "CFALayout", + 50712: "LinearizationTable", + 50713: "BlackLevelRepeatDim", + 50714: "BlackLevel", + 50715: "BlackLevelDeltaH", + 50716: "BlackLevelDeltaV", + 50717: "WhiteLevel", + 50718: "DefaultScale", + 50741: "BestQualityScale", + 50719: "DefaultCropOrigin", + 50720: "DefaultCropSize", + 50778: "CalibrationIlluminant1", + 50779: "CalibrationIlluminant2", + 50721: "ColorMatrix1", + 50722: "ColorMatrix2", + 50723: "CameraCalibration1", + 50724: "CameraCalibration2", + 50725: "ReductionMatrix1", + 50726: "ReductionMatrix2", + 50727: "AnalogBalance", + 50728: "AsShotNeutral", + 50729: "AsShotWhiteXY", + 50730: "BaselineExposure", + 50731: "BaselineNoise", + 50732: "BaselineSharpness", + 50733: "BayerGreenSplit", + 50734: "LinearResponseLimit", + 50735: "CameraSerialNumber", + 50736: "LensInfo", + 50737: "ChromaBlurRadius", + 50738: "AntiAliasStrength", + 50740: "DNGPrivateData", + 50741: "MakerNoteSafety", +} + +## +# Map type numbers to type names. + +TYPES = { + + 1: "byte", + 2: "ascii", + 3: "short", + 4: "long", + 5: "rational", + 6: "signed byte", + 7: "undefined", + 8: "signed short", + 9: "signed long", + 10: "signed rational", + 11: "float", + 12: "double", + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py new file mode 100755 index 00000000000..fb8c38ab4af --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py @@ -0,0 +1,126 @@ +# -*- coding: iso-8859-1 -*- +# +# The Python Imaging Library. +# $Id$ +# +# WAL file handling +# +# History: +# 2003-04-23 fl created +# +# Copyright (c) 2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +# NOTE: This format cannot be automatically recognized, so the reader +# is not registered for use with Image.open(). To open a WEL file, use +# the WalImageFile.open() function instead. + +# This reader is based on the specification available from: +# http://www.flipcode.com/tutorials/tut_q2levels.shtml +# and has been tested with a few sample files found using google. + +import Image + +def i32(c, o=0): + return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24) + +## +# Load texture from a Quake2 WAL texture file. +#

+# By default, a Quake2 standard palette is attached to the texture. +# To override the palette, use the putpalette method. +# +# @param filename WAL file name, or an opened file handle. +# @return An image instance. + +def open(filename): + # FIXME: modify to return a WalImageFile instance instead of + # plain Image object ? + + if hasattr(filename, "read"): + fp = filename + else: + import __builtin__ + fp = __builtin__.open(filename, "rb") + + # read header fields + header = fp.read(32+24+32+12) + size = i32(header, 32), i32(header, 36) + offset = i32(header, 40) + + # load pixel data + fp.seek(offset) + + im = Image.fromstring("P", size, fp.read(size[0] * size[1])) + im.putpalette(quake2palette) + + im.format = "WAL" + im.format_description = "Quake2 Texture" + + # strings are null-terminated + im.info["name"] = header[:32].split("\0", 1)[0] + next_name = header[56:56+32].split("\0", 1)[0] + if next_name: + im.info["next_name"] = next_name + + return im + + +quake2palette = ( + # default palette taken from piffo 0.93 by Hans Hggstrm + "\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e" + "\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f" + "\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c" + "\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b" + "\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10" + "\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07" + "\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f" + "\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16" + "\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d" + "\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31" + "\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28" + "\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07" + "\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27" + "\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b" + "\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01" + "\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21" + "\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14" + "\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07" + "\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14" + "\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f" + "\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34" + "\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d" + "\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14" + "\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01" + "\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24" + "\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10" + "\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01" + "\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27" + "\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c" + "\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a" + "\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26" + "\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d" + "\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01" + "\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20" + "\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17" + "\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07" + "\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25" + "\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c" + "\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01" + "\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23" + "\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f" + "\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b" + "\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37" + "\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b" + "\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01" + "\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10" + "\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b" + "\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20" +) + +if __name__ == "__main__": + im = open("../hacks/sample.wal") + print im.info, im.mode, im.size + im.save("../out.png") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py new file mode 100755 index 00000000000..5191f1e51d5 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py @@ -0,0 +1,167 @@ +# +# The Python Imaging Library +# $Id$ +# +# WMF stub codec +# +# history: +# 1996-12-14 fl Created +# 2004-02-22 fl Turned into a stub driver +# 2004-02-23 fl Added EMF support +# +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.2" + +import Image, ImageFile + +_handler = None + +## +# Install application-specific WMF image handler. +# +# @param handler Handler object. + +def register_handler(handler): + global _handler + _handler = handler + +if hasattr(Image.core, "drawwmf"): + # install default handler (windows only) + + class WmfHandler: + + def open(self, im): + im.mode = "RGB" + self.bbox = im.info["wmf_bbox"] + + def load(self, im): + im.fp.seek(0) # rewind + return Image.fromstring( + "RGB", im.size, + Image.core.drawwmf(im.fp.read(), im.size, self.bbox), + "raw", "BGR", (im.size[0]*3 + 3) & -4, -1 + ) + + register_handler(WmfHandler()) + +# -------------------------------------------------------------------- + +def word(c, o=0): + return ord(c[o]) + (ord(c[o+1])<<8) + +def short(c, o=0): + v = ord(c[o]) + (ord(c[o+1])<<8) + if v >= 32768: + v = v - 65536 + return v + +def dword(c, o=0): + return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24) + +def long(c, o=0): + return dword(c, o) + +# +# -------------------------------------------------------------------- +# Read WMF file + +def _accept(prefix): + return ( + prefix[:6] == "\xd7\xcd\xc6\x9a\x00\x00" or + prefix[:4] == "\x01\x00\x00\x00" + ) + +## +# Image plugin for Windows metafiles. + +class WmfStubImageFile(ImageFile.StubImageFile): + + format = "WMF" + format_description = "Windows Metafile" + + def _open(self): + + # check placable header + s = self.fp.read(80) + + if s[:6] == "\xd7\xcd\xc6\x9a\x00\x00": + + # placeable windows metafile + + # get units per inch + inch = word(s, 14) + + # get bounding box + x0 = short(s, 6); y0 = short(s, 8) + x1 = short(s, 10); y1 = short(s, 12) + + # normalize size to 72 dots per inch + size = (x1 - x0) * 72 / inch, (y1 - y0) * 72 / inch + + self.info["wmf_bbox"] = x0, y0, x1, y1 + + self.info["dpi"] = 72 + + # print self.mode, self.size, self.info + + # sanity check (standard metafile header) + if s[22:26] != "\x01\x00\t\x00": + raise SyntaxError("Unsupported WMF file format") + + elif long(s) == 1 and s[40:44] == " EMF": + # enhanced metafile + + # get bounding box + x0 = long(s, 8); y0 = long(s, 12) + x1 = long(s, 16); y1 = long(s, 20) + + # get frame (in 0.01 millimeter units) + frame = long(s, 24), long(s, 28), long(s, 32), long(s, 36) + + # normalize size to 72 dots per inch + size = x1 - x0, y1 - y0 + + # calculate dots per inch from bbox and frame + xdpi = 2540 * (x1 - y0) / (frame[2] - frame[0]) + ydpi = 2540 * (y1 - y0) / (frame[3] - frame[1]) + + self.info["wmf_bbox"] = x0, y0, x1, y1 + + if xdpi == ydpi: + self.info["dpi"] = xdpi + else: + self.info["dpi"] = xdpi, ydpi + + else: + raise SyntaxError("Unsupported file format") + + self.mode = "RGB" + self.size = size + + loader = self._load() + if loader: + loader.open(self) + + def _load(self): + return _handler + + +def _save(im, fp, filename): + if _handler is None or not hasattr("_handler", "save"): + raise IOError("WMF save handler not installed") + _handler.save(im, fp, filename) + +# +# -------------------------------------------------------------------- +# Registry stuff + +Image.register_open(WmfStubImageFile.format, WmfStubImageFile, _accept) +Image.register_save(WmfStubImageFile.format, _save) + +Image.register_extension(WmfStubImageFile.format, ".wmf") +Image.register_extension(WmfStubImageFile.format, ".emf") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py new file mode 100755 index 00000000000..ab1fb5d7ac8 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py @@ -0,0 +1,73 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XV Thumbnail file handler by Charles E. "Gene" Cash +# (gcash@magicnet.net) +# +# see xvcolor.c and xvbrowse.c in the sources to John Bradley's XV, +# available from ftp://ftp.cis.upenn.edu/pub/xv/ +# +# history: +# 98-08-15 cec created (b/w only) +# 98-12-09 cec added color palette +# 98-12-28 fl added to PIL (with only a few very minor modifications) +# +# To do: +# FIXME: make save work (this requires quantization support) +# + +__version__ = "0.1" + +import string +import Image, ImageFile, ImagePalette + +# standard color palette for thumbnails (RGB332) +PALETTE = "" +for r in range(8): + for g in range(8): + for b in range(4): + PALETTE = PALETTE + (chr((r*255)/7)+chr((g*255)/7)+chr((b*255)/3)) + +## +# Image plugin for XV thumbnail images. + +class XVThumbImageFile(ImageFile.ImageFile): + + format = "XVThumb" + format_description = "XV thumbnail image" + + def _open(self): + + # check magic + s = self.fp.read(6) + if s != "P7 332": + raise SyntaxError, "not an XV thumbnail file" + + # Skip to beginning of next line + self.fp.readline() + + # skip info comments + while 1: + s = self.fp.readline() + if not s: + raise SyntaxError, "Unexpected EOF reading XV thumbnail file" + if s[0] != '#': + break + + # parse header line (already read) + s = string.split(s.strip()) + + self.mode = "P" + self.size = int(s[0]), int(s[1]) + + self.palette = ImagePalette.raw("RGB", PALETTE) + + self.tile = [ + ("raw", (0, 0)+self.size, + self.fp.tell(), (self.mode, 0, 1) + )] + +# -------------------------------------------------------------------- + +Image.register_open("XVThumb", XVThumbImageFile) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py new file mode 100755 index 00000000000..a8cf1026dce --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py @@ -0,0 +1,94 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XBM File handling +# +# History: +# 1995-09-08 fl Created +# 1996-11-01 fl Added save support +# 1997-07-07 fl Made header parser more tolerant +# 1997-07-22 fl Fixed yet another parser bug +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) +# 2001-05-13 fl Added hotspot handling (based on code from Bernhard Herzog) +# 2004-02-24 fl Allow some whitespace before first #define +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +__version__ = "0.6" + +import re, string +import Image, ImageFile + +# XBM header +xbm_head = re.compile( + "\s*#define[ \t]+[^_]*_width[ \t]+(?P[0-9]+)[\r\n]+" + "#define[ \t]+[^_]*_height[ \t]+(?P[0-9]+)[\r\n]+" + "(?P" + "#define[ \t]+[^_]*_x_hot[ \t]+(?P[0-9]+)[\r\n]+" + "#define[ \t]+[^_]*_y_hot[ \t]+(?P[0-9]+)[\r\n]+" + ")?" + "[\\000-\\377]*_bits\\[\\]" +) + +def _accept(prefix): + return string.lstrip(prefix)[:7] == "#define" + +## +# Image plugin for X11 bitmaps. + +class XbmImageFile(ImageFile.ImageFile): + + format = "XBM" + format_description = "X11 Bitmap" + + def _open(self): + + m = xbm_head.match(self.fp.read(512)) + + if m: + + xsize = int(m.group("width")) + ysize = int(m.group("height")) + + if m.group("hotspot"): + self.info["hotspot"] = ( + int(m.group("xhot")), int(m.group("yhot")) + ) + + self.mode = "1" + self.size = xsize, ysize + + self.tile = [("xbm", (0, 0)+self.size, m.end(), None)] + + +def _save(im, fp, filename): + + if im.mode != "1": + raise IOError, "cannot write mode %s as XBM" % im.mode + + fp.write("#define im_width %d\n" % im.size[0]) + fp.write("#define im_height %d\n" % im.size[1]) + + hotspot = im.encoderinfo.get("hotspot") + if hotspot: + fp.write("#define im_x_hot %d\n" % hotspot[0]) + fp.write("#define im_y_hot %d\n" % hotspot[1]) + + fp.write("static char im_bits[] = {\n") + + ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)]) + + fp.write("};\n") + + +Image.register_open("XBM", XbmImageFile, _accept) +Image.register_save("XBM", _save) + +Image.register_extension("XBM", ".xbm") + +Image.register_mime("XBM", "image/xbm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py new file mode 100755 index 00000000000..a3f40f02c4e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py @@ -0,0 +1,129 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XPM File handling +# +# History: +# 1996-12-29 fl Created +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) +# +# Copyright (c) Secret Labs AB 1997-2001. +# Copyright (c) Fredrik Lundh 1996-2001. +# +# See the README file for information on usage and redistribution. +# + + +__version__ = "0.2" + + +import re, string +import Image, ImageFile, ImagePalette + +# XPM header +xpm_head = re.compile("\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)") + + +def _accept(prefix): + return prefix[:9] == "/* XPM */" + +## +# Image plugin for X11 pixel maps. + +class XpmImageFile(ImageFile.ImageFile): + + format = "XPM" + format_description = "X11 Pixel Map" + + def _open(self): + + if not _accept(self.fp.read(9)): + raise SyntaxError, "not an XPM file" + + # skip forward to next string + while 1: + s = self.fp.readline() + if not s: + raise SyntaxError, "broken XPM file" + m = xpm_head.match(s) + if m: + break + + self.size = int(m.group(1)), int(m.group(2)) + + pal = int(m.group(3)) + bpp = int(m.group(4)) + + if pal > 256 or bpp != 1: + raise ValueError, "cannot read this XPM file" + + # + # load palette description + + palette = ["\0\0\0"] * 256 + + for i in range(pal): + + s = self.fp.readline() + if s[-2:] == '\r\n': + s = s[:-2] + elif s[-1:] in '\r\n': + s = s[:-1] + + c = ord(s[1]) + s = string.split(s[2:-2]) + + for i in range(0, len(s), 2): + + if s[i] == "c": + + # process colour key + rgb = s[i+1] + if rgb == "None": + self.info["transparency"] = c + elif rgb[0] == "#": + # FIXME: handle colour names (see ImagePalette.py) + rgb = string.atoi(rgb[1:], 16) + palette[c] = chr((rgb >> 16) & 255) +\ + chr((rgb >> 8) & 255) +\ + chr(rgb & 255) + else: + # unknown colour + raise ValueError, "cannot read this XPM file" + break + + else: + + # missing colour key + raise ValueError, "cannot read this XPM file" + + self.mode = "P" + self.palette = ImagePalette.raw("RGB", string.join(palette, "")) + + self.tile = [("raw", (0, 0)+self.size, self.fp.tell(), ("P", 0, 1))] + + def load_read(self, bytes): + + # + # load all image data in one chunk + + xsize, ysize = self.size + + s = [None] * ysize + + for i in range(ysize): + s[i] = string.ljust(self.fp.readline()[1:xsize+1], xsize) + + self.fp = None + + return string.join(s, "") + +# +# Registry + +Image.register_open("XPM", XpmImageFile, _accept) + +Image.register_extension("XPM", ".xpm") + +Image.register_mime("XPM", "image/xpm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py new file mode 100755 index 00000000000..ed54d26f66e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py @@ -0,0 +1,12 @@ +# +# The Python Imaging Library. +# $Id$ +# +# package placeholder +# +# Copyright (c) 1999 by Secret Labs AB. +# +# See the README file for information on usage and redistribution. +# + +# ;-) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imaging.pyd b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imaging.pyd new file mode 100755 index 0000000000000000000000000000000000000000..22ee66c119717b931306da63a289e09754eeefd3 GIT binary patch literal 193536 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 z%0A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 literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/README b/tools/HitboxExpander/third_party/Imaging-1.1.7/README new file mode 100755 index 00000000000..458975b3bac --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/README @@ -0,0 +1,300 @@ +The Python Imaging Library +$Id$ + +Release 1.1.7 (November 15, 2009) + +==================================================================== +The Python Imaging Library 1.1.7 +==================================================================== + +Contents +-------- + ++ Introduction ++ Support Options + - Commercial support + - Free support ++ Software License ++ Build instructions (all platforms) + - Additional notes for Mac OS X + - Additional notes for Windows + +-------------------------------------------------------------------- +Introduction +-------------------------------------------------------------------- + +The Python Imaging Library (PIL) adds image processing capabilities +to your Python environment. This library provides extensive file +format support, an efficient internal representation, and powerful +image processing capabilities. + +This source kit has been built and tested with Python 2.0 and newer, +on Windows, Mac OS X, and major Unix platforms. Large parts of the +library also work on 1.5.2 and 1.6. + +The main distribution site for this software is: + + http://www.pythonware.com/products/pil/ + +That site also contains information about free and commercial support +options, PIL add-ons, answers to frequently asked questions, and more. + + +Development versions (alphas, betas) are available here: + + http://effbot.org/downloads/ + + +The PIL handbook is not included in this distribution; to get the +latest version, check: + + http://www.pythonware.com/library/ + http://effbot.org/books/imagingbook/ (drafts) + + +For installation and licensing details, see below. + + +-------------------------------------------------------------------- +Support Options +-------------------------------------------------------------------- + ++ Commercial Support + +Secret Labs (PythonWare) offers support contracts for companies using +the Python Imaging Library in commercial applications, and in mission- +critical environments. The support contract includes technical support, +bug fixes, extensions to the PIL library, sample applications, and more. + +For the full story, check: + + http://www.pythonware.com/products/pil/support.htm + + ++ Free Support + +For support and general questions on the Python Imaging Library, send +e-mail to the Image SIG mailing list: + + image-sig@python.org + +You can join the Image SIG by sending a mail to: + + image-sig-request@python.org + +Put "subscribe" in the message body to automatically subscribe to the +list, or "help" to get additional information. Alternatively, you can +send your questions to the Python mailing list, python-list@python.org, +or post them to the newsgroup comp.lang.python. DO NOT SEND SUPPORT +QUESTIONS TO PYTHONWARE ADDRESSES. + + +-------------------------------------------------------------------- +Software License +-------------------------------------------------------------------- + +The Python Imaging Library is + +Copyright (c) 1997-2009 by Secret Labs AB +Copyright (c) 1995-2009 by Fredrik Lundh + +By obtaining, using, and/or copying this software and/or its +associated documentation, you agree that you have read, understood, +and will comply with the following terms and conditions: + +Permission to use, copy, modify, and distribute this software and its +associated documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies, and that both that copyright notice and this permission notice +appear in supporting documentation, and that the name of Secret Labs +AB or the author not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR +ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +-------------------------------------------------------------------- +Build instructions (all platforms) +-------------------------------------------------------------------- + +For a list of changes in this release, see the CHANGES document. + +0. If you're in a hurry, try this: + + $ tar xvfz Imaging-1.1.7.tar.gz + $ cd Imaging-1.1.7 + $ python setup.py install + + If you prefer to know what you're doing, read on. + + +1. Prerequisites. + + If you need any of the features described below, make sure you + have the necessary libraries before building PIL. + + feature library + ----------------------------------------------------------------- + JPEG support libjpeg (6a or 6b) + + http://www.ijg.org + http://www.ijg.org/files/jpegsrc.v6b.tar.gz + ftp://ftp.uu.net/graphics/jpeg/ + + PNG support zlib (1.2.3 or later is recommended) + + http://www.gzip.org/zlib/ + + OpenType/TrueType freetype2 (2.3.9 or later is recommended) + support + http://www.freetype.org + http://freetype.sourceforge.net + + CMS support littleCMS (1.1.5 or later is recommended) + support + http://www.littlecms.com/ + + If you have a recent Linux version, the libraries provided with the + operating system usually work just fine. If some library is + missing, installing a prebuilt version (jpeg-devel, zlib-devel, + etc) is usually easier than building from source. For example, for + Ubuntu 9.10 (karmic), you can install the following libraries: + + sudo apt-get install libjpeg62-dev + sudo apt-get install zlib1g-dev + sudo apt-get install libfreetype6-dev + sudo apt-get install liblcms1-dev + + If you're using Mac OS X, you can use the 'fink' tool to install + missing libraries (also see the Mac OS X section below). + + Similar tools are available for many other platforms. + + +2. To build under Python 1.5.2, you need to install the stand-alone + version of the distutils library: + + http://www.python.org/sigs/distutils-sig/download.html + + You can fetch distutils 1.0.2 from the Python source repository: + + svn export http://svn.python.org/projects/python/tags/Distutils-1_0_2/Lib/distutils/ + + For newer releases, the distutils library is included in the + Python standard library. + + NOTE: Version 1.1.7 is not fully compatible with 1.5.2. Some + more recent additions to the library may not work, but the core + functionality is available. + + +3. If you didn't build Python from sources, make sure you have + Python's build support files on your machine. If you've down- + loaded a prebuilt package (e.g. a Linux RPM), you probably + need additional developer packages. Look for packages named + "python-dev", "python-devel", or similar. For example, for + Ubuntu 9.10 (karmic), use the following command: + + sudo apt-get install python-dev + + +4. When you have everything you need, unpack the PIL distribution + (the file Imaging-1.1.7.tar.gz) in a suitable work directory: + + $ cd MyExtensions # example + $ gunzip Imaging-1.1.7.tar.gz + $ tar xvf Imaging-1.1.7.tar + + +5. Build the library. We recommend that you do an in-place build, + and run the self test before installing. + + $ cd Imaging-1.1.7 + $ python setup.py build_ext -i + $ python selftest.py + + During the build process, the setup.py will display a summary + report that lists what external components it found. The self- + test will display a similar report, with what external components + the tests found in the actual build files: + + ---------------------------------------------------------------- + PIL 1.1.7 SETUP SUMMARY + ---------------------------------------------------------------- + *** TKINTER support not available (Tcl/Tk 8.5 libraries needed) + --- JPEG support available + --- ZLIB (PNG/ZIP) support available + --- FREETYPE support available + ---------------------------------------------------------------- + + Make sure that the optional components you need are included. + + If the build script won't find a given component, you can edit the + setup.py file and set the appropriate ROOT variable. For details, + see instructions in the file. + + If the build script finds the component, but the tests cannot + identify it, try rebuilding *all* modules: + + $ python setup.py clean + $ python setup.py build_ext -i + + +6. If the setup.py and selftest.py commands finish without any + errors, you're ready to install the library: + + $ python setup.py install + + (depending on how Python has been installed on your machine, + you might have to log in as a superuser to run the 'install' + command, or use the 'sudo' command to run 'install'.) + + +-------------------------------------------------------------------- +Additional notes for Mac OS X +-------------------------------------------------------------------- + +On Mac OS X you will usually install additional software such as +libjpeg or freetype with the "fink" tool, and then it ends up in +"/sw". If you have installed the libraries elsewhere, you may have +to tweak the "setup.py" file before building. + + +-------------------------------------------------------------------- +Additional notes for Windows +-------------------------------------------------------------------- + +On Windows, you need to tweak the ROOT settings in the "setup.py" +file, to make it find the external libraries. See comments in the +file for details. + +Make sure to build PIL and the external libraries with the same +runtime linking options as was used for the Python interpreter +(usually /MD, under Visual Studio). + + +Note that most Python distributions for Windows include libraries +compiled for Microsoft Visual Studio. You can get the free Express +edition of Visual Studio from: + + http://www.microsoft.com/Express/ + +To build extensions using other tool chains, see the "Using +non-Microsoft compilers on Windows" section in the distutils handbook: + + http://www.python.org/doc/current/inst/non-ms-compilers.html + +For additional information on how to build extensions using the +popular MinGW compiler, see: + + http://mingw.org (compiler) + http://sebsauvage.net/python/mingw.html (build instructions) + http://sourceforge.net/projects/gnuwin32 (prebuilt libraries) + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES new file mode 100755 index 00000000000..95c14697e83 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES @@ -0,0 +1,34 @@ + +from V1.0 to V2.0 + +_sane.c: + - Values for option constraints are correctly translated to floats + if value type is TYPE_FIXED for SANE_CONSTRAINT_RANGE and + SANE_CONSTRAINT_WORD_LIST + - added constants INFO_INEXACT, INFO_RELOAD_OPTIONS, + INFO_RELOAD_PARAMS (possible return values of set_option()) + to module dictionnary. + - removed additional return variable 'i' from SaneDev_get_option(), + because it is only set when SANE_ACTION_SET_VALUE is used. + - scanDev.get_parameters() now returns the scanner mode as 'format', + no more the typical PIL codes. So 'L' became 'gray', 'RGB' is now + 'color', 'R' is 'red', 'G' is 'green', 'B' is 'red'. This matches + the way scanDev.mode is set. + This should be the only incompatibility vs. version 1.0. + +sane.py + - ScanDev got new method __load_option_dict() called from __init__() + and from __setattr__() if backend reported that the frontend should + reload the options. + - Nice human-readable __repr__() method added for class Option + - if __setattr__ (i.e. set_option) reports that all other options + have to be reloaded due to a change in the backend then they are reloaded. + - due to the change in SaneDev_get_option() only the 'value' is + returned from get_option(). + - in __setattr__ integer values are automatically converted to floats + if SANE backend expects SANE_FIXED (i.e. fix-point float) + - The scanner options can now directly be accessed via scanDev[optionName] + instead scanDev.opt[optionName]. (The old way still works). + +V1.0: + A.M. Kuchling's original pysane package. \ No newline at end of file diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README new file mode 100755 index 00000000000..ddff0cf2479 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README @@ -0,0 +1,22 @@ + +Python SANE module V1.1 (30 Sep. 2004) + +The SANE module provides an interface to the SANE scanner and frame +grabber interface for Linux. This module was contributed by Andrew +Kuchling and is extended and currently maintained by Ralph Heinkel +(rheinkel-at-email.de). If you write to me please make sure to have the +word 'SANE' or 'sane' in the subject of your mail, otherwise it might +be classified as spam in the future. + + +To build this module, type (in the Sane directory): + + python setup.py build + +In order to install the module type: + + python setup.py install + + +For some basic documentation please look at the file sanedoc.txt +The two demo_*.py scripts give basic examples on how to use the software. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c new file mode 100755 index 00000000000..21e542fa512 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c @@ -0,0 +1,1325 @@ +/*********************************************************** +(C) Copyright 2003 A.M. Kuchling. All Rights Reserved +(C) Copyright 2004 A.M. Kuchling, Ralph Heinkel All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of A.M. Kuchling and +Ralph Heinkel not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +A.M. KUCHLING, R.H. HEINKEL DISCLAIM ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/* SaneDev objects */ + +#include "Python.h" +#include "Imaging.h" +#include + +#include + +static PyObject *ErrorObject; + +typedef struct { + PyObject_HEAD + SANE_Handle h; +} SaneDevObject; + +#ifdef WITH_THREAD +PyThreadState *_save; +#endif + +/* Raise a SANE exception */ +PyObject * +PySane_Error(SANE_Status st) +{ + const char *string; + + if (st==SANE_STATUS_GOOD) {Py_INCREF(Py_None); return (Py_None);} + string=sane_strstatus(st); + PyErr_SetString(ErrorObject, string); + return NULL; +} + +staticforward PyTypeObject SaneDev_Type; + +#define SaneDevObject_Check(v) ((v)->ob_type == &SaneDev_Type) + +static SaneDevObject * +newSaneDevObject(void) +{ + SaneDevObject *self; + self = PyObject_NEW(SaneDevObject, &SaneDev_Type); + if (self == NULL) + return NULL; + self->h=NULL; + return self; +} + +/* SaneDev methods */ + +static void +SaneDev_dealloc(SaneDevObject *self) +{ + if (self->h) sane_close(self->h); + self->h=NULL; + PyObject_DEL(self); +} + +static PyObject * +SaneDev_close(SaneDevObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (self->h) sane_close(self->h); + self->h=NULL; + Py_INCREF(Py_None); + return (Py_None); +} + +static PyObject * +SaneDev_get_parameters(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + SANE_Parameters p; + char *format="unknown format"; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + Py_BEGIN_ALLOW_THREADS + st=sane_get_parameters(self->h, &p); + Py_END_ALLOW_THREADS + + if (st) return PySane_Error(st); + switch (p.format) + { + case(SANE_FRAME_GRAY): format="gray"; break; + case(SANE_FRAME_RGB): format="color"; break; + case(SANE_FRAME_RED): format="red"; break; + case(SANE_FRAME_GREEN): format="green"; break; + case(SANE_FRAME_BLUE): format="blue"; break; + } + + return Py_BuildValue("si(ii)ii", format, p.last_frame, p.pixels_per_line, + p.lines, p.depth, p.bytes_per_line); +} + + +static PyObject * +SaneDev_fileno(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + SANE_Int fd; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + st=sane_get_select_fd(self->h, &fd); + if (st) return PySane_Error(st); + return PyInt_FromLong(fd); +} + +static PyObject * +SaneDev_start(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + /* sane_start can take several seconds, if the user initiates + a new scan, while the scan head of a flatbed scanner moves + back to the start position after finishing a previous scan. + Hence it is worth to allow threads here. + */ + Py_BEGIN_ALLOW_THREADS + st=sane_start(self->h); + Py_END_ALLOW_THREADS + if (st) return PySane_Error(st); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +SaneDev_cancel(SaneDevObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + sane_cancel(self->h); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +SaneDev_get_options(SaneDevObject *self, PyObject *args) +{ + const SANE_Option_Descriptor *d; + PyObject *list, *value; + int i=1; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + if (!(list = PyList_New(0))) + return NULL; + + do + { + d=sane_get_option_descriptor(self->h, i); + if (d!=NULL) + { + PyObject *constraint=NULL; + int j; + + switch (d->constraint_type) + { + case(SANE_CONSTRAINT_NONE): + Py_INCREF(Py_None); constraint=Py_None; break; + case(SANE_CONSTRAINT_RANGE): + if (d->type == SANE_TYPE_INT) + constraint=Py_BuildValue("iii", d->constraint.range->min, + d->constraint.range->max, + d->constraint.range->quant); + else + constraint=Py_BuildValue("ddd", + SANE_UNFIX(d->constraint.range->min), + SANE_UNFIX(d->constraint.range->max), + SANE_UNFIX(d->constraint.range->quant)); + break; + case(SANE_CONSTRAINT_WORD_LIST): + constraint=PyList_New(d->constraint.word_list[0]); + if (d->type == SANE_TYPE_INT) + for (j=1; j<=d->constraint.word_list[0]; j++) + PyList_SetItem(constraint, j-1, + PyInt_FromLong(d->constraint.word_list[j])); + else + for (j=1; j<=d->constraint.word_list[0]; j++) + PyList_SetItem(constraint, j-1, + PyFloat_FromDouble(SANE_UNFIX(d->constraint.word_list[j]))); + break; + case(SANE_CONSTRAINT_STRING_LIST): + constraint=PyList_New(0); + for(j=0; d->constraint.string_list[j]!=NULL; j++) + PyList_Append(constraint, + PyString_FromString(d->constraint.string_list[j])); + break; + } + value=Py_BuildValue("isssiiiiO", i, d->name, d->title, d->desc, + d->type, d->unit, d->size, d->cap, constraint); + PyList_Append(list, value); + } + i++; + } while (d!=NULL); + return list; +} + +static PyObject * +SaneDev_get_option(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + const SANE_Option_Descriptor *d; + PyObject *value=NULL; + int n; + void *v; + + if (!PyArg_ParseTuple(args, "i", &n)) + { + return NULL; + } + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + d=sane_get_option_descriptor(self->h, n); + v=malloc(d->size+1); + st=sane_control_option(self->h, n, SANE_ACTION_GET_VALUE, + v, NULL); + + if (st) + { + free(v); + return PySane_Error(st); + } + + switch(d->type) + { + case(SANE_TYPE_BOOL): + case(SANE_TYPE_INT): + value=Py_BuildValue("i", *( (SANE_Int*)v) ); + break; + case(SANE_TYPE_FIXED): + value=Py_BuildValue("d", SANE_UNFIX((*((SANE_Fixed*)v))) ); + break; + case(SANE_TYPE_STRING): + value=Py_BuildValue("s", v); + break; + case(SANE_TYPE_BUTTON): + case(SANE_TYPE_GROUP): + value=Py_BuildValue("O", Py_None); + break; + } + + free(v); + return value; +} + +static PyObject * +SaneDev_set_option(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + const SANE_Option_Descriptor *d; + SANE_Int i; + PyObject *value; + int n; + void *v; + + if (!PyArg_ParseTuple(args, "iO", &n, &value)) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + d=sane_get_option_descriptor(self->h, n); + v=malloc(d->size+1); + + switch(d->type) + { + case(SANE_TYPE_BOOL): + if (!PyInt_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "SANE_BOOL requires an integer"); + free(v); + return NULL; + } + /* fall through */ + case(SANE_TYPE_INT): + if (!PyInt_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "SANE_INT requires an integer"); + free(v); + return NULL; + } + *( (SANE_Int*)v) = PyInt_AsLong(value); + break; + case(SANE_TYPE_FIXED): + if (!PyFloat_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "SANE_FIXED requires a floating point number"); + free(v); + return NULL; + } + *( (SANE_Fixed*)v) = SANE_FIX(PyFloat_AsDouble(value)); + break; + case(SANE_TYPE_STRING): + if (!PyString_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "SANE_STRING requires a string"); + free(v); + return NULL; + } + strncpy(v, PyString_AsString(value), d->size-1); + ((char*)v)[d->size-1] = 0; + break; + case(SANE_TYPE_BUTTON): + case(SANE_TYPE_GROUP): + break; + } + + st=sane_control_option(self->h, n, SANE_ACTION_SET_VALUE, + v, &i); + if (st) {free(v); return PySane_Error(st);} + + free(v); + return Py_BuildValue("i", i); +} + +static PyObject * +SaneDev_set_auto_option(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + const SANE_Option_Descriptor *d; + SANE_Int i; + int n; + + if (!PyArg_ParseTuple(args, "i", &n)) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + d=sane_get_option_descriptor(self->h, n); + st=sane_control_option(self->h, n, SANE_ACTION_SET_AUTO, + NULL, &i); + if (st) {return PySane_Error(st);} + + return Py_BuildValue("i", i); + } + +#define READSIZE 32768 + +static PyObject * +SaneDev_snap(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + /* The buffer should be a multiple of 3 in size, so each sane_read + operation will return an integral number of RGB triples. */ + SANE_Byte buffer[READSIZE]; /* XXX how big should the buffer be? */ + SANE_Int len, lastlen; + Imaging im; + SANE_Parameters p; + int px, py, remain, cplen, bufpos, padbytes; + long L; + char errmsg[80]; + union + { char c[2]; + INT16 i16; + } + endian; + PyObject *pyNoCancel = NULL; + int noCancel = 0; + + endian.i16 = 1; + + if (!PyArg_ParseTuple(args, "l|O", &L, &pyNoCancel)) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + im=(Imaging)L; + + if (pyNoCancel) + noCancel = PyObject_IsTrue(pyNoCancel); + + st=SANE_STATUS_GOOD; px=py=0; + /* xxx not yet implemented + - handscanner support (i.e., unknown image length during start) + - generally: move the functionality from method snap in sane.py + down here -- I don't like this cross-dependency. + we need to call sane_get_parameters here, and we can create + the result Image object here. + */ + + Py_UNBLOCK_THREADS + sane_get_parameters(self->h, &p); + if (p.format == SANE_FRAME_GRAY) + { + switch (p.depth) + { + case 1: + remain = p.bytes_per_line * im->ysize; + padbytes = p.bytes_per_line - (im->xsize+7)/8; + bufpos = 0; + lastlen = len = 0; + while (st!=SANE_STATUS_EOF && py < im->ysize) + { + while (len > 0 && py < im->ysize) + { + int i, j, k; + j = buffer[bufpos++]; + k = 0x80; + for (i = 0; i < 8 && px < im->xsize; i++) + { + im->image8[py][px++] = (k&j) ? 0 : 0xFF; + k = k >> 1; + } + len--; + if (px >= im->xsize) + { + bufpos += padbytes; + len -= padbytes; + py++; + px = 0; + } + } + st=sane_read(self->h, buffer, + remainh); + Py_BLOCK_THREADS + return PySane_Error(st); + } + bufpos -= lastlen; + lastlen = len; + remain -= len; + /* skip possible pad bytes at the start of the buffer */ + len -= bufpos; + } + break; + case 8: + remain = p.bytes_per_line * im->ysize; + padbytes = p.bytes_per_line - im->xsize; + bufpos = 0; + len = 0; + while (st!=SANE_STATUS_EOF && py < im->ysize) + { + while (len > 0 && py < im->ysize) + { + cplen = len; + if (px + cplen >= im->xsize) + cplen = im->xsize - px; + memcpy(&im->image8[py][px], &buffer[bufpos], cplen); + len -= cplen; + bufpos += cplen; + px += cplen; + if (px >= im->xsize) + { + px = 0; + py++; + bufpos += padbytes; + len -= padbytes; + } + } + bufpos = -len; + + st=sane_read(self->h, buffer, + remainh); + Py_BLOCK_THREADS + return PySane_Error(st); + } + remain -= len; + len -= bufpos; + } + break; + case 16: + remain = p.bytes_per_line * im->ysize; + padbytes = p.bytes_per_line - 2 * im->xsize; + bufpos = endian.c[0]; + lastlen = len = 0; + while (st!=SANE_STATUS_EOF && py < im->ysize) + { + while (len > 0 && py < im->ysize) + { + im->image8[py][px++] = buffer[bufpos]; + bufpos += 2; + len -= 2; + if (px >= im->xsize) + { + bufpos += padbytes; + len -= padbytes; + py++; + px = 0; + } + } + st=sane_read(self->h, buffer, + remainh); + Py_BLOCK_THREADS + return PySane_Error(st); + } + remain -= len; + bufpos -= lastlen; + lastlen = len; + len -= bufpos; + } + break; + default: + /* other depths are not formally "illegal" according to the + Sane API, but it's agreed by Sane developers that other + depths than 1, 8, 16 should not be used + */ + sane_cancel(self->h); + Py_BLOCK_THREADS + snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth); + PyErr_SetString(ErrorObject, errmsg); + return NULL; + } + } + else if (p.format == SANE_FRAME_RGB) + { + int incr, color, pxs, pxmax, bit, val, mask; + switch (p.depth) + { + case 1: + remain = p.bytes_per_line * im->ysize; + padbytes = p.bytes_per_line - ((im->xsize+7)/8) * 3; + bufpos = 0; + len = 0; + lastlen = 0; + pxmax = 4 * im->xsize; + while (st!=SANE_STATUS_EOF && py < im->ysize) + { + pxs = px; + for (color = 0; color < 3; color++) + { + while (len <= 0 && st == SANE_STATUS_GOOD) + { + st=sane_read(self->h, buffer, + remainh); + Py_BLOCK_THREADS + return PySane_Error(st); + } + bufpos -= lastlen; + remain -= len; + lastlen = len; + /* skip possible pad bytes at the start of the buffer */ + len -= bufpos; + } + if (st == SANE_STATUS_EOF) break; + pxs = px; + val = buffer[bufpos++]; + len--; + mask = 0x80; + for (bit = 0; (bit < 8) && (px < pxmax); bit++) + { + ((UINT8**)(im->image32))[py][px] = (val&mask) ? 0xFF : 0; + mask = mask >> 1; + px += 4; + } + pxs++; + px = pxs; + } + if (st == SANE_STATUS_EOF) + break; + for (bit = 0; bit < 8 && px < pxmax; bit++) + { + ((UINT8**)(im->image32))[py][px] = 0; + px += 4; + } + px -= 3; + if (px >= pxmax) + { + bufpos += padbytes; + len -= padbytes; + py++; + px = 0; + } + } + break; + case 8: + case 16: + if (p.depth == 8) + { + padbytes = p.bytes_per_line - 3 * im->xsize; + bufpos = 0; + incr = 1; + } + else + { + padbytes = p.bytes_per_line - 6 * im->xsize; + bufpos = endian.c[0]; + incr = 2; + } + remain = p.bytes_per_line * im->ysize; + len = 0; + lastlen = 0; + pxmax = 4 * im->xsize; + /* probably not very efficient. But we have to deal with these + possible conditions: + - we may have padding bytes at the end of a scan line + - the number of bytes read with sane_read may be smaller + than the number of pad bytes + - the buffer may become empty after setting any of the + red/green/blue pixel values + + */ + while (st != SANE_STATUS_EOF && py < im->ysize) + { + for (color = 0; color < 3; color++) + { + while (len <= 0 && st == SANE_STATUS_GOOD) + { + bufpos -= lastlen; + if (remain == 0) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + PyErr_SetString(ErrorObject, "internal _sane error: premature end of scan"); + return NULL; + } + st = sane_read(self->h, buffer, + remain<(READSIZE) ? remain : (READSIZE), &len); + if (st && (st!=SANE_STATUS_EOF)) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + return PySane_Error(st); + } + lastlen = len; + remain -= len; + len -= bufpos; + } + if (st == SANE_STATUS_EOF) break; + ((UINT8**)(im->image32))[py][px++] = buffer[bufpos]; + bufpos += incr; + len -= incr; + } + if (st == SANE_STATUS_EOF) break; + + ((UINT8**)(im->image32))[py][px++] = 0; + + if (px >= pxmax) + { + px = 0; + py++; + bufpos += padbytes; + len -= padbytes; + } + } + break; + default: + Py_BLOCK_THREADS + sane_cancel(self->h); + snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth); + PyErr_SetString(ErrorObject, errmsg); + return NULL; + } + + } + else /* should be SANE_FRAME_RED, GREEN or BLUE */ + { + int lastlen, pxa, pxmax, offset, incr, frame_count = 0; + /* at least the Sane test backend behaves a bit weird, if + it returns "premature EOF" for sane_read, i.e., if the + option "return value of sane_read" is set to SANE_STATUS_EOF. + In this case, the test backend does not advance to the next frame, + so p.last_frame will never be set... + So let's count the number of frames we try to acquire + */ + while (!p.last_frame && frame_count < 4) + { + frame_count++; + st = sane_get_parameters(self->h, &p); + if (st) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + return PySane_Error(st); + } + remain = p.bytes_per_line * im->ysize; + bufpos = 0; + len = 0; + lastlen = 0; + py = 0; + switch (p.format) + { + case SANE_FRAME_RED: + offset = 0; + break; + case SANE_FRAME_GREEN: + offset = 1; + break; + case SANE_FRAME_BLUE: + offset = 2; + break; + default: + sane_cancel(self->h); + Py_BLOCK_THREADS + snprintf(errmsg, 80, "unknown/invalid frame format: %i", p.format); + PyErr_SetString(ErrorObject, errmsg); + return NULL; + } + px = offset; + pxa = 3; + pxmax = im->xsize * 4; + switch (p.depth) + { + case 1: + padbytes = p.bytes_per_line - (im->xsize+7)/8; + st = SANE_STATUS_GOOD; + while (st != SANE_STATUS_EOF && py < im->ysize) + { + while (len > 0) + { + int bit, mask, val; + val = buffer[bufpos++]; len--; + mask = 0x80; + for (bit = 0; bit < 8 && px < pxmax; bit++) + { + ((UINT8**)(im->image32))[py][px] + = val&mask ? 0xFF : 0; + ((UINT8**)(im->image32))[py][pxa] = 0; + px += 4; + pxa += 4; + mask = mask >> 1; + } + + if (px >= pxmax) + { + px = offset; + pxa = 3; + py++; + bufpos += padbytes; + len -= padbytes; + } + } + while (len <= 0 && st == SANE_STATUS_GOOD && remain > 0) + { + bufpos -= lastlen; + st = sane_read(self->h, buffer, + remain<(READSIZE) ? remain : (READSIZE), &len); + if (st && (st!=SANE_STATUS_EOF)) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + return PySane_Error(st); + } + remain -= len; + lastlen = len; + len -= bufpos; + } + } + break; + case 8: + case 16: + if (p.depth == 8) + { + padbytes = p.bytes_per_line - im->xsize; + incr = 1; + } + else + { + padbytes = p.bytes_per_line - 2 * im->xsize; + incr = 2; + bufpos = endian.c[0]; + } + st = SANE_STATUS_GOOD; + while (st != SANE_STATUS_EOF && py < im->ysize) + { + while (len <= 0) + { + bufpos -= lastlen; + if (remain == 0) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + PyErr_SetString(ErrorObject, "internal _sane error: premature end of scan"); + return NULL; + } + st = sane_read(self->h, buffer, + remain<(READSIZE) ? remain : (READSIZE), &len); + if (st && (st!=SANE_STATUS_EOF)) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + return PySane_Error(st); + } + if (st == SANE_STATUS_EOF) + break; + lastlen = len; + remain -= len; + if (bufpos >= len) + len = 0; + else + len -= bufpos; + } + if (st == SANE_STATUS_EOF) + break; + ((UINT8**)(im->image32))[py][px] = buffer[bufpos]; + ((UINT8**)(im->image32))[py][pxa] = 0; + bufpos += incr; + len -= incr; + px += 4; + pxa += 4; + + if (px >= pxmax) + { + px = offset; + pxa = 3; + py++; + bufpos += padbytes; + len -= padbytes; + } + } + break; + default: + sane_cancel(self->h); + Py_BLOCK_THREADS + snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth); + PyErr_SetString(ErrorObject, errmsg); + return NULL; + } + if (!p.last_frame) + { + /* all sane_read calls in the above loop may return + SANE_STATUS_GOOD, but the backend may need another sane_read + call which returns SANE_STATUS_EOF in order to start + a new frame. + */ + do { + st = sane_read(self->h, buffer, READSIZE, &len); + } + while (st == SANE_STATUS_GOOD); + if (st != SANE_STATUS_EOF) + { + Py_BLOCK_THREADS + sane_cancel(self->h); + return PySane_Error(st); + } + + st = sane_start(self->h); + if (st) + { + Py_BLOCK_THREADS + return PySane_Error(st); + } + } + } + } + /* enforce SANE_STATUS_EOF. Can be necessary for ADF scans for some backends */ + do { + st = sane_read(self->h, buffer, READSIZE, &len); + } + while (st == SANE_STATUS_GOOD); + if (st != SANE_STATUS_EOF) + { + sane_cancel(self->h); + Py_BLOCK_THREADS + return PySane_Error(st); + } + + if (!noCancel) + sane_cancel(self->h); + Py_BLOCK_THREADS + Py_INCREF(Py_None); + return Py_None; +} + + +#ifdef WITH_NUMARRAY + +#include "numarray/libnumarray.h" + +/* this global variable is set to 1 in 'init_sane()' after successfully + importing the numarray module. */ +int NUMARRAY_IMPORTED = 0; + +static PyObject * +SaneDev_arr_snap(SaneDevObject *self, PyObject *args) +{ + SANE_Status st; + SANE_Byte buffer[READSIZE]; + SANE_Int len; + SANE_Parameters p; + + PyArrayObject *pyArr = NULL; + NumarrayType arrType; + int line, line_index, buffer_index, remain_bytes_line, num_pad_bytes; + int cp_num_bytes, total_remain, bpp, arr_bytes_per_line; + int pixels_per_line = -1; + char errmsg[80]; + + if (!NUMARRAY_IMPORTED) + { + PyErr_SetString(ErrorObject, "numarray package not available"); + return NULL; + } + + if (!PyArg_ParseTuple(args, "|i", &pixels_per_line)) + return NULL; + if (self->h==NULL) + { + PyErr_SetString(ErrorObject, "SaneDev object is closed"); + return NULL; + } + + sane_get_parameters(self->h, &p); + if (p.format != SANE_FRAME_GRAY) + { + sane_cancel(self->h); + snprintf(errmsg, 80, "numarray only supports gray-scale images"); + PyErr_SetString(ErrorObject, errmsg); + return NULL; + } + + if (p.depth == 8) + { + bpp=1; /* bytes-per-pixel */ + arrType = tUInt8; + } + else if (p.depth == 16) + { + bpp=2; /* bytes-per-pixel */ + arrType = tUInt16; + } + else + { + sane_cancel(self->h); + snprintf(errmsg, 80, "arrsnap: unsupported pixel depth: %i", p.depth); + PyErr_SetString(ErrorObject, errmsg); + return NULL; + } + + if (pixels_per_line < 1) + /* The user can choose a smaller result array than the actual scan */ + pixels_per_line = p.pixels_per_line; + else + if (pixels_per_line > p.pixels_per_line) + { + PyErr_SetString(ErrorObject,"given pixels_per_line too big"); + return NULL; + } + /* important: NumArray have indices like (y, x) !! */ + if (!(pyArr = NA_NewArray(NULL, arrType, 2, p.lines, pixels_per_line))) + { + PyErr_SetString(ErrorObject, "failed to create NumArray object"); + return NULL; + } + + arr_bytes_per_line = pixels_per_line * bpp; + st=SANE_STATUS_GOOD; +#ifdef WRITE_PGM + FILE *fp; + fp = fopen("sane_p5.pgm", "w"); + fprintf(fp, "P5\n%d %d\n%d\n", p.pixels_per_line, + p.lines, (int) pow(2.0, (double) p.depth)-1); +#endif + line_index = line = 0; + remain_bytes_line = arr_bytes_per_line; + total_remain = p.bytes_per_line * p.lines; + num_pad_bytes = p.bytes_per_line - arr_bytes_per_line; + + while (st!=SANE_STATUS_EOF) + { + Py_BEGIN_ALLOW_THREADS + st = sane_read(self->h, buffer, + READSIZE < total_remain ? READSIZE : total_remain, &len); + Py_END_ALLOW_THREADS +#ifdef WRITE_PGM + printf("p5_write: read %d of %d\n", len, READSIZE); + fwrite(buffer, 1, len, fp); +#endif + + buffer_index = 0; + total_remain -= len; + + while (len > 0) + { + /* copy at most the number of bytes that fit into (the rest of) + one line: */ + cp_num_bytes = (len > remain_bytes_line ? remain_bytes_line : len); + remain_bytes_line -= cp_num_bytes; + len -= cp_num_bytes; +#ifdef DEBUG + printf("copying %d bytes from b_idx %d to d_idx %d\n", + cp_num_bytes, buffer_index, + line * arr_bytes_per_line + line_index); + printf("len is now %d\n", len); +#endif + memcpy(pyArr->data + line * arr_bytes_per_line + line_index, + buffer + buffer_index, cp_num_bytes); + + buffer_index += cp_num_bytes; + if (remain_bytes_line ==0) + { + /* The line has been completed, so reinitialize remain_bytes_line + increase the line counter, and reset line_index */ +#ifdef DEBUG + printf("line %d full, skipping %d bytes\n",line,num_pad_bytes); +#endif + remain_bytes_line = arr_bytes_per_line; + line++; + line_index = 0; + /* Skip the number of bytes in the input stream which + are not used: */ + len -= num_pad_bytes; + buffer_index += num_pad_bytes; + } + else + line_index += cp_num_bytes; + } + } +#ifdef WRITE_PGM + fclose(fp); + printf("p5_write finished\n"); +#endif + sane_cancel(self->h); + return (PyObject*) pyArr; +} + + + +#endif /* WITH_NUMARRAY */ + +static PyMethodDef SaneDev_methods[] = { + {"get_parameters", (PyCFunction)SaneDev_get_parameters, 1}, + + {"get_options", (PyCFunction)SaneDev_get_options, 1}, + {"get_option", (PyCFunction)SaneDev_get_option, 1}, + {"set_option", (PyCFunction)SaneDev_set_option, 1}, + {"set_auto_option", (PyCFunction)SaneDev_set_auto_option, 1}, + + {"start", (PyCFunction)SaneDev_start, 1}, + {"cancel", (PyCFunction)SaneDev_cancel, 1}, + {"snap", (PyCFunction)SaneDev_snap, 1}, +#ifdef WITH_NUMARRAY + {"arr_snap", (PyCFunction)SaneDev_arr_snap, 1}, +#endif /* WITH_NUMARRAY */ + {"fileno", (PyCFunction)SaneDev_fileno, 1}, + {"close", (PyCFunction)SaneDev_close, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +SaneDev_getattr(SaneDevObject *self, char *name) +{ + return Py_FindMethod(SaneDev_methods, (PyObject *)self, name); +} + +staticforward PyTypeObject SaneDev_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "SaneDev", /*tp_name*/ + sizeof(SaneDevObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)SaneDev_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)SaneDev_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ +}; + +/* --------------------------------------------------------------------- */ + +static PyObject * +PySane_init(PyObject *self, PyObject *args) +{ + SANE_Status st; + SANE_Int version; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + /* XXX Authorization is not yet supported */ + st=sane_init(&version, NULL); + if (st) return PySane_Error(st); + return Py_BuildValue("iiii", version, SANE_VERSION_MAJOR(version), + SANE_VERSION_MINOR(version), SANE_VERSION_BUILD(version)); +} + +static PyObject * +PySane_exit(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + sane_exit(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +PySane_get_devices(PyObject *self, PyObject *args) +{ + SANE_Device **devlist; + SANE_Device *dev; + SANE_Status st; + PyObject *list; + int local_only, i; + + if (!PyArg_ParseTuple(args, "|i", &local_only)) + { + return NULL; + } + + st=sane_get_devices(&devlist, local_only); + if (st) return PySane_Error(st); + if (!(list = PyList_New(0))) + return NULL; + for(i=0; devlist[i]!=NULL; i++) + { + dev=devlist[i]; + PyList_Append(list, Py_BuildValue("ssss", dev->name, dev->vendor, + dev->model, dev->type)); + } + + return list; +} + +/* Function returning new SaneDev object */ + +static PyObject * +PySane_open(PyObject *self, PyObject *args) +{ + SaneDevObject *rv; + SANE_Status st; + char *name; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + rv = newSaneDevObject(); + if ( rv == NULL ) + return NULL; + st = sane_open(name, &(rv->h)); + if (st) + { + Py_DECREF(rv); + return PySane_Error(st); + } + return (PyObject *)rv; +} + +static PyObject * +PySane_OPTION_IS_ACTIVE(PyObject *self, PyObject *args) +{ + SANE_Int cap; + long lg; + + if (!PyArg_ParseTuple(args, "l", &lg)) + return NULL; + cap=lg; + return PyInt_FromLong( SANE_OPTION_IS_ACTIVE(cap)); +} + +static PyObject * +PySane_OPTION_IS_SETTABLE(PyObject *self, PyObject *args) +{ + SANE_Int cap; + long lg; + + if (!PyArg_ParseTuple(args, "l", &lg)) + return NULL; + cap=lg; + return PyInt_FromLong( SANE_OPTION_IS_SETTABLE(cap)); +} + + +/* List of functions defined in the module */ + +static PyMethodDef PySane_methods[] = { + {"init", PySane_init, 1}, + {"exit", PySane_exit, 1}, + {"get_devices", PySane_get_devices, 1}, + {"_open", PySane_open, 1}, + {"OPTION_IS_ACTIVE", PySane_OPTION_IS_ACTIVE, 1}, + {"OPTION_IS_SETTABLE", PySane_OPTION_IS_SETTABLE, 1}, + {NULL, NULL} /* sentinel */ +}; + + +static void +insint(PyObject *d, char *name, int value) +{ + PyObject *v = PyInt_FromLong((long) value); + if (!v || PyDict_SetItemString(d, name, v)) + Py_FatalError("can't initialize sane module"); + + Py_DECREF(v); +} + +void +init_sane(void) +{ + PyObject *m, *d; + + /* Create the module and add the functions */ + m = Py_InitModule("_sane", PySane_methods); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyString_FromString("_sane.error"); + PyDict_SetItemString(d, "error", ErrorObject); + + insint(d, "INFO_INEXACT", SANE_INFO_INEXACT); + insint(d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS); + insint(d, "RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS); + + insint(d, "FRAME_GRAY", SANE_FRAME_GRAY); + insint(d, "FRAME_RGB", SANE_FRAME_RGB); + insint(d, "FRAME_RED", SANE_FRAME_RED); + insint(d, "FRAME_GREEN", SANE_FRAME_GREEN); + insint(d, "FRAME_BLUE", SANE_FRAME_BLUE); + + insint(d, "CONSTRAINT_NONE", SANE_CONSTRAINT_NONE); + insint(d, "CONSTRAINT_RANGE", SANE_CONSTRAINT_RANGE); + insint(d, "CONSTRAINT_WORD_LIST", SANE_CONSTRAINT_WORD_LIST); + insint(d, "CONSTRAINT_STRING_LIST", SANE_CONSTRAINT_STRING_LIST); + + insint(d, "TYPE_BOOL", SANE_TYPE_BOOL); + insint(d, "TYPE_INT", SANE_TYPE_INT); + insint(d, "TYPE_FIXED", SANE_TYPE_FIXED); + insint(d, "TYPE_STRING", SANE_TYPE_STRING); + insint(d, "TYPE_BUTTON", SANE_TYPE_BUTTON); + insint(d, "TYPE_GROUP", SANE_TYPE_GROUP); + + insint(d, "UNIT_NONE", SANE_UNIT_NONE); + insint(d, "UNIT_PIXEL", SANE_UNIT_PIXEL); + insint(d, "UNIT_BIT", SANE_UNIT_BIT); + insint(d, "UNIT_MM", SANE_UNIT_MM); + insint(d, "UNIT_DPI", SANE_UNIT_DPI); + insint(d, "UNIT_PERCENT", SANE_UNIT_PERCENT); + insint(d, "UNIT_MICROSECOND", SANE_UNIT_MICROSECOND); + + insint(d, "CAP_SOFT_SELECT", SANE_CAP_SOFT_SELECT); + insint(d, "CAP_HARD_SELECT", SANE_CAP_HARD_SELECT); + insint(d, "CAP_SOFT_DETECT", SANE_CAP_SOFT_DETECT); + insint(d, "CAP_EMULATED", SANE_CAP_EMULATED); + insint(d, "CAP_AUTOMATIC", SANE_CAP_AUTOMATIC); + insint(d, "CAP_INACTIVE", SANE_CAP_INACTIVE); + insint(d, "CAP_ADVANCED", SANE_CAP_ADVANCED); + + /* handy for checking array lengths: */ + insint(d, "SANE_WORD_SIZE", sizeof(SANE_Word)); + + /* possible return values of set_option() */ + insint(d, "INFO_INEXACT", SANE_INFO_INEXACT); + insint(d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS); + insint(d, "INFO_RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS); + + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module _sane"); + +#ifdef WITH_NUMARRAY + import_libnumarray(); + if (PyErr_Occurred()) + PyErr_Clear(); + else + /* this global variable is declared just in front of the + arr_snap() function and should be set to 1 after + successfully importing the numarray module. */ + NUMARRAY_IMPORTED = 1; + +#endif /* WITH_NUMARRAY */ +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py new file mode 100755 index 00000000000..0104af2d550 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +# +# Shows how to scan a 16 bit grayscale image into a numarray object +# + +# Get the path set up to find PIL modules if not installed yet: +import sys ; sys.path.append('../PIL') + +from numarray import * +import sane +import Image + +def toImage(arr): + if arr.type().bytes == 1: + # need to swap coordinates btw array and image (with [::-1]) + im = Image.fromstring('L', arr.shape[::-1], arr.tostring()) + else: + arr_c = arr - arr.min() + arr_c *= (255./arr_c.max()) + arr = arr_c.astype(UInt8) + # need to swap coordinates btw array and image (with [::-1]) + im = Image.fromstring('L', arr.shape[::-1], arr.tostring()) + return im + +print 'SANE version:', sane.init() +print 'Available devices=', sane.get_devices() + +s = sane.open(sane.get_devices()[0][0]) + +# Set scan parameters +s.mode = 'gray' +s.br_x=320. ; s.br_y=240. + +print 'Device parameters:', s.get_parameters() + +s.depth=16 +arr16 = s.arr_scan() +toImage(arr16).show() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py new file mode 100755 index 00000000000..016361f8a82 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# +# Shows how to scan a color image into a PIL rgb-image +# + +# Get the path set up to find PIL modules if not installed yet: +import sys ; sys.path.append('../PIL') + +import sane +print 'SANE version:', sane.init() +print 'Available devices=', sane.get_devices() + +s = sane.open(sane.get_devices()[0][0]) + +s.mode = 'color' +s.br_x=320. ; s.br_y=240. + +print 'Device parameters:', s.get_parameters() + +# Initiate the scan +s.start() + +# Get an Image object +# (For my B&W QuickCam, this is a grey-scale image. Other scanning devices +# may return a +im=s.snap() + +# Write the image out as a GIF file +#im.save('foo.gif') + +# The show method() simply saves the image to a temporary file and calls "xv". +im.show() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py new file mode 100755 index 00000000000..27be5a259c4 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py @@ -0,0 +1,289 @@ +# sane.py +# +# Python wrapper on top of the _sane module, which is in turn a very +# thin wrapper on top of the SANE library. For a complete understanding +# of SANE, consult the documentation at the SANE home page: +# http://www.mostang.com/sane/ . + +__version__ = '2.0' +__author__ = ['Andrew Kuchling', 'Ralph Heinkel'] + +from PIL import Image + +import _sane +from _sane import * + +TYPE_STR = { TYPE_BOOL: "TYPE_BOOL", TYPE_INT: "TYPE_INT", + TYPE_FIXED: "TYPE_FIXED", TYPE_STRING: "TYPE_STRING", + TYPE_BUTTON: "TYPE_BUTTON", TYPE_GROUP: "TYPE_GROUP" } + +UNIT_STR = { UNIT_NONE: "UNIT_NONE", + UNIT_PIXEL: "UNIT_PIXEL", + UNIT_BIT: "UNIT_BIT", + UNIT_MM: "UNIT_MM", + UNIT_DPI: "UNIT_DPI", + UNIT_PERCENT: "UNIT_PERCENT", + UNIT_MICROSECOND: "UNIT_MICROSECOND" } + + +class Option: + """Class representing a SANE option. + Attributes: + index -- number from 0 to n, giving the option number + name -- a string uniquely identifying the option + title -- single-line string containing a title for the option + desc -- a long string describing the option; useful as a help message + type -- type of this option. Possible values: TYPE_BOOL, + TYPE_INT, TYPE_STRING, and so forth. + unit -- units of this option. Possible values: UNIT_NONE, + UNIT_PIXEL, etc. + size -- size of the value in bytes + cap -- capabilities available; CAP_EMULATED, CAP_SOFT_SELECT, etc. + constraint -- constraint on values. Possible values: + None : No constraint + (min,max,step) Integer values, from min to max, stepping by + list of integers or strings: only the listed values are allowed + """ + + def __init__(self, args, scanDev): + import string + self.scanDev = scanDev # needed to get current value of this option + self.index, self.name = args[0], args[1] + self.title, self.desc = args[2], args[3] + self.type, self.unit = args[4], args[5] + self.size, self.cap = args[6], args[7] + self.constraint = args[8] + def f(x): + if x=='-': return '_' + else: return x + if type(self.name)!=type(''): self.py_name=str(self.name) + else: self.py_name=string.join(map(f, self.name), '') + + def is_active(self): + return _sane.OPTION_IS_ACTIVE(self.cap) + def is_settable(self): + return _sane.OPTION_IS_SETTABLE(self.cap) + def __repr__(self): + if self.is_settable(): + settable = 'yes' + else: + settable = 'no' + if self.is_active(): + active = 'yes' + curValue = repr(getattr(self.scanDev, self.py_name)) + else: + active = 'no' + curValue = '' + s = """\nName: %s +Cur value: %s +Index: %d +Title: %s +Desc: %s +Type: %s +Unit: %s +Constr: %s +active: %s +settable: %s\n""" % (self.py_name, curValue, + self.index, self.title, self.desc, + TYPE_STR[self.type], UNIT_STR[self.unit], + `self.constraint`, active, settable) + return s + + +class _SaneIterator: + """ intended for ADF scans. + """ + + def __init__(self, device): + self.device = device + + def __iter__(self): + return self + + def __del__(self): + self.device.cancel() + + def next(self): + try: + self.device.start() + except error, v: + if v == 'Document feeder out of documents': + raise StopIteration + else: + raise + return self.device.snap(1) + + + +class SaneDev: + """Class representing a SANE device. + Methods: + start() -- initiate a scan, using the current settings + snap() -- snap a picture, returning an Image object + arr_snap() -- snap a picture, returning a numarray object + cancel() -- cancel an in-progress scanning operation + fileno() -- return the file descriptor for the scanner (handy for select) + + Also available, but rather low-level: + get_parameters() -- get the current parameter settings of the device + get_options() -- return a list of tuples describing all the options. + + Attributes: + optlist -- list of option names + + You can also access an option name to retrieve its value, and to + set it. For example, if one option has a .name attribute of + imagemode, and scanner is a SaneDev object, you can do: + print scanner.imagemode + scanner.imagemode = 'Full frame' + scanner.['imagemode'] returns the corresponding Option object. + """ + def __init__(self, devname): + d=self.__dict__ + d['sane_signature'] = self._getSaneSignature(devname) + d['scanner_model'] = d['sane_signature'][1:3] + d['dev'] = _sane._open(devname) + self.__load_option_dict() + + def _getSaneSignature(self, devname): + devices = get_devices() + if not devices: + raise RuntimeError('no scanner available') + for dev in devices: + if devname == dev[0]: + return dev + raise RuntimeError('no such scan device "%s"' % devname) + + def __load_option_dict(self): + d=self.__dict__ + d['opt']={} + optlist=d['dev'].get_options() + for t in optlist: + o=Option(t, self) + if o.type!=TYPE_GROUP: + d['opt'][o.py_name]=o + + def __setattr__(self, key, value): + dev=self.__dict__['dev'] + optdict=self.__dict__['opt'] + if not optdict.has_key(key): + self.__dict__[key]=value ; return + opt=optdict[key] + if opt.type==TYPE_GROUP: + raise AttributeError, "Groups can't be set: "+key + if not _sane.OPTION_IS_ACTIVE(opt.cap): + raise AttributeError, 'Inactive option: '+key + if not _sane.OPTION_IS_SETTABLE(opt.cap): + raise AttributeError, "Option can't be set by software: "+key + if type(value) == int and opt.type == TYPE_FIXED: + # avoid annoying errors of backend if int is given instead float: + value = float(value) + self.last_opt = dev.set_option(opt.index, value) + # do binary AND to find if we have to reload options: + if self.last_opt & INFO_RELOAD_OPTIONS: + self.__load_option_dict() + + def __getattr__(self, key): + dev=self.__dict__['dev'] + optdict=self.__dict__['opt'] + if key=='optlist': + return self.opt.keys() + if key=='area': + return (self.tl_x, self.tl_y),(self.br_x, self.br_y) + if not optdict.has_key(key): + raise AttributeError, 'No such attribute: '+key + opt=optdict[key] + if opt.type==TYPE_BUTTON: + raise AttributeError, "Buttons don't have values: "+key + if opt.type==TYPE_GROUP: + raise AttributeError, "Groups don't have values: "+key + if not _sane.OPTION_IS_ACTIVE(opt.cap): + raise AttributeError, 'Inactive option: '+key + value = dev.get_option(opt.index) + return value + + def __getitem__(self, key): + return self.opt[key] + + def get_parameters(self): + """Return a 5-tuple holding all the current device settings: + (format, last_frame, (pixels_per_line, lines), depth, bytes_per_line) + +- format is one of 'L' (grey), 'RGB', 'R' (red), 'G' (green), 'B' (blue). +- last_frame [bool] indicates if this is the last frame of a multi frame image +- (pixels_per_line, lines) specifies the size of the scanned image (x,y) +- lines denotes the number of scanlines per frame +- depth gives number of pixels per sample +""" + return self.dev.get_parameters() + + def get_options(self): + "Return a list of tuples describing all the available options" + return self.dev.get_options() + + def start(self): + "Initiate a scanning operation" + return self.dev.start() + + def cancel(self): + "Cancel an in-progress scanning operation" + return self.dev.cancel() + + def snap(self, no_cancel=0): + "Snap a picture, returning a PIL image object with the results" + (mode, last_frame, + (xsize, ysize), depth, bytes_per_line) = self.get_parameters() + if mode in ['gray', 'red', 'green', 'blue']: + format = 'L' + elif mode == 'color': + format = 'RGB' + else: + raise ValueError('got unknown "mode" from self.get_parameters()') + im=Image.new(format, (xsize,ysize)) + self.dev.snap( im.im.id, no_cancel ) + return im + + def scan(self): + self.start() + return self.snap() + + def multi_scan(self): + return _SaneIterator(self) + + def arr_snap(self, multipleOf=1): + """Snap a picture, returning a numarray object with the results. + By default the resulting array has the same number of pixels per + line as specified in self.get_parameters()[2][0] + However sometimes it is necessary to obtain arrays where + the number of pixels per line is e.g. a multiple of 4. This can then + be achieved with the option 'multipleOf=4'. So if the scanner + scanned 34 pixels per line, you will obtain an array with 32 pixels + per line. + """ + (mode, last_frame, (xsize, ysize), depth, bpl) = self.get_parameters() + if not mode in ['gray', 'red', 'green', 'blue']: + raise RuntimeError('arr_snap() only works with monochrome images') + if multipleOf < 1: + raise ValueError('option "multipleOf" must be a positive number') + elif multipleOf > 1: + pixels_per_line = xsize - divmod(xsize, 4)[1] + else: + pixels_per_line = xsize + return self.dev.arr_snap(pixels_per_line) + + def arr_scan(self, multipleOf=1): + self.start() + return self.arr_snap(multipleOf=multipleOf) + + def fileno(self): + "Return the file descriptor for the scanning device" + return self.dev.fileno() + + def close(self): + self.dev.close() + + +def open(devname): + "Open a device for scanning" + new=SaneDev(devname) + return new diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt new file mode 100755 index 00000000000..db86938e313 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt @@ -0,0 +1,294 @@ +The _sane_ module is an Python interface to the SANE (Scanning is Now +Easy) library, which provides access to various raster scanning +devices such as flatbed scanners and digital cameras. For more +information about SANE, consult the SANE Web site at +http://www.mostang.com/sane/ . Note that this +documentation doesn't duplicate all the information in the SANE +documentation, which you must also consult to get a complete +understanding. + +This module has been originally developed by A.M. Kuchling (amk1@erols.com), +now development has been taken over by Ralph Heinkel (rheinkel-at-email.de). +If you write to me please make sure to have the word 'SANE' or 'sane' in +the subject of your mail, otherwise it might be classified as spam in the +future. + + +The module exports two object types, a bunch of constants, and two +functions. + +get_devices() + Return a list of 4-tuples containing the available scanning + devices. Each tuple contains 4 strings: the device name, suitable for + passing to _open()_; the device's vendor; the model; and the type of + device, such as 'virtual device' or 'video camera'. + + >>> import sane ; sane.get_devices() + [('epson:libusb:001:004', 'Epson', 'GT-8300', 'flatbed scanner')] + +open(devicename) + Open a device, given a string containing its name. SANE + devices have names like 'epson:libusb:001:004'. If the attempt + to open the device fails, a _sane.error_ exception will be raised. If + there are no problems, a SaneDev object will be returned. + As an easy way to open the scanner (if only one is available) just type + >>> sane.open(sane.get_devices()[0][0]) + + +SaneDev objects +=============== + +The basic process of scanning an image consists of getting a SaneDev +object for the device, setting various parameters, starting the scan, +and then reading the image data. Images are composed of one or more +frames; greyscale and one-pass colour scanners return a single frame +containing all the image data, but 3-pass scanners will usually return +3 frames, one for each of the red, green, blue channels. + +Methods: +-------- +fileno() + Returns a file descriptor for the scanning device. This + method's existence means that SaneDev objects can be used by the + select module. + +get_parameters() + Return a tuple containing information about the current settings of + the device and the current frame: (format, last_frame, + pixels_per_line, lines, depth, bytes_per_line). + + mode -- 'gray' for greyscale image, 'color' for RGB image, or + one of 'red', 'green', 'blue' if the image is a single + channel of an RGB image (from PIL's point of view, + this is equivalent to 'L'). + last_frame -- A Boolean value, which is true if this is the + last frame of the image, and false otherwise. + pixels_per_line -- Width of the frame. + lines -- Height of the frame. + depth -- Depth of the image, measured in bits. SANE will only + allow using 8, 16, or 24-bit depths. + bytes_per_line -- Bytes required to store a single line of + data, as computed from pixels_per_line and depth. + +start() + Start a scan. This function must be called before the + _snap()_ method can be used. + +cancel() + Cancel a scan already in progress. + +snap(no_cancel=0) + Snap a single frame of data, returning a PIL Image object + containing the data. If no_cancel is false, the Sane library function + sane_cancel is called after the scan. This is reasonable in most cases, + but may cause backends for duplex ADF scanners to drop the backside image, + when snap() is called for the front side image. If no_cancel is true, + cancel() should be called manually, after all scans are finished. + +scan() + This is just a shortcut for s.start(); s.snap() + Returns a PIL image + +multi_scan() + This method returns an iterator. It is intended to be used for + scanning with an automatic document feeder. The next() method of the + iterator tries to start a scan. If this is successful, it returns a + PIL Image object, like scan(); if the document feeder runs out of + paper, it raises StopIteration, thereby signaling that the sequence + is ran out of items. + +arr_snap(multipleOf=1) + same as snap, but the result is a NumArray object. (Not that + num_array must be installed already at compilation time, otherwise + this feature will not be activated). + By default the resulting array has the same number of pixels per + line as specified in self.get_parameters()[2][0] + However sometimes it is necessary to obtain arrays where + the number of pixels per line is e.g. a multiple of 4. This can then + be achieved with the option 'multipleOf=4'. So if the scanner + scanned 34 pixels per line, you will obtain an array with 32 pixels + per line. + Note that this only works with monochrome images (e.g. gray-scales) + +arr_scan(multipleOf=1) + This is just a shortcut for s.start(); s.arr_snap(multipleOf=1) + Returns a NumArray object + +close() + Closes the object. + + +Attributes: +----------- +SaneDev objects have a few fixed attributes which are always +available, and a larger collection of attributes which vary depending +on the device. An Epson 1660 photo scanner has attributes like +'mode', 'depth', etc. +Another (pseudo scanner), the _pnm:0_ device, takes a PNM file and +simulates a scanner using the image data; a SaneDev object +representing the _pnm:0_ device therefore has a _filename_ attribute +which can be changed to specify the filename, _contrast_ and +_brightness_ attributes to modify the returned image, and so forth. + +The values of the scanner options may be an integer, floating-point +value, or string, depending on the nature of the option. + +sane_signature + The tuple for this scandev that is returned by sane.get_devices() + e.g. ('epson:libusb:001:006', 'Epson', 'GT-8300', 'flatbed scanner') + +scanner_model + same as sane_signature[1:3], i.e. ('Epson', 'GT-8300') for the case above. + +optlist + A list containing the all the options supported by this device. + + >>> import sane ; s=sane.open('epson:libusb:001:004') ; s.optlist + ['focus_position', 'color_correction', 'sharpness', ...., 'br_x'] + +A closer look at all options listed in s.optlist can be obtained +through the SaneOption objects. + +SaneOption objects +================== + +SANE's option handling is its most elaborate subsystem, intended to +allow automatically generating dialog boxes and prompts for user +configuration of the scanning device. The SaneOption object can be +used to get a human-readable name and description for an option, the +units to use, and what the legal values are. No information about the +current value of the option is available; for that, read the +corresponding attribute of a SaneDev object. + +This documentation does not explain all the details of SANE's option +handling; consult the SANE documentation for all the details. + +A scandevice option is accessed via __getitem__. For example +s['mode'] returns the option descriptor for the mode-option which +controls whether the scanner works in color, grayscale, or b/w mode. + +>>> s['mode'] +Name: mode +Cur value: Color +Index: 2 +Title: Scan mode +Desc: Selects the scan mode (e.g., lineart, monochrome, or color). +Type: TYPE_STRING +Unit: UNIT_NONE +Constr: ['Binary', 'Gray', 'Color'] +active: yes +settable: yes + +In order to change 'mode' to 'gray', just type: +>>> s.mode = 'gray' + + +With the attributes and methods of sane-option objects it is possible +to access individual option values: + +is_active() + Returns true if the option is active. + +is_settable() + Returns true if the option can be set under software control. + + +Attributes: + +cap + An integer containing various flags about the object's + capabilities; whether it's active, whether it's settable, etc. Also + available as the _capability_ attribute. + +constraint + The constraint placed on the value of this option. If it's + _None_, there are essentially no constraint of the value. It may also + be a list of integers or strings, in which case the value *must* be + one of the possibilities in the list. Numeric values may have a + 3-tuple as the constraint; this 3-tuple contains _(minimum, maximum, + increment)_, and the value must be in the defined range. + +desc + A lengthy description of what the option does; it may be shown + to the user for clarification. + +index + An integer giving the option's index in the option list. + +name + A short name for the option, as it comes from the sane-backend. + +py_name + The option's name, as a legal Python identifier. The name + attribute may contain the '-' character, so it will be converted to + '_' for the py_name attribute. + +size + For a string-valued option, this is the maximum length allowed. + +title + A single-line string that can be used as a title string. + +type + A constant giving the type of this option: will be one of the following + constants found in the SANE module: + TYPE_BOOL + TYPE_INT + TYPE_FIXED + TYPE_STRING + TYPE_BUTTON + TYPE_GROUP + +unit + For numeric-valued options, this is a constant representing + the unit used for this option. It will be one of the following + constants found in the SANE module: + UNIT_NONE + UNIT_PIXEL + UNIT_BIT + UNIT_MM + UNIT_DPI + UNIT_PERCENT + + + +Example us usage: +================= +>>> import sane +>>> print 'SANE version:', sane.init() +>>> print 'Available devices=', sane.get_devices() +SANE version: (16777230, 1, 0, 14) +>>> s = sane.open(sane.get_devices()[0][0]) +>>> print 'Device parameters:', s.get_parameters() +Device parameters: ('L', 1, (424, 585), 1, 53) +>>> print s.resolution +50 + +## In order to scan a color image into a PIL object: +>>> s.mode = 'color' +>>> s.start() +>>> img = s.snap() +>>> img.show() + + +## In order to obtain a 16-bit grayscale image at 100DPI in a numarray object +## with bottom-right coordinates set to (160, 120) [in millimeter] : +>>> s.mode = 'gray' +>>> s.br_x=160. ; s.br_y=120. +>>> s.resolution = 100 +>>> s.depth=16 +>>> s.start() +>>> s.get_parameters()[2] # just check the size +(624, 472) +>>> arr16 = s.arr_snap() +>>> arr16 +array([[63957, 64721, 65067, ..., 65535, 65535, 65535], + [63892, 64342, 64236, ..., 65535, 65535, 65535], + [64286, 64248, 64705, ..., 65535, 65535, 65535], + ..., + [65518, 65249, 65058, ..., 65535, 65535, 65535], + [64435, 65047, 65081, ..., 65535, 65535, 65535], + [65309, 65438, 65535, ..., 65535, 65535, 65535]], type=UInt16) +>>> arr16.shape # inverse order of coordinates, first y, then x! +(472, 624) + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py new file mode 100755 index 00000000000..3837198ec94 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py @@ -0,0 +1,24 @@ +from distutils.core import setup, Extension + +PIL_BUILD_DIR = '..' +PIL_IMAGING_DIR = PIL_BUILD_DIR+'/libImaging' + +defs = [] +try: + import numarray + defs.append(('WITH_NUMARRAY',None)) +except ImportError: + pass + +sane = Extension('_sane', + include_dirs = [PIL_IMAGING_DIR], + libraries = ['sane'], + library_dirs = [PIL_IMAGING_DIR], + define_macros = defs, + sources = ['_sane.c']) + +setup (name = 'pysane', + version = '2.0', + description = 'This is the pysane package', + py_modules = ['sane'], + ext_modules = [sane]) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README new file mode 100755 index 00000000000..a09b0621a1c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README @@ -0,0 +1,83 @@ +------- +Scripts +------- + +This directory contains a number of more or less trivial utilities +and demo programs. + +Comments and contributions are welcome. + + + +-------------------------------------------------------------------- +pildriver.py (by Eric S. Raymond) + +A class implementing an image-processing calculator for scripts. +Parses lists of commnds (or, called interactively, command-line +arguments) into image loads, transformations, and saves. + +-------------------------------------------------------------------- +viewer.py + +A simple image viewer. Can display all file formats handled by +PIL. Transparent images are properly handled. + +-------------------------------------------------------------------- +thresholder.py + +A simple utility that demonstrates how a transparent 1-bit overlay +can be used to show the current thresholding of an 8-bit image. + +-------------------------------------------------------------------- +enhancer.py + +Illustrates the ImageEnhance module. Drag the sliders to modify the +images. This might be very slow on some platforms, depending on the +Tk version. + +-------------------------------------------------------------------- +painter.py + +Illustrates how a painting program could be based on PIL and Tk. +Press the left mouse button and drag over the image to remove the +colour. Some clever tricks have been used to get decent performance +when updating the screen; see the sources for details. + +-------------------------------------------------------------------- +player.py + +A simple image sequence player. You can use either a sequence format +like FLI/FLC, GIF, or ARG, or give a number of images which are +interpreted as frames in a sequence. All frames must have the same +size. + +-------------------------------------------------------------------- +gifmaker.py + +Convert a sequence file to a GIF animation. + +Note that the GIF encoder provided with this release of PIL writes +uncompressed GIF files only, so the resulting animations are rather +large compared with these created by other tools. + +-------------------------------------------------------------------- +explode.py + +Split a sequence file into individual frames. + +-------------------------------------------------------------------- +image2py.py + +Convert an image to a Python module containing an IMAGE variable. +Note that the module using the module must include JPEG and ZIP +decoders, unless the -u option is used. + +-------------------------------------------------------------------- +olesummary.py + +Uses the OleFileIO module to dump the summary information from an OLE +structured storage file. This works with most OLE files, including +Word documents, FlashPix images, etc. + +Note that datetime fields currently show the number of seconds since +January 1st, 1601. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py new file mode 100755 index 00000000000..957b51c8d91 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py @@ -0,0 +1,53 @@ +# +# The Python Imaging Library +# $Id$ +# +# this demo script creates four windows containing an image and a slider. +# drag the slider to modify the image. +# + +from Tkinter import * +from PIL import Image, ImageTk, ImageEnhance +import sys + +# +# enhancer widget + +class Enhance(Frame): + def __init__(self, master, image, name, enhancer, lo, hi): + Frame.__init__(self, master) + + # set up the image + self.tkim = ImageTk.PhotoImage(image.mode, image.size) + self.enhancer = enhancer(image) + self.update("1.0") # normalize + + # image window + Label(self, image=self.tkim).pack() + + # scale + s = Scale(self, label=name, orient=HORIZONTAL, + from_=lo, to=hi, resolution=0.01, + command=self.update) + s.set(self.value) + s.pack() + + def update(self, value): + self.value = eval(value) + self.tkim.paste(self.enhancer.enhance(self.value)) + +# +# main + +root = Tk() + +im = Image.open(sys.argv[1]) + +im.thumbnail((200, 200)) + +Enhance(root, im, "Color", ImageEnhance.Color, 0.0, 4.0).pack() +Enhance(Toplevel(), im, "Sharpness", ImageEnhance.Sharpness, -2.0, 2.0).pack() +Enhance(Toplevel(), im, "Brightness", ImageEnhance.Brightness, -1.0, 3.0).pack() +Enhance(Toplevel(), im, "Contrast", ImageEnhance.Contrast, -1.0, 3.0).pack() + +root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py new file mode 100755 index 00000000000..a336f06990c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py @@ -0,0 +1,107 @@ +# +# The Python Imaging Library +# $Id$ +# +# split an animation into a number of frame files +# + +from PIL import Image +import os, string, sys + +class Interval: + + def __init__(self, interval = "0"): + + self.setinterval(interval) + + def setinterval(self, interval): + + self.hilo = [] + + for s in string.split(interval, ","): + if not string.strip(s): + continue + try: + v = string.atoi(s) + if v < 0: + lo, hi = 0, -v + else: + lo = hi = v + except ValueError: + i = string.find(s, "-") + lo, hi = string.atoi(s[:i]), string.atoi(s[i+1:]) + + self.hilo.append((hi, lo)) + + if not self.hilo: + self.hilo = [(sys.maxint, 0)] + + def __getitem__(self, index): + + for hi, lo in self.hilo: + if hi >= index >= lo: + return 1 + return 0 + +# -------------------------------------------------------------------- +# main program + +html = 0 + +if sys.argv[1:2] == ["-h"]: + html = 1 + del sys.argv[1] + +if not sys.argv[2:]: + print + print "Syntax: python explode.py infile template [range]" + print + print "The template argument is used to construct the names of the" + print "individual frame files. The frames are numbered file001.ext," + print "file002.ext, etc. You can insert %d to control the placement" + print "and syntax of the frame number." + print + print "The optional range argument specifies which frames to extract." + print "You can give one or more ranges like 1-10, 5, -15 etc. If" + print "omitted, all frames are extracted." + sys.exit(1) + +infile = sys.argv[1] +outfile = sys.argv[2] + +frames = Interval(string.join(sys.argv[3:], ",")) + +try: + # check if outfile contains a placeholder + outfile % 1 +except TypeError: + file, ext = os.path.splitext(outfile) + outfile = file + "%03d" + ext + +ix = 1 + +im = Image.open(infile) + +if html: + file, ext = os.path.splitext(outfile) + html = open(file+".html", "w") + html.write("\n\n") + +while 1: + + if frames[ix]: + im.save(outfile % ix) + print outfile % ix + + if html: + html.write("
\n" % outfile % ix) + + try: + im.seek(ix) + except EOFError: + break + + ix = ix + 1 + +if html: + html.write("\n\n") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py new file mode 100755 index 00000000000..95524eacc1c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py @@ -0,0 +1,135 @@ +# +# The Python Imaging Library +# $Id$ +# +# convert sequence format to GIF animation +# +# history: +# 97-01-03 fl created +# +# Copyright (c) Secret Labs AB 1997. All rights reserved. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +# +# For special purposes, you can import this module and call +# the makedelta or compress functions yourself. For example, +# if you have an application that generates a sequence of +# images, you can convert it to a GIF animation using some- +# thing like the following code: +# +# import Image +# import gifmaker +# +# sequence = [] +# +# # generate sequence +# for i in range(100): +# im = +# sequence.append(im) +# +# # write GIF animation +# fp = open("out.gif", "wb") +# gifmaker.makedelta(fp, sequence) +# fp.close() +# +# Alternatively, use an iterator to generate the sequence, and +# write data directly to a socket. Or something... +# + +from PIL import Image, ImageChops +import string + +from PIL.GifImagePlugin import getheader, getdata + +# -------------------------------------------------------------------- +# sequence iterator + +class image_sequence: + def __init__(self, im): + self.im = im + def __getitem__(self, ix): + try: + if ix: + self.im.seek(ix) + return self.im + except EOFError: + raise IndexError # end of sequence + +# -------------------------------------------------------------------- +# straightforward delta encoding + +def makedelta(fp, sequence): + """Convert list of image frames to a GIF animation file""" + + frames = 0 + + previous = None + + for im in sequence: + + # + # FIXME: write graphics control block before each frame + + if not previous: + + # global header + for s in getheader(im) + getdata(im): + fp.write(s) + + else: + + # delta frame + delta = ImageChops.subtract_modulo(im, previous) + + bbox = delta.getbbox() + + if bbox: + + # compress difference + for s in getdata(im.crop(bbox), offset = bbox[:2]): + fp.write(s) + + else: + # FIXME: what should we do in this case? + pass + + previous = im.copy() + + frames = frames + 1 + + fp.write(";") + + return frames + +# -------------------------------------------------------------------- +# main hack + +def compress(infile, outfile): + + # open input image, and force loading of first frame + im = Image.open(infile) + im.load() + + # open output file + fp = open(outfile, "wb") + + seq = image_sequence(im) + + makedelta(fp, seq) + + fp.close() + + +if __name__ == "__main__": + + import sys + + if len(sys.argv) < 3: + print "GIFMAKER -- create GIF animations" + print "Usage: gifmaker infile outfile" + sys.exit(1) + + compress(sys.argv[1], sys.argv[2]) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py new file mode 100755 index 00000000000..efe307386ff --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py @@ -0,0 +1,72 @@ +# +# The Python Imaging Library +# $Id$ +# +# this demo script illustrates pasting into an already displayed +# photoimage. note that the current version of Tk updates the whole +# image everytime we paste, so to get decent performance, we split +# the image into a set of tiles. +# + +from Tkinter import * +from PIL import Image, ImageTk +import sys + +# +# painter widget + +class PaintCanvas(Canvas): + def __init__(self, master, image): + Canvas.__init__(self, master, width=image.size[0], height=image.size[1]) + + # fill the canvas + self.tile = {} + self.tilesize = tilesize = 32 + xsize, ysize = image.size + for x in range(0, xsize, tilesize): + for y in range(0, ysize, tilesize): + box = x, y, min(xsize, x+tilesize), min(ysize, y+tilesize) + tile = ImageTk.PhotoImage(image.crop(box)) + self.create_image(x, y, image=tile, anchor=NW) + self.tile[(x,y)] = box, tile + + self.image = image + + self.bind("", self.paint) + + def paint(self, event): + xy = event.x - 10, event.y - 10, event.x + 10, event.y + 10 + im = self.image.crop(xy) + + # process the image in some fashion + im = im.convert("L") + + self.image.paste(im, xy) + self.repair(xy) + + def repair(self, box): + # update canvas + dx = box[0] % self.tilesize + dy = box[1] % self.tilesize + for x in range(box[0]-dx, box[2]+1, self.tilesize): + for y in range(box[1]-dy, box[3]+1, self.tilesize): + try: + xy, tile = self.tile[(x, y)] + tile.paste(self.image.crop(xy)) + except KeyError: + pass # outside the image + self.update_idletasks() + +# +# main + +root = Tk() + +im = Image.open(sys.argv[1]) + +if im.mode != "RGB": + im = im.convert("RGB") + +PaintCanvas(root, im).pack() + +root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py new file mode 100755 index 00000000000..1c688f7c9b0 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py @@ -0,0 +1,96 @@ +#! /usr/local/bin/python +# +# The Python Imaging Library. +# $Id$ +# +# convert image files +# +# History: +# 0.1 96-04-20 fl Created +# 0.2 96-10-04 fl Use draft mode when converting images +# 0.3 96-12-30 fl Optimize output (PNG, JPEG) +# 0.4 97-01-18 fl Made optimize an option (PNG, JPEG) +# 0.5 98-12-30 fl Fixed -f option (from Anthony Baxter) +# + +import site +import getopt, string, sys + +from PIL import Image + +def usage(): + print "PIL Convert 0.5/1998-12-30 -- convert image files" + print "Usage: pilconvert [option] infile outfile" + print + print "Options:" + print + print " -c convert to format (default is given by extension)" + print + print " -g convert to greyscale" + print " -p convert to palette image (using standard palette)" + print " -r convert to rgb" + print + print " -o optimize output (trade speed for size)" + print " -q set compression quality (0-100, JPEG only)" + print + print " -f list supported file formats" + sys.exit(1) + +if len(sys.argv) == 1: + usage() + +try: + opt, argv = getopt.getopt(sys.argv[1:], "c:dfgopq:r") +except getopt.error, v: + print v + sys.exit(1) + +format = None +convert = None + +options = { } + +for o, a in opt: + + if o == "-f": + Image.init() + id = Image.ID[:] + id.sort() + print "Supported formats (* indicates output format):" + for i in id: + if Image.SAVE.has_key(i): + print i+"*", + else: + print i, + sys.exit(1) + + elif o == "-c": + format = a + + if o == "-g": + convert = "L" + elif o == "-p": + convert = "P" + elif o == "-r": + convert = "RGB" + + elif o == "-o": + options["optimize"] = 1 + elif o == "-q": + options["quality"] = string.atoi(a) + +if len(argv) != 2: + usage() + +try: + im = Image.open(argv[0]) + if convert and im.mode != convert: + im.draft(convert, im.size) + im = im.convert(convert) + if format: + apply(im.save, (argv[1], format), options) + else: + apply(im.save, (argv[1],), options) +except: + print "cannot convert image", + print "(%s:%s)" % (sys.exc_type, sys.exc_value) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py new file mode 100755 index 00000000000..5dd575a3fd6 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py @@ -0,0 +1,524 @@ +#!/usr/bin/env python +"""PILdriver, an image-processing calculator using PIL. + +An instance of class PILDriver is essentially a software stack machine +(Polish-notation interpreter) for sequencing PIL image +transformations. The state of the instance is the interpreter stack. + +The only method one will normally invoke after initialization is the +`execute' method. This takes an argument list of tokens, pushes them +onto the instance's stack, and then tries to clear the stack by +successive evaluation of PILdriver operators. Any part of the stack +not cleaned off persists and is part of the evaluation context for +the next call of the execute method. + +PILDriver doesn't catch any exceptions, on the theory that these +are actually diagnostic information that should be interpreted by +the calling code. + +When called as a script, the command-line arguments are passed to +a PILDriver instance. If there are no command-line arguments, the +module runs an interactive interpreter, each line of which is split into +space-separated tokens and passed to the execute method. + +In the method descriptions below, a first line beginning with the string +`usage:' means this method can be invoked with the token that follows +it. Following <>-enclosed arguments describe how the method interprets +the entries on the stack. Each argument specification begins with a +type specification: either `int', `float', `string', or `image'. + +All operations consume their arguments off the stack (use `dup' to +keep copies around). Use `verbose 1' to see the stack state displayed +before each operation. + +Usage examples: + + `show crop 0 0 200 300 open test.png' loads test.png, crops out a portion +of its upper-left-hand corner and displays the cropped portion. + + `save rotated.png rotate 30 open test.tiff' loads test.tiff, rotates it +30 degrees, and saves the result as rotated.png (in PNG format). +""" +# by Eric S. Raymond +# $Id$ + +# TO DO: +# 1. Add PILFont capabilities, once that's documented. +# 2. Add PILDraw operations. +# 3. Add support for composing and decomposing multiple-image files. +# + +from PIL import Image +import string + +class PILDriver: + + verbose = 0 + + def do_verbose(self): + """usage: verbose + + Set verbosity flag from top of stack. + """ + self.verbose = self.do_pop() + + # The evaluation stack (internal only) + + stack = [] # Stack of pending operations + + def push(self, item): + "Push an argument onto the evaluation stack." + self.stack = [item] + self.stack + + def top(self): + "Return the top-of-stack element." + return self.stack[0] + + # Stack manipulation (callable) + + def do_clear(self): + """usage: clear + + Clear the stack. + """ + self.stack = [] + + def do_pop(self): + """usage: pop + + Discard the top element on the stack. + """ + top = self.stack[0] + self.stack = self.stack[1:] + return top + + def do_dup(self): + """usage: dup + + Duplicate the top-of-stack item. + """ + if hasattr(self, 'format'): # If it's an image, do a real copy + dup = self.stack[0].copy() + else: + dup = self.stack[0] + self.stack = [dup] + self.stack + + def do_swap(self): + """usage: swap + + Swap the top-of-stack item with the next one down. + """ + self.stack = [self.stack[1], self.stack[0]] + self.stack[2:] + + # Image module functions (callable) + + def do_new(self): + """usage: new : + + Create and push a greyscale image of given size and color. + """ + xsize = int(self.do_pop()) + ysize = int(self.do_pop()) + color = int(self.do_pop()) + self.push(Image.new("L", (xsize, ysize), color)) + + def do_open(self): + """usage: open + + Open the indicated image, read it, push the image on the stack. + """ + self.push(Image.open(self.do_pop())) + + def do_blend(self): + """usage: blend + + Replace two images and an alpha with the blended image. + """ + image1 = self.do_pop() + image2 = self.do_pop() + alpha = float(self.do_pop()) + self.push(Image.blend(image1, image2, alpha)) + + def do_composite(self): + """usage: composite + + Replace two images and a mask with their composite. + """ + image1 = self.do_pop() + image2 = self.do_pop() + mask = self.do_pop() + self.push(Image.composite(image1, image2, mask)) + + def do_merge(self): + """usage: merge [ [ []]] + + Merge top-of stack images in a way described by the mode. + """ + mode = self.do_pop() + bandlist = [] + for band in mode: + bandlist.append(self.do_pop()) + self.push(Image.merge(mode, bandlist)) + + # Image class methods + + def do_convert(self): + """usage: convert + + Convert the top image to the given mode. + """ + mode = self.do_pop() + image = self.do_pop() + self.push(image.convert(mode)) + + def do_copy(self): + """usage: copy + + Make and push a true copy of the top image. + """ + self.dup() + + def do_crop(self): + """usage: crop + + Crop and push a rectangular region from the current image. + """ + left = int(self.do_pop()) + upper = int(self.do_pop()) + right = int(self.do_pop()) + lower = int(self.do_pop()) + image = self.do_pop() + self.push(image.crop((left, upper, right, lower))) + + def do_draft(self): + """usage: draft + + Configure the loader for a given mode and size. + """ + mode = self.do_pop() + xsize = int(self.do_pop()) + ysize = int(self.do_pop()) + self.push(self.draft(mode, (xsize, ysize))) + + def do_filter(self): + """usage: filter + + Process the top image with the given filter. + """ + import ImageFilter + filter = eval("ImageFilter." + string.upper(self.do_pop())) + image = self.do_pop() + self.push(image.filter(filter)) + + def do_getbbox(self): + """usage: getbbox + + Push left, upper, right, and lower pixel coordinates of the top image. + """ + bounding_box = self.do_pop().getbbox() + self.push(bounding_box[3]) + self.push(bounding_box[2]) + self.push(bounding_box[1]) + self.push(bounding_box[0]) + + def do_getextrema(self): + """usage: extrema + + Push minimum and maximum pixel values of the top image. + """ + extrema = self.do_pop().extrema() + self.push(extrema[1]) + self.push(extrema[0]) + + def do_offset(self): + """usage: offset + + Offset the pixels in the top image. + """ + xoff = int(self.do_pop()) + yoff = int(self.do_pop()) + image = self.do_pop() + self.push(image.offset(xoff, yoff)) + + def do_paste(self): + """usage: paste + + Paste figure image into ground with upper left at given offsets. + """ + figure = self.do_pop() + xoff = int(self.do_pop()) + yoff = int(self.do_pop()) + ground = self.do_pop() + if figure.mode == "RGBA": + ground.paste(figure, (xoff, yoff), figure) + else: + ground.paste(figure, (xoff, yoff)) + self.push(ground) + + def do_resize(self): + """usage: resize + + Resize the top image. + """ + ysize = int(self.do_pop()) + xsize = int(self.do_pop()) + image = self.do_pop() + self.push(image.resize((xsize, ysize))) + + def do_rotate(self): + """usage: rotate + + Rotate image through a given angle + """ + angle = int(self.do_pop()) + image = self.do_pop() + self.push(image.rotate(angle)) + + def do_save(self): + """usage: save + + Save image with default options. + """ + filename = self.do_pop() + image = self.do_pop() + image.save(filename) + + def do_save2(self): + """usage: save2 + + Save image with specified options. + """ + filename = self.do_pop() + options = self.do_pop() + image = self.do_pop() + image.save(filename, None, options) + + def do_show(self): + """usage: show + + Display and pop the top image. + """ + self.do_pop().show() + + def do_thumbnail(self): + """usage: thumbnail + + Modify the top image in the stack to contain a thumbnail of itself. + """ + ysize = int(self.do_pop()) + xsize = int(self.do_pop()) + self.top().thumbnail((xsize, ysize)) + + def do_transpose(self): + """usage: transpose + + Transpose the top image. + """ + transpose = string.upper(self.do_pop()) + image = self.do_pop() + self.push(image.transpose(transpose)) + + # Image attributes + + def do_format(self): + """usage: format + + Push the format of the top image onto the stack. + """ + self.push(self.pop().format) + + def do_mode(self): + """usage: mode + + Push the mode of the top image onto the stack. + """ + self.push(self.pop().mode) + + def do_size(self): + """usage: size + + Push the image size on the stack as (y, x). + """ + size = self.pop().size + self.push(size[0]) + self.push(size[1]) + + # ImageChops operations + + def do_invert(self): + """usage: invert + + Invert the top image. + """ + import ImageChops + self.push(ImageChops.invert(self.do_pop())) + + def do_lighter(self): + """usage: lighter + + Pop the two top images, push an image of the lighter pixels of both. + """ + import ImageChops + image1 = self.do_pop() + image2 = self.do_pop() + self.push(ImageChops.lighter(image1, image2)) + + def do_darker(self): + """usage: darker + + Pop the two top images, push an image of the darker pixels of both. + """ + import ImageChops + image1 = self.do_pop() + image2 = self.do_pop() + self.push(ImageChops.darker(image1, image2)) + + def do_difference(self): + """usage: difference + + Pop the two top images, push the difference image + """ + import ImageChops + image1 = self.do_pop() + image2 = self.do_pop() + self.push(ImageChops.difference(image1, image2)) + + def do_multiply(self): + """usage: multiply + + Pop the two top images, push the multiplication image. + """ + import ImageChops + image1 = self.do_pop() + image2 = self.do_pop() + self.push(ImageChops.multiply(image1, image2)) + + def do_screen(self): + """usage: screen + + Pop the two top images, superimpose their inverted versions. + """ + import ImageChops + image2 = self.do_pop() + image1 = self.do_pop() + self.push(ImageChops.screen(image1, image2)) + + def do_add(self): + """usage: add + + Pop the two top images, produce the scaled sum with offset. + """ + import ImageChops + image1 = self.do_pop() + image2 = self.do_pop() + scale = float(self.do_pop()) + offset = int(self.do_pop()) + self.push(ImageChops.add(image1, image2, scale, offset)) + + def do_subtract(self): + """usage: subtract + + Pop the two top images, produce the scaled difference with offset. + """ + import ImageChops + image1 = self.do_pop() + image2 = self.do_pop() + scale = float(self.do_pop()) + offset = int(self.do_pop()) + self.push(ImageChops.subtract(image1, image2, scale, offset)) + + # ImageEnhance classes + + def do_color(self): + """usage: color + + Enhance color in the top image. + """ + import ImageEnhance + factor = float(self.do_pop()) + image = self.do_pop() + enhancer = ImageEnhance.Color(image) + self.push(enhancer.enhance(factor)) + + def do_contrast(self): + """usage: contrast + + Enhance contrast in the top image. + """ + import ImageEnhance + factor = float(self.do_pop()) + image = self.do_pop() + enhancer = ImageEnhance.Color(image) + self.push(enhancer.enhance(factor)) + + def do_brightness(self): + """usage: brightness + + Enhance brightness in the top image. + """ + import ImageEnhance + factor = float(self.do_pop()) + image = self.do_pop() + enhancer = ImageEnhance.Color(image) + self.push(enhancer.enhance(factor)) + + def do_sharpness(self): + """usage: sharpness + + Enhance sharpness in the top image. + """ + import ImageEnhance + factor = float(self.do_pop()) + image = self.do_pop() + enhancer = ImageEnhance.Color(image) + self.push(enhancer.enhance(factor)) + + # The interpreter loop + + def execute(self, list): + "Interpret a list of PILDriver commands." + list.reverse() + while len(list) > 0: + self.push(list[0]) + list = list[1:] + if self.verbose: + print "Stack: " + `self.stack` + top = self.top() + if type(top) != type(""): + continue; + funcname = "do_" + top + if not hasattr(self, funcname): + continue + else: + self.do_pop() + func = getattr(self, funcname) + func() + +if __name__ == '__main__': + import sys + try: + import readline + except ImportError: + pass # not available on all platforms + + # If we see command-line arguments, interpret them as a stack state + # and execute. Otherwise go interactive. + + driver = PILDriver() + if len(sys.argv[1:]) > 0: + driver.execute(sys.argv[1:]) + else: + print "PILDriver says hello." + while 1: + try: + line = raw_input('pildriver> '); + except EOFError: + print "\nPILDriver says goodbye." + break + driver.execute(string.split(line)) + print driver.stack + +# The following sets edit modes for GNU EMACS +# Local Variables: +# mode:python +# End: diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py new file mode 100755 index 00000000000..6957257965e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py @@ -0,0 +1,94 @@ +#! /usr/local/bin/python +# +# The Python Imaging Library. +# $Id$ +# +# a utility to identify image files +# +# this script identifies image files, extracting size and +# pixel mode information for known file formats. Note that +# you don't need the PIL C extension to use this module. +# +# History: +# 0.0 1995-09-01 fl Created +# 0.1 1996-05-18 fl Modified options, added debugging mode +# 0.2 1996-12-29 fl Added verify mode +# 0.3 1999-06-05 fl Don't mess up on class exceptions (1.5.2 and later) +# 0.4 2003-09-30 fl Expand wildcards on Windows; robustness tweaks +# + +import site +import getopt, glob, sys + +from PIL import Image + +if len(sys.argv) == 1: + print "PIL File 0.4/2003-09-30 -- identify image files" + print "Usage: pilfile [option] files..." + print "Options:" + print " -f list supported file formats" + print " -i show associated info and tile data" + print " -v verify file headers" + print " -q quiet, don't warn for unidentified/missing/broken files" + sys.exit(1) + +try: + opt, args = getopt.getopt(sys.argv[1:], "fqivD") +except getopt.error, v: + print v + sys.exit(1) + +verbose = quiet = verify = 0 + +for o, a in opt: + if o == "-f": + Image.init() + id = Image.ID[:] + id.sort() + print "Supported formats:" + for i in id: + print i, + sys.exit(1) + elif o == "-i": + verbose = 1 + elif o == "-q": + quiet = 1 + elif o == "-v": + verify = 1 + elif o == "-D": + Image.DEBUG = Image.DEBUG + 1 + +def globfix(files): + # expand wildcards where necessary + if sys.platform == "win32": + out = [] + for file in files: + if glob.has_magic(file): + out.extend(glob.glob(file)) + else: + out.append(file) + return out + return files + +for file in globfix(args): + try: + im = Image.open(file) + print "%s:" % file, im.format, "%dx%d" % im.size, im.mode, + if verbose: + print im.info, im.tile, + print + if verify: + try: + im.verify() + except: + if not quiet: + print "failed to verify image", + print "(%s:%s)" % (sys.exc_type, sys.exc_value) + except IOError, v: + if not quiet: + print file, "failed:", v + except: + import traceback + if not quiet: + print file, "failed:", "unexpected error" + traceback.print_exc(file=sys.stdout) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py new file mode 100755 index 00000000000..df08d4c083e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py @@ -0,0 +1,54 @@ +# +# The Python Imaging Library +# $Id$ +# +# PIL raster font compiler +# +# history: +# 1997-08-25 fl created +# 2002-03-10 fl use "from PIL import" +# + +VERSION = "0.4" + +import site +import glob, os, sys + +# drivers +from PIL import BdfFontFile +from PIL import PcfFontFile + +if len(sys.argv) <= 1: + print "PILFONT", VERSION, "-- PIL font compiler." + print + print "Usage: pilfont fontfiles..." + print + print "Convert given font files to the PIL raster font format." + print "This version of pilfont supports X BDF and PCF fonts." + sys.exit(1) + +files = [] +for f in sys.argv[1:]: + files = files + glob.glob(f) + +for f in files: + + print f + "...", + + try: + + fp = open(f, "rb") + + try: + p = PcfFontFile.PcfFontFile(fp) + except SyntaxError: + fp.seek(0) + p = BdfFontFile.BdfFontFile(fp) + + p.save(f) + + except (SyntaxError, IOError): + print "failed" + + else: + print "OK" diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py new file mode 100755 index 00000000000..a98b39f7d9b --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py @@ -0,0 +1,93 @@ +#! /usr/local/bin/python +# +# The Python Imaging Library. +# $Id$ +# +# print image files to postscript printer +# +# History: +# 0.1 1996-04-20 fl Created +# 0.2 1996-10-04 fl Use draft mode when converting. +# 0.3 2003-05-06 fl Fixed a typo or two. +# + +VERSION = "pilprint 0.3/2003-05-05" + +from PIL import Image +from PIL import PSDraw + +letter = ( 1.0*72, 1.0*72, 7.5*72, 10.0*72 ) + +def description(file, image): + import os + title = os.path.splitext(os.path.split(file)[1])[0] + format = " (%dx%d " + if image.format: + format = " (" + image.format + " %dx%d " + return title + format % image.size + image.mode + ")" + +import getopt, os, sys + +if len(sys.argv) == 1: + print "PIL Print 0.2a1/96-10-04 -- print image files" + print "Usage: pilprint files..." + print "Options:" + print " -c colour printer (default is monochrome)" + print " -p print via lpr (default is stdout)" + print " -P same as -p but use given printer" + sys.exit(1) + +try: + opt, argv = getopt.getopt(sys.argv[1:], "cdpP:") +except getopt.error, v: + print v + sys.exit(1) + +printer = None # print to stdout +monochrome = 1 # reduce file size for most common case + +for o, a in opt: + if o == "-d": + # debug: show available drivers + Image.init() + print Image.ID + sys.exit(1) + elif o == "-c": + # colour printer + monochrome = 0 + elif o == "-p": + # default printer channel + printer = "lpr" + elif o == "-P": + # printer channel + printer = "lpr -P%s" % a + +for file in argv: + try: + + im = Image.open(file) + + title = description(file, im) + + if monochrome and im.mode not in ["1", "L"]: + im.draft("L", im.size) + im = im.convert("L") + + if printer: + fp = os.popen(printer, "w") + else: + fp = sys.stdout + + ps = PSDraw.PSDraw(fp) + + ps.begin_document() + ps.setfont("Helvetica-Narrow-Bold", 18) + ps.text((letter[0], letter[3]+24), title) + ps.setfont("Helvetica-Narrow-Bold", 8) + ps.text((letter[0], letter[1]-30), VERSION) + ps.image(letter, im) + ps.end_document() + + except: + print "cannot print image", + print "(%s:%s)" % (sys.exc_type, sys.exc_value) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py new file mode 100755 index 00000000000..9ca4500bfd4 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py @@ -0,0 +1,121 @@ +# +# The Python Imaging Library +# $Id$ +# + +from Tkinter import * +from PIL import Image, ImageTk +import sys + + +Image.DEBUG = 0 + + +# -------------------------------------------------------------------- +# experimental: support ARG animation scripts + +import ArgImagePlugin + +def applet_hook(animation, images): + app = animation(animation_display, images) + app.run() + +ArgImagePlugin.APPLET_HOOK = applet_hook + +class AppletDisplay: + def __init__(self, ui): + self.__ui = ui + def paste(self, im, bbox): + self.__ui.image.paste(im, bbox) + def update(self): + self.__ui.update_idletasks() + +# -------------------------------------------------------------------- +# an image animation player + +class UI(Label): + + def __init__(self, master, im): + if type(im) == type([]): + # list of images + self.im = im[1:] + im = self.im[0] + else: + # sequence + self.im = im + + if im.mode == "1": + self.image = ImageTk.BitmapImage(im, foreground="white") + else: + self.image = ImageTk.PhotoImage(im) + + # APPLET SUPPORT (very crude, and not 100% safe) + global animation_display + animation_display = AppletDisplay(self) + + Label.__init__(self, master, image=self.image, bg="black", bd=0) + + self.update() + + try: + duration = im.info["duration"] + except KeyError: + duration = 100 + self.after(duration, self.next) + + def next(self): + + if type(self.im) == type([]): + + try: + im = self.im[0] + del self.im[0] + self.image.paste(im) + except IndexError: + return # end of list + + else: + + try: + im = self.im + im.seek(im.tell() + 1) + self.image.paste(im) + except EOFError: + return # end of file + + try: + duration = im.info["duration"] + except KeyError: + duration = 100 + self.after(duration, self.next) + + self.update_idletasks() + + +# -------------------------------------------------------------------- +# script interface + +if __name__ == "__main__": + + if not sys.argv[1:]: + print "Syntax: python player.py imagefile(s)" + sys.exit(1) + + filename = sys.argv[1] + + root = Tk() + root.title(filename) + + if len(sys.argv) > 2: + # list of images + print "loading..." + im = [] + for filename in sys.argv[1:]: + im.append(Image.open(filename)) + else: + # sequence + im = Image.open(filename) + + UI(root, im).pack() + + root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py new file mode 100755 index 00000000000..eb510987267 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py @@ -0,0 +1,68 @@ +# +# The Python Imaging Library +# $Id$ +# +# this demo script illustrates how a 1-bit BitmapImage can be used +# as a dynamically updated overlay +# + +from Tkinter import * +from PIL import Image, ImageTk +import sys + +# +# an image viewer + +class UI(Frame): + def __init__(self, master, im, value = 128): + Frame.__init__(self, master) + + self.image = im + self.value = value + + self.canvas = Canvas(self, width=im.size[0], height=im.size[1]) + self.backdrop = ImageTk.PhotoImage(im) + self.canvas.create_image(0, 0, image=self.backdrop, anchor=NW) + self.canvas.pack() + + scale = Scale(self, orient=HORIZONTAL, from_=0, to=255, + resolution=1, command=self.update, length=256) + scale.set(value) + scale.bind("", self.redraw) + scale.pack() + + # uncomment the following line for instant feedback (might + # be too slow on some platforms) + # self.redraw() + + def update(self, value): + self.value = eval(value) + + self.redraw() + + def redraw(self, event = None): + + # create overlay (note the explicit conversion to mode "1") + im = self.image.point(lambda v,t=self.value: v>=t, "1") + self.overlay = ImageTk.BitmapImage(im, foreground="green") + + # update canvas + self.canvas.delete("overlay") + self.canvas.create_image(0, 0, image=self.overlay, anchor=NW, + tags="overlay") + +# -------------------------------------------------------------------- +# main + +root = Tk() + +im = Image.open(sys.argv[1]) + +if im.mode != "L": + im = im.convert("L") + +# im.thumbnail((320,200)) + +UI(root, im).pack() + +root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py new file mode 100755 index 00000000000..6e4dc8b67a1 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py @@ -0,0 +1,46 @@ +# +# The Python Imaging Library +# $Id$ +# + +from Tkinter import * +from PIL import Image, ImageTk + +# +# an image viewer + +class UI(Label): + + def __init__(self, master, im): + + if im.mode == "1": + # bitmap image + self.image = ImageTk.BitmapImage(im, foreground="white") + Label.__init__(self, master, image=self.image, bg="black", bd=0) + + else: + # photo image + self.image = ImageTk.PhotoImage(im) + Label.__init__(self, master, image=self.image, bd=0) + +# +# script interface + +if __name__ == "__main__": + + import sys + + if not sys.argv[1:]: + print "Syntax: python viewer.py imagefile" + sys.exit(1) + + filename = sys.argv[1] + + root = Tk() + root.title(filename) + + im = Image.open(filename) + + UI(root, im).pack() + + root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt new file mode 100755 index 00000000000..2d787983b75 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt @@ -0,0 +1,108 @@ +==================================================================== +The Photoimage Booster Patch (for Windows 95/NT) +==================================================================== + + This patch kit boosts performance for 16/24-bit displays. The +first patch is required on Tk 4.2 (where it fixes the problems for +16-bit displays) and later versions, with the exception for Tk 8.0b1 +where Sun added something similar themselves, only to remove it in +8.0b2. By installing both patches, Tk's PhotoImage handling becomes +much faster on both 16-bit and 24-bit displays. The patch has been +tested with Tk 4.2 and 8.0. + + Here's a benchmark, made with a sample program which loads two +512x512 greyscale PGM's, and two 512x512 colour PPM's, and displays +each of them in a separate toplevel windows. Tcl/Tk was compiled +with Visual C 4.0, and run on a P100 under Win95. Image load times +are not included in the timings: + + 8-bit 16-bit 24-bit +-------------------------------------------------------------------- +1. original 4.2 code 5.52 s 8.57 s 3.79 s +2. booster patch 5.49 s 1.87 s 1.82 s + + speedup None 4.6x 2.1x + +==================================================================== + +Here's the patches: + +1. For portability and speed, the best thing under Windows is to +treat 16-bit displays as if they were 24-bit. The Windows device +drivers take care of the rest. + + ---------------------------------------------------------------- + If you have Tk 4.1 or Tk 8.0b1, you don't have to apply this + patch! It only applies to Tk 4.2, Tk 8.0a[12] and Tk 8.0b2. + ---------------------------------------------------------------- + +In win/tkWinImage.c, change the following line in XCreateImage: + + imagePtr->bits_per_pixel = depth; + +to + +/* ==================================================================== */ +/* The tk photo image booster patch -- patch section 1 */ +/* ==================================================================== */ + + if (visual->class == TrueColor) + /* true colour is stored as 3 bytes: (blue, green, red) */ + imagePtr->bits_per_pixel = 24; + else + imagePtr->bits_per_pixel = depth; + +/* ==================================================================== */ + + +2. The DitherInstance implementation is not good. It's especially +bad on highend truecolour displays. IMO, it should be rewritten from +scratch (some other day...). + + Anyway, the following band-aid makes the situation a little bit +better under Windows. This hack trades some marginal quality (no +dithering on 16-bit displays) for a dramatic performance boost. +Requires patch 1, unless you're using Tk 4.1 or Tk 8.0b1. + +In generic/tkImgPhoto.c, add the #ifdef section to the DitherInstance +function: + + for (; height > 0; height -= nLines) { + if (nLines > height) { + nLines = height; + } + dstLinePtr = (unsigned char *) imagePtr->data; + yEnd = yStart + nLines; + +/* ==================================================================== */ +/* The tk photo image booster patch -- patch section 2 */ +/* ==================================================================== */ + +#ifdef __WIN32__ + if (colorPtr->visualInfo.class == TrueColor + && instancePtr->gamma == 1.0) { + /* Windows hicolor/truecolor booster */ + for (y = yStart; y < yEnd; ++y) { + destBytePtr = dstLinePtr; + srcPtr = srcLinePtr; + for (x = xStart; x < xEnd; ++x) { + destBytePtr[0] = srcPtr[2]; + destBytePtr[1] = srcPtr[1]; + destBytePtr[2] = srcPtr[0]; + destBytePtr += 3; srcPtr += 3; + } + srcLinePtr += lineLength; + dstLinePtr += bytesPerLine; + } + } else +#endif + +/* ==================================================================== */ + + for (y = yStart; y < yEnd; ++y) { + srcPtr = srcLinePtr; + errPtr = errLinePtr; + destBytePtr = dstLinePtr; + +==================================================================== +last updated: 97-07-03/fl diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt new file mode 100755 index 00000000000..e24d36301c7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt @@ -0,0 +1,41 @@ +==================================================================== +Using PIL With Tkinter +==================================================================== + +Starting with 1.0 final (release candidate 2 and later, to be +precise), PIL can attach itself to Tkinter in flight. As a result, +you no longer need to rebuild the Tkinter extension to be able to +use PIL. + +However, if you cannot get the this to work on your platform, you +can do it in the old way: + +* Adding Tkinter support + +1. Compile Python's _tkinter.c with the WITH_APPINIT and WITH_PIL + flags set, and link it with tkImaging.c and tkappinit.c. To + do this, copy the former to the Modules directory, and edit + the _tkinter line in Setup (or Setup.in) according to the + instructions in that file. + + NOTE: if you have an old Python version, the tkappinit.c + file is not included by default. If this is the case, you + will have to add the following lines to tkappinit.c, after + the MOREBUTTONS stuff: + + { + extern void TkImaging_Init(Tcl_Interp* interp); + TkImaging_Init(interp); + } + + This registers a Tcl command called "PyImagingPhoto", which is + use to communicate between PIL and Tk's PhotoImage handler. + + You must also change the _tkinter line in Setup (or Setup.in) + to something like: + + _tkinter _tkinter.c tkImaging.c tkappinit.c -DWITH_APPINIT + -I/usr/local/include -L/usr/local/lib -ltk8.0 -ltcl8.0 -lX11 + + + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt new file mode 100755 index 00000000000..e7c46c65fea --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt @@ -0,0 +1,149 @@ +==================================================================== +The PIL Bitmap Booster Patch +==================================================================== + +The pilbitmap booster patch greatly improves performance of the +ImageTk.BitmapImage constructor. Unfortunately, the design of Tk +doesn't allow us to do this from the tkImaging interface module, so +you have to patch the Tk sources. + +Once installed, the ImageTk module will automatically detect this +patch. + +(Note: this patch has been tested with Tk 8.0 on Win32 only, but it +should work just fine on other platforms as well). + +1. To the beginning of TkGetBitmapData (in generic/tkImgBmap.c), add + the following stuff: + +------------------------------------------------------------------------ + int width, height, numBytes, hotX, hotY; + char *p, *end, *expandedFileName; + ParseInfo pi; + char *data = NULL; + Tcl_DString buffer; + +/* ==================================================================== */ +/* The pilbitmap booster patch -- patch section */ +/* ==================================================================== */ + + char *PILGetBitmapData(); + + if (string) { + /* Is this a PIL bitmap reference? */ + data = PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr); + if (data) + return data; + } + +/* ==================================================================== */ + + pi.string = string; + if (string == NULL) { + if (Tcl_IsSafe(interp)) { +------------------------------------------------------------------------ + + +2. Append the following to the same file (you may wish to include +Imaging.h instead of copying the struct declaration...) + +------------------------------------------------------------------------ + +/* ==================================================================== */ +/* The pilbitmap booster patch -- code section */ +/* ==================================================================== */ + +/* Imaging declaration boldly copied from Imaging.h (!) */ + +typedef struct ImagingInstance *Imaging; /* a.k.a. ImagingImage :-) */ + +typedef unsigned char UINT8; +typedef int INT32; + +struct ImagingInstance { + + /* Format */ + char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */ + int type; /* Always 0 in this version */ + int depth; /* Always 8 in this version */ + int bands; /* Number of bands (1, 3, or 4) */ + int xsize; /* Image dimension. */ + int ysize; + + /* Colour palette (for "P" images only) */ + void* palette; + + /* Data pointers */ + UINT8 **image8; /* Set for 8-bit image (pixelsize=1). */ + INT32 **image32; /* Set for 32-bit image (pixelsize=4). */ + + /* Internals */ + char **image; /* Actual raster data. */ + char *block; /* Set if data is allocated in a single block. */ + + int pixelsize; /* Size of a pixel, in bytes (1 or 4) */ + int linesize; /* Size of a line, in bytes (xsize * pixelsize) */ + + /* Virtual methods */ + void (*im_delete)(Imaging *); + +}; + +/* The pilbitmap booster patch allows you to pass PIL images to the + Tk bitmap decoder. Passing images this way is much more efficient + than using the "tobitmap" method. */ + +char * +PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr) + char *string; + int *widthPtr, *heightPtr; + int *hotXPtr, *hotYPtr; +{ + char* data; + char* p; + int y; + Imaging im; + + if (strncmp(string, "PIL:", 4) != 0) + return NULL; + + im = (Imaging) atol(string + 4); + + if (strcmp(im->mode, "1") != 0 && strcmp(im->mode, "L") != 0) + return NULL; + + data = p = (char *) ckalloc((unsigned) ((im->xsize+7)/8) * im->ysize); + + for (y = 0; y < im->ysize; y++) { + char* in = im->image8[y]; + int i, m, b; + b = 0; m = 1; + for (i = 0; i < im->xsize; i++) { + if (in[i] != 0) + b |= m; + m <<= 1; + if (m == 256){ + *p++ = b; + b = 0; m = 1; + } + } + if (m != 1) + *p++ = b; + } + + *widthPtr = im->xsize; + *heightPtr = im->ysize; + *hotXPtr = -1; + *hotYPtr = -1; + + return data; +} + +/* ==================================================================== */ + +------------------------------------------------------------------------ + +3. Recompile Tk and relink the _tkinter module (where necessary). + +==================================================================== +Last updated: 97-05-17/fl diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c new file mode 100755 index 00000000000..5963ee24c7d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c @@ -0,0 +1,265 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * TK interface for Python Imaging objects + * + * Copies (parts of) a named display memory to a photo image object. + * Also contains code to create an display memory. Under Tk, a + * display memory is simply an "L" or "RGB" image memory that is + * allocated in a single block. + * + * To use this module, import the _imagingtk module (ImageTk does + * this for you). + * + * If you're using Python in an embedded context, you can add the + * following lines to your Tcl_AppInit function (in tkappinit.c) + * instead. Put them after the calls to Tcl_Init and Tk_Init: + * + * { + * extern void TkImaging_Init(Tcl_Interp* interp); + * TkImaging_Init(interp); + * } + * + * This registers a Tcl command called "PyImagingPhoto", which is used + * to communicate between PIL and Tk's PhotoImage handler. + * + * Compile and link tkImaging.c with tkappinit.c and _tkinter (see the + * Setup file for details on how to use tkappinit.c). Note that + * _tkinter.c must be compiled with WITH_APPINIT. + * + * History: + * 1995-09-12 fl Created + * 1996-04-08 fl Ready for release + * 1997-05-09 fl Use command instead of image type + * 2001-03-18 fl Initialize alpha layer pointer (struct changed in 8.3) + * 2003-04-23 fl Fixed building for Tk 8.4.1 and later (Jack Jansen) + * 2004-06-24 fl Fixed building for Tk 8.4.6 and later. + * + * Copyright (c) 1997-2004 by Secret Labs AB + * Copyright (c) 1995-2004 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + +#define TK (TK_MAJOR_VERSION*10 + TK_MINOR_VERSION) + +/* This is needed for (at least) Tk 8.4.6 and later, to avoid warnings + for the Tcl_CreateCommand command. */ +#define USE_COMPAT_CONST + +#include "tk.h" + +#include "Imaging.h" + +#include + + +static Imaging +ImagingFind(const char* name) +{ + long id; + + /* FIXME: use CObject instead? */ + id = atol(name); + if (!id) + return NULL; + + return (Imaging) id; +} + + +static int +PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp, + int argc, char **argv) +{ + Imaging im; + Tk_PhotoHandle photo; + Tk_PhotoImageBlock block; + + if (argc != 3) { + Tcl_AppendResult(interp, "usage: ", argv[0], + " destPhoto srcImage", (char *) NULL); + return TCL_ERROR; + } + + /* get Tcl PhotoImage handle */ + photo = Tk_FindPhoto(interp, argv[1]); + if (photo == NULL) { + Tcl_AppendResult( + interp, "destination photo must exist", (char *) NULL + ); + return TCL_ERROR; + } + + /* get PIL Image handle */ + im = ImagingFind(argv[2]); + if (!im) { + Tcl_AppendResult(interp, "bad name", (char*) NULL); + return TCL_ERROR; + } + if (!im->block) { + Tcl_AppendResult(interp, "bad display memory", (char*) NULL); + return TCL_ERROR; + } + + /* Active region */ +#if 0 + if (src_xoffset + xsize > im->xsize) + xsize = im->xsize - src_xoffset; + if (src_yoffset + ysize > im->ysize) + ysize = im->ysize - src_yoffset; + if (xsize < 0 || ysize < 0 + || src_xoffset >= im->xsize + || src_yoffset >= im->ysize) + return TCL_OK; +#endif + + /* Mode */ + + if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { + block.pixelSize = 1; + block.offset[0] = block.offset[1] = block.offset[2] = 0; + } else if (strncmp(im->mode, "RGB", 3) == 0) { + block.pixelSize = 4; + block.offset[0] = 0; + block.offset[1] = 1; + block.offset[2] = 2; + if (strcmp(im->mode, "RGBA") == 0) + block.offset[3] = 3; /* alpha (or reserved, under 8.2) */ + else + block.offset[3] = 0; /* no alpha */ + } else { + Tcl_AppendResult(interp, "Bad mode", (char*) NULL); + return TCL_ERROR; + } + + block.width = im->xsize; + block.height = im->ysize; + block.pitch = im->linesize; + block.pixelPtr = (unsigned char*) im->block; +#if 0 + block.pixelPtr = (unsigned char*) im->block + + src_yoffset * im->linesize + + src_xoffset * im->pixelsize; +#endif + +#if TK < 84 /* < 8.4.0 */ + if (strcmp(im->mode, "RGBA") == 0) { + /* Copy non-transparent pixels to photo image */ + int x, y; + Tk_PhotoImageBlock run; + + /* Clear current contents */ + Tk_PhotoBlank(photo); + + /* Setup run descriptor */ + run.height = 1; + run.pitch = block.pitch; + run.pixelSize = block.pixelSize; + run.offset[0] = 0; + run.offset[1] = 1; + run.offset[2] = 2; + run.offset[3] = 0; /* no alpha (or reserved, under 8.2) */ + + /* Copy opaque runs to photo image */ + for (y = 0; y < block.height; y++) { + unsigned char* p = block.pixelPtr + y*block.pitch; + unsigned char* s = p; + int w = 0; + for (x = 0; x < block.width; x++) { + if (p[3]) { + /* opaque: add pixel to current run */ + if (w == 0) + s = p; + w = w + 1; + } else if (s) { + /* copy run to photo image */ + if (w > 0) { + run.width = w; + run.pixelPtr = s; + Tk_PhotoPutBlock(photo, &run, x-w, y, run.width, 1); + } + w = 0; + } + p += block.pixelSize; + } + if (w > 0) { + /* copy final run, if any */ + run.width = w; + run.pixelPtr = s; + Tk_PhotoPutBlock(photo, &run, x-w, y, run.width, 1); + } + } + + } else + + /* Copy opaque block to photo image, and leave the rest to TK */ + Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); + +#else /* Tk 8.4 and newer */ +#if TK < 85 /* Tk 8.4 */ + Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height, + TK_PHOTO_COMPOSITE_SET); + if (strcmp(im->mode, "RGBA") == 0) + /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */ + /* (fixed in Tk 8.5a3) */ + Tk_PhotoSetSize(photo, block.width, block.height); +#else /* Tk 8.5 */ + Tk_PhotoPutBlock(interp, photo, &block, 0, 0, block.width, block.height, + TK_PHOTO_COMPOSITE_SET); +#endif +#endif + + return TCL_OK; +} + + +static int +PyImagingPhotoGet(ClientData clientdata, Tcl_Interp* interp, + int argc, char **argv) +{ + Tk_PhotoHandle photo; + Tk_PhotoImageBlock block; + + if (argc != 2) { + Tcl_AppendResult(interp, "usage: ", argv[0], + " srcPhoto", (char *) NULL); + return TCL_ERROR; + } + + /* get Tcl PhotoImage handle */ + photo = Tk_FindPhoto(interp, argv[1]); + if (photo == NULL) { + Tcl_AppendResult( + interp, "source photo must exist", (char *) NULL + ); + return TCL_ERROR; + } + + Tk_PhotoGetImage(photo, &block); + + printf("pixelPtr = %p\n", block.pixelPtr); + printf("width = %d\n", block.width); + printf("height = %d\n", block.height); + printf("pitch = %d\n", block.pitch); + printf("pixelSize = %d\n", block.pixelSize); + printf("offset = %d %d %d %d\n", block.offset[0], block.offset[1], + block.offset[2], block.offset[3]); + + Tcl_AppendResult( + interp, "this function is not yet supported", (char *) NULL + ); + + return TCL_ERROR; +} + + +void +TkImaging_Init(Tcl_Interp* interp) +{ + Tcl_CreateCommand(interp, "PyImagingPhoto", PyImagingPhotoPut, + (ClientData) 0, (Tcl_CmdDeleteProc*) NULL); + Tcl_CreateCommand(interp, "PyImagingPhotoGet", PyImagingPhotoGet, + (ClientData) 0, (Tcl_CmdDeleteProc*) NULL); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c new file mode 100755 index 00000000000..c21897decdc --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c @@ -0,0 +1,3281 @@ +/* + * The Python Imaging Library. + * + * the imaging library bindings + * + * history: + * 1995-09-24 fl Created + * 1996-03-24 fl Ready for first public release (release 0.0) + * 1996-03-25 fl Added fromstring (for Jack's "img" library) + * 1996-03-28 fl Added channel operations + * 1996-03-31 fl Added point operation + * 1996-04-08 fl Added new/new_block/new_array factories + * 1996-04-13 fl Added decoders + * 1996-05-04 fl Added palette hack + * 1996-05-12 fl Compile cleanly as C++ + * 1996-05-19 fl Added matrix conversions, gradient fills + * 1996-05-27 fl Added display_mode + * 1996-07-22 fl Added getbbox, offset + * 1996-07-23 fl Added sequence semantics + * 1996-08-13 fl Added logical operators, point mode + * 1996-08-16 fl Modified paste interface + * 1996-09-06 fl Added putdata methods, use abstract interface + * 1996-11-01 fl Added xbm encoder + * 1996-11-04 fl Added experimental path stuff, draw_lines, etc + * 1996-12-10 fl Added zip decoder, crc32 interface + * 1996-12-14 fl Added modulo arithmetics + * 1996-12-29 fl Added zip encoder + * 1997-01-03 fl Added fli and msp decoders + * 1997-01-04 fl Added experimental sun_rle and tga_rle decoders + * 1997-01-05 fl Added gif encoder, getpalette hack + * 1997-02-23 fl Added histogram mask + * 1997-05-12 fl Minor tweaks to match the IFUNC95 interface + * 1997-05-21 fl Added noise generator, spread effect + * 1997-06-05 fl Added mandelbrot generator + * 1997-08-02 fl Modified putpalette to coerce image mode if necessary + * 1998-01-11 fl Added INT32 support + * 1998-01-22 fl Fixed draw_points to draw the last point too + * 1998-06-28 fl Added getpixel, getink, draw_ink + * 1998-07-12 fl Added getextrema + * 1998-07-17 fl Added point conversion to arbitrary formats + * 1998-09-21 fl Added support for resampling filters + * 1998-09-22 fl Added support for quad transform + * 1998-12-29 fl Added support for arcs, chords, and pieslices + * 1999-01-10 fl Added some experimental arrow graphics stuff + * 1999-02-06 fl Added draw_bitmap, font acceleration stuff + * 2001-04-17 fl Fixed some egcs compiler nits + * 2001-09-17 fl Added screen grab primitives (win32) + * 2002-03-09 fl Added stretch primitive + * 2002-03-10 fl Fixed filter handling in rotate + * 2002-06-06 fl Added I, F, and RGB support to putdata + * 2002-06-08 fl Added rankfilter + * 2002-06-09 fl Added support for user-defined filter kernels + * 2002-11-19 fl Added clipboard grab primitives (win32) + * 2002-12-11 fl Added draw context + * 2003-04-26 fl Tweaks for Python 2.3 beta 1 + * 2003-05-21 fl Added createwindow primitive (win32) + * 2003-09-13 fl Added thread section hooks + * 2003-09-15 fl Added expand helper + * 2003-09-26 fl Added experimental LA support + * 2004-02-21 fl Handle zero-size images in quantize + * 2004-06-05 fl Added ptr attribute (used to access Imaging objects) + * 2004-06-05 fl Don't crash when fetching pixels from zero-wide images + * 2004-09-17 fl Added getcolors + * 2004-10-04 fl Added modefilter + * 2005-10-02 fl Added access proxy + * 2006-06-18 fl Always draw last point in polyline + * + * Copyright (c) 1997-2006 by Secret Labs AB + * Copyright (c) 1995-2006 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + + +#include "Python.h" + +#include "Imaging.h" + + +/* Configuration stuff. Feel free to undef things you don't need. */ +#define WITH_IMAGECHOPS /* ImageChops support */ +#define WITH_IMAGEDRAW /* ImageDraw support */ +#define WITH_MAPPING /* use memory mapping to read some file formats */ +#define WITH_IMAGEPATH /* ImagePath stuff */ +#define WITH_ARROW /* arrow graphics stuff (experimental) */ +#define WITH_EFFECTS /* special effects */ +#define WITH_QUANTIZE /* quantization support */ +#define WITH_RANKFILTER /* rank filter */ +#define WITH_MODEFILTER /* mode filter */ +#define WITH_THREADING /* "friendly" threading support */ +#define WITH_UNSHARPMASK /* Kevin Cazabon's unsharpmask module */ + +#define WITH_DEBUG /* extra debugging interfaces */ + +/* PIL Plus extensions */ +#undef WITH_CRACKCODE /* pil plus */ + +#undef VERBOSE + +#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) + +#define B16(p, i) ((((int)p[(i)]) << 8) + p[(i)+1]) +#define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)]) +#define S16(v) ((v) < 32768 ? (v) : ((v) - 65536)) + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#if PY_VERSION_HEX < 0x02050000 +#define Py_ssize_t int +#define ssizeargfunc intargfunc +#define ssizessizeargfunc intintargfunc +#define ssizeobjargproc intobjargproc +#define ssizessizeobjargproc intintobjargproc +#endif + +/* -------------------------------------------------------------------- */ +/* OBJECT ADMINISTRATION */ +/* -------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + Imaging image; + ImagingAccess access; +} ImagingObject; + +staticforward PyTypeObject Imaging_Type; + +#ifdef WITH_IMAGEDRAW + +typedef struct +{ + /* to write a character, cut out sxy from glyph data, place + at current position plus dxy, and advance by (dx, dy) */ + int dx, dy; + int dx0, dy0, dx1, dy1; + int sx0, sy0, sx1, sy1; +} Glyph; + +typedef struct { + PyObject_HEAD + ImagingObject* ref; + Imaging bitmap; + int ysize; + int baseline; + Glyph glyphs[256]; +} ImagingFontObject; + +staticforward PyTypeObject ImagingFont_Type; + +typedef struct { + PyObject_HEAD + ImagingObject* image; + UINT8 ink[4]; + int blend; +} ImagingDrawObject; + +staticforward PyTypeObject ImagingDraw_Type; + +#endif + +typedef struct { + PyObject_HEAD + ImagingObject* image; + int readonly; +} PixelAccessObject; + +staticforward PyTypeObject PixelAccess_Type; + +PyObject* +PyImagingNew(Imaging imOut) +{ + ImagingObject* imagep; + + if (!imOut) + return NULL; + + imagep = PyObject_New(ImagingObject, &Imaging_Type); + if (imagep == NULL) { + ImagingDelete(imOut); + return NULL; + } + +#ifdef VERBOSE + printf("imaging %p allocated\n", imagep); +#endif + + imagep->image = imOut; + imagep->access = ImagingAccessNew(imOut); + + return (PyObject*) imagep; +} + +static void +_dealloc(ImagingObject* imagep) +{ + +#ifdef VERBOSE + printf("imaging %p deleted\n", imagep); +#endif + + if (imagep->access) + ImagingAccessDelete(imagep->image, imagep->access); + ImagingDelete(imagep->image); + PyObject_Del(imagep); +} + +#define PyImaging_Check(op) ((op)->ob_type == &Imaging_Type) + +Imaging PyImaging_AsImaging(PyObject *op) +{ + if (!PyImaging_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + + return ((ImagingObject *)op)->image; +} + + +/* -------------------------------------------------------------------- */ +/* THREAD HANDLING */ +/* -------------------------------------------------------------------- */ + +void ImagingSectionEnter(ImagingSectionCookie* cookie) +{ +#ifdef WITH_THREADING + *cookie = (PyThreadState *) PyEval_SaveThread(); +#endif +} + +void ImagingSectionLeave(ImagingSectionCookie* cookie) +{ +#ifdef WITH_THREADING + PyEval_RestoreThread((PyThreadState*) *cookie); +#endif +} + +/* -------------------------------------------------------------------- */ +/* BUFFER HANDLING */ +/* -------------------------------------------------------------------- */ +/* Python compatibility API */ + +#if PY_VERSION_HEX < 0x02020000 + +int PyImaging_CheckBuffer(PyObject *buffer) +{ + PyBufferProcs *procs = buffer->ob_type->tp_as_buffer; + if (procs && procs->bf_getreadbuffer && procs->bf_getsegcount && + procs->bf_getsegcount(buffer, NULL) == 1) + return 1; + return 0; +} + +int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr) +{ + PyBufferProcs *procs = buffer->ob_type->tp_as_buffer; + return procs->bf_getreadbuffer(buffer, 0, ptr); +} + +#else + +int PyImaging_CheckBuffer(PyObject* buffer) +{ + return PyObject_CheckReadBuffer(buffer); +} + +int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr) +{ + /* must call check_buffer first! */ +#if PY_VERSION_HEX < 0x02050000 + int n = 0; +#else + Py_ssize_t n = 0; +#endif + PyObject_AsReadBuffer(buffer, ptr, &n); + return (int) n; +} + +#endif + +/* -------------------------------------------------------------------- */ +/* EXCEPTION REROUTING */ +/* -------------------------------------------------------------------- */ + +/* error messages */ +static const char* must_be_sequence = "argument must be a sequence"; +static const char* wrong_mode = "unrecognized image mode"; +static const char* wrong_raw_mode = "unrecognized raw mode"; +static const char* outside_image = "image index out of range"; +static const char* outside_palette = "palette index out of range"; +static const char* no_palette = "image has no palette"; +static const char* readonly = "image is readonly"; +/* static const char* no_content = "image has no content"; */ + +void * +ImagingError_IOError(void) +{ + PyErr_SetString(PyExc_IOError, "error when accessing file"); + return NULL; +} + +void * +ImagingError_MemoryError(void) +{ + return PyErr_NoMemory(); +} + +void * +ImagingError_Mismatch(void) +{ + PyErr_SetString(PyExc_ValueError, "images do not match"); + return NULL; +} + +void * +ImagingError_ModeError(void) +{ + PyErr_SetString(PyExc_ValueError, "image has wrong mode"); + return NULL; +} + +void * +ImagingError_ValueError(const char *message) +{ + PyErr_SetString( + PyExc_ValueError, + (message) ? (char*) message : "unrecognized argument value" + ); + return NULL; +} + +void +ImagingError_Clear(void) +{ + PyErr_Clear(); +} + +/* -------------------------------------------------------------------- */ +/* HELPERS */ +/* -------------------------------------------------------------------- */ + +static int +getbands(const char* mode) +{ + Imaging im; + int bands; + + /* FIXME: add primitive to libImaging to avoid extra allocation */ + im = ImagingNew(mode, 0, 0); + if (!im) + return -1; + + bands = im->bands; + + ImagingDelete(im); + + return bands; +} + +#define TYPE_UINT8 (0x100|sizeof(UINT8)) +#define TYPE_INT32 (0x200|sizeof(INT32)) +#define TYPE_FLOAT32 (0x300|sizeof(FLOAT32)) +#define TYPE_DOUBLE (0x400|sizeof(double)) + +static void* +getlist(PyObject* arg, int* length, const char* wrong_length, int type) +{ + int i, n; + void* list; + + if (!PySequence_Check(arg)) { + PyErr_SetString(PyExc_TypeError, must_be_sequence); + return NULL; + } + + n = PyObject_Length(arg); + if (length && wrong_length && n != *length) { + PyErr_SetString(PyExc_ValueError, wrong_length); + return NULL; + } + + list = malloc(n * (type & 0xff)); + if (!list) + return PyErr_NoMemory(); + + switch (type) { + case TYPE_UINT8: + if (PyList_Check(arg)) { + for (i = 0; i < n; i++) { + PyObject *op = PyList_GET_ITEM(arg, i); + int temp = PyInt_AsLong(op); + ((UINT8*)list)[i] = CLIP(temp); + } + } else { + for (i = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(arg, i); + int temp = PyInt_AsLong(op); + Py_XDECREF(op); + ((UINT8*)list)[i] = CLIP(temp); + } + } + break; + case TYPE_INT32: + if (PyList_Check(arg)) { + for (i = 0; i < n; i++) { + PyObject *op = PyList_GET_ITEM(arg, i); + int temp = PyInt_AsLong(op); + ((INT32*)list)[i] = temp; + } + } else { + for (i = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(arg, i); + int temp = PyInt_AsLong(op); + Py_XDECREF(op); + ((INT32*)list)[i] = temp; + } + } + break; + case TYPE_FLOAT32: + if (PyList_Check(arg)) { + for (i = 0; i < n; i++) { + PyObject *op = PyList_GET_ITEM(arg, i); + double temp = PyFloat_AsDouble(op); + ((FLOAT32*)list)[i] = (FLOAT32) temp; + } + } else { + for (i = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(arg, i); + double temp = PyFloat_AsDouble(op); + Py_XDECREF(op); + ((FLOAT32*)list)[i] = (FLOAT32) temp; + } + } + break; + case TYPE_DOUBLE: + if (PyList_Check(arg)) { + for (i = 0; i < n; i++) { + PyObject *op = PyList_GET_ITEM(arg, i); + double temp = PyFloat_AsDouble(op); + ((double*)list)[i] = temp; + } + } else { + for (i = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(arg, i); + double temp = PyFloat_AsDouble(op); + Py_XDECREF(op); + ((double*)list)[i] = temp; + } + } + break; + } + + if (length) + *length = n; + + PyErr_Clear(); + + return list; +} + +static inline PyObject* +getpixel(Imaging im, ImagingAccess access, int x, int y) +{ + union { + UINT8 b[4]; + INT16 h; + INT32 i; + FLOAT32 f; + } pixel; + + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { + PyErr_SetString(PyExc_IndexError, outside_image); + return NULL; + } + + access->get_pixel(im, x, y, &pixel); + + switch (im->type) { + case IMAGING_TYPE_UINT8: + switch (im->bands) { + case 1: + return PyInt_FromLong(pixel.b[0]); + case 2: + return Py_BuildValue("ii", pixel.b[0], pixel.b[1]); + case 3: + return Py_BuildValue("iii", pixel.b[0], pixel.b[1], pixel.b[2]); + case 4: + return Py_BuildValue("iiii", pixel.b[0], pixel.b[1], pixel.b[2], pixel.b[3]); + } + break; + case IMAGING_TYPE_INT32: + return PyInt_FromLong(pixel.i); + case IMAGING_TYPE_FLOAT32: + return PyFloat_FromDouble(pixel.f); + case IMAGING_TYPE_SPECIAL: + if (strncmp(im->mode, "I;16", 4) == 0) + return PyInt_FromLong(pixel.h); + break; + } + + /* unknown type */ + Py_INCREF(Py_None); + return Py_None; +} + +static char* +getink(PyObject* color, Imaging im, char* ink) +{ + int r, g, b, a; + double f; + + /* fill ink buffer (four bytes) with something that can + be cast to either UINT8 or INT32 */ + + switch (im->type) { + case IMAGING_TYPE_UINT8: + /* unsigned integer */ + if (im->bands == 1) { + /* unsigned integer, single layer */ + r = PyInt_AsLong(color); + if (r == -1 && PyErr_Occurred()) + return NULL; + ink[0] = CLIP(r); + ink[1] = ink[2] = ink[3] = 0; + } else { + a = 255; + if (PyInt_Check(color)) { + r = PyInt_AS_LONG(color); + /* compatibility: ABGR */ + a = (UINT8) (r >> 24); + b = (UINT8) (r >> 16); + g = (UINT8) (r >> 8); + r = (UINT8) r; + } else { + if (im->bands == 2) { + if (!PyArg_ParseTuple(color, "i|i", &r, &a)) + return NULL; + g = b = r; + } else { + if (!PyArg_ParseTuple(color, "iii|i", &r, &g, &b, &a)) + return NULL; + } + } + ink[0] = CLIP(r); + ink[1] = CLIP(g); + ink[2] = CLIP(b); + ink[3] = CLIP(a); + } + return ink; + case IMAGING_TYPE_INT32: + /* signed integer */ + r = PyInt_AsLong(color); + if (r == -1 && PyErr_Occurred()) + return NULL; + *(INT32*) ink = r; + return ink; + case IMAGING_TYPE_FLOAT32: + /* floating point */ + f = PyFloat_AsDouble(color); + if (f == -1.0 && PyErr_Occurred()) + return NULL; + *(FLOAT32*) ink = (FLOAT32) f; + return ink; + case IMAGING_TYPE_SPECIAL: + if (strncmp(im->mode, "I;16", 4) == 0) { + r = PyInt_AsLong(color); + if (r == -1 && PyErr_Occurred()) + return NULL; + ink[0] = (UINT8) r; + ink[1] = (UINT8) (r >> 8); + ink[2] = ink[3] = 0; + return ink; + } + } + + PyErr_SetString(PyExc_ValueError, wrong_mode); + return NULL; +} + +/* -------------------------------------------------------------------- */ +/* FACTORIES */ +/* -------------------------------------------------------------------- */ + +static PyObject* +_fill(PyObject* self, PyObject* args) +{ + char* mode; + int xsize, ysize; + PyObject* color; + char buffer[4]; + Imaging im; + + xsize = ysize = 256; + color = NULL; + + if (!PyArg_ParseTuple(args, "s|(ii)O", &mode, &xsize, &ysize, &color)) + return NULL; + + im = ImagingNew(mode, xsize, ysize); + if (!im) + return NULL; + + if (color) { + if (!getink(color, im, buffer)) { + ImagingDelete(im); + return NULL; + } + } else + buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0; + + (void) ImagingFill(im, buffer); + + return PyImagingNew(im); +} + +static PyObject* +_new(PyObject* self, PyObject* args) +{ + char* mode; + int xsize, ysize; + + if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) + return NULL; + + return PyImagingNew(ImagingNew(mode, xsize, ysize)); +} + +static PyObject* +_new_array(PyObject* self, PyObject* args) +{ + char* mode; + int xsize, ysize; + + if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) + return NULL; + + return PyImagingNew(ImagingNewArray(mode, xsize, ysize)); +} + +static PyObject* +_new_block(PyObject* self, PyObject* args) +{ + char* mode; + int xsize, ysize; + + if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) + return NULL; + + return PyImagingNew(ImagingNewBlock(mode, xsize, ysize)); +} + +static PyObject* +_getcount(PyObject* self, PyObject* args) +{ + if (!PyArg_ParseTuple(args, ":getcount")) + return NULL; + + return PyInt_FromLong(ImagingNewCount); +} + +static PyObject* +_linear_gradient(PyObject* self, PyObject* args) +{ + char* mode; + + if (!PyArg_ParseTuple(args, "s", &mode)) + return NULL; + + return PyImagingNew(ImagingFillLinearGradient(mode)); +} + +static PyObject* +_radial_gradient(PyObject* self, PyObject* args) +{ + char* mode; + + if (!PyArg_ParseTuple(args, "s", &mode)) + return NULL; + + return PyImagingNew(ImagingFillRadialGradient(mode)); +} + +static PyObject* +_open_ppm(PyObject* self, PyObject* args) +{ + char* filename; + + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + return PyImagingNew(ImagingOpenPPM(filename)); +} + +static PyObject* +_blend(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep1; + ImagingObject* imagep2; + double alpha; + + alpha = 0.5; + if (!PyArg_ParseTuple(args, "O!O!|d", + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2, + &alpha)) + return NULL; + + return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image, + (float) alpha)); +} + +/* -------------------------------------------------------------------- */ +/* METHODS */ +/* -------------------------------------------------------------------- */ + +static PyObject* +_convert(ImagingObject* self, PyObject* args) +{ + char* mode; + int dither = 0; + ImagingObject *paletteimage = NULL; + + if (!PyArg_ParseTuple(args, "s|iO", &mode, &dither, &paletteimage)) + return NULL; + if (paletteimage != NULL) { + if (!PyImaging_Check(paletteimage)) { + PyObject_Print((PyObject *)paletteimage, stderr, 0); + PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'"); + return NULL; + } + if (paletteimage->image->palette == NULL) { + PyErr_SetString(PyExc_ValueError, "null palette"); + return NULL; + } + } + + return PyImagingNew(ImagingConvert(self->image, mode, paletteimage ? paletteimage->image->palette : NULL, dither)); +} + +static PyObject* +_convert2(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep1; + ImagingObject* imagep2; + if (!PyArg_ParseTuple(args, "O!O!", + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2)) + return NULL; + + if (!ImagingConvert2(imagep1->image, imagep2->image)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_convert_matrix(ImagingObject* self, PyObject* args) +{ + char* mode; + float m[12]; + if (!PyArg_ParseTuple(args, "s(ffff)", &mode, m+0, m+1, m+2, m+3)) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "s(ffffffffffff)", &mode, + m+0, m+1, m+2, m+3, + m+4, m+5, m+6, m+7, + m+8, m+9, m+10, m+11)) + return NULL; + } + + return PyImagingNew(ImagingConvertMatrix(self->image, mode, m)); +} + +static PyObject* +_copy(ImagingObject* self, PyObject* args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + return PyImagingNew(ImagingCopy(self->image)); +} + +static PyObject* +_copy2(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep1; + ImagingObject* imagep2; + if (!PyArg_ParseTuple(args, "O!O!", + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2)) + return NULL; + + if (!ImagingCopy2(imagep1->image, imagep2->image)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_crop(ImagingObject* self, PyObject* args) +{ + int x0, y0, x1, y1; + if (!PyArg_ParseTuple(args, "(iiii)", &x0, &y0, &x1, &y1)) + return NULL; + + return PyImagingNew(ImagingCrop(self->image, x0, y0, x1, y1)); +} + +static PyObject* +_expand(ImagingObject* self, PyObject* args) +{ + int x, y; + int mode = 0; + if (!PyArg_ParseTuple(args, "ii|i", &x, &y, &mode)) + return NULL; + + return PyImagingNew(ImagingExpand(self->image, x, y, mode)); +} + +static PyObject* +_filter(ImagingObject* self, PyObject* args) +{ + PyObject* imOut; + int kernelsize; + FLOAT32* kerneldata; + + int xsize, ysize; + float divisor, offset; + PyObject* kernel = NULL; + if (!PyArg_ParseTuple(args, "(ii)ffO", &xsize, &ysize, + &divisor, &offset, &kernel)) + return NULL; + + /* get user-defined kernel */ + kerneldata = getlist(kernel, &kernelsize, NULL, TYPE_FLOAT32); + if (!kerneldata) + return NULL; + if (kernelsize != xsize * ysize) { + free(kerneldata); + return ImagingError_ValueError("bad kernel size"); + } + + imOut = PyImagingNew( + ImagingFilter(self->image, xsize, ysize, kerneldata, offset, divisor) + ); + + free(kerneldata); + + return imOut; +} + +#ifdef WITH_UNSHARPMASK +static PyObject* +_gaussian_blur(ImagingObject* self, PyObject* args) +{ + Imaging imIn; + Imaging imOut; + + float radius = 0; + if (!PyArg_ParseTuple(args, "f", &radius)) + return NULL; + + imIn = self->image; + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + if (!imOut) + return NULL; + + if (!ImagingGaussianBlur(imIn, imOut, radius)) + return NULL; + + return PyImagingNew(imOut); +} +#endif + +static PyObject* +_getpalette(ImagingObject* self, PyObject* args) +{ + PyObject* palette; + int palettesize = 256; + int bits; + ImagingShuffler pack; + + char* mode = "RGB"; + char* rawmode = "RGB"; + if (!PyArg_ParseTuple(args, "|ss", &mode, &rawmode)) + return NULL; + + if (!self->image->palette) { + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; + } + + pack = ImagingFindPacker(mode, rawmode, &bits); + if (!pack) { + PyErr_SetString(PyExc_ValueError, wrong_raw_mode); + return NULL; + } + + palette = PyString_FromStringAndSize(NULL, palettesize * bits / 8); + if (!palette) + return NULL; + + pack((UINT8*) PyString_AsString(palette), + self->image->palette->palette, palettesize); + + return palette; +} + +static inline int +_getxy(PyObject* xy, int* x, int *y) +{ + PyObject* value; + + if (!PyTuple_Check(xy) || PyTuple_GET_SIZE(xy) != 2) + goto badarg; + + value = PyTuple_GET_ITEM(xy, 0); + if (PyInt_Check(value)) + *x = PyInt_AS_LONG(value); + else if (PyFloat_Check(value)) + *x = (int) PyFloat_AS_DOUBLE(value); + else + goto badval; + + value = PyTuple_GET_ITEM(xy, 1); + if (PyInt_Check(value)) + *y = PyInt_AS_LONG(value); + else if (PyFloat_Check(value)) + *y = (int) PyFloat_AS_DOUBLE(value); + else + goto badval; + + return 0; + + badarg: + PyErr_SetString( + PyExc_TypeError, + "argument must be sequence of length 2" + ); + return -1; + + badval: + PyErr_SetString( + PyExc_TypeError, + "an integer is required" + ); + return -1; +} + +static PyObject* +_getpixel(ImagingObject* self, PyObject* args) +{ + PyObject* xy; + int x, y; + + if (PyTuple_GET_SIZE(args) != 1) { + PyErr_SetString( + PyExc_TypeError, + "argument 1 must be sequence of length 2" + ); + return NULL; + } + + xy = PyTuple_GET_ITEM(args, 0); + + if (_getxy(xy, &x, &y)) + return NULL; + + if (self->access == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + + return getpixel(self->image, self->access, x, y); +} + +static PyObject* +_histogram(ImagingObject* self, PyObject* args) +{ + ImagingHistogram h; + PyObject* list; + int i; + union { + UINT8 u[2]; + INT32 i[2]; + FLOAT32 f[2]; + } extrema; + void* ep; + int i0, i1; + double f0, f1; + + PyObject* extremap = NULL; + ImagingObject* maskp = NULL; + if (!PyArg_ParseTuple(args, "|OO!", &extremap, &Imaging_Type, &maskp)) + return NULL; + + if (extremap) { + ep = &extrema; + switch (self->image->type) { + case IMAGING_TYPE_UINT8: + if (!PyArg_ParseTuple(extremap, "ii", &i0, &i1)) + return NULL; + /* FIXME: clip */ + extrema.u[0] = i0; + extrema.u[1] = i1; + break; + case IMAGING_TYPE_INT32: + if (!PyArg_ParseTuple(extremap, "ii", &i0, &i1)) + return NULL; + extrema.i[0] = i0; + extrema.i[1] = i1; + break; + case IMAGING_TYPE_FLOAT32: + if (!PyArg_ParseTuple(extremap, "dd", &f0, &f1)) + return NULL; + extrema.f[0] = (FLOAT32) f0; + extrema.f[1] = (FLOAT32) f1; + break; + default: + ep = NULL; + break; + } + } else + ep = NULL; + + h = ImagingGetHistogram(self->image, (maskp) ? maskp->image : NULL, ep); + + if (!h) + return NULL; + + /* Build an integer list containing the histogram */ + list = PyList_New(h->bands * 256); + for (i = 0; i < h->bands * 256; i++) { + PyObject* item; + item = PyInt_FromLong(h->histogram[i]); + if (item == NULL) { + Py_DECREF(list); + list = NULL; + break; + } + PyList_SetItem(list, i, item); + } + + ImagingHistogramDelete(h); + + return list; +} + +#ifdef WITH_MODEFILTER +static PyObject* +_modefilter(ImagingObject* self, PyObject* args) +{ + int size; + if (!PyArg_ParseTuple(args, "i", &size)) + return NULL; + + return PyImagingNew(ImagingModeFilter(self->image, size)); +} +#endif + +static PyObject* +_offset(ImagingObject* self, PyObject* args) +{ + int xoffset, yoffset; + if (!PyArg_ParseTuple(args, "ii", &xoffset, &yoffset)) + return NULL; + + return PyImagingNew(ImagingOffset(self->image, xoffset, yoffset)); +} + +static PyObject* +_paste(ImagingObject* self, PyObject* args) +{ + int status; + char ink[4]; + + PyObject* source; + int x0, y0, x1, y1; + ImagingObject* maskp = NULL; + if (!PyArg_ParseTuple(args, "O(iiii)|O!", + &source, + &x0, &y0, &x1, &y1, + &Imaging_Type, &maskp)) + return NULL; + + if (PyImaging_Check(source)) + status = ImagingPaste( + self->image, PyImaging_AsImaging(source), + (maskp) ? maskp->image : NULL, + x0, y0, x1, y1 + ); + + else { + if (!getink(source, self->image, ink)) + return NULL; + status = ImagingFill2( + self->image, ink, + (maskp) ? maskp->image : NULL, + x0, y0, x1, y1 + ); + } + + if (status < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_point(ImagingObject* self, PyObject* args) +{ + static const char* wrong_number = "wrong number of lut entries"; + + int n, i; + int bands; + Imaging im; + + PyObject* list; + char* mode; + if (!PyArg_ParseTuple(args, "Oz", &list, &mode)) + return NULL; + + if (mode && !strcmp(mode, "F")) { + FLOAT32* data; + + /* map from 8-bit data to floating point */ + n = 256; + data = getlist(list, &n, wrong_number, TYPE_FLOAT32); + if (!data) + return NULL; + im = ImagingPoint(self->image, mode, (void*) data); + free(data); + + } else if (!strcmp(self->image->mode, "I") && mode && !strcmp(mode, "L")) { + UINT8* data; + + /* map from 16-bit subset of 32-bit data to 8-bit */ + /* FIXME: support arbitrary number of entries (requires API change) */ + n = 65536; + data = getlist(list, &n, wrong_number, TYPE_UINT8); + if (!data) + return NULL; + im = ImagingPoint(self->image, mode, (void*) data); + free(data); + + } else { + INT32* data; + UINT8 lut[1024]; + + if (mode) { + bands = getbands(mode); + if (bands < 0) + return NULL; + } else + bands = self->image->bands; + + /* map to integer data */ + n = 256 * bands; + data = getlist(list, &n, wrong_number, TYPE_INT32); + if (!data) + return NULL; + + if (mode && !strcmp(mode, "I")) + im = ImagingPoint(self->image, mode, (void*) data); + else if (mode && bands > 1) { + for (i = 0; i < 256; i++) { + lut[i*4] = CLIP(data[i]); + lut[i*4+1] = CLIP(data[i+256]); + lut[i*4+2] = CLIP(data[i+512]); + if (n > 768) + lut[i*4+3] = CLIP(data[i+768]); + } + im = ImagingPoint(self->image, mode, (void*) lut); + } else { + /* map individual bands */ + for (i = 0; i < n; i++) + lut[i] = CLIP(data[i]); + im = ImagingPoint(self->image, mode, (void*) lut); + } + free(data); + } + + return PyImagingNew(im); +} + +static PyObject* +_point_transform(ImagingObject* self, PyObject* args) +{ + double scale = 1.0; + double offset = 0.0; + if (!PyArg_ParseTuple(args, "|dd", &scale, &offset)) + return NULL; + + return PyImagingNew(ImagingPointTransform(self->image, scale, offset)); +} + +static PyObject* +_putdata(ImagingObject* self, PyObject* args) +{ + Imaging image; + int n, i, x, y; + + PyObject* data; + double scale = 1.0; + double offset = 0.0; + if (!PyArg_ParseTuple(args, "O|dd", &data, &scale, &offset)) + return NULL; + + if (!PySequence_Check(data)) { + PyErr_SetString(PyExc_TypeError, must_be_sequence); + return NULL; + } + + image = self->image; + + n = PyObject_Length(data); + if (n > (int) (image->xsize * image->ysize)) { + PyErr_SetString(PyExc_TypeError, "too many data entries"); + return NULL; + } + + if (image->image8) { + if (PyString_Check(data)) { + unsigned char* p; + p = (unsigned char*) PyString_AS_STRING((PyStringObject*) data); + if (scale == 1.0 && offset == 0.0) + /* Plain string data */ + for (i = y = 0; i < n; i += image->xsize, y++) { + x = n - i; + if (x > (int) image->xsize) + x = image->xsize; + memcpy(image->image8[y], p+i, x); + } + else + /* Scaled and clipped string data */ + for (i = x = y = 0; i < n; i++) { + image->image8[y][x] = CLIP((int) (p[i] * scale + offset)); + if (++x >= (int) image->xsize) + x = 0, y++; + } + } else { + if (scale == 1.0 && offset == 0.0) { + /* Clipped data */ + if (PyList_Check(data)) { + for (i = x = y = 0; i < n; i++) { + PyObject *op = PyList_GET_ITEM(data, i); + image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op)); + if (++x >= (int) image->xsize) + x = 0, y++; + } + } else { + for (i = x = y = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(data, i); + image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op)); + Py_XDECREF(op); + if (++x >= (int) image->xsize) + x = 0, y++; + } + } + } else { + if (PyList_Check(data)) { + /* Scaled and clipped data */ + for (i = x = y = 0; i < n; i++) { + PyObject *op = PyList_GET_ITEM(data, i); + image->image8[y][x] = CLIP( + (int) (PyFloat_AsDouble(op) * scale + offset)); + if (++x >= (int) image->xsize) + x = 0, y++; + } + } else { + for (i = x = y = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(data, i); + image->image8[y][x] = CLIP( + (int) (PyFloat_AsDouble(op) * scale + offset)); + Py_XDECREF(op); + if (++x >= (int) image->xsize) + x = 0, y++; + } + } + } + PyErr_Clear(); /* Avoid weird exceptions */ + } + } else { + /* 32-bit images */ + switch (image->type) { + case IMAGING_TYPE_INT32: + for (i = x = y = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(data, i); + IMAGING_PIXEL_INT32(image, x, y) = + (INT32) (PyFloat_AsDouble(op) * scale + offset); + Py_XDECREF(op); + if (++x >= (int) image->xsize) + x = 0, y++; + } + PyErr_Clear(); /* Avoid weird exceptions */ + break; + case IMAGING_TYPE_FLOAT32: + for (i = x = y = 0; i < n; i++) { + PyObject *op = PySequence_GetItem(data, i); + IMAGING_PIXEL_FLOAT32(image, x, y) = + (FLOAT32) (PyFloat_AsDouble(op) * scale + offset); + Py_XDECREF(op); + if (++x >= (int) image->xsize) + x = 0, y++; + } + PyErr_Clear(); /* Avoid weird exceptions */ + break; + default: + for (i = x = y = 0; i < n; i++) { + char ink[4]; + PyObject *op = PySequence_GetItem(data, i); + if (!op || !getink(op, image, ink)) { + Py_DECREF(op); + return NULL; + } + /* FIXME: what about scale and offset? */ + image->image32[y][x] = *((INT32*) ink); + Py_XDECREF(op); + if (++x >= (int) image->xsize) + x = 0, y++; + } + PyErr_Clear(); /* Avoid weird exceptions */ + break; + } + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WITH_QUANTIZE + +#include "Quant.h" +static PyObject* +_quantize(ImagingObject* self, PyObject* args) +{ + int colours = 256; + int method = 0; + int kmeans = 0; + if (!PyArg_ParseTuple(args, "|iii", &colours, &method, &kmeans)) + return NULL; + + if (!self->image->xsize || !self->image->ysize) { + /* no content; return an empty image */ + return PyImagingNew( + ImagingNew("P", self->image->xsize, self->image->ysize) + ); + } + + return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans)); +} +#endif + +static PyObject* +_putpalette(ImagingObject* self, PyObject* args) +{ + ImagingShuffler unpack; + int bits; + + char* rawmode; + UINT8* palette; + int palettesize; + if (!PyArg_ParseTuple(args, "ss#", &rawmode, &palette, &palettesize)) + return NULL; + + if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) { + PyErr_SetString(PyExc_ValueError, wrong_mode); + return NULL; + } + + unpack = ImagingFindUnpacker("RGB", rawmode, &bits); + if (!unpack) { + PyErr_SetString(PyExc_ValueError, wrong_raw_mode); + return NULL; + } + + ImagingPaletteDelete(self->image->palette); + + strcpy(self->image->mode, "P"); + + self->image->palette = ImagingPaletteNew("RGB"); + + unpack(self->image->palette->palette, palette, palettesize * 8 / bits); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_putpalettealpha(ImagingObject* self, PyObject* args) +{ + int index; + int alpha = 0; + if (!PyArg_ParseTuple(args, "i|i", &index, &alpha)) + return NULL; + + if (!self->image->palette) { + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; + } + + if (index < 0 || index >= 256) { + PyErr_SetString(PyExc_ValueError, outside_palette); + return NULL; + } + + strcpy(self->image->palette->mode, "RGBA"); + self->image->palette->palette[index*4+3] = (UINT8) alpha; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_putpixel(ImagingObject* self, PyObject* args) +{ + Imaging im; + char ink[4]; + + int x, y; + PyObject* color; + if (!PyArg_ParseTuple(args, "(ii)O", &x, &y, &color)) + return NULL; + + im = self->image; + + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { + PyErr_SetString(PyExc_IndexError, outside_image); + return NULL; + } + + if (!getink(color, im, ink)) + return NULL; + + if (self->access) + self->access->put_pixel(im, x, y, ink); + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WITH_RANKFILTER +static PyObject* +_rankfilter(ImagingObject* self, PyObject* args) +{ + int size, rank; + if (!PyArg_ParseTuple(args, "ii", &size, &rank)) + return NULL; + + return PyImagingNew(ImagingRankFilter(self->image, size, rank)); +} +#endif + +static PyObject* +_resize(ImagingObject* self, PyObject* args) +{ + Imaging imIn; + Imaging imOut; + + int xsize, ysize; + int filter = IMAGING_TRANSFORM_NEAREST; + if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) + return NULL; + + imIn = self->image; + + imOut = ImagingNew(imIn->mode, xsize, ysize); + if (imOut) + (void) ImagingResize(imOut, imIn, filter); + + return PyImagingNew(imOut); +} + +static PyObject* +_rotate(ImagingObject* self, PyObject* args) +{ + Imaging imOut; + Imaging imIn; + + double theta; + int filter = IMAGING_TRANSFORM_NEAREST; + if (!PyArg_ParseTuple(args, "d|i", &theta, &filter)) + return NULL; + + imIn = self->image; + + theta = fmod(theta, 360.0); + if (theta < 0.0) + theta += 360; + + if (filter && imIn->type != IMAGING_TYPE_SPECIAL) { + /* Rotate with resampling filter */ + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + (void) ImagingRotate(imOut, imIn, theta, filter); + } else if (theta == 90.0 || theta == 270.0) { + /* Use fast version */ + imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize); + if (imOut) { + if (theta == 90.0) + (void) ImagingRotate90(imOut, imIn); + else + (void) ImagingRotate270(imOut, imIn); + } + } else { + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + if (imOut) { + if (theta == 0.0) + /* No rotation: simply copy the input image */ + (void) ImagingCopy2(imOut, imIn); + else if (theta == 180.0) + /* Use fast version */ + (void) ImagingRotate180(imOut, imIn); + else + /* Use ordinary version */ + (void) ImagingRotate(imOut, imIn, theta, 0); + } + } + + return PyImagingNew(imOut); +} + +#define IS_RGB(mode)\ + (!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode, "RGBX")) + +static PyObject* +im_setmode(ImagingObject* self, PyObject* args) +{ + /* attempt to modify the mode of an image in place */ + + Imaging im; + + char* mode; + int modelen; + if (!PyArg_ParseTuple(args, "s#:setmode", &mode, &modelen)) + return NULL; + + im = self->image; + + /* move all logic in here to the libImaging primitive */ + + if (!strcmp(im->mode, mode)) { + ; /* same mode; always succeeds */ + } else if (IS_RGB(im->mode) && IS_RGB(mode)) { + /* color to color */ + strcpy(im->mode, mode); + im->bands = modelen; + if (!strcmp(mode, "RGBA")) + (void) ImagingFillBand(im, 3, 255); + } else { + /* trying doing an in-place conversion */ + if (!ImagingConvertInPlace(im, mode)) + return NULL; + } + + if (self->access) + ImagingAccessDelete(im, self->access); + self->access = ImagingAccessNew(im); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_stretch(ImagingObject* self, PyObject* args) +{ + Imaging imIn; + Imaging imTemp; + Imaging imOut; + + int xsize, ysize; + int filter = IMAGING_TRANSFORM_NEAREST; + if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) + return NULL; + + imIn = self->image; + + /* two-pass resize: minimize size of intermediate image */ + if (imIn->xsize * ysize < xsize * imIn->ysize) + imTemp = ImagingNew(imIn->mode, imIn->xsize, ysize); + else + imTemp = ImagingNew(imIn->mode, xsize, imIn->ysize); + if (!imTemp) + return NULL; + + /* first pass */ + if (!ImagingStretch(imTemp, imIn, filter)) { + ImagingDelete(imTemp); + return NULL; + } + + imOut = ImagingNew(imIn->mode, xsize, ysize); + if (!imOut) { + ImagingDelete(imTemp); + return NULL; + } + + /* second pass */ + if (!ImagingStretch(imOut, imTemp, filter)) { + ImagingDelete(imOut); + ImagingDelete(imTemp); + return NULL; + } + + ImagingDelete(imTemp); + + return PyImagingNew(imOut); +} + +static PyObject* +_transform2(ImagingObject* self, PyObject* args) +{ + static const char* wrong_number = "wrong number of matrix entries"; + + Imaging imIn; + Imaging imOut; + int n; + double *a; + + ImagingObject* imagep; + int x0, y0, x1, y1; + int method; + PyObject* data; + int filter = IMAGING_TRANSFORM_NEAREST; + int fill = 1; + if (!PyArg_ParseTuple(args, "(iiii)O!iO|ii", + &x0, &y0, &x1, &y1, + &Imaging_Type, &imagep, + &method, &data, + &filter, &fill)) + return NULL; + + switch (method) { + case IMAGING_TRANSFORM_AFFINE: + n = 6; + break; + case IMAGING_TRANSFORM_PERSPECTIVE: + n = 8; + break; + case IMAGING_TRANSFORM_QUAD: + n = 8; + break; + default: + n = -1; /* force error */ + } + + a = getlist(data, &n, wrong_number, TYPE_DOUBLE); + if (!a) + return NULL; + + imOut = self->image; + imIn = imagep->image; + + /* FIXME: move transform dispatcher into libImaging */ + + switch (method) { + case IMAGING_TRANSFORM_AFFINE: + imOut = ImagingTransformAffine( + imOut, imIn, x0, y0, x1, y1, a, filter, 1 + ); + break; + case IMAGING_TRANSFORM_PERSPECTIVE: + imOut = ImagingTransformPerspective( + imOut, imIn, x0, y0, x1, y1, a, filter, 1 + ); + break; + case IMAGING_TRANSFORM_QUAD: + imOut = ImagingTransformQuad( + imOut, imIn, x0, y0, x1, y1, a, filter, 1 + ); + break; + default: + (void) ImagingError_ValueError("bad transform method"); + } + + free(a); + + if (!imOut) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_transpose(ImagingObject* self, PyObject* args) +{ + Imaging imIn; + Imaging imOut; + + int op; + if (!PyArg_ParseTuple(args, "i", &op)) + return NULL; + + imIn = self->image; + + switch (op) { + case 0: /* flip left right */ + case 1: /* flip top bottom */ + case 3: /* rotate 180 */ + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + break; + case 2: /* rotate 90 */ + case 4: /* rotate 270 */ + imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize); + break; + default: + PyErr_SetString(PyExc_ValueError, "No such transpose operation"); + return NULL; + } + + if (imOut) + switch (op) { + case 0: + (void) ImagingFlipLeftRight(imOut, imIn); + break; + case 1: + (void) ImagingFlipTopBottom(imOut, imIn); + break; + case 2: + (void) ImagingRotate90(imOut, imIn); + break; + case 3: + (void) ImagingRotate180(imOut, imIn); + break; + case 4: + (void) ImagingRotate270(imOut, imIn); + break; + } + + return PyImagingNew(imOut); +} + +#ifdef WITH_UNSHARPMASK +static PyObject* +_unsharp_mask(ImagingObject* self, PyObject* args) +{ + Imaging imIn; + Imaging imOut; + + float radius; + int percent, threshold; + if (!PyArg_ParseTuple(args, "fii", &radius, &percent, &threshold)) + return NULL; + + + imIn = self->image; + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + if (!imOut) + return NULL; + + if (!ImagingUnsharpMask(imIn, imOut, radius, percent, threshold)) + return NULL; + + return PyImagingNew(imOut); +} +#endif + +/* -------------------------------------------------------------------- */ + +static PyObject* +_isblock(ImagingObject* self, PyObject* args) +{ + return PyInt_FromLong((long) self->image->block); +} + +static PyObject* +_getbbox(ImagingObject* self, PyObject* args) +{ + int bbox[4]; + if (!ImagingGetBBox(self->image, bbox)) { + Py_INCREF(Py_None); + return Py_None; + } + + return Py_BuildValue("iiii", bbox[0], bbox[1], bbox[2], bbox[3]); +} + +static PyObject* +_getcolors(ImagingObject* self, PyObject* args) +{ + ImagingColorItem* items; + int i, colors; + PyObject* out; + + int maxcolors = 256; + if (!PyArg_ParseTuple(args, "i:getcolors", &maxcolors)) + return NULL; + + items = ImagingGetColors(self->image, maxcolors, &colors); + if (!items) + return NULL; + + if (colors > maxcolors) { + out = Py_None; + Py_INCREF(out); + } else { + out = PyList_New(colors); + for (i = 0; i < colors; i++) { + ImagingColorItem* v = &items[i]; + PyObject* item = Py_BuildValue( + "iN", v->count, getpixel(self->image, self->access, v->x, v->y) + ); + PyList_SetItem(out, i, item); + } + } + + free(items); + + return out; +} + +static PyObject* +_getextrema(ImagingObject* self, PyObject* args) +{ + union { + UINT8 u[2]; + INT32 i[2]; + FLOAT32 f[2]; + } extrema; + int status; + + status = ImagingGetExtrema(self->image, &extrema); + if (status < 0) + return NULL; + + if (status) + switch (self->image->type) { + case IMAGING_TYPE_UINT8: + return Py_BuildValue("ii", extrema.u[0], extrema.u[1]); + case IMAGING_TYPE_INT32: + return Py_BuildValue("ii", extrema.i[0], extrema.i[1]); + case IMAGING_TYPE_FLOAT32: + return Py_BuildValue("dd", extrema.f[0], extrema.f[1]); + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_getprojection(ImagingObject* self, PyObject* args) +{ + unsigned char* xprofile; + unsigned char* yprofile; + PyObject* result; + + xprofile = malloc(self->image->xsize); + yprofile = malloc(self->image->ysize); + + if (xprofile == NULL || yprofile == NULL) { + free(xprofile); + free(yprofile); + return PyErr_NoMemory(); + } + + ImagingGetProjection(self->image, (unsigned char *)xprofile, (unsigned char *)yprofile); + + result = Py_BuildValue("s#s#", xprofile, self->image->xsize, + yprofile, self->image->ysize); + + free(xprofile); + free(yprofile); + + return result; +} + +/* -------------------------------------------------------------------- */ + +static PyObject* +_getband(ImagingObject* self, PyObject* args) +{ + int band; + + if (!PyArg_ParseTuple(args, "i", &band)) + return NULL; + + return PyImagingNew(ImagingGetBand(self->image, band)); +} + +static PyObject* +_fillband(ImagingObject* self, PyObject* args) +{ + int band; + int color; + + if (!PyArg_ParseTuple(args, "ii", &band, &color)) + return NULL; + + if (!ImagingFillBand(self->image, band, color)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_putband(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + int band; + if (!PyArg_ParseTuple(args, "O!i", + &Imaging_Type, &imagep, + &band)) + return NULL; + + if (!ImagingPutBand(self->image, imagep->image, band)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +/* -------------------------------------------------------------------- */ + +#ifdef WITH_IMAGECHOPS + +static PyObject* +_chop_invert(ImagingObject* self, PyObject* args) +{ + return PyImagingNew(ImagingNegative(self->image)); +} + +static PyObject* +_chop_lighter(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopLighter(self->image, imagep->image)); +} + +static PyObject* +_chop_darker(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopDarker(self->image, imagep->image)); +} + +static PyObject* +_chop_difference(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopDifference(self->image, imagep->image)); +} + +static PyObject* +_chop_multiply(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopMultiply(self->image, imagep->image)); +} + +static PyObject* +_chop_screen(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopScreen(self->image, imagep->image)); +} + +static PyObject* +_chop_add(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + float scale; + int offset; + + scale = 1.0; + offset = 0; + + if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep, + &scale, &offset)) + return NULL; + + return PyImagingNew(ImagingChopAdd(self->image, imagep->image, + scale, offset)); +} + +static PyObject* +_chop_subtract(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + float scale; + int offset; + + scale = 1.0; + offset = 0; + + if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep, + &scale, &offset)) + return NULL; + + return PyImagingNew(ImagingChopSubtract(self->image, imagep->image, + scale, offset)); +} + +static PyObject* +_chop_and(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopAnd(self->image, imagep->image)); +} + +static PyObject* +_chop_or(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopOr(self->image, imagep->image)); +} + +static PyObject* +_chop_xor(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopXor(self->image, imagep->image)); +} + +static PyObject* +_chop_add_modulo(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopAddModulo(self->image, imagep->image)); +} + +static PyObject* +_chop_subtract_modulo(ImagingObject* self, PyObject* args) +{ + ImagingObject* imagep; + + if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) + return NULL; + + return PyImagingNew(ImagingChopSubtractModulo(self->image, imagep->image)); +} + +#endif + + +/* -------------------------------------------------------------------- */ + +#ifdef WITH_IMAGEDRAW + +static PyObject* +_font_new(PyObject* self_, PyObject* args) +{ + ImagingFontObject *self; + int i, y0, y1; + static const char* wrong_length = "descriptor table has wrong size"; + + ImagingObject* imagep; + unsigned char* glyphdata; + int glyphdata_length; + if (!PyArg_ParseTuple(args, "O!s#", + &Imaging_Type, &imagep, + &glyphdata, &glyphdata_length)) + return NULL; + + if (glyphdata_length != 256 * 20) { + PyErr_SetString(PyExc_ValueError, wrong_length); + return NULL; + } + + self = PyObject_New(ImagingFontObject, &ImagingFont_Type); + if (self == NULL) + return NULL; + + /* glyph bitmap */ + self->bitmap = imagep->image; + + y0 = y1 = 0; + + /* glyph glyphs */ + for (i = 0; i < 256; i++) { + self->glyphs[i].dx = S16(B16(glyphdata, 0)); + self->glyphs[i].dy = S16(B16(glyphdata, 2)); + self->glyphs[i].dx0 = S16(B16(glyphdata, 4)); + self->glyphs[i].dy0 = S16(B16(glyphdata, 6)); + self->glyphs[i].dx1 = S16(B16(glyphdata, 8)); + self->glyphs[i].dy1 = S16(B16(glyphdata, 10)); + self->glyphs[i].sx0 = S16(B16(glyphdata, 12)); + self->glyphs[i].sy0 = S16(B16(glyphdata, 14)); + self->glyphs[i].sx1 = S16(B16(glyphdata, 16)); + self->glyphs[i].sy1 = S16(B16(glyphdata, 18)); + if (self->glyphs[i].dy0 < y0) + y0 = self->glyphs[i].dy0; + if (self->glyphs[i].dy1 > y1) + y1 = self->glyphs[i].dy1; + glyphdata += 20; + } + + self->baseline = -y0; + self->ysize = y1 - y0; + + /* keep a reference to the bitmap object */ + Py_INCREF(imagep); + self->ref = imagep; + + return (PyObject*) self; +} + +static void +_font_dealloc(ImagingFontObject* self) +{ + Py_XDECREF(self->ref); + PyObject_Del(self); +} + +static inline int +textwidth(ImagingFontObject* self, const unsigned char* text) +{ + int xsize; + + for (xsize = 0; *text; text++) + xsize += self->glyphs[*text].dx; + + return xsize; +} + +static PyObject* +_font_getmask(ImagingFontObject* self, PyObject* args) +{ + Imaging im; + Imaging bitmap; + int x, b; + int status; + Glyph* glyph; + + unsigned char* text; + char* mode = ""; + if (!PyArg_ParseTuple(args, "s|s:getmask", &text, &mode)) + return NULL; + + im = ImagingNew(self->bitmap->mode, textwidth(self, text), self->ysize); + if (!im) + return NULL; + + b = 0; + (void) ImagingFill(im, &b); + + b = self->baseline; + for (x = 0; *text; text++) { + glyph = &self->glyphs[*text]; + bitmap = ImagingCrop( + self->bitmap, + glyph->sx0, glyph->sy0, glyph->sx1, glyph->sy1 + ); + if (!bitmap) + goto failed; + status = ImagingPaste( + im, bitmap, NULL, + glyph->dx0+x, glyph->dy0+b, glyph->dx1+x, glyph->dy1+b + ); + ImagingDelete(bitmap); + if (status < 0) + goto failed; + x = x + glyph->dx; + b = b + glyph->dy; + } + + return PyImagingNew(im); + + failed: + ImagingDelete(im); + return NULL; +} + +static PyObject* +_font_getsize(ImagingFontObject* self, PyObject* args) +{ + unsigned char* text; + if (!PyArg_ParseTuple(args, "s:getsize", &text)) + return NULL; + + return Py_BuildValue("ii", textwidth(self, text), self->ysize); +} + +static struct PyMethodDef _font_methods[] = { + {"getmask", (PyCFunction)_font_getmask, 1}, + {"getsize", (PyCFunction)_font_getsize, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +_font_getattr(ImagingFontObject* self, char* name) +{ + return Py_FindMethod(_font_methods, (PyObject*) self, name); +} + +/* -------------------------------------------------------------------- */ + +static PyObject* +_draw_new(PyObject* self_, PyObject* args) +{ + ImagingDrawObject *self; + + ImagingObject* imagep; + int blend = 0; + if (!PyArg_ParseTuple(args, "O!|i", &Imaging_Type, &imagep, &blend)) + return NULL; + + self = PyObject_New(ImagingDrawObject, &ImagingDraw_Type); + if (self == NULL) + return NULL; + + /* keep a reference to the image object */ + Py_INCREF(imagep); + self->image = imagep; + + self->ink[0] = self->ink[1] = self->ink[2] = self->ink[3] = 0; + + self->blend = blend; + + return (PyObject*) self; +} + +static void +_draw_dealloc(ImagingDrawObject* self) +{ + Py_XDECREF(self->image); + PyObject_Del(self); +} + +extern int PyPath_Flatten(PyObject* data, double **xy); + +static PyObject* +_draw_ink(ImagingDrawObject* self, PyObject* args) +{ + INT32 ink = 0; + PyObject* color; + char* mode = NULL; /* not used in this release */ + if (!PyArg_ParseTuple(args, "O|s", &color, &mode)) + return NULL; + + if (!getink(color, self->image->image, (char*) &ink)) + return NULL; + + return PyInt_FromLong((int) ink); +} + +static PyObject* +_draw_arc(ImagingDrawObject* self, PyObject* args) +{ + int x0, y0, x1, y1; + int ink; + int start, end; + int op = 0; + if (!PyArg_ParseTuple(args, "(iiii)iii|i", + &x0, &y0, &x1, &y1, + &start, &end, &ink)) + return NULL; + + if (ImagingDrawArc(self->image->image, x0, y0, x1, y1, start, end, + &ink, op) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_bitmap(ImagingDrawObject* self, PyObject* args) +{ + double *xy; + int n; + + PyObject *data; + ImagingObject* bitmap; + int ink; + if (!PyArg_ParseTuple(args, "OO!i", &data, &Imaging_Type, &bitmap, &ink)) + return NULL; + + n = PyPath_Flatten(data, &xy); + if (n < 0) + return NULL; + if (n != 1) { + PyErr_SetString( + PyExc_TypeError, + "coordinate list must contain exactly 1 coordinate" + ); + return NULL; + } + + n = ImagingDrawBitmap( + self->image->image, (int) xy[0], (int) xy[1], bitmap->image, + &ink, self->blend + ); + + free(xy); + + if (n < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_chord(ImagingDrawObject* self, PyObject* args) +{ + int x0, y0, x1, y1; + int ink, fill; + int start, end; + if (!PyArg_ParseTuple(args, "(iiii)iiii", + &x0, &y0, &x1, &y1, &start, &end, &ink, &fill)) + return NULL; + + if (ImagingDrawChord(self->image->image, x0, y0, x1, y1, + start, end, &ink, fill, self->blend) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_ellipse(ImagingDrawObject* self, PyObject* args) +{ + double* xy; + int n; + + PyObject* data; + int ink; + int fill = 0; + if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) + return NULL; + + n = PyPath_Flatten(data, &xy); + if (n < 0) + return NULL; + if (n != 2) { + PyErr_SetString( + PyExc_TypeError, + "coordinate list must contain exactly 2 coordinates" + ); + return NULL; + } + + n = ImagingDrawEllipse( + self->image->image, (int) xy[0], (int) xy[1], (int) xy[2], (int) xy[3], + &ink, fill, self->blend + ); + + free(xy); + + if (n < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_line(ImagingDrawObject* self, PyObject* args) +{ + int x0, y0, x1, y1; + int ink; + if (!PyArg_ParseTuple(args, "(ii)(ii)i", &x0, &y0, &x1, &y1, &ink)) + return NULL; + + if (ImagingDrawLine(self->image->image, x0, y0, x1, y1, + &ink, self->blend) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_lines(ImagingDrawObject* self, PyObject* args) +{ + double *xy; + int i, n; + + PyObject *data; + int ink; + int width = 0; + if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &width)) + return NULL; + + n = PyPath_Flatten(data, &xy); + if (n < 0) + return NULL; + + if (width <= 1) { + double *p = NULL; + for (i = 0; i < n-1; i++) { + p = &xy[i+i]; + if (ImagingDrawLine( + self->image->image, + (int) p[0], (int) p[1], (int) p[2], (int) p[3], + &ink, self->blend) < 0) { + free(xy); + return NULL; + } + } + if (p) /* draw last point */ + ImagingDrawPoint( + self->image->image, + (int) p[2], (int) p[3], + &ink, self->blend + ); + } else { + for (i = 0; i < n-1; i++) { + double *p = &xy[i+i]; + if (ImagingDrawWideLine( + self->image->image, + (int) p[0], (int) p[1], (int) p[2], (int) p[3], + &ink, width, self->blend) < 0) { + free(xy); + return NULL; + } + } + } + + free(xy); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_point(ImagingDrawObject* self, PyObject* args) +{ + int x, y; + int ink; + if (!PyArg_ParseTuple(args, "(ii)i", &x, &y, &ink)) + return NULL; + + if (ImagingDrawPoint(self->image->image, x, y, &ink, self->blend) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_points(ImagingDrawObject* self, PyObject* args) +{ + double *xy; + int i, n; + + PyObject *data; + int ink; + if (!PyArg_ParseTuple(args, "Oi", &data, &ink)) + return NULL; + + n = PyPath_Flatten(data, &xy); + if (n < 0) + return NULL; + + for (i = 0; i < n; i++) { + double *p = &xy[i+i]; + if (ImagingDrawPoint(self->image->image, (int) p[0], (int) p[1], + &ink, self->blend) < 0) { + free(xy); + return NULL; + } + } + + free(xy); + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WITH_ARROW + +/* from outline.c */ +extern ImagingOutline PyOutline_AsOutline(PyObject* outline); + +static PyObject* +_draw_outline(ImagingDrawObject* self, PyObject* args) +{ + ImagingOutline outline; + + PyObject* outline_; + int ink; + int fill = 0; + if (!PyArg_ParseTuple(args, "Oi|i", &outline_, &ink, &fill)) + return NULL; + + outline = PyOutline_AsOutline(outline_); + if (!outline) { + PyErr_SetString(PyExc_TypeError, "expected outline object"); + return NULL; + } + + if (ImagingDrawOutline(self->image->image, outline, + &ink, fill, self->blend) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +#endif + +static PyObject* +_draw_pieslice(ImagingDrawObject* self, PyObject* args) +{ + int x0, y0, x1, y1; + int ink, fill; + int start, end; + if (!PyArg_ParseTuple(args, "(iiii)iiii", + &x0, &y0, &x1, &y1, &start, &end, &ink, &fill)) + return NULL; + + if (ImagingDrawPieslice(self->image->image, x0, y0, x1, y1, + start, end, &ink, fill, self->blend) < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_polygon(ImagingDrawObject* self, PyObject* args) +{ + double *xy; + int *ixy; + int n, i; + + PyObject* data; + int ink; + int fill = 0; + if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) + return NULL; + + n = PyPath_Flatten(data, &xy); + if (n < 0) + return NULL; + if (n < 2) { + PyErr_SetString( + PyExc_TypeError, + "coordinate list must contain at least 2 coordinates" + ); + return NULL; + } + + /* Copy list of vertices to array */ + ixy = (int*) malloc(n * 2 * sizeof(int)); + + for (i = 0; i < n; i++) { + ixy[i+i] = (int) xy[i+i]; + ixy[i+i+1] = (int) xy[i+i+1]; + } + + free(xy); + + if (ImagingDrawPolygon(self->image->image, n, ixy, + &ink, fill, self->blend) < 0) { + free(ixy); + return NULL; + } + + free(ixy); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw_rectangle(ImagingDrawObject* self, PyObject* args) +{ + double* xy; + int n; + + PyObject* data; + int ink; + int fill = 0; + if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) + return NULL; + + n = PyPath_Flatten(data, &xy); + if (n < 0) + return NULL; + if (n != 2) { + PyErr_SetString( + PyExc_TypeError, + "coordinate list must contain exactly 2 coordinates" + ); + return NULL; + } + + n = ImagingDrawRectangle( + self->image->image, (int) xy[0], (int) xy[1], + (int) xy[2], (int) xy[3], &ink, fill, self->blend + ); + + free(xy); + + if (n < 0) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static struct PyMethodDef _draw_methods[] = { +#ifdef WITH_IMAGEDRAW + /* Graphics (ImageDraw) */ + {"draw_line", (PyCFunction)_draw_line, 1}, + {"draw_lines", (PyCFunction)_draw_lines, 1}, +#ifdef WITH_ARROW + {"draw_outline", (PyCFunction)_draw_outline, 1}, +#endif + {"draw_polygon", (PyCFunction)_draw_polygon, 1}, + {"draw_rectangle", (PyCFunction)_draw_rectangle, 1}, + {"draw_point", (PyCFunction)_draw_point, 1}, + {"draw_points", (PyCFunction)_draw_points, 1}, + {"draw_arc", (PyCFunction)_draw_arc, 1}, + {"draw_bitmap", (PyCFunction)_draw_bitmap, 1}, + {"draw_chord", (PyCFunction)_draw_chord, 1}, + {"draw_ellipse", (PyCFunction)_draw_ellipse, 1}, + {"draw_pieslice", (PyCFunction)_draw_pieslice, 1}, + {"draw_ink", (PyCFunction)_draw_ink, 1}, +#endif + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +_draw_getattr(ImagingDrawObject* self, char* name) +{ + return Py_FindMethod(_draw_methods, (PyObject*) self, name); +} + +#endif + + +static PyObject* +pixel_access_new(ImagingObject* imagep, PyObject* args) +{ + PixelAccessObject *self; + + int readonly = 0; + if (!PyArg_ParseTuple(args, "|i", &readonly)) + return NULL; + + self = PyObject_New(PixelAccessObject, &PixelAccess_Type); + if (self == NULL) + return NULL; + + /* keep a reference to the image object */ + Py_INCREF(imagep); + self->image = imagep; + + self->readonly = readonly; + + return (PyObject*) self; +} + +static void +pixel_access_dealloc(PixelAccessObject* self) +{ + Py_XDECREF(self->image); + PyObject_Del(self); +} + +static PyObject * +pixel_access_getitem(PixelAccessObject *self, PyObject *xy) +{ + int x, y; + if (_getxy(xy, &x, &y)) + return NULL; + + return getpixel(self->image->image, self->image->access, x, y); +} + +static int +pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) +{ + Imaging im = self->image->image; + char ink[4]; + int x, y; + + if (self->readonly) { + (void) ImagingError_ValueError(readonly); + return -1; + } + + if (_getxy(xy, &x, &y)) + return -1; + + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { + PyErr_SetString(PyExc_IndexError, outside_image); + return -1; + } + + if (!color) /* FIXME: raise exception? */ + return 0; + + if (!getink(color, im, ink)) + return -1; + + self->image->access->put_pixel(im, x, y, ink); + + return 0; +} + +/* -------------------------------------------------------------------- */ +/* EFFECTS (experimental) */ +/* -------------------------------------------------------------------- */ + +#ifdef WITH_EFFECTS + +static PyObject* +_effect_mandelbrot(ImagingObject* self, PyObject* args) +{ + int xsize = 512; + int ysize = 512; + double extent[4]; + int quality = 100; + + extent[0] = -3; extent[1] = -2.5; + extent[2] = 2; extent[3] = 2.5; + + if (!PyArg_ParseTuple(args, "|(ii)(dddd)i", &xsize, &ysize, + &extent[0], &extent[1], &extent[2], &extent[3], + &quality)) + return NULL; + + return PyImagingNew(ImagingEffectMandelbrot(xsize, ysize, extent, quality)); +} + +static PyObject* +_effect_noise(ImagingObject* self, PyObject* args) +{ + int xsize, ysize; + float sigma = 128; + if (!PyArg_ParseTuple(args, "(ii)|f", &xsize, &ysize, &sigma)) + return NULL; + + return PyImagingNew(ImagingEffectNoise(xsize, ysize, sigma)); +} + +static PyObject* +_effect_spread(ImagingObject* self, PyObject* args) +{ + int dist; + + if (!PyArg_ParseTuple(args, "i", &dist)) + return NULL; + + return PyImagingNew(ImagingEffectSpread(self->image, dist)); +} + +#endif + +/* -------------------------------------------------------------------- */ +/* UTILITIES */ +/* -------------------------------------------------------------------- */ + +static PyObject* +_crc32(PyObject* self, PyObject* args) +{ + unsigned char* buffer; + int bytes; + int hi, lo; + UINT32 crc; + + hi = lo = 0; + + if (!PyArg_ParseTuple(args, "s#|(ii)", &buffer, &bytes, &hi, &lo)) + return NULL; + + crc = ((UINT32) (hi & 0xFFFF) << 16) + (lo & 0xFFFF); + + crc = ImagingCRC32(crc, (unsigned char *)buffer, bytes); + + return Py_BuildValue("ii", (crc >> 16) & 0xFFFF, crc & 0xFFFF); +} + +static PyObject* +_getcodecstatus(PyObject* self, PyObject* args) +{ + int status; + char* msg; + + if (!PyArg_ParseTuple(args, "i", &status)) + return NULL; + + switch (status) { + case IMAGING_CODEC_OVERRUN: + msg = "buffer overrun"; break; + case IMAGING_CODEC_BROKEN: + msg = "broken data stream"; break; + case IMAGING_CODEC_UNKNOWN: + msg = "unrecognized data stream contents"; break; + case IMAGING_CODEC_CONFIG: + msg = "codec configuration error"; break; + case IMAGING_CODEC_MEMORY: + msg = "out of memory"; break; + default: + Py_INCREF(Py_None); + return Py_None; + } + + return PyString_FromString(msg); +} + +/* -------------------------------------------------------------------- */ +/* DEBUGGING HELPERS */ +/* -------------------------------------------------------------------- */ + + +#ifdef WITH_DEBUG + +static PyObject* +_save_ppm(ImagingObject* self, PyObject* args) +{ + char* filename; + + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + if (!ImagingSavePPM(self->image, filename)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +#endif + +/* -------------------------------------------------------------------- */ + +/* methods */ + +static struct PyMethodDef methods[] = { + + /* Put commonly used methods first */ + {"getpixel", (PyCFunction)_getpixel, 1}, + {"putpixel", (PyCFunction)_putpixel, 1}, + + {"pixel_access", (PyCFunction)pixel_access_new, 1}, + + /* Standard processing methods (Image) */ + {"convert", (PyCFunction)_convert, 1}, + {"convert2", (PyCFunction)_convert2, 1}, + {"convert_matrix", (PyCFunction)_convert_matrix, 1}, + {"copy", (PyCFunction)_copy, 1}, + {"copy2", (PyCFunction)_copy2, 1}, +#ifdef WITH_CRACKCODE + {"crackcode", (PyCFunction)_crackcode, 1}, +#endif + {"crop", (PyCFunction)_crop, 1}, + {"expand", (PyCFunction)_expand, 1}, + {"filter", (PyCFunction)_filter, 1}, + {"histogram", (PyCFunction)_histogram, 1}, +#ifdef WITH_MODEFILTER + {"modefilter", (PyCFunction)_modefilter, 1}, +#endif + {"offset", (PyCFunction)_offset, 1}, + {"paste", (PyCFunction)_paste, 1}, + {"point", (PyCFunction)_point, 1}, + {"point_transform", (PyCFunction)_point_transform, 1}, + {"putdata", (PyCFunction)_putdata, 1}, +#ifdef WITH_QUANTIZE + {"quantize", (PyCFunction)_quantize, 1}, +#endif +#ifdef WITH_RANKFILTER + {"rankfilter", (PyCFunction)_rankfilter, 1}, +#endif + {"resize", (PyCFunction)_resize, 1}, + {"rotate", (PyCFunction)_rotate, 1}, + {"stretch", (PyCFunction)_stretch, 1}, + {"transpose", (PyCFunction)_transpose, 1}, + {"transform2", (PyCFunction)_transform2, 1}, + + {"isblock", (PyCFunction)_isblock, 1}, + + {"getbbox", (PyCFunction)_getbbox, 1}, + {"getcolors", (PyCFunction)_getcolors, 1}, + {"getextrema", (PyCFunction)_getextrema, 1}, + {"getprojection", (PyCFunction)_getprojection, 1}, + + {"getband", (PyCFunction)_getband, 1}, + {"putband", (PyCFunction)_putband, 1}, + {"fillband", (PyCFunction)_fillband, 1}, + + {"setmode", (PyCFunction)im_setmode, 1}, + + {"getpalette", (PyCFunction)_getpalette, 1}, + {"putpalette", (PyCFunction)_putpalette, 1}, + {"putpalettealpha", (PyCFunction)_putpalettealpha, 1}, + +#ifdef WITH_IMAGECHOPS + /* Channel operations (ImageChops) */ + {"chop_invert", (PyCFunction)_chop_invert, 1}, + {"chop_lighter", (PyCFunction)_chop_lighter, 1}, + {"chop_darker", (PyCFunction)_chop_darker, 1}, + {"chop_difference", (PyCFunction)_chop_difference, 1}, + {"chop_multiply", (PyCFunction)_chop_multiply, 1}, + {"chop_screen", (PyCFunction)_chop_screen, 1}, + {"chop_add", (PyCFunction)_chop_add, 1}, + {"chop_subtract", (PyCFunction)_chop_subtract, 1}, + {"chop_add_modulo", (PyCFunction)_chop_add_modulo, 1}, + {"chop_subtract_modulo", (PyCFunction)_chop_subtract_modulo, 1}, + {"chop_and", (PyCFunction)_chop_and, 1}, + {"chop_or", (PyCFunction)_chop_or, 1}, + {"chop_xor", (PyCFunction)_chop_xor, 1}, +#endif + +#ifdef WITH_UNSHARPMASK + /* Kevin Cazabon's unsharpmask extension */ + {"gaussian_blur", (PyCFunction)_gaussian_blur, 1}, + {"unsharp_mask", (PyCFunction)_unsharp_mask, 1}, +#endif + +#ifdef WITH_EFFECTS + /* Special effects */ + {"effect_spread", (PyCFunction)_effect_spread, 1}, +#endif + + /* Misc. */ + {"new_array", (PyCFunction)_new_array, 1}, + {"new_block", (PyCFunction)_new_block, 1}, + +#ifdef WITH_DEBUG + {"save_ppm", (PyCFunction)_save_ppm, 1}, +#endif + + {NULL, NULL} /* sentinel */ +}; + + +/* attributes */ + +static PyObject* +_getattr(ImagingObject* self, char* name) +{ + PyObject* res; + + res = Py_FindMethod(methods, (PyObject*) self, name); + if (res) + return res; + PyErr_Clear(); + if (strcmp(name, "mode") == 0) + return PyString_FromString(self->image->mode); + if (strcmp(name, "size") == 0) + return Py_BuildValue("ii", self->image->xsize, self->image->ysize); + if (strcmp(name, "bands") == 0) + return PyInt_FromLong(self->image->bands); + if (strcmp(name, "id") == 0) + return PyInt_FromLong((long) self->image); + if (strcmp(name, "ptr") == 0) + return PyCObject_FromVoidPtrAndDesc(self->image, IMAGING_MAGIC, NULL); + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + + +/* basic sequence semantics */ + +static Py_ssize_t +image_length(ImagingObject *self) +{ + Imaging im = self->image; + + return im->xsize * im->ysize; +} + +static PyObject * +image_item(ImagingObject *self, Py_ssize_t i) +{ + int x, y; + Imaging im = self->image; + + if (im->xsize > 0) { + x = i % im->xsize; + y = i / im->xsize; + } else + x = y = 0; /* leave it to getpixel to raise an exception */ + + return getpixel(im, self->access, x, y); +} + +static PySequenceMethods image_as_sequence = { + (inquiry) image_length, /*sq_length*/ + (binaryfunc) NULL, /*sq_concat*/ + (ssizeargfunc) NULL, /*sq_repeat*/ + (ssizeargfunc) image_item, /*sq_item*/ + (ssizessizeargfunc) NULL, /*sq_slice*/ + (ssizeobjargproc) NULL, /*sq_ass_item*/ + (ssizessizeobjargproc) NULL, /*sq_ass_slice*/ +}; + + +/* type description */ + +statichere PyTypeObject Imaging_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingCore", /*tp_name*/ + sizeof(ImagingObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + &image_as_sequence, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0 /*tp_hash*/ +}; + +#ifdef WITH_IMAGEDRAW + +statichere PyTypeObject ImagingFont_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingFont", /*tp_name*/ + sizeof(ImagingFontObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_font_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_font_getattr, /*tp_getattr*/ +}; + +statichere PyTypeObject ImagingDraw_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingDraw", /*tp_name*/ + sizeof(ImagingDrawObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_draw_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_draw_getattr, /*tp_getattr*/ +}; + +#endif + +static PyMappingMethods pixel_access_as_mapping = { + (inquiry) NULL, /*mp_length*/ + (binaryfunc) pixel_access_getitem, /*mp_subscript*/ + (objobjargproc) pixel_access_setitem, /*mp_ass_subscript*/ +}; + +/* type description */ + +statichere PyTypeObject PixelAccess_Type = { + PyObject_HEAD_INIT(NULL) + 0, "PixelAccess", sizeof(PixelAccessObject), 0, + /* methods */ + (destructor)pixel_access_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + 0, /*tp_as_sequence */ + &pixel_access_as_mapping, /*tp_as_mapping */ + 0 /*tp_hash*/ +}; + +/* -------------------------------------------------------------------- */ + +/* FIXME: this is something of a mess. Should replace this with + pluggable codecs, but not before PIL 1.2 */ + +/* Decoders (in decode.c) */ +extern PyObject* PyImaging_BitDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_FliDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_GifDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_HexDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_JpegDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_MspDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_PcdDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_PcxDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_RawDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_XbmDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_ZipDecoderNew(PyObject* self, PyObject* args); + +/* Encoders (in encode.c) */ +extern PyObject* PyImaging_EpsEncoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_GifEncoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_JpegEncoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_PcxEncoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_RawEncoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_XbmEncoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_ZipEncoderNew(PyObject* self, PyObject* args); + +/* Display support etc (in display.c) */ +#ifdef WIN32 +extern PyObject* PyImaging_CreateWindowWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_DisplayWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_DisplayModeWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_GrabScreenWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_ListWindowsWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_EventLoopWin32(PyObject* self, PyObject* args); +extern PyObject* PyImaging_DrawWmf(PyObject* self, PyObject* args); +#endif + +/* Experimental path stuff (in path.c) */ +extern PyObject* PyPath_Create(ImagingObject* self, PyObject* args); + +/* Experimental outline stuff (in outline.c) */ +extern PyObject* PyOutline_Create(ImagingObject* self, PyObject* args); + +extern PyObject* PyImaging_Mapper(PyObject* self, PyObject* args); +extern PyObject* PyImaging_MapBuffer(PyObject* self, PyObject* args); + +static PyMethodDef functions[] = { + + /* Object factories */ + {"blend", (PyCFunction)_blend, 1}, + {"fill", (PyCFunction)_fill, 1}, + {"new", (PyCFunction)_new, 1}, + + {"getcount", (PyCFunction)_getcount, 1}, + + /* Functions */ + {"convert", (PyCFunction)_convert2, 1}, + {"copy", (PyCFunction)_copy2, 1}, + + /* Codecs */ + {"bit_decoder", (PyCFunction)PyImaging_BitDecoderNew, 1}, + {"eps_encoder", (PyCFunction)PyImaging_EpsEncoderNew, 1}, + {"fli_decoder", (PyCFunction)PyImaging_FliDecoderNew, 1}, + {"gif_decoder", (PyCFunction)PyImaging_GifDecoderNew, 1}, + {"gif_encoder", (PyCFunction)PyImaging_GifEncoderNew, 1}, + {"hex_decoder", (PyCFunction)PyImaging_HexDecoderNew, 1}, + {"hex_encoder", (PyCFunction)PyImaging_EpsEncoderNew, 1}, /* EPS=HEX! */ +#ifdef HAVE_LIBJPEG + {"jpeg_decoder", (PyCFunction)PyImaging_JpegDecoderNew, 1}, + {"jpeg_encoder", (PyCFunction)PyImaging_JpegEncoderNew, 1}, +#endif + {"tiff_lzw_decoder", (PyCFunction)PyImaging_TiffLzwDecoderNew, 1}, + {"msp_decoder", (PyCFunction)PyImaging_MspDecoderNew, 1}, + {"packbits_decoder", (PyCFunction)PyImaging_PackbitsDecoderNew, 1}, + {"pcd_decoder", (PyCFunction)PyImaging_PcdDecoderNew, 1}, + {"pcx_decoder", (PyCFunction)PyImaging_PcxDecoderNew, 1}, + {"pcx_encoder", (PyCFunction)PyImaging_PcxEncoderNew, 1}, + {"raw_decoder", (PyCFunction)PyImaging_RawDecoderNew, 1}, + {"raw_encoder", (PyCFunction)PyImaging_RawEncoderNew, 1}, + {"sun_rle_decoder", (PyCFunction)PyImaging_SunRleDecoderNew, 1}, + {"tga_rle_decoder", (PyCFunction)PyImaging_TgaRleDecoderNew, 1}, + {"xbm_decoder", (PyCFunction)PyImaging_XbmDecoderNew, 1}, + {"xbm_encoder", (PyCFunction)PyImaging_XbmEncoderNew, 1}, +#ifdef HAVE_LIBZ + {"zip_decoder", (PyCFunction)PyImaging_ZipDecoderNew, 1}, + {"zip_encoder", (PyCFunction)PyImaging_ZipEncoderNew, 1}, +#endif + + /* Memory mapping */ +#ifdef WITH_MAPPING +#ifdef WIN32 + {"map", (PyCFunction)PyImaging_Mapper, 1}, +#endif + {"map_buffer", (PyCFunction)PyImaging_MapBuffer, 1}, +#endif + + /* Display support */ +#ifdef WIN32 + {"display", (PyCFunction)PyImaging_DisplayWin32, 1}, + {"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, 1}, + {"grabscreen", (PyCFunction)PyImaging_GrabScreenWin32, 1}, + {"grabclipboard", (PyCFunction)PyImaging_GrabClipboardWin32, 1}, + {"createwindow", (PyCFunction)PyImaging_CreateWindowWin32, 1}, + {"eventloop", (PyCFunction)PyImaging_EventLoopWin32, 1}, + {"listwindows", (PyCFunction)PyImaging_ListWindowsWin32, 1}, + {"drawwmf", (PyCFunction)PyImaging_DrawWmf, 1}, +#endif + + /* Utilities */ + {"crc32", (PyCFunction)_crc32, 1}, + {"getcodecstatus", (PyCFunction)_getcodecstatus, 1}, + + /* Debugging stuff */ + {"open_ppm", (PyCFunction)_open_ppm, 1}, + + /* Special effects (experimental) */ +#ifdef WITH_EFFECTS + {"effect_mandelbrot", (PyCFunction)_effect_mandelbrot, 1}, + {"effect_noise", (PyCFunction)_effect_noise, 1}, + {"linear_gradient", (PyCFunction)_linear_gradient, 1}, + {"radial_gradient", (PyCFunction)_radial_gradient, 1}, + {"wedge", (PyCFunction)_linear_gradient, 1}, /* Compatibility */ +#endif + + /* Drawing support stuff */ +#ifdef WITH_IMAGEDRAW + {"font", (PyCFunction)_font_new, 1}, + {"draw", (PyCFunction)_draw_new, 1}, +#endif + + /* Experimental path stuff */ +#ifdef WITH_IMAGEPATH + {"path", (PyCFunction)PyPath_Create, 1}, +#endif + + /* Experimental arrow graphics stuff */ +#ifdef WITH_ARROW + {"outline", (PyCFunction)PyOutline_Create, 1}, +#endif + + {NULL, NULL} /* sentinel */ +}; + +DL_EXPORT(void) +init_imaging(void) +{ + PyObject* m; + PyObject* d; + + /* Patch object type */ + Imaging_Type.ob_type = &PyType_Type; +#ifdef WITH_IMAGEDRAW + ImagingFont_Type.ob_type = &PyType_Type; + ImagingDraw_Type.ob_type = &PyType_Type; +#endif + PixelAccess_Type.ob_type = &PyType_Type; + + ImagingAccessInit(); + + m = Py_InitModule("_imaging", functions); + d = PyModule_GetDict(m); + +#ifdef HAVE_LIBJPEG + { + extern const char* ImagingJpegVersion(void); + PyDict_SetItemString(d, "jpeglib_version", PyString_FromString(ImagingJpegVersion())); + } +#endif + +#ifdef HAVE_LIBZ + { + extern const char* ImagingZipVersion(void); + PyDict_SetItemString(d, "zlib_version", PyString_FromString(ImagingZipVersion())); + } +#endif +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c new file mode 100755 index 00000000000..e9a3b00c596 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c @@ -0,0 +1,608 @@ +/* + * pyCMS + * a Python / PIL interface to the littleCMS ICC Color Management System + * Copyright (C) 2002-2003 Kevin Cazabon + * kevin@cazabon.com + * http://www.cazabon.com + * Adapted/reworked for PIL by Fredrik Lundh + * Copyright (c) 2009 Fredrik Lundh + * + * pyCMS home page: http://www.cazabon.com/pyCMS + * littleCMS home page: http://www.littlecms.com + * (littleCMS is Copyright (C) 1998-2001 Marti Maria) + * + * Originally released under LGPL. Graciously donated to PIL in + * March 2009, for distribution under the standard PIL license + */ + +#define COPYRIGHTINFO "\ +pyCMS\n\ +a Python / PIL interface to the littleCMS ICC Color Management System\n\ +Copyright (C) 2002-2003 Kevin Cazabon\n\ +kevin@cazabon.com\n\ +http://www.cazabon.com\n\ +" + +#include "Python.h" +#include "lcms.h" +#include "Imaging.h" + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#if LCMS_VERSION < 117 +#define LCMSBOOL BOOL +#endif + +#ifdef WIN32 +#include +#endif + +#define PYCMSVERSION "0.1.0 pil" + +/* version history */ + +/* + 0.1.0 pil integration & refactoring + 0.0.2 alpha: Minor updates, added interfaces to littleCMS features, Jan 6, 2003 + - fixed some memory holes in how transforms/profiles were created and passed back to Python + due to improper destructor setup for PyCObjects + - added buildProofTransformFromOpenProfiles() function + - eliminated some code redundancy, centralizing several common tasks with internal functions + + 0.0.1 alpha: First public release Dec 26, 2002 + +*/ + +/* known to-do list with current version: + + Verify that PILmode->littleCMStype conversion in findLCMStype is correct for all PIL modes (it probably isn't for the more obscure ones) + + Add support for creating custom RGB profiles on the fly + Add support for checking presence of a specific tag in a profile + Add support for other littleCMS features as required + +*/ + +/* + INTENT_PERCEPTUAL 0 + INTENT_RELATIVE_COLORIMETRIC 1 + INTENT_SATURATION 2 + INTENT_ABSOLUTE_COLORIMETRIC 3 +*/ + +/* -------------------------------------------------------------------- */ +/* wrapper classes */ + +/* a profile represents the ICC characteristics for a specific device */ + +typedef struct { + PyObject_HEAD + cmsHPROFILE profile; +} CmsProfileObject; + +staticforward PyTypeObject CmsProfile_Type; + +#define CmsProfile_Check(op) ((op)->ob_type == &CmsProfile_Type) + +static PyObject* +cms_profile_new(cmsHPROFILE profile) +{ + CmsProfileObject* self; + + self = PyObject_New(CmsProfileObject, &CmsProfile_Type); + if (!self) + return NULL; + + self->profile = profile; + + return (PyObject*) self; +} + +static PyObject* +cms_profile_open(PyObject* self, PyObject* args) +{ + cmsHPROFILE hProfile; + + char* sProfile; + if (!PyArg_ParseTuple(args, "s:profile_open", &sProfile)) + return NULL; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + hProfile = cmsOpenProfileFromFile(sProfile, "r"); + if (!hProfile) { + PyErr_SetString(PyExc_IOError, "cannot open profile file"); + return NULL; + } + + return cms_profile_new(hProfile); +} + +static PyObject* +cms_profile_fromstring(PyObject* self, PyObject* args) +{ + cmsHPROFILE hProfile; + + char* pProfile; + int nProfile; + if (!PyArg_ParseTuple(args, "s#:profile_fromstring", &pProfile, &nProfile)) + return NULL; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + hProfile = cmsOpenProfileFromMem(pProfile, nProfile); + if (!hProfile) + PyErr_SetString(PyExc_IOError, "cannot open profile from string"); + + return cms_profile_new(hProfile); +} + +static void +cms_profile_dealloc(CmsProfileObject* self) +{ + (void) cmsCloseProfile(self->profile); + PyObject_Del(self); +} + +/* a transform represents the mapping between two profiles */ + +typedef struct { + PyObject_HEAD + char mode_in[8]; + char mode_out[8]; + cmsHTRANSFORM transform; +} CmsTransformObject; + +staticforward PyTypeObject CmsTransform_Type; + +#define CmsTransform_Check(op) ((op)->ob_type == &CmsTransform_Type) + +static PyObject* +cms_transform_new(cmsHTRANSFORM transform, char* mode_in, char* mode_out) +{ + CmsTransformObject* self; + + self = PyObject_New(CmsTransformObject, &CmsTransform_Type); + if (!self) + return NULL; + + self->transform = transform; + + strcpy(self->mode_in, mode_in); + strcpy(self->mode_out, mode_out); + + return (PyObject*) self; +} + +static void +cms_transform_dealloc(CmsTransformObject* self) +{ + cmsDeleteTransform(self->transform); + PyObject_Del(self); +} + +/* -------------------------------------------------------------------- */ +/* internal functions */ + +static const char* +findICmode(icColorSpaceSignature cs) +{ + switch (cs) { + case icSigXYZData: return "XYZ"; + case icSigLabData: return "LAB"; + case icSigLuvData: return "LUV"; + case icSigYCbCrData: return "YCbCr"; + case icSigYxyData: return "YXY"; + case icSigRgbData: return "RGB"; + case icSigGrayData: return "L"; + case icSigHsvData: return "HSV"; + case icSigHlsData: return "HLS"; + case icSigCmykData: return "CMYK"; + case icSigCmyData: return "CMY"; + default: return ""; /* other TBA */ + } +} + +static DWORD +findLCMStype(char* PILmode) +{ + if (strcmp(PILmode, "RGB") == 0) { + return TYPE_RGBA_8; + } + else if (strcmp(PILmode, "RGBA") == 0) { + return TYPE_RGBA_8; + } + else if (strcmp(PILmode, "RGBX") == 0) { + return TYPE_RGBA_8; + } + else if (strcmp(PILmode, "RGBA;16B") == 0) { + return TYPE_RGBA_16; + } + else if (strcmp(PILmode, "CMYK") == 0) { + return TYPE_CMYK_8; + } + else if (strcmp(PILmode, "L") == 0) { + return TYPE_GRAY_8; + } + else if (strcmp(PILmode, "L;16") == 0) { + return TYPE_GRAY_16; + } + else if (strcmp(PILmode, "L;16B") == 0) { + return TYPE_GRAY_16_SE; + } + else if (strcmp(PILmode, "YCCA") == 0) { + return TYPE_YCbCr_8; + } + else if (strcmp(PILmode, "YCC") == 0) { + return TYPE_YCbCr_8; + } + + else { + /* take a wild guess... but you probably should fail instead. */ + return TYPE_GRAY_8; /* so there's no buffer overrun... */ + } +} + +static int +pyCMSdoTransform(Imaging im, Imaging imOut, cmsHTRANSFORM hTransform) +{ + int i; + + if (im->xsize > imOut->xsize || im->ysize > imOut->ysize) + return -1; + + Py_BEGIN_ALLOW_THREADS + + for (i = 0; i < im->ysize; i++) + cmsDoTransform(hTransform, im->image[i], imOut->image[i], im->xsize); + + Py_END_ALLOW_THREADS + + return 0; +} + +static cmsHTRANSFORM +_buildTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, char *sInMode, char *sOutMode, int iRenderingIntent, DWORD cmsFLAGS) +{ + cmsHTRANSFORM hTransform; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + Py_BEGIN_ALLOW_THREADS + + /* create the transform */ + hTransform = cmsCreateTransform(hInputProfile, + findLCMStype(sInMode), + hOutputProfile, + findLCMStype(sOutMode), + iRenderingIntent, cmsFLAGS); + + Py_END_ALLOW_THREADS + + if (!hTransform) + PyErr_SetString(PyExc_ValueError, "cannot build transform"); + + return hTransform; /* if NULL, an exception is set */ +} + +static cmsHTRANSFORM +_buildProofTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, cmsHPROFILE hProofProfile, char *sInMode, char *sOutMode, int iRenderingIntent, int iProofIntent, DWORD cmsFLAGS) +{ + cmsHTRANSFORM hTransform; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + Py_BEGIN_ALLOW_THREADS + + /* create the transform */ + hTransform = cmsCreateProofingTransform(hInputProfile, + findLCMStype(sInMode), + hOutputProfile, + findLCMStype(sOutMode), + hProofProfile, + iRenderingIntent, + iProofIntent, + cmsFLAGS); + + Py_END_ALLOW_THREADS + + if (!hTransform) + PyErr_SetString(PyExc_ValueError, "cannot build proof transform"); + + return hTransform; /* if NULL, an exception is set */ +} + +/* -------------------------------------------------------------------- */ +/* Python callable functions */ + +static PyObject * +buildTransform(PyObject *self, PyObject *args) { + CmsProfileObject *pInputProfile; + CmsProfileObject *pOutputProfile; + char *sInMode; + char *sOutMode; + int iRenderingIntent = 0; + int cmsFLAGS = 0; + + cmsHTRANSFORM transform = NULL; + + if (!PyArg_ParseTuple(args, "O!O!ss|ii:buildTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &sInMode, &sOutMode, &iRenderingIntent, &cmsFLAGS)) + return NULL; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + transform = _buildTransform(pInputProfile->profile, pOutputProfile->profile, sInMode, sOutMode, iRenderingIntent, cmsFLAGS); + + if (!transform) + return NULL; + + return cms_transform_new(transform, sInMode, sOutMode); +} + +static PyObject * +buildProofTransform(PyObject *self, PyObject *args) +{ + CmsProfileObject *pInputProfile; + CmsProfileObject *pOutputProfile; + CmsProfileObject *pProofProfile; + char *sInMode; + char *sOutMode; + int iRenderingIntent = 0; + int iProofIntent = 0; + int cmsFLAGS = 0; + + cmsHTRANSFORM transform = NULL; + + if (!PyArg_ParseTuple(args, "O!O!O!ss|iii:buildProofTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &CmsProfile_Type, &pProofProfile, &sInMode, &sOutMode, &iRenderingIntent, &iProofIntent, &cmsFLAGS)) + return NULL; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + transform = _buildProofTransform(pInputProfile->profile, pOutputProfile->profile, pProofProfile->profile, sInMode, sOutMode, iRenderingIntent, iProofIntent, cmsFLAGS); + + if (!transform) + return NULL; + + return cms_transform_new(transform, sInMode, sOutMode); + +} + +static PyObject * +cms_transform_apply(CmsTransformObject *self, PyObject *args) +{ + long idIn; + long idOut; + Imaging im; + Imaging imOut; + + int result; + + if (!PyArg_ParseTuple(args, "ll:apply", &idIn, &idOut)) + return NULL; + + im = (Imaging) idIn; + imOut = (Imaging) idOut; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + result = pyCMSdoTransform(im, imOut, self->transform); + + return Py_BuildValue("i", result); +} + +/* -------------------------------------------------------------------- */ +/* Python-Callable On-The-Fly profile creation functions */ + +static PyObject * +createProfile(PyObject *self, PyObject *args) +{ + char *sColorSpace; + cmsHPROFILE hProfile; + int iColorTemp = 0; + LPcmsCIExyY whitePoint = NULL; + LCMSBOOL result; + + if (!PyArg_ParseTuple(args, "s|i:createProfile", &sColorSpace, &iColorTemp)) + return NULL; + + cmsErrorAction(LCMS_ERROR_IGNORE); + + if (strcmp(sColorSpace, "LAB") == 0) { + if (iColorTemp > 0) { + result = cmsWhitePointFromTemp(iColorTemp, whitePoint); + if (!result) { + PyErr_SetString(PyExc_ValueError, "ERROR: Could not calculate white point from color temperature provided, must be integer in degrees Kelvin"); + return NULL; + } + hProfile = cmsCreateLabProfile(whitePoint); + } else + hProfile = cmsCreateLabProfile(NULL); + } + else if (strcmp(sColorSpace, "XYZ") == 0) + hProfile = cmsCreateXYZProfile(); + else if (strcmp(sColorSpace, "sRGB") == 0) + hProfile = cmsCreate_sRGBProfile(); + else + hProfile = NULL; + + if (!hProfile) { + PyErr_SetString(PyExc_ValueError, "failed to create requested color space"); + return NULL; + } + + return cms_profile_new(hProfile); +} + +/* -------------------------------------------------------------------- */ +/* profile methods */ + +static PyObject * +cms_profile_is_intent_supported(CmsProfileObject *self, PyObject *args) +{ + LCMSBOOL result; + + int intent; + int direction; + if (!PyArg_ParseTuple(args, "ii:is_intent_supported", &intent, &direction)) + return NULL; + + result = cmsIsIntentSupported(self->profile, intent, direction); + + /* printf("cmsIsIntentSupported(%p, %d, %d) => %d\n", self->profile, intent, direction, result); */ + + return PyInt_FromLong(result != 0); +} + +#ifdef WIN32 +static PyObject * +cms_get_display_profile_win32(PyObject* self, PyObject* args) +{ + char filename[MAX_PATH]; + DWORD filename_size; + BOOL ok; + + int handle = 0; + int is_dc = 0; + if (!PyArg_ParseTuple(args, "|ii:get_display_profile", &handle, &is_dc)) + return NULL; + + filename_size = sizeof(filename); + + if (is_dc) { + ok = GetICMProfile((HDC) handle, &filename_size, filename); + } else { + HDC dc = GetDC((HWND) handle); + ok = GetICMProfile(dc, &filename_size, filename); + ReleaseDC((HWND) handle, dc); + } + + if (ok) + return PyString_FromStringAndSize(filename, filename_size-1); + + Py_INCREF(Py_None); + return Py_None; +} +#endif + +/* -------------------------------------------------------------------- */ +/* Python interface setup */ + +static PyMethodDef pyCMSdll_methods[] = { + + {"profile_open", cms_profile_open, 1}, + {"profile_fromstring", cms_profile_fromstring, 1}, + + /* profile and transform functions */ + {"buildTransform", buildTransform, 1}, + {"buildProofTransform", buildProofTransform, 1}, + {"createProfile", createProfile, 1}, + + /* platform specific tools */ +#ifdef WIN32 + {"get_display_profile_win32", cms_get_display_profile_win32, 1}, +#endif + + {NULL, NULL} +}; + +static struct PyMethodDef cms_profile_methods[] = { + {"is_intent_supported", (PyCFunction) cms_profile_is_intent_supported, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +cms_profile_getattr(CmsProfileObject* self, char* name) +{ + if (!strcmp(name, "product_name")) + return PyString_FromString(cmsTakeProductName(self->profile)); + if (!strcmp(name, "product_desc")) + return PyString_FromString(cmsTakeProductDesc(self->profile)); + if (!strcmp(name, "product_info")) + return PyString_FromString(cmsTakeProductInfo(self->profile)); + if (!strcmp(name, "rendering_intent")) + return PyInt_FromLong(cmsTakeRenderingIntent(self->profile)); + if (!strcmp(name, "pcs")) + return PyString_FromString(findICmode(cmsGetPCS(self->profile))); + if (!strcmp(name, "color_space")) + return PyString_FromString(findICmode(cmsGetColorSpace(self->profile))); + /* FIXME: add more properties (creation_datetime etc) */ + + return Py_FindMethod(cms_profile_methods, (PyObject*) self, name); +} + +statichere PyTypeObject CmsProfile_Type = { + PyObject_HEAD_INIT(NULL) + 0, "CmsProfile", sizeof(CmsProfileObject), 0, + /* methods */ + (destructor) cms_profile_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc) cms_profile_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0 /*tp_hash*/ +}; + +static struct PyMethodDef cms_transform_methods[] = { + {"apply", (PyCFunction) cms_transform_apply, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +cms_transform_getattr(CmsTransformObject* self, char* name) +{ + if (!strcmp(name, "inputMode")) + return PyString_FromString(self->mode_in); + if (!strcmp(name, "outputMode")) + return PyString_FromString(self->mode_out); + + return Py_FindMethod(cms_transform_methods, (PyObject*) self, name); +} + +statichere PyTypeObject CmsTransform_Type = { + PyObject_HEAD_INIT(NULL) + 0, "CmsTransform", sizeof(CmsTransformObject), 0, + /* methods */ + (destructor) cms_transform_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc) cms_transform_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0 /*tp_hash*/ +}; + +DL_EXPORT(void) +init_imagingcms(void) +{ + PyObject *m; + PyObject *d; + PyObject *v; + + /* Patch up object types */ + CmsProfile_Type.ob_type = &PyType_Type; + CmsTransform_Type.ob_type = &PyType_Type; + + m = Py_InitModule("_imagingcms", pyCMSdll_methods); + d = PyModule_GetDict(m); + +#if PY_VERSION_HEX >= 0x02020000 + v = PyString_FromFormat("%d.%d", LCMS_VERSION / 100, LCMS_VERSION % 100); +#else + { + char buffer[100]; + sprintf(buffer, "%d.%d", LCMS_VERSION / 100, LCMS_VERSION % 100); + v = PyString_FromString(buffer); + } +#endif + PyDict_SetItemString(d, "littlecms_version", v); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c new file mode 100755 index 00000000000..9358087180d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c @@ -0,0 +1,502 @@ +/* + * PIL FreeType Driver + * + * a FreeType 2.X driver for PIL + * + * history: + * 2001-02-17 fl Created (based on old experimental freetype 1.0 code) + * 2001-04-18 fl Fixed some egcs compiler nits + * 2002-11-08 fl Added unicode support; more font metrics, etc + * 2003-05-20 fl Fixed compilation under 1.5.2 and newer non-unicode builds + * 2003-09-27 fl Added charmap encoding support + * 2004-05-15 fl Fixed compilation for FreeType 2.1.8 + * 2004-09-10 fl Added support for monochrome bitmaps + * 2006-06-18 fl Fixed glyph bearing calculation + * 2007-12-23 fl Fixed crash in family/style attribute fetch + * 2008-01-02 fl Handle Unicode filenames properly + * + * Copyright (c) 1998-2007 by Secret Labs AB + */ + +#include "Python.h" +#include "Imaging.h" + +#if !defined(USE_FREETYPE_2_0) +/* undef/comment out to use freetype 2.0 */ +#define USE_FREETYPE_2_1 +#endif + +#if defined(USE_FREETYPE_2_1) +/* freetype 2.1 and newer */ +#include +#include FT_FREETYPE_H +#else +/* freetype 2.0 */ +#include +#endif + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#if PY_VERSION_HEX >= 0x01060000 +#if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE) +/* defining this enables unicode support (default under 1.6a1 and later) */ +#define HAVE_UNICODE +#endif +#endif + +#if !defined(Py_RETURN_NONE) +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#if !defined(FT_LOAD_TARGET_MONO) +#define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME +#endif + +/* -------------------------------------------------------------------- */ +/* error table */ + +#undef FTERRORS_H +#undef __FTERRORS_H__ + +#define FT_ERRORDEF( e, v, s ) { e, s }, +#define FT_ERROR_START_LIST { +#define FT_ERROR_END_LIST { 0, 0 } }; + +struct { + int code; + const char* message; +} ft_errors[] = + +#include + +/* -------------------------------------------------------------------- */ +/* font objects */ + +static FT_Library library; + +typedef struct { + PyObject_HEAD + FT_Face face; +} FontObject; + +staticforward PyTypeObject Font_Type; + +/* round a 26.6 pixel coordinate to the nearest larger integer */ +#define PIXEL(x) ((((x)+63) & -64)>>6) + +static PyObject* +geterror(int code) +{ + int i; + + for (i = 0; ft_errors[i].message; i++) + if (ft_errors[i].code == code) { + PyErr_SetString(PyExc_IOError, ft_errors[i].message); + return NULL; + } + + PyErr_SetString(PyExc_IOError, "unknown freetype error"); + return NULL; +} + +static PyObject* +getfont(PyObject* self_, PyObject* args, PyObject* kw) +{ + /* create a font object from a file name and a size (in pixels) */ + + FontObject* self; + int error; + + char* filename; + int size; + int index = 0; + unsigned char* encoding = NULL; + static char* kwlist[] = { + "filename", "size", "index", "encoding", NULL + }; + +#if defined(HAVE_UNICODE) && PY_VERSION_HEX >= 0x02020000 + if (!PyArg_ParseTupleAndKeywords(args, kw, "eti|is", kwlist, + Py_FileSystemDefaultEncoding, &filename, + &size, &index, &encoding)) + return NULL; +#else + if (!PyArg_ParseTupleAndKeywords(args, kw, "si|is", kwlist, + &filename, &size, &index, &encoding)) + return NULL; +#endif + + if (!library) { + PyErr_SetString( + PyExc_IOError, + "failed to initialize FreeType library" + ); + return NULL; + } + + self = PyObject_New(FontObject, &Font_Type); + if (!self) + return NULL; + + error = FT_New_Face(library, filename, index, &self->face); + + if (!error) + error = FT_Set_Pixel_Sizes(self->face, 0, size); + + if (!error && encoding && strlen((char*) encoding) == 4) { + FT_Encoding encoding_tag = FT_MAKE_TAG( + encoding[0], encoding[1], encoding[2], encoding[3] + ); + error = FT_Select_Charmap(self->face, encoding_tag); + } + + if (error) { + PyObject_Del(self); + return geterror(error); + } + + return (PyObject*) self; +} + +static int +font_getchar(PyObject* string, int index, FT_ULong* char_out) +{ +#if defined(HAVE_UNICODE) + if (PyUnicode_Check(string)) { + Py_UNICODE* p = PyUnicode_AS_UNICODE(string); + int size = PyUnicode_GET_SIZE(string); + if (index >= size) + return 0; + *char_out = p[index]; + return 1; + } +#endif + if (PyString_Check(string)) { + unsigned char* p = (unsigned char*) PyString_AS_STRING(string); + int size = PyString_GET_SIZE(string); + if (index >= size) + return 0; + *char_out = (unsigned char) p[index]; + return 1; + } + return 0; +} + +static PyObject* +font_getsize(FontObject* self, PyObject* args) +{ + int i, x; + FT_ULong ch; + FT_Face face; + int xoffset; + FT_Bool kerning = FT_HAS_KERNING(self->face); + FT_UInt last_index = 0; + + /* calculate size and bearing for a given string */ + + PyObject* string; + if (!PyArg_ParseTuple(args, "O:getsize", &string)) + return NULL; + +#if defined(HAVE_UNICODE) + if (!PyUnicode_Check(string) && !PyString_Check(string)) { +#else + if (!PyString_Check(string)) { +#endif + PyErr_SetString(PyExc_TypeError, "expected string"); + return NULL; + } + + face = NULL; + xoffset = 0; + + for (x = i = 0; font_getchar(string, i, &ch); i++) { + int index, error; + face = self->face; + index = FT_Get_Char_Index(face, ch); + if (kerning && last_index && index) { + FT_Vector delta; + FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, + &delta); + x += delta.x; + } + error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT); + if (error) + return geterror(error); + if (i == 0) + xoffset = face->glyph->metrics.horiBearingX; + x += face->glyph->metrics.horiAdvance; + last_index = index; + } + + if (face) { + int offset; + /* left bearing */ + if (xoffset < 0) + x -= xoffset; + else + xoffset = 0; + /* right bearing */ + offset = face->glyph->metrics.horiAdvance - + face->glyph->metrics.width - + face->glyph->metrics.horiBearingX; + if (offset < 0) + x -= offset; + } + + return Py_BuildValue( + "(ii)(ii)", + PIXEL(x), PIXEL(self->face->size->metrics.height), + PIXEL(xoffset), 0 + ); +} + +static PyObject* +font_getabc(FontObject* self, PyObject* args) +{ + FT_ULong ch; + FT_Face face; + double a, b, c; + + /* calculate ABC values for a given string */ + + PyObject* string; + if (!PyArg_ParseTuple(args, "O:getabc", &string)) + return NULL; + +#if defined(HAVE_UNICODE) + if (!PyUnicode_Check(string) && !PyString_Check(string)) { +#else + if (!PyString_Check(string)) { +#endif + PyErr_SetString(PyExc_TypeError, "expected string"); + return NULL; + } + + if (font_getchar(string, 0, &ch)) { + int index, error; + face = self->face; + index = FT_Get_Char_Index(face, ch); + error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT); + if (error) + return geterror(error); + a = face->glyph->metrics.horiBearingX / 64.0; + b = face->glyph->metrics.width / 64.0; + c = (face->glyph->metrics.horiAdvance - + face->glyph->metrics.horiBearingX - + face->glyph->metrics.width) / 64.0; + } else + a = b = c = 0.0; + + return Py_BuildValue("ddd", a, b, c); +} + +static PyObject* +font_render(FontObject* self, PyObject* args) +{ + int i, x, y; + Imaging im; + int index, error, ascender; + int load_flags; + unsigned char *source; + FT_ULong ch; + FT_GlyphSlot glyph; + FT_Bool kerning = FT_HAS_KERNING(self->face); + FT_UInt last_index = 0; + + /* render string into given buffer (the buffer *must* have + the right size, or this will crash) */ + PyObject* string; + long id; + int mask = 0; + if (!PyArg_ParseTuple(args, "Ol|i:render", &string, &id, &mask)) + return NULL; + +#if defined(HAVE_UNICODE) + if (!PyUnicode_Check(string) && !PyString_Check(string)) { +#else + if (!PyString_Check(string)) { +#endif + PyErr_SetString(PyExc_TypeError, "expected string"); + return NULL; + } + + im = (Imaging) id; + + load_flags = FT_LOAD_RENDER; + if (mask) + load_flags |= FT_LOAD_TARGET_MONO; + + for (x = i = 0; font_getchar(string, i, &ch); i++) { + if (i == 0 && self->face->glyph->metrics.horiBearingX < 0) + x = -PIXEL(self->face->glyph->metrics.horiBearingX); + index = FT_Get_Char_Index(self->face, ch); + if (kerning && last_index && index) { + FT_Vector delta; + FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, + &delta); + x += delta.x >> 6; + } + error = FT_Load_Glyph(self->face, index, load_flags); + if (error) + return geterror(error); + glyph = self->face->glyph; + if (mask) { + /* use monochrome mask (on palette images, etc) */ + int xx, x0, x1; + source = (unsigned char*) glyph->bitmap.buffer; + ascender = PIXEL(self->face->size->metrics.ascender); + xx = x + glyph->bitmap_left; + x0 = 0; + x1 = glyph->bitmap.width; + if (xx < 0) + x0 = -xx; + if (xx + x1 > im->xsize) + x1 = im->xsize - xx; + for (y = 0; y < glyph->bitmap.rows; y++) { + int yy = y + ascender - glyph->bitmap_top; + if (yy >= 0 && yy < im->ysize) { + /* blend this glyph into the buffer */ + unsigned char *target = im->image8[yy] + xx; + int i, j, m = 128; + for (i = j = 0; j < x1; j++) { + if (j >= x0 && (source[i] & m)) + target[j] = 255; + if (!(m >>= 1)) { + m = 128; + i++; + } + } + } + source += glyph->bitmap.pitch; + } + } else { + /* use antialiased rendering */ + int xx, x0, x1; + source = (unsigned char*) glyph->bitmap.buffer; + ascender = PIXEL(self->face->size->metrics.ascender); + xx = x + glyph->bitmap_left; + x0 = 0; + x1 = glyph->bitmap.width; + if (xx < 0) + x0 = -xx; + if (xx + x1 > im->xsize) + x1 = im->xsize - xx; + for (y = 0; y < glyph->bitmap.rows; y++) { + int yy = y + ascender - glyph->bitmap_top; + if (yy >= 0 && yy < im->ysize) { + /* blend this glyph into the buffer */ + int i; + unsigned char *target = im->image8[yy] + xx; + for (i = x0; i < x1; i++) { + if (target[i] < source[i]) + target[i] = source[i]; + } + } + source += glyph->bitmap.pitch; + } + } + x += PIXEL(glyph->metrics.horiAdvance); + last_index = index; + } + + Py_RETURN_NONE; +} + +static void +font_dealloc(FontObject* self) +{ + FT_Done_Face(self->face); + PyObject_Del(self); +} + +static PyMethodDef font_methods[] = { + {"render", (PyCFunction) font_render, METH_VARARGS}, + {"getsize", (PyCFunction) font_getsize, METH_VARARGS}, + {"getabc", (PyCFunction) font_getabc, METH_VARARGS}, + {NULL, NULL} +}; + +static PyObject* +font_getattr(FontObject* self, char* name) +{ + PyObject* res; + + res = Py_FindMethod(font_methods, (PyObject*) self, name); + + if (res) + return res; + + PyErr_Clear(); + + /* attributes */ + if (!strcmp(name, "family")) { + if (self->face->family_name) + return PyString_FromString(self->face->family_name); + Py_RETURN_NONE; + } + if (!strcmp(name, "style")) { + if (self->face->style_name) + return PyString_FromString(self->face->style_name); + Py_RETURN_NONE; + } + if (!strcmp(name, "ascent")) + return PyInt_FromLong(PIXEL(self->face->size->metrics.ascender)); + if (!strcmp(name, "descent")) + return PyInt_FromLong(-PIXEL(self->face->size->metrics.descender)); + + if (!strcmp(name, "glyphs")) + /* number of glyphs provided by this font */ + return PyInt_FromLong(self->face->num_glyphs); + + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +statichere PyTypeObject Font_Type = { + PyObject_HEAD_INIT(NULL) + 0, "Font", sizeof(FontObject), 0, + /* methods */ + (destructor)font_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + (getattrfunc)font_getattr, /* tp_getattr */ +}; + +static PyMethodDef _functions[] = { + {"getfont", (PyCFunction) getfont, METH_VARARGS|METH_KEYWORDS}, + {NULL, NULL} +}; + +DL_EXPORT(void) +init_imagingft(void) +{ + PyObject* m; + PyObject* d; + PyObject* v; + int major, minor, patch; + + /* Patch object type */ + Font_Type.ob_type = &PyType_Type; + + m = Py_InitModule("_imagingft", _functions); + d = PyModule_GetDict(m); + + if (FT_Init_FreeType(&library)) + return; /* leave it uninitalized */ + + FT_Library_Version(library, &major, &minor, &patch); + +#if PY_VERSION_HEX >= 0x02020000 + v = PyString_FromFormat("%d.%d.%d", major, minor, patch); +#else + { + char buffer[100]; + sprintf(buffer, "%d.%d.%d", major, minor, patch); + v = PyString_FromString(buffer); + } +#endif + PyDict_SetItemString(d, "freetype2_version", v); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c new file mode 100755 index 00000000000..928986bb323 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c @@ -0,0 +1,284 @@ +/* + * The Python Imaging Library + * + * a simple math add-on for the Python Imaging Library + * + * history: + * 1999-02-15 fl Created + * 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 + * + * Copyright (c) 1999-2005 by Secret Labs AB + * Copyright (c) 2005 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + +#include "Python.h" + +#include "Imaging.h" + +#include "math.h" +#include "float.h" + +#define MAX_INT32 2147483647.0 +#define MIN_INT32 -2147483648.0 + +#if defined(_MSC_VER) && _MSC_VER < 1500 +/* python 2.1/2.2/2.3 = VC98 = VER 1200 */ +/* python 2.4/2.5 = VS.NET 2003 = VER 1310 */ +/* python 2.6 = VS 9.0 = VER 1500 */ +#define powf(a, b) ((float) pow((double) (a), (double) (b))) +#endif + +#define UNOP(name, op, type)\ +void name(Imaging out, Imaging im1)\ +{\ + int x, y;\ + for (y = 0; y < out->ysize; y++) {\ + type* p0 = (type*) out->image[y];\ + type* p1 = (type*) im1->image[y];\ + for (x = 0; x < out->xsize; x++) {\ + *p0 = op(type, *p1);\ + p0++; p1++;\ + }\ + }\ +} + +#define BINOP(name, op, type)\ +void name(Imaging out, Imaging im1, Imaging im2)\ +{\ + int x, y;\ + for (y = 0; y < out->ysize; y++) {\ + type* p0 = (type*) out->image[y];\ + type* p1 = (type*) im1->image[y];\ + type* p2 = (type*) im2->image[y];\ + for (x = 0; x < out->xsize; x++) {\ + *p0 = op(type, *p1, *p2);\ + p0++; p1++; p2++;\ + }\ + }\ +} + +#define NEG(type, v1) -(v1) +#define INVERT(type, v1) ~(v1) + +#define ADD(type, v1, v2) (v1)+(v2) +#define SUB(type, v1, v2) (v1)-(v2) +#define MUL(type, v1, v2) (v1)*(v2) + +#define MIN(type, v1, v2) ((v1)<(v2))?(v1):(v2) +#define MAX(type, v1, v2) ((v1)>(v2))?(v1):(v2) + +#define AND(type, v1, v2) (v1)&(v2) +#define OR(type, v1, v2) (v1)|(v2) +#define XOR(type, v1, v2) (v1)^(v2) +#define LSHIFT(type, v1, v2) (v1)<<(v2) +#define RSHIFT(type, v1, v2) (v1)>>(v2) + +#define ABS_I(type, v1) abs((v1)) +#define ABS_F(type, v1) fabs((v1)) + +/* -------------------------------------------------------------------- + * some day, we should add FPE protection mechanisms. see pyfpe.h for + * details. + * + * PyFPE_START_PROTECT("Error in foobar", return 0) + * PyFPE_END_PROTECT(result) + */ + +#define DIV_I(type, v1, v2) ((v2)!=0)?(v1)/(v2):0 +#define DIV_F(type, v1, v2) ((v2)!=0.0F)?(v1)/(v2):0.0F + +#define MOD_I(type, v1, v2) ((v2)!=0)?(v1)%(v2):0 +#define MOD_F(type, v1, v2) ((v2)!=0.0F)?fmod((v1),(v2)):0.0F + +static int powi(int x, int y) +{ + double v = pow(x, y) + 0.5; + if (errno == EDOM) + return 0; + if (v < MIN_INT32) + v = MIN_INT32; + else if (v > MAX_INT32) + v = MAX_INT32; + return (int) v; +} + +#define POW_I(type, v1, v2) powi(v1, v2) +#define POW_F(type, v1, v2) powf(v1, v2) /* FIXME: EDOM handling */ + +#define DIFF_I(type, v1, v2) abs((v1)-(v2)) +#define DIFF_F(type, v1, v2) fabs((v1)-(v2)) + +#define EQ(type, v1, v2) (v1)==(v2) +#define NE(type, v1, v2) (v1)!=(v2) +#define LT(type, v1, v2) (v1)<(v2) +#define LE(type, v1, v2) (v1)<=(v2) +#define GT(type, v1, v2) (v1)>(v2) +#define GE(type, v1, v2) (v1)>=(v2) + +UNOP(abs_I, ABS_I, INT32) +UNOP(neg_I, NEG, INT32) + +BINOP(add_I, ADD, INT32) +BINOP(sub_I, SUB, INT32) +BINOP(mul_I, MUL, INT32) +BINOP(div_I, DIV_I, INT32) +BINOP(mod_I, MOD_I, INT32) +BINOP(pow_I, POW_I, INT32) +BINOP(diff_I, DIFF_I, INT32) + +UNOP(invert_I, INVERT, INT32) +BINOP(and_I, AND, INT32) +BINOP(or_I, OR, INT32) +BINOP(xor_I, XOR, INT32) +BINOP(lshift_I, LSHIFT, INT32) +BINOP(rshift_I, RSHIFT, INT32) + +BINOP(min_I, MIN, INT32) +BINOP(max_I, MAX, INT32) + +BINOP(eq_I, EQ, INT32) +BINOP(ne_I, NE, INT32) +BINOP(lt_I, LT, INT32) +BINOP(le_I, LE, INT32) +BINOP(gt_I, GT, INT32) +BINOP(ge_I, GE, INT32) + +UNOP(abs_F, ABS_F, FLOAT32) +UNOP(neg_F, NEG, FLOAT32) + +BINOP(add_F, ADD, FLOAT32) +BINOP(sub_F, SUB, FLOAT32) +BINOP(mul_F, MUL, FLOAT32) +BINOP(div_F, DIV_F, FLOAT32) +BINOP(mod_F, MOD_F, FLOAT32) +BINOP(pow_F, POW_F, FLOAT32) +BINOP(diff_F, DIFF_F, FLOAT32) + +BINOP(min_F, MIN, FLOAT32) +BINOP(max_F, MAX, FLOAT32) + +BINOP(eq_F, EQ, FLOAT32) +BINOP(ne_F, NE, FLOAT32) +BINOP(lt_F, LT, FLOAT32) +BINOP(le_F, LE, FLOAT32) +BINOP(gt_F, GT, FLOAT32) +BINOP(ge_F, GE, FLOAT32) + +static PyObject * +_unop(PyObject* self, PyObject* args) +{ + Imaging out; + Imaging im1; + void (*unop)(Imaging, Imaging); + + long op, i0, i1; + if (!PyArg_ParseTuple(args, "lll", &op, &i0, &i1)) + return NULL; + + out = (Imaging) i0; + im1 = (Imaging) i1; + + unop = (void*) op; + + unop(out, im1); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +_binop(PyObject* self, PyObject* args) +{ + Imaging out; + Imaging im1; + Imaging im2; + void (*binop)(Imaging, Imaging, Imaging); + + long op, i0, i1, i2; + if (!PyArg_ParseTuple(args, "llll", &op, &i0, &i1, &i2)) + return NULL; + + out = (Imaging) i0; + im1 = (Imaging) i1; + im2 = (Imaging) i2; + + binop = (void*) op; + + binop(out, im1, im2); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef _functions[] = { + {"unop", _unop, 1}, + {"binop", _binop, 1}, + {NULL, NULL} +}; + +static void +install(PyObject *d, char* name, void* value) +{ + PyObject *v = PyInt_FromLong((long) value); + if (!v || PyDict_SetItemString(d, name, v)) + PyErr_Clear(); + Py_XDECREF(v); +} + +DL_EXPORT(void) +init_imagingmath(void) +{ + PyObject* m; + PyObject* d; + + m = Py_InitModule("_imagingmath", _functions); + d = PyModule_GetDict(m); + + install(d, "abs_I", abs_I); + install(d, "neg_I", neg_I); + install(d, "add_I", add_I); + install(d, "sub_I", sub_I); + install(d, "diff_I", diff_I); + install(d, "mul_I", mul_I); + install(d, "div_I", div_I); + install(d, "mod_I", mod_I); + install(d, "min_I", min_I); + install(d, "max_I", max_I); + install(d, "pow_I", pow_I); + + install(d, "invert_I", invert_I); + install(d, "and_I", and_I); + install(d, "or_I", or_I); + install(d, "xor_I", xor_I); + install(d, "lshift_I", lshift_I); + install(d, "rshift_I", rshift_I); + + install(d, "eq_I", eq_I); + install(d, "ne_I", ne_I); + install(d, "lt_I", lt_I); + install(d, "le_I", le_I); + install(d, "gt_I", gt_I); + install(d, "ge_I", ge_I); + + install(d, "abs_F", abs_F); + install(d, "neg_F", neg_F); + install(d, "add_F", add_F); + install(d, "sub_F", sub_F); + install(d, "diff_F", diff_F); + install(d, "mul_F", mul_F); + install(d, "div_F", div_F); + install(d, "mod_F", mod_F); + install(d, "min_F", min_F); + install(d, "max_F", max_F); + install(d, "pow_F", pow_F); + + install(d, "eq_F", eq_F); + install(d, "ne_F", ne_F); + install(d, "lt_F", lt_F); + install(d, "le_F", le_F); + install(d, "gt_F", gt_F); + install(d, "ge_F", ge_F); + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c new file mode 100755 index 00000000000..6165a2acb93 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c @@ -0,0 +1,70 @@ +/* + * The Python Imaging Library. + * + * tkinter hooks + * + * history: + * 99-07-26 fl created + * 99-08-15 fl moved to its own support module + * + * Copyright (c) Secret Labs AB 1999. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Python.h" +#include "Imaging.h" + +#include "tk.h" + +/* must link with Tk/tkImaging.c */ +extern void TkImaging_Init(Tcl_Interp* interp); + +/* copied from _tkinter.c (this isn't as bad as it may seem: for new + versions, we use _tkinter's interpaddr hook instead, and all older + versions use this structure layout) */ + +typedef struct { + PyObject_HEAD + Tcl_Interp* interp; +} TkappObject; + +static PyObject* +_tkinit(PyObject* self, PyObject* args) +{ + Tcl_Interp* interp; + + long arg; + int is_interp; + if (!PyArg_ParseTuple(args, "li", &arg, &is_interp)) + return NULL; + + if (is_interp) + interp = (Tcl_Interp*) arg; + else { + TkappObject* app; + /* Do it the hard way. This will break if the TkappObject + layout changes */ + app = (TkappObject*) arg; + interp = app->interp; + } + + /* This will bomb if interp is invalid... */ + TkImaging_Init(interp); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef functions[] = { + /* Tkinter interface stuff */ + {"tkinit", (PyCFunction)_tkinit, 1}, + {NULL, NULL} /* sentinel */ +}; + +DL_EXPORT(void) +init_imagingtk(void) +{ + Py_InitModule("_imagingtk", functions); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.exp b/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.exp new file mode 100755 index 0000000000000000000000000000000000000000..7247036d7846cba448752fb860a08262cea605b2 GIT binary patch literal 670 zcmY*XO;5r=5S@aGF&@Bp^w0wbh_We|h%p+8Uy+DtAmOwLS=hC1EZwGEp!y%YdGk;B z!@PJm(b+adnRMQ~d719)&ThxbL8JE8`?dhqAu)>x&NNFCgB^5^{$UcdHS`vKgp1MC zE%%LPtcYuTrgVWVD4v5Z6llFusSR`oHm54Zi zT{tck@DI~7wG9kvX2Go-hbmGJ+OG7fcBkFFfmb*w!FbN$;)rT@7-^=Z@~KwJi|Dn~ zBNbo90rR;CseY6p9|kPc&$OMMyH+Q4(gYC;I6tEIp>jhuv9F{jBD)eF9#rXH&w-4l z%(MG?%B8aF4sqzz@OC0Da|`1vs>`+xJMJ`d4L zmrZbm24<-ey1@(+FcZ#{w8~66Q|5OeJ{f1Bl)DaE9ZnYtlH^8AG?s%c#N{3S0vo-5 AWB>pF literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.lib b/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.lib new file mode 100755 index 0000000000000000000000000000000000000000..c6fe61113dae7ec20238a1c100fb1862481fca66 GIT binary patch literal 1736 zcmcIl%}(1u5dLfzNG*h-(i@^O5>nwnN{r1^Mm>ZHwlQ#Ge96><}{TjlswC#ES zYT!gvS_;9Z?b2GfvJ@=Qk*MCFVLxh$4m!Cc%hqdJoYVJL2`Eh{VERny%_=d5ctQ3=kJ$pOGo9vPykr)GQa=vr zErzoLB;*U37*Fx>tM#aI5Ff^0o7RLsX?excTC#g<7$lw#@&%v@@hVFrS8agM(Lx)W zAulR%y+Q8A$3Jm(B?kEn6Z@w_qAmc5$9p14;$usONF3H70opq5jfCZ6JSgJZf%l5z zNk>5A)9}e@Hn!cSU7-3Oym|AF z__s{F>uj4M#!2Vxo0r+n?Cf4yIjC3O`h^_88YE^B!I@@hVDKKDqkotHZ56$ZAK_v+ zaY}baGqz;`e5G`bZP++5fvJ&+m+Bdq(S?_6)X~T zu`&^H0K0Hh%;PRoH??(K)YO7&ISN&z9<^QW@7Pz}-X*-kaS=u{4yP@uok66TmddAE zDL0}QQV&&p76;7dBBXjOLp}&tsGn&!ok68WYNP=o7SL(Y+fX?n^Xzl!ipVa<&BGn~ zTk}Ci6Xx1?dcvi$YgJOE4;^~a?NL|yPuRM^TY_fMOn>lirtOi!<4dll@9_O?PPh0H z%$_BPUV6;Kztk~GmCy;M7=W2{rleVB;+ZnL3GoS4=SrzpMXNz)t{_Qn#;nG2u!;D; F%O5MChW`Kn literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.lib b/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.lib new file mode 100755 index 0000000000000000000000000000000000000000..725d4c008867b596b0bb6209e3b04d6e2073a741 GIT binary patch literal 1882 zcmcIl!EVz)5Pfz+TPzM%LG7uMfg<2Q(ztfW0aY#(L{!(U-1LUznxsv9NF9~55-08z zM~-{}AA$M}960a+{f#oS@y2cvnxraYd3WdScz0&@&HCZ1@VMSu(~8DbDXms)%QDNQ zm8-Z^OSY9v>}vq-0ICk;JsO??GZ*{@L3L|q+ph&1Z+GAL)t%b59|Tc5Y(_`TcGztp z2)sSl9k#-ktXa>f_I}UX3^vwl>-1UF?oe|Sb+dLDMy8IcTG@+hv)MsXm>u_yOZp6I@oO<$q&xdE*x4>&Ozx0+o_dEhEJm@mHh z3konNas{Q(IQV$dT;A=ez&jdzl}ge(&|ep#M%WFPO*!>|2EXVfA_>V+>tN+Pu`4Gq z=4p_p{iGe^4vcd;I4t5WtI!9-e2V+}EKTsDEX?5ebbc$UAIG2K!>;kne{Q%{Z&S<; zH1|m74|xIFTa1YMf)}&I!Ia-3qj2hRyF+frr{8gTDL3WsSlCY$GI|FPp0^|-;^f_O z60z8Z0Q7C_6k+@cH;M4-z*?elr{V*(H)rh_E>6iF)3*Ed<|?XS&rjhc`#PFE4KbBA z8TPD7l-ct`DoM}m`G2gKstate, 0, sizeof(decoder->state)); + + /* Allocate decoder context */ + if (contextsize > 0) { + context = (void*) calloc(1, contextsize); + if (!context) { + Py_DECREF(decoder); + (void) PyErr_NoMemory(); + return NULL; + } + } else + context = 0; + + /* Initialize decoder context */ + decoder->state.context = context; + + /* Target image */ + decoder->lock = NULL; + decoder->im = NULL; + + return decoder; +} + +static void +_dealloc(ImagingDecoderObject* decoder) +{ + free(decoder->state.buffer); + free(decoder->state.context); + Py_XDECREF(decoder->lock); + PyObject_Del(decoder); +} + +static PyObject* +_decode(ImagingDecoderObject* decoder, PyObject* args) +{ + UINT8* buffer; + int bufsize, status; + + if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize)) + return NULL; + + status = decoder->decode(decoder->im, &decoder->state, buffer, bufsize); + + return Py_BuildValue("ii", status, decoder->state.errcode); +} + +extern Imaging PyImaging_AsImaging(PyObject *op); + +static PyObject* +_setimage(ImagingDecoderObject* decoder, PyObject* args) +{ + PyObject* op; + Imaging im; + ImagingCodecState state; + int x0, y0, x1, y1; + + x0 = y0 = x1 = y1 = 0; + + /* FIXME: should publish the ImagingType descriptor */ + if (!PyArg_ParseTuple(args, "O|(iiii)", &op, &x0, &y0, &x1, &y1)) + return NULL; + im = PyImaging_AsImaging(op); + if (!im) + return NULL; + + decoder->im = im; + + state = &decoder->state; + + /* Setup decoding tile extent */ + if (x0 == 0 && x1 == 0) { + state->xsize = im->xsize; + state->ysize = im->ysize; + } else { + state->xoff = x0; + state->yoff = y0; + state->xsize = x1 - x0; + state->ysize = y1 - y0; + } + + if (state->xsize <= 0 || + state->xsize + state->xoff > (int) im->xsize || + state->ysize <= 0 || + state->ysize + state->yoff > (int) im->ysize) { + PyErr_SetString(PyExc_ValueError, "tile cannot extend outside image"); + return NULL; + } + + /* Allocate memory buffer (if bits field is set) */ + if (state->bits > 0) { + if (!state->bytes) + state->bytes = (state->bits * state->xsize+7)/8; + state->buffer = (UINT8*) malloc(state->bytes); + if (!state->buffer) + return PyErr_NoMemory(); + } + + /* Keep a reference to the image object, to make sure it doesn't + go away before we do */ + Py_INCREF(op); + Py_XDECREF(decoder->lock); + decoder->lock = op; + + Py_INCREF(Py_None); + return Py_None; +} + +static struct PyMethodDef methods[] = { + {"decode", (PyCFunction)_decode, 1}, + {"setimage", (PyCFunction)_setimage, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +_getattr(ImagingDecoderObject* self, char* name) +{ + return Py_FindMethod(methods, (PyObject*) self, name); +} + +statichere PyTypeObject ImagingDecoderType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingDecoder", /*tp_name*/ + sizeof(ImagingDecoderObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_hash*/ +}; + +/* -------------------------------------------------------------------- */ + +int +get_unpacker(ImagingDecoderObject* decoder, const char* mode, + const char* rawmode) +{ + int bits; + ImagingShuffler unpack; + + unpack = ImagingFindUnpacker(mode, rawmode, &bits); + if (!unpack) { + Py_DECREF(decoder); + PyErr_SetString(PyExc_ValueError, "unknown raw mode"); + return -1; + } + + decoder->state.shuffle = unpack; + decoder->state.bits = bits; + + return 0; +} + + +/* -------------------------------------------------------------------- */ +/* BIT (packed fields) */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_BitDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + int bits = 8; + int pad = 8; + int fill = 0; + int sign = 0; + int ystep = 1; + if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill, + &sign, &ystep)) + return NULL; + + if (strcmp(mode, "F") != 0) { + PyErr_SetString(PyExc_ValueError, "bad image mode"); + return NULL; + } + + decoder = PyImaging_DecoderNew(sizeof(BITSTATE)); + if (decoder == NULL) + return NULL; + + decoder->decode = ImagingBitDecode; + + decoder->state.ystep = ystep; + + ((BITSTATE*)decoder->state.context)->bits = bits; + ((BITSTATE*)decoder->state.context)->pad = pad; + ((BITSTATE*)decoder->state.context)->fill = fill; + ((BITSTATE*)decoder->state.context)->sign = sign; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* FLI */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_FliDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + decoder->decode = ImagingFliDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* GIF */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_GifDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + int bits = 8; + int interlace = 0; + if (!PyArg_ParseTuple(args, "s|ii", &mode, &bits, &interlace)) + return NULL; + + if (strcmp(mode, "L") != 0 && strcmp(mode, "P") != 0) { + PyErr_SetString(PyExc_ValueError, "bad image mode"); + return NULL; + } + + decoder = PyImaging_DecoderNew(sizeof(GIFDECODERSTATE)); + if (decoder == NULL) + return NULL; + + decoder->decode = ImagingGifDecode; + + ((GIFDECODERSTATE*)decoder->state.context)->bits = bits; + ((GIFDECODERSTATE*)decoder->state.context)->interlace = interlace; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* HEX */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_HexDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) + return NULL; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingHexDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* LZW */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + int filter = 0; + if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &filter)) + return NULL; + + decoder = PyImaging_DecoderNew(sizeof(LZWSTATE)); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingLzwDecode; + + ((LZWSTATE*)decoder->state.context)->filter = filter; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* MSP */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_MspDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, "1", "1") < 0) + return NULL; + + decoder->decode = ImagingMspDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* PackBits */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) + return NULL; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingPackbitsDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* PCD */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_PcdDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + /* Unpack from PhotoYCC to RGB */ + if (get_unpacker(decoder, "RGB", "YCC;P") < 0) + return NULL; + + decoder->decode = ImagingPcdDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* PCX */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_PcxDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + int stride; + if (!PyArg_ParseTuple(args, "ssi", &mode, &rawmode, &stride)) + return NULL; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->state.bytes = stride; + + decoder->decode = ImagingPcxDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* RAW */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_RawDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + int stride = 0; + int ystep = 1; + if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) + return NULL; + + decoder = PyImaging_DecoderNew(sizeof(RAWSTATE)); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingRawDecode; + + decoder->state.ystep = ystep; + + ((RAWSTATE*)decoder->state.context)->stride = stride; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* SUN RLE */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) + return NULL; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingSunRleDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* TGA RLE */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + int ystep = 1; + int depth = 8; + if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &depth)) + return NULL; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingTgaRleDecode; + + decoder->state.ystep = ystep; + decoder->state.count = depth / 8; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* XBM */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_XbmDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + decoder = PyImaging_DecoderNew(0); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, "1", "1;R") < 0) + return NULL; + + decoder->decode = ImagingXbmDecode; + + return (PyObject*) decoder; +} + + +/* -------------------------------------------------------------------- */ +/* ZIP */ +/* -------------------------------------------------------------------- */ + +#ifdef HAVE_LIBZ + +#include "Zip.h" + +PyObject* +PyImaging_ZipDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; + int interlaced = 0; + if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &interlaced)) + return NULL; + + decoder = PyImaging_DecoderNew(sizeof(ZIPSTATE)); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingZipDecode; + + ((ZIPSTATE*)decoder->state.context)->interlaced = interlaced; + + return (PyObject*) decoder; +} +#endif + + +/* -------------------------------------------------------------------- */ +/* JPEG */ +/* -------------------------------------------------------------------- */ + +#ifdef HAVE_LIBJPEG + +/* We better define this decoder last in this file, so the following + undef's won't mess things up for the Imaging library proper. */ + +#undef HAVE_PROTOTYPES +#undef HAVE_STDDEF_H +#undef HAVE_STDLIB_H +#undef UINT8 +#undef UINT16 +#undef UINT32 +#undef INT8 +#undef INT16 +#undef INT32 + +#include "Jpeg.h" + +PyObject* +PyImaging_JpegDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + + char* mode; + char* rawmode; /* what we wan't from the decoder */ + char* jpegmode; /* what's in the file */ + int scale = 1; + int draft = 0; + if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode, + &scale, &draft)) + return NULL; + + if (!jpegmode) + jpegmode = ""; + + decoder = PyImaging_DecoderNew(sizeof(JPEGSTATE)); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + decoder->decode = ImagingJpegDecode; + + strncpy(((JPEGSTATE*)decoder->state.context)->rawmode, rawmode, 8); + strncpy(((JPEGSTATE*)decoder->state.context)->jpegmode, jpegmode, 8); + + ((JPEGSTATE*)decoder->state.context)->scale = scale; + ((JPEGSTATE*)decoder->state.context)->draft = draft; + + return (PyObject*) decoder; +} +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/display.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/display.c new file mode 100755 index 00000000000..1a08fadd56e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/display.c @@ -0,0 +1,836 @@ +/* + * The Python Imaging Library. + * + * display support (and other windows-related stuff) + * + * History: + * 1996-05-13 fl Windows DIB support + * 1996-05-21 fl Added palette stuff + * 1996-05-28 fl Added display_mode stuff + * 1997-09-21 fl Added draw primitive + * 2001-09-17 fl Added ImagingGrabScreen (from _grabscreen.c) + * 2002-05-12 fl Added ImagingListWindows + * 2002-11-19 fl Added clipboard support + * 2002-11-25 fl Added GetDC/ReleaseDC helpers + * 2003-05-21 fl Added create window support (including window callback) + * 2003-09-05 fl Added fromstring/tostring methods + * 2009-03-14 fl Added WMF support (from pilwmf) + * + * Copyright (c) 1997-2003 by Secret Labs AB. + * Copyright (c) 1996-1997 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Python.h" + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#include "Imaging.h" + +/* -------------------------------------------------------------------- */ +/* Windows DIB support */ + +#ifdef WIN32 + +#include "ImDib.h" + +typedef struct { + PyObject_HEAD + ImagingDIB dib; +} ImagingDisplayObject; + +staticforward PyTypeObject ImagingDisplayType; + +static ImagingDisplayObject* +_new(const char* mode, int xsize, int ysize) +{ + ImagingDisplayObject *display; + + display = PyObject_New(ImagingDisplayObject, &ImagingDisplayType); + if (display == NULL) + return NULL; + + display->dib = ImagingNewDIB(mode, xsize, ysize); + if (!display->dib) { + Py_DECREF(display); + return NULL; + } + + return display; +} + +static void +_delete(ImagingDisplayObject* display) +{ + if (display->dib) + ImagingDeleteDIB(display->dib); + PyObject_Del(display); +} + +static PyObject* +_expose(ImagingDisplayObject* display, PyObject* args) +{ + int hdc; + if (!PyArg_ParseTuple(args, "i", &hdc)) + return NULL; + + ImagingExposeDIB(display->dib, hdc); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_draw(ImagingDisplayObject* display, PyObject* args) +{ + int hdc; + int dst[4]; + int src[4]; + if (!PyArg_ParseTuple(args, "i(iiii)(iiii)", &hdc, + dst+0, dst+1, dst+2, dst+3, + src+0, src+1, src+2, src+3)) + return NULL; + + ImagingDrawDIB(display->dib, hdc, dst, src); + + Py_INCREF(Py_None); + return Py_None; +} + +extern Imaging PyImaging_AsImaging(PyObject *op); + +static PyObject* +_paste(ImagingDisplayObject* display, PyObject* args) +{ + Imaging im; + + PyObject* op; + int xy[4]; + xy[0] = xy[1] = xy[2] = xy[3] = 0; + if (!PyArg_ParseTuple(args, "O|(iiii)", &op, xy+0, xy+1, xy+2, xy+3)) + return NULL; + im = PyImaging_AsImaging(op); + if (!im) + return NULL; + + if (xy[2] <= xy[0]) + xy[2] = xy[0] + im->xsize; + if (xy[3] <= xy[1]) + xy[3] = xy[1] + im->ysize; + + ImagingPasteDIB(display->dib, im, xy); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_query_palette(ImagingDisplayObject* display, PyObject* args) +{ + int hdc; + int status; + + if (!PyArg_ParseTuple(args, "i", &hdc)) + return NULL; + + status = ImagingQueryPaletteDIB(display->dib, hdc); + + return Py_BuildValue("i", status); +} + +static PyObject* +_getdc(ImagingDisplayObject* display, PyObject* args) +{ + int window; + HDC dc; + + if (!PyArg_ParseTuple(args, "i", &window)) + return NULL; + + dc = GetDC((HWND) window); + if (!dc) { + PyErr_SetString(PyExc_IOError, "cannot create dc"); + return NULL; + } + + return Py_BuildValue("i", (int) dc); +} + +static PyObject* +_releasedc(ImagingDisplayObject* display, PyObject* args) +{ + int window, dc; + + if (!PyArg_ParseTuple(args, "ii", &window, &dc)) + return NULL; + + ReleaseDC((HWND) window, (HDC) dc); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_fromstring(ImagingDisplayObject* display, PyObject* args) +{ + char* ptr; + int bytes; + if (!PyArg_ParseTuple(args, "s#:fromstring", &ptr, &bytes)) + return NULL; + + if (display->dib->ysize * display->dib->linesize != bytes) { + PyErr_SetString(PyExc_ValueError, "wrong size"); + return NULL; + } + + memcpy(display->dib->bits, ptr, bytes); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_tostring(ImagingDisplayObject* display, PyObject* args) +{ + if (!PyArg_ParseTuple(args, ":tostring")) + return NULL; + + return PyString_FromStringAndSize( + display->dib->bits, display->dib->ysize * display->dib->linesize + ); +} + +static struct PyMethodDef methods[] = { + {"draw", (PyCFunction)_draw, 1}, + {"expose", (PyCFunction)_expose, 1}, + {"paste", (PyCFunction)_paste, 1}, + {"query_palette", (PyCFunction)_query_palette, 1}, + {"getdc", (PyCFunction)_getdc, 1}, + {"releasedc", (PyCFunction)_releasedc, 1}, + {"fromstring", (PyCFunction)_fromstring, 1}, + {"tostring", (PyCFunction)_tostring, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +_getattr(ImagingDisplayObject* self, char* name) +{ + PyObject* res; + + res = Py_FindMethod(methods, (PyObject*) self, name); + if (res) + return res; + PyErr_Clear(); + if (!strcmp(name, "mode")) + return Py_BuildValue("s", self->dib->mode); + if (!strcmp(name, "size")) + return Py_BuildValue("ii", self->dib->xsize, self->dib->ysize); + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +statichere PyTypeObject ImagingDisplayType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingDisplay", /*tp_name*/ + sizeof(ImagingDisplayObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_delete, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_hash*/ +}; + +PyObject* +PyImaging_DisplayWin32(PyObject* self, PyObject* args) +{ + ImagingDisplayObject* display; + char *mode; + int xsize, ysize; + + if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) + return NULL; + + display = _new(mode, xsize, ysize); + if (display == NULL) + return NULL; + + return (PyObject*) display; +} + +PyObject* +PyImaging_DisplayModeWin32(PyObject* self, PyObject* args) +{ + char *mode; + int size[2]; + + mode = ImagingGetModeDIB(size); + + return Py_BuildValue("s(ii)", mode, size[0], size[1]); +} + +/* -------------------------------------------------------------------- */ +/* Windows screen grabber */ + +PyObject* +PyImaging_GrabScreenWin32(PyObject* self, PyObject* args) +{ + int width, height; + HBITMAP bitmap; + BITMAPCOREHEADER core; + HDC screen, screen_copy; + PyObject* buffer; + + /* step 1: create a memory DC large enough to hold the + entire screen */ + + screen = CreateDC("DISPLAY", NULL, NULL, NULL); + screen_copy = CreateCompatibleDC(screen); + + width = GetDeviceCaps(screen, HORZRES); + height = GetDeviceCaps(screen, VERTRES); + + bitmap = CreateCompatibleBitmap(screen, width, height); + if (!bitmap) + goto error; + + if (!SelectObject(screen_copy, bitmap)) + goto error; + + /* step 2: copy bits into memory DC bitmap */ + + if (!BitBlt(screen_copy, 0, 0, width, height, screen, 0, 0, SRCCOPY)) + goto error; + + /* step 3: extract bits from bitmap */ + + buffer = PyString_FromStringAndSize(NULL, height * ((width*3 + 3) & -4)); + if (!buffer) + return NULL; + + core.bcSize = sizeof(core); + core.bcWidth = width; + core.bcHeight = height; + core.bcPlanes = 1; + core.bcBitCount = 24; + if (!GetDIBits(screen_copy, bitmap, 0, height, PyString_AS_STRING(buffer), + (BITMAPINFO*) &core, DIB_RGB_COLORS)) + goto error; + + DeleteObject(bitmap); + DeleteDC(screen_copy); + DeleteDC(screen); + + return Py_BuildValue("(ii)N", width, height, buffer); + +error: + PyErr_SetString(PyExc_IOError, "screen grab failed"); + + DeleteDC(screen_copy); + DeleteDC(screen); + + return NULL; +} + +static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam) +{ + PyObject* window_list = (PyObject*) lParam; + PyObject* item; + PyObject* title; + RECT inner, outer; + int title_size; + int status; + + /* get window title */ + title_size = GetWindowTextLength(hwnd); + if (title_size > 0) { + title = PyString_FromStringAndSize(NULL, title_size); + if (title) + GetWindowText(hwnd, PyString_AS_STRING(title), title_size+1); + } else + title = PyString_FromString(""); + if (!title) + return 0; + + /* get bounding boxes */ + GetClientRect(hwnd, &inner); + GetWindowRect(hwnd, &outer); + + item = Py_BuildValue( + "lN(iiii)(iiii)", (long) hwnd, title, + inner.left, inner.top, inner.right, inner.bottom, + outer.left, outer.top, outer.right, outer.bottom + ); + if (!item) + return 0; + + status = PyList_Append(window_list, item); + + Py_DECREF(item); + + if (status < 0) + return 0; + + return 1; +} + +PyObject* +PyImaging_ListWindowsWin32(PyObject* self, PyObject* args) +{ + PyObject* window_list; + + window_list = PyList_New(0); + if (!window_list) + return NULL; + + EnumWindows(list_windows_callback, (LPARAM) window_list); + + if (PyErr_Occurred()) { + Py_DECREF(window_list); + return NULL; + } + + return window_list; +} + +/* -------------------------------------------------------------------- */ +/* Windows clipboard grabber */ + +PyObject* +PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args) +{ + int clip; + HANDLE handle; + int size; + void* data; + PyObject* result; + + int verbose = 0; /* debugging; will be removed in future versions */ + if (!PyArg_ParseTuple(args, "|i", &verbose)) + return NULL; + + + clip = OpenClipboard(NULL); + /* FIXME: check error status */ + + if (verbose) { + UINT format = EnumClipboardFormats(0); + char buffer[200]; + char* result; + while (format != 0) { + if (GetClipboardFormatName(format, buffer, sizeof buffer) > 0) + result = buffer; + else + switch (format) { + case CF_BITMAP: + result = "CF_BITMAP"; + break; + case CF_DIB: + result = "CF_DIB"; + break; + case CF_DIF: + result = "CF_DIF"; + break; + case CF_ENHMETAFILE: + result = "CF_ENHMETAFILE"; + break; + case CF_HDROP: + result = "CF_HDROP"; + break; + case CF_LOCALE: + result = "CF_LOCALE"; + break; + case CF_METAFILEPICT: + result = "CF_METAFILEPICT"; + break; + case CF_OEMTEXT: + result = "CF_OEMTEXT"; + break; + case CF_OWNERDISPLAY: + result = "CF_OWNERDISPLAY"; + break; + case CF_PALETTE: + result = "CF_PALETTE"; + break; + case CF_PENDATA: + result = "CF_PENDATA"; + break; + case CF_RIFF: + result = "CF_RIFF"; + break; + case CF_SYLK: + result = "CF_SYLK"; + break; + case CF_TEXT: + result = "CF_TEXT"; + break; + case CF_WAVE: + result = "CF_WAVE"; + break; + case CF_TIFF: + result = "CF_TIFF"; + break; + case CF_UNICODETEXT: + result = "CF_UNICODETEXT"; + break; + default: + sprintf(buffer, "[%d]", format); + result = buffer; + break; + } + printf("%s (%d)\n", result, format); + format = EnumClipboardFormats(format); + } + } + + handle = GetClipboardData(CF_DIB); + if (!handle) { + /* FIXME: add CF_HDROP support to allow cut-and-paste from + the explorer */ + CloseClipboard(); + Py_INCREF(Py_None); + return Py_None; + } + + size = GlobalSize(handle); + data = GlobalLock(handle); + +#if 0 + /* calculate proper size for string formats */ + if (format == CF_TEXT || format == CF_OEMTEXT) + size = strlen(data); + else if (format == CF_UNICODETEXT) + size = wcslen(data) * 2; +#endif + + result = PyString_FromStringAndSize(data, size); + + GlobalUnlock(handle); + + CloseClipboard(); + + return result; +} + +/* -------------------------------------------------------------------- */ +/* Windows class */ + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL 522 +#endif + +static int mainloop = 0; + +static void +callback_error(const char* handler) +{ + PyObject* sys_stderr; + + sys_stderr = PySys_GetObject("stderr"); + + if (sys_stderr) { + PyFile_WriteString("*** ImageWin: error in ", sys_stderr); + PyFile_WriteString((char*) handler, sys_stderr); + PyFile_WriteString(":\n", sys_stderr); + } + + PyErr_Print(); + PyErr_Clear(); +} + +static LRESULT CALLBACK +windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT ps; + PyObject* callback = NULL; + PyObject* result; + PyThreadState* threadstate; + PyThreadState* current_threadstate; + HDC dc; + RECT rect; + LRESULT status = 0; + + /* set up threadstate for messages that calls back into python */ + switch (message) { + case WM_CREATE: + mainloop++; + break; + case WM_DESTROY: + mainloop--; + /* fall through... */ + case WM_PAINT: + case WM_SIZE: + callback = (PyObject*) GetWindowLong(wnd, 0); + if (callback) { + threadstate = (PyThreadState*) + GetWindowLong(wnd, sizeof(PyObject*)); + current_threadstate = PyThreadState_Swap(NULL); + PyEval_RestoreThread(threadstate); + } else + return DefWindowProc(wnd, message, wParam, lParam); + } + + /* process message */ + switch (message) { + + case WM_PAINT: + /* redraw (part of) window. this generates a WCK-style + damage/clear/repair cascade */ + BeginPaint(wnd, &ps); + dc = GetDC(wnd); + GetWindowRect(wnd, &rect); /* in screen coordinates */ + + result = PyObject_CallFunction( + callback, "siiii", "damage", + ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right, ps.rcPaint.bottom + ); + if (result) + Py_DECREF(result); + else + callback_error("window damage callback"); + + result = PyObject_CallFunction( + callback, "siiiii", "clear", (int) dc, + 0, 0, rect.right-rect.left, rect.bottom-rect.top + ); + if (result) + Py_DECREF(result); + else + callback_error("window clear callback"); + + result = PyObject_CallFunction( + callback, "siiiii", "repair", (int) dc, + 0, 0, rect.right-rect.left, rect.bottom-rect.top + ); + if (result) + Py_DECREF(result); + else + callback_error("window repair callback"); + + ReleaseDC(wnd, dc); + EndPaint(wnd, &ps); + break; + + case WM_SIZE: + /* resize window */ + result = PyObject_CallFunction( + callback, "sii", "resize", LOWORD(lParam), HIWORD(lParam) + ); + if (result) { + InvalidateRect(wnd, NULL, 1); + Py_DECREF(result); + } else + callback_error("window resize callback"); + break; + + case WM_DESTROY: + /* destroy window */ + result = PyObject_CallFunction(callback, "s", "destroy"); + if (result) + Py_DECREF(result); + else + callback_error("window destroy callback"); + Py_DECREF(callback); + break; + + default: + status = DefWindowProc(wnd, message, wParam, lParam); + } + + if (callback) { + /* restore thread state */ + PyEval_SaveThread(); + PyThreadState_Swap(threadstate); + } + + return status; +} + +PyObject* +PyImaging_CreateWindowWin32(PyObject* self, PyObject* args) +{ + HWND wnd; + WNDCLASS windowClass; + + char* title; + PyObject* callback; + int width = 0, height = 0; + if (!PyArg_ParseTuple(args, "sO|ii", &title, &callback, &width, &height)) + return NULL; + + if (width <= 0) + width = CW_USEDEFAULT; + if (height <= 0) + height = CW_USEDEFAULT; + + /* register toplevel window class */ + windowClass.style = CS_CLASSDC; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = sizeof(PyObject*) + sizeof(PyThreadState*); + windowClass.hInstance = GetModuleHandle(NULL); + /* windowClass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); */ + windowClass.hbrBackground = NULL; + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = "pilWindow"; + windowClass.lpfnWndProc = windowCallback; + windowClass.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(1)); + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); /* CROSS? */ + + RegisterClass(&windowClass); /* FIXME: check return status */ + + wnd = CreateWindowEx( + 0, windowClass.lpszClassName, title, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, width, height, + HWND_DESKTOP, NULL, NULL, NULL + ); + + if (!wnd) { + PyErr_SetString(PyExc_IOError, "failed to create window"); + return NULL; + } + + /* register window callback */ + Py_INCREF(callback); + SetWindowLong(wnd, 0, (LONG) callback); + SetWindowLong(wnd, sizeof(callback), (LONG) PyThreadState_Get()); + + Py_BEGIN_ALLOW_THREADS + ShowWindow(wnd, SW_SHOWNORMAL); + SetForegroundWindow(wnd); /* to make sure it's visible */ + Py_END_ALLOW_THREADS + + return Py_BuildValue("l", (long) wnd); +} + +PyObject* +PyImaging_EventLoopWin32(PyObject* self, PyObject* args) +{ + MSG msg; + + Py_BEGIN_ALLOW_THREADS + while (mainloop && GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + Py_END_ALLOW_THREADS + + Py_INCREF(Py_None); + return Py_None; +} + +/* -------------------------------------------------------------------- */ +/* windows WMF renderer */ + +#define GET32(p,o) ((DWORD*)(p+o))[0] + +PyObject * +PyImaging_DrawWmf(PyObject* self, PyObject* args) +{ + HBITMAP bitmap; + HENHMETAFILE meta; + BITMAPCOREHEADER core; + HDC dc; + RECT rect; + PyObject* buffer = NULL; + char* ptr; + + char* data; + int datasize; + int width, height; + int x0, y0, x1, y1; + if (!PyArg_ParseTuple(args, "s#(ii)(iiii):_load", &data, &datasize, + &width, &height, &x0, &x1, &y0, &y1)) + return NULL; + + /* step 1: copy metafile contents into METAFILE object */ + + if (datasize > 22 && GET32(data, 0) == 0x9ac6cdd7) { + + /* placeable windows metafile (22-byte aldus header) */ + meta = SetWinMetaFileBits(datasize-22, data+22, NULL, NULL); + + } else if (datasize > 80 && GET32(data, 0) == 1 && + GET32(data, 40) == 0x464d4520) { + + /* enhanced metafile */ + meta = SetEnhMetaFileBits(datasize, data); + + } else { + + /* unknown meta format */ + meta = NULL; + + } + + if (!meta) { + PyErr_SetString(PyExc_IOError, "cannot load metafile"); + return NULL; + } + + /* step 2: create bitmap */ + + core.bcSize = sizeof(core); + core.bcWidth = width; + core.bcHeight = height; + core.bcPlanes = 1; + core.bcBitCount = 24; + + dc = CreateCompatibleDC(NULL); + + bitmap = CreateDIBSection( + dc, (BITMAPINFO*) &core, DIB_RGB_COLORS, &ptr, NULL, 0 + ); + + if (!bitmap) { + PyErr_SetString(PyExc_IOError, "cannot create bitmap"); + goto error; + } + + if (!SelectObject(dc, bitmap)) { + PyErr_SetString(PyExc_IOError, "cannot select bitmap"); + goto error; + } + + /* step 3: render metafile into bitmap */ + + rect.left = rect.top = 0; + rect.right = width; + rect.bottom = height; + + /* FIXME: make background transparent? configurable? */ + FillRect(dc, &rect, GetStockObject(WHITE_BRUSH)); + + if (!PlayEnhMetaFile(dc, meta, &rect)) { + PyErr_SetString(PyExc_IOError, "cannot render metafile"); + goto error; + } + + /* step 4: extract bits from bitmap */ + + GdiFlush(); + + buffer = PyString_FromStringAndSize(ptr, height * ((width*3 + 3) & -4)); + +error: + DeleteEnhMetaFile(meta); + + if (bitmap) + DeleteObject(bitmap); + + DeleteDC(dc); + + return buffer; +} + +#endif /* WIN32 */ diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py new file mode 100755 index 00000000000..e8140ecdfdd --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py @@ -0,0 +1,1111 @@ +# Module doctest version 0.9.6 +# Released to the public domain 16-Jan-2001, +# by Tim Peters (tim.one@home.com). + +# local modifications: +# 2001-02-13 fl: minor tweaks to make it run under both 1.5.2 and 2.0 + +# Provided as-is; use at your own risk; no warranty; no promises; enjoy! + +"""Module doctest -- a framework for running examples in docstrings. + +NORMAL USAGE + +In normal use, end each module M with: + +def _test(): + import doctest, M # replace M with your module's name + return doctest.testmod(M) # ditto + +if __name__ == "__main__": + _test() + +Then running the module as a script will cause the examples in the +docstrings to get executed and verified: + +python M.py + +This won't display anything unless an example fails, in which case the +failing example(s) and the cause(s) of the failure(s) are printed to stdout +(why not stderr? because stderr is a lame hack <0.2 wink>), and the final +line of output is "Test failed.". + +Run it with the -v switch instead: + +python M.py -v + +and a detailed report of all examples tried is printed to stdout, along +with assorted summaries at the end. + +You can force verbose mode by passing "verbose=1" to testmod, or prohibit +it by passing "verbose=0". In either of those cases, sys.argv is not +examined by testmod. + +In any case, testmod returns a 2-tuple of ints (f, t), where f is the +number of docstring examples that failed and t is the total number of +docstring examples attempted. + + +WHICH DOCSTRINGS ARE EXAMINED? + ++ M.__doc__. + ++ f.__doc__ for all functions f in M.__dict__.values(), except those + with private names. + ++ C.__doc__ for all classes C in M.__dict__.values(), except those with + private names. + ++ If M.__test__ exists and "is true", it must be a dict, and + each entry maps a (string) name to a function object, class object, or + string. Function and class object docstrings found from M.__test__ + are searched even if the name is private, and strings are searched + directly as if they were docstrings. In output, a key K in M.__test__ + appears with name + .__test__.K + +Any classes found are recursively searched similarly, to test docstrings in +their contained methods and nested classes. Private names reached from M's +globals are skipped, but all names reached from M.__test__ are searched. + +By default, a name is considered to be private if it begins with an +underscore (like "_my_func") but doesn't both begin and end with (at least) +two underscores (like "__init__"). You can change the default by passing +your own "isprivate" function to testmod. + +If you want to test docstrings in objects with private names too, stuff +them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your +own isprivate function to Tester's constructor, or call the rundoc method +of a Tester instance). + +Warning: imports can cause trouble; e.g., if you do + +from XYZ import XYZclass + +then XYZclass is a name in M.__dict__ too, and doctest has no way to know +that XYZclass wasn't *defined* in M. So it may try to execute the examples +in XYZclass's docstring, and those in turn may require a different set of +globals to work correctly. I prefer to do "import *"- friendly imports, +a la + +import XYY +_XYZclass = XYZ.XYZclass +del XYZ + +or (Python 2.0) + +from XYZ import XYZclass as _XYZclass + +and then the leading underscore stops testmod from going nuts. You may +prefer the method in the next section. + + +WHAT'S THE EXECUTION CONTEXT? + +By default, each time testmod finds a docstring to test, it uses a *copy* +of M's globals (so that running tests on a module doesn't change the +module's real globals, and so that one test in M can't leave behind crumbs +that accidentally allow another test to work). This means examples can +freely use any names defined at top-level in M. It also means that sloppy +imports (see above) can cause examples in external docstrings to use +globals inappropriate for them. + +You can force use of your own dict as the execution context by passing +"globs=your_dict" to testmod instead. Presumably this would be a copy of +M.__dict__ merged with the globals from other imported modules. + + +WHAT IF I WANT TO TEST A WHOLE PACKAGE? + +Piece o' cake, provided the modules do their testing from docstrings. +Here's the test.py I use for the world's most elaborate Rational/ +floating-base-conversion pkg (which I'll distribute some day): + +from Rational import Cvt +from Rational import Format +from Rational import machprec +from Rational import Rat +from Rational import Round +from Rational import utils + +modules = (Cvt, + Format, + machprec, + Rat, + Round, + utils) + +def _test(): + import doctest + import sys + verbose = "-v" in sys.argv + for mod in modules: + doctest.testmod(mod, verbose=verbose, report=0) + doctest.master.summarize() + +if __name__ == "__main__": + _test() + +IOW, it just runs testmod on all the pkg modules. testmod remembers the +names and outcomes (# of failures, # of tries) for each item it's seen, and +passing "report=0" prevents it from printing a summary in verbose mode. +Instead, the summary is delayed until all modules have been tested, and +then "doctest.master.summarize()" forces the summary at the end. + +So this is very nice in practice: each module can be tested individually +with almost no work beyond writing up docstring examples, and collections +of modules can be tested too as a unit with no more work than the above. + + +WHAT ABOUT EXCEPTIONS? + +No problem, as long as the only output generated by the example is the +traceback itself. For example: + + >>> a = [None] + >>> a[1] + Traceback (innermost last): + File "", line 1, in ? + IndexError: list index out of range + >>> + +Note that only the exception type and value are compared (specifically, +only the last line in the traceback). + + +ADVANCED USAGE + +doctest.testmod() captures the testing policy I find most useful most +often. You may want other policies. + +testmod() actually creates a local instance of class doctest.Tester, runs +appropriate methods of that class, and merges the results into global +Tester instance doctest.master. + +You can create your own instances of doctest.Tester, and so build your own +policies, or even run methods of doctest.master directly. See +doctest.Tester.__doc__ for details. + + +SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!? + +Oh ya. It's easy! In most cases a copy-and-paste of an interactive +console session works fine -- just make sure the leading whitespace is +rigidly consistent (you can mix tabs and spaces if you're too lazy to do it +right, but doctest is not in the business of guessing what you think a tab +means). + + >>> # comments are ignored + >>> x = 12 + >>> x + 12 + >>> if x == 13: + ... print "yes" + ... else: + ... print "no" + ... print "NO" + ... print "NO!!!" + ... + no + NO + NO!!! + >>> + +Any expected output must immediately follow the final ">>>" or "..." line +containing the code, and the expected output (if any) extends to the next +">>>" or all-whitespace line. That's it. + +Bummers: + ++ Expected output cannot contain an all-whitespace line, since such a line + is taken to signal the end of expected output. + ++ Output to stdout is captured, but not output to stderr (exception + tracebacks are captured via a different means). + ++ If you continue a line via backslashing in an interactive session, or for + any other reason use a backslash, you need to double the backslash in the + docstring version. This is simply because you're in a string, and so the + backslash must be escaped for it to survive intact. Like: + +>>> if "yes" == \\ +... "y" + \\ +... "es": # in the source code you'll see the doubled backslashes +... print 'yes' +yes + +The starting column doesn't matter: + +>>> assert "Easy!" + >>> import math + >>> math.floor(1.9) + 1.0 + +and as many leading whitespace characters are stripped from the expected +output as appeared in the initial ">>>" line that triggered it. + +If you execute this very file, the examples above will be found and +executed, leading to this output in verbose mode: + +Running doctest.__doc__ +Trying: a = [None] +Expecting: nothing +ok +Trying: a[1] +Expecting: +Traceback (innermost last): + File "", line 1, in ? +IndexError: list index out of range +ok +Trying: x = 12 +Expecting: nothing +ok +Trying: x +Expecting: 12 +ok +Trying: +if x == 13: + print "yes" +else: + print "no" + print "NO" + print "NO!!!" +Expecting: +no +NO +NO!!! +ok +... and a bunch more like that, with this summary at the end: + +5 items had no tests: + doctest.Tester.__init__ + doctest.Tester.run__test__ + doctest.Tester.summarize + doctest.run_docstring_examples + doctest.testmod +12 items passed all tests: + 9 tests in doctest + 6 tests in doctest.Tester + 10 tests in doctest.Tester.merge + 7 tests in doctest.Tester.rundict + 3 tests in doctest.Tester.rundoc + 3 tests in doctest.Tester.runstring + 2 tests in doctest.__test__._TestClass + 2 tests in doctest.__test__._TestClass.__init__ + 2 tests in doctest.__test__._TestClass.get + 1 tests in doctest.__test__._TestClass.square + 2 tests in doctest.__test__.string + 7 tests in doctest.is_private +54 tests in 17 items. +54 passed and 0 failed. +Test passed. +""" + +# 0,0,1 06-Mar-1999 +# initial version posted +# 0,0,2 06-Mar-1999 +# loosened parsing: +# cater to stinkin' tabs +# don't insist on a blank after PS2 prefix +# so trailing "... " line from a compound stmt no longer +# breaks if the file gets whitespace-trimmed +# better error msgs for inconsistent leading whitespace +# 0,9,1 08-Mar-1999 +# exposed the Tester class and added client methods +# plus docstring examples of their use (eww - head-twisting!) +# fixed logic error in reporting total # of tests & failures +# added __test__ support to testmod (a pale reflection of Christian +# Tismer's vision ...) +# removed the "deep" argument; fiddle __test__ instead +# simplified endcase logic for extracting tests, and running them. +# before, if no output was expected but some was produced +# anyway via an eval'ed result, the discrepancy wasn't caught +# made TestClass private and used __test__ to get at it +# many doc updates +# speed _SpoofOut for long expected outputs +# 0,9,2 09-Mar-1999 +# throw out comments from examples, enabling use of the much simpler +# exec compile(... "single") ... +# for simulating the runtime; that barfs on comment-only lines +# used the traceback module to do a much better job of reporting +# exceptions +# run __doc__ values thru str(), "just in case" +# privateness of names now determined by an overridable "isprivate" +# function +# by default a name now considered to be private iff it begins with +# an underscore but doesn't both begin & end with two of 'em; so +# e.g. Class.__init__ etc are searched now -- as they always +# should have been +# 0,9,3 18-Mar-1999 +# added .flush stub to _SpoofOut (JPython buglet diagnosed by +# Hugh Emberson) +# repaired ridiculous docs about backslashes in examples +# minor internal changes +# changed source to Unix line-end conventions +# moved __test__ logic into new Tester.run__test__ method +# 0,9,4 27-Mar-1999 +# report item name and line # in failing examples +# 0,9,5 29-Jun-1999 +# allow straightforward exceptions in examples - thanks to Mark Hammond! +# 0,9,6 16-Jan-2001 +# fiddling for changes in Python 2.0: some of the embedded docstring +# examples no longer worked *exactly* as advertised, due to minor +# language changes, and running doctest on itself pointed that out. +# Hard to think of a better example of why this is useful . + +__version__ = 0, 9, 6 + +import types +_FunctionType = types.FunctionType +_ClassType = types.ClassType +_ModuleType = types.ModuleType +_StringType = types.StringType +del types + +import string +_string_find = string.find +_string_join = string.join +_string_split = string.split +_string_rindex = string.rindex +del string + +import re +PS1 = ">>>" +PS2 = "..." +_isPS1 = re.compile(r"(\s*)" + re.escape(PS1)).match +_isPS2 = re.compile(r"(\s*)" + re.escape(PS2)).match +_isEmpty = re.compile(r"\s*$").match +_isComment = re.compile(r"\s*#").match +del re + +__all__ = [] + +# Extract interactive examples from a string. Return a list of triples, +# (source, outcome, lineno). "source" is the source code, and ends +# with a newline iff the source spans more than one line. "outcome" is +# the expected output if any, else an empty string. When not empty, +# outcome always ends with a newline. "lineno" is the line number, +# 0-based wrt the start of the string, of the first source line. + +def _extract_examples(s): + isPS1, isPS2 = _isPS1, _isPS2 + isEmpty, isComment = _isEmpty, _isComment + examples = [] + lines = _string_split(s, "\n") + i, n = 0, len(lines) + while i < n: + line = lines[i] + i = i + 1 + m = isPS1(line) + if m is None: + continue + j = m.end(0) # beyond the prompt + if isEmpty(line, j) or isComment(line, j): + # a bare prompt or comment -- not interesting + continue + lineno = i - 1 + if line[j] != " ": + raise ValueError("line " + `lineno` + " of docstring lacks " + "blank after " + PS1 + ": " + line) + j = j + 1 + blanks = m.group(1) + nblanks = len(blanks) + # suck up this and following PS2 lines + source = [] + while 1: + source.append(line[j:]) + line = lines[i] + m = isPS2(line) + if m: + if m.group(1) != blanks: + raise ValueError("inconsistent leading whitespace " + "in line " + `i` + " of docstring: " + line) + i = i + 1 + else: + break + if len(source) == 1: + source = source[0] + else: + # get rid of useless null line from trailing empty "..." + if source[-1] == "": + del source[-1] + source = _string_join(source, "\n") + "\n" + # suck up response + if isPS1(line) or isEmpty(line): + expect = "" + else: + expect = [] + while 1: + if line[:nblanks] != blanks: + raise ValueError("inconsistent leading whitespace " + "in line " + `i` + " of docstring: " + line) + expect.append(line[nblanks:]) + i = i + 1 + line = lines[i] + if isPS1(line) or isEmpty(line): + break + expect = _string_join(expect, "\n") + "\n" + examples.append( (source, expect, lineno) ) + return examples + +# Capture stdout when running examples. + +class _SpoofOut: + def __init__(self): + self.clear() + def write(self, s): + self.buf.append(s) + def get(self): + return _string_join(self.buf, "") + def clear(self): + self.buf = [] + def flush(self): + # JPython calls flush + pass + +# Display some tag-and-msg pairs nicely, keeping the tag and its msg +# on the same line when that makes sense. + +def _tag_out(printer, *tag_msg_pairs): + for tag, msg in tag_msg_pairs: + printer(tag + ":") + msg_has_nl = msg[-1:] == "\n" + msg_has_two_nl = msg_has_nl and \ + _string_find(msg, "\n") < len(msg) - 1 + if len(tag) + len(msg) < 76 and not msg_has_two_nl: + printer(" ") + else: + printer("\n") + printer(msg) + if not msg_has_nl: + printer("\n") + +# Run list of examples, in context globs. "out" can be used to display +# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut +# that captures the examples' std output. Return (#failures, #tries). + +def _run_examples_inner(out, fakeout, examples, globs, verbose, name): + import sys, traceback + OK, BOOM, FAIL = range(3) + NADA = "nothing" + stderr = _SpoofOut() + failures = 0 + for source, want, lineno in examples: + if verbose: + _tag_out(out, ("Trying", source), + ("Expecting", want or NADA)) + fakeout.clear() + try: + exec compile(source, "", "single") in globs + got = fakeout.get() + state = OK + except: + # See whether the exception was expected. + if _string_find(want, "Traceback (innermost last):\n") == 0 or\ + _string_find(want, "Traceback (most recent call last):\n") == 0: + # Only compare exception type and value - the rest of + # the traceback isn't necessary. + want = _string_split(want, '\n')[-2] + '\n' + exc_type, exc_val, exc_tb = sys.exc_info() + got = traceback.format_exception_only(exc_type, exc_val)[0] + state = OK + else: + # unexpected exception + stderr.clear() + traceback.print_exc(file=stderr) + state = BOOM + + if state == OK: + if got == want: + if verbose: + out("ok\n") + continue + state = FAIL + + assert state in (FAIL, BOOM) + failures = failures + 1 + out("*" * 65 + "\n") + _tag_out(out, ("Failure in example", source)) + out("from line #" + `lineno` + " of " + name + "\n") + if state == FAIL: + _tag_out(out, ("Expected", want or NADA), ("Got", got)) + else: + assert state == BOOM + _tag_out(out, ("Exception raised", stderr.get())) + + return failures, len(examples) + +# Run list of examples, in context globs. Return (#failures, #tries). + +def _run_examples(examples, globs, verbose, name): + import sys + saveout = sys.stdout + try: + sys.stdout = fakeout = _SpoofOut() + x = _run_examples_inner(saveout.write, fakeout, examples, + globs, verbose, name) + finally: + sys.stdout = saveout + return x + +def run_docstring_examples(f, globs, verbose=0, name="NoName"): + """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. + + Use dict globs as the globals for execution. + Return (#failures, #tries). + + If optional arg verbose is true, print stuff even if there are no + failures. + Use string name in failure msgs. + """ + + try: + doc = f.__doc__ + if not doc: + # docstring empty or None + return 0, 0 + # just in case CT invents a doc object that has to be forced + # to look like a string <0.9 wink> + doc = str(doc) + except: + return 0, 0 + + e = _extract_examples(doc) + if not e: + return 0, 0 + return _run_examples(e, globs, verbose, name) + +def is_private(prefix, base): + """prefix, base -> true iff name prefix + "." + base is "private". + + Prefix may be an empty string, and base does not contain a period. + Prefix is ignored (although functions you write conforming to this + protocol may make use of it). + Return true iff base begins with an (at least one) underscore, but + does not both begin and end with (at least) two underscores. + + >>> is_private("a.b", "my_func") + 0 + >>> is_private("____", "_my_func") + 1 + >>> is_private("someclass", "__init__") + 0 + >>> is_private("sometypo", "__init_") + 1 + >>> is_private("x.y.z", "_") + 1 + >>> is_private("_x.y.z", "__") + 0 + >>> is_private("", "") # senseless but consistent + 0 + """ + + return base[:1] == "_" and not base[:2] == "__" == base[-2:] + +class Tester: + """Class Tester -- runs docstring examples and accumulates stats. + +In normal use, function doctest.testmod() hides all this from you, +so use that if you can. Create your own instances of Tester to do +fancier things. + +Methods: + runstring(s, name) + Search string s for examples to run; use name for logging. + Return (#failures, #tries). + + rundoc(object, name=None) + Search object.__doc__ for examples to run; use name (or + object.__name__) for logging. Return (#failures, #tries). + + rundict(d, name) + Search for examples in docstrings in all of d.values(); use name + for logging. Return (#failures, #tries). + + run__test__(d, name) + Treat dict d like module.__test__. Return (#failures, #tries). + + summarize(verbose=None) + Display summary of testing results, to stdout. Return + (#failures, #tries). + + merge(other) + Merge in the test results from Tester instance "other". + +>>> from doctest import Tester +>>> t = Tester(globs={'x': 42}, verbose=0) +>>> t.runstring(r''' +... >>> x = x * 2 +... >>> print x +... 42 +... ''', 'XYZ') +***************************************************************** +Failure in example: print x +from line #2 of XYZ +Expected: 42 +Got: 84 +(1, 2) +>>> t.runstring(">>> x = x * 2\\n>>> print x\\n84\\n", 'example2') +(0, 2) +>>> t.summarize() +1 items had failures: + 1 of 2 in XYZ +***Test Failed*** 1 failures. +(1, 4) +>>> t.summarize(verbose=1) +1 items passed all tests: + 2 tests in example2 +1 items had failures: + 1 of 2 in XYZ +4 tests in 2 items. +3 passed and 1 failed. +***Test Failed*** 1 failures. +(1, 4) +>>> +""" + + def __init__(self, mod=None, globs=None, verbose=None, + isprivate=None): + """mod=None, globs=None, verbose=None, isprivate=None + +See doctest.__doc__ for an overview. + +Optional keyword arg "mod" is a module, whose globals are used for +executing examples. If not specified, globs must be specified. + +Optional keyword arg "globs" gives a dict to be used as the globals +when executing examples; if not specified, use the globals from +module mod. + +In either case, a copy of the dict is used for each docstring +examined. + +Optional keyword arg "verbose" prints lots of stuff if true, only +failures if false; by default, it's true iff "-v" is in sys.argv. + +Optional keyword arg "isprivate" specifies a function used to determine +whether a name is private. The default function is doctest.is_private; +see its docs for details. +""" + + if mod is None and globs is None: + raise TypeError("Tester.__init__: must specify mod or globs") + if mod is not None and type(mod) is not _ModuleType: + raise TypeError("Tester.__init__: mod must be a module; " + + `mod`) + if globs is None: + globs = mod.__dict__ + self.globs = globs + + if verbose is None: + import sys + verbose = "-v" in sys.argv + self.verbose = verbose + + if isprivate is None: + isprivate = is_private + self.isprivate = isprivate + + self.name2ft = {} # map name to (#failures, #trials) pair + + def runstring(self, s, name): + """ + s, name -> search string s for examples to run, logging as name. + + Use string name as the key for logging the outcome. + Return (#failures, #examples). + + >>> t = Tester(globs={}, verbose=1) + >>> test = r''' + ... # just an example + ... >>> x = 1 + 2 + ... >>> x + ... 3 + ... ''' + >>> t.runstring(test, "Example") + Running string Example + Trying: x = 1 + 2 + Expecting: nothing + ok + Trying: x + Expecting: 3 + ok + 0 of 2 examples failed in string Example + (0, 2) + """ + + if self.verbose: + print "Running string", name + f = t = 0 + e = _extract_examples(s) + if e: + f, t = _run_examples(e, self.globs.copy(), self.verbose, name) + if self.verbose: + print f, "of", t, "examples failed in string", name + self.__record_outcome(name, f, t) + return f, t + + def rundoc(self, object, name=None): + """ + object, name=None -> search object.__doc__ for examples to run. + + Use optional string name as the key for logging the outcome; + by default use object.__name__. + Return (#failures, #examples). + If object is a class object, search recursively for method + docstrings too. + object.__doc__ is examined regardless of name, but if object is + a class, whether private names reached from object are searched + depends on the constructor's "isprivate" argument. + + >>> t = Tester(globs={}, verbose=0) + >>> def _f(): + ... '''Trivial docstring example. + ... >>> assert 2 == 2 + ... ''' + ... return 32 + ... + >>> t.rundoc(_f) # expect 0 failures in 1 example + (0, 1) + """ + + if name is None: + try: + name = object.__name__ + except AttributeError: + raise ValueError("Tester.rundoc: name must be given " + "when object.__name__ doesn't exist; " + `object`) + if self.verbose: + print "Running", name + ".__doc__" + f, t = run_docstring_examples(object, self.globs.copy(), + self.verbose, name) + if self.verbose: + print f, "of", t, "examples failed in", name + ".__doc__" + self.__record_outcome(name, f, t) + if type(object) is _ClassType: + f2, t2 = self.rundict(object.__dict__, name) + f = f + f2 + t = t + t2 + return f, t + + def rundict(self, d, name): + """ + d. name -> search for docstring examples in all of d.values(). + + For k, v in d.items() such that v is a function or class, + do self.rundoc(v, name + "." + k). Whether this includes + objects with private names depends on the constructor's + "isprivate" argument. + Return aggregate (#failures, #examples). + + >>> def _f(): + ... '''>>> assert 1 == 1 + ... ''' + >>> def g(): + ... '''>>> assert 2 != 1 + ... ''' + >>> d = {"_f": _f, "g": g} + >>> t = Tester(globs={}, verbose=0) + >>> t.rundict(d, "rundict_test") # _f is skipped + (0, 1) + >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) + >>> t.rundict(d, "rundict_test_pvt") # both are searched + (0, 2) + """ + + if not hasattr(d, "items"): + raise TypeError("Tester.rundict: d must support .items(); " + + `d`) + f = t = 0 + for thisname, value in d.items(): + if type(value) in (_FunctionType, _ClassType): + f2, t2 = self.__runone(value, name + "." + thisname) + f = f + f2 + t = t + t2 + return f, t + + def run__test__(self, d, name): + """d, name -> Treat dict d like module.__test__. + + Return (#failures, #tries). + See testmod.__doc__ for details. + """ + + failures = tries = 0 + prefix = name + "." + savepvt = self.isprivate + try: + self.isprivate = lambda *args: 0 + for k, v in d.items(): + thisname = prefix + k + if type(v) is _StringType: + f, t = self.runstring(v, thisname) + elif type(v) in (_FunctionType, _ClassType): + f, t = self.rundoc(v, thisname) + else: + raise TypeError("Tester.run__test__: values in " + "dict must be strings, functions " + "or classes; " + `v`) + failures = failures + f + tries = tries + t + finally: + self.isprivate = savepvt + return failures, tries + + def summarize(self, verbose=None): + """ + verbose=None -> summarize results, return (#failures, #tests). + + Print summary of test results to stdout. + Optional arg 'verbose' controls how wordy this is. By + default, use the verbose setting established by the + constructor. + """ + + if verbose is None: + verbose = self.verbose + notests = [] + passed = [] + failed = [] + totalt = totalf = 0 + for x in self.name2ft.items(): + name, (f, t) = x + assert f <= t + totalt = totalt + t + totalf = totalf + f + if t == 0: + notests.append(name) + elif f == 0: + passed.append( (name, t) ) + else: + failed.append(x) + if verbose: + if notests: + print len(notests), "items had no tests:" + notests.sort() + for thing in notests: + print " ", thing + if passed: + print len(passed), "items passed all tests:" + passed.sort() + for thing, count in passed: + print " %3d tests in %s" % (count, thing) + if failed: + print len(failed), "items had failures:" + failed.sort() + for thing, (f, t) in failed: + print " %3d of %3d in %s" % (f, t, thing) + if verbose: + print totalt, "tests in", len(self.name2ft), "items." + print totalt - totalf, "passed and", totalf, "failed." + if totalf: + print "***Test Failed***", totalf, "failures." + elif verbose: + print "Test passed." + return totalf, totalt + + def merge(self, other): + """ + other -> merge in test results from the other Tester instance. + + If self and other both have a test result for something + with the same name, the (#failures, #tests) results are + summed, and a warning is printed to stdout. + + >>> from doctest import Tester + >>> t1 = Tester(globs={}, verbose=0) + >>> t1.runstring(''' + ... >>> x = 12 + ... >>> print x + ... 12 + ... ''', "t1example") + (0, 2) + >>> + >>> t2 = Tester(globs={}, verbose=0) + >>> t2.runstring(''' + ... >>> x = 13 + ... >>> print x + ... 13 + ... ''', "t2example") + (0, 2) + >>> common = ">>> assert 1 + 2 == 3\\n" + >>> t1.runstring(common, "common") + (0, 1) + >>> t2.runstring(common, "common") + (0, 1) + >>> t1.merge(t2) + *** Tester.merge: 'common' in both testers; summing outcomes. + >>> t1.summarize(1) + 3 items passed all tests: + 2 tests in common + 2 tests in t1example + 2 tests in t2example + 6 tests in 3 items. + 6 passed and 0 failed. + Test passed. + (0, 6) + >>> + """ + + d = self.name2ft + for name, (f, t) in other.name2ft.items(): + if d.has_key(name): + print "*** Tester.merge: '" + name + "' in both" \ + " testers; summing outcomes." + f2, t2 = d[name] + f = f + f2 + t = t + t2 + d[name] = f, t + + def __record_outcome(self, name, f, t): + if self.name2ft.has_key(name): + print "*** Warning: '" + name + "' was tested before;", \ + "summing outcomes." + f2, t2 = self.name2ft[name] + f = f + f2 + t = t + t2 + self.name2ft[name] = f, t + + def __runone(self, target, name): + if "." in name: + i = _string_rindex(name, ".") + prefix, base = name[:i], name[i+1:] + else: + prefix, base = "", base + if self.isprivate(prefix, base): + return 0, 0 + return self.rundoc(target, name) + +master = None + +def testmod(m, name=None, globs=None, verbose=None, isprivate=None, + report=1): + """m, name=None, globs=None, verbose=None, isprivate=None, report=1 + + Test examples in docstrings in functions and classes reachable from + module m, starting with m.__doc__. Private names are skipped. + + Also test examples reachable from dict m.__test__ if it exists and is + not None. m.__dict__ maps names to functions, classes and strings; + function and class docstrings are tested even if the name is private; + strings are tested directly, as if they were docstrings. + + Return (#failures, #tests). + + See doctest.__doc__ for an overview. + + Optional keyword arg "name" gives the name of the module; by default + use m.__name__. + + Optional keyword arg "globs" gives a dict to be used as the globals + when executing examples; by default, use m.__dict__. A copy of this + dict is actually used for each docstring, so that each docstring's + examples start with a clean slate. + + Optional keyword arg "verbose" prints lots of stuff if true, prints + only failures if false; by default, it's true iff "-v" is in sys.argv. + + Optional keyword arg "isprivate" specifies a function used to + determine whether a name is private. The default function is + doctest.is_private; see its docs for details. + + Optional keyword arg "report" prints a summary at the end when true, + else prints nothing at the end. In verbose mode, the summary is + detailed, else very brief (in fact, empty if all tests passed). + + Advanced tomfoolery: testmod runs methods of a local instance of + class doctest.Tester, then merges the results into (or creates) + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. + Passing report=0 to testmod is especially useful then, to delay + displaying a summary. Invoke doctest.master.summarize(verbose) + when you're done fiddling. + """ + + global master + + if type(m) is not _ModuleType: + raise TypeError("testmod: module required; " + `m`) + if name is None: + name = m.__name__ + tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) + failures, tries = tester.rundoc(m, name) + f, t = tester.rundict(m.__dict__, name) + failures = failures + f + tries = tries + t + if hasattr(m, "__test__"): + testdict = m.__test__ + if testdict: + if not hasattr(testdict, "items"): + raise TypeError("testmod: module.__test__ must support " + ".items(); " + `testdict`) + f, t = tester.run__test__(testdict, name + ".__test__") + failures = failures + f + tries = tries + t + if report: + tester.summarize() + if master is None: + master = tester + else: + master.merge(tester) + return failures, tries + +class _TestClass: + """ + A pointless class, for sanity-checking of docstring testing. + + Methods: + square() + get() + + >>> _TestClass(13).get() + _TestClass(-12).get() + 1 + >>> hex(_TestClass(13).square().get()) + '0xa9' + """ + + def __init__(self, val): + """val -> _TestClass object with associated value val. + + >>> t = _TestClass(123) + >>> print t.get() + 123 + """ + + self.val = val + + def square(self): + """square() -> square TestClass's associated value + + >>> _TestClass(13).square().get() + 169 + """ + + self.val = self.val ** 2 + return self + + def get(self): + """get() -> return TestClass's associated value. + + >>> x = _TestClass(-42) + >>> print x.get() + -42 + """ + + return self.val + +__test__ = {"_TestClass": _TestClass, + "string": r""" + Example of a string object, searched as-is. + >>> x = 1; y = 2 + >>> x + y, x * y + (3, 2) + """ + } + +def _test(): + import doctest + return doctest.testmod(doctest) + +if __name__ == "__main__": + _test() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c new file mode 100755 index 00000000000..2ae13ad7281 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c @@ -0,0 +1,540 @@ +/* + * The Python Imaging Library. + * + * standard encoder interfaces for the Imaging library + * + * History: + * 1996-04-19 fl Based on decoders.c + * 1996-05-12 fl Compile cleanly as C++ + * 1996-12-30 fl Plugged potential memory leak for tiled images + * 1997-01-03 fl Added GIF encoder + * 1997-01-05 fl Plugged encoder buffer leaks + * 1997-01-11 fl Added encode_to_file method + * 1998-03-09 fl Added mode/rawmode argument to encoders + * 1998-07-09 fl Added interlace argument to GIF encoder + * 1999-02-07 fl Added PCX encoder + * + * Copyright (c) 1997-2001 by Secret Labs AB + * Copyright (c) 1996-1997 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + +/* FIXME: make these pluggable! */ + +#include "Python.h" + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#include "Imaging.h" +#include "Gif.h" + +#ifdef HAVE_UNISTD_H +#include /* write */ +#endif + +/* -------------------------------------------------------------------- */ +/* Common */ +/* -------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + int (*encode)(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); + struct ImagingCodecStateInstance state; + Imaging im; + PyObject* lock; +} ImagingEncoderObject; + +staticforward PyTypeObject ImagingEncoderType; + +static ImagingEncoderObject* +PyImaging_EncoderNew(int contextsize) +{ + ImagingEncoderObject *encoder; + void *context; + + ImagingEncoderType.ob_type = &PyType_Type; + + encoder = PyObject_New(ImagingEncoderObject, &ImagingEncoderType); + if (encoder == NULL) + return NULL; + + /* Clear the encoder state */ + memset(&encoder->state, 0, sizeof(encoder->state)); + + /* Allocate encoder context */ + if (contextsize > 0) { + context = (void*) calloc(1, contextsize); + if (!context) { + Py_DECREF(encoder); + (void) PyErr_NoMemory(); + return NULL; + } + } else + context = 0; + + /* Initialize encoder context */ + encoder->state.context = context; + + /* Target image */ + encoder->lock = NULL; + encoder->im = NULL; + + return encoder; +} + +static void +_dealloc(ImagingEncoderObject* encoder) +{ + free(encoder->state.buffer); + free(encoder->state.context); + Py_XDECREF(encoder->lock); + PyObject_Del(encoder); +} + +static PyObject* +_encode(ImagingEncoderObject* encoder, PyObject* args) +{ + PyObject* buf; + PyObject* result; + int status; + + /* Encode to a Python string (allocated by this method) */ + + int bufsize = 16384; + + if (!PyArg_ParseTuple(args, "|i", &bufsize)) + return NULL; + + buf = PyString_FromStringAndSize(NULL, bufsize); + if (!buf) + return NULL; + + status = encoder->encode(encoder->im, &encoder->state, + (UINT8*) PyString_AsString(buf), bufsize); + + /* adjust string length to avoid slicing in encoder */ + if (_PyString_Resize(&buf, (status > 0) ? status : 0) < 0) + return NULL; + + result = Py_BuildValue("iiO", status, encoder->state.errcode, buf); + + Py_DECREF(buf); /* must release buffer!!! */ + + return result; +} + +static PyObject* +_encode_to_file(ImagingEncoderObject* encoder, PyObject* args) +{ + UINT8* buf; + int status; + ImagingSectionCookie cookie; + + /* Encode to a file handle */ + + int fh; + int bufsize = 16384; + + if (!PyArg_ParseTuple(args, "i|i", &fh, &bufsize)) + return NULL; + + /* Allocate an encoder buffer */ + buf = (UINT8*) malloc(bufsize); + if (!buf) + return PyErr_NoMemory(); + + ImagingSectionEnter(&cookie); + + do { + + /* This replaces the inner loop in the ImageFile _save + function. */ + + status = encoder->encode(encoder->im, &encoder->state, buf, bufsize); + + if (status > 0) + if (write(fh, buf, status) < 0) { + ImagingSectionLeave(&cookie); + free(buf); + return PyErr_SetFromErrno(PyExc_IOError); + } + + } while (encoder->state.errcode == 0); + + ImagingSectionLeave(&cookie); + + free(buf); + + return Py_BuildValue("i", encoder->state.errcode); +} + +extern Imaging PyImaging_AsImaging(PyObject *op); + +static PyObject* +_setimage(ImagingEncoderObject* encoder, PyObject* args) +{ + PyObject* op; + Imaging im; + ImagingCodecState state; + int x0, y0, x1, y1; + + /* Define where image data should be stored */ + + x0 = y0 = x1 = y1 = 0; + + /* FIXME: should publish the ImagingType descriptor */ + if (!PyArg_ParseTuple(args, "O|(iiii)", &op, &x0, &y0, &x1, &y1)) + return NULL; + im = PyImaging_AsImaging(op); + if (!im) + return NULL; + + encoder->im = im; + + state = &encoder->state; + + if (x0 == 0 && x1 == 0) { + state->xsize = im->xsize; + state->ysize = im->ysize; + } else { + state->xoff = x0; + state->yoff = y0; + state->xsize = x1 - x0; + state->ysize = y1 - y0; + } + + if (state->xsize <= 0 || + state->xsize + state->xoff > im->xsize || + state->ysize <= 0 || + state->ysize + state->yoff > im->ysize) { + PyErr_SetString(PyExc_SystemError, "tile cannot extend outside image"); + return NULL; + } + + /* Allocate memory buffer (if bits field is set) */ + if (state->bits > 0) { + state->bytes = (state->bits * state->xsize+7)/8; + state->buffer = (UINT8*) malloc(state->bytes); + if (!state->buffer) + return PyErr_NoMemory(); + } + + /* Keep a reference to the image object, to make sure it doesn't + go away before we do */ + Py_INCREF(op); + Py_XDECREF(encoder->lock); + encoder->lock = op; + + Py_INCREF(Py_None); + return Py_None; +} + +static struct PyMethodDef methods[] = { + {"encode", (PyCFunction)_encode, 1}, + {"encode_to_file", (PyCFunction)_encode_to_file, 1}, + {"setimage", (PyCFunction)_setimage, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +_getattr(ImagingEncoderObject* self, char* name) +{ + return Py_FindMethod(methods, (PyObject*) self, name); +} + +statichere PyTypeObject ImagingEncoderType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingEncoder", /*tp_name*/ + sizeof(ImagingEncoderObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_hash*/ +}; + +/* -------------------------------------------------------------------- */ + +int +get_packer(ImagingEncoderObject* encoder, const char* mode, + const char* rawmode) +{ + int bits; + ImagingShuffler pack; + + pack = ImagingFindPacker(mode, rawmode, &bits); + if (!pack) { + Py_DECREF(encoder); + PyErr_SetString(PyExc_SystemError, "unknown raw mode"); + return -1; + } + + encoder->state.shuffle = pack; + encoder->state.bits = bits; + + return 0; +} + + +/* -------------------------------------------------------------------- */ +/* EPS */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_EpsEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + encoder = PyImaging_EncoderNew(0); + if (encoder == NULL) + return NULL; + + encoder->encode = ImagingEpsEncode; + + return (PyObject*) encoder; +} + + +/* -------------------------------------------------------------------- */ +/* GIF */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_GifEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + char *mode; + char *rawmode; + int bits = 8; + int interlace = 0; + if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &bits, &interlace)) + return NULL; + + encoder = PyImaging_EncoderNew(sizeof(GIFENCODERSTATE)); + if (encoder == NULL) + return NULL; + + if (get_packer(encoder, mode, rawmode) < 0) + return NULL; + + encoder->encode = ImagingGifEncode; + + ((GIFENCODERSTATE*)encoder->state.context)->bits = bits; + ((GIFENCODERSTATE*)encoder->state.context)->interlace = interlace; + + return (PyObject*) encoder; +} + + +/* -------------------------------------------------------------------- */ +/* PCX */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_PcxEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + char *mode; + char *rawmode; + int bits = 8; + if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &bits)) + return NULL; + + encoder = PyImaging_EncoderNew(0); + if (encoder == NULL) + return NULL; + + if (get_packer(encoder, mode, rawmode) < 0) + return NULL; + + encoder->encode = ImagingPcxEncode; + + return (PyObject*) encoder; +} + + +/* -------------------------------------------------------------------- */ +/* RAW */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_RawEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + char *mode; + char *rawmode; + int stride = 0; + int ystep = 1; + + if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) + return NULL; + + encoder = PyImaging_EncoderNew(0); + if (encoder == NULL) + return NULL; + + if (get_packer(encoder, mode, rawmode) < 0) + return NULL; + + encoder->encode = ImagingRawEncode; + + encoder->state.ystep = ystep; + encoder->state.count = stride; + + return (PyObject*) encoder; +} + + +/* -------------------------------------------------------------------- */ +/* XBM */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyImaging_XbmEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + encoder = PyImaging_EncoderNew(0); + if (encoder == NULL) + return NULL; + + if (get_packer(encoder, "1", "1;R") < 0) + return NULL; + + encoder->encode = ImagingXbmEncode; + + return (PyObject*) encoder; +} + + +/* -------------------------------------------------------------------- */ +/* ZIP */ +/* -------------------------------------------------------------------- */ + +#ifdef HAVE_LIBZ + +#include "Zip.h" + +PyObject* +PyImaging_ZipEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + char* mode; + char* rawmode; + int optimize = 0; + char* dictionary = NULL; + int dictionary_size = 0; + if (!PyArg_ParseTuple(args, "ss|is#", &mode, &rawmode, &optimize, + &dictionary, &dictionary_size)) + return NULL; + + encoder = PyImaging_EncoderNew(sizeof(ZIPSTATE)); + if (encoder == NULL) + return NULL; + + if (get_packer(encoder, mode, rawmode) < 0) + return NULL; + + encoder->encode = ImagingZipEncode; + + if (rawmode[0] == 'P') + /* disable filtering */ + ((ZIPSTATE*)encoder->state.context)->mode = ZIP_PNG_PALETTE; + + ((ZIPSTATE*)encoder->state.context)->optimize = optimize; + ((ZIPSTATE*)encoder->state.context)->dictionary = dictionary; + ((ZIPSTATE*)encoder->state.context)->dictionary_size = dictionary_size; + + return (PyObject*) encoder; +} +#endif + + +/* -------------------------------------------------------------------- */ +/* JPEG */ +/* -------------------------------------------------------------------- */ + +#ifdef HAVE_LIBJPEG + +/* We better define this encoder last in this file, so the following + undef's won't mess things up for the Imaging library proper. */ + +#undef HAVE_PROTOTYPES +#undef HAVE_STDDEF_H +#undef HAVE_STDLIB_H +#undef UINT8 +#undef UINT16 +#undef UINT32 +#undef INT8 +#undef INT16 +#undef INT32 + +#include "Jpeg.h" + +PyObject* +PyImaging_JpegEncoderNew(PyObject* self, PyObject* args) +{ + ImagingEncoderObject* encoder; + + char *mode; + char *rawmode; + int quality = 0; + int progressive = 0; + int smooth = 0; + int optimize = 0; + int streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */ + int xdpi = 0, ydpi = 0; + int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */ + char* extra = NULL; int extra_size; + if (!PyArg_ParseTuple(args, "ss|iiiiiiiis#", &mode, &rawmode, &quality, + &progressive, &smooth, &optimize, &streamtype, + &xdpi, &ydpi, &subsampling, &extra, &extra_size)) + return NULL; + + encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE)); + if (encoder == NULL) + return NULL; + + if (get_packer(encoder, mode, rawmode) < 0) + return NULL; + + if (extra && extra_size > 0) { + char* p = malloc(extra_size); + if (!p) + return PyErr_NoMemory(); + memcpy(p, extra, extra_size); + extra = p; + } else + extra = NULL; + + encoder->encode = ImagingJpegEncode; + + ((JPEGENCODERSTATE*)encoder->state.context)->quality = quality; + ((JPEGENCODERSTATE*)encoder->state.context)->subsampling = subsampling; + ((JPEGENCODERSTATE*)encoder->state.context)->progressive = progressive; + ((JPEGENCODERSTATE*)encoder->state.context)->smooth = smooth; + ((JPEGENCODERSTATE*)encoder->state.context)->optimize = optimize; + ((JPEGENCODERSTATE*)encoder->state.context)->streamtype = streamtype; + ((JPEGENCODERSTATE*)encoder->state.context)->xdpi = xdpi; + ((JPEGENCODERSTATE*)encoder->state.context)->ydpi = ydpi; + ((JPEGENCODERSTATE*)encoder->state.context)->extra = extra; + ((JPEGENCODERSTATE*)encoder->state.context)->extra_size = extra_size; + + return (PyObject*) encoder; +} + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c new file mode 100755 index 00000000000..5ebc9b6f36d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c @@ -0,0 +1,255 @@ +/* + * The Python Imaging Library + * $Id$ + * + * imaging access objects + * + * Copyright (c) Fredrik Lundh 2009. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +/* use Tests/make_hash.py to calculate these values */ +#define ACCESS_TABLE_SIZE 21 +#define ACCESS_TABLE_HASH 30197 + +static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE]; + +static inline UINT32 +hash(const char* mode) +{ + UINT32 i = ACCESS_TABLE_HASH; + while (*mode) + i = ((i<<5) + i) ^ (UINT8) *mode++; + return i % ACCESS_TABLE_SIZE; +} + +static ImagingAccess +add_item(const char* mode) +{ + UINT32 i = hash(mode); + /* printf("hash %s => %d\n", mode, i); */ + if (access_table[i].mode) { + fprintf(stderr, "AccessInit: hash collision: %d for both %s and %s\n", + i, mode, access_table[i].mode); + exit(1); + } + access_table[i].mode = mode; + return &access_table[i]; +} + +/* fetch pointer to pixel line */ + +static void* +line_8(Imaging im, int x, int y) +{ + return &im->image8[y][x]; +} + +static void* +line_16(Imaging im, int x, int y) +{ + return &im->image8[y][x+x]; +} + +static void* +line_32(Imaging im, int x, int y) +{ + return &im->image32[y][x]; +} + +/* fetch individual pixel */ + +static void +get_pixel(Imaging im, int x, int y, void* color) +{ + char* out = color; + + /* generic pixel access*/ + + if (im->image8) { + out[0] = im->image8[y][x]; + } else { + UINT8* p = (UINT8*) &im->image32[y][x]; + if (im->type == IMAGING_TYPE_UINT8 && im->bands == 2) { + out[0] = p[0]; + out[1] = p[3]; + return; + } + memcpy(out, p, im->pixelsize); + } +} + +static void +get_pixel_8(Imaging im, int x, int y, void* color) +{ + char* out = color; + out[0] = im->image8[y][x]; +} + +static void +get_pixel_16L(Imaging im, int x, int y, void* color) +{ + UINT8* in = (UINT8*) &im->image[y][x+x]; + INT16* out = color; +#ifdef WORDS_BIGENDIAN + out[0] = in[0] + (in[1]<<8); +#else + out[0] = *(INT16*) in; +#endif +} + +static void +get_pixel_16B(Imaging im, int x, int y, void* color) +{ + UINT8* in = (UINT8*) &im->image[y][x+x]; + INT16* out = color; +#ifdef WORDS_BIGENDIAN + out[0] = *(INT16*) in; +#else + out[0] = in[1] + (in[0]<<8); +#endif +} + +static void +get_pixel_32(Imaging im, int x, int y, void* color) +{ + INT32* out = color; + out[0] = im->image32[y][x]; +} + +static void +get_pixel_32L(Imaging im, int x, int y, void* color) +{ + UINT8* in = (UINT8*) &im->image[y][x*4]; + INT32* out = color; +#ifdef WORDS_BIGENDIAN + out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); +#else + out[0] = *(INT32*) in; +#endif +} + +static void +get_pixel_32B(Imaging im, int x, int y, void* color) +{ + UINT8* in = (UINT8*) &im->image[y][x*4]; + INT32* out = color; +#ifdef WORDS_BIGENDIAN + out[0] = *(INT32*) in; +#else + out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); +#endif +} + +/* store individual pixel */ + +static void +put_pixel(Imaging im, int x, int y, const void* color) +{ + if (im->image8) + im->image8[y][x] = *((UINT8*) color); + else + im->image32[y][x] = *((INT32*) color); +} + +static void +put_pixel_8(Imaging im, int x, int y, const void* color) +{ + im->image8[y][x] = *((UINT8*) color); +} + +static void +put_pixel_16L(Imaging im, int x, int y, const void* color) +{ + const char* in = color; + UINT8* out = (UINT8*) &im->image8[y][x+x]; + out[0] = in[0]; + out[1] = in[1]; +} + +static void +put_pixel_16B(Imaging im, int x, int y, const void* color) +{ + const char* in = color; + UINT8* out = (UINT8*) &im->image8[y][x+x]; + out[0] = in[1]; + out[1] = in[0]; +} + +static void +put_pixel_32L(Imaging im, int x, int y, const void* color) +{ + const char* in = color; + UINT8* out = (UINT8*) &im->image8[y][x*4]; + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +static void +put_pixel_32B(Imaging im, int x, int y, const void* color) +{ + const char* in = color; + UINT8* out = (UINT8*) &im->image8[y][x*4]; + out[0] = in[3]; + out[1] = in[2]; + out[2] = in[1]; + out[3] = in[0]; +} + +static void +put_pixel_32(Imaging im, int x, int y, const void* color) +{ + im->image32[y][x] = *((INT32*) color); +} + +void +ImagingAccessInit() +{ +#define ADD(mode_, line_, get_pixel_, put_pixel_) \ + { ImagingAccess access = add_item(mode_); \ + access->line = line_; \ + access->get_pixel = get_pixel_; \ + access->put_pixel = put_pixel_; \ + } + + /* populate access table */ + ADD("1", line_8, get_pixel_8, put_pixel_8); + ADD("L", line_8, get_pixel_8, put_pixel_8); + ADD("LA", line_32, get_pixel, put_pixel); + ADD("I", line_32, get_pixel_32, put_pixel_32); + ADD("I;16", line_16, get_pixel_16L, put_pixel_16L); + ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L); + ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B); + ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L); + ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B); + ADD("F", line_32, get_pixel_32, put_pixel_32); + ADD("P", line_8, get_pixel_8, put_pixel_8); + ADD("PA", line_32, get_pixel, put_pixel); + ADD("RGB", line_32, get_pixel_32, put_pixel_32); + ADD("RGBA", line_32, get_pixel_32, put_pixel_32); + ADD("RGBa", line_32, get_pixel_32, put_pixel_32); + ADD("RGBX", line_32, get_pixel_32, put_pixel_32); + ADD("CMYK", line_32, get_pixel_32, put_pixel_32); + ADD("YCbCr", line_32, get_pixel_32, put_pixel_32); +} + +ImagingAccess +ImagingAccessNew(Imaging im) +{ + ImagingAccess access = &access_table[hash(im->mode)]; + if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) + return NULL; + return access; +} + +void +_ImagingAccessDelete(Imaging im, ImagingAccess access) +{ + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c new file mode 100755 index 00000000000..53dfa352251 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c @@ -0,0 +1,307 @@ +/* + * The Python Imaging Library + * $Id$ + * + * pilopen antialiasing support + * + * history: + * 2002-03-09 fl Created (for PIL 1.1.3) + * 2002-03-10 fl Added support for mode "F" + * + * Copyright (c) 1997-2002 by Secret Labs AB + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +#include + +/* resampling filters (from antialias.py) */ + +struct filter { + float (*filter)(float x); + float support; +}; + +static inline float sinc_filter(float x) +{ + if (x == 0.0) + return 1.0; + x = x * M_PI; + return sin(x) / x; +} + +static inline float antialias_filter(float x) +{ + /* lanczos (truncated sinc) */ + if (-3.0 <= x && x < 3.0) + return sinc_filter(x) * sinc_filter(x/3); + return 0.0; +} + +static struct filter ANTIALIAS = { antialias_filter, 3.0 }; + +static inline float nearest_filter(float x) +{ + if (-0.5 <= x && x < 0.5) + return 1.0; + return 0.0; +} + +static struct filter NEAREST = { nearest_filter, 0.5 }; + +static inline float bilinear_filter(float x) +{ + if (x < 0.0) + x = -x; + if (x < 1.0) + return 1.0-x; + return 0.0; +} + +static struct filter BILINEAR = { bilinear_filter, 1.0 }; + +static inline float bicubic_filter(float x) +{ + /* FIXME: double-check this algorithm */ + /* FIXME: for best results, "a" should be -0.5 to -1.0, but we'll + set it to zero for now, to match the 1.1 magnifying filter */ +#define a 0.0 + if (x < 0.0) + x = -x; + if (x < 1.0) + return (((a + 2.0) * x) - (a + 3.0)) * x*x + 1; + if (x < 2.0) + return (((a * x) - 5*a) * x + 8) * x - 4*a; + return 0.0; +#undef a +} + +static struct filter BICUBIC = { bicubic_filter, 2.0 }; + +Imaging +ImagingStretch(Imaging imOut, Imaging imIn, int filter) +{ + /* FIXME: this is a quick and straightforward translation from a + python prototype. might need some further C-ification... */ + + ImagingSectionCookie cookie; + struct filter *filterp; + float support, scale, filterscale; + float center, ww, ss, ymin, ymax, xmin, xmax; + int xx, yy, x, y, b; + float *k; + + /* check modes */ + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + + /* check filter */ + switch (filter) { + case IMAGING_TRANSFORM_NEAREST: + filterp = &NEAREST; + break; + case IMAGING_TRANSFORM_ANTIALIAS: + filterp = &ANTIALIAS; + break; + case IMAGING_TRANSFORM_BILINEAR: + filterp = &BILINEAR; + break; + case IMAGING_TRANSFORM_BICUBIC: + filterp = &BICUBIC; + break; + default: + return (Imaging) ImagingError_ValueError( + "unsupported resampling filter" + ); + } + + if (imIn->ysize == imOut->ysize) { + /* prepare for horizontal stretch */ + filterscale = scale = (float) imIn->xsize / imOut->xsize; + } else if (imIn->xsize == imOut->xsize) { + /* prepare for vertical stretch */ + filterscale = scale = (float) imIn->ysize / imOut->ysize; + } else + return (Imaging) ImagingError_Mismatch(); + + /* determine support size (length of resampling filter) */ + support = filterp->support; + + if (filterscale < 1.0) { + filterscale = 1.0; + support = 0.5; + } + + support = support * filterscale; + + /* coefficient buffer (with rounding safety margin) */ + k = malloc(((int) support * 2 + 10) * sizeof(float)); + if (!k) + return (Imaging) ImagingError_MemoryError(); + + ImagingSectionEnter(&cookie); + if (imIn->xsize == imOut->xsize) { + /* vertical stretch */ + for (yy = 0; yy < imOut->ysize; yy++) { + center = (yy + 0.5) * scale; + ww = 0.0; + ss = 1.0 / filterscale; + /* calculate filter weights */ + ymin = floor(center - support); + if (ymin < 0.0) + ymin = 0.0; + ymax = ceil(center + support); + if (ymax > (float) imIn->ysize) + ymax = (float) imIn->ysize; + for (y = (int) ymin; y < (int) ymax; y++) { + float w = filterp->filter((y - center + 0.5) * ss) * ss; + k[y - (int) ymin] = w; + ww = ww + w; + } + if (ww == 0.0) + ww = 1.0; + else + ww = 1.0 / ww; + if (imIn->image8) { + /* 8-bit grayscale */ + for (xx = 0; xx < imOut->xsize; xx++) { + ss = 0.0; + for (y = (int) ymin; y < (int) ymax; y++) + ss = ss + imIn->image8[y][xx] * k[y - (int) ymin]; + ss = ss * ww + 0.5; + if (ss < 0.5) + imOut->image8[yy][xx] = 0; + else if (ss >= 255.0) + imOut->image8[yy][xx] = 255; + else + imOut->image8[yy][xx] = (UINT8) ss; + } + } else + switch(imIn->type) { + case IMAGING_TYPE_UINT8: + /* n-bit grayscale */ + for (xx = 0; xx < imOut->xsize*4; xx++) { + /* FIXME: skip over unused pixels */ + ss = 0.0; + for (y = (int) ymin; y < (int) ymax; y++) + ss = ss + (UINT8) imIn->image[y][xx] * k[y-(int) ymin]; + ss = ss * ww + 0.5; + if (ss < 0.5) + imOut->image[yy][xx] = (UINT8) 0; + else if (ss >= 255.0) + imOut->image[yy][xx] = (UINT8) 255; + else + imOut->image[yy][xx] = (UINT8) ss; + } + break; + case IMAGING_TYPE_INT32: + /* 32-bit integer */ + for (xx = 0; xx < imOut->xsize; xx++) { + ss = 0.0; + for (y = (int) ymin; y < (int) ymax; y++) + ss = ss + IMAGING_PIXEL_I(imIn, xx, y) * k[y - (int) ymin]; + IMAGING_PIXEL_I(imOut, xx, yy) = (int) ss * ww; + } + break; + case IMAGING_TYPE_FLOAT32: + /* 32-bit float */ + for (xx = 0; xx < imOut->xsize; xx++) { + ss = 0.0; + for (y = (int) ymin; y < (int) ymax; y++) + ss = ss + IMAGING_PIXEL_F(imIn, xx, y) * k[y - (int) ymin]; + IMAGING_PIXEL_F(imOut, xx, yy) = ss * ww; + } + break; + default: + ImagingSectionLeave(&cookie); + return (Imaging) ImagingError_ModeError(); + } + } + } else { + /* horizontal stretch */ + for (xx = 0; xx < imOut->xsize; xx++) { + center = (xx + 0.5) * scale; + ww = 0.0; + ss = 1.0 / filterscale; + xmin = floor(center - support); + if (xmin < 0.0) + xmin = 0.0; + xmax = ceil(center + support); + if (xmax > (float) imIn->xsize) + xmax = (float) imIn->xsize; + for (x = (int) xmin; x < (int) xmax; x++) { + float w = filterp->filter((x - center + 0.5) * ss) * ss; + k[x - (int) xmin] = w; + ww = ww + w; + } + if (ww == 0.0) + ww = 1.0; + else + ww = 1.0 / ww; + if (imIn->image8) { + /* 8-bit grayscale */ + for (yy = 0; yy < imOut->ysize; yy++) { + ss = 0.0; + for (x = (int) xmin; x < (int) xmax; x++) + ss = ss + imIn->image8[yy][x] * k[x - (int) xmin]; + ss = ss * ww + 0.5; + if (ss < 0.5) + imOut->image8[yy][xx] = (UINT8) 0; + else if (ss >= 255.0) + imOut->image8[yy][xx] = (UINT8) 255; + else + imOut->image8[yy][xx] = (UINT8) ss; + } + } else + switch(imIn->type) { + case IMAGING_TYPE_UINT8: + /* n-bit grayscale */ + for (yy = 0; yy < imOut->ysize; yy++) { + for (b = 0; b < imIn->bands; b++) { + if (imIn->bands == 2 && b) + b = 3; /* hack to deal with LA images */ + ss = 0.0; + for (x = (int) xmin; x < (int) xmax; x++) + ss = ss + (UINT8) imIn->image[yy][x*4+b] * k[x - (int) xmin]; + ss = ss * ww + 0.5; + if (ss < 0.5) + imOut->image[yy][xx*4+b] = (UINT8) 0; + else if (ss >= 255.0) + imOut->image[yy][xx*4+b] = (UINT8) 255; + else + imOut->image[yy][xx*4+b] = (UINT8) ss; + } + } + break; + case IMAGING_TYPE_INT32: + /* 32-bit integer */ + for (yy = 0; yy < imOut->ysize; yy++) { + ss = 0.0; + for (x = (int) xmin; x < (int) xmax; x++) + ss = ss + IMAGING_PIXEL_I(imIn, x, yy) * k[x - (int) xmin]; + IMAGING_PIXEL_I(imOut, xx, yy) = (int) ss * ww; + } + break; + case IMAGING_TYPE_FLOAT32: + /* 32-bit float */ + for (yy = 0; yy < imOut->ysize; yy++) { + ss = 0.0; + for (x = (int) xmin; x < (int) xmax; x++) + ss = ss + IMAGING_PIXEL_F(imIn, x, yy) * k[x - (int) xmin]; + IMAGING_PIXEL_F(imOut, xx, yy) = ss * ww; + } + break; + default: + ImagingSectionLeave(&cookie); + return (Imaging) ImagingError_ModeError(); + } + } + } + ImagingSectionLeave(&cookie); + + free(k); + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c new file mode 100755 index 00000000000..fdfc6ae9581 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c @@ -0,0 +1,129 @@ +/* + * The Python Imaging Library + * $Id$ + * + * stuff to extract and paste back individual bands + * + * history: + * 1996-03-20 fl Created + * 1997-08-27 fl Fixed putband for single band targets. + * 2003-09-26 fl Fixed getband/putband for 2-band images (LA, PA). + * + * Copyright (c) 1997-2003 by Secret Labs AB. + * Copyright (c) 1996-1997 by Fredrik Lundh. + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + + +#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) + + +Imaging +ImagingGetBand(Imaging imIn, int band) +{ + Imaging imOut; + int x, y; + + /* Check arguments */ + if (!imIn || imIn->type != IMAGING_TYPE_UINT8) + return (Imaging) ImagingError_ModeError(); + + if (band < 0 || band >= imIn->bands) + return (Imaging) ImagingError_ValueError("band index out of range"); + + /* Shortcuts */ + if (imIn->bands == 1) + return ImagingCopy(imIn); + + /* Special case for LXXA etc */ + if (imIn->bands == 2 && band == 1) + band = 3; + + imOut = ImagingNew("L", imIn->xsize, imIn->ysize); + if (!imOut) + return NULL; + + /* Extract band from image */ + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = (UINT8*) imIn->image[y] + band; + UINT8* out = imOut->image8[y]; + for (x = 0; x < imIn->xsize; x++) { + out[x] = *in; + in += 4; + } + } + + return imOut; +} + +Imaging +ImagingPutBand(Imaging imOut, Imaging imIn, int band) +{ + int x, y; + + /* Check arguments */ + if (!imIn || imIn->bands != 1 || !imOut) + return (Imaging) ImagingError_ModeError(); + + if (band < 0 || band >= imOut->bands) + return (Imaging) ImagingError_ValueError("band index out of range"); + + if (imIn->type != imOut->type || + imIn->xsize != imOut->xsize || + imIn->ysize != imOut->ysize) + return (Imaging) ImagingError_Mismatch(); + + /* Shortcuts */ + if (imOut->bands == 1) + return ImagingCopy2(imOut, imIn); + + /* Special case for LXXA etc */ + if (imOut->bands == 2 && band == 1) + band = 3; + + /* Insert band into image */ + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = imIn->image8[y]; + UINT8* out = (UINT8*) imOut->image[y] + band; + for (x = 0; x < imIn->xsize; x++) { + *out = in[x]; + out += 4; + } + } + + return imOut; +} + +Imaging +ImagingFillBand(Imaging imOut, int band, int color) +{ + int x, y; + + /* Check arguments */ + if (!imOut || imOut->type != IMAGING_TYPE_UINT8) + return (Imaging) ImagingError_ModeError(); + + if (band < 0 || band >= imOut->bands) + return (Imaging) ImagingError_ValueError("band index out of range"); + + /* Special case for LXXA etc */ + if (imOut->bands == 2 && band == 1) + band = 3; + + color = CLIP(color); + + /* Insert color into image */ + for (y = 0; y < imOut->ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y] + band; + for (x = 0; x < imOut->xsize; x++) { + *out = (UINT8) color; + out += 4; + } + } + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h new file mode 100755 index 00000000000..56e3a17d2e7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h @@ -0,0 +1,30 @@ +/* Bit.h */ + +typedef struct { + + /* CONFIGURATION */ + + /* Number of bits per pixel */ + int bits; + + /* Line padding (0 or 8) */ + int pad; + + /* Fill order */ + /* 0=msb/msb, 1=msbfill/lsbshift, 2=lsbfill/msbshift, 3=lsb/lsb */ + int fill; + + /* Signed integers (0=unsigned, 1=signed) */ + int sign; + + /* Lookup table (not implemented) */ + unsigned long lutsize; + FLOAT32* lut; + + /* INTERNAL */ + unsigned long mask; + unsigned long signmask; + unsigned long bitbuffer; + int bitcount; + +} BITSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c new file mode 100755 index 00000000000..572926f0079 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c @@ -0,0 +1,138 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for packed bitfields (converts to floating point) + * + * history: + * 97-05-31 fl created (much more than originally intended) + * + * Copyright (c) Fredrik Lundh 1997. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include "Bit.h" + + +int +ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + BITSTATE* bitstate = state->context; + UINT8* ptr; + + if (state->state == 0) { + + /* Initialize context variables */ + + /* this decoder only works for float32 image buffers */ + if (im->type != IMAGING_TYPE_FLOAT32) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + /* sanity check */ + if (bitstate->bits < 1 || bitstate->bits >= 32) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + bitstate->mask = (1<bits)-1; + + if (bitstate->sign) + bitstate->signmask = (1<<(bitstate->bits-1)); + + /* check image orientation */ + if (state->ystep < 0) { + state->y = state->ysize-1; + state->ystep = -1; + } else + state->ystep = 1; + + state->state = 1; + + } + + ptr = buf; + + while (bytes > 0) { + + UINT8 byte = *ptr; + + ptr++; + bytes--; + + /* get a byte from the input stream and insert in the bit buffer */ + if (bitstate->fill&1) + /* fill MSB first */ + bitstate->bitbuffer |= (unsigned long) byte << bitstate->bitcount; + else + /* fill LSB first */ + bitstate->bitbuffer = (bitstate->bitbuffer << 8) | byte; + + bitstate->bitcount += 8; + + while (bitstate->bitcount >= bitstate->bits) { + + /* get a pixel from the bit buffer */ + unsigned long data; + FLOAT32 pixel; + + if (bitstate->fill&2) { + /* store LSB first */ + data = bitstate->bitbuffer & bitstate->mask; + if (bitstate->bitcount > 32) + /* bitbuffer overflow; restore it from last input byte */ + bitstate->bitbuffer = byte >> (8 - (bitstate->bitcount - + bitstate->bits)); + else + bitstate->bitbuffer >>= bitstate->bits; + } else + /* store MSB first */ + data = (bitstate->bitbuffer >> (bitstate->bitcount - + bitstate->bits)) + & bitstate->mask; + + bitstate->bitcount -= bitstate->bits; + + if (bitstate->lutsize > 0) { + /* map through lookup table */ + if (data <= 0) + pixel = bitstate->lut[0]; + else if (data >= bitstate->lutsize) + pixel = bitstate->lut[bitstate->lutsize-1]; + else + pixel = bitstate->lut[data]; + } else { + /* convert */ + if (data & bitstate->signmask) + /* image memory contains signed data */ + pixel = (FLOAT32) (INT32) (data | ~bitstate->mask); + else + pixel = (FLOAT32) data; + } + + *(FLOAT32*)(&im->image32[state->y][state->x]) = pixel; + + /* step forward */ + if (++state->x >= state->xsize) { + /* new line */ + state->y += state->ystep; + if (state->y < 0 || state->y >= state->ysize) { + /* end of file (errcode = 0) */ + return -1; + } + state->x = 0; + /* reset bit buffer */ + if (bitstate->pad > 0) + bitstate->bitcount = 0; + } + } + } + + return ptr - buf; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c new file mode 100755 index 00000000000..0861c8ef4fb --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c @@ -0,0 +1,79 @@ +/* + * The Python Imaging Library + * $Id$ + * + * interpolate between two existing images + * + * history: + * 96-03-20 fl Created + * 96-05-18 fl Simplified blend expression + * 96-10-05 fl Fixed expression bug, special case for interpolation + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + + +Imaging +ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) +{ + Imaging imOut; + int x, y; + + /* Check arguments */ + if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8) + return ImagingError_ModeError(); + if (imIn1->type != imIn2->type || + imIn1->bands != imIn2->bands || + imIn1->xsize != imIn2->xsize || + imIn1->ysize != imIn2->ysize) + return ImagingError_Mismatch(); + + /* Shortcuts */ + if (alpha == 0.0) + return ImagingCopy(imIn1); + else if (alpha == 1.0) + return ImagingCopy(imIn2); + + imOut = ImagingNew(imIn1->mode, imIn1->xsize, imIn1->ysize); + if (!imOut) + return NULL; + + ImagingCopyInfo(imOut, imIn1); + + if (alpha >= 0 && alpha <= 1.0) { + /* Interpolate between bands */ + for (y = 0; y < imIn1->ysize; y++) { + UINT8* in1 = (UINT8*) imIn1->image[y]; + UINT8* in2 = (UINT8*) imIn2->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + for (x = 0; x < imIn1->linesize; x++) + out[x] = (UINT8) + ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); + } + } else { + /* Extrapolation; must make sure to clip resulting values */ + for (y = 0; y < imIn1->ysize; y++) { + UINT8* in1 = (UINT8*) imIn1->image[y]; + UINT8* in2 = (UINT8*) imIn2->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + for (x = 0; x < imIn1->linesize; x++) { + float temp = (float) + ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); + if (temp <= 0.0) + out[x] = 0; + else if (temp >= 255.0) + out[x] = 255; + else + out[x] = (UINT8) temp; + } + } + } + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c new file mode 100755 index 00000000000..e5993195a03 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c @@ -0,0 +1,148 @@ +/* + * The Python Imaging Library + * $Id$ + * + * basic channel operations + * + * history: + * 1996-03-28 fl Created + * 1996-08-13 fl Added and/or/xor for "1" images + * 1996-12-14 fl Added add_modulo, sub_modulo + * 2005-09-10 fl Fixed output values from and/or/xor + * + * Copyright (c) 1996 by Fredrik Lundh. + * Copyright (c) 1997 by Secret Labs AB. + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + +#define CHOP(operation, mode)\ + int x, y;\ + Imaging imOut;\ + imOut = create(imIn1, imIn2, mode);\ + if (!imOut)\ + return NULL;\ + for (y = 0; y < imOut->ysize; y++) {\ + UINT8* out = (UINT8*) imOut->image[y];\ + UINT8* in1 = (UINT8*) imIn1->image[y];\ + UINT8* in2 = (UINT8*) imIn2->image[y];\ + for (x = 0; x < imOut->linesize; x++) {\ + int temp = operation;\ + if (temp <= 0)\ + out[x] = 0;\ + else if (temp >= 255)\ + out[x] = 255;\ + else\ + out[x] = temp;\ + }\ + }\ + return imOut; + +#define CHOP2(operation, mode)\ + int x, y;\ + Imaging imOut;\ + imOut = create(imIn1, imIn2, mode);\ + if (!imOut)\ + return NULL;\ + for (y = 0; y < imOut->ysize; y++) {\ + UINT8* out = (UINT8*) imOut->image[y];\ + UINT8* in1 = (UINT8*) imIn1->image[y];\ + UINT8* in2 = (UINT8*) imIn2->image[y];\ + for (x = 0; x < imOut->linesize; x++) {\ + out[x] = operation;\ + }\ + }\ + return imOut; + +static Imaging +create(Imaging im1, Imaging im2, char* mode) +{ + int xsize, ysize; + + if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 || + (mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) + return (Imaging) ImagingError_ModeError(); + if (im1->type != im2->type || + im1->bands != im2->bands) + return (Imaging) ImagingError_Mismatch(); + + xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize; + ysize = (im1->ysize < im2->ysize) ? im1->ysize : im2->ysize; + + return ImagingNew(im1->mode, xsize, ysize); +} + +Imaging +ImagingChopLighter(Imaging imIn1, Imaging imIn2) +{ + CHOP((in1[x] > in2[x]) ? in1[x] : in2[x], NULL); +} + +Imaging +ImagingChopDarker(Imaging imIn1, Imaging imIn2) +{ + CHOP((in1[x] < in2[x]) ? in1[x] : in2[x], NULL); +} + +Imaging +ImagingChopDifference(Imaging imIn1, Imaging imIn2) +{ + CHOP(abs((int) in1[x] - (int) in2[x]), NULL); +} + +Imaging +ImagingChopMultiply(Imaging imIn1, Imaging imIn2) +{ + CHOP((int) in1[x] * (int) in2[x] / 255, NULL); +} + +Imaging +ImagingChopScreen(Imaging imIn1, Imaging imIn2) +{ + CHOP(255 - ((int) (255 - in1[x]) * (int) (255 - in2[x])) / 255, NULL); +} + +Imaging +ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset) +{ + CHOP(((int) in1[x] + (int) in2[x]) / scale + offset, NULL); +} + +Imaging +ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) +{ + CHOP(((int) in1[x] - (int) in2[x]) / scale + offset, NULL); +} + +Imaging +ImagingChopAnd(Imaging imIn1, Imaging imIn2) +{ + CHOP2((in1[x] && in2[x]) ? 255 : 0, "1"); +} + +Imaging +ImagingChopOr(Imaging imIn1, Imaging imIn2) +{ + CHOP2((in1[x] || in2[x]) ? 255 : 0, "1"); +} + +Imaging +ImagingChopXor(Imaging imIn1, Imaging imIn2) +{ + CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1"); +} + +Imaging +ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) +{ + CHOP2(in1[x] + in2[x], NULL); +} + +Imaging +ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) +{ + CHOP2(in1[x] - in2[x], NULL); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c new file mode 100755 index 00000000000..25299aa8280 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c @@ -0,0 +1,1132 @@ +/* + * The Python Imaging Library + * $Id$ + * + * convert images + * + * history: + * 1995-06-15 fl created + * 1995-11-28 fl added some "RGBA" and "CMYK" conversions + * 1996-04-22 fl added "1" conversions (same as "L") + * 1996-05-05 fl added palette conversions (hack) + * 1996-07-23 fl fixed "1" conversions to zero/non-zero convention + * 1996-11-01 fl fixed "P" to "L" and "RGB" to "1" conversions + * 1996-12-29 fl set alpha byte in RGB converters + * 1997-05-12 fl added ImagingConvert2 + * 1997-05-30 fl added floating point support + * 1997-08-27 fl added "P" to "1" and "P" to "F" conversions + * 1998-01-11 fl added integer support + * 1998-07-01 fl added "YCbCr" support + * 1998-07-02 fl added "RGBX" conversions (sort of) + * 1998-07-04 fl added floyd-steinberg dithering + * 1998-07-12 fl changed "YCrCb" to "YCbCr" (!) + * 1998-12-29 fl added basic "I;16" and "I;16B" conversions + * 1999-02-03 fl added "RGBa", and "BGR" conversions (experimental) + * 2003-09-26 fl added "LA" and "PA" conversions (experimental) + * 2005-05-05 fl fixed "P" to "1" threshold + * 2005-12-08 fl fixed palette memory leak in topalette + * + * Copyright (c) 1997-2005 by Secret Labs AB. + * Copyright (c) 1995-1997 by Fredrik Lundh. + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + +#define CLIP(v) ((v) <= 0 ? 0 : (v) >= 255 ? 255 : (v)) +#define CLIP16(v) ((v) <= -32768 ? -32768 : (v) >= 32767 ? 32767 : (v)) + +/* like (a * b + 127) / 255), but much faster on most platforms */ +#define MULDIV255(a, b, tmp)\ + (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) + +/* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ +#define L(rgb)\ + ((INT32) (rgb)[0]*299 + (INT32) (rgb)[1]*587 + (INT32) (rgb)[2]*114) + +/* ------------------- */ +/* 1 (bit) conversions */ +/* ------------------- */ + +static void +bit2l(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) + *out++ = (*in++ != 0) ? 255 : 0; +} + +static void +bit2rgb(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + UINT8 v = (*in++ != 0) ? 255 : 0; + *out++ = v; + *out++ = v; + *out++ = v; + *out++ = 255; + } +} + +static void +bit2cmyk(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = (*in++ != 0) ? 0 : 255; + } +} + +static void +bit2ycbcr(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + *out++ = (*in++ != 0) ? 255 : 0; + *out++ = 128; + *out++ = 128; + *out++ = 255; + } +} + +/* ----------------- */ +/* RGB/L conversions */ +/* ----------------- */ + +static void +l2bit(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) + *out++ = (*in++ >= 128) ? 255 : 0; +} + +static void +l2la(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + UINT8 v = *in++; + *out++ = v; + *out++ = v; + *out++ = v; + *out++ = 255; + } +} + +static void +l2rgb(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + UINT8 v = *in++; + *out++ = v; + *out++ = v; + *out++ = v; + *out++ = 255; + } +} + +static void +la2l(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) + *out++ = in[0]; +} + +static void +la2rgb(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) { + UINT8 v = in[0]; + *out++ = v; + *out++ = v; + *out++ = v; + *out++ = in[3]; + } +} + +static void +rgb2bit(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) + /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ + *out++ = (L(in) >= 128000) ? 255 : 0; +} + +static void +rgb2l(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) + /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ + *out++ = L(in) / 1000; +} + +static void +rgb2la(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4, out += 4) { + /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ + out[0] = out[1] = out[2] = L(in) / 1000; + out[3] = 255; + } +} + +static void +rgb2i(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++, in += 4) + *out++ = L(in) / 1000; +} + +static void +rgb2f(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++, in += 4) + *out++ = (float) L(in) / 1000.0F; +} + +static void +rgb2bgr15(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + UINT16* out = (UINT16*) out_; + for (x = 0; x < xsize; x++, in += 4) + *out++ = + ((((UINT16)in[0])<<7)&0x7c00) + + ((((UINT16)in[1])<<2)&0x03e0) + + ((((UINT16)in[2])>>3)&0x001f); +} + +static void +rgb2bgr16(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + UINT16* out = (UINT16*) out_; + for (x = 0; x < xsize; x++, in += 4) + *out++ = + ((((UINT16)in[0])<<8)&0xf800) + + ((((UINT16)in[1])<<3)&0x07e0) + + ((((UINT16)in[2])>>3)&0x001f); +} + +static void +rgb2bgr24(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) { + *out++ = in[2]; + *out++ = in[1]; + *out++ = in[0]; + } +} + +/* ---------------- */ +/* RGBA conversions */ +/* ---------------- */ + +static void +rgb2rgba(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + *out++ = 255; in++; + } +} + +static void +rgba2la(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4, out += 4) { + /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ + out[0] = out[1] = out[2] = L(in) / 1000; + out[3] = in[3]; + } +} + +static void +rgba2rgb(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + *out++ = 255; in++; + } +} + +static void +rgba2rgba(UINT8* out, const UINT8* in, int xsize) +{ + int x; + unsigned int alpha, tmp; + for (x = 0; x < xsize; x++) { + alpha = in[3]; + *out++ = MULDIV255(*in++, alpha, tmp); + *out++ = MULDIV255(*in++, alpha, tmp); + *out++ = MULDIV255(*in++, alpha, tmp); + *out++ = *in++; + } +} + +/* ---------------- */ +/* CMYK conversions */ +/* ---------------- */ + +static void +l2cmyk(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = ~(*in++); + } +} + +static void +rgb2cmyk(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + /* Note: no undercolour removal */ + *out++ = ~(*in++); + *out++ = ~(*in++); + *out++ = ~(*in++); + *out++ = 0; in++; + } +} + +static void +cmyk2rgb(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) { + *out++ = CLIP(255 - (in[0] + in[3])); + *out++ = CLIP(255 - (in[1] + in[3])); + *out++ = CLIP(255 - (in[2] + in[3])); + *out++ = 255; + } +} + +/* ------------- */ +/* I conversions */ +/* ------------- */ + +static void +bit2i(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (*in++ != 0) ? 255 : 0; +} + +static void +l2i(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (INT32) *in++; +} + +static void +i2l(UINT8* out, const UINT8* in_, int xsize) +{ + int x; + INT32* in = (INT32*) in_; + for (x = 0; x < xsize; x++, in++, out++) { + if (*in <= 0) + *out = 0; + else if (*in >= 255) + *out = 255; + else + *out = (UINT8) *in; + } +} + +static void +i2f(UINT8* out_, const UINT8* in_, int xsize) +{ + int x; + INT32* in = (INT32*) in_; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (FLOAT32) *in++; +} + +/* ------------- */ +/* F conversions */ +/* ------------- */ + +static void +bit2f(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (*in++ != 0) ? 255.0F : 0.0F; +} + +static void +l2f(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (FLOAT32) *in++; +} + +static void +f2l(UINT8* out, const UINT8* in_, int xsize) +{ + int x; + FLOAT32* in = (FLOAT32*) in_; + for (x = 0; x < xsize; x++, in++, out++) { + if (*in <= 0.0) + *out = 0; + else if (*in >= 255.0) + *out = 255; + else + *out = (UINT8) *in; + } +} + +static void +f2i(UINT8* out_, const UINT8* in_, int xsize) +{ + int x; + FLOAT32* in = (FLOAT32*) in_; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (INT32) *in++; +} + +/* ----------------- */ +/* YCbCr conversions */ +/* ----------------- */ + +/* See ConvertYCbCr.c for RGB/YCbCr tables */ + +static void +l2ycbcr(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++) { + *out++ = *in++; + *out++ = 128; + *out++ = 128; + *out++ = 255; + } +} + +static void +ycbcr2l(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) + *out++ = in[0]; +} + +/* ------------------------- */ +/* I;16 (16-bit) conversions */ +/* ------------------------- */ + +static void +I_I16L(UINT8* out, const UINT8* in_, int xsize) +{ + int x, v; + INT32* in = (INT32*) in_; + for (x = 0; x < xsize; x++, in++) { + v = CLIP16(*in); + *out++ = (UINT8) v; + *out++ = (UINT8) (v >> 8); + } +} + +static void +I_I16B(UINT8* out, const UINT8* in_, int xsize) +{ + int x, v; + INT32* in = (INT32*) in_; + for (x = 0; x < xsize; x++, in++) { + v = CLIP16(*in); + *out++ = (UINT8) (v >> 8); + *out++ = (UINT8) v; + } +} + + +static void +I16L_I(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++, in += 2) + *out++ = in[0] + ((int) in[1] << 8); +} + + +static void +I16B_I(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++, in += 2) + *out++ = in[1] + ((int) in[0] << 8); +} + +static void +L_I16L(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in++) { + *out++ = *in; + *out++ = 0; + } +} + +static void +L_I16B(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in++) { + *out++ = 0; + *out++ = *in; + } +} + +static void +I16L_L(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 2) + if (in[1] != 0) + *out++ = 255; + else + *out++ = in[0]; +} + +static void +I16B_L(UINT8* out, const UINT8* in, int xsize) +{ + int x; + for (x = 0; x < xsize; x++, in += 2) + if (in[0] != 0) + *out++ = 255; + else + *out++ = in[1]; +} + +static struct { + const char* from; + const char* to; + ImagingShuffler convert; +} converters[] = { + + { "1", "L", bit2l }, + { "1", "I", bit2i }, + { "1", "F", bit2f }, + { "1", "RGB", bit2rgb }, + { "1", "RGBA", bit2rgb }, + { "1", "RGBX", bit2rgb }, + { "1", "CMYK", bit2cmyk }, + { "1", "YCbCr", bit2ycbcr }, + + { "L", "1", l2bit }, + { "L", "LA", l2la }, + { "L", "I", l2i }, + { "L", "F", l2f }, + { "L", "RGB", l2rgb }, + { "L", "RGBA", l2rgb }, + { "L", "RGBX", l2rgb }, + { "L", "CMYK", l2cmyk }, + { "L", "YCbCr", l2ycbcr }, + + { "LA", "L", la2l }, + { "LA", "RGB", la2rgb }, + { "LA", "RGBX", la2rgb }, + { "LA", "RGBA", la2rgb }, + + { "I", "L", i2l }, + { "I", "F", i2f }, + + { "F", "L", f2l }, + { "F", "I", f2i }, + + { "RGB", "1", rgb2bit }, + { "RGB", "L", rgb2l }, + { "RGB", "LA", rgb2la }, + { "RGB", "I", rgb2i }, + { "RGB", "F", rgb2f }, + { "RGB", "BGR;15", rgb2bgr15 }, + { "RGB", "BGR;16", rgb2bgr16 }, + { "RGB", "BGR;24", rgb2bgr24 }, + { "RGB", "RGBA", rgb2rgba }, + { "RGB", "RGBX", rgb2rgba }, + { "RGB", "CMYK", rgb2cmyk }, + { "RGB", "YCbCr", ImagingConvertRGB2YCbCr }, + + { "RGBA", "1", rgb2bit }, + { "RGBA", "L", rgb2l }, + { "RGBA", "LA", rgba2la }, + { "RGBA", "I", rgb2i }, + { "RGBA", "F", rgb2f }, + { "RGBA", "RGB", rgba2rgb }, + { "RGBA", "RGBa", rgba2rgba }, + { "RGBA", "RGBX", rgb2rgba }, + { "RGBA", "CMYK", rgb2cmyk }, + { "RGBA", "YCbCr", ImagingConvertRGB2YCbCr }, + + { "RGBX", "1", rgb2bit }, + { "RGBX", "L", rgb2l }, + { "RGBA", "I", rgb2i }, + { "RGBA", "F", rgb2f }, + { "RGBX", "RGB", rgba2rgb }, + { "RGBX", "CMYK", rgb2cmyk }, + { "RGBX", "YCbCr", ImagingConvertRGB2YCbCr }, + + { "CMYK", "RGB", cmyk2rgb }, + { "CMYK", "RGBA", cmyk2rgb }, + { "CMYK", "RGBX", cmyk2rgb }, + + { "YCbCr", "L", ycbcr2l }, + { "YCbCr", "RGB", ImagingConvertYCbCr2RGB }, + + { "I", "I;16", I_I16L }, + { "I;16", "I", I16L_I }, + { "L", "I;16", L_I16L }, + { "I;16", "L", I16L_L }, + + { "I", "I;16L", I_I16L }, + { "I;16L", "I", I16L_I }, + { "I", "I;16B", I_I16B }, + { "I;16B", "I", I16B_I }, + + { "L", "I;16L", L_I16L }, + { "I;16L", "L", I16L_L }, + { "L", "I;16B", L_I16B }, + { "I;16B", "L", I16B_L }, + + { NULL } +}; + +/* FIXME: translate indexed versions to pointer versions below this line */ + +/* ------------------- */ +/* Palette conversions */ +/* ------------------- */ + +static void +p2bit(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + /* FIXME: precalculate greyscale palette? */ + for (x = 0; x < xsize; x++) + *out++ = (L(&palette[in[x]*4]) >= 128000) ? 255 : 0; +} + +static void +p2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + /* FIXME: precalculate greyscale palette? */ + for (x = 0; x < xsize; x++) + *out++ = L(&palette[in[x]*4]) / 1000; +} + +static void +pa2la(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + /* FIXME: precalculate greyscale palette? */ + for (x = 0; x < xsize; x++, in += 2) { + *out++ = L(&palette[in[0]*4]) / 1000; + *out++ = in[1]; + } +} + +static void +p2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + INT32* out = (INT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = L(&palette[in[x]*4]) / 1000; +} + +static void +p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++) + *out++ = (float) L(&palette[in[x]*4]) / 1000.0F; +} + +static void +p2rgb(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + for (x = 0; x < xsize; x++) { + const UINT8* rgb = &palette[*in++ * 4]; + *out++ = rgb[0]; + *out++ = rgb[1]; + *out++ = rgb[2]; + *out++ = 255; + } +} + +static void +p2rgba(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + for (x = 0; x < xsize; x++) { + const UINT8* rgba = &palette[*in++ * 4]; + *out++ = rgba[0]; + *out++ = rgba[1]; + *out++ = rgba[2]; + *out++ = rgba[3]; + } +} + +static void +pa2rgba(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + int x; + for (x = 0; x < xsize; x++, in += 4) { + const UINT8* rgb = &palette[in[0] * 4]; + *out++ = rgb[0]; + *out++ = rgb[1]; + *out++ = rgb[2]; + *out++ = in[3]; + } +} + +static void +p2cmyk(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + p2rgb(out, in, xsize, palette); + rgb2cmyk(out, out, xsize); +} + +static void +p2ycbcr(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) +{ + p2rgb(out, in, xsize, palette); + ImagingConvertRGB2YCbCr(out, out, xsize); +} + +static Imaging +frompalette(Imaging imOut, Imaging imIn, const char *mode) +{ + ImagingSectionCookie cookie; + int alpha; + int y; + void (*convert)(UINT8*, const UINT8*, int, const UINT8*); + + /* Map palette image to L, RGB, RGBA, or CMYK */ + + if (!imIn->palette) + return (Imaging) ImagingError_ValueError("no palette"); + + alpha = !strcmp(imIn->mode, "PA"); + + if (strcmp(mode, "1") == 0) + convert = p2bit; + else if (strcmp(mode, "L") == 0) + convert = p2l; + else if (strcmp(mode, "LA") == 0) + convert = (alpha) ? pa2la : p2l; + else if (strcmp(mode, "I") == 0) + convert = p2i; + else if (strcmp(mode, "F") == 0) + convert = p2f; + else if (strcmp(mode, "RGB") == 0) + convert = p2rgb; + else if (strcmp(mode, "RGBA") == 0) + convert = (alpha) ? pa2rgba : p2rgba; + else if (strcmp(mode, "RGBX") == 0) + convert = p2rgba; + else if (strcmp(mode, "CMYK") == 0) + convert = p2cmyk; + else if (strcmp(mode, "YCbCr") == 0) + convert = p2ycbcr; + else + return (Imaging) ImagingError_ValueError("conversion not supported"); + + imOut = ImagingNew2(mode, imOut, imIn); + if (!imOut) + return NULL; + + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) + (*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], + imIn->xsize, imIn->palette->palette); + ImagingSectionLeave(&cookie); + + return imOut; +} + +static Imaging +topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) +{ + ImagingSectionCookie cookie; + int x, y; + ImagingPalette palette = inpalette;; + + /* Map L or RGB/RGBX/RGBA to palette image */ + if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) + return (Imaging) ImagingError_ValueError("conversion not supported"); + + if (palette == NULL) { + /* FIXME: make user configurable */ + if (imIn->bands == 1) + palette = ImagingPaletteNew("RGB"); /* Initialised to grey ramp */ + else + palette = ImagingPaletteNewBrowser(); /* Standard colour cube */ + } + + if (!palette) + return (Imaging) ImagingError_ValueError("no palette"); + + imOut = ImagingNew2("P", imOut, imIn); + if (!imOut) { + if (palette != inpalette) + ImagingPaletteDelete(palette); + return NULL; + } + + ImagingPaletteDelete(imOut->palette); + imOut->palette = ImagingPaletteDuplicate(palette); + + if (imIn->bands == 1) { + /* greyscale image */ + + /* Greyscale palette: copy data as is */ + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) + memcpy(imOut->image[y], imIn->image[y], imIn->linesize); + ImagingSectionLeave(&cookie); + + } else { + /* colour image */ + + /* Create mapping cache */ + if (ImagingPaletteCachePrepare(palette) < 0) { + ImagingDelete(imOut); + if (palette != inpalette) + ImagingPaletteDelete(palette); + return NULL; + } + + if (dither) { + /* floyd-steinberg dither */ + + int* errors; + errors = calloc(imIn->xsize + 1, sizeof(int) * 3); + if (!errors) { + ImagingDelete(imOut); + return ImagingError_MemoryError(); + } + + /* Map each pixel to the nearest palette entry */ + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + int r, r0, r1, r2; + int g, g0, g1, g2; + int b, b0, b1, b2; + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = imOut->image8[y]; + int* e = errors; + + r = r0 = r1 = 0; + g = g0 = g1 = 0; + b = b0 = b1 = b2 = 0; + + for (x = 0; x < imIn->xsize; x++, in += 4) { + int d2; + INT16* cache; + + r = CLIP(in[0] + (r + e[3+0])/16); + g = CLIP(in[1] + (g + e[3+1])/16); + b = CLIP(in[2] + (b + e[3+2])/16); + + /* get closest colour */ + cache = &ImagingPaletteCache(palette, r, g, b); + if (cache[0] == 0x100) + ImagingPaletteCacheUpdate(palette, r, g, b); + out[x] = (UINT8) cache[0]; + + r -= (int) palette->palette[cache[0]*4]; + g -= (int) palette->palette[cache[0]*4+1]; + b -= (int) palette->palette[cache[0]*4+2]; + + /* propagate errors (don't ask ;-) */ + r2 = r; d2 = r + r; r += d2; e[0] = r + r0; + r += d2; r0 = r + r1; r1 = r2; r += d2; + g2 = g; d2 = g + g; g += d2; e[1] = g + g0; + g += d2; g0 = g + g1; g1 = g2; g += d2; + b2 = b; d2 = b + b; b += d2; e[2] = b + b0; + b += d2; b0 = b + b1; b1 = b2; b += d2; + + e += 3; + + } + + e[0] = b0; + e[1] = b1; + e[2] = b2; + + } + ImagingSectionLeave(&cookie); + free(errors); + + } else { + + /* closest colour */ + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + int r, g, b; + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = imOut->image8[y]; + + for (x = 0; x < imIn->xsize; x++, in += 4) { + INT16* cache; + + r = in[0]; g = in[1]; b = in[2]; + + /* get closest colour */ + cache = &ImagingPaletteCache(palette, r, g, b); + if (cache[0] == 0x100) + ImagingPaletteCacheUpdate(palette, r, g, b); + out[x] = (UINT8) cache[0]; + + } + } + ImagingSectionLeave(&cookie); + + } + if (inpalette != palette) + ImagingPaletteCacheDelete(palette); + } + + if (inpalette != palette) + ImagingPaletteDelete(palette); + + return imOut; +} + +static Imaging +tobilevel(Imaging imOut, Imaging imIn, int dither) +{ + ImagingSectionCookie cookie; + int x, y; + int* errors; + + /* Map L or RGB to dithered 1 image */ + if (strcmp(imIn->mode, "L") != 0 && strcmp(imIn->mode, "RGB") != 0) + return (Imaging) ImagingError_ValueError("conversion not supported"); + + imOut = ImagingNew2("1", imOut, imIn); + if (!imOut) + return NULL; + + errors = calloc(imIn->xsize + 1, sizeof(int)); + if (!errors) { + ImagingDelete(imOut); + return ImagingError_MemoryError(); + } + + if (imIn->bands == 1) { + + /* map each pixel to black or white, using error diffusion */ + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + int l, l0, l1, l2, d2; + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = imOut->image8[y]; + + l = l0 = l1 = 0; + + for (x = 0; x < imIn->xsize; x++) { + + /* pick closest colour */ + l = CLIP(in[x] + (l + errors[x+1])/16); + out[x] = (l > 128) ? 255 : 0; + + /* propagate errors */ + l -= (int) out[x]; + l2 = l; d2 = l + l; l += d2; errors[x] = l + l0; + l += d2; l0 = l + l1; l1 = l2; l += d2; + } + + errors[x] = l0; + + } + ImagingSectionLeave(&cookie); + + } else { + + /* map each pixel to black or white, using error diffusion */ + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + int l, l0, l1, l2, d2; + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = imOut->image8[y]; + + l = l0 = l1 = 0; + + for (x = 0; x < imIn->xsize; x++, in += 4) { + + /* pick closest colour */ + l = CLIP(L(in)/1000 + (l + errors[x+1])/16); + out[x] = (l > 128) ? 255 : 0; + + /* propagate errors */ + l -= (int) out[x]; + l2 = l; d2 = l + l; l += d2; errors[x] = l + l0; + l += d2; l0 = l + l1; l1 = l2; l += d2; + + } + + errors[x] = l0; + + } + ImagingSectionLeave(&cookie); + } + + free(errors); + + return imOut; +} + + +static Imaging +convert(Imaging imOut, Imaging imIn, const char *mode, + ImagingPalette palette, int dither) +{ + ImagingSectionCookie cookie; + ImagingShuffler convert; + int y; + + if (!imIn) + return (Imaging) ImagingError_ModeError(); + + if (!mode) { + /* Map palette image to full depth */ + if (!imIn->palette) + return (Imaging) ImagingError_ModeError(); + mode = imIn->palette->mode; + } else + /* Same mode? */ + if (!strcmp(imIn->mode, mode)) + return ImagingCopy2(imOut, imIn); + + + /* test for special conversions */ + + if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) + return frompalette(imOut, imIn, mode); + + if (strcmp(mode, "P") == 0) + return topalette(imOut, imIn, palette, dither); + + if (dither && strcmp(mode, "1") == 0) + return tobilevel(imOut, imIn, dither); + + + /* standard conversion machinery */ + + convert = NULL; + + for (y = 0; converters[y].from; y++) + if (!strcmp(imIn->mode, converters[y].from) && + !strcmp(mode, converters[y].to)) { + convert = converters[y].convert; + break; + } + + if (!convert) +#ifdef notdef + return (Imaging) ImagingError_ValueError("conversion not supported"); +#else + { + static char buf[256]; + /* FIXME: may overflow if mode is too large */ + sprintf(buf, "conversion from %s to %s not supported", imIn->mode, mode); + return (Imaging) ImagingError_ValueError(buf); + } +#endif + + imOut = ImagingNew2(mode, imOut, imIn); + if (!imOut) + return NULL; + + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) + (*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], + imIn->xsize); + ImagingSectionLeave(&cookie); + + return imOut; +} + +Imaging +ImagingConvert(Imaging imIn, const char *mode, + ImagingPalette palette, int dither) +{ + return convert(NULL, imIn, mode, palette, dither); +} + +Imaging +ImagingConvert2(Imaging imOut, Imaging imIn) +{ + return convert(imOut, imIn, imOut->mode, NULL, 0); +} + +Imaging +ImagingConvertInPlace(Imaging imIn, const char* mode) +{ + ImagingSectionCookie cookie; + ImagingShuffler convert; + int y; + + /* limited support for inplace conversion */ + if (strcmp(imIn->mode, "L") == 0 && strcmp(mode, "1") == 0) + convert = l2bit; + else if (strcmp(imIn->mode, "1") == 0 && strcmp(mode, "L") == 0) + convert = bit2l; + else + return ImagingError_ModeError(); + + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) + (*convert)((UINT8*) imIn->image[y], (UINT8*) imIn->image[y], + imIn->xsize); + ImagingSectionLeave(&cookie); + + return imIn; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c new file mode 100755 index 00000000000..40cd01780d9 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c @@ -0,0 +1,387 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * code to convert YCbCr data + * + * history: + * 98-07-01 hk Created + * + * Copyright (c) Secret Labs AB 1998 + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +/* JPEG/JFIF YCbCr conversions + + Y = R * 0.29900 + G * 0.58700 + B * 0.11400 + Cb = R * -0.16874 + G * -0.33126 + B * 0.50000 + 128 + Cr = R * 0.50000 + G * -0.41869 + B * -0.08131 + 128 + + R = Y + + (Cr - 128) * 1.40200 + G = Y + (Cb - 128) * -0.34414 + (Cr - 128) * -0.71414 + B = Y + (Cb - 128) * 1.77200 + +*/ + +#define SCALE 6 /* bits */ + +static INT16 Y_R[] = { 0, 19, 38, 57, 77, 96, 115, 134, 153, 172, 191, +210, 230, 249, 268, 287, 306, 325, 344, 364, 383, 402, 421, 440, 459, +478, 498, 517, 536, 555, 574, 593, 612, 631, 651, 670, 689, 708, 727, +746, 765, 785, 804, 823, 842, 861, 880, 899, 919, 938, 957, 976, 995, +1014, 1033, 1052, 1072, 1091, 1110, 1129, 1148, 1167, 1186, 1206, +1225, 1244, 1263, 1282, 1301, 1320, 1340, 1359, 1378, 1397, 1416, +1435, 1454, 1473, 1493, 1512, 1531, 1550, 1569, 1588, 1607, 1627, +1646, 1665, 1684, 1703, 1722, 1741, 1761, 1780, 1799, 1818, 1837, +1856, 1875, 1894, 1914, 1933, 1952, 1971, 1990, 2009, 2028, 2048, +2067, 2086, 2105, 2124, 2143, 2162, 2182, 2201, 2220, 2239, 2258, +2277, 2296, 2315, 2335, 2354, 2373, 2392, 2411, 2430, 2449, 2469, +2488, 2507, 2526, 2545, 2564, 2583, 2602, 2622, 2641, 2660, 2679, +2698, 2717, 2736, 2756, 2775, 2794, 2813, 2832, 2851, 2870, 2890, +2909, 2928, 2947, 2966, 2985, 3004, 3023, 3043, 3062, 3081, 3100, +3119, 3138, 3157, 3177, 3196, 3215, 3234, 3253, 3272, 3291, 3311, +3330, 3349, 3368, 3387, 3406, 3425, 3444, 3464, 3483, 3502, 3521, +3540, 3559, 3578, 3598, 3617, 3636, 3655, 3674, 3693, 3712, 3732, +3751, 3770, 3789, 3808, 3827, 3846, 3865, 3885, 3904, 3923, 3942, +3961, 3980, 3999, 4019, 4038, 4057, 4076, 4095, 4114, 4133, 4153, +4172, 4191, 4210, 4229, 4248, 4267, 4286, 4306, 4325, 4344, 4363, +4382, 4401, 4420, 4440, 4459, 4478, 4497, 4516, 4535, 4554, 4574, +4593, 4612, 4631, 4650, 4669, 4688, 4707, 4727, 4746, 4765, 4784, +4803, 4822, 4841, 4861, 4880 }; + +static INT16 Y_G[] = { 0, 38, 75, 113, 150, 188, 225, 263, 301, 338, +376, 413, 451, 488, 526, 564, 601, 639, 676, 714, 751, 789, 826, 864, +902, 939, 977, 1014, 1052, 1089, 1127, 1165, 1202, 1240, 1277, 1315, +1352, 1390, 1428, 1465, 1503, 1540, 1578, 1615, 1653, 1691, 1728, +1766, 1803, 1841, 1878, 1916, 1954, 1991, 2029, 2066, 2104, 2141, +2179, 2217, 2254, 2292, 2329, 2367, 2404, 2442, 2479, 2517, 2555, +2592, 2630, 2667, 2705, 2742, 2780, 2818, 2855, 2893, 2930, 2968, +3005, 3043, 3081, 3118, 3156, 3193, 3231, 3268, 3306, 3344, 3381, +3419, 3456, 3494, 3531, 3569, 3607, 3644, 3682, 3719, 3757, 3794, +3832, 3870, 3907, 3945, 3982, 4020, 4057, 4095, 4132, 4170, 4208, +4245, 4283, 4320, 4358, 4395, 4433, 4471, 4508, 4546, 4583, 4621, +4658, 4696, 4734, 4771, 4809, 4846, 4884, 4921, 4959, 4997, 5034, +5072, 5109, 5147, 5184, 5222, 5260, 5297, 5335, 5372, 5410, 5447, +5485, 5522, 5560, 5598, 5635, 5673, 5710, 5748, 5785, 5823, 5861, +5898, 5936, 5973, 6011, 6048, 6086, 6124, 6161, 6199, 6236, 6274, +6311, 6349, 6387, 6424, 6462, 6499, 6537, 6574, 6612, 6650, 6687, +6725, 6762, 6800, 6837, 6875, 6913, 6950, 6988, 7025, 7063, 7100, +7138, 7175, 7213, 7251, 7288, 7326, 7363, 7401, 7438, 7476, 7514, +7551, 7589, 7626, 7664, 7701, 7739, 7777, 7814, 7852, 7889, 7927, +7964, 8002, 8040, 8077, 8115, 8152, 8190, 8227, 8265, 8303, 8340, +8378, 8415, 8453, 8490, 8528, 8566, 8603, 8641, 8678, 8716, 8753, +8791, 8828, 8866, 8904, 8941, 8979, 9016, 9054, 9091, 9129, 9167, +9204, 9242, 9279, 9317, 9354, 9392, 9430, 9467, 9505, 9542, 9580 }; + +static INT16 Y_B[] = { 0, 7, 15, 22, 29, 36, 44, 51, 58, 66, 73, 80, +88, 95, 102, 109, 117, 124, 131, 139, 146, 153, 161, 168, 175, 182, +190, 197, 204, 212, 219, 226, 233, 241, 248, 255, 263, 270, 277, 285, +292, 299, 306, 314, 321, 328, 336, 343, 350, 358, 365, 372, 379, 387, +394, 401, 409, 416, 423, 430, 438, 445, 452, 460, 467, 474, 482, 489, +496, 503, 511, 518, 525, 533, 540, 547, 554, 562, 569, 576, 584, 591, +598, 606, 613, 620, 627, 635, 642, 649, 657, 664, 671, 679, 686, 693, +700, 708, 715, 722, 730, 737, 744, 751, 759, 766, 773, 781, 788, 795, +803, 810, 817, 824, 832, 839, 846, 854, 861, 868, 876, 883, 890, 897, +905, 912, 919, 927, 934, 941, 948, 956, 963, 970, 978, 985, 992, 1000, +1007, 1014, 1021, 1029, 1036, 1043, 1051, 1058, 1065, 1073, 1080, +1087, 1094, 1102, 1109, 1116, 1124, 1131, 1138, 1145, 1153, 1160, +1167, 1175, 1182, 1189, 1197, 1204, 1211, 1218, 1226, 1233, 1240, +1248, 1255, 1262, 1270, 1277, 1284, 1291, 1299, 1306, 1313, 1321, +1328, 1335, 1342, 1350, 1357, 1364, 1372, 1379, 1386, 1394, 1401, +1408, 1415, 1423, 1430, 1437, 1445, 1452, 1459, 1466, 1474, 1481, +1488, 1496, 1503, 1510, 1518, 1525, 1532, 1539, 1547, 1554, 1561, +1569, 1576, 1583, 1591, 1598, 1605, 1612, 1620, 1627, 1634, 1642, +1649, 1656, 1663, 1671, 1678, 1685, 1693, 1700, 1707, 1715, 1722, +1729, 1736, 1744, 1751, 1758, 1766, 1773, 1780, 1788, 1795, 1802, +1809, 1817, 1824, 1831, 1839, 1846, 1853, 1860 }; + +static INT16 Cb_R[] = { 0, -10, -21, -31, -42, -53, -64, -75, -85, +-96, -107, -118, -129, -139, -150, -161, -172, -183, -193, -204, -215, +-226, -237, -247, -258, -269, -280, -291, -301, -312, -323, -334, +-345, -355, -366, -377, -388, -399, -409, -420, -431, -442, -453, +-463, -474, -485, -496, -507, -517, -528, -539, -550, -561, -571, +-582, -593, -604, -615, -625, -636, -647, -658, -669, -679, -690, +-701, -712, -723, -733, -744, -755, -766, -777, -787, -798, -809, +-820, -831, -841, -852, -863, -874, -885, -895, -906, -917, -928, +-939, -949, -960, -971, -982, -993, -1003, -1014, -1025, -1036, -1047, +-1057, -1068, -1079, -1090, -1101, -1111, -1122, -1133, -1144, -1155, +-1165, -1176, -1187, -1198, -1209, -1219, -1230, -1241, -1252, -1263, +-1273, -1284, -1295, -1306, -1317, -1327, -1338, -1349, -1360, -1371, +-1381, -1392, -1403, -1414, -1425, -1435, -1446, -1457, -1468, -1479, +-1489, -1500, -1511, -1522, -1533, -1543, -1554, -1565, -1576, -1587, +-1597, -1608, -1619, -1630, -1641, -1651, -1662, -1673, -1684, -1694, +-1705, -1716, -1727, -1738, -1748, -1759, -1770, -1781, -1792, -1802, +-1813, -1824, -1835, -1846, -1856, -1867, -1878, -1889, -1900, -1910, +-1921, -1932, -1943, -1954, -1964, -1975, -1986, -1997, -2008, -2018, +-2029, -2040, -2051, -2062, -2072, -2083, -2094, -2105, -2116, -2126, +-2137, -2148, -2159, -2170, -2180, -2191, -2202, -2213, -2224, -2234, +-2245, -2256, -2267, -2278, -2288, -2299, -2310, -2321, -2332, -2342, +-2353, -2364, -2375, -2386, -2396, -2407, -2418, -2429, -2440, -2450, +-2461, -2472, -2483, -2494, -2504, -2515, -2526, -2537, -2548, -2558, +-2569, -2580, -2591, -2602, -2612, -2623, -2634, -2645, -2656, -2666, +-2677, -2688, -2699, -2710, -2720, -2731, -2742, -2753 }; + +static INT16 Cb_G[] = { 0, -20, -41, -63, -84, -105, -126, -147, -169, +-190, -211, -232, -253, -275, -296, -317, -338, -359, -381, -402, +-423, -444, -465, -487, -508, -529, -550, -571, -593, -614, -635, +-656, -677, -699, -720, -741, -762, -783, -805, -826, -847, -868, +-889, -911, -932, -953, -974, -995, -1017, -1038, -1059, -1080, -1101, +-1123, -1144, -1165, -1186, -1207, -1229, -1250, -1271, -1292, -1313, +-1335, -1356, -1377, -1398, -1419, -1441, -1462, -1483, -1504, -1525, +-1547, -1568, -1589, -1610, -1631, -1653, -1674, -1695, -1716, -1737, +-1759, -1780, -1801, -1822, -1843, -1865, -1886, -1907, -1928, -1949, +-1971, -1992, -2013, -2034, -2055, -2077, -2098, -2119, -2140, -2161, +-2183, -2204, -2225, -2246, -2267, -2289, -2310, -2331, -2352, -2373, +-2395, -2416, -2437, -2458, -2479, -2501, -2522, -2543, -2564, -2585, +-2607, -2628, -2649, -2670, -2691, -2713, -2734, -2755, -2776, -2797, +-2819, -2840, -2861, -2882, -2903, -2925, -2946, -2967, -2988, -3009, +-3031, -3052, -3073, -3094, -3115, -3137, -3158, -3179, -3200, -3221, +-3243, -3264, -3285, -3306, -3328, -3349, -3370, -3391, -3412, -3434, +-3455, -3476, -3497, -3518, -3540, -3561, -3582, -3603, -3624, -3646, +-3667, -3688, -3709, -3730, -3752, -3773, -3794, -3815, -3836, -3858, +-3879, -3900, -3921, -3942, -3964, -3985, -4006, -4027, -4048, -4070, +-4091, -4112, -4133, -4154, -4176, -4197, -4218, -4239, -4260, -4282, +-4303, -4324, -4345, -4366, -4388, -4409, -4430, -4451, -4472, -4494, +-4515, -4536, -4557, -4578, -4600, -4621, -4642, -4663, -4684, -4706, +-4727, -4748, -4769, -4790, -4812, -4833, -4854, -4875, -4896, -4918, +-4939, -4960, -4981, -5002, -5024, -5045, -5066, -5087, -5108, -5130, +-5151, -5172, -5193, -5214, -5236, -5257, -5278, -5299, -5320, -5342, +-5363, -5384, -5405 }; + +static INT16 Cb_B[] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, +320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736, +768, 800, 832, 864, 896, 928, 960, 992, 1024, 1056, 1088, 1120, 1152, +1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504, +1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856, +1888, 1920, 1952, 1984, 2016, 2048, 2080, 2112, 2144, 2176, 2208, +2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464, 2496, 2528, 2560, +2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848, 2880, 2912, +2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232, 3264, +3296, 3328, 3360, 3392, 3424, 3456, 3488, 3520, 3552, 3584, 3616, +3648, 3680, 3712, 3744, 3776, 3808, 3840, 3872, 3904, 3936, 3968, +4000, 4032, 4064, 4096, 4128, 4160, 4192, 4224, 4256, 4288, 4320, +4352, 4384, 4416, 4448, 4480, 4512, 4544, 4576, 4608, 4640, 4672, +4704, 4736, 4768, 4800, 4832, 4864, 4896, 4928, 4960, 4992, 5024, +5056, 5088, 5120, 5152, 5184, 5216, 5248, 5280, 5312, 5344, 5376, +5408, 5440, 5472, 5504, 5536, 5568, 5600, 5632, 5664, 5696, 5728, +5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, +6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, +6464, 6496, 6528, 6560, 6592, 6624, 6656, 6688, 6720, 6752, 6784, +6816, 6848, 6880, 6912, 6944, 6976, 7008, 7040, 7072, 7104, 7136, +7168, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488, +7520, 7552, 7584, 7616, 7648, 7680, 7712, 7744, 7776, 7808, 7840, +7872, 7904, 7936, 7968, 8000, 8032, 8064, 8096, 8128, 8160 }; + +#define Cr_R Cb_B + +static INT16 Cr_G[] = { 0, -26, -53, -79, -106, -133, -160, -187, +-213, -240, -267, -294, -321, -347, -374, -401, -428, -455, -481, +-508, -535, -562, -589, -615, -642, -669, -696, -722, -749, -776, +-803, -830, -856, -883, -910, -937, -964, -990, -1017, -1044, -1071, +-1098, -1124, -1151, -1178, -1205, -1232, -1258, -1285, -1312, -1339, +-1366, -1392, -1419, -1446, -1473, -1500, -1526, -1553, -1580, -1607, +-1634, -1660, -1687, -1714, -1741, -1768, -1794, -1821, -1848, -1875, +-1902, -1928, -1955, -1982, -2009, -2036, -2062, -2089, -2116, -2143, +-2169, -2196, -2223, -2250, -2277, -2303, -2330, -2357, -2384, -2411, +-2437, -2464, -2491, -2518, -2545, -2571, -2598, -2625, -2652, -2679, +-2705, -2732, -2759, -2786, -2813, -2839, -2866, -2893, -2920, -2947, +-2973, -3000, -3027, -3054, -3081, -3107, -3134, -3161, -3188, -3215, +-3241, -3268, -3295, -3322, -3349, -3375, -3402, -3429, -3456, -3483, +-3509, -3536, -3563, -3590, -3616, -3643, -3670, -3697, -3724, -3750, +-3777, -3804, -3831, -3858, -3884, -3911, -3938, -3965, -3992, -4018, +-4045, -4072, -4099, -4126, -4152, -4179, -4206, -4233, -4260, -4286, +-4313, -4340, -4367, -4394, -4420, -4447, -4474, -4501, -4528, -4554, +-4581, -4608, -4635, -4662, -4688, -4715, -4742, -4769, -4796, -4822, +-4849, -4876, -4903, -4929, -4956, -4983, -5010, -5037, -5063, -5090, +-5117, -5144, -5171, -5197, -5224, -5251, -5278, -5305, -5331, -5358, +-5385, -5412, -5439, -5465, -5492, -5519, -5546, -5573, -5599, -5626, +-5653, -5680, -5707, -5733, -5760, -5787, -5814, -5841, -5867, -5894, +-5921, -5948, -5975, -6001, -6028, -6055, -6082, -6109, -6135, -6162, +-6189, -6216, -6243, -6269, -6296, -6323, -6350, -6376, -6403, -6430, +-6457, -6484, -6510, -6537, -6564, -6591, -6618, -6644, -6671, -6698, +-6725, -6752, -6778, -6805, -6832 }; + +static INT16 Cr_B[] = { 0, -4, -9, -15, -20, -25, -30, -35, -41, -46, +-51, -56, -61, -67, -72, -77, -82, -87, -93, -98, -103, -108, -113, +-119, -124, -129, -134, -140, -145, -150, -155, -160, -166, -171, +-176, -181, -186, -192, -197, -202, -207, -212, -218, -223, -228, +-233, -238, -244, -249, -254, -259, -264, -270, -275, -280, -285, +-290, -296, -301, -306, -311, -316, -322, -327, -332, -337, -342, +-348, -353, -358, -363, -368, -374, -379, -384, -389, -394, -400, +-405, -410, -415, -421, -426, -431, -436, -441, -447, -452, -457, +-462, -467, -473, -478, -483, -488, -493, -499, -504, -509, -514, +-519, -525, -530, -535, -540, -545, -551, -556, -561, -566, -571, +-577, -582, -587, -592, -597, -603, -608, -613, -618, -623, -629, +-634, -639, -644, -649, -655, -660, -665, -670, -675, -681, -686, +-691, -696, -702, -707, -712, -717, -722, -728, -733, -738, -743, +-748, -754, -759, -764, -769, -774, -780, -785, -790, -795, -800, +-806, -811, -816, -821, -826, -832, -837, -842, -847, -852, -858, +-863, -868, -873, -878, -884, -889, -894, -899, -904, -910, -915, +-920, -925, -930, -936, -941, -946, -951, -957, -962, -967, -972, +-977, -983, -988, -993, -998, -1003, -1009, -1014, -1019, -1024, +-1029, -1035, -1040, -1045, -1050, -1055, -1061, -1066, -1071, -1076, +-1081, -1087, -1092, -1097, -1102, -1107, -1113, -1118, -1123, -1128, +-1133, -1139, -1144, -1149, -1154, -1159, -1165, -1170, -1175, -1180, +-1185, -1191, -1196, -1201, -1206, -1211, -1217, -1222, -1227, -1232, +-1238, -1243, -1248, -1253, -1258, -1264, -1269, -1274, -1279, -1284, +-1290, -1295, -1300, -1305, -1310, -1316, -1321, -1326 }; + +static INT16 R_Cr[] = { -11484, -11394, -11305, -11215, -11125, +-11036, -10946, -10856, -10766, -10677, -10587, -10497, -10407, +-10318, -10228, -10138, -10049, -9959, -9869, -9779, -9690, -9600, +-9510, -9420, -9331, -9241, -9151, -9062, -8972, -8882, -8792, -8703, +-8613, -8523, -8433, -8344, -8254, -8164, -8075, -7985, -7895, -7805, +-7716, -7626, -7536, -7446, -7357, -7267, -7177, -7088, -6998, -6908, +-6818, -6729, -6639, -6549, -6459, -6370, -6280, -6190, -6101, -6011, +-5921, -5831, -5742, -5652, -5562, -5472, -5383, -5293, -5203, -5113, +-5024, -4934, -4844, -4755, -4665, -4575, -4485, -4396, -4306, -4216, +-4126, -4037, -3947, -3857, -3768, -3678, -3588, -3498, -3409, -3319, +-3229, -3139, -3050, -2960, -2870, -2781, -2691, -2601, -2511, -2422, +-2332, -2242, -2152, -2063, -1973, -1883, -1794, -1704, -1614, -1524, +-1435, -1345, -1255, -1165, -1076, -986, -896, -807, -717, -627, -537, +-448, -358, -268, -178, -89, 0, 90, 179, 269, 359, 449, 538, 628, 718, +808, 897, 987, 1077, 1166, 1256, 1346, 1436, 1525, 1615, 1705, 1795, +1884, 1974, 2064, 2153, 2243, 2333, 2423, 2512, 2602, 2692, 2782, +2871, 2961, 3051, 3140, 3230, 3320, 3410, 3499, 3589, 3679, 3769, +3858, 3948, 4038, 4127, 4217, 4307, 4397, 4486, 4576, 4666, 4756, +4845, 4935, 5025, 5114, 5204, 5294, 5384, 5473, 5563, 5653, 5743, +5832, 5922, 6012, 6102, 6191, 6281, 6371, 6460, 6550, 6640, 6730, +6819, 6909, 6999, 7089, 7178, 7268, 7358, 7447, 7537, 7627, 7717, +7806, 7896, 7986, 8076, 8165, 8255, 8345, 8434, 8524, 8614, 8704, +8793, 8883, 8973, 9063, 9152, 9242, 9332, 9421, 9511, 9601, 9691, +9780, 9870, 9960, 10050, 10139, 10229, 10319, 10408, 10498, 10588, +10678, 10767, 10857, 10947, 11037, 11126, 11216, 11306, 11395 }; + +static INT16 G_Cb[] = { 2819, 2797, 2775, 2753, 2731, 2709, 2687, +2665, 2643, 2621, 2599, 2577, 2555, 2533, 2511, 2489, 2467, 2445, +2423, 2401, 2379, 2357, 2335, 2313, 2291, 2269, 2247, 2225, 2202, +2180, 2158, 2136, 2114, 2092, 2070, 2048, 2026, 2004, 1982, 1960, +1938, 1916, 1894, 1872, 1850, 1828, 1806, 1784, 1762, 1740, 1718, +1696, 1674, 1652, 1630, 1608, 1586, 1564, 1542, 1520, 1498, 1476, +1454, 1432, 1410, 1388, 1366, 1344, 1321, 1299, 1277, 1255, 1233, +1211, 1189, 1167, 1145, 1123, 1101, 1079, 1057, 1035, 1013, 991, 969, +947, 925, 903, 881, 859, 837, 815, 793, 771, 749, 727, 705, 683, 661, +639, 617, 595, 573, 551, 529, 507, 485, 463, 440, 418, 396, 374, 352, +330, 308, 286, 264, 242, 220, 198, 176, 154, 132, 110, 88, 66, 44, 22, +0, -21, -43, -65, -87, -109, -131, -153, -175, -197, -219, -241, -263, +-285, -307, -329, -351, -373, -395, -417, -439, -462, -484, -506, +-528, -550, -572, -594, -616, -638, -660, -682, -704, -726, -748, +-770, -792, -814, -836, -858, -880, -902, -924, -946, -968, -990, +-1012, -1034, -1056, -1078, -1100, -1122, -1144, -1166, -1188, -1210, +-1232, -1254, -1276, -1298, -1320, -1343, -1365, -1387, -1409, -1431, +-1453, -1475, -1497, -1519, -1541, -1563, -1585, -1607, -1629, -1651, +-1673, -1695, -1717, -1739, -1761, -1783, -1805, -1827, -1849, -1871, +-1893, -1915, -1937, -1959, -1981, -2003, -2025, -2047, -2069, -2091, +-2113, -2135, -2157, -2179, -2201, -2224, -2246, -2268, -2290, -2312, +-2334, -2356, -2378, -2400, -2422, -2444, -2466, -2488, -2510, -2532, +-2554, -2576, -2598, -2620, -2642, -2664, -2686, -2708, -2730, -2752, +-2774, -2796 }; + +static INT16 G_Cr[] = { 5850, 5805, 5759, 5713, 5667, 5622, 5576, +5530, 5485, 5439, 5393, 5347, 5302, 5256, 5210, 5165, 5119, 5073, +5028, 4982, 4936, 4890, 4845, 4799, 4753, 4708, 4662, 4616, 4570, +4525, 4479, 4433, 4388, 4342, 4296, 4251, 4205, 4159, 4113, 4068, +4022, 3976, 3931, 3885, 3839, 3794, 3748, 3702, 3656, 3611, 3565, +3519, 3474, 3428, 3382, 3336, 3291, 3245, 3199, 3154, 3108, 3062, +3017, 2971, 2925, 2879, 2834, 2788, 2742, 2697, 2651, 2605, 2559, +2514, 2468, 2422, 2377, 2331, 2285, 2240, 2194, 2148, 2102, 2057, +2011, 1965, 1920, 1874, 1828, 1782, 1737, 1691, 1645, 1600, 1554, +1508, 1463, 1417, 1371, 1325, 1280, 1234, 1188, 1143, 1097, 1051, +1006, 960, 914, 868, 823, 777, 731, 686, 640, 594, 548, 503, 457, 411, +366, 320, 274, 229, 183, 137, 91, 46, 0, -45, -90, -136, -182, -228, +-273, -319, -365, -410, -456, -502, -547, -593, -639, -685, -730, +-776, -822, -867, -913, -959, -1005, -1050, -1096, -1142, -1187, +-1233, -1279, -1324, -1370, -1416, -1462, -1507, -1553, -1599, -1644, +-1690, -1736, -1781, -1827, -1873, -1919, -1964, -2010, -2056, -2101, +-2147, -2193, -2239, -2284, -2330, -2376, -2421, -2467, -2513, -2558, +-2604, -2650, -2696, -2741, -2787, -2833, -2878, -2924, -2970, -3016, +-3061, -3107, -3153, -3198, -3244, -3290, -3335, -3381, -3427, -3473, +-3518, -3564, -3610, -3655, -3701, -3747, -3793, -3838, -3884, -3930, +-3975, -4021, -4067, -4112, -4158, -4204, -4250, -4295, -4341, -4387, +-4432, -4478, -4524, -4569, -4615, -4661, -4707, -4752, -4798, -4844, +-4889, -4935, -4981, -5027, -5072, -5118, -5164, -5209, -5255, -5301, +-5346, -5392, -5438, -5484, -5529, -5575, -5621, -5666, -5712, -5758, +-5804 }; + +static INT16 B_Cb[] = { -14515, -14402, -14288, -14175, -14062, +-13948, -13835, -13721, -13608, -13495, -13381, -13268, -13154, +-13041, -12928, -12814, -12701, -12587, -12474, -12360, -12247, +-12134, -12020, -11907, -11793, -11680, -11567, -11453, -11340, +-11226, -11113, -11000, -10886, -10773, -10659, -10546, -10433, +-10319, -10206, -10092, -9979, -9865, -9752, -9639, -9525, -9412, +-9298, -9185, -9072, -8958, -8845, -8731, -8618, -8505, -8391, -8278, +-8164, -8051, -7938, -7824, -7711, -7597, -7484, -7371, -7257, -7144, +-7030, -6917, -6803, -6690, -6577, -6463, -6350, -6236, -6123, -6010, +-5896, -5783, -5669, -5556, -5443, -5329, -5216, -5102, -4989, -4876, +-4762, -4649, -4535, -4422, -4309, -4195, -4082, -3968, -3855, -3741, +-3628, -3515, -3401, -3288, -3174, -3061, -2948, -2834, -2721, -2607, +-2494, -2381, -2267, -2154, -2040, -1927, -1814, -1700, -1587, -1473, +-1360, -1246, -1133, -1020, -906, -793, -679, -566, -453, -339, -226, +-112, 0, 113, 227, 340, 454, 567, 680, 794, 907, 1021, 1134, 1247, +1361, 1474, 1588, 1701, 1815, 1928, 2041, 2155, 2268, 2382, 2495, +2608, 2722, 2835, 2949, 3062, 3175, 3289, 3402, 3516, 3629, 3742, +3856, 3969, 4083, 4196, 4310, 4423, 4536, 4650, 4763, 4877, 4990, +5103, 5217, 5330, 5444, 5557, 5670, 5784, 5897, 6011, 6124, 6237, +6351, 6464, 6578, 6691, 6804, 6918, 7031, 7145, 7258, 7372, 7485, +7598, 7712, 7825, 7939, 8052, 8165, 8279, 8392, 8506, 8619, 8732, +8846, 8959, 9073, 9186, 9299, 9413, 9526, 9640, 9753, 9866, 9980, +10093, 10207, 10320, 10434, 10547, 10660, 10774, 10887, 11001, 11114, +11227, 11341, 11454, 11568, 11681, 11794, 11908, 12021, 12135, 12248, +12361, 12475, 12588, 12702, 12815, 12929, 13042, 13155, 13269, 13382, +13496, 13609, 13722, 13836, 13949, 14063, 14176, 14289, 14403 }; + + +void +ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels) +{ + int x; + UINT8 a; + int r, g, b; + int y, cr, cb; + + for (x = 0; x < pixels; x++, in +=4, out += 4) { + + r = in[0]; + g = in[1]; + b = in[2]; + a = in[3]; + + y = (Y_R[r] + Y_G[g] + Y_B[b]) >> SCALE; + cb = ((Cb_R[r] + Cb_G[g] + Cb_B[b]) >> SCALE) + 128; + cr = ((Cr_R[r] + Cr_G[g] + Cr_B[b]) >> SCALE) + 128; + + out[0] = (UINT8) y; + out[1] = (UINT8) cb; + out[2] = (UINT8) cr; + out[3] = a; + } +} + +void +ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels) +{ + int x; + UINT8 a; + int r, g, b; + int y, cr, cb; + + for (x = 0; x < pixels; x++, in += 4, out += 4) { + + y = in[0]; + cb = in[1]; + cr = in[2]; + a = in[3]; + + r = y + (( R_Cr[cr]) >> SCALE); + g = y + ((G_Cb[cb] + G_Cr[cr]) >> SCALE); + b = y + ((B_Cb[cb] ) >> SCALE); + + out[0] = (r <= 0) ? 0 : (r >= 255) ? 255 : r; + out[1] = (g <= 0) ? 0 : (g >= 255) ? 255 : g; + out[2] = (b <= 0) ? 0 : (b >= 255) ? 255 : b; + out[3] = a; + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c new file mode 100755 index 00000000000..4a1fc248974 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c @@ -0,0 +1,58 @@ +/* + * The Python Imaging Library + * $Id$ + * + * copy image + * + * history: + * 95-11-26 fl Moved from Imaging.c + * 97-05-12 fl Added ImagingCopy2 + * 97-08-28 fl Allow imOut == NULL in ImagingCopy2 + * + * Copyright (c) Fredrik Lundh 1995-97. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + + +static Imaging +_copy(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int y; + + if (!imIn) + return (Imaging) ImagingError_ValueError(NULL); + + imOut = ImagingNew2(imIn->mode, imOut, imIn); + if (!imOut) + return NULL; + + ImagingCopyInfo(imOut, imIn); + + ImagingSectionEnter(&cookie); + if (imIn->block != NULL && imOut->block != NULL) + memcpy(imOut->block, imIn->block, imIn->ysize * imIn->linesize); + else + for (y = 0; y < imIn->ysize; y++) + memcpy(imOut->image[y], imIn->image[y], imIn->linesize); + ImagingSectionLeave(&cookie); + + return imOut; +} + +Imaging +ImagingCopy(Imaging imIn) +{ + return _copy(NULL, imIn); +} + +Imaging +ImagingCopy2(Imaging imOut, Imaging imIn) +{ + return _copy(imOut, imIn); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c new file mode 100755 index 00000000000..d83d0fbacb0 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c @@ -0,0 +1,87 @@ +/* + * The Python Imaging Library + * $Id$ + * + * calculate ISO 3307 checksum + * + * history: + * 96-12-10 fl: Created (based on example in the PNG spec) + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +/* Precalculated CRC values (created by makecrctable.py) */ + +static UINT32 crc32table[] = { 0x0, 0x77073096L, 0xEE0E612CL, +0x990951BAL, 0x76DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, +0xEDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 0x9B64C2BL, +0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, +0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, +0x83D385C7L, 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, +0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L, +0x4C69105EL, 0xD56041E4L, 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, +0xD20D85FDL, 0xA50AB56BL, 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, +0xACBCF940L, 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, +0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, 0x21B4F4B5L, +0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, 0x2802B89EL, 0x5F058808L, +0xC60CD9B2L, 0xB10BE924L, 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, +0xB6662D3DL, 0x76DC4190L, 0x1DB7106L, 0x98D220BCL, 0xEFD5102AL, +0x71B18589L, 0x6B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, 0x7807C9A2L, +0xF00F934L, 0x9609A88EL, 0xE10E9818L, 0x7F6A0DBBL, 0x86D3D2DL, +0x91646C97L, 0xE6635C01L, 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, +0xF262004EL, 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, +0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL, +0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, 0x4DB26158L, 0x3AB551CEL, +0xA3BC0074L, 0xD4BB30E2L, 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, +0xD3D6F4FBL, 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, +0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, 0x5005713CL, +0x270241AAL, 0xBE0B1010L, 0xC90C2086L, 0x5768B525L, 0x206F85B3L, +0xB966D409L, 0xCE61E49FL, 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, +0xC7D7A8B4L, 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, +0xEDB88320L, 0x9ABFB3B6L, 0x3B6E20CL, 0x74B1D29AL, 0xEAD54739L, +0x9DD277AFL, 0x4DB2615L, 0x73DC1683L, 0xE3630B12L, 0x94643B84L, +0xD6D6A3EL, 0x7A6A5AA8L, 0xE40ECF0BL, 0x9309FF9DL, 0xA00AE27L, +0x7D079EB1L, 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, +0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, 0xFED41B76L, +0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, 0xF9B9DF6FL, 0x8EBEEFF9L, +0x17B7BE43L, 0x60B08ED5L, 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, +0x4FDFF252L, 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, +0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, 0xDF60EFC3L, +0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, 0xCB61B38CL, 0xBC66831AL, +0x256FD2A0L, 0x5268E236L, 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, +0x5505262FL, 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, +0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, 0x9B64C2B0L, +0xEC63F226L, 0x756AA39CL, 0x26D930AL, 0x9C0906A9L, 0xEB0E363FL, +0x72076785L, 0x5005713L, 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, +0xCB61B38L, 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0xBDBDF21L, +0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL, +0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, 0x88085AE6L, 0xFF0F6A70L, +0x66063BCAL, 0x11010B5CL, 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, +0x166CCF45L, 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, +0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, 0xAED16A4AL, +0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, 0xA9BCAE53L, 0xDEBB9EC5L, +0x47B2CF7FL, 0x30B5FFE9L, 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, +0x24B4A3A6L, 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, +0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, +0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL }; + + +UINT32 +ImagingCRC32(UINT32 crc, UINT8* buffer, int bytes) +{ + int i; + + crc ^= 0xFFFFFFFFL; + + for (i = 0; i < bytes; i++) + crc = crc32table[(UINT8) crc ^ buffer[i]] ^ (crc >> 8); + + return crc ^ 0xFFFFFFFFL; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c new file mode 100755 index 00000000000..5acacd4c47c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c @@ -0,0 +1,61 @@ +/* + * The Python Imaging Library + * $Id$ + * + * cut region from image + * + * history: + * 95-11-27 fl Created + * 98-07-10 fl Fixed "null result" error + * 99-02-05 fl Rewritten to use Paste primitive + * + * Copyright (c) Secret Labs AB 1997-99. + * Copyright (c) Fredrik Lundh 1995. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +Imaging +ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1) +{ + Imaging imOut; + int xsize, ysize; + int dx0, dy0, dx1, dy1; + INT32 zero = 0; + + if (!imIn) + return (Imaging) ImagingError_ModeError(); + + xsize = sx1 - sx0; + if (xsize < 0) + xsize = 0; + ysize = sy1 - sy0; + if (ysize < 0) + ysize = 0; + + imOut = ImagingNew(imIn->mode, xsize, ysize); + if (!imOut) + return NULL; + + ImagingCopyInfo(imOut, imIn); + + if (sx0 < 0 || sy0 < 0 || sx1 > imIn->xsize || sy1 > imIn->ysize) + (void) ImagingFill(imOut, &zero); + + dx0 = -sx0; + dy0 = -sy0; + dx1 = imIn->xsize - sx0; + dy1 = imIn->ysize - sy0; + + /* paste the source image on top of the output image!!! */ + if (ImagingPaste(imOut, imIn, NULL, dx0, dy0, dx1, dy1) < 0) { + ImagingDelete(imOut); + return NULL; + } + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c new file mode 100755 index 00000000000..36dc24ef3ac --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c @@ -0,0 +1,311 @@ +/* + * The Python Imaging Library + * $Id$ + * + * imaging display object for Windows + * + * history: + * 1996-05-12 fl Created + * 1996-05-17 fl Up and running + * 1996-05-21 fl Added palette stuff + * 1996-05-26 fl Added query palette and mode inquery + * 1997-09-21 fl Added draw primitive + * 1998-01-20 fl Use StretchDIBits instead of StretchBlt + * 1998-12-30 fl Plugged a resource leak in DeleteDIB (from Roger Burnham) + * + * Copyright (c) Secret Labs AB 1997-2001. + * Copyright (c) Fredrik Lundh 1996. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#ifdef WIN32 + +#include "ImDib.h" + + +char* +ImagingGetModeDIB(int size_out[2]) +{ + /* Get device characteristics */ + + HDC dc; + char* mode; + + dc = CreateCompatibleDC(NULL); + + mode = "P"; + if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) { + mode = "RGB"; + if (GetDeviceCaps(dc, BITSPIXEL) == 1) + mode = "1"; + } + + if (size_out) { + size_out[0] = GetDeviceCaps(dc, HORZRES); + size_out[1] = GetDeviceCaps(dc, VERTRES); + } + + DeleteDC(dc); + + return mode; +} + + +ImagingDIB +ImagingNewDIB(const char *mode, int xsize, int ysize) +{ + /* Create a Windows bitmap */ + + ImagingDIB dib; + RGBQUAD *palette; + int i; + + /* Check mode */ + if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 && + strcmp(mode, "RGB") != 0) + return (ImagingDIB) ImagingError_ModeError(); + + /* Create DIB context and info header */ + dib = (ImagingDIB) malloc(sizeof(*dib)); + if (!dib) + return (ImagingDIB) ImagingError_MemoryError(); + dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + + 256 * sizeof(RGBQUAD)); + if (!dib->info) { + free(dib); + return (ImagingDIB) ImagingError_MemoryError(); + } + + memset(dib->info, 0, sizeof(BITMAPINFOHEADER)); + dib->info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dib->info->bmiHeader.biWidth = xsize; + dib->info->bmiHeader.biHeight = ysize; + dib->info->bmiHeader.biPlanes = 1; + dib->info->bmiHeader.biBitCount = strlen(mode)*8; + dib->info->bmiHeader.biCompression = BI_RGB; + + /* Create DIB */ + dib->dc = CreateCompatibleDC(NULL); + if (!dib->dc) { + free(dib->info); + free(dib); + return (ImagingDIB) ImagingError_MemoryError(); + } + + dib->bitmap = CreateDIBSection(dib->dc, dib->info, DIB_RGB_COLORS, + &dib->bits, NULL, 0); + if (!dib->bitmap) { + free(dib->info); + free(dib); + return (ImagingDIB) ImagingError_MemoryError(); + } + + strcpy(dib->mode, mode); + dib->xsize = xsize; + dib->ysize = ysize; + + dib->pixelsize = strlen(mode); + dib->linesize = (xsize * dib->pixelsize + 3) & -4; + + if (dib->pixelsize == 1) + dib->pack = dib->unpack = (ImagingShuffler) memcpy; + else { + dib->pack = ImagingPackBGR; + dib->unpack = ImagingPackBGR; + } + + /* Bind the DIB to the device context */ + dib->old_bitmap = SelectObject(dib->dc, dib->bitmap); + + palette = dib->info->bmiColors; + + /* Bind a palette to it as well (only required for 8-bit DIBs) */ + if (dib->pixelsize == 1) { + for (i = 0; i < 256; i++) { + palette[i].rgbRed = + palette[i].rgbGreen = + palette[i].rgbBlue = i; + palette[i].rgbReserved = 0; + } + SetDIBColorTable(dib->dc, 0, 256, palette); + } + + /* Create an associated palette (for 8-bit displays only) */ + if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) { + + char palbuf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)]; + LPLOGPALETTE pal = (LPLOGPALETTE) palbuf; + int i, r, g, b; + + /* Load system palette */ + pal->palVersion = 0x300; + pal->palNumEntries = 256; + GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry); + + if (strcmp(mode, "L") == 0) { + + /* Greyscale DIB. Fill all 236 slots with a greyscale ramp + * (this is usually overkill on Windows since VGA only offers + * 6 bits greyscale resolution). Ignore the slots already + * allocated by Windows */ + + i = 10; + for (r = 0; r < 236; r++) { + pal->palPalEntry[i].peRed = + pal->palPalEntry[i].peGreen = + pal->palPalEntry[i].peBlue = i; + i++; + } + + dib->palette = CreatePalette(pal); + + } else if (strcmp(mode, "RGB") == 0) { + +#ifdef CUBE216 + + /* Colour DIB. Create a 6x6x6 colour cube (216 entries) and + * add 20 extra greylevels for best result with greyscale + * images. */ + + i = 10; + for (r = 0; r < 256; r += 51) + for (g = 0; g < 256; g += 51) + for (b = 0; b < 256; b += 51) { + pal->palPalEntry[i].peRed = r; + pal->palPalEntry[i].peGreen = g; + pal->palPalEntry[i].peBlue = b; + i++; + } + for (r = 1; r < 22-1; r++) { + /* Black and white are already provided by the cube. */ + pal->palPalEntry[i].peRed = + pal->palPalEntry[i].peGreen = + pal->palPalEntry[i].peBlue = r * 255 / (22-1); + i++; + } + +#else + + /* Colour DIB. Alternate palette. */ + + i = 10; + for (r = 0; r < 256; r += 37) + for (g = 0; g < 256; g += 32) + for (b = 0; b < 256; b += 64) { + pal->palPalEntry[i].peRed = r; + pal->palPalEntry[i].peGreen = g; + pal->palPalEntry[i].peBlue = b; + i++; + } + +#endif + +#if 0 + { + /* DEBUG: dump palette to file */ + FILE *err = fopen("dib.pal", "w"); + for (i = 0; i < 256; i++) + fprintf(err, "%d: %d/%d/%d\n", i, + pal->palPalEntry[i].peRed, + pal->palPalEntry[i].peGreen, + pal->palPalEntry[i].peBlue); + fclose(err); + } +#endif + + dib->palette = CreatePalette(pal); + + } + + } + + return dib; +} + +void +ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]) +{ + /* Paste image data into a bitmap */ + + /* FIXME: check size! */ + + int y; + for (y = 0; y < im->ysize; y++) + dib->pack(dib->bits + dib->linesize*(dib->ysize-(xy[1]+y)-1) + + xy[0]*dib->pixelsize, im->image[y], im->xsize); + +} + +void +ImagingExposeDIB(ImagingDIB dib, int dc) +{ + /* Copy bitmap to display */ + + if (dib->palette != 0) + SelectPalette((HDC) dc, dib->palette, FALSE); + BitBlt((HDC) dc, 0, 0, dib->xsize, dib->ysize, dib->dc, 0, 0, SRCCOPY); +} + +void +ImagingDrawDIB(ImagingDIB dib, int dc, int dst[4], int src[4]) +{ + /* Copy bitmap to printer/display */ + + if (GetDeviceCaps((HDC) dc, RASTERCAPS) & RC_STRETCHDIB) { + /* stretchdib (printers) */ + StretchDIBits((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1], + src[0], src[1], src[2]-src[0], src[3]-src[1], dib->bits, + dib->info, DIB_RGB_COLORS, SRCCOPY); + } else { + /* stretchblt (displays) */ + if (dib->palette != 0) + SelectPalette((HDC) dc, dib->palette, FALSE); + StretchBlt((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1], + dib->dc, src[0], src[1], src[2]-src[0], src[3]-src[1], + SRCCOPY); + } +} + +int +ImagingQueryPaletteDIB(ImagingDIB dib, int dc) +{ + /* Install bitmap palette */ + + int n; + + if (dib->palette != 0) { + + /* Realize associated palette */ + HPALETTE now = SelectPalette((HDC) dc, dib->palette, FALSE); + n = RealizePalette((HDC) dc); + + /* Restore palette */ + SelectPalette((HDC) dc, now, FALSE); + + } else + n = 0; + + return n; /* number of colours that was changed */ +} + +void +ImagingDeleteDIB(ImagingDIB dib) +{ + /* Clean up */ + + if (dib->palette) + DeleteObject(dib->palette); + if (dib->bitmap) { + SelectObject(dib->dc, dib->old_bitmap); + DeleteObject(dib->bitmap); + } + if (dib->dc) + DeleteDC(dib->dc); + free(dib->info); +} + +#endif /* WIN32 */ diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c new file mode 100755 index 00000000000..bdf17e18aa6 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c @@ -0,0 +1,1167 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * a simple drawing package for the Imaging library + * + * history: + * 1996-04-13 fl Created. + * 1996-04-30 fl Added transforms and polygon support. + * 1996-08-12 fl Added filled polygons. + * 1996-11-05 fl Fixed float/int confusion in polygon filler + * 1997-07-04 fl Support 32-bit images (C++ would have been nice) + * 1998-09-09 fl Eliminated qsort casts; improved rectangle clipping + * 1998-09-10 fl Fixed fill rectangle to include lower edge (!) + * 1998-12-29 fl Added arc, chord, and pieslice primitives + * 1999-01-10 fl Added some level 2 ("arrow") stuff (experimental) + * 1999-02-06 fl Added bitmap primitive + * 1999-07-26 fl Eliminated a compiler warning + * 1999-07-31 fl Pass ink as void* instead of int + * 2002-12-10 fl Added experimental RGBA-on-RGB drawing + * 2004-09-04 fl Support simple wide lines (no joins) + * 2005-05-25 fl Fixed line width calculation + * + * Copyright (c) 1996-2006 by Fredrik Lundh + * Copyright (c) 1997-2006 by Secret Labs AB. + * + * See the README file for information on usage and redistribution. + */ + +/* FIXME: support fill/outline attribute for all filled shapes */ +/* FIXME: support zero-winding fill */ +/* FIXME: add drawing context, support affine transforms */ +/* FIXME: support clip window (and mask?) */ + +#include "Imaging.h" + +#include + +#define CEIL(v) (int) ceil(v) +#define FLOOR(v) ((v) >= 0.0 ? (int) (v) : (int) floor(v)) + +#define INK8(ink) (*(UINT8*)ink) +#define INK32(ink) (*(INT32*)ink) + +/* like (a * b + 127) / 255), but much faster on most platforms */ +#define MULDIV255(a, b, tmp)\ + (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) + +#define BLEND(mask, in1, in2, tmp1, tmp2)\ + (MULDIV255(in1, 255 - mask, tmp1) + MULDIV255(in2, mask, tmp2)) + +/* -------------------------------------------------------------------- */ +/* Primitives */ +/* -------------------------------------------------------------------- */ + +typedef struct { + /* edge descriptor for polygon engine */ + int d; + int x0, y0; + int xmin, ymin, xmax, ymax; + float dx; +} Edge; + +static inline void +point8(Imaging im, int x, int y, int ink) +{ + if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) + im->image8[y][x] = (UINT8) ink; +} + +static inline void +point32(Imaging im, int x, int y, int ink) +{ + if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) + im->image32[y][x] = ink; +} + +static inline void +point32rgba(Imaging im, int x, int y, int ink) +{ + unsigned int tmp1, tmp2; + + if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) { + UINT8* out = (UINT8*) im->image[y]+x*4; + UINT8* in = (UINT8*) &ink; + out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2); + out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2); + out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2); + } +} + +static inline void +hline8(Imaging im, int x0, int y0, int x1, int ink) +{ + int tmp; + + if (y0 >= 0 && y0 < im->ysize) { + if (x0 > x1) + tmp = x0, x0 = x1, x1 = tmp; + if (x0 < 0) + x0 = 0; + else if (x0 >= im->xsize) + return; + if (x1 < 0) + return; + else if (x1 >= im->xsize) + x1 = im->xsize-1; + if (x0 <= x1) + memset(im->image8[y0] + x0, (UINT8) ink, x1 - x0 + 1); + } +} + +static inline void +hline32(Imaging im, int x0, int y0, int x1, int ink) +{ + int tmp; + INT32* p; + + if (y0 >= 0 && y0 < im->ysize) { + if (x0 > x1) + tmp = x0, x0 = x1, x1 = tmp; + if (x0 < 0) + x0 = 0; + else if (x0 >= im->xsize) + return; + if (x1 < 0) + return; + else if (x1 >= im->xsize) + x1 = im->xsize-1; + p = im->image32[y0]; + while (x0 <= x1) + p[x0++] = ink; + } +} + +static inline void +hline32rgba(Imaging im, int x0, int y0, int x1, int ink) +{ + int tmp; + unsigned int tmp1, tmp2; + + if (y0 >= 0 && y0 < im->ysize) { + if (x0 > x1) + tmp = x0, x0 = x1, x1 = tmp; + if (x0 < 0) + x0 = 0; + else if (x0 >= im->xsize) + return; + if (x1 < 0) + return; + else if (x1 >= im->xsize) + x1 = im->xsize-1; + if (x0 <= x1) { + UINT8* out = (UINT8*) im->image[y0]+x0*4; + UINT8* in = (UINT8*) &ink; + while (x0 <= x1) { + out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2); + out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2); + out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2); + x0++; out += 4; + } + } + } +} + +static inline void +line8(Imaging im, int x0, int y0, int x1, int y1, int ink) +{ + int i, n, e; + int dx, dy; + int xs, ys; + + /* normalize coordinates */ + dx = x1-x0; + if (dx < 0) + dx = -dx, xs = -1; + else + xs = 1; + dy = y1-y0; + if (dy < 0) + dy = -dy, ys = -1; + else + ys = 1; + + n = (dx > dy) ? dx : dy; + + if (dx == 0) + + /* vertical */ + for (i = 0; i < dy; i++) { + point8(im, x0, y0, ink); + y0 += ys; + } + + else if (dy == 0) + + /* horizontal */ + for (i = 0; i < dx; i++) { + point8(im, x0, y0, ink); + x0 += xs; + } + + else if (dx > dy) { + + /* bresenham, horizontal slope */ + n = dx; + dy += dy; + e = dy - dx; + dx += dx; + + for (i = 0; i < n; i++) { + point8(im, x0, y0, ink); + if (e >= 0) { + y0 += ys; + e -= dx; + } + e += dy; + x0 += xs; + } + + } else { + + /* bresenham, vertical slope */ + n = dy; + dx += dx; + e = dx - dy; + dy += dy; + + for (i = 0; i < n; i++) { + point8(im, x0, y0, ink); + if (e >= 0) { + x0 += xs; + e -= dy; + } + e += dx; + y0 += ys; + } + + } +} + +static inline void +line32(Imaging im, int x0, int y0, int x1, int y1, int ink) +{ + int i, n, e; + int dx, dy; + int xs, ys; + + /* normalize coordinates */ + dx = x1-x0; + if (dx < 0) + dx = -dx, xs = -1; + else + xs = 1; + dy = y1-y0; + if (dy < 0) + dy = -dy, ys = -1; + else + ys = 1; + + n = (dx > dy) ? dx : dy; + + if (dx == 0) + + /* vertical */ + for (i = 0; i < dy; i++) { + point32(im, x0, y0, ink); + y0 += ys; + } + + else if (dy == 0) + + /* horizontal */ + for (i = 0; i < dx; i++) { + point32(im, x0, y0, ink); + x0 += xs; + } + + else if (dx > dy) { + + /* bresenham, horizontal slope */ + n = dx; + dy += dy; + e = dy - dx; + dx += dx; + + for (i = 0; i < n; i++) { + point32(im, x0, y0, ink); + if (e >= 0) { + y0 += ys; + e -= dx; + } + e += dy; + x0 += xs; + } + + } else { + + /* bresenham, vertical slope */ + n = dy; + dx += dx; + e = dx - dy; + dy += dy; + + for (i = 0; i < n; i++) { + point32(im, x0, y0, ink); + if (e >= 0) { + x0 += xs; + e -= dy; + } + e += dx; + y0 += ys; + } + + } +} + +static inline void +line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) +{ + int i, n, e; + int dx, dy; + int xs, ys; + + /* normalize coordinates */ + dx = x1-x0; + if (dx < 0) + dx = -dx, xs = -1; + else + xs = 1; + dy = y1-y0; + if (dy < 0) + dy = -dy, ys = -1; + else + ys = 1; + + n = (dx > dy) ? dx : dy; + + if (dx == 0) + + /* vertical */ + for (i = 0; i < dy; i++) { + point32rgba(im, x0, y0, ink); + y0 += ys; + } + + else if (dy == 0) + + /* horizontal */ + for (i = 0; i < dx; i++) { + point32rgba(im, x0, y0, ink); + x0 += xs; + } + + else if (dx > dy) { + + /* bresenham, horizontal slope */ + n = dx; + dy += dy; + e = dy - dx; + dx += dx; + + for (i = 0; i < n; i++) { + point32rgba(im, x0, y0, ink); + if (e >= 0) { + y0 += ys; + e -= dx; + } + e += dy; + x0 += xs; + } + + } else { + + /* bresenham, vertical slope */ + n = dy; + dx += dx; + e = dx - dy; + dy += dy; + + for (i = 0; i < n; i++) { + point32rgba(im, x0, y0, ink); + if (e >= 0) { + x0 += xs; + e -= dy; + } + e += dx; + y0 += ys; + } + + } +} + +static int +x_cmp(const void *x0, const void *x1) +{ + float diff = *((float*)x0) - *((float*)x1); + if (diff < 0) + return -1; + else if (diff > 0) + return 1; + else + return 0; +} + +static inline int +polygon8(Imaging im, int n, Edge *e, int ink, int eofill) +{ + int i, j; + float *xx; + int ymin, ymax; + float y; + + if (n <= 0) + return 0; + + /* Find upper and lower polygon boundary (within image) */ + + ymin = e[0].ymin; + ymax = e[0].ymax; + for (i = 1; i < n; i++) { + if (e[i].ymin < ymin) ymin = e[i].ymin; + if (e[i].ymax > ymax) ymax = e[i].ymax; + } + + if (ymin < 0) + ymin = 0; + if (ymax >= im->ysize) + ymax = im->ysize-1; + + /* Process polygon edges */ + + xx = malloc(n * sizeof(float)); + if (!xx) + return -1; + + for (;ymin <= ymax; ymin++) { + y = ymin+0.5F; + for (i = j = 0; i < n; i++) + if (y >= e[i].ymin && y <= e[i].ymax) { + if (e[i].d == 0) + hline8(im, e[i].xmin, ymin, e[i].xmax, ink); + else + xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; + } + if (j == 2) { + if (xx[0] < xx[1]) + hline8(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); + else + hline8(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); + } else { + qsort(xx, j, sizeof(float), x_cmp); + for (i = 0; i < j-1 ; i += 2) + hline8(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); + } + } + + free(xx); + + return 0; +} + +static inline int +polygon32(Imaging im, int n, Edge *e, int ink, int eofill) +{ + int i, j; + float *xx; + int ymin, ymax; + float y; + + if (n <= 0) + return 0; + + /* Find upper and lower polygon boundary (within image) */ + + ymin = e[0].ymin; + ymax = e[0].ymax; + for (i = 1; i < n; i++) { + if (e[i].ymin < ymin) ymin = e[i].ymin; + if (e[i].ymax > ymax) ymax = e[i].ymax; + } + + if (ymin < 0) + ymin = 0; + if (ymax >= im->ysize) + ymax = im->ysize-1; + + /* Process polygon edges */ + + xx = malloc(n * sizeof(float)); + if (!xx) + return -1; + + for (;ymin <= ymax; ymin++) { + y = ymin+0.5F; + for (i = j = 0; i < n; i++) { + if (y >= e[i].ymin && y <= e[i].ymax) { + if (e[i].d == 0) + hline32(im, e[i].xmin, ymin, e[i].xmax, ink); + else + xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; + } + } + if (j == 2) { + if (xx[0] < xx[1]) + hline32(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); + else + hline32(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); + } else { + qsort(xx, j, sizeof(float), x_cmp); + for (i = 0; i < j-1 ; i += 2) + hline32(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); + } + } + + free(xx); + + return 0; +} + +static inline int +polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill) +{ + int i, j; + float *xx; + int ymin, ymax; + float y; + + if (n <= 0) + return 0; + + /* Find upper and lower polygon boundary (within image) */ + + ymin = e[0].ymin; + ymax = e[0].ymax; + for (i = 1; i < n; i++) { + if (e[i].ymin < ymin) ymin = e[i].ymin; + if (e[i].ymax > ymax) ymax = e[i].ymax; + } + + if (ymin < 0) + ymin = 0; + if (ymax >= im->ysize) + ymax = im->ysize-1; + + /* Process polygon edges */ + + xx = malloc(n * sizeof(float)); + if (!xx) + return -1; + + for (;ymin <= ymax; ymin++) { + y = ymin+0.5F; + for (i = j = 0; i < n; i++) { + if (y >= e[i].ymin && y <= e[i].ymax) { + if (e[i].d == 0) + hline32rgba(im, e[i].xmin, ymin, e[i].xmax, ink); + else + xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; + } + } + if (j == 2) { + if (xx[0] < xx[1]) + hline32rgba(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); + else + hline32rgba(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); + } else { + qsort(xx, j, sizeof(float), x_cmp); + for (i = 0; i < j-1 ; i += 2) + hline32rgba(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); + } + } + + free(xx); + + return 0; +} + +static inline void +add_edge(Edge *e, int x0, int y0, int x1, int y1) +{ + /* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */ + + if (x0 <= x1) + e->xmin = x0, e->xmax = x1; + else + e->xmin = x1, e->xmax = x0; + + if (y0 <= y1) + e->ymin = y0, e->ymax = y1; + else + e->ymin = y1, e->ymax = y0; + + if (y0 == y1) { + e->d = 0; + e->dx = 0.0; + } else { + e->dx = ((float)(x1-x0)) / (y1-y0); + if (y0 == e->ymin) + e->d = 1; + else + e->d = -1; + } + + e->x0 = x0; + e->y0 = y0; +} + +typedef struct { + void (*point)(Imaging im, int x, int y, int ink); + void (*hline)(Imaging im, int x0, int y0, int x1, int ink); + void (*line)(Imaging im, int x0, int y0, int x1, int y1, int ink); + int (*polygon)(Imaging im, int n, Edge *e, int ink, int eofill); +} DRAW; + +DRAW draw8 = { point8, hline8, line8, polygon8 }; +DRAW draw32 = { point32, hline32, line32, polygon32 }; +DRAW draw32rgba = { point32rgba, hline32rgba, line32rgba, polygon32rgba }; + +/* -------------------------------------------------------------------- */ +/* Interface */ +/* -------------------------------------------------------------------- */ + +#define DRAWINIT()\ + if (im->image8) {\ + draw = &draw8;\ + ink = INK8(ink_);\ + } else {\ + draw = (op) ? &draw32rgba : &draw32; \ + ink = INK32(ink_);\ + } + +int +ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op) +{ + DRAW* draw; + INT32 ink; + + DRAWINIT(); + + draw->point(im, x0, y0, ink); + + return 0; +} + +int +ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_, + int op) +{ + DRAW* draw; + INT32 ink; + + DRAWINIT(); + + draw->line(im, x0, y0, x1, y1, ink); + + return 0; +} + +int +ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1, + const void* ink_, int width, int op) +{ + DRAW* draw; + INT32 ink; + + Edge e[4]; + + int dx, dy; + double d; + + DRAWINIT(); + + if (width <= 1) { + draw->line(im, x0, y0, x1, y1, ink); + return 0; + } + + dx = x1-x0; + dy = y1-y0; + + if (dx == 0 && dy == 0) { + draw->point(im, x0, y0, ink); + return 0; + } + + d = width / sqrt((float) (dx*dx + dy*dy)) / 2.0; + + dx = (int) floor(d * (y1-y0) + 0.5); + dy = (int) floor(d * (x1-x0) + 0.5); + + add_edge(e+0, x0 - dx, y0 + dy, x1 - dx, y1 + dy); + add_edge(e+1, x1 - dx, y1 + dy, x1 + dx, y1 - dy); + add_edge(e+2, x1 + dx, y1 - dy, x0 + dx, y0 - dy); + add_edge(e+3, x0 + dx, y0 - dy, x0 - dx, y0 + dy); + + draw->polygon(im, 4, e, ink, 0); + + return 0; +} + +int +ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1, + const void* ink_, int fill, int op) +{ + int y; + int tmp; + DRAW* draw; + INT32 ink; + + DRAWINIT(); + + if (y0 > y1) + tmp = y0, y0 = y1, y1 = tmp; + + if (fill) { + + if (y0 < 0) + y0 = 0; + else if (y0 >= im->ysize) + return 0; + + if (y1 < 0) + return 0; + else if (y1 > im->ysize) + y1 = im->ysize; + + for (y = y0; y <= y1; y++) + draw->hline(im, x0, y, x1, ink); + + } else { + + /* outline */ + draw->line(im, x0, y0, x1, y0, ink); + draw->line(im, x1, y0, x1, y1, ink); + draw->line(im, x1, y1, x0, y1, ink); + draw->line(im, x0, y1, x0, y0, ink); + + } + + return 0; +} + +int +ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_, + int fill, int op) +{ + int i, n; + DRAW* draw; + INT32 ink; + + if (count <= 0) + return 0; + + DRAWINIT(); + + if (fill) { + + /* Build edge list */ + Edge* e = malloc(count * sizeof(Edge)); + if (!e) { + (void) ImagingError_MemoryError(); + return -1; + } + for (i = n = 0; i < count-1; i++) + add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3]); + if (xy[i+i] != xy[0] || xy[i+i+1] != xy[1]) + add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[0], xy[1]); + draw->polygon(im, n, e, ink, 0); + free(e); + + } else { + + /* Outline */ + for (i = 0; i < count-1; i++) + draw->line(im, xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3], ink); + draw->line(im, xy[i+i], xy[i+i+1], xy[0], xy[1], ink); + + } + + return 0; +} + +int +ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void* ink, + int op) +{ + return ImagingFill2( + im, ink, bitmap, + x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize + ); +} + +/* -------------------------------------------------------------------- */ +/* standard shapes */ + +#define ARC 0 +#define CHORD 1 +#define PIESLICE 2 + +static int +ellipse(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink_, int fill, + int mode, int op) +{ + int i, n; + int cx, cy; + int w, h; + int x = 0, y = 0; + int lx = 0, ly = 0; + int sx = 0, sy = 0; + DRAW* draw; + INT32 ink; + + w = x1 - x0; + h = y1 - y0; + if (w < 0 || h < 0) + return 0; + + DRAWINIT(); + + cx = (x0 + x1) / 2; + cy = (y0 + y1) / 2; + + while (end < start) + end += 360; + + if (mode != ARC && fill) { + + /* Build edge list */ + Edge* e = malloc((end - start + 3) * sizeof(Edge)); + if (!e) { + ImagingError_MemoryError(); + return -1; + } + + n = 0; + + for (i = start; i <= end; i++) { + x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5); + y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5); + if (i != start) + add_edge(&e[n++], lx, ly, x, y); + else + sx = x, sy = y; + lx = x, ly = y; + } + + if (n > 0) { + /* close and draw polygon */ + if (mode == PIESLICE) { + if (x != cx || y != cy) { + add_edge(&e[n++], x, y, cx, cy); + add_edge(&e[n++], cx, cy, sx, sy); + } + } else { + if (x != sx || y != sy) + add_edge(&e[n++], x, y, sx, sy); + } + draw->polygon(im, n, e, ink, 0); + } + + free(e); + + } else { + + for (i = start; i <= end; i++) { + x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5); + y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5); + if (i != start) + draw->line(im, lx, ly, x, y, ink); + else + sx = x, sy = y; + lx = x, ly = y; + } + + if (i != start) { + if (mode == PIESLICE) { + if (x != cx || y != cy) { + draw->line(im, x, y, cx, cy, ink); + draw->line(im, cx, cy, sx, sy, ink); + } + } else if (mode == CHORD) { + if (x != sx || y != sy) + draw->line(im, x, y, sx, sy, ink); + } + } + } + + return 0; +} + +int +ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink, int op) +{ + return ellipse(im, x0, y0, x1, y1, start, end, ink, 0, ARC, op); +} + +int +ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink, int fill, int op) +{ + return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, CHORD, op); +} + +int +ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1, + const void* ink, int fill, int op) +{ + return ellipse(im, x0, y0, x1, y1, 0, 360, ink, fill, CHORD, op); +} + +int +ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink, int fill, int op) +{ + return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, PIESLICE, op); +} + +/* -------------------------------------------------------------------- */ + +/* experimental level 2 ("arrow") graphics stuff. this implements + portions of the arrow api on top of the Edge structure. the + semantics are ok, except that "curve" flattens the bezier curves by + itself */ + +#if 1 /* ARROW_GRAPHICS */ + +struct ImagingOutlineInstance { + + float x0, y0; + + float x, y; + + int count; + Edge *edges; + + int size; + +}; + + +ImagingOutline +ImagingOutlineNew(void) +{ + ImagingOutline outline; + + outline = calloc(1, sizeof(struct ImagingOutlineInstance)); + if (!outline) + return (ImagingOutline) ImagingError_MemoryError(); + + outline->edges = NULL; + outline->count = outline->size = 0; + + ImagingOutlineMove(outline, 0, 0); + + return outline; +} + +void +ImagingOutlineDelete(ImagingOutline outline) +{ + if (!outline) + return; + + if (outline->edges) + free(outline->edges); + + free(outline); +} + + +static Edge* +allocate(ImagingOutline outline, int extra) +{ + Edge* e; + + if (outline->count + extra > outline->size) { + /* expand outline buffer */ + outline->size += extra + 25; + if (!outline->edges) + e = malloc(outline->size * sizeof(Edge)); + else + e = realloc(outline->edges, outline->size * sizeof(Edge)); + if (!e) + return NULL; + outline->edges = e; + } + + e = outline->edges + outline->count; + + outline->count += extra; + + return e; +} + +int +ImagingOutlineMove(ImagingOutline outline, float x0, float y0) +{ + outline->x = outline->x0 = x0; + outline->y = outline->y0 = y0; + + return 0; +} + +int +ImagingOutlineLine(ImagingOutline outline, float x1, float y1) +{ + Edge* e; + + e = allocate(outline, 1); + if (!e) + return -1; /* out of memory */ + + add_edge(e, (int) outline->x, (int) outline->y, (int) x1, (int) y1); + + outline->x = x1; + outline->y = y1; + + return 0; +} + +int +ImagingOutlineCurve(ImagingOutline outline, float x1, float y1, + float x2, float y2, float x3, float y3) +{ + Edge* e; + int i; + float xo, yo; + +#define STEPS 32 + + e = allocate(outline, STEPS); + if (!e) + return -1; /* out of memory */ + + xo = outline->x; + yo = outline->y; + + /* flatten the bezier segment */ + + for (i = 1; i <= STEPS; i++) { + + float t = ((float) i) / STEPS; + float t2 = t*t; + float t3 = t2*t; + + float u = 1.0F - t; + float u2 = u*u; + float u3 = u2*u; + + float x = outline->x*u3 + 3*(x1*t*u2 + x2*t2*u) + x3*t3 + 0.5; + float y = outline->y*u3 + 3*(y1*t*u2 + y2*t2*u) + y3*t3 + 0.5; + + add_edge(e++, xo, yo, (int) x, (int) y); + + xo = x, yo = y; + + } + + outline->x = xo; + outline->y = yo; + + return 0; +} + +int +ImagingOutlineCurve2(ImagingOutline outline, float cx, float cy, + float x3, float y3) +{ + /* add bezier curve based on three control points (as + in the Flash file format) */ + + return ImagingOutlineCurve( + outline, + (outline->x + cx + cx)/3, (outline->y + cy + cy)/3, + (cx + cx + x3)/3, (cy + cy + y3)/3, + x3, y3); +} + +int +ImagingOutlineClose(ImagingOutline outline) +{ + if (outline->x == outline->x0 && outline->y == outline->y0) + return 0; + return ImagingOutlineLine(outline, outline->x0, outline->y0); +} + +int +ImagingOutlineTransform(ImagingOutline outline, double a[6]) +{ + Edge *eIn; + Edge *eOut; + int i, n; + int x0, y0, x1, y1; + int X0, Y0, X1, Y1; + + double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; + double a3 = a[3]; double a4 = a[4]; double a5 = a[5]; + + eIn = outline->edges; + n = outline->count; + + /* FIXME: ugly! */ + outline->edges = NULL; + outline->count = outline->size = 0; + + eOut = allocate(outline, n); + if (!eOut) { + outline->edges = eIn; + outline->count = outline->size = n; + ImagingError_MemoryError(); + return -1; + } + + for (i = 0; i < n; i++) { + + x0 = eIn->x0; + y0 = eIn->y0; + + /* FIXME: ouch! */ + if (eIn->x0 == eIn->xmin) + x1 = eIn->xmax; + else + x1 = eIn->xmin; + if (eIn->y0 == eIn->ymin) + y1 = eIn->ymax; + else + y1 = eIn->ymin; + + /* full moon tonight! if this doesn't work, you may need to + upgrade your compiler (make sure you have the right service + pack) */ + + X0 = (int) (a0*x0 + a1*y0 + a2); + Y0 = (int) (a3*x0 + a4*y0 + a5); + X1 = (int) (a0*x1 + a1*y1 + a2); + Y1 = (int) (a3*x1 + a4*y1 + a5); + + add_edge(eOut, X0, Y0, X1, Y1); + + eIn++; + eOut++; + + } + + free(eIn); + + return 0; +} + +int +ImagingDrawOutline(Imaging im, ImagingOutline outline, const void* ink_, + int fill, int op) +{ + DRAW* draw; + INT32 ink; + + DRAWINIT(); + + draw->polygon(im, outline->count, outline->edges, ink, 0); + + return 0; +} + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c new file mode 100755 index 00000000000..1b964ac408f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c @@ -0,0 +1,373 @@ +/* + * The Python Imaging Library + * $Id$ + * + * various special effects and image generators + * + * history: + * 1997-05-21 fl Just for fun + * 1997-06-05 fl Added mandelbrot generator + * 2003-05-24 fl Added perlin_turbulence generator (in progress) + * + * Copyright (c) 1997-2003 by Fredrik Lundh. + * Copyright (c) 1997 by Secret Labs AB. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include + +Imaging +ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) +{ + /* Generate a Mandelbrot set covering the given extent */ + + Imaging im; + int x, y, k; + double width, height; + double x1, y1, xi2, yi2, cr, ci, radius; + double dr, di; + + /* Check arguments */ + width = extent[2] - extent[0]; + height = extent[3] - extent[1]; + if (width < 0.0 || height < 0.0 || quality < 2) + return (Imaging) ImagingError_ValueError(NULL); + + im = ImagingNew("L", xsize, ysize); + if (!im) + return NULL; + + dr = width/(xsize-1); + di = height/(ysize-1); + + radius = 100.0; + + for (y = 0; y < ysize; y++) { + UINT8* buf = im->image8[y]; + for (x = 0; x < xsize; x++) { + x1 = y1 = xi2 = yi2 = 0.0; + cr = x*dr + extent[0]; + ci = y*di + extent[1]; + for (k = 1;; k++) { + y1 = 2*x1*y1 + ci; + x1 = xi2 - yi2 + cr; + xi2 = x1*x1; + yi2 = y1*y1; + if ((xi2 + yi2) > radius) { + buf[x] = k*255/quality; + break; + } + if (k > quality) { + buf[x] = 0; + break; + } + } + } + } + return im; +} + +Imaging +ImagingEffectNoise(int xsize, int ysize, float sigma) +{ + /* Generate gaussian noise centered around 128 */ + + Imaging imOut; + int x, y; + int nextok; + double this, next; + + imOut = ImagingNew("L", xsize, ysize); + if (!imOut) + return NULL; + + next = 0.0; + nextok = 0; + + for (y = 0; y < imOut->ysize; y++) { + UINT8* out = imOut->image8[y]; + for (x = 0; x < imOut->xsize; x++) { + if (nextok) { + this = next; + nextok = 0; + } else { + /* after numerical recepies */ + double v1, v2, radius, factor; + do { + v1 = rand()*(2.0/32767.0) - 1.0; + v2 = rand()*(2.0/32767.0) - 1.0; + radius= v1*v1 + v2*v2; + } while (radius >= 1.0); + factor = sqrt(-2.0*log(radius)/radius); + this = factor * v1; + next = factor * v2; + } + out[x] = (unsigned char) (128 + sigma * this); + } + } + + return imOut; +} + +Imaging +ImagingEffectPerlinTurbulence(int xsize, int ysize) +{ + /* Perlin turbulence (In progress) */ + + return NULL; +} + +Imaging +ImagingEffectSpread(Imaging imIn, int distance) +{ + /* Randomly spread pixels in an image */ + + Imaging imOut; + int x, y; + + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + + if (!imOut) + return NULL; + +#define SPREAD(type, image)\ + for (y = 0; y < imIn->ysize; y++)\ + for (x = 0; x < imIn->xsize; x++) {\ + int xx = x + (rand() % distance) - distance/2;\ + int yy = y + (rand() % distance) - distance/2;\ + if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) {\ + imOut->image[yy][xx] = imIn->image[y][x];\ + imOut->image[y][x] = imIn->image[yy][xx];\ + } else\ + imOut->image[y][x] = imIn->image[y][x];\ + } + + if (imIn->image8) { + SPREAD(UINT8, image8); + } else { + SPREAD(INT32, image32); + } + + ImagingCopyInfo(imOut, imIn); + + return imOut; +} + +/* -------------------------------------------------------------------- */ +/* Taken from the "C" code in the W3C SVG specification. Translated + to C89 by Fredrik Lundh */ + +#if 0 + +/* Produces results in the range [1, 2**31 - 2]. +Algorithm is: r = (a * r) mod m +where a = 16807 and m = 2**31 - 1 = 2147483647 +See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988 +To test: the algorithm should produce the result 1043618065 +as the 10,000th generated number if the original seed is 1. +*/ +#define RAND_m 2147483647 /* 2**31 - 1 */ +#define RAND_a 16807 /* 7**5; primitive root of m */ +#define RAND_q 127773 /* m / a */ +#define RAND_r 2836 /* m % a */ + +static long +perlin_setup_seed(long lSeed) +{ + if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1; + if (lSeed > RAND_m - 1) lSeed = RAND_m - 1; + return lSeed; +} + +static long +perlin_random(long lSeed) +{ + long result; + result = RAND_a * (lSeed % RAND_q) - RAND_r * (lSeed / RAND_q); + if (result <= 0) result += RAND_m; + return result; +} + +#define BSize 0x100 +#define BM 0xff +#define PerlinN 0x1000 +#define NP 12 /* 2^PerlinN */ +#define NM 0xfff +static int perlin_uLatticeSelector[BSize + BSize + 2]; +static double perlin_fGradient[4][BSize + BSize + 2][2]; +typedef struct +{ + int nWidth; /* How much to subtract to wrap for stitching. */ + int nHeight; + int nWrapX; /* Minimum value to wrap. */ + int nWrapY; +} StitchInfo; + +static void +perlin_init(long lSeed) +{ + double s; + int i, j, k; + lSeed = perlin_setup_seed(lSeed); + for(k = 0; k < 4; k++) + { + for(i = 0; i < BSize; i++) + { + perlin_uLatticeSelector[i] = i; + for (j = 0; j < 2; j++) + perlin_fGradient[k][i][j] = (double)(((lSeed = perlin_random(lSeed)) % (BSize + BSize)) - BSize) / BSize; + s = (double) (sqrt(perlin_fGradient[k][i][0] * perlin_fGradient[k][i][0] + perlin_fGradient[k][i][1] * perlin_fGradient[k][i][1])); + perlin_fGradient[k][i][0] /= s; + perlin_fGradient[k][i][1] /= s; + } + } + while(--i) + { + k = perlin_uLatticeSelector[i]; + perlin_uLatticeSelector[i] = perlin_uLatticeSelector[j = (lSeed = perlin_random(lSeed)) % BSize]; + perlin_uLatticeSelector[j] = k; + } + for(i = 0; i < BSize + 2; i++) + { + perlin_uLatticeSelector[BSize + i] = perlin_uLatticeSelector[i]; + for(k = 0; k < 4; k++) + for(j = 0; j < 2; j++) + perlin_fGradient[k][BSize + i][j] = perlin_fGradient[k][i][j]; + } +} + +#define s_curve(t) ( t * t * (3. - 2. * t) ) +#define lerp(t, a, b) ( a + t * (b - a) ) +static double +perlin_noise2(int nColorChannel, double vec[2], StitchInfo *pStitchInfo) +{ + int bx0, bx1, by0, by1, b00, b10, b01, b11; + double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v; + register int i, j; + + t = vec[0] + (double) PerlinN; + bx0 = (int)t; + bx1 = bx0+1; + rx0 = t - (int)t; + rx1 = rx0 - 1.0f; + t = vec[1] + (double) PerlinN; + by0 = (int)t; + by1 = by0+1; + ry0 = t - (int)t; + ry1 = ry0 - 1.0f; + + /* If stitching, adjust lattice points accordingly. */ + if(pStitchInfo != NULL) + { + if(bx0 >= pStitchInfo->nWrapX) + bx0 -= pStitchInfo->nWidth; + if(bx1 >= pStitchInfo->nWrapX) + bx1 -= pStitchInfo->nWidth; + if(by0 >= pStitchInfo->nWrapY) + by0 -= pStitchInfo->nHeight; + if(by1 >= pStitchInfo->nWrapY) + by1 -= pStitchInfo->nHeight; + } + + bx0 &= BM; + bx1 &= BM; + by0 &= BM; + by1 &= BM; + + i = perlin_uLatticeSelector[bx0]; + j = perlin_uLatticeSelector[bx1]; + b00 = perlin_uLatticeSelector[i + by0]; + b10 = perlin_uLatticeSelector[j + by0]; + b01 = perlin_uLatticeSelector[i + by1]; + b11 = perlin_uLatticeSelector[j + by1]; + sx = (double) (s_curve(rx0)); + sy = (double) (s_curve(ry0)); + q = perlin_fGradient[nColorChannel][b00]; u = rx0 * q[0] + ry0 * q[1]; + q = perlin_fGradient[nColorChannel][b10]; v = rx1 * q[0] + ry0 * q[1]; + a = lerp(sx, u, v); + q = perlin_fGradient[nColorChannel][b01]; u = rx0 * q[0] + ry1 * q[1]; + q = perlin_fGradient[nColorChannel][b11]; v = rx1 * q[0] + ry1 * q[1]; + b = lerp(sx, u, v); + return lerp(sy, a, b); +} + +double +perlin_turbulence( + int nColorChannel, double *point, double fBaseFreqX, double fBaseFreqY, + int nNumOctaves, int bFractalSum, int bDoStitching, + double fTileX, double fTileY, double fTileWidth, double fTileHeight) +{ + StitchInfo stitch; + StitchInfo *pStitchInfo = NULL; /* Not stitching when NULL. */ + + double fSum = 0.0f; + double vec[2]; + double ratio = 1; + + int nOctave; + + vec[0] = point[0] * fBaseFreqX; + vec[1] = point[1] * fBaseFreqY; + + /* Adjust the base frequencies if necessary for stitching. */ + if(bDoStitching) + { + /* When stitching tiled turbulence, the frequencies must be adjusted */ + /* so that the tile borders will be continuous. */ + if(fBaseFreqX != 0.0) + { + double fLoFreq = (double) (floor(fTileWidth * fBaseFreqX)) / fTileWidth; + double fHiFreq = (double) (ceil(fTileWidth * fBaseFreqX)) / fTileWidth; + if(fBaseFreqX / fLoFreq < fHiFreq / fBaseFreqX) + fBaseFreqX = fLoFreq; + else + fBaseFreqX = fHiFreq; + } + + if(fBaseFreqY != 0.0) + { + double fLoFreq = (double) (floor(fTileHeight * fBaseFreqY)) / fTileHeight; + double fHiFreq = (double) (ceil(fTileHeight * fBaseFreqY)) / fTileHeight; + if(fBaseFreqY / fLoFreq < fHiFreq / fBaseFreqY) + fBaseFreqY = fLoFreq; + else + fBaseFreqY = fHiFreq; + } + + /* Set up initial stitch values. */ + pStitchInfo = &stitch; + stitch.nWidth = (int) (fTileWidth * fBaseFreqX + 0.5f); + stitch.nWrapX = (int) (fTileX * fBaseFreqX + PerlinN + stitch.nWidth); + stitch.nHeight = (int) (fTileHeight * fBaseFreqY + 0.5f); + stitch.nWrapY = (int) (fTileY * fBaseFreqY + PerlinN + stitch.nHeight); + } + + for(nOctave = 0; nOctave < nNumOctaves; nOctave++) + { + if(bFractalSum) + fSum += (double) (perlin_noise2(nColorChannel, vec, pStitchInfo) / ratio); + else + fSum += (double) (fabs(perlin_noise2(nColorChannel, vec, pStitchInfo)) / ratio); + + vec[0] *= 2; + vec[1] *= 2; + ratio *= 2; + + if(pStitchInfo != NULL) + { + /* Update stitch values. Subtracting PerlinN before the multiplication and */ + /* adding it afterward simplifies to subtracting it once. */ + stitch.nWidth *= 2; + stitch.nWrapX = 2 * stitch.nWrapX - PerlinN; + stitch.nHeight *= 2; + stitch.nWrapY = 2 * stitch.nWrapY - PerlinN; + } + } + return fSum; +} + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c new file mode 100755 index 00000000000..704d5a6567d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c @@ -0,0 +1,80 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * encoder for EPS hex data + * + * history: + * 96-04-19 fl created + * 96-06-27 fl don't drop last block of encoded data + * + * notes: + * FIXME: rename to HexEncode.c ?? + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + enum { HEXBYTE=1, NEWLINE }; + const char *hex = "0123456789abcdef"; + + UINT8* ptr = buf; + UINT8* in, i; + + if (!state->state) { + state->state = HEXBYTE; + state->xsize *= im->pixelsize; /* Hack! */ + } + + in = (UINT8*) im->image[state->y]; + + for (;;) { + + if (state->state == NEWLINE) { + if (bytes < 1) + break; + *ptr++ = '\n'; + bytes--; + state->state = HEXBYTE; + } + + if (bytes < 2) + break; + + i = in[state->x++]; + *ptr++ = hex[(i>>4)&15]; + *ptr++ = hex[i&15]; + bytes -= 2; + + /* Skip junk bytes */ + if (im->bands == 3 && (state->x & 3) == 3) + state->x++; + + if (++state->count >= 79/2) { + state->state = NEWLINE; + state->count = 0; + } + + if (state->x >= state->xsize) { + state->x = 0; + if (++state->y >= state->ysize) { + state->errcode = IMAGING_CODEC_END; + break; + } + in = (UINT8*) im->image[state->y]; + } + + } + + return ptr - buf; + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c new file mode 100755 index 00000000000..635435d576c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c @@ -0,0 +1,83 @@ +/* + * The Python Imaging Library + * $Id$ + * + * default exception handling + * + * This module is usually overridden by application code (e.g. + * _imaging.c for PIL's standard Python bindings). If you get + * linking errors, remove this file from your project/library. + * + * history: + * 1995-06-15 fl Created + * 1998-12-29 fl Minor tweaks + * 2003-09-13 fl Added ImagingEnter/LeaveSection() + * + * Copyright (c) 1997-2003 by Secret Labs AB. + * Copyright (c) 1995-2003 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +/* exception state */ + +void * +ImagingError_IOError(void) +{ + fprintf(stderr, "*** exception: file access error\n"); + return NULL; +} + +void * +ImagingError_MemoryError(void) +{ + fprintf(stderr, "*** exception: out of memory\n"); + return NULL; +} + +void * +ImagingError_ModeError(void) +{ + return ImagingError_ValueError("bad image mode"); + return NULL; +} + +void * +ImagingError_Mismatch(void) +{ + return ImagingError_ValueError("images don't match"); + return NULL; +} + +void * +ImagingError_ValueError(const char *message) +{ + if (!message) + message = "exception: bad argument to function"; + fprintf(stderr, "*** %s\n", message); + return NULL; +} + +void +ImagingError_Clear(void) +{ + /* nop */; +} + +/* thread state */ + +void +ImagingSectionEnter(ImagingSectionCookie* cookie) +{ + /* pass */ +} + +void +ImagingSectionLeave(ImagingSectionCookie* cookie) +{ + /* pass */ +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c new file mode 100755 index 00000000000..6f454d1ca5d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c @@ -0,0 +1,193 @@ +/* + * The Python Imaging Library + * $Id$ + * + * built-in image file handling + * + * history: + * 1995-11-26 fl Created, supports PGM/PPM + * 1996-08-07 fl Write "1" images as PGM + * 1999-02-21 fl Don't write non-standard modes + * + * Copyright (c) 1997-99 by Secret Labs AB. + * Copyright (c) 1995-96 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include + +Imaging +ImagingOpenPPM(const char* infile) +{ + FILE* fp; + int i, c, v; + char* mode; + int x, y, max; + Imaging im; + + if (!infile) + return ImagingError_ValueError(NULL); + + fp = fopen(infile, "rb"); + if (!fp) + return ImagingError_IOError(); + + /* PPM magic */ + if (fgetc(fp) != 'P') + goto error; + switch (fgetc(fp)) { + case '4': /* FIXME: 1-bit images are not yet supported */ + goto error; + case '5': + mode = "L"; + break; + case '6': + mode = "RGB"; + break; + default: + goto error; + } + + i = 0; + c = fgetc(fp); + + x = y = max = 0; + + while (i < 3) { + + /* Ignore optional comment fields */ + while (c == '\n') { + c = fgetc(fp); + if (c == '#') { + do { + c = fgetc(fp); + if (c == EOF) + goto error; + } while (c != '\n'); + c = fgetc(fp); + } + } + + /* Skip forward to next value */ + while (isspace(c)) + c = fgetc(fp); + + /* And parse it */ + v = 0; + while (isdigit(c)) { + v = v * 10 + (c - '0'); + c = fgetc(fp); + } + + if (c == EOF) + goto error; + + switch (i++) { + case 0: + x = v; + break; + case 1: + y = v; + break; + case 2: + max = v; + break; + } + } + + im = ImagingNew(mode, x, y); + if (!im) + return NULL; + + /* if (max != 255) ... FIXME: does anyone ever use this feature? */ + + if (strcmp(im->mode, "L") == 0) { + + /* PPM "L" */ + for (y = 0; y < im->ysize; y++) + if (fread(im->image[y], im->xsize, 1, fp) != 1) + goto error; + + } else { + + /* PPM "RGB" or PyPPM mode */ + for (y = 0; y < im->ysize; y++) + for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) + if (fread(im->image[y]+i, im->bands, 1, fp) != 1) + goto error; + } + + fclose(fp); + + return im; + +error: + fclose(fp); + return ImagingError_IOError(); +} + + +int +ImagingSaveRaw(Imaging im, FILE* fp) +{ + int x, y, i; + + if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { + + /* @PIL227: FIXME: for mode "1", map != 0 to 255 */ + + /* PGM "L" */ + for (y = 0; y < im->ysize; y++) + fwrite(im->image[y], 1, im->xsize, fp); + + } else { + + /* PPM "RGB" or other internal format */ + for (y = 0; y < im->ysize; y++) + for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) + fwrite(im->image[y]+i, 1, im->bands, fp); + + } + + return 1; +} + + +int +ImagingSavePPM(Imaging im, const char* outfile) +{ + FILE* fp; + + if (!im) { + (void) ImagingError_ValueError(NULL); + return 0; + } + + fp = fopen(outfile, "wb"); + if (!fp) { + (void) ImagingError_IOError(); + return 0; + } + + if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { + /* Write "PGM" */ + fprintf(fp, "P5\n%d %d\n255\n", im->xsize, im->ysize); + } else if (strcmp(im->mode, "RGB") == 0) { + /* Write "PPM" */ + fprintf(fp, "P6\n%d %d\n255\n", im->xsize, im->ysize); + } else { + (void) ImagingError_ModeError(); + return 0; + } + + ImagingSaveRaw(im, fp); + + fclose(fp); + + return 1; +} + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c new file mode 100755 index 00000000000..ce00e6c157c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c @@ -0,0 +1,101 @@ +/* + * The Python Imaging Library + * $Id$ + * + * fill image with constant pixel value + * + * history: + * 95-11-26 fl moved from Imaging.c + * 96-05-17 fl added radial fill, renamed wedge to linear + * 98-06-23 fl changed ImageFill signature + * + * Copyright (c) Secret Labs AB 1997-98. All rights reserved. + * Copyright (c) Fredrik Lundh 1995-96. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include "math.h" + +Imaging +ImagingFill(Imaging im, const void* colour) +{ + int x, y; + + if (im->type == IMAGING_TYPE_SPECIAL) { + /* use generic API */ + ImagingAccess access = ImagingAccessNew(im); + if (access) { + for (y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++) + access->put_pixel(im, x, y, colour); + ImagingAccessDelete(im, access); + } else { + /* wipe the image */ + for (y = 0; y < im->ysize; y++) + memset(im->image[y], 0, im->linesize); + } + } else { + INT32 c = 0L; + memcpy(&c, colour, im->pixelsize); + if (im->image32 && c != 0L) { + for (y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++) + im->image32[y][x] = c; + } else { + unsigned char cc = (unsigned char) *(UINT8*) colour; + for (y = 0; y < im->ysize; y++) + memset(im->image[y], cc, im->linesize); + } + } + + return im; +} + +Imaging +ImagingFillLinearGradient(const char *mode) +{ + Imaging im; + int y; + + if (strlen(mode) != 1) + return (Imaging) ImagingError_ModeError(); + + im = ImagingNew(mode, 256, 256); + if (!im) + return NULL; + + for (y = 0; y < 256; y++) + memset(im->image8[y], (unsigned char) y, 256); + + return im; +} + +Imaging +ImagingFillRadialGradient(const char *mode) +{ + Imaging im; + int x, y; + int d; + + if (strlen(mode) != 1) + return (Imaging) ImagingError_ModeError(); + + im = ImagingNew(mode, 256, 256); + if (!im) + return NULL; + + for (y = 0; y < 256; y++) + for (x = 0; x < 256; x++) { + d = (int) sqrt((double) ((x-128)*(x-128) + (y-128)*(y-128)) * 2.0); + if (d >= 255) + im->image8[y][x] = 255; + else + im->image8[y][x] = d; + } + + return im; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c new file mode 100755 index 00000000000..45c9bf0606f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c @@ -0,0 +1,179 @@ +/* + * The Python Imaging Library + * $Id$ + * + * apply convolution kernel to image + * + * history: + * 1995-11-26 fl Created, supports 3x3 kernels + * 1995-11-27 fl Added 5x5 kernels, copy border + * 1999-07-26 fl Eliminated a few compiler warnings + * 2002-06-09 fl Moved kernel definitions to Python + * 2002-06-11 fl Support floating point kernels + * 2003-09-15 fl Added ImagingExpand helper + * + * Copyright (c) Secret Labs AB 1997-2002. All rights reserved. + * Copyright (c) Fredrik Lundh 1995. + * + * See the README file for information on usage and redistribution. + */ + +/* + * FIXME: Support RGB and RGBA/CMYK modes as well + * FIXME: Expand image border (current version leaves border as is) + * FIXME: Implement image processing gradient filters + */ + +#include "Imaging.h" + +Imaging +ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode) +{ + Imaging imOut; + int x, y; + + if (xmargin < 0 && ymargin < 0) + return (Imaging) ImagingError_ValueError("bad kernel size"); + + imOut = ImagingNew( + imIn->mode, imIn->xsize+2*xmargin, imIn->ysize+2*ymargin + ); + if (!imOut) + return NULL; + +#define EXPAND_LINE(type, image, yin, yout) {\ + for (x = 0; x < xmargin; x++)\ + imOut->image[yout][x] = imIn->image[yin][0];\ + for (x = 0; x < imIn->xsize; x++)\ + imOut->image[yout][x+xmargin] = imIn->image[yin][x];\ + for (x = 0; x < xmargin; x++)\ + imOut->image[yout][xmargin+imIn->xsize+x] =\ + imIn->image[yin][imIn->xsize-1];\ + } + +#define EXPAND(type, image) {\ + for (y = 0; y < ymargin; y++)\ + EXPAND_LINE(type, image, 0, y);\ + for (y = 0; y < imIn->ysize; y++)\ + EXPAND_LINE(type, image, y, y+ymargin);\ + for (y = 0; y < ymargin; y++)\ + EXPAND_LINE(type, image, imIn->ysize-1, ymargin+imIn->ysize+y);\ + } + + if (imIn->image8) { + EXPAND(UINT8, image8); + } else { + EXPAND(INT32, image32); + } + + ImagingCopyInfo(imOut, imIn); + + return imOut; +} + +Imaging +ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32* kernel, + FLOAT32 offset, FLOAT32 divisor) +{ + Imaging imOut; + int x, y; + FLOAT32 sum; + + if (!im || strcmp(im->mode, "L") != 0) + return (Imaging) ImagingError_ModeError(); + + if (im->xsize < xsize || im->ysize < ysize) + return ImagingCopy(im); + + if ((xsize != 3 && xsize != 5) || xsize != ysize) + return (Imaging) ImagingError_ValueError("bad kernel size"); + + imOut = ImagingNew(im->mode, im->xsize, im->ysize); + if (!imOut) + return NULL; + + /* brute force kernel implementations */ +#define KERNEL3x3(image, kernel, d) ( \ + (int) image[y+1][x-d] * kernel[0] + \ + (int) image[y+1][x] * kernel[1] + \ + (int) image[y+1][x+d] * kernel[2] + \ + (int) image[y][x-d] * kernel[3] + \ + (int) image[y][x] * kernel[4] + \ + (int) image[y][x+d] * kernel[5] + \ + (int) image[y-1][x-d] * kernel[6] + \ + (int) image[y-1][x] * kernel[7] + \ + (int) image[y-1][x+d] * kernel[8]) + +#define KERNEL5x5(image, kernel, d) ( \ + (int) image[y+2][x-d-d] * kernel[0] + \ + (int) image[y+2][x-d] * kernel[1] + \ + (int) image[y+2][x] * kernel[2] + \ + (int) image[y+2][x+d] * kernel[3] + \ + (int) image[y+2][x+d+d] * kernel[4] + \ + (int) image[y+1][x-d-d] * kernel[5] + \ + (int) image[y+1][x-d] * kernel[6] + \ + (int) image[y+1][x] * kernel[7] + \ + (int) image[y+1][x+d] * kernel[8] + \ + (int) image[y+1][x+d+d] * kernel[9] + \ + (int) image[y][x-d-d] * kernel[10] + \ + (int) image[y][x-d] * kernel[11] + \ + (int) image[y][x] * kernel[12] + \ + (int) image[y][x+d] * kernel[13] + \ + (int) image[y][x+d+d] * kernel[14] + \ + (int) image[y-1][x-d-d] * kernel[15] + \ + (int) image[y-1][x-d] * kernel[16] + \ + (int) image[y-1][x] * kernel[17] + \ + (int) image[y-1][x+d] * kernel[18] + \ + (int) image[y-1][x+d+d] * kernel[19] + \ + (int) image[y-2][x-d-d] * kernel[20] + \ + (int) image[y-2][x-d] * kernel[21] + \ + (int) image[y-2][x] * kernel[22] + \ + (int) image[y-2][x+d] * kernel[23] + \ + (int) image[y-2][x+d+d] * kernel[24]) + + if (xsize == 3) { + /* 3x3 kernel. */ + for (x = 0; x < im->xsize; x++) + imOut->image[0][x] = im->image8[0][x]; + for (y = 1; y < im->ysize-1; y++) { + imOut->image[y][0] = im->image8[y][0]; + for (x = 1; x < im->xsize-1; x++) { + sum = KERNEL3x3(im->image8, kernel, 1) / divisor + offset; + if (sum <= 0) + imOut->image8[y][x] = 0; + else if (sum >= 255) + imOut->image8[y][x] = 255; + else + imOut->image8[y][x] = (UINT8) sum; + } + imOut->image8[y][x] = im->image8[y][x]; + } + for (x = 0; x < im->xsize; x++) + imOut->image8[y][x] = im->image8[y][x]; + } else { + /* 5x5 kernel. */ + for (y = 0; y < 2; y++) + for (x = 0; x < im->xsize; x++) + imOut->image8[y][x] = im->image8[y][x]; + for (; y < im->ysize-2; y++) { + for (x = 0; x < 2; x++) + imOut->image8[y][x] = im->image8[y][x]; + for (; x < im->xsize-2; x++) { + sum = KERNEL5x5(im->image8, kernel, 1) / divisor + offset; + if (sum <= 0) + imOut->image8[y][x] = 0; + else if (sum >= 255) + imOut->image8[y][x] = 255; + else + imOut->image8[y][x] = (UINT8) sum; + } + for (; x < im->xsize; x++) + imOut->image8[y][x] = im->image8[y][x]; + } + for (; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++) + imOut->image8[y][x] = im->image8[y][x]; + } + return imOut; +} + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c new file mode 100755 index 00000000000..75eebe86c90 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c @@ -0,0 +1,205 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for Autodesk Animator FLI/FLC animations + * + * history: + * 97-01-03 fl Created + * 97-01-17 fl Added SS2 support (FLC) + * + * Copyright (c) Fredrik Lundh 1997. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +#define I16(ptr)\ + ((ptr)[0] + ((ptr)[1] << 8)) + +#define I32(ptr)\ + ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) + + +int +ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8* ptr; + int framesize; + int c, chunks; + int l, lines; + int i, j, x = 0, y, ymax; + + /* If not even the chunk size is present, we'd better leave */ + + if (bytes < 4) + return 0; + + /* We don't decode anything unless we have a full chunk in the + input buffer (on the other hand, the Python part of the driver + makes sure this is always the case) */ + + ptr = buf; + + framesize = I32(ptr); + if (framesize < I32(ptr)) + return 0; + + /* Make sure this is a frame chunk. The Python driver takes + case of other chunk types. */ + + if (I16(ptr+4) != 0xF1FA) { + state->errcode = IMAGING_CODEC_UNKNOWN; + return -1; + } + + chunks = I16(ptr+6); + ptr += 16; + + /* Process subchunks */ + for (c = 0; c < chunks; c++) { + UINT8 *data = ptr + 6; + switch (I16(ptr+4)) { + case 4: case 11: + /* FLI COLOR chunk */ + break; /* ignored; handled by Python code */ + case 7: + /* FLI SS2 chunk (word delta) */ + lines = I16(data); data += 2; + for (l = y = 0; l < lines && y < state->ysize; l++, y++) { + UINT8* buf = (UINT8*) im->image[y]; + int p, packets; + packets = I16(data); data += 2; + while (packets & 0x8000) { + /* flag word */ + if (packets & 0x4000) { + y += 65536 - packets; /* skip lines */ + if (y >= state->ysize) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + buf = (UINT8*) im->image[y]; + } else { + /* store last byte (used if line width is odd) */ + buf[state->xsize-1] = (UINT8) packets; + } + packets = I16(data); data += 2; + } + for (p = x = 0; p < packets; p++) { + x += data[0]; /* pixel skip */ + if (data[1] >= 128) { + i = 256-data[1]; /* run */ + if (x + i + i > state->xsize) + break; + for (j = 0; j < i; j++) { + buf[x++] = data[2]; + buf[x++] = data[3]; + } + data += 2 + 2; + } else { + i = 2 * (int) data[1]; /* chunk */ + if (x + i > state->xsize) + break; + memcpy(buf + x, data + 2, i); + data += 2 + i; + x += i; + } + } + if (p < packets) + break; /* didn't process all packets */ + } + if (l < lines) { + /* didn't process all lines */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + break; + case 12: + /* FLI LC chunk (byte delta) */ + y = I16(data); ymax = y + I16(data+2); data += 4; + for (; y < ymax && y < state->ysize; y++) { + UINT8* out = (UINT8*) im->image[y]; + int p, packets = *data++; + for (p = x = 0; p < packets; p++, x += i) { + x += data[0]; /* skip pixels */ + if (data[1] & 0x80) { + i = 256-data[1]; /* run */ + if (x + i > state->xsize) + break; + memset(out + x, data[2], i); + data += 3; + } else { + i = data[1]; /* chunk */ + if (x + i > state->xsize) + break; + memcpy(out + x, data + 2, i); + data += i + 2; + } + } + if (p < packets) + break; /* didn't process all packets */ + } + if (y < ymax) { + /* didn't process all lines */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + break; + case 13: + /* FLI BLACK chunk */ + for (y = 0; y < state->ysize; y++) + memset(im->image[y], 0, state->xsize); + break; + case 15: + /* FLI BRUN chunk */ + for (y = 0; y < state->ysize; y++) { + UINT8* out = (UINT8*) im->image[y]; + data += 1; /* ignore packetcount byte */ + for (x = 0; x < state->xsize; x += i) { + if (data[0] & 0x80) { + i = 256 - data[0]; + if (x + i > state->xsize) + break; /* safety first */ + memcpy(out + x, data + 1, i); + data += i + 1; + } else { + i = data[0]; + if (x + i > state->xsize) + break; /* safety first */ + memset(out + x, data[1], i); + data += 2; + } + } + if (x != state->xsize) { + /* didn't unpack whole line */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + } + break; + case 16: + /* COPY chunk */ + for (y = 0; y < state->ysize; y++) { + UINT8* buf = (UINT8*) im->image[y]; + memcpy(buf+x, data, state->xsize); + data += state->xsize; + } + break; + case 18: + /* PSTAMP chunk */ + break; /* ignored */ + default: + /* unknown chunk */ + /* printf("unknown FLI/FLC chunk: %d\n", I16(ptr+4)); */ + state->errcode = IMAGING_CODEC_UNKNOWN; + return -1; + } + ptr += I32(ptr); + } + + return -1; /* end of frame */ +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c new file mode 100755 index 00000000000..41f535b562d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c @@ -0,0 +1,959 @@ +/* + * The Python Imaging Library + * $Id$ + * + * the imaging geometry methods + * + * history: + * 1995-06-15 fl Created + * 1996-04-15 fl Changed origin + * 1996-05-18 fl Fixed rotate90/270 for rectangular images + * 1996-05-27 fl Added general purpose transform + * 1996-11-22 fl Don't crash when resizing from outside source image + * 1997-08-09 fl Fixed rounding error in resize + * 1998-09-21 fl Incorporated transformation patches (from Zircon #2) + * 1998-09-22 fl Added bounding box to transform engines + * 1999-02-03 fl Fixed bicubic filtering for RGB images + * 1999-02-16 fl Added fixed-point version of affine transform + * 2001-03-28 fl Fixed transform(EXTENT) for xoffset < 0 + * 2003-03-10 fl Compiler tweaks + * 2004-09-19 fl Fixed bilinear/bicubic filtering of LA images + * + * Copyright (c) 1997-2003 by Secret Labs AB + * Copyright (c) 1995-1997 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +/* Undef if you don't need resampling filters */ +#define WITH_FILTERS + +#define COORD(v) ((v) < 0.0 ? -1 : ((int)(v))) +#define FLOOR(v) ((v) < 0.0 ? ((int)floor(v)) : ((int)(v))) + +/* -------------------------------------------------------------------- */ +/* Transpose operations */ + +Imaging +ImagingFlipLeftRight(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int x, y, xr; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) + return (Imaging) ImagingError_Mismatch(); + + ImagingCopyInfo(imOut, imIn); + +#define FLIP_HORIZ(image)\ + for (y = 0; y < imIn->ysize; y++) {\ + xr = imIn->xsize-1;\ + for (x = 0; x < imIn->xsize; x++, xr--)\ + imOut->image[y][x] = imIn->image[y][xr];\ + } + + ImagingSectionEnter(&cookie); + + if (imIn->image8) + FLIP_HORIZ(image8) + else + FLIP_HORIZ(image32) + + ImagingSectionLeave(&cookie); + + return imOut; +} + + +Imaging +ImagingFlipTopBottom(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int y, yr; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) + return (Imaging) ImagingError_Mismatch(); + + ImagingCopyInfo(imOut, imIn); + + ImagingSectionEnter(&cookie); + + yr = imIn->ysize-1; + for (y = 0; y < imIn->ysize; y++, yr--) + memcpy(imOut->image[yr], imIn->image[y], imIn->linesize); + + ImagingSectionLeave(&cookie); + + return imOut; +} + + +Imaging +ImagingRotate90(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int x, y, xr; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) + return (Imaging) ImagingError_Mismatch(); + + ImagingCopyInfo(imOut, imIn); + +#define ROTATE_90(image)\ + for (y = 0; y < imIn->ysize; y++) {\ + xr = imIn->xsize-1;\ + for (x = 0; x < imIn->xsize; x++, xr--)\ + imOut->image[xr][y] = imIn->image[y][x];\ + } + + ImagingSectionEnter(&cookie); + + if (imIn->image8) + ROTATE_90(image8) + else + ROTATE_90(image32) + + ImagingSectionLeave(&cookie); + + return imOut; +} + + +Imaging +ImagingRotate180(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int x, y, xr, yr; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) + return (Imaging) ImagingError_Mismatch(); + + ImagingCopyInfo(imOut, imIn); + + yr = imIn->ysize-1; + +#define ROTATE_180(image)\ + for (y = 0; y < imIn->ysize; y++, yr--) {\ + xr = imIn->xsize-1;\ + for (x = 0; x < imIn->xsize; x++, xr--)\ + imOut->image[y][x] = imIn->image[yr][xr];\ + } + + ImagingSectionEnter(&cookie); + + if (imIn->image8) + ROTATE_180(image8) + else + ROTATE_180(image32) + + ImagingSectionLeave(&cookie); + + return imOut; +} + + +Imaging +ImagingRotate270(Imaging imOut, Imaging imIn) +{ + ImagingSectionCookie cookie; + int x, y, yr; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) + return (Imaging) ImagingError_Mismatch(); + + ImagingCopyInfo(imOut, imIn); + + yr = imIn->ysize - 1; + +#define ROTATE_270(image)\ + for (y = 0; y < imIn->ysize; y++, yr--)\ + for (x = 0; x < imIn->xsize; x++)\ + imOut->image[x][y] = imIn->image[yr][x]; + + ImagingSectionEnter(&cookie); + + if (imIn->image8) + ROTATE_270(image8) + else + ROTATE_270(image32) + + ImagingSectionLeave(&cookie); + + return imOut; +} + + +/* -------------------------------------------------------------------- */ +/* Transforms */ + +/* transform primitives (ImagingTransformMap) */ + +static int +affine_transform(double* xin, double* yin, int x, int y, void* data) +{ + /* full moon tonight. your compiler will generate bogus code + for simple expressions, unless you reorganize the code, or + install Service Pack 3 */ + + double* a = (double*) data; + double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; + double a3 = a[3]; double a4 = a[4]; double a5 = a[5]; + + xin[0] = a0 + a1*x + a2*y; + yin[0] = a3 + a4*x + a5*y; + + return 1; +} + +static int +perspective_transform(double* xin, double* yin, int x, int y, void* data) +{ + double* a = (double*) data; + double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; + double a3 = a[3]; double a4 = a[4]; double a5 = a[5]; + double a6 = a[6]; double a7 = a[7]; + + xin[0] = (a0 + a1*x + a2*y) / (a6*x + a7*y + 1); + yin[0] = (a3 + a4*x + a5*y) / (a6*x + a7*y + 1); + + return 1; +} + +#if 0 +static int +quadratic_transform(double* xin, double* yin, int x, int y, void* data) +{ + double* a = (double*) data; + + double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3]; + double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7]; + double a8 = a[8]; double a9 = a[9]; double a10 = a[10]; double a11 = a[11]; + + xin[0] = a0 + a1*x + a2*y + a3*x*x + a4*x*y + a5*y*y; + yin[0] = a6 + a7*x + a8*y + a9*x*x + a10*x*y + a11*y*y; + + return 1; +} +#endif + +static int +quad_transform(double* xin, double* yin, int x, int y, void* data) +{ + /* quad warp: map quadrilateral to rectangle */ + + double* a = (double*) data; + double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3]; + double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7]; + + xin[0] = a0 + a1*x + a2*y + a3*x*y; + yin[0] = a4 + a5*x + a6*y + a7*x*y; + + return 1; +} + +/* transform filters (ImagingTransformFilter) */ + +#ifdef WITH_FILTERS + +static int +nearest_filter8(void* out, Imaging im, double xin, double yin, void* data) +{ + int x = COORD(xin); + int y = COORD(yin); + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) + return 0; + ((UINT8*)out)[0] = im->image8[y][x]; + return 1; +} + +static int +nearest_filter16(void* out, Imaging im, double xin, double yin, void* data) +{ + int x = COORD(xin); + int y = COORD(yin); + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) + return 0; + ((INT16*)out)[0] = ((INT16*)(im->image8[y]))[x]; + return 1; +} + +static int +nearest_filter32(void* out, Imaging im, double xin, double yin, void* data) +{ + int x = COORD(xin); + int y = COORD(yin); + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) + return 0; + ((INT32*)out)[0] = im->image32[y][x]; + return 1; +} + +#define XCLIP(im, x) ( ((x) < 0) ? 0 : ((x) < im->xsize) ? (x) : im->xsize-1 ) +#define YCLIP(im, y) ( ((y) < 0) ? 0 : ((y) < im->ysize) ? (y) : im->ysize-1 ) + +#define BILINEAR(v, a, b, d)\ + (v = (a) + ( (b) - (a) ) * (d)) + +#define BILINEAR_HEAD(type)\ + int x, y;\ + int x0, x1;\ + double v1, v2;\ + double dx, dy;\ + type* in;\ + if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize)\ + return 0;\ + xin -= 0.5;\ + yin -= 0.5;\ + x = FLOOR(xin);\ + y = FLOOR(yin);\ + dx = xin - x;\ + dy = yin - y; + +#define BILINEAR_BODY(type, image, step, offset) {\ + in = (type*) ((image)[YCLIP(im, y)] + offset);\ + x0 = XCLIP(im, x+0)*step;\ + x1 = XCLIP(im, x+1)*step;\ + BILINEAR(v1, in[x0], in[x1], dx);\ + if (y+1 >= 0 && y+1 < im->ysize) {\ + in = (type*) ((image)[y+1] + offset);\ + BILINEAR(v2, in[x0], in[x1], dx);\ + } else\ + v2 = v1;\ + BILINEAR(v1, v1, v2, dy);\ +} + +static int +bilinear_filter8(void* out, Imaging im, double xin, double yin, void* data) +{ + BILINEAR_HEAD(UINT8); + BILINEAR_BODY(UINT8, im->image8, 1, 0); + ((UINT8*)out)[0] = (UINT8) v1; + return 1; +} + +static int +bilinear_filter32I(void* out, Imaging im, double xin, double yin, void* data) +{ + BILINEAR_HEAD(INT32); + BILINEAR_BODY(INT32, im->image32, 1, 0); + ((INT32*)out)[0] = (INT32) v1; + return 1; +} + +static int +bilinear_filter32F(void* out, Imaging im, double xin, double yin, void* data) +{ + BILINEAR_HEAD(FLOAT32); + BILINEAR_BODY(FLOAT32, im->image32, 1, 0); + ((FLOAT32*)out)[0] = (FLOAT32) v1; + return 1; +} + +static int +bilinear_filter32LA(void* out, Imaging im, double xin, double yin, void* data) +{ + BILINEAR_HEAD(UINT8); + BILINEAR_BODY(UINT8, im->image, 4, 0); + ((UINT8*)out)[0] = (UINT8) v1; + ((UINT8*)out)[1] = (UINT8) v1; + ((UINT8*)out)[2] = (UINT8) v1; + BILINEAR_BODY(UINT8, im->image, 4, 3); + ((UINT8*)out)[3] = (UINT8) v1; + return 1; +} + +static int +bilinear_filter32RGB(void* out, Imaging im, double xin, double yin, void* data) +{ + int b; + BILINEAR_HEAD(UINT8); + for (b = 0; b < im->bands; b++) { + BILINEAR_BODY(UINT8, im->image, 4, b); + ((UINT8*)out)[b] = (UINT8) v1; + } + return 1; +} + +#define BICUBIC(v, v1, v2, v3, v4, d) {\ + double p1 = v2;\ + double p2 = -v1 + v3;\ + double p3 = 2*(v1 - v2) + v3 - v4;\ + double p4 = -v1 + v2 - v3 + v4;\ + v = p1 + (d)*(p2 + (d)*(p3 + (d)*p4));\ +} + +#define BICUBIC_HEAD(type)\ + int x = FLOOR(xin);\ + int y = FLOOR(yin);\ + int x0, x1, x2, x3;\ + double v1, v2, v3, v4;\ + double dx, dy;\ + type* in;\ + if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize)\ + return 0;\ + xin -= 0.5;\ + yin -= 0.5;\ + x = FLOOR(xin);\ + y = FLOOR(yin);\ + dx = xin - x;\ + dy = yin - y;\ + x--; y--; + +#define BICUBIC_BODY(type, image, step, offset) {\ + in = (type*) ((image)[YCLIP(im, y)] + offset);\ + x0 = XCLIP(im, x+0)*step;\ + x1 = XCLIP(im, x+1)*step;\ + x2 = XCLIP(im, x+2)*step;\ + x3 = XCLIP(im, x+3)*step;\ + BICUBIC(v1, in[x0], in[x1], in[x2], in[x3], dx);\ + if (y+1 >= 0 && y+1 < im->ysize) {\ + in = (type*) ((image)[y+1] + offset);\ + BICUBIC(v2, in[x0], in[x1], in[x2], in[x3], dx);\ + } else\ + v2 = v1;\ + if (y+2 >= 0 && y+2 < im->ysize) {\ + in = (type*) ((image)[y+2] + offset);\ + BICUBIC(v3, in[x0], in[x1], in[x2], in[x3], dx);\ + } else\ + v3 = v2;\ + if (y+3 >= 0 && y+3 < im->ysize) {\ + in = (type*) ((image)[y+3] + offset);\ + BICUBIC(v4, in[x0], in[x1], in[x2], in[x3], dx);\ + } else\ + v4 = v3;\ + BICUBIC(v1, v1, v2, v3, v4, dy);\ +} + + +static int +bicubic_filter8(void* out, Imaging im, double xin, double yin, void* data) +{ + BICUBIC_HEAD(UINT8); + BICUBIC_BODY(UINT8, im->image8, 1, 0); + if (v1 <= 0.0) + ((UINT8*)out)[0] = 0; + else if (v1 >= 255.0) + ((UINT8*)out)[0] = 255; + else + ((UINT8*)out)[0] = (UINT8) v1; + return 1; +} + +static int +bicubic_filter32I(void* out, Imaging im, double xin, double yin, void* data) +{ + BICUBIC_HEAD(INT32); + BICUBIC_BODY(INT32, im->image32, 1, 0); + ((INT32*)out)[0] = (INT32) v1; + return 1; +} + +static int +bicubic_filter32F(void* out, Imaging im, double xin, double yin, void* data) +{ + BICUBIC_HEAD(FLOAT32); + BICUBIC_BODY(FLOAT32, im->image32, 1, 0); + ((FLOAT32*)out)[0] = (FLOAT32) v1; + return 1; +} + +static int +bicubic_filter32LA(void* out, Imaging im, double xin, double yin, void* data) +{ + BICUBIC_HEAD(UINT8); + BICUBIC_BODY(UINT8, im->image, 4, 0); + if (v1 <= 0.0) { + ((UINT8*)out)[0] = 0; + ((UINT8*)out)[1] = 0; + ((UINT8*)out)[2] = 0; + } else if (v1 >= 255.0) { + ((UINT8*)out)[0] = 255; + ((UINT8*)out)[1] = 255; + ((UINT8*)out)[2] = 255; + } else { + ((UINT8*)out)[0] = (UINT8) v1; + ((UINT8*)out)[1] = (UINT8) v1; + ((UINT8*)out)[2] = (UINT8) v1; + } + BICUBIC_BODY(UINT8, im->image, 4, 3); + if (v1 <= 0.0) + ((UINT8*)out)[3] = 0; + else if (v1 >= 255.0) + ((UINT8*)out)[3] = 255; + else + ((UINT8*)out)[3] = (UINT8) v1; + return 1; +} + +static int +bicubic_filter32RGB(void* out, Imaging im, double xin, double yin, void* data) +{ + int b; + BICUBIC_HEAD(UINT8); + for (b = 0; b < im->bands; b++) { + BICUBIC_BODY(UINT8, im->image, 4, b); + if (v1 <= 0.0) + ((UINT8*)out)[b] = 0; + else if (v1 >= 255.0) + ((UINT8*)out)[b] = 255; + else + ((UINT8*)out)[b] = (UINT8) v1; + } + return 1; +} + +static ImagingTransformFilter +getfilter(Imaging im, int filterid) +{ + switch (filterid) { + case IMAGING_TRANSFORM_NEAREST: + if (im->image8) + switch (im->type) { + case IMAGING_TYPE_UINT8: + return (ImagingTransformFilter) nearest_filter8; + case IMAGING_TYPE_SPECIAL: + switch (im->pixelsize) { + case 1: + return (ImagingTransformFilter) nearest_filter8; + case 2: + return (ImagingTransformFilter) nearest_filter16; + case 4: + return (ImagingTransformFilter) nearest_filter32; + } + } + else + return (ImagingTransformFilter) nearest_filter32; + break; + case IMAGING_TRANSFORM_BILINEAR: + if (im->image8) + return (ImagingTransformFilter) bilinear_filter8; + else if (im->image32) { + switch (im->type) { + case IMAGING_TYPE_UINT8: + if (im->bands == 2) + return (ImagingTransformFilter) bilinear_filter32LA; + else + return (ImagingTransformFilter) bilinear_filter32RGB; + case IMAGING_TYPE_INT32: + return (ImagingTransformFilter) bilinear_filter32I; + case IMAGING_TYPE_FLOAT32: + return (ImagingTransformFilter) bilinear_filter32F; + } + } + break; + case IMAGING_TRANSFORM_BICUBIC: + if (im->image8) + return (ImagingTransformFilter) bicubic_filter8; + else if (im->image32) { + switch (im->type) { + case IMAGING_TYPE_UINT8: + if (im->bands == 2) + return (ImagingTransformFilter) bicubic_filter32LA; + else + return (ImagingTransformFilter) bicubic_filter32RGB; + case IMAGING_TYPE_INT32: + return (ImagingTransformFilter) bicubic_filter32I; + case IMAGING_TYPE_FLOAT32: + return (ImagingTransformFilter) bicubic_filter32F; + } + } + break; + } + /* no such filter */ + return NULL; +} + +#else +#define getfilter(im, id) NULL +#endif + +/* transformation engines */ + +Imaging +ImagingTransform( + Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, + ImagingTransformMap transform, void* transform_data, + ImagingTransformFilter filter, void* filter_data, + int fill) +{ + /* slow generic transformation. use ImagingTransformAffine or + ImagingScaleAffine where possible. */ + + ImagingSectionCookie cookie; + int x, y; + char *out; + double xx, yy; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + + ImagingCopyInfo(imOut, imIn); + + ImagingSectionEnter(&cookie); + + if (x0 < 0) + x0 = 0; + if (y0 < 0) + y0 = 0; + if (x1 > imOut->xsize) + x1 = imOut->xsize; + if (y1 > imOut->ysize) + y1 = imOut->ysize; + + for (y = y0; y < y1; y++) { + out = imOut->image[y] + x0*imOut->pixelsize; + for (x = x0; x < x1; x++) { + if (!transform(&xx, &yy, x-x0, y-y0, transform_data) || + !filter(out, imIn, xx, yy, filter_data)) { + if (fill) + memset(out, 0, imOut->pixelsize); + } + out += imOut->pixelsize; + } + } + + ImagingSectionLeave(&cookie); + + return imOut; +} + +static Imaging +ImagingScaleAffine(Imaging imOut, Imaging imIn, + int x0, int y0, int x1, int y1, + double a[6], int fill) +{ + /* scale, nearest neighbour resampling */ + + ImagingSectionCookie cookie; + int x, y; + int xin; + double xo, yo; + int xmin, xmax; + int *xintab; + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + + ImagingCopyInfo(imOut, imIn); + + if (x0 < 0) + x0 = 0; + if (y0 < 0) + y0 = 0; + if (x1 > imOut->xsize) + x1 = imOut->xsize; + if (y1 > imOut->ysize) + y1 = imOut->ysize; + + xintab = (int*) malloc(imOut->xsize * sizeof(int)); + if (!xintab) { + ImagingDelete(imOut); + return (Imaging) ImagingError_MemoryError(); + } + + xo = a[0]; + yo = a[3]; + + xmin = x1; + xmax = x0; + + /* Pretabulate horizontal pixel positions */ + for (x = x0; x < x1; x++) { + xin = COORD(xo); + if (xin >= 0 && xin < (int) imIn->xsize) { + xmax = x+1; + if (x < xmin) + xmin = x; + xintab[x] = xin; + } + xo += a[1]; + } + +#define AFFINE_SCALE(pixel, image)\ + for (y = y0; y < y1; y++) {\ + int yi = COORD(yo);\ + pixel *in, *out;\ + out = imOut->image[y];\ + if (fill && x1 > x0)\ + memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ + if (yi >= 0 && yi < imIn->ysize) {\ + in = imIn->image[yi];\ + for (x = xmin; x < xmax; x++)\ + out[x] = in[xintab[x]];\ + }\ + yo += a[5];\ + } + + ImagingSectionEnter(&cookie); + + if (imIn->image8) { + AFFINE_SCALE(UINT8, image8); + } else { + AFFINE_SCALE(INT32, image32); + } + + ImagingSectionLeave(&cookie); + + free(xintab); + + return imOut; +} + +static inline int +check_fixed(double a[6], int x, int y) +{ + return (fabs(a[0] + x*a[1] + y*a[2]) < 32768.0 && + fabs(a[3] + x*a[4] + y*a[5]) < 32768.0); +} + +static inline Imaging +affine_fixed(Imaging imOut, Imaging imIn, + int x0, int y0, int x1, int y1, + double a[6], int filterid, int fill) +{ + /* affine transform, nearest neighbour resampling, fixed point + arithmetics */ + + int x, y; + int xin, yin; + int xsize, ysize; + int xx, yy; + int a0, a1, a2, a3, a4, a5; + + ImagingCopyInfo(imOut, imIn); + + xsize = (int) imIn->xsize; + ysize = (int) imIn->ysize; + +/* use 16.16 fixed point arithmetics */ +#define FIX(v) FLOOR((v)*65536.0 + 0.5) + + a0 = FIX(a[0]); a1 = FIX(a[1]); a2 = FIX(a[2]); + a3 = FIX(a[3]); a4 = FIX(a[4]); a5 = FIX(a[5]); + +#define AFFINE_TRANSFORM_FIXED(pixel, image)\ + for (y = y0; y < y1; y++) {\ + pixel *out;\ + xx = a0;\ + yy = a3;\ + out = imOut->image[y];\ + if (fill && x1 > x0)\ + memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ + for (x = x0; x < x1; x++, out++) {\ + xin = xx >> 16;\ + if (xin >= 0 && xin < xsize) {\ + yin = yy >> 16;\ + if (yin >= 0 && yin < ysize)\ + *out = imIn->image[yin][xin];\ + }\ + xx += a1;\ + yy += a4;\ + }\ + a0 += a2;\ + a3 += a5;\ + } + + if (imIn->image8) + AFFINE_TRANSFORM_FIXED(UINT8, image8) + else + AFFINE_TRANSFORM_FIXED(INT32, image32) + + return imOut; +} + +Imaging +ImagingTransformAffine(Imaging imOut, Imaging imIn, + int x0, int y0, int x1, int y1, + double a[6], int filterid, int fill) +{ + /* affine transform, nearest neighbour resampling, floating point + arithmetics*/ + + ImagingSectionCookie cookie; + int x, y; + int xin, yin; + int xsize, ysize; + double xx, yy; + double xo, yo; + + if (filterid || imIn->type == IMAGING_TYPE_SPECIAL) { + /* Filtered transform */ + ImagingTransformFilter filter = getfilter(imIn, filterid); + if (!filter) + return (Imaging) ImagingError_ValueError("unknown filter"); + return ImagingTransform( + imOut, imIn, + x0, y0, x1, y1, + affine_transform, a, + filter, NULL, fill); + } + + if (a[2] == 0 && a[4] == 0) + /* Scaling */ + return ImagingScaleAffine(imOut, imIn, x0, y0, x1, y1, a, fill); + + if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) + return (Imaging) ImagingError_ModeError(); + + if (x0 < 0) + x0 = 0; + if (y0 < 0) + y0 = 0; + if (x1 > imOut->xsize) + x1 = imOut->xsize; + if (y1 > imOut->ysize) + y1 = imOut->ysize; + + ImagingCopyInfo(imOut, imIn); + + /* translate all four corners to check if they are within the + range that can be represented by the fixed point arithmetics */ + + if (check_fixed(a, 0, 0) && check_fixed(a, x1-x0, y1-y0) && + check_fixed(a, 0, y1-y0) && check_fixed(a, x1-x0, 0)) + return affine_fixed(imOut, imIn, x0, y0, x1, y1, a, filterid, fill); + + /* FIXME: cannot really think of any reasonable case when the + following code is used. maybe we should fall back on the slow + generic transform engine in this case? */ + + xsize = (int) imIn->xsize; + ysize = (int) imIn->ysize; + + xo = a[0]; + yo = a[3]; + +#define AFFINE_TRANSFORM(pixel, image)\ + for (y = y0; y < y1; y++) {\ + pixel *out;\ + xx = xo;\ + yy = yo;\ + out = imOut->image[y];\ + if (fill && x1 > x0)\ + memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ + for (x = x0; x < x1; x++, out++) {\ + xin = COORD(xx);\ + if (xin >= 0 && xin < xsize) {\ + yin = COORD(yy);\ + if (yin >= 0 && yin < ysize)\ + *out = imIn->image[yin][xin];\ + }\ + xx += a[1];\ + yy += a[4];\ + }\ + xo += a[2];\ + yo += a[5];\ + } + + ImagingSectionEnter(&cookie); + + if (imIn->image8) + AFFINE_TRANSFORM(UINT8, image8) + else + AFFINE_TRANSFORM(INT32, image32) + + ImagingSectionLeave(&cookie); + + return imOut; +} + +Imaging +ImagingTransformPerspective(Imaging imOut, Imaging imIn, + int x0, int y0, int x1, int y1, + double a[8], int filterid, int fill) +{ + ImagingTransformFilter filter = getfilter(imIn, filterid); + if (!filter) + return (Imaging) ImagingError_ValueError("bad filter number"); + + return ImagingTransform( + imOut, imIn, + x0, y0, x1, y1, + perspective_transform, a, + filter, NULL, + fill); +} + +Imaging +ImagingTransformQuad(Imaging imOut, Imaging imIn, + int x0, int y0, int x1, int y1, + double a[8], int filterid, int fill) +{ + ImagingTransformFilter filter = getfilter(imIn, filterid); + if (!filter) + return (Imaging) ImagingError_ValueError("bad filter number"); + + return ImagingTransform( + imOut, imIn, + x0, y0, x1, y1, + quad_transform, a, + filter, NULL, + fill); +} + +/* -------------------------------------------------------------------- */ +/* Convenience functions */ + +Imaging +ImagingResize(Imaging imOut, Imaging imIn, int filterid) +{ + double a[6]; + + if (imOut->xsize == imIn->xsize && imOut->ysize == imIn->ysize) + return ImagingCopy2(imOut, imIn); + + memset(a, 0, sizeof a); + a[1] = (double) imIn->xsize / imOut->xsize; + a[5] = (double) imIn->ysize / imOut->ysize; + + if (!filterid && imIn->type != IMAGING_TYPE_SPECIAL) + return ImagingScaleAffine( + imOut, imIn, + 0, 0, imOut->xsize, imOut->ysize, + a, 1); + + return ImagingTransformAffine( + imOut, imIn, + 0, 0, imOut->xsize, imOut->ysize, + a, filterid, 1); +} + +Imaging +ImagingRotate(Imaging imOut, Imaging imIn, double theta, int filterid) +{ + int xsize, ysize; + double sintheta, costheta; + double a[6]; + + /* Setup an affine transform to rotate around the image center */ + theta = -theta * M_PI / 180.0; + sintheta = sin(theta); + costheta = cos(theta); + + xsize = imOut->xsize; + ysize = imOut->ysize; + + a[0] = -costheta * xsize/2 - sintheta * ysize/2 + xsize/2; + a[1] = costheta; + a[2] = sintheta; + a[3] = sintheta * xsize/2 - costheta * ysize/2 + ysize/2; + a[4] = -sintheta; + a[5] = costheta; + + return ImagingTransformAffine( + imOut, imIn, + 0, 0, imOut->xsize, imOut->ysize, + a, filterid, 1); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c new file mode 100755 index 00000000000..d1722fe1488 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c @@ -0,0 +1,316 @@ +/* + * The Python Imaging Library + * $Id$ + * + * helpers to bounding boxes, min/max values, number of colors, etc. + * + * history: + * 1996-07-22 fl Created + * 1996-12-30 fl Added projection stuff + * 1998-07-12 fl Added extrema stuff + * 2004-09-17 fl Added colors stuff + * + * Copyright (c) 1997-2004 by Secret Labs AB. + * Copyright (c) 1996-2004 by Fredrik Lundh. + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingGetBBox(Imaging im, int bbox[4]) +{ + /* Get the bounding box for any non-zero data in the image.*/ + + int x, y; + int has_data; + + /* Initialize bounding box to max values */ + bbox[0] = im->xsize; + bbox[1] = -1; + bbox[2] = bbox[3] = 0; + +#define GETBBOX(image, mask)\ + for (y = 0; y < im->ysize; y++) {\ + has_data = 0;\ + for (x = 0; x < im->xsize; x++)\ + if (im->image[y][x] & mask) {\ + has_data = 1;\ + if (x < bbox[0])\ + bbox[0] = x;\ + if (x >= bbox[2])\ + bbox[2] = x+1;\ + }\ + if (has_data) {\ + if (bbox[1] < 0)\ + bbox[1] = y;\ + bbox[3] = y+1;\ + }\ + } + + if (im->image8) { + GETBBOX(image8, 0xff); + } else { + INT32 mask = 0xffffffff; + if (im->bands == 3) + ((UINT8*) &mask)[3] = 0; + GETBBOX(image32, mask); + } + + /* Check that we got a box */ + if (bbox[1] < 0) + return 0; /* no data */ + + return 1; /* ok */ +} + + +int +ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj) +{ + /* Get projection arrays for non-zero data in the image.*/ + + int x, y; + int has_data; + + /* Initialize projection arrays */ + memset(xproj, 0, im->xsize); + memset(yproj, 0, im->ysize); + +#define GETPROJ(image, mask)\ + for (y = 0; y < im->ysize; y++) {\ + has_data = 0;\ + for (x = 0; x < im->xsize; x++)\ + if (im->image[y][x] & mask) {\ + has_data = 1;\ + xproj[x] = 1;\ + }\ + if (has_data)\ + yproj[y] = 1;\ + } + + if (im->image8) { + GETPROJ(image8, 0xff); + } else { + INT32 mask = 0xffffffff; + if (im->bands == 3) + ((UINT8*) &mask)[3] = 0; + GETPROJ(image32, mask); + } + + return 1; /* ok */ +} + + +int +ImagingGetExtrema(Imaging im, void *extrema) +{ + int x, y; + INT32 imin, imax; + FLOAT32 fmin, fmax; + + if (im->bands != 1) { + (void) ImagingError_ModeError(); + return -1; /* mismatch */ + } + + if (!im->xsize || !im->ysize) + return 0; /* zero size */ + + switch (im->type) { + case IMAGING_TYPE_UINT8: + imin = imax = im->image8[0][0]; + for (y = 0; y < im->ysize; y++) { + UINT8* in = im->image8[y]; + for (x = 0; x < im->xsize; x++) { + if (imin > in[x]) + imin = in[x]; + else if (imax < in[x]) + imax = in[x]; + } + } + ((UINT8*) extrema)[0] = (UINT8) imin; + ((UINT8*) extrema)[1] = (UINT8) imax; + break; + case IMAGING_TYPE_INT32: + imin = imax = im->image32[0][0]; + for (y = 0; y < im->ysize; y++) { + INT32* in = im->image32[y]; + for (x = 0; x < im->xsize; x++) { + if (imin > in[x]) + imin = in[x]; + else if (imax < in[x]) + imax = in[x]; + } + } + ((INT32*) extrema)[0] = imin; + ((INT32*) extrema)[1] = imax; + break; + case IMAGING_TYPE_FLOAT32: + fmin = fmax = ((FLOAT32*) im->image32[0])[0]; + for (y = 0; y < im->ysize; y++) { + FLOAT32* in = (FLOAT32*) im->image32[y]; + for (x = 0; x < im->xsize; x++) { + if (fmin > in[x]) + fmin = in[x]; + else if (fmax < in[x]) + fmax = in[x]; + } + } + ((FLOAT32*) extrema)[0] = fmin; + ((FLOAT32*) extrema)[1] = fmax; + break; + case IMAGING_TYPE_SPECIAL: + if (strcmp(im->mode, "I;16") == 0) { + imin = imax = ((UINT16*) im->image8[0])[0]; + for (y = 0; y < im->ysize; y++) { + UINT16* in = (UINT16 *) im->image[y]; + for (x = 0; x < im->xsize; x++) { + if (imin > in[x]) + imin = in[x]; + else if (imax < in[x]) + imax = in[x]; + } + } + ((UINT16*) extrema)[0] = (UINT16) imin; + ((UINT16*) extrema)[1] = (UINT16) imax; + break; + } + /* FALL THROUGH */ + default: + (void) ImagingError_ModeError(); + return -1; + } + return 1; /* ok */ +} + + +/* static ImagingColorItem* getcolors8(Imaging im, int maxcolors, int* size);*/ +static ImagingColorItem* getcolors32(Imaging im, int maxcolors, int* size); + +ImagingColorItem* +ImagingGetColors(Imaging im, int maxcolors, int* size) +{ + /* FIXME: add support for 8-bit images */ + return getcolors32(im, maxcolors, size); +} + +static ImagingColorItem* +getcolors32(Imaging im, int maxcolors, int* size) +{ + unsigned int h; + unsigned int i, incr; + int colors; + INT32 pixel_mask; + int x, y; + ImagingColorItem* table; + ImagingColorItem* v; + + unsigned int code_size; + unsigned int code_poly; + unsigned int code_mask; + + /* note: the hash algorithm used here is based on the dictionary + code in Python 2.1.3; the exact implementation is borrowed from + Python's Unicode property database (written by yours truly) /F */ + + static int SIZES[] = { + 4,3, 8,3, 16,3, 32,5, 64,3, 128,3, 256,29, 512,17, 1024,9, 2048,5, + 4096,83, 8192,27, 16384,43, 32768,3, 65536,45, 131072,9, 262144,39, + 524288,39, 1048576,9, 2097152,5, 4194304,3, 8388608,33, 16777216,27, + 33554432,9, 67108864,71, 134217728,39, 268435456,9, 536870912,5, + 1073741824,83, 0 + }; + + code_size = code_poly = code_mask = 0; + + for (i = 0; SIZES[i]; i += 2) { + if (SIZES[i] > maxcolors) { + code_size = SIZES[i]; + code_poly = SIZES[i+1]; + code_mask = code_size - 1; + break; + } + } + + /* printf("code_size=%d\n", code_size); */ + /* printf("code_poly=%d\n", code_poly); */ + + if (!code_size) + return ImagingError_MemoryError(); /* just give up */ + + if (!im->image32) + return ImagingError_ModeError(); + + table = calloc(code_size + 1, sizeof(ImagingColorItem)); + if (!table) + return ImagingError_MemoryError(); + + pixel_mask = 0xffffffff; + if (im->bands == 3) + ((UINT8*) &pixel_mask)[3] = 0; + + colors = 0; + + for (y = 0; y < im->ysize; y++) { + INT32* p = im->image32[y]; + for (x = 0; x < im->xsize; x++) { + INT32 pixel = p[x] & pixel_mask; + h = (pixel); /* null hashing */ + i = (~h) & code_mask; + v = &table[i]; + if (!v->count) { + /* add to table */ + if (colors++ == maxcolors) + goto overflow; + v->x = x; v->y = y; + v->pixel = pixel; + v->count = 1; + continue; + } else if (v->pixel == pixel) { + v->count++; + continue; + } + incr = (h ^ (h >> 3)) & code_mask; + if (!incr) + incr = code_mask; + for (;;) { + i = (i + incr) & code_mask; + v = &table[i]; + if (!v->count) { + /* add to table */ + if (colors++ == maxcolors) + goto overflow; + v->x = x; v->y = y; + v->pixel = pixel; + v->count = 1; + break; + } else if (v->pixel == pixel) { + v->count++; + break; + } + incr = incr << 1; + if (incr > code_mask) + incr = incr ^ code_poly; + } + } + } + +overflow: + + /* pack the table */ + for (x = y = 0; x < (int) code_size; x++) + if (table[x].count) { + if (x != y) + table[y] = table[x]; + y++; + } + table[y].count = 0; /* mark end of table */ + + *size = colors; + + return table; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h new file mode 100755 index 00000000000..85d428b0d2d --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h @@ -0,0 +1,109 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * Declarations for a fast, suspendable GIF decoder. + * + * Copyright (c) Fredrik Lundh 1995-96. + */ + + +/* Max size for a LZW code word. */ + +#define GIFBITS 12 + +#define GIFTABLE (1< +#include /* memcpy() */ + +#include "Gif.h" + + +#define NEWLINE(state, context) {\ + state->x = 0;\ + state->y += context->step;\ + while (state->y >= state->ysize)\ + switch (context->interlace) {\ + case 1:\ + context->repeat = state->y = 4;\ + context->interlace = 2;\ + break;\ + case 2:\ + context->step = 4;\ + context->repeat = state->y = 2;\ + context->interlace = 3;\ + break;\ + case 3:\ + context->step = 2;\ + context->repeat = state->y = 1;\ + context->interlace = 0;\ + break;\ + default:\ + return -1;\ + }\ + if (state->y < state->ysize)\ + out = im->image8[state->y + state->yoff] + state->xoff;\ +} + + +int +ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes) +{ + UINT8* p; + UINT8* out; + int c, i; + int thiscode; + GIFDECODERSTATE *context = (GIFDECODERSTATE*) state->context; + + UINT8 *ptr = buffer; + + if (!state->state) { + + /* Initialise state */ + if (context->bits < 0 || context->bits > 8) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + /* Clear code */ + context->clear = 1 << context->bits; + + /* End code */ + context->end = context->clear + 1; + + /* Interlace */ + if (context->interlace) { + context->interlace = 1; + context->step = context->repeat = 8; + } else + context->step = 1; + + state->state = 1; + } + + out = im->image8[state->y + state->yoff] + state->xoff + state->x; + + for (;;) { + + if (state->state == 1) { + + /* First free entry in table */ + context->next = context->clear + 2; + + /* Initial code size */ + context->codesize = context->bits + 1; + context->codemask = (1 << context->codesize) - 1; + + /* Buffer pointer. We fill the buffer from right, which + allows us to return all of it in one operation. */ + context->bufferindex = GIFBUFFER; + + state->state = 2; + } + + if (context->bufferindex < GIFBUFFER) { + + /* Return whole buffer in one chunk */ + i = GIFBUFFER - context->bufferindex; + p = &context->buffer[context->bufferindex]; + + context->bufferindex = GIFBUFFER; + + } else { + + /* Get current symbol */ + + while (context->bitcount < context->codesize) { + + if (context->blocksize > 0) { + + /* Read next byte */ + c = *ptr++; bytes--; + + context->blocksize--; + + /* New bits are shifted in from from the left. */ + context->bitbuffer |= (INT32) c << context->bitcount; + context->bitcount += 8; + + } else { + + /* New GIF block */ + + /* We don't start decoding unless we have a full block */ + if (bytes < 1) + return ptr - buffer; + c = *ptr; + if (bytes < c+1) + return ptr - buffer; + + context->blocksize = c; + + ptr++; bytes--; + + } + } + + /* Extract current symbol from bit buffer. */ + c = (int) context->bitbuffer & context->codemask; + + /* Adjust buffer */ + context->bitbuffer >>= context->codesize; + context->bitcount -= context->codesize; + + /* If c is less than "clear", it's a data byte. Otherwise, + it's either clear/end or a code symbol which should be + expanded. */ + + if (c == context->clear) { + if (state->state != 2) + state->state = 1; + continue; + } + + if (c == context->end) + break; + + i = 1; + p = &context->lastdata; + + if (state->state == 2) { + + /* First valid symbol after clear; use as is */ + if (c > context->clear) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->lastdata = context->lastcode = c; + state->state = 3; + + } else { + + thiscode = c; + + if (c > context->next) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + if (c == context->next) { + + /* c == next is allowed. not sure why. */ + + if (context->bufferindex <= 0) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->buffer[--context->bufferindex] = + context->lastdata; + + c = context->lastcode; + + } + + while (c >= context->clear) { + + /* Copy data string to buffer (beginning from right) */ + + if (context->bufferindex <= 0 || c >= GIFTABLE) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->buffer[--context->bufferindex] = + context->data[c]; + + c = context->link[c]; + } + + context->lastdata = c; + + if (context->next < GIFTABLE) { + + /* We'll only add this symbol if we have room + for it (take advise, Netscape!) */ + context->data[context->next] = c; + context->link[context->next] = context->lastcode; + + if (context->next == context->codemask && + context->codesize < GIFBITS) { + + /* Expand code size */ + context->codesize++; + context->codemask = (1 << context->codesize) - 1; + } + + context->next++; + + } + + context->lastcode = thiscode; + + } + } + + /* Copy the bytes into the image */ + if (state->y >= state->ysize) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + /* To squeeze some extra pixels out of this loop, we test for + some common cases and handle them separately. */ + + /* FIXME: should we handle the transparency index in here??? */ + + if (i == 1) { + if (state->x < state->xsize-1) { + /* Single pixel, not at the end of the line. */ + *out++ = p[0]; + state->x++; + continue; + } + } else if (state->x + i <= state->xsize) { + /* This string fits into current line. */ + memcpy(out, p, i); + out += i; + state->x += i; + if (state->x == state->xsize) { + NEWLINE(state, context); + } + continue; + } + + /* No shortcut, copy pixel by pixel */ + for (c = 0; c < i; c++) { + *out++ = p[c]; + if (++state->x >= state->xsize) { + NEWLINE(state, context); + } + } + } + + return ptr - buffer; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c new file mode 100755 index 00000000000..f4d07598fce --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c @@ -0,0 +1,319 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * encoder for uncompressed GIF data + * + * history: + * 97-01-05 fl created (writes uncompressed data) + * 97-08-27 fl fixed off-by-one error in buffer size test + * 98-07-09 fl added interlace write support + * 99-02-07 fl rewritten, now uses a run-length encoding strategy + * 99-02-08 fl improved run-length encoding for long runs + * + * Copyright (c) Secret Labs AB 1997-99. + * Copyright (c) Fredrik Lundh 1997. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +#include "Gif.h" + +/* codes from 0 to 255 are literals */ +#define CLEAR_CODE 256 +#define EOF_CODE 257 +#define FIRST_CODE 258 +#define LAST_CODE 511 + +enum { INIT, ENCODE, ENCODE_EOF, FLUSH, EXIT }; + +/* to make things a little less complicated, we use a simple output + queue to hold completed blocks. the following inlined function + adds a byte to the current block. it allocates a new block if + necessary. */ + +static inline int +emit(GIFENCODERSTATE *context, int byte) +{ + /* write a byte to the output buffer */ + + if (!context->block || context->block->size == 255) { + GIFENCODERBLOCK* block; + + /* no room in the current block (or no current block); + allocate a new one */ + + /* add current block to end of flush queue */ + if (context->block) { + block = context->flush; + while (block && block->next) + block = block->next; + if (block) + block->next = context->block; + else + context->flush = context->block; + } + + /* get a new block */ + if (context->free) { + block = context->free; + context->free = NULL; + } else { + block = malloc(sizeof(GIFENCODERBLOCK)); + if (!block) + return 0; + } + + block->size = 0; + block->next = NULL; + + context->block = block; + + } + + /* write new byte to block */ + context->block->data[context->block->size++] = byte; + + return 1; +} + +/* write a code word to the current block. this is a macro to make + sure it's inlined on all platforms */ + +#define EMIT(code) {\ + context->bitbuffer |= ((INT32) (code)) << context->bitcount;\ + context->bitcount += 9;\ + while (context->bitcount >= 8) {\ + if (!emit(context, (UINT8) context->bitbuffer)) {\ + state->errcode = IMAGING_CODEC_MEMORY;\ + return 0;\ + }\ + context->bitbuffer >>= 8;\ + context->bitcount -= 8;\ + }\ +} + +/* write a run. we use a combination of literals and combinations of + literals. this can give quite decent compression for images with + long stretches of identical pixels. but remember: if you want + really good compression, use another file format. */ + +#define EMIT_RUN(label) {\ +label:\ + while (context->count > 0) {\ + int run = 2;\ + EMIT(context->last);\ + context->count--;\ + if (state->count++ == LAST_CODE) {\ + EMIT(CLEAR_CODE);\ + state->count = FIRST_CODE;\ + goto label;\ + }\ + while (context->count >= run) {\ + EMIT(state->count - 1);\ + context->count -= run;\ + run++;\ + if (state->count++ == LAST_CODE) {\ + EMIT(CLEAR_CODE);\ + state->count = FIRST_CODE;\ + goto label;\ + }\ + }\ + if (context->count > 1) {\ + EMIT(state->count - 1 - (run - context->count));\ + context->count = 0;\ + if (state->count++ == LAST_CODE) {\ + EMIT(CLEAR_CODE);\ + state->count = FIRST_CODE;\ + }\ + break;\ + }\ + }\ +} + +int +ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8* ptr; + int this; + + GIFENCODERBLOCK* block; + GIFENCODERSTATE *context = (GIFENCODERSTATE*) state->context; + + if (!state->state) { + + /* place a clear code in the output buffer */ + context->bitbuffer = CLEAR_CODE; + context->bitcount = 9; + + state->count = FIRST_CODE; + + if (context->interlace) { + context->interlace = 1; + context->step = 8; + } else + context->step = 1; + + context->last = -1; + + /* sanity check */ + if (state->xsize <= 0 || state->ysize <= 0) + state->state = ENCODE_EOF; + + } + + ptr = buf; + + for (;;) + + switch (state->state) { + + case INIT: + case ENCODE: + + /* identify and store a run of pixels */ + + if (state->x == 0 || state->x >= state->xsize) { + + if (!context->interlace && state->y >= state->ysize) { + state->state = ENCODE_EOF; + break; + } + + if (context->flush) { + state->state = FLUSH; + break; + } + + /* get another line of data */ + state->shuffle( + state->buffer, + (UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->xsize + ); + + state->x = 0; + + if (state->state == INIT) { + /* preload the run-length buffer and get going */ + context->last = state->buffer[0]; + context->count = state->x = 1; + state->state = ENCODE; + } + + /* step forward, according to the interlace settings */ + state->y += context->step; + while (context->interlace && state->y >= state->ysize) + switch (context->interlace) { + case 1: + state->y = 4; + context->interlace = 2; + break; + case 2: + context->step = 4; + state->y = 2; + context->interlace = 3; + break; + case 3: + context->step = 2; + state->y = 1; + context->interlace = 0; + break; + default: + /* just make sure we don't loop forever */ + context->interlace = 0; + } + + } + + this = state->buffer[state->x++]; + + if (this == context->last) + context->count++; + else { + EMIT_RUN(label1); + context->last = this; + context->count = 1; + } + break; + + + case ENCODE_EOF: + + /* write the final run */ + EMIT_RUN(label2); + + /* write an end of image marker */ + EMIT(EOF_CODE); + + /* empty the bit buffer */ + while (context->bitcount > 0) { + if (!emit(context, (UINT8) context->bitbuffer)) { + state->errcode = IMAGING_CODEC_MEMORY; + return 0; + } + context->bitbuffer >>= 8; + context->bitcount -= 8; + } + + /* flush the last block, and exit */ + if (context->block) { + GIFENCODERBLOCK* block; + block = context->flush; + while (block && block->next) + block = block->next; + if (block) + block->next = context->block; + else + context->flush = context->block; + context->block = NULL; + } + + state->state = EXIT; + + /* fall through... */ + + case EXIT: + case FLUSH: + + while (context->flush) { + + /* get a block from the flush queue */ + block = context->flush; + + if (block->size > 0) { + + /* make sure it fits into the output buffer */ + if (bytes < block->size+1) + return ptr - buf; + + ptr[0] = block->size; + memcpy(ptr+1, block->data, block->size); + + ptr += block->size+1; + bytes -= block->size+1; + + } + + context->flush = block->next; + + if (context->free) + free(context->free); + context->free = block; + + } + + if (state->state == EXIT) { + /* this was the last block! */ + if (context->free) + free(context->free); + state->errcode = IMAGING_CODEC_END; + return ptr - buf; + } + + state->state = ENCODE; + break; + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c new file mode 100755 index 00000000000..14f5241dc5e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c @@ -0,0 +1,67 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for hex encoded image data + * + * history: + * 96-05-16 fl Created + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#define HEX(v) ((v >= '0' && v <= '9') ? v - '0' :\ + (v >= 'a' && v <= 'f') ? v - 'a' + 10 :\ + (v >= 'A' && v <= 'F') ? v - 'A' + 10 : -1) + +int +ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8* ptr; + int a, b; + + ptr = buf; + + for (;;) { + + if (bytes < 2) + return ptr - buf; + + a = HEX(ptr[0]); + b = HEX(ptr[1]); + + if (a < 0 || b < 0) { + + ptr++; + bytes--; + + } else { + + ptr += 2; + bytes -= 2; + + state->buffer[state->x] = (a<<4) + b; + + if (++state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y], state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + } + + } + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c new file mode 100755 index 00000000000..513c844756e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c @@ -0,0 +1,169 @@ +/* + * The Python Imaging Library + * $Id$ + * + * histogram support + * + * history: + * 1995-06-15 fl Created. + * 1996-04-05 fl Fixed histogram for multiband images. + * 1997-02-23 fl Added mask support + * 1998-07-01 fl Added basic 32-bit float/integer support + * + * Copyright (c) 1997-2003 by Secret Labs AB. + * Copyright (c) 1995-2003 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +/* HISTOGRAM */ +/* -------------------------------------------------------------------- + * Take a histogram of an image. Returns a histogram object containing + * 256 slots per band in the input image. + */ + +void +ImagingHistogramDelete(ImagingHistogram h) +{ + if (h->histogram) + free(h->histogram); + free(h); +} + +ImagingHistogram +ImagingHistogramNew(Imaging im) +{ + ImagingHistogram h; + + /* Create histogram descriptor */ + h = calloc(1, sizeof(struct ImagingHistogramInstance)); + strcpy(h->mode, im->mode); + h->bands = im->bands; + h->histogram = calloc(im->pixelsize, 256 * sizeof(long)); + + return h; +} + +ImagingHistogram +ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) +{ + ImagingSectionCookie cookie; + int x, y, i; + ImagingHistogram h; + INT32 imin, imax; + FLOAT32 fmin, fmax, scale; + + if (!im) + return ImagingError_ModeError(); + + if (imMask) { + /* Validate mask */ + if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) + return ImagingError_Mismatch(); + if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) + return ImagingError_ValueError("bad transparency mask"); + } + + h = ImagingHistogramNew(im); + + if (imMask) { + /* mask */ + if (im->image8) { + ImagingSectionEnter(&cookie); + for (y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++) + if (imMask->image8[y][x] != 0) + h->histogram[im->image8[y][x]]++; + ImagingSectionLeave(&cookie); + } else { /* yes, we need the braces. C isn't Python! */ + if (im->type != IMAGING_TYPE_UINT8) + return ImagingError_ModeError(); + ImagingSectionEnter(&cookie); + for (y = 0; y < im->ysize; y++) { + UINT8* in = (UINT8*) im->image32[y]; + for (x = 0; x < im->xsize; x++) + if (imMask->image8[y][x] != 0) { + h->histogram[(*in++)]++; + h->histogram[(*in++)+256]++; + h->histogram[(*in++)+512]++; + h->histogram[(*in++)+768]++; + } else + in += 4; + } + ImagingSectionLeave(&cookie); + } + } else { + /* mask not given; process pixels in image */ + if (im->image8) { + ImagingSectionEnter(&cookie); + for (y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++) + h->histogram[im->image8[y][x]]++; + ImagingSectionLeave(&cookie); + } else { + switch (im->type) { + case IMAGING_TYPE_UINT8: + ImagingSectionEnter(&cookie); + for (y = 0; y < im->ysize; y++) { + UINT8* in = (UINT8*) im->image[y]; + for (x = 0; x < im->xsize; x++) { + h->histogram[(*in++)]++; + h->histogram[(*in++)+256]++; + h->histogram[(*in++)+512]++; + h->histogram[(*in++)+768]++; + } + } + ImagingSectionLeave(&cookie); + break; + case IMAGING_TYPE_INT32: + if (!minmax) + return ImagingError_ValueError("min/max not given"); + if (!im->xsize || !im->ysize) + break; + imin = ((INT32*) minmax)[0]; + imax = ((INT32*) minmax)[1]; + if (imin >= imax) + break; + ImagingSectionEnter(&cookie); + scale = 255.0F / (imax - imin); + for (y = 0; y < im->ysize; y++) { + INT32* in = im->image32[y]; + for (x = 0; x < im->xsize; x++) { + i = (int) (((*in++)-imin)*scale); + if (i >= 0 && i < 256) + h->histogram[i]++; + } + } + ImagingSectionLeave(&cookie); + break; + case IMAGING_TYPE_FLOAT32: + if (!minmax) + return ImagingError_ValueError("min/max not given"); + if (!im->xsize || !im->ysize) + break; + fmin = ((FLOAT32*) minmax)[0]; + fmax = ((FLOAT32*) minmax)[1]; + if (fmin >= fmax) + break; + ImagingSectionEnter(&cookie); + scale = 255.0F / (fmax - fmin); + for (y = 0; y < im->ysize; y++) { + FLOAT32* in = (FLOAT32*) im->image32[y]; + for (x = 0; x < im->xsize; x++) { + i = (int) (((*in++)-fmin)*scale); + if (i >= 0 && i < 256) + h->histogram[i]++; + } + } + ImagingSectionLeave(&cookie); + break; + } + } + } + + return h; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h new file mode 100755 index 00000000000..2effd387044 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h @@ -0,0 +1,64 @@ +/* + * The Python Imaging Library + * $Id$ + * + * Windows DIB specifics + * + * Copyright (c) Secret Labs AB 1997-98. + * Copyright (c) Fredrik Lundh 1996. + * + * See the README file for information on usage and redistribution. + */ + +#ifdef WIN32 + +#if (defined(_MSC_VER) && _MSC_VER >= 1200) || (defined __GNUC__) +/* already defined in basetsd.h */ +#undef INT32 +#undef INT64 +#undef UINT32 +#endif + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct ImagingDIBInstance { + /* Windows interface */ + HDC dc; + HBITMAP bitmap; + HGDIOBJ old_bitmap; + BITMAPINFO *info; + UINT8 *bits; + HPALETTE palette; + /* Used by cut and paste */ + char mode[4]; + int xsize, ysize; + int pixelsize; + int linesize; + ImagingShuffler pack; + ImagingShuffler unpack; +}; + +typedef struct ImagingDIBInstance* ImagingDIB; + +extern char* ImagingGetModeDIB(int size_out[2]); + +extern ImagingDIB ImagingNewDIB(const char *mode, int xsize, int ysize); + +extern void ImagingDeleteDIB(ImagingDIB im); + +extern void ImagingDrawDIB(ImagingDIB dib, int dc, int dst[4], int src[4]); +extern void ImagingExposeDIB(ImagingDIB dib, int dc); + +extern int ImagingQueryPaletteDIB(ImagingDIB dib, int dc); + +extern void ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h new file mode 100755 index 00000000000..4ffd6fdef9e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h @@ -0,0 +1,72 @@ +/* + * The Python Imaging Library + * $Id$ + * + * platform declarations for the imaging core library + * + * Copyright (c) Fredrik Lundh 1995-2003. + */ + +#include "Python.h" + +/* Check that we have an ANSI compliant compiler */ +#ifndef HAVE_PROTOTYPES +#error Sorry, this library requires support for ANSI prototypes. +#endif +#ifndef STDC_HEADERS +#error Sorry, this library requires ANSI header files. +#endif + +#if defined(_MSC_VER) +#ifndef WIN32 +#define WIN32 +#endif +/* VC++ 4.0 is a bit annoying when it comes to precision issues (like + claiming that "float a = 0.0;" would lead to loss of precision). I + don't like to see warnings from my code, but since I still want to + keep it readable, I simply switch off a few warnings instead of adding + the tons of casts that VC++ seem to require. This code is compiled + with numerous other compilers as well, so any real errors are likely + to be catched anyway. */ +#pragma warning(disable: 4244) /* conversion from 'float' to 'int' */ +#endif + +#if defined(_MSC_VER) +#define inline __inline +#elif !defined(USE_INLINE) +#define inline +#endif + +#if SIZEOF_SHORT == 2 +#define INT16 short +#elif SIZEOF_INT == 2 +#define INT16 int +#else +#define INT16 short /* most things works just fine anyway... */ +#endif + +#if SIZEOF_SHORT == 4 +#define INT32 short +#elif SIZEOF_INT == 4 +#define INT32 int +#elif SIZEOF_LONG == 4 +#define INT32 long +#else +#error Cannot find required 32-bit integer type +#endif + +#if SIZEOF_LONG == 8 +#define INT64 long +#elif SIZEOF_LONG_LONG == 8 +#define INT64 long +#endif + +/* assume IEEE; tweak if necessary (patches are welcome) */ +#define FLOAT32 float +#define FLOAT64 double + +#define INT8 signed char +#define UINT8 unsigned char + +#define UINT16 unsigned INT16 +#define UINT32 unsigned INT32 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h new file mode 100755 index 00000000000..4609376adda --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h @@ -0,0 +1,497 @@ +/* + * The Python Imaging Library + * $Id$ + * + * declarations for the imaging core library + * + * Copyright (c) 1997-2005 by Secret Labs AB + * Copyright (c) 1995-2005 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + + +#include "ImPlatform.h" + + +#if defined(__cplusplus) +extern "C" { +#endif + + +#ifndef M_PI +#define M_PI 3.14159265359 +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * Image data organization: + * + * mode bytes byte order + * ------------------------------- + * 1 1 1 + * L 1 L + * P 1 P + * I 4 I (32-bit integer, native byte order) + * F 4 F (32-bit IEEE float, native byte order) + * RGB 4 R, G, B, - + * RGBA 4 R, G, B, A + * CMYK 4 C, M, Y, K + * YCbCr 4 Y, Cb, Cr, - + * + * experimental modes (incomplete): + * LA 4 L, -, -, A + * PA 4 P, -, -, A + * I;16 2 I (16-bit integer, native byte order) + * + * "P" is an 8-bit palette mode, which should be mapped through the + * palette member to get an output image. Check palette->mode to + * find the corresponding "real" mode. + * + * For information on how to access Imaging objects from your own C + * extensions, see http://www.effbot.org/zone/pil-extending.htm + */ + +/* Handles */ + +typedef struct ImagingMemoryInstance* Imaging; + +typedef struct ImagingAccessInstance* ImagingAccess; +typedef struct ImagingHistogramInstance* ImagingHistogram; +typedef struct ImagingOutlineInstance* ImagingOutline; +typedef struct ImagingPaletteInstance* ImagingPalette; + +/* handle magics (used with PyCObject). */ +#define IMAGING_MAGIC "PIL Imaging" + +/* pixel types */ +#define IMAGING_TYPE_UINT8 0 +#define IMAGING_TYPE_INT32 1 +#define IMAGING_TYPE_FLOAT32 2 +#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */ + +struct ImagingMemoryInstance { + + /* Format */ + char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */ + int type; /* Data type (IMAGING_TYPE_*) */ + int depth; /* Depth (ignored in this version) */ + int bands; /* Number of bands (1, 2, 3, or 4) */ + int xsize; /* Image dimension. */ + int ysize; + + /* Colour palette (for "P" images only) */ + ImagingPalette palette; + + /* Data pointers */ + UINT8 **image8; /* Set for 8-bit images (pixelsize=1). */ + INT32 **image32; /* Set for 32-bit images (pixelsize=4). */ + + /* Internals */ + char **image; /* Actual raster data. */ + char *block; /* Set if data is allocated in a single block. */ + + int pixelsize; /* Size of a pixel, in bytes (1, 2 or 4) */ + int linesize; /* Size of a line, in bytes (xsize * pixelsize) */ + + /* Virtual methods */ + void (*destroy)(Imaging im); +}; + + +#define IMAGING_PIXEL_1(im,x,y) ((im)->image8[(y)][(x)]) +#define IMAGING_PIXEL_L(im,x,y) ((im)->image8[(y)][(x)]) +#define IMAGING_PIXEL_LA(im,x,y) ((im)->image[(y)][(x)*4]) +#define IMAGING_PIXEL_P(im,x,y) ((im)->image8[(y)][(x)]) +#define IMAGING_PIXEL_PA(im,x,y) ((im)->image[(y)][(x)*4]) +#define IMAGING_PIXEL_I(im,x,y) ((im)->image32[(y)][(x)]) +#define IMAGING_PIXEL_F(im,x,y) (((FLOAT32*)(im)->image32[y])[x]) +#define IMAGING_PIXEL_RGB(im,x,y) ((im)->image[(y)][(x)*4]) +#define IMAGING_PIXEL_RGBA(im,x,y) ((im)->image[(y)][(x)*4]) +#define IMAGING_PIXEL_CMYK(im,x,y) ((im)->image[(y)][(x)*4]) +#define IMAGING_PIXEL_YCbCr(im,x,y) ((im)->image[(y)][(x)*4]) + +#define IMAGING_PIXEL_UINT8(im,x,y) ((im)->image8[(y)][(x)]) +#define IMAGING_PIXEL_INT32(im,x,y) ((im)->image32[(y)][(x)]) +#define IMAGING_PIXEL_FLOAT32(im,x,y) (((FLOAT32*)(im)->image32[y])[x]) + +struct ImagingAccessInstance { + const char* mode; + void* (*line)(Imaging im, int x, int y); + void (*get_pixel)(Imaging im, int x, int y, void* pixel); + void (*put_pixel)(Imaging im, int x, int y, const void* pixel); +}; + +struct ImagingHistogramInstance { + + /* Format */ + char mode[4+1]; /* Band names (of corresponding source image) */ + int bands; /* Number of bands (1, 3, or 4) */ + + /* Data */ + long *histogram; /* Histogram (bands*256 longs) */ + +}; + + +struct ImagingPaletteInstance { + + /* Format */ + char mode[4+1]; /* Band names */ + + /* Data */ + UINT8 palette[1024];/* Palette data (same format as image data) */ + + INT16* cache; /* Palette cache (used for predefined palettes) */ + int keep_cache; /* This palette will be reused; keep cache */ + +}; + + +/* Objects */ +/* ------- */ + +extern int ImagingNewCount; + +extern Imaging ImagingNew(const char* mode, int xsize, int ysize); +extern Imaging ImagingNew2(const char* mode, Imaging imOut, Imaging imIn); +extern void ImagingDelete(Imaging im); + +extern Imaging ImagingNewBlock(const char* mode, int xsize, int ysize); +extern Imaging ImagingNewArray(const char* mode, int xsize, int ysize); +extern Imaging ImagingNewMap(const char* filename, int readonly, + const char* mode, int xsize, int ysize); + +extern Imaging ImagingNewPrologue(const char *mode, + unsigned xsize, unsigned ysize); +extern Imaging ImagingNewPrologueSubtype(const char *mode, + unsigned xsize, unsigned ysize, + int structure_size); +extern Imaging ImagingNewEpilogue(Imaging im); + +extern void ImagingCopyInfo(Imaging destination, Imaging source); + +extern void ImagingHistogramDelete(ImagingHistogram histogram); + +extern void ImagingAccessInit(void); +extern ImagingAccess ImagingAccessNew(Imaging im); +extern void _ImagingAccessDelete(Imaging im, ImagingAccess access); +#define ImagingAccessDelete(im, access) /* nop, for now */ +/*#define ImagingAccessDelete(im, access) \ + ((access)->dynamic ? _ImagingAccessDelete((im), (access)), 0 : 0)) */ + +extern ImagingPalette ImagingPaletteNew(const char *mode); +extern ImagingPalette ImagingPaletteNewBrowser(void); +extern ImagingPalette ImagingPaletteDuplicate(ImagingPalette palette); +extern void ImagingPaletteDelete(ImagingPalette palette); + +extern int ImagingPaletteCachePrepare(ImagingPalette palette); +extern void ImagingPaletteCacheUpdate(ImagingPalette palette, + int r, int g, int b); +extern void ImagingPaletteCacheDelete(ImagingPalette palette); + +#define ImagingPaletteCache(p, r, g, b)\ + p->cache[(r>>2) + (g>>2)*64 + (b>>2)*64*64] + +extern Imaging ImagingQuantize(Imaging im, int colours, int mode, int kmeans); + +/* Threading */ +/* --------- */ + +typedef void* ImagingSectionCookie; + +extern void ImagingSectionEnter(ImagingSectionCookie* cookie); +extern void ImagingSectionLeave(ImagingSectionCookie* cookie); + +/* Exceptions */ +/* ---------- */ + +extern void* ImagingError_IOError(void); +extern void* ImagingError_MemoryError(void); +extern void* ImagingError_ModeError(void); /* maps to ValueError by default */ +extern void* ImagingError_Mismatch(void); /* maps to ValueError by default */ +extern void* ImagingError_ValueError(const char* message); +extern void ImagingError_Clear(void); + +/* Transform callbacks */ +/* ------------------- */ + +/* standard transforms */ +#define IMAGING_TRANSFORM_AFFINE 0 +#define IMAGING_TRANSFORM_PERSPECTIVE 2 +#define IMAGING_TRANSFORM_QUAD 3 + + +/* standard filters */ +#define IMAGING_TRANSFORM_NEAREST 0 +#define IMAGING_TRANSFORM_ANTIALIAS 1 +#define IMAGING_TRANSFORM_BILINEAR 2 +#define IMAGING_TRANSFORM_BICUBIC 3 + +typedef int (*ImagingTransformMap)(double* X, double* Y, + int x, int y, void* data); +typedef int (*ImagingTransformFilter)(void* out, Imaging im, + double x, double y, + void* data); + +/* Image Manipulation Methods */ +/* -------------------------- */ + +extern Imaging ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha); +extern Imaging ImagingCopy(Imaging im); +extern Imaging ImagingConvert(Imaging im, const char* mode, ImagingPalette palette, int dither); +extern Imaging ImagingConvertInPlace(Imaging im, const char* mode); +extern Imaging ImagingConvertMatrix(Imaging im, const char *mode, float m[]); +extern Imaging ImagingCrop(Imaging im, int x0, int y0, int x1, int y1); +extern Imaging ImagingExpand(Imaging im, int x, int y, int mode); +extern Imaging ImagingFill(Imaging im, const void* ink); +extern int ImagingFill2( + Imaging into, const void* ink, Imaging mask, + int x0, int y0, int x1, int y1); +extern Imaging ImagingFillBand(Imaging im, int band, int color); +extern Imaging ImagingFillLinearGradient(const char* mode); +extern Imaging ImagingFillRadialGradient(const char* mode); +extern Imaging ImagingFilter( + Imaging im, int xsize, int ysize, const FLOAT32* kernel, + FLOAT32 offset, FLOAT32 divisor); +extern Imaging ImagingFlipLeftRight(Imaging imOut, Imaging imIn); +extern Imaging ImagingFlipTopBottom(Imaging imOut, Imaging imIn); +extern Imaging ImagingGaussianBlur(Imaging im, Imaging imOut, float radius); +extern Imaging ImagingGetBand(Imaging im, int band); +extern int ImagingGetBBox(Imaging im, int bbox[4]); +typedef struct { int x, y; INT32 count; INT32 pixel; } ImagingColorItem; +extern ImagingColorItem* ImagingGetColors(Imaging im, int maxcolors, + int *colors); +extern int ImagingGetExtrema(Imaging im, void *extrema); +extern int ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj); +extern ImagingHistogram ImagingGetHistogram( + Imaging im, Imaging mask, void *extrema); +extern Imaging ImagingModeFilter(Imaging im, int size); +extern Imaging ImagingNegative(Imaging im); +extern Imaging ImagingOffset(Imaging im, int xoffset, int yoffset); +extern int ImagingPaste( + Imaging into, Imaging im, Imaging mask, + int x0, int y0, int x1, int y1); +extern Imaging ImagingPoint( + Imaging im, const char* tablemode, const void* table); +extern Imaging ImagingPointTransform( + Imaging imIn, double scale, double offset); +extern Imaging ImagingPutBand(Imaging im, Imaging imIn, int band); +extern Imaging ImagingRankFilter(Imaging im, int size, int rank); +extern Imaging ImagingResize(Imaging imOut, Imaging imIn, int filter); +extern Imaging ImagingRotate( + Imaging imOut, Imaging imIn, double theta, int filter); +extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn); +extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn); +extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn); +extern Imaging ImagingStretch(Imaging imOut, Imaging imIn, int filter); +extern Imaging ImagingTransformPerspective( + Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, + double a[8], int filter, int fill); +extern Imaging ImagingTransformAffine( + Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, + double a[6], int filter, int fill); +extern Imaging ImagingTransformQuad( + Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, + double a[8], int filter, int fill); +extern Imaging ImagingTransform( + Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, + ImagingTransformMap transform, void* transform_data, + ImagingTransformFilter filter, void* filter_data, + int fill); +extern Imaging ImagingUnsharpMask( + Imaging im, Imaging imOut, float radius, int percent, int threshold); + +extern Imaging ImagingCopy2(Imaging imOut, Imaging imIn); +extern Imaging ImagingConvert2(Imaging imOut, Imaging imIn); + +/* Channel operations */ +/* any mode, except "F" */ +extern Imaging ImagingChopLighter(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopDarker(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopDifference(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopMultiply(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopScreen(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopAdd( + Imaging imIn1, Imaging imIn2, float scale, int offset); +extern Imaging ImagingChopSubtract( + Imaging imIn1, Imaging imIn2, float scale, int offset); +extern Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2); + +/* "1" images only */ +extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2); +extern Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2); + +/* Image measurement */ +extern void ImagingCrack(Imaging im, int x0, int y0); + +/* Graphics */ +struct ImagingAffineMatrixInstance { + float a[9]; +}; + +typedef struct ImagingAffineMatrixInstance *ImagingAffineMatrix; + +extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink, int op); +extern int ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, + const void* ink, int op); +extern int ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink, int fill, + int op); +extern int ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1, + const void* ink, int fill, int op); +extern int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, + const void* ink, int op); +extern int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1, + const void* ink, int width, int op); +extern int ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1, + int start, int end, const void* ink, int fill, + int op); +extern int ImagingDrawPoint(Imaging im, int x, int y, const void* ink, int op); +extern int ImagingDrawPolygon(Imaging im, int points, int *xy, + const void* ink, int fill, int op); +extern int ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1, + const void* ink, int fill, int op); + +/* Level 2 graphics (WORK IN PROGRESS) */ +extern ImagingOutline ImagingOutlineNew(void); +extern void ImagingOutlineDelete(ImagingOutline outline); + +extern int ImagingDrawOutline(Imaging im, ImagingOutline outline, + const void* ink, int fill, int op); + +extern int ImagingOutlineMove(ImagingOutline outline, float x, float y); +extern int ImagingOutlineLine(ImagingOutline outline, float x, float y); +extern int ImagingOutlineCurve(ImagingOutline outline, float x1, float y1, + float x2, float y2, float x3, float y3); +extern int ImagingOutlineTransform(ImagingOutline outline, double a[6]); + +extern int ImagingOutlineClose(ImagingOutline outline); + +/* Special effects */ +extern Imaging ImagingEffectSpread(Imaging imIn, int distance); +extern Imaging ImagingEffectNoise(int xsize, int ysize, float sigma); +extern Imaging ImagingEffectMandelbrot(int xsize, int ysize, + double extent[4], int quality); + +/* Obsolete */ +extern int ImagingToString(Imaging im, int orientation, char *buffer); +extern int ImagingFromString(Imaging im, int orientation, char *buffer); + + +/* File I/O */ +/* -------- */ + +/* Built-in drivers */ +extern Imaging ImagingOpenPPM(const char* filename); +extern int ImagingSavePPM(Imaging im, const char* filename); + +/* Utility functions */ +extern UINT32 ImagingCRC32(UINT32 crc, UINT8* buffer, int bytes); + +/* Codecs */ +typedef struct ImagingCodecStateInstance *ImagingCodecState; +typedef int (*ImagingCodec)(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); + +extern int ImagingBitDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingEpsEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingFliDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingGifDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingGifEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingHexDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#ifdef HAVE_LIBJPEG +extern int ImagingJpegDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingJpegEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#endif +extern int ImagingLzwDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#ifdef HAVE_LIBMPEG +extern int ImagingMpegDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#endif +extern int ImagingMspDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingPackbitsDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingPcdDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingPcxDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingPcxEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingRawDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingRawEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingSunRleDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingTgaRleDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingXbmDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingXbmEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#ifdef HAVE_LIBZ +extern int ImagingZipDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +extern int ImagingZipEncode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#endif + +typedef void (*ImagingShuffler)(UINT8* out, const UINT8* in, int pixels); + +/* Public shufflers */ +extern void ImagingPackRGB(UINT8* out, const UINT8* in, int pixels); +extern void ImagingPackBGR(UINT8* out, const UINT8* in, int pixels); +extern void ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels); +extern void ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels); +extern void ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels); +extern void ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels); +extern void ImagingUnpackYCbCr(UINT8* out, const UINT8* in, int pixels); + +extern void ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels); +extern void ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels); + +extern ImagingShuffler ImagingFindUnpacker(const char* mode, + const char* rawmode, int* bits_out); +extern ImagingShuffler ImagingFindPacker(const char* mode, + const char* rawmode, int* bits_out); + +struct ImagingCodecStateInstance { + int count; + int state; + int errcode; + int x, y; + int ystep; + int xsize, ysize, xoff, yoff; + ImagingShuffler shuffle; + int bits, bytes; + UINT8 *buffer; + void *context; +}; + +/* Errcodes */ +#define IMAGING_CODEC_END 1 +#define IMAGING_CODEC_OVERRUN -1 +#define IMAGING_CODEC_BROKEN -2 +#define IMAGING_CODEC_UNKNOWN -3 +#define IMAGING_CODEC_CONFIG -8 +#define IMAGING_CODEC_MEMORY -9 + +#if defined(__cplusplus) +} +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h new file mode 100755 index 00000000000..d39165f3cfd --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h @@ -0,0 +1,104 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * declarations for the IJG JPEG codec interface. + * + * Copyright (c) 1995-2001 by Secret Labs AB + * Copyright (c) 1995-1996 by Fredrik Lundh + */ + +#include "jpeglib.h" + +#include + + +typedef struct { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +} JPEGERROR; + + +/* -------------------------------------------------------------------- */ +/* Decoder */ + +typedef struct { + struct jpeg_source_mgr pub; + int skip; +} JPEGSOURCE; + +typedef struct { + + /* CONFIGURATION */ + + /* Jpeg file mode (empty if not known) */ + char jpegmode[8+1]; + + /* Converter output mode (input to the shuffler). If empty, + convert conversions are disabled */ + char rawmode[8+1]; + + /* If set, trade quality for speed */ + int draft; + + /* Scale factor (1, 2, 4, 8) */ + int scale; + + /* PRIVATE CONTEXT (set by decoder) */ + + struct jpeg_decompress_struct cinfo; + + JPEGERROR error; + + JPEGSOURCE source; + +} JPEGSTATE; + + +/* -------------------------------------------------------------------- */ +/* Encoder */ + +typedef struct { + struct jpeg_destination_mgr pub; + /* might add something some other day */ +} JPEGDESTINATION; + +typedef struct { + + /* CONFIGURATION */ + + /* Quality (1-100, 0 means default) */ + int quality; + + /* Progressive mode */ + int progressive; + + /* Smoothing factor (1-100, 0 means none) */ + int smooth; + + /* Optimize Huffman tables (slow) */ + int optimize; + + /* Stream type (0=full, 1=tables only, 2=image only) */ + int streamtype; + + /* DPI setting (0=square pixels, otherwide DPI) */ + int xdpi, ydpi; + + /* Chroma Subsampling (-1=default, 0=none, 1=medium, 2=high) */ + int subsampling; + + /* Extra data (to be injected after header) */ + char* extra; int extra_size; + + /* PRIVATE CONTEXT (set by encoder) */ + + struct jpeg_compress_struct cinfo; + + JPEGERROR error; + + JPEGDESTINATION destination; + + int extra_offset; + +} JPEGENCODERSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c new file mode 100755 index 00000000000..11b2767ba2f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c @@ -0,0 +1,267 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for JPEG image data. + * + * history: + * 1996-05-02 fl Created + * 1996-05-05 fl Handle small JPEG files correctly + * 1996-05-28 fl Added "draft mode" support + * 1997-01-25 fl Added colour conversion override + * 1998-01-31 fl Adapted to libjpeg 6a + * 1998-07-12 fl Extended YCbCr support + * 1998-12-29 fl Added new state to handle suspension in multipass modes + * 2000-10-12 fl Suppress warnings + * 2000-12-04 fl Suppress errors beyond end of image data + * + * Copyright (c) 1998-2000 Secret Labs AB + * Copyright (c) 1996-2000 Fredrik Lundh + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + +#ifdef HAVE_LIBJPEG + +#undef HAVE_PROTOTYPES +#undef HAVE_STDLIB_H +#undef HAVE_STDDEF_H +#undef UINT8 +#undef UINT16 +#undef UINT32 +#undef INT16 +#undef INT32 + +#include "Jpeg.h" + + +/* -------------------------------------------------------------------- */ +/* Suspending input handler */ +/* -------------------------------------------------------------------- */ + +METHODDEF(void) +stub(j_decompress_ptr cinfo) +{ + /* empty */ +} + +METHODDEF(boolean) +fill_input_buffer(j_decompress_ptr cinfo) +{ + /* Suspension */ + return FALSE; +} + +METHODDEF(void) +skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + JPEGSOURCE* source = (JPEGSOURCE*) cinfo->src; + + if (num_bytes > (long) source->pub.bytes_in_buffer) { + /* We need to skip more data than we have in the buffer. + This will force the JPEG library to suspend decoding. */ + source->skip = num_bytes - source->pub.bytes_in_buffer; + source->pub.next_input_byte += source->pub.bytes_in_buffer; + source->pub.bytes_in_buffer = 0; + } else { + /* Skip portion of the buffer */ + source->pub.bytes_in_buffer -= num_bytes; + source->pub.next_input_byte += num_bytes; + source->skip = 0; + } +} + + +GLOBAL(void) +jpeg_buffer_src(j_decompress_ptr cinfo, JPEGSOURCE* source) +{ + cinfo->src = (void*) source; + + /* Prepare for suspending reader */ + source->pub.init_source = stub; + source->pub.fill_input_buffer = fill_input_buffer; + source->pub.skip_input_data = skip_input_data; + source->pub.resync_to_restart = jpeg_resync_to_restart; + source->pub.term_source = stub; + source->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + + source->skip = 0; +} + + +/* -------------------------------------------------------------------- */ +/* Error handler */ +/* -------------------------------------------------------------------- */ + +METHODDEF(void) +error(j_common_ptr cinfo) +{ + JPEGERROR* error; + error = (JPEGERROR*) cinfo->err; + longjmp(error->setjmp_buffer, 1); +} + +METHODDEF(void) +output(j_common_ptr cinfo) +{ + /* nothing */ +} + +/* -------------------------------------------------------------------- */ +/* Decoder */ +/* -------------------------------------------------------------------- */ + +int +ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + JPEGSTATE* context = (JPEGSTATE*) state->context; + int ok; + + if (setjmp(context->error.setjmp_buffer)) { + /* JPEG error handler */ + jpeg_destroy_decompress(&context->cinfo); + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + if (!state->state) { + + /* Setup decompression context */ + context->cinfo.err = jpeg_std_error(&context->error.pub); + context->error.pub.error_exit = error; + context->error.pub.output_message = output; + jpeg_create_decompress(&context->cinfo); + jpeg_buffer_src(&context->cinfo, &context->source); + + /* Ready to decode */ + state->state = 1; + + } + + /* Load the source buffer */ + context->source.pub.next_input_byte = buf; + context->source.pub.bytes_in_buffer = bytes; + + if (context->source.skip > 0) { + skip_input_data(&context->cinfo, context->source.skip); + if (context->source.skip > 0) + return context->source.pub.next_input_byte - buf; + } + + switch (state->state) { + + case 1: + + /* Read JPEG header, until we find an image body. */ + do { + + /* Note that we cannot return unless we have decoded + as much data as possible. */ + ok = jpeg_read_header(&context->cinfo, FALSE); + + } while (ok == JPEG_HEADER_TABLES_ONLY); + + if (ok == JPEG_SUSPENDED) + break; + + /* Decoder settings */ + + /* jpegmode indicates whats in the file; if not set, we'll + trust the decoder */ + if (strcmp(context->jpegmode, "L") == 0) + context->cinfo.jpeg_color_space = JCS_GRAYSCALE; + else if (strcmp(context->jpegmode, "RGB") == 0) + context->cinfo.jpeg_color_space = JCS_RGB; + else if (strcmp(context->jpegmode, "CMYK") == 0) + context->cinfo.jpeg_color_space = JCS_CMYK; + else if (strcmp(context->jpegmode, "YCbCr") == 0) + context->cinfo.jpeg_color_space = JCS_YCbCr; + else if (strcmp(context->jpegmode, "YCbCrK") == 0) { + context->cinfo.jpeg_color_space = JCS_YCCK; + } + + /* rawmode indicates what we want from the decoder. if not + set, conversions are disabled */ + if (strcmp(context->rawmode, "L") == 0) + context->cinfo.out_color_space = JCS_GRAYSCALE; + else if (strcmp(context->rawmode, "RGB") == 0) + context->cinfo.out_color_space = JCS_RGB; + else if (strcmp(context->rawmode, "CMYK") == 0 || + strcmp(context->rawmode, "CMYK;I") == 0) + context->cinfo.out_color_space = JCS_CMYK; + else if (strcmp(context->rawmode, "YCbCr") == 0) + context->cinfo.out_color_space = JCS_YCbCr; + else if (strcmp(context->rawmode, "YCbCrK") == 0) + context->cinfo.out_color_space = JCS_YCCK; + else { + /* Disable decoder conversions */ + context->cinfo.jpeg_color_space = JCS_UNKNOWN; + context->cinfo.out_color_space = JCS_UNKNOWN; + } + + if (context->scale > 1) { + context->cinfo.scale_num = 1; + context->cinfo.scale_denom = context->scale; + } + if (context->draft) { + context->cinfo.do_fancy_upsampling = FALSE; + context->cinfo.dct_method = JDCT_FASTEST; + } + + state->state++; + /* fall through */ + + case 2: + + /* Set things up for decompression (this processes the entire + file if necessary to return data line by line) */ + if (!jpeg_start_decompress(&context->cinfo)) + break; + + state->state++; + /* fall through */ + + case 3: + + /* Decompress a single line of data */ + ok = 1; + while (state->y < state->ysize) { + ok = jpeg_read_scanlines(&context->cinfo, &state->buffer, 1); + if (ok != 1) + break; + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + state->y++; + } + if (ok != 1) + break; + state->state++; + /* fall through */ + + case 4: + + /* Finish decompression */ + if (!jpeg_finish_decompress(&context->cinfo)) { + /* FIXME: add strictness mode test */ + if (state->y < state->ysize) + break; + } + + /* Clean up */ + jpeg_destroy_decompress(&context->cinfo); + /* if (jerr.pub.num_warnings) return BROKEN; */ + return -1; + + } + + /* Return number of bytes consumed */ + return context->source.pub.next_input_byte - buf; + +} + +#endif + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c new file mode 100755 index 00000000000..1e2191a69b0 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c @@ -0,0 +1,284 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * coder for JPEG data + * + * history: + * 1996-05-06 fl created + * 1996-07-16 fl don't drop last block of encoded data + * 1996-12-30 fl added quality and progressive settings + * 1997-01-08 fl added streamtype settings + * 1998-01-31 fl adapted to libjpeg 6a + * 1998-07-12 fl added YCbCr support + * 2001-04-16 fl added DPI write support + * + * Copyright (c) 1997-2001 by Secret Labs AB + * Copyright (c) 1995-1997 by Fredrik Lundh + * + * See the README file for details on usage and redistribution. + */ + + +#include "Imaging.h" + +#ifdef HAVE_LIBJPEG + +#undef HAVE_PROTOTYPES +#undef HAVE_STDLIB_H +#undef HAVE_STDDEF_H +#undef UINT8 +#undef UINT16 +#undef UINT32 +#undef INT16 +#undef INT32 + +#include "Jpeg.h" + +/* -------------------------------------------------------------------- */ +/* Suspending output handler */ +/* -------------------------------------------------------------------- */ + +METHODDEF(void) +stub(j_compress_ptr cinfo) +{ + /* empty */ +} + +METHODDEF(boolean) +empty_output_buffer (j_compress_ptr cinfo) +{ + /* Suspension */ + return FALSE; +} + +GLOBAL(void) +jpeg_buffer_dest(j_compress_ptr cinfo, JPEGDESTINATION* destination) +{ + cinfo->dest = (void*) destination; + + destination->pub.init_destination = stub; + destination->pub.empty_output_buffer = empty_output_buffer; + destination->pub.term_destination = stub; +} + + +/* -------------------------------------------------------------------- */ +/* Error handler */ +/* -------------------------------------------------------------------- */ + +METHODDEF(void) +error(j_common_ptr cinfo) +{ + JPEGERROR* error; + error = (JPEGERROR*) cinfo->err; + (*cinfo->err->output_message) (cinfo); + longjmp(error->setjmp_buffer, 1); +} + + +/* -------------------------------------------------------------------- */ +/* Encoder */ +/* -------------------------------------------------------------------- */ + +int +ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + JPEGENCODERSTATE* context = (JPEGENCODERSTATE*) state->context; + int ok; + + if (setjmp(context->error.setjmp_buffer)) { + /* JPEG error handler */ + jpeg_destroy_compress(&context->cinfo); + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + if (!state->state) { + + /* Setup compression context (very similar to the decoder) */ + context->cinfo.err = jpeg_std_error(&context->error.pub); + context->error.pub.error_exit = error; + jpeg_create_compress(&context->cinfo); + jpeg_buffer_dest(&context->cinfo, &context->destination); + + context->extra_offset = 0; + + /* Ready to encode */ + state->state = 1; + + } + + /* Load the destination buffer */ + context->destination.pub.next_output_byte = buf; + context->destination.pub.free_in_buffer = bytes; + + switch (state->state) { + + case 1: + + context->cinfo.image_width = state->xsize; + context->cinfo.image_height = state->ysize; + + switch (state->bits) { + case 8: + context->cinfo.input_components = 1; + context->cinfo.in_color_space = JCS_GRAYSCALE; + break; + case 24: + context->cinfo.input_components = 3; + if (strcmp(im->mode, "YCbCr") == 0) + context->cinfo.in_color_space = JCS_YCbCr; + else + context->cinfo.in_color_space = JCS_RGB; + break; + case 32: + context->cinfo.input_components = 4; + context->cinfo.in_color_space = JCS_CMYK; + break; + default: + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + /* Compressor configuration */ + jpeg_set_defaults(&context->cinfo); + if (context->quality > 0) + jpeg_set_quality(&context->cinfo, context->quality, 1); + + /* Set subsampling options */ + switch (context->subsampling) + { + case 0: /* 1x1 1x1 1x1 (4:4:4) : None */ + { + context->cinfo.comp_info[0].h_samp_factor = 1; + context->cinfo.comp_info[0].v_samp_factor = 1; + context->cinfo.comp_info[1].h_samp_factor = 1; + context->cinfo.comp_info[1].v_samp_factor = 1; + context->cinfo.comp_info[2].h_samp_factor = 1; + context->cinfo.comp_info[2].v_samp_factor = 1; + break; + } + case 1: /* 2x1, 1x1, 1x1 (4:2:2) : Medium */ + { + context->cinfo.comp_info[0].h_samp_factor = 2; + context->cinfo.comp_info[0].v_samp_factor = 1; + context->cinfo.comp_info[1].h_samp_factor = 1; + context->cinfo.comp_info[1].v_samp_factor = 1; + context->cinfo.comp_info[2].h_samp_factor = 1; + context->cinfo.comp_info[2].v_samp_factor = 1; + break; + } + case 2: /* 2x2, 1x1, 1x1 (4:1:1) : High */ + { + context->cinfo.comp_info[0].h_samp_factor = 2; + context->cinfo.comp_info[0].v_samp_factor = 2; + context->cinfo.comp_info[1].h_samp_factor = 1; + context->cinfo.comp_info[1].v_samp_factor = 1; + context->cinfo.comp_info[2].h_samp_factor = 1; + context->cinfo.comp_info[2].v_samp_factor = 1; + break; + } + default: + { + /* Use the lib's default */ + break; + } + } + if (context->progressive) + jpeg_simple_progression(&context->cinfo); + context->cinfo.smoothing_factor = context->smooth; + context->cinfo.optimize_coding = (boolean) context->optimize; + if (context->xdpi > 0 && context->ydpi > 0) { + context->cinfo.density_unit = 1; /* dots per inch */ + context->cinfo.X_density = context->xdpi; + context->cinfo.Y_density = context->ydpi; + } + switch (context->streamtype) { + case 1: + /* tables only -- not yet implemented */ + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + case 2: + /* image only */ + jpeg_suppress_tables(&context->cinfo, TRUE); + jpeg_start_compress(&context->cinfo, FALSE); + /* suppress extra section */ + context->extra_offset = context->extra_size; + break; + default: + /* interchange stream */ + jpeg_start_compress(&context->cinfo, TRUE); + break; + } + state->state++; + /* fall through */ + + case 2: + + if (context->extra) { + /* copy extra buffer to output buffer */ + unsigned int n = context->extra_size - context->extra_offset; + if (n > context->destination.pub.free_in_buffer) + n = context->destination.pub.free_in_buffer; + memcpy(context->destination.pub.next_output_byte, + context->extra + context->extra_offset, n); + context->destination.pub.next_output_byte += n; + context->destination.pub.free_in_buffer -= n; + context->extra_offset += n; + if (context->extra_offset >= context->extra_size) + state->state++; + else + break; + } else + state->state++; + + case 3: + + ok = 1; + while (state->y < state->ysize) { + state->shuffle(state->buffer, + (UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->xsize); + ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1); + if (ok != 1) + break; + state->y++; + } + + if (ok != 1) + break; + state->state++; + /* fall through */ + + case 4: + + /* Finish compression */ + if (context->destination.pub.free_in_buffer < 100) + break; + jpeg_finish_compress(&context->cinfo); + + /* Clean up */ + if (context->extra) + free(context->extra); + jpeg_destroy_compress(&context->cinfo); + /* if (jerr.pub.num_warnings) return BROKEN; */ + state->errcode = IMAGING_CODEC_END; + break; + + } + + /* Return number of bytes in output buffer */ + return context->destination.pub.next_output_byte - buf; + +} + +const char* +ImagingJpegVersion(void) +{ + static char version[20]; + sprintf(version, "%d.%d", JPEG_LIB_VERSION / 10, JPEG_LIB_VERSION % 10); + return version; +} + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h new file mode 100755 index 00000000000..7d087ac4779 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h @@ -0,0 +1,52 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * declarations for the TIFF LZW decoder. + * + * Copyright (c) Fredrik Lundh 1995-96. + */ + + +/* Max size for LZW code words */ + +#define LZWBITS 12 + +#define LZWTABLE (1< +#include /* memcpy() */ + +#include "Lzw.h" + + +int +ImagingLzwDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8* p; + int c, i; + int thiscode; + LZWSTATE* context = (LZWSTATE*) state->context; + + unsigned char *ptr = buf; + + if (!state->state) { + + /* Clear code */ + context->clear = 1 << 8; + + /* End code */ + context->end = context->clear + 1; + + state->state = 1; + } + + for (;;) { + + if (state->state == 1) { + + /* First free entry in table */ + context->next = context->clear + 2; + + /* Initial code size */ + context->codesize = 8 + 1; + context->codemask = (1 << context->codesize) - 1; + + /* Buffer pointer. We fill the buffer from right, which + allows us to return all of it in one operation. */ + context->bufferindex = LZWBUFFER; + + state->state = 2; + } + + if (context->bufferindex < LZWBUFFER) { + + /* Return whole buffer in one chunk */ + i = LZWBUFFER - context->bufferindex; + p = &context->buffer[context->bufferindex]; + + context->bufferindex = LZWBUFFER; + + } else { + + /* Get current symbol */ + while (context->bitcount < context->codesize) { + + if (bytes < 1) + return ptr - buf;; + + /* Read next byte */ + c = *ptr++; bytes--; + + /* New bits are shifted in from from the right. */ + context->bitbuffer = (context->bitbuffer << 8) | c; + context->bitcount += 8; + + } + + /* Extract current symbol from bit buffer. */ + c = (context->bitbuffer >> (context->bitcount - + context->codesize)) + & context->codemask; + + /* Adjust buffer */ + context->bitcount -= context->codesize; + + /* If c is less than clear, it's a data byte. Otherwise, + it's either clear/end or a code symbol which should be + expanded. */ + + if (c == context->clear) { + if (state->state != 2) + state->state = 1; + continue; + } + + if (c == context->end) + break; + + i = 1; + p = &context->lastdata; + + if (state->state == 2) { + + /* First valid symbol after clear; use as is */ + if (c > context->clear) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->lastdata = context->lastcode = c; + state->state = 3; + + } else { + + thiscode = c; + + if (c > context->next) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + if (c == context->next) { + + /* c == next is allowed, by some strange reason */ + if (context->bufferindex <= 0) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->buffer[--context->bufferindex] = context->lastdata; + c = context->lastcode; + } + + while (c >= context->clear) { + + /* Copy data string to buffer (beginning from right) */ + + if (context->bufferindex <= 0 || c >= LZWTABLE) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + context->buffer[--context->bufferindex] = + context->data[c]; + c = context->link[c]; + } + + context->lastdata = c; + + if (context->next < LZWTABLE) { + + /* While we still have room for it, add this + symbol to the table. */ + context->data[context->next] = c; + context->link[context->next] = context->lastcode; + + context->next++; + + if (context->next == context->codemask && + context->codesize < LZWBITS) { + + /* Expand code size */ + context->codesize++; + context->codemask = (1 << context->codesize) - 1; + + } + } + context->lastcode = thiscode; + } + } + + /* Update the output image */ + for (c = 0; c < i; c++) { + + state->buffer[state->x] = p[c]; + + if (++state->x >= state->bytes) { + + int x, bpp; + + /* Apply filter */ + switch (context->filter) { + case 2: + /* Horizontal differing ("prior") */ + bpp = (state->bits + 7) / 8; + for (x = bpp; x < state->bytes; x++) + state->buffer[x] += state->buffer[x-bpp]; + } + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) + /* End of file (errcode = 0) */ + return -1; + } + } + } + + return ptr - buf; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c new file mode 100755 index 00000000000..5d2f031cf3c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c @@ -0,0 +1,74 @@ +/* + * The Python Imaging Library + * $Id$ + * + * colour and luminance matrix transforms + * + * history: + * 1996-05-18 fl: created (brute force implementation) + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +#define CLIPF(v) ((v <= 0.0) ? 0 : (v >= 255.0F) ? 255 : (UINT8) v) + + +Imaging +ImagingConvertMatrix(Imaging im, const char *mode, float m[]) +{ + Imaging imOut; + int x, y; + + /* Assume there's enough data in the buffer */ + if (!im) + return (Imaging) ImagingError_ModeError(); + + if (strcmp(mode, "L") == 0 && im->bands == 3) { + + imOut = ImagingNew("L", im->xsize, im->ysize); + if (!imOut) + return NULL; + + for (y = 0; y < im->ysize; y++) { + UINT8* in = (UINT8*) im->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + + for (x = 0; x < im->xsize; x++) { + float v = m[0]*in[0] + m[1]*in[1] + m[2]*in[2] + m[3] + 0.5; + out[x] = CLIPF(v); + in += 4; + } + } + + } else if (strlen(mode) == 3 && im->bands == 3) { + + imOut = ImagingNew(mode, im->xsize, im->ysize); + if (!imOut) + return NULL; + + for (y = 0; y < im->ysize; y++) { + UINT8* in = (UINT8*) im->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + + for (x = 0; x < im->xsize; x++) { + float v0 = m[0]*in[0] + m[1]*in[1] + m[2]*in[2] + m[3] + 0.5; + float v1 = m[4]*in[0] + m[5]*in[1] + m[6]*in[2] + m[7] + 0.5; + float v2 = m[8]*in[0] + m[9]*in[1] + m[10]*in[2] + m[11] + 0.5; + out[0] = CLIPF(v0); + out[1] = CLIPF(v1); + out[2] = CLIPF(v2); + in += 4; out += 4; + } + } + } else + return (Imaging) ImagingError_ModeError(); + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c new file mode 100755 index 00000000000..ad11d87d4a3 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c @@ -0,0 +1,78 @@ +/* + * The Python Imaging Library + * $Id$ + * + * mode filter + * + * history: + * 2002-06-08 fl Created (based on code from IFUNC95) + * 2004-10-05 fl Rewritten; use a simpler brute-force algorithm + * + * Copyright (c) Secret Labs AB 2002-2004. All rights reserved. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +Imaging +ImagingModeFilter(Imaging im, int size) +{ + Imaging imOut; + int x, y, i; + int xx, yy; + int maxcount; + UINT8 maxpixel; + int histogram[256]; + + if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) + return (Imaging) ImagingError_ModeError(); + + imOut = ImagingNew(im->mode, im->xsize, im->ysize); + if (!imOut) + return NULL; + + size = size / 2; + + for (y = 0; y < imOut->ysize; y++) { + UINT8* out = &IMAGING_PIXEL_L(imOut, 0, y); + for (x = 0; x < imOut->xsize; x++) { + + /* calculate histogram over current area */ + + /* FIXME: brute force! to improve, update the histogram + incrementally. may also add a "frequent list", like in + the old implementation, but I'm not sure that's worth + the added complexity... */ + + memset(histogram, 0, sizeof(histogram)); + for (yy = y - size; yy <= y + size; yy++) + if (yy >= 0 && yy < imOut->ysize) { + UINT8* in = &IMAGING_PIXEL_L(im, 0, yy); + for (xx = x - size; xx <= x + size; xx++) + if (xx >= 0 && xx < imOut->xsize) + histogram[in[xx]]++; + } + + /* find most frequent pixel value in this region */ + maxpixel = 0; + maxcount = histogram[maxpixel]; + for (i = 1; i < 256; i++) + if (histogram[i] > maxcount) { + maxcount = histogram[i]; + maxpixel = (UINT8) i; + } + + if (maxcount > 2) + out[x] = maxpixel; + else + out[x] = IMAGING_PIXEL_L(im, x, y); + + } + + } + + ImagingCopyInfo(imOut, im); + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c new file mode 100755 index 00000000000..b611098d874 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c @@ -0,0 +1,91 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for MSP version 2 data. + * + * history: + * 97-01-03 fl Created + * + * Copyright (c) Fredrik Lundh 1997. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + int n; + UINT8* ptr; + + ptr = buf; + + for (;;) { + + if (bytes < 1) + return ptr - buf; + + if (ptr[0] == 0) { + + /* Run (3 bytes block) */ + if (bytes < 3) + break; + + n = ptr[1]; + + if (state->x + n > state->bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + memset(state->buffer + state->x, ptr[2], n); + + ptr += 3; + bytes -= 3; + + } else { + + /* Literal (1+n bytes block) */ + n = ptr[0]; + + if (bytes < 1 + n) + break; + + if (state->x + n > state->bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + memcpy(state->buffer + state->x, ptr + 1, n); + + ptr += 1 + n; + bytes -= 1 + n; + + } + + state->x += n; + + if (state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + } + + } + + return ptr - buf; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c new file mode 100755 index 00000000000..eaa790768f0 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c @@ -0,0 +1,42 @@ +/* + * The Python Imaging Library + * $Id$ + * + * negate image + * + * to do: + * FIXME: Maybe this should be implemented using ImagingPoint() + * + * history: + * 95-11-27 fl: Created + * + * Copyright (c) Fredrik Lundh 1995. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +Imaging +ImagingNegative(Imaging im) +{ + Imaging imOut; + int x, y; + + if (!im) + return (Imaging) ImagingError_ModeError(); + + imOut = ImagingNew(im->mode, im->xsize, im->ysize); + if (!imOut) + return NULL; + + for (y = 0; y < im->ysize; y++) + for (x = 0; x < im->linesize; x++) + imOut->image[y][x] = ~im->image[y][x]; + + return imOut; +} + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c new file mode 100755 index 00000000000..f6d6e510e5c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c @@ -0,0 +1,61 @@ +/* + * The Python Imaging Library + * $Id$ + * + * offset an image in x and y directions + * + * history: + * 96-07-22 fl: Created + * 98-11-01 cgw@pgt.com: Fixed negative-array index bug + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +Imaging +ImagingOffset(Imaging im, int xoffset, int yoffset) +{ + int x, y; + Imaging imOut; + + if (!im) + return (Imaging) ImagingError_ModeError(); + + imOut = ImagingNew(im->mode, im->xsize, im->ysize); + if (!imOut) + return NULL; + + ImagingCopyInfo(imOut, im); + + /* make offsets positive to avoid negative coordinates */ + xoffset %= im->xsize; + xoffset = im->xsize - xoffset; + if (xoffset < 0) + xoffset += im->xsize; + + yoffset %= im->ysize; + yoffset = im->ysize - yoffset; + if (yoffset < 0) + yoffset += im->ysize; + +#define OFFSET(image)\ + for (y = 0; y < im->ysize; y++)\ + for (x = 0; x < im->xsize; x++) {\ + int yi = (y + yoffset) % im->ysize;\ + int xi = (x + xoffset) % im->xsize;\ + imOut->image[y][x] = im->image[yi][xi];\ + } + + if (im->image8) + OFFSET(image8) + else + OFFSET(image32) + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c new file mode 100755 index 00000000000..478de74996c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c @@ -0,0 +1,566 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * code to pack raw data + * + * history: + * 1996-04-30 fl Created + * 1996-05-12 fl Published a few RGB packers + * 1996-11-01 fl More RGB packers (Tk booster stuff) + * 1996-12-30 fl Added P;1, P;2 and P;4 packers + * 1997-06-02 fl Added F (F;32NF) packer + * 1997-08-28 fl Added 1 as L packer + * 1998-02-08 fl Added I packer + * 1998-03-09 fl Added mode field, RGBA/RGBX as RGB packers + * 1998-07-01 fl Added YCbCr support + * 1998-07-12 fl Added I 16 packer + * 1999-02-03 fl Added BGR packers + * 2003-09-26 fl Added LA/PA packers + * 2006-06-22 fl Added CMYK;I packer + * + * Copyright (c) 1997-2006 by Secret Labs AB. + * Copyright (c) 1996-1997 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#define R 0 +#define G 1 +#define B 2 +#define X 3 +#define A 3 + +#define C 0 +#define M 1 +#define Y 2 +#define K 3 + +/* byte swapping macros */ + +#define C16N\ + (out[0]=tmp[0], out[1]=tmp[1]); +#define C16S\ + (out[1]=tmp[0], out[0]=tmp[1]); +#define C32N\ + (out[0]=tmp[0], out[1]=tmp[1], out[2]=tmp[2], out[3]=tmp[3]); +#define C32S\ + (out[3]=tmp[0], out[2]=tmp[1], out[1]=tmp[2], out[0]=tmp[3]); +#define C64N\ + (out[0]=tmp[0], out[1]=tmp[1], out[2]=tmp[2], out[3]=tmp[3],\ + out[4]=tmp[4], out[5]=tmp[5], out[6]=tmp[6], out[7]=tmp[7]); +#define C64S\ + (out[7]=tmp[0], out[6]=tmp[1], out[5]=tmp[2], out[4]=tmp[3],\ + out[3]=tmp[4], out[2]=tmp[5], out[1]=tmp[6], out[0]=tmp[7]); + +#ifdef WORDS_BIGENDIAN +#define C16B C16N +#define C16L C16S +#define C32B C32N +#define C32L C32S +#define C64B C64N +#define C64L C64S +#else +#define C16B C16S +#define C16L C16N +#define C32B C32S +#define C32L C32N +#define C64B C64S +#define C64L C64N +#endif + +static void +pack1(UINT8* out, const UINT8* in, int pixels) +{ + int i, m, b; + /* bilevel (black is 0) */ + b = 0; m = 128; + for (i = 0; i < pixels; i++) { + if (in[i] != 0) + b |= m; + m >>= 1; + if (m == 0) { + *out++ = b; + b = 0; m = 128; + } + } + if (m != 128) + *out++ = b; +} + +static void +pack1I(UINT8* out, const UINT8* in, int pixels) +{ + int i, m, b; + /* bilevel (black is 1) */ + b = 0; m = 128; + for (i = 0; i < pixels; i++) { + if (in[i] == 0) + b |= m; + m >>= 1; + if (m == 0) { + *out++ = b; + b = 0; m = 128; + } + } + if (m != 128) + *out++ = b; +} + +static void +pack1R(UINT8* out, const UINT8* in, int pixels) +{ + int i, m, b; + /* bilevel, lsb first (black is 0) */ + b = 0; m = 1; + for (i = 0; i < pixels; i++) { + if (in[i] != 0) + b |= m; + m <<= 1; + if (m == 256){ + *out++ = b; + b = 0; m = 1; + } + } + if (m != 1) + *out++ = b; +} + +static void +pack1IR(UINT8* out, const UINT8* in, int pixels) +{ + int i, m, b; + /* bilevel, lsb first (black is 1) */ + b = 0; m = 1; + for (i = 0; i < pixels; i++) { + if (in[i] == 0) + b |= m; + m <<= 1; + if (m == 256){ + *out++ = b; + b = 0; m = 1; + } + } + if (m != 1) + *out++ = b; +} + +static void +pack1L(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* bilevel, stored as bytes */ + for (i = 0; i < pixels; i++) + out[i] = (in[i] != 0) ? 255 : 0; +} + +static void +packP4(UINT8* out, const UINT8* in, int pixels) +{ + while (pixels >= 2) { + *out++ = (in[0] << 4) | + (in[1] & 15); + in += 2; pixels -= 2; + } + + if (pixels) + out[0] = (in[0] << 4); +} + +static void +packP2(UINT8* out, const UINT8* in, int pixels) +{ + while (pixels >= 4) { + *out++ = (in[0] << 6) | + ((in[1] & 3) << 4) | + ((in[2] & 3) << 2) | + (in[3] & 3); + in += 4; pixels -= 4; + } + + switch (pixels) { + case 3: + out[0] = (in[0] << 6) | + ((in[1] & 3) << 4) | + ((in[2] & 3) << 2); + break; + case 2: + out[0] = (in[0] << 6) | + ((in[1] & 3) << 4); + case 1: + out[0] = (in[0] << 6); + } +} + +static void +packLA(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* LA, pixel interleaved */ + for (i = 0; i < pixels; i++) { + out[0] = in[R]; + out[1] = in[A]; + out += 2; in += 4; + } +} + +static void +packLAL(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* LA, line interleaved */ + for (i = 0; i < pixels; i++) { + out[i] = in[R]; + out[i+pixels] = in[A]; + in += 4; + } +} + +void +ImagingPackRGB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB triplets */ + for (i = 0; i < pixels; i++) { + out[0] = in[R]; + out[1] = in[G]; + out[2] = in[B]; + out += 3; in += 4; + } +} + +void +ImagingPackXRGB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* XRGB, triplets with left padding */ + for (i = 0; i < pixels; i++) { + out[0] = 0; + out[1] = in[R]; + out[2] = in[G]; + out[3] = in[B]; + out += 4; in += 4; + } +} + +void +ImagingPackBGR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, reversed bytes */ + for (i = 0; i < pixels; i++) { + out[0] = in[B]; + out[1] = in[G]; + out[2] = in[R]; + out += 3; in += 4; + } +} + +void +ImagingPackBGRX(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* BGRX, reversed bytes with right padding */ + for (i = 0; i < pixels; i++) { + out[0] = in[B]; + out[1] = in[G]; + out[2] = in[R]; + out[3] = 0; + out += 4; in += 4; + } +} + +void +ImagingPackXBGR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* XBGR, reversed bytes with left padding */ + for (i = 0; i < pixels; i++) { + out[0] = 0; + out[1] = in[B]; + out[2] = in[G]; + out[3] = in[R]; + out += 4; in += 4; + } +} + +void +ImagingPackBGRA(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* BGRX, reversed bytes with right padding */ + for (i = 0; i < pixels; i++) { + out[0] = in[B]; + out[1] = in[G]; + out[2] = in[R]; + out[3] = in[A]; + out += 4; in += 4; + } +} + +void +ImagingPackABGR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* XBGR, reversed bytes with left padding */ + for (i = 0; i < pixels; i++) { + out[0] = in[A]; + out[1] = in[B]; + out[2] = in[G]; + out[3] = in[R]; + out += 4; in += 4; + } +} + +static void +packRGBL(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, line interleaved */ + for (i = 0; i < pixels; i++) { + out[i] = in[R]; + out[i+pixels] = in[G]; + out[i+pixels+pixels] = in[B]; + in += 4; + } +} + +static void +packRGBXL(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGBX, line interleaved */ + for (i = 0; i < pixels; i++) { + out[i] = in[R]; + out[i+pixels] = in[G]; + out[i+pixels+pixels] = in[B]; + out[i+pixels+pixels+pixels] = in[X]; + in += 4; + } +} + +static void +packI16B(UINT8* out, const UINT8* in_, int pixels) +{ + int i; + INT32* in = (INT32*) in_; + UINT16 tmp_; + UINT8* tmp = (UINT8*) &tmp_; + for (i = 0; i < pixels; i++) { + if (in[0] <= 0) + tmp_ = 0; + else if (in[0] > 65535) + tmp_ = 65535; + else + tmp_ = in[0]; + C16B; + out += 2; in++; + } +} + +static void +packI32S(UINT8* out, const UINT8* in, int pixels) +{ + int i; + UINT8* tmp = (UINT8*) in; + for (i = 0; i < pixels; i++) { + C32L; + out += 4; tmp += 4; + } +} + +static void +copy1(UINT8* out, const UINT8* in, int pixels) +{ + /* L, P */ + memcpy(out, in, pixels); +} + +static void +copy2(UINT8* out, const UINT8* in, int pixels) +{ + /* I;16, etc */ + memcpy(out, in, pixels*2); +} + +static void +copy3(UINT8* out, const UINT8* in, int pixels) +{ + /* BGR;24, etc */ + memcpy(out, in, pixels*3); +} + +static void +copy4(UINT8* out, const UINT8* in, int pixels) +{ + /* RGBA, CMYK quadruples */ + memcpy(out, in, 4*pixels); +} + +static void +copy4I(UINT8* out, const UINT8* in, int pixels) +{ + /* RGBA, CMYK quadruples, inverted */ + int i; + for (i = 0; i < pixels*4; i++) + out[i] = ~in[i]; +} + +static void +band0(UINT8* out, const UINT8* in, int pixels) +{ + int i; + for (i = 0; i < pixels; i++, in += 4) + out[i] = in[0]; +} + +static void +band1(UINT8* out, const UINT8* in, int pixels) +{ + int i; + for (i = 0; i < pixels; i++, in += 4) + out[i] = in[1]; +} + +static void +band2(UINT8* out, const UINT8* in, int pixels) +{ + int i; + for (i = 0; i < pixels; i++, in += 4) + out[i] = in[2]; +} + +static void +band3(UINT8* out, const UINT8* in, int pixels) +{ + int i; + for (i = 0; i < pixels; i++, in += 4) + out[i] = in[3]; +} + +static struct { + const char* mode; + const char* rawmode; + int bits; + ImagingShuffler pack; +} packers[] = { + + /* bilevel */ + {"1", "1", 1, pack1}, + {"1", "1;I", 1, pack1I}, + {"1", "1;R", 1, pack1R}, + {"1", "1;IR", 1, pack1IR}, + {"1", "L", 8, pack1L}, + + /* greyscale */ + {"L", "L", 8, copy1}, + + /* greyscale w. alpha */ + {"LA", "LA", 16, packLA}, + {"LA", "LA;L", 16, packLAL}, + + /* palette */ + {"P", "P;1", 1, pack1}, + {"P", "P;2", 2, packP2}, + {"P", "P;4", 4, packP4}, + {"P", "P", 8, copy1}, + + /* palette w. alpha */ + {"PA", "PA", 16, packLA}, + {"PA", "PA;L", 16, packLAL}, + + /* true colour */ + {"RGB", "RGB", 24, ImagingPackRGB}, + {"RGB", "RGBX", 32, copy4}, + {"RGB", "XRGB", 32, ImagingPackXRGB}, + {"RGB", "BGR", 24, ImagingPackBGR}, + {"RGB", "BGRX", 32, ImagingPackBGRX}, + {"RGB", "XBGR", 32, ImagingPackXBGR}, + {"RGB", "RGB;L", 24, packRGBL}, + {"RGB", "R", 8, band0}, + {"RGB", "G", 8, band1}, + {"RGB", "B", 8, band2}, + + /* true colour w. alpha */ + {"RGBA", "RGBA", 32, copy4}, + {"RGBA", "RGBA;L", 32, packRGBXL}, + {"RGBA", "RGB", 24, ImagingPackRGB}, + {"RGBA", "BGR", 24, ImagingPackBGR}, + {"RGBA", "BGRA", 32, ImagingPackBGRA}, + {"RGBA", "ABGR", 32, ImagingPackABGR}, + {"RGBA", "R", 8, band0}, + {"RGBA", "G", 8, band1}, + {"RGBA", "B", 8, band2}, + {"RGBA", "A", 8, band3}, + + /* true colour w. padding */ + {"RGBX", "RGBX", 32, copy4}, + {"RGBX", "RGBX;L", 32, packRGBXL}, + {"RGBX", "RGB", 32, ImagingPackRGB}, + {"RGBX", "BGR", 32, ImagingPackBGR}, + {"RGBX", "BGRX", 32, ImagingPackBGRX}, + {"RGBX", "XBGR", 32, ImagingPackXBGR}, + {"RGBX", "R", 8, band0}, + {"RGBX", "G", 8, band1}, + {"RGBX", "B", 8, band2}, + {"RGBX", "X", 8, band3}, + + /* colour separation */ + {"CMYK", "CMYK", 32, copy4}, + {"CMYK", "CMYK;I", 32, copy4I}, + {"CMYK", "CMYK;L", 32, packRGBXL}, + {"CMYK", "C", 8, band0}, + {"CMYK", "M", 8, band1}, + {"CMYK", "Y", 8, band2}, + {"CMYK", "K", 8, band3}, + + /* video (YCbCr) */ + {"YCbCr", "YCbCr", 24, ImagingPackRGB}, + {"YCbCr", "YCbCr;L", 24, packRGBL}, + {"YCbCr", "YCbCrX", 32, copy4}, + {"YCbCr", "YCbCrK", 32, copy4}, + {"YCbCr", "Y", 8, band0}, + {"YCbCr", "Cb", 8, band1}, + {"YCbCr", "Cr", 8, band2}, + + /* integer */ + {"I", "I", 32, copy4}, + {"I", "I;16B", 16, packI16B}, + {"I", "I;32S", 32, packI32S}, + {"I", "I;32NS", 32, copy4}, + + /* floating point */ + {"F", "F", 32, copy4}, + {"F", "F;32F", 32, packI32S}, + {"F", "F;32NF", 32, copy4}, + + /* storage modes */ + {"I;16", "I;16", 16, copy2}, + {"I;16B", "I;16B", 16, copy2}, + {"I;16L", "I;16L", 16, copy2}, + {"BGR;15", "BGR;15", 16, copy2}, + {"BGR;16", "BGR;16", 16, copy2}, + {"BGR;24", "BGR;24", 24, copy3}, + + {NULL} /* sentinel */ +}; + + +ImagingShuffler +ImagingFindPacker(const char* mode, const char* rawmode, int* bits_out) +{ + int i; + + /* find a suitable pixel packer */ + for (i = 0; packers[i].rawmode; i++) + if (strcmp(packers[i].mode, mode) == 0 && + strcmp(packers[i].rawmode, rawmode) == 0) { + if (bits_out) + *bits_out = packers[i].bits; + return packers[i].pack; + } + return NULL; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c new file mode 100755 index 00000000000..aea8f04e301 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c @@ -0,0 +1,92 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for PackBits image data. + * + * history: + * 96-04-19 fl Created + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +int +ImagingPackbitsDecode(Imaging im, ImagingCodecState state, + UINT8* buf, int bytes) +{ + UINT8 n; + UINT8* ptr; + int i; + + ptr = buf; + + for (;;) { + + if (bytes < 1) + return ptr - buf; + + if (ptr[0] & 0x80) { + + if (ptr[0] == 0x80) { + /* Nop */ + ptr++; bytes--; + continue; + } + + /* Run */ + if (bytes < 2) + return ptr - buf; + + for (n = 257 - ptr[0]; n > 0; n--) { + if (state->x >= state->bytes) { + /* state->errcode = IMAGING_CODEC_OVERRUN; */ + break; + } + state->buffer[state->x++] = ptr[1]; + } + + ptr += 2; bytes -= 2; + + } else { + + /* Literal */ + n = ptr[0]+2; + + if (bytes < n) + return ptr - buf; + + for (i = 1; i < n; i++) { + if (state->x >= state->bytes) { + /* state->errcode = IMAGING_CODEC_OVERRUN; */ + break; + } + state->buffer[state->x++] = ptr[i]; + } + + ptr += n; bytes -= n; + + } + + if (state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + } + + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c new file mode 100755 index 00000000000..bd4f4f1d637 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c @@ -0,0 +1,316 @@ +/* + * The Python Imaging Library + * $Id$ + * + * imaging palette object + * + * history: + * 1996-05-05 fl Added to library + * 1996-05-27 fl Added colour mapping stuff + * 1997-05-12 fl Support RGBA palettes + * 2005-02-09 fl Removed grayscale entries from web palette + * + * Copyright (c) Secret Labs AB 1997-2005. All rights reserved. + * Copyright (c) Fredrik Lundh 1995-1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include + + +ImagingPalette +ImagingPaletteNew(const char* mode) +{ + /* Create a palette object */ + + int i; + ImagingPalette palette; + + if (strcmp(mode, "RGB") && strcmp(mode, "RGBA")) + return (ImagingPalette) ImagingError_ModeError(); + + palette = calloc(1, sizeof(struct ImagingPaletteInstance)); + if (!palette) + return (ImagingPalette) ImagingError_MemoryError(); + + strcpy(palette->mode, mode); + + /* Initialize to ramp */ + for (i = 0; i < 256; i++) { + palette->palette[i*4+0] = + palette->palette[i*4+1] = + palette->palette[i*4+2] = (UINT8) i; + palette->palette[i*4+3] = 255; /* opaque */ + } + + return palette; +} + +ImagingPalette +ImagingPaletteNewBrowser(void) +{ + /* Create a standard "browser" palette object */ + + int i, r, g, b; + ImagingPalette palette; + + palette = ImagingPaletteNew("RGB"); + if (!palette) + return NULL; + + /* Blank out unused entries */ + /* FIXME: Add 10-level windows palette here? */ + + for (i = 0; i < 10; i++) { + palette->palette[i*4+0] = + palette->palette[i*4+1] = + palette->palette[i*4+2] = 0; + } + + /* Simple 6x6x6 colour cube */ + + for (b = 0; b < 256; b += 51) + for (g = 0; g < 256; g += 51) + for (r = 0; r < 256; r += 51) { + palette->palette[i*4+0] = r; + palette->palette[i*4+1] = g; + palette->palette[i*4+2] = b; + i++; + } + + /* Blank out unused entries */ + /* FIXME: add 30-level greyscale wedge here? */ + + for (; i < 256; i++) { + palette->palette[i*4+0] = + palette->palette[i*4+1] = + palette->palette[i*4+2] = 0; + } + + return palette; +} + +ImagingPalette +ImagingPaletteDuplicate(ImagingPalette palette) +{ + /* Duplicate palette descriptor */ + + ImagingPalette new_palette; + + if (!palette) + return NULL; + + new_palette = malloc(sizeof(struct ImagingPaletteInstance)); + if (!new_palette) + return (ImagingPalette) ImagingError_MemoryError(); + + memcpy(new_palette, palette, sizeof(struct ImagingPaletteInstance)); + + /* Don't share the cache */ + new_palette->cache = NULL; + + return new_palette; +} + +void +ImagingPaletteDelete(ImagingPalette palette) +{ + /* Destroy palette object */ + + if (palette) { + if (palette->cache) + free(palette->cache); + free(palette); + } +} + + +/* -------------------------------------------------------------------- */ +/* Colour mapping */ +/* -------------------------------------------------------------------- */ + +/* This code is used to map RGB triplets to palette indices, using + a palette index cache. */ + +/* + * This implementation is loosely based on the corresponding code in + * the IJG JPEG library by Thomas G. Lane. Original algorithms by + * Paul Heckbert and Spencer W. Thomas. + * + * The IJG JPEG library is copyright (C) 1991-1995, Thomas G. Lane. */ + +#define DIST(a, b, s) (a - b) * (a - b) * s + +/* Colour weights (no scaling, for now) */ +#define RSCALE 1 +#define GSCALE 1 +#define BSCALE 1 + +/* Calculated scaled distances */ +#define RDIST(a, b) DIST(a, b, RSCALE*RSCALE) +#define GDIST(a, b) DIST(a, b, GSCALE*GSCALE) +#define BDIST(a, b) DIST(a, b, BSCALE*BSCALE) + +/* Incremental steps */ +#define RSTEP (4 * RSCALE) +#define GSTEP (4 * GSCALE) +#define BSTEP (4 * BSCALE) + +#define BOX 8 + +#define BOXVOLUME BOX*BOX*BOX + +void +ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b) +{ + int i, j; + unsigned int dmin[256], dmax; + int r0, g0, b0; + int r1, g1, b1; + int rc, gc, bc; + unsigned int d[BOXVOLUME]; + UINT8 c[BOXVOLUME]; + + /* Get box boundaries for the given (r,g,b)-triplet. Each box + covers eight cache slots (32 colour values, that is). */ + + r0 = r & 0xe0; r1 = r0 + 0x1f; rc = (r0 + r1) / 2; + g0 = g & 0xe0; g1 = g0 + 0x1f; gc = (g0 + g1) / 2; + b0 = b & 0xe0; b1 = b0 + 0x1f; bc = (b0 + b1) / 2; + + /* Step 1 -- Select relevant palette entries (after Heckbert) */ + + /* For each palette entry, calculate the min and max distances to + * any position in the box given by the colour we're looking for. */ + + dmax = (unsigned int) ~0; + + for (i = 0; i < 256; i++) { + + int r, g, b; + unsigned int tmin, tmax; + + /* Find min and max distances to any point in the box */ + r = palette->palette[i*4+0]; + tmin = (r < r0) ? RDIST(r, r1) : (r > r1) ? RDIST(r, r0) : 0; + tmax = (r <= rc) ? RDIST(r, r1) : RDIST(r, r0); + + g = palette->palette[i*4+1]; + tmin += (g < g0) ? GDIST(g, g1) : (g > g1) ? GDIST(g, g0) : 0; + tmax += (g <= gc) ? GDIST(g, g1) : GDIST(g, g0); + + b = palette->palette[i*4+2]; + tmin += (b < b0) ? BDIST(b, b1) : (b > b1) ? BDIST(b, b0) : 0; + tmax += (b <= bc) ? BDIST(b, b1) : BDIST(b, b0); + + dmin[i] = tmin; + if (tmax < dmax) + dmax = tmax; /* keep the smallest max distance only */ + + } + + /* Step 2 -- Incrementally update cache slot (after Thomas) */ + + /* Find the box containing the nearest palette entry, and update + * all slots in that box. We only check boxes for which the min + * distance is less than or equal the smallest max distance */ + + for (i = 0; i < BOXVOLUME; i++) + d[i] = (unsigned int) ~0; + + for (i = 0; i < 256; i++) + + if (dmin[i] <= dmax) { + + int rd, gd, bd; + int ri, gi, bi; + int rx, gx, bx; + + ri = (r0 - palette->palette[i*4+0]) * RSCALE; + gi = (g0 - palette->palette[i*4+1]) * GSCALE; + bi = (b0 - palette->palette[i*4+2]) * BSCALE; + + rd = ri*ri + gi*gi + bi*bi; + + ri = ri * (2 * RSTEP) + RSTEP * RSTEP; + gi = gi * (2 * GSTEP) + GSTEP * GSTEP; + bi = bi * (2 * BSTEP) + BSTEP * BSTEP; + + rx = ri; + for (r = j = 0; r < BOX; r++) { + gd = rd; gx = gi; + for (g = 0; g < BOX; g++) { + bd = gd; bx = bi; + for (b = 0; b < BOX; b++) { + if ((unsigned int) bd < d[j]) { + d[j] = bd; + c[j] = (UINT8) i; + } + bd += bx; + bx += 2 * BSTEP * BSTEP; + j++; + } + gd += gx; + gx += 2 * GSTEP * GSTEP; + } + rd += rx; + rx += 2 * RSTEP * RSTEP; + } + } + + /* Step 3 -- Update cache */ + + /* The c array now contains the closest match for each + * cache slot in the box. Update the cache. */ + + j = 0; + for (r = r0; r < r1; r+=4) + for (g = g0; g < g1; g+=4) + for (b = b0; b < b1; b+=4) + ImagingPaletteCache(palette, r, g, b) = c[j++]; +} + + +int +ImagingPaletteCachePrepare(ImagingPalette palette) +{ + /* Add a colour cache to a palette */ + + int i; + int entries = 64*64*64; + + if (palette->cache == NULL) { + + /* The cache is 512k. It might be a good idea to break it + up into a pointer array (e.g. an 8-bit image?) */ + + palette->cache = (INT16*) malloc(entries * sizeof(INT16)); + if (!palette->cache) { + (void) ImagingError_MemoryError(); + return -1; + } + + /* Mark all entries as empty */ + for (i = 0; i < entries; i++) + palette->cache[i] = 0x100; + + } + + return 0; +} + + +void +ImagingPaletteCacheDelete(ImagingPalette palette) +{ + /* Release the colour cache, if any */ + + if (palette && palette->cache) { + free(palette->cache); + palette->cache = NULL; + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c new file mode 100755 index 00000000000..b89dd640453 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c @@ -0,0 +1,555 @@ +/* + * The Python Imaging Library + * $Id$ + * + * paste image on another image + * + * history: + * 96-03-27 fl Created + * 96-07-16 fl Support "1", "L" and "RGBA" masks + * 96-08-16 fl Merged with opaque paste + * 97-01-17 fl Faster blending, added support for RGBa images + * 97-08-27 fl Faster masking for 32-bit images + * 98-02-02 fl Fixed MULDIV255 macro for gcc + * 99-02-02 fl Added "RGBa" mask support + * 99-02-06 fl Rewritten. Added support for masked fill operations. + * 99-12-08 fl Fixed matte fill. + * + * Copyright (c) Fredrik Lundh 1996-97. + * Copyright (c) Secret Labs AB 1997-99. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +/* like (a * b + 127) / 255), but much faster on most platforms */ +#define MULDIV255NEW(a, b, tmp)\ + (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) + +#define MULDIV255OLD(a, b, tmp)\ + (((a) * (b) + 127) / 255) + +#define MULDIV255 MULDIV255NEW + +#define BLEND(mask, in1, in2, tmp1, tmp2)\ + (MULDIV255(in1, 255 - mask, tmp1) + MULDIV255(in2, mask, tmp2)) + +#define PREBLEND(mask, in1, in2, tmp1)\ + (MULDIV255(in1, 255 - mask, tmp1) + in2) + +static inline void +paste(Imaging imOut, Imaging imIn, int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* paste opaque region */ + + int y; + + dx *= pixelsize; + sx *= pixelsize; + + xsize *= pixelsize; + + for (y = 0; y < ysize; y++) + memcpy(imOut->image[y+dy]+dx, imIn->image[y+sy]+sx, xsize); +} + +static inline void +paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* paste with mode "1" mask */ + + int x, y; + + if (imOut->image8) { + + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* in = imIn->image8[y+sy]+sx; + UINT8* mask = imMask->image8[y+sy]+sx; + for (x = 0; x < xsize; x++) { + if (*mask++) + *out = *in; + out++, in++; + } + } + + } else { + + for (y = 0; y < ysize; y++) { + INT32* out = imOut->image32[y+dy]+dx; + INT32* in = imIn->image32[y+sy]+sx; + UINT8* mask = imMask->image8[y+sy]+sx; + for (x = 0; x < xsize; x++) { + if (*mask++) + *out = *in; + out++, in++; + } + } + } +} + +static inline void +paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* paste with mode "L" matte */ + + int x, y, i; + unsigned int tmp1, tmp2; + + if (imOut->image8) { + + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* in = imIn->image8[y+sy]+sx; + UINT8* mask = imMask->image8[y+sy]+sx; + for (x = 0; x < xsize; x++) { + *out = BLEND(*mask, *out, *in, tmp1, tmp2); + out++, in++, mask++; + } + } + + } else { + + for (y = 0; y < ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; + UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; + for (x = 0; x < xsize; x++) { + for (i = 0; i < pixelsize; i++) { + *out = BLEND(*mask, *out, *in, tmp1, tmp2); + out++, in++; + } + mask++; + } + } + } +} + +static inline void +paste_mask_RGBA(Imaging imOut, Imaging imIn, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* paste with mode "RGBA" matte */ + + int x, y, i; + unsigned int tmp1, tmp2; + + if (imOut->image8) { + + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* in = imIn->image8[y+sy]+sx; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; + for (x = 0; x < xsize; x++) { + *out = BLEND(*mask, *out, *in, tmp1, tmp2); + out++, in++, mask += 4; + } + } + + } else { + + for (y = 0; y < ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; + UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; + for (x = 0; x < xsize; x++) { + for (i = 0; i < pixelsize; i++) { + *out = BLEND(*mask, *out, *in, tmp1, tmp2); + out++, in++; + } + mask += 4; + } + } + } +} + + +static inline void +paste_mask_RGBa(Imaging imOut, Imaging imIn, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* paste with mode "RGBa" matte */ + + int x, y, i; + unsigned int tmp1; + + if (imOut->image8) { + + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* in = imIn->image8[y+sy]+sx; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; + for (x = 0; x < xsize; x++) { + *out = PREBLEND(*mask, *out, *in, tmp1); + out++, in++, mask += 4; + } + } + + } else { + + for (y = 0; y < ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; + UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; + for (x = 0; x < xsize; x++) { + for (i = 0; i < pixelsize; i++) { + *out = PREBLEND(*mask, *out, *in, tmp1); + out++, in++; + } + mask += 4; + } + } + } +} + +int +ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask, + int dx0, int dy0, int dx1, int dy1) +{ + int xsize, ysize; + int pixelsize; + int sx0, sy0; + ImagingSectionCookie cookie; + + if (!imOut || !imIn) { + (void) ImagingError_ModeError(); + return -1; + } + + pixelsize = imOut->pixelsize; + + xsize = dx1 - dx0; + ysize = dy1 - dy0; + + if (xsize != imIn->xsize || ysize != imIn->ysize || + pixelsize != imIn->pixelsize) { + (void) ImagingError_Mismatch(); + return -1; + } + + if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { + (void) ImagingError_Mismatch(); + return -1; + } + + /* Determine which region to copy */ + sx0 = sy0 = 0; + if (dx0 < 0) + xsize += dx0, sx0 = -dx0, dx0 = 0; + if (dx0 + xsize > imOut->xsize) + xsize = imOut->xsize - dx0; + if (dy0 < 0) + ysize += dy0, sy0 = -dy0, dy0 = 0; + if (dy0 + ysize > imOut->ysize) + ysize = imOut->ysize - dy0; + + if (xsize <= 0 || ysize <= 0) + return 0; + + if (!imMask) { + ImagingSectionEnter(&cookie); + paste(imOut, imIn, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "1") == 0) { + ImagingSectionEnter(&cookie); + paste_mask_1(imOut, imIn, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "L") == 0) { + ImagingSectionEnter(&cookie); + paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "RGBA") == 0) { + ImagingSectionEnter(&cookie); + paste_mask_RGBA(imOut, imIn, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "RGBa") == 0) { + ImagingSectionEnter(&cookie); + paste_mask_RGBa(imOut, imIn, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else { + (void) ImagingError_ValueError("bad transparency mask"); + return -1; + } + + return 0; +} + +static inline void +fill(Imaging imOut, const void* ink_, int dx, int dy, + int xsize, int ysize, int pixelsize) +{ + /* fill opaque region */ + + int x, y; + UINT8 ink8 = 0; + INT32 ink32 = 0L; + + memcpy(&ink32, ink_, pixelsize); + memcpy(&ink8, ink_, sizeof(ink8)); + + if (imOut->image8 || ink32 == 0L) { + + dx *= pixelsize; + xsize *= pixelsize; + for (y = 0; y < ysize; y++) + memset(imOut->image[y+dy]+dx, ink8, xsize); + + } else { + + for (y = 0; y < ysize; y++) { + INT32* out = imOut->image32[y+dy]+dx; + for (x = 0; x < xsize; x++) + out[x] = ink32; + } + + } +} + +static inline void +fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* fill with mode "1" mask */ + + int x, y; + UINT8 ink8 = 0; + INT32 ink32 = 0L; + + memcpy(&ink32, ink_, pixelsize); + memcpy(&ink8, ink_, sizeof(ink8)); + + if (imOut->image8) { + + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* mask = imMask->image8[y+sy]+sx; + for (x = 0; x < xsize; x++) { + if (*mask++) + *out = ink8; + out++; + } + } + + } else { + + for (y = 0; y < ysize; y++) { + INT32* out = imOut->image32[y+dy]+dx; + UINT8* mask = imMask->image8[y+sy]+sx; + for (x = 0; x < xsize; x++) { + if (*mask++) + *out = ink32; + out++; + } + } + } +} + +static inline void +fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* fill with mode "L" matte */ + + int x, y, i; + unsigned int tmp1, tmp2; + + if (imOut->image8) { + + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* mask = imMask->image8[y+sy]+sx; + for (x = 0; x < xsize; x++) { + *out = BLEND(*mask, *out, ink[0], tmp1, tmp2); + out++, mask++; + } + } + + } else { + + for (y = 0; y < ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; + for (x = 0; x < xsize; x++) { + for (i = 0; i < pixelsize; i++) { + *out = BLEND(*mask, *out, ink[i], tmp1, tmp2); + out++; + } + mask++; + } + } + } +} + +static inline void +fill_mask_RGBA(Imaging imOut, const UINT8* ink, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* fill with mode "RGBA" matte */ + + int x, y, i; + unsigned int tmp1, tmp2; + + if (imOut->image8) { + + sx = sx*4+3; + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; + for (x = 0; x < xsize; x++) { + *out = BLEND(*mask, *out, ink[0], tmp1, tmp2); + out++, mask += 4; + } + } + + } else { + + dx *= pixelsize; + sx = sx*4 + 3; + for (y = 0; y < ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y+dy]+dx; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; + for (x = 0; x < xsize; x++) { + for (i = 0; i < pixelsize; i++) { + *out = BLEND(*mask, *out, ink[i], tmp1, tmp2); + out++; + } + mask += 4; + } + } + } +} + +static inline void +fill_mask_RGBa(Imaging imOut, const UINT8* ink, Imaging imMask, + int dx, int dy, int sx, int sy, + int xsize, int ysize, int pixelsize) +{ + /* fill with mode "RGBa" matte */ + + int x, y, i; + unsigned int tmp1; + + if (imOut->image8) { + + sx = sx*4 + 3; + for (y = 0; y < ysize; y++) { + UINT8* out = imOut->image8[y+dy]+dx; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; + for (x = 0; x < xsize; x++) { + *out = PREBLEND(*mask, *out, ink[0], tmp1); + out++, mask += 4; + } + } + + } else { + + dx *= pixelsize; + sx = sx*4 + 3; + for (y = 0; y < ysize; y++) { + UINT8* out = (UINT8*) imOut->image[y+dy]+dx; + UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; + for (x = 0; x < xsize; x++) { + for (i = 0; i < pixelsize; i++) { + *out = PREBLEND(*mask, *out, ink[i], tmp1); + out++; + } + mask += 4; + } + } + } +} + +int +ImagingFill2(Imaging imOut, const void* ink, Imaging imMask, + int dx0, int dy0, int dx1, int dy1) +{ + ImagingSectionCookie cookie; + int xsize, ysize; + int pixelsize; + int sx0, sy0; + + if (!imOut || !ink) { + (void) ImagingError_ModeError(); + return -1; + } + + pixelsize = imOut->pixelsize; + + xsize = dx1 - dx0; + ysize = dy1 - dy0; + + if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { + (void) ImagingError_Mismatch(); + return -1; + } + + /* Determine which region to fill */ + sx0 = sy0 = 0; + if (dx0 < 0) + xsize += dx0, sx0 = -dx0, dx0 = 0; + if (dx0 + xsize > imOut->xsize) + xsize = imOut->xsize - dx0; + if (dy0 < 0) + ysize += dy0, sy0 = -dy0, dy0 = 0; + if (dy0 + ysize > imOut->ysize) + ysize = imOut->ysize - dy0; + + if (xsize <= 0 || ysize <= 0) + return 0; + + if (!imMask) { + ImagingSectionEnter(&cookie); + fill(imOut, ink, dx0, dy0, xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "1") == 0) { + ImagingSectionEnter(&cookie); + fill_mask_1(imOut, ink, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "L") == 0) { + ImagingSectionEnter(&cookie); + fill_mask_L(imOut, ink, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "RGBA") == 0) { + ImagingSectionEnter(&cookie); + fill_mask_RGBA(imOut, ink, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else if (strcmp(imMask->mode, "RGBa") == 0) { + ImagingSectionEnter(&cookie); + fill_mask_RGBa(imOut, ink, imMask, dx0, dy0, sx0, sy0, + xsize, ysize, pixelsize); + ImagingSectionLeave(&cookie); + + } else { + (void) ImagingError_ValueError("bad transparency mask"); + return -1; + } + + return 0; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c new file mode 100755 index 00000000000..b6898e301d1 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c @@ -0,0 +1,78 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for uncompressed PCD image data. + * + * history: + * 96-05-10 fl Created + * 96-05-18 fl New tables + * 97-01-25 fl Use PhotoYCC unpacker + * + * notes: + * This driver supports uncompressed PCD modes only + * (resolutions up to 768x512). + * + * Copyright (c) Fredrik Lundh 1996-97. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + int x; + int chunk; + UINT8* out; + UINT8* ptr; + + ptr = buf; + + chunk = 3 * state->xsize; + + for (;;) { + + /* We need data for two full lines before we can do anything */ + if (bytes < chunk) + return ptr - buf; + + /* Unpack first line */ + out = state->buffer; + for (x = 0; x < state->xsize; x++) { + out[0] = ptr[x]; + out[1] = ptr[(x+4*state->xsize)/2]; + out[2] = ptr[(x+5*state->xsize)/2]; + out += 4; + } + + state->shuffle((UINT8*) im->image[state->y], + state->buffer, state->xsize); + + if (++state->y >= state->ysize) + return -1; /* This can hardly happen */ + + /* Unpack second line */ + out = state->buffer; + for (x = 0; x < state->xsize; x++) { + out[0] = ptr[x+state->xsize]; + out[1] = ptr[(x+4*state->xsize)/2]; + out[2] = ptr[(x+5*state->xsize)/2]; + out += 4; + } + + state->shuffle((UINT8*) im->image[state->y], + state->buffer, state->xsize); + + if (++state->y >= state->ysize) + return -1; + + ptr += chunk; + bytes -= chunk; + + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c new file mode 100755 index 00000000000..ab82b23adcc --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c @@ -0,0 +1,75 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for PCX image data. + * + * history: + * 95-09-14 fl Created + * + * Copyright (c) Fredrik Lundh 1995. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +int +ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8 n; + UINT8* ptr; + + ptr = buf; + + for (;;) { + + if (bytes < 1) + return ptr - buf; + + if ((*ptr & 0xC0) == 0xC0) { + + /* Run */ + if (bytes < 2) + return ptr - buf; + + n = ptr[0] & 0x3F; + + while (n > 0) { + if (state->x >= state->bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + break; + } + state->buffer[state->x++] = ptr[1]; + n--; + } + + ptr += 2; bytes -= 2; + + } else { + + /* Literal */ + state->buffer[state->x++] = ptr[0]; + ptr++; bytes--; + + } + + if (state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + } + + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c new file mode 100755 index 00000000000..87d59946388 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c @@ -0,0 +1,148 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * encoder for PCX data + * + * history: + * 99-02-07 fl created + * + * Copyright (c) Fredrik Lundh 1999. + * Copyright (c) Secret Labs AB 1999. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +enum { INIT, FETCH, ENCODE }; + +/* we're reusing "ystep" to store the last value */ +#define LAST ystep + +int +ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8* ptr; + int this; + + ptr = buf; + + if (!state->state) { + + /* sanity check */ + if (state->xsize <= 0 || state->ysize <= 0) { + state->errcode = IMAGING_CODEC_END; + return 0; + } + + state->bytes = (state->xsize*state->bits + 7) / 8; + state->state = FETCH; + + } + + for (;;) + + switch (state->state) { + case FETCH: + + /* get a line of data */ + if (state->y >= state->ysize) { + state->errcode = IMAGING_CODEC_END; + return ptr - buf; + } + + state->shuffle(state->buffer, + (UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->xsize); + + state->y++; + + state->count = 1; + state->LAST = state->buffer[0]; + + state->x = 1; + + state->state = ENCODE; + /* fall through */ + + case ENCODE: + + /* compress this line */ + + /* when we arrive here, "count" contains the number of + bytes having the value of "LAST" that we've already + seen */ + + while (state->x < state->bytes) { + + if (state->count == 63) { + + /* this run is full; flush it */ + if (bytes < 2) + return ptr - buf; + *ptr++ = 0xff; + *ptr++ = state->LAST; + bytes -= 2; + + state->count = 0; + + } + + this = state->buffer[state->x]; + + if (this == state->LAST) { + + /* extend the current run */ + state->x++; + state->count++; + + } else { + + /* start a new run */ + if (state->count == 1 && (state->LAST < 0xc0)) { + if (bytes < 1) + return ptr - buf; + *ptr++ = state->LAST; + bytes--; + } else { + if (state->count > 0) { + if (bytes < 2) + return ptr - buf; + *ptr++ = 0xc0 | state->count; + *ptr++ = state->LAST; + bytes -= 2; + } + } + + state->LAST = this; + state->count = 1; + + state->x++; + + } + } + + /* end of line; flush the current run */ + if (state->count == 1 && (state->LAST < 0xc0)) { + if (bytes < 1) + return ptr - buf; + *ptr++ = state->LAST; + bytes--; + } else { + if (state->count > 0) { + if (bytes < 2) + return ptr - buf; + *ptr++ = 0xc0 | state->count; + *ptr++ = state->LAST; + bytes -= 2; + } + } + + /* read next line */ + state->state = FETCH; + break; + + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c new file mode 100755 index 00000000000..2593dca57ec --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c @@ -0,0 +1,263 @@ +/* + * The Python Imaging Library + * $Id$ + * + * point (pixel) translation + * + * history: + * 1995-11-27 fl Created + * 1996-03-31 fl Fixed colour support + * 1996-08-13 fl Support 8-bit to "1" thresholding + * 1997-05-31 fl Added floating point transform + * 1998-07-02 fl Added integer point transform + * 1998-07-17 fl Support L to anything lookup + * 2004-12-18 fl Refactored; added I to L lookup + * + * Copyright (c) 1997-2004 by Secret Labs AB. + * Copyright (c) 1995-2004 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +typedef struct { + const void* table; +} im_point_context; + +static void +im_point_8_8(Imaging imOut, Imaging imIn, im_point_context* context) +{ + int x, y; + /* 8-bit source, 8-bit destination */ + UINT8* table = (UINT8*) context->table; + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = imIn->image8[y]; + UINT8* out = imOut->image8[y]; + for (x = 0; x < imIn->xsize; x++) + out[x] = table[in[x]]; + } +} + +static void +im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context* context) +{ + int x, y; + /* 2x8-bit source, 2x8-bit destination */ + UINT8* table = (UINT8*) context->table; + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + for (x = 0; x < imIn->xsize; x++) { + out[0] = table[in[0]]; + out[3] = table[in[3]+256]; + in += 4; out += 4; + } + } +} + +static void +im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context* context) +{ + int x, y; + /* 3x8-bit source, 3x8-bit destination */ + UINT8* table = (UINT8*) context->table; + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + for (x = 0; x < imIn->xsize; x++) { + out[0] = table[in[0]]; + out[1] = table[in[1]+256]; + out[2] = table[in[2]+512]; + in += 4; out += 4; + } + } +} + +static void +im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context* context) +{ + int x, y; + /* 4x8-bit source, 4x8-bit destination */ + UINT8* table = (UINT8*) context->table; + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = (UINT8*) imIn->image[y]; + UINT8* out = (UINT8*) imOut->image[y]; + for (x = 0; x < imIn->xsize; x++) { + out[0] = table[in[0]]; + out[1] = table[in[1]+256]; + out[2] = table[in[2]+512]; + out[3] = table[in[3]+768]; + in += 4; out += 4; + } + } +} + +static void +im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context) +{ + int x, y; + /* 8-bit source, 32-bit destination */ + INT32* table = (INT32*) context->table; + for (y = 0; y < imIn->ysize; y++) { + UINT8* in = imIn->image8[y]; + INT32* out = imOut->image32[y]; + for (x = 0; x < imIn->xsize; x++) + out[x] = table[in[x]]; + } +} + +static void +im_point_32_8(Imaging imOut, Imaging imIn, im_point_context* context) +{ + int x, y; + /* 32-bit source, 8-bit destination */ + UINT8* table = (UINT8*) context->table; + for (y = 0; y < imIn->ysize; y++) { + INT32* in = imIn->image32[y]; + UINT8* out = imOut->image8[y]; + for (x = 0; x < imIn->xsize; x++) { + int v = in[x]; + if (v < 0) + v = 0; + else if (v > 65535) + v = 65535; + out[x] = table[v]; + } + } +} + +Imaging +ImagingPoint(Imaging imIn, const char* mode, const void* table) +{ + /* lookup table transform */ + + ImagingSectionCookie cookie; + Imaging imOut; + im_point_context context; + void (*point)(Imaging imIn, Imaging imOut, im_point_context* context); + + if (!imIn) + return (Imaging) ImagingError_ModeError(); + + if (!mode) + mode = imIn->mode; + + if (imIn->type != IMAGING_TYPE_UINT8) { + if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0) + goto mode_mismatch; + } else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0) + goto mode_mismatch; + + imOut = ImagingNew(mode, imIn->xsize, imIn->ysize); + if (!imOut) + return NULL; + + /* find appropriate handler */ + if (imIn->type == IMAGING_TYPE_UINT8) { + if (imIn->bands == imOut->bands && imIn->type == imOut->type) { + switch (imIn->bands) { + case 1: + point = im_point_8_8; + break; + case 2: + point = im_point_2x8_2x8; + break; + case 3: + point = im_point_3x8_3x8; + break; + case 4: + point = im_point_4x8_4x8; + break; + default: + /* this cannot really happen */ + point = im_point_8_8; + break; + } + } else + point = im_point_8_32; + } else + point = im_point_32_8; + + ImagingCopyInfo(imOut, imIn); + + ImagingSectionEnter(&cookie); + + context.table = table; + point(imOut, imIn, &context); + + ImagingSectionLeave(&cookie); + + return imOut; + + mode_mismatch: + return (Imaging) ImagingError_ValueError( + "point operation not supported for this mode" + ); +} + + +Imaging +ImagingPointTransform(Imaging imIn, double scale, double offset) +{ + /* scale/offset transform */ + + ImagingSectionCookie cookie; + Imaging imOut; + int x, y; + + if (!imIn || (strcmp(imIn->mode, "I") != 0 && + strcmp(imIn->mode, "I;16") != 0 && + strcmp(imIn->mode, "F") != 0)) + return (Imaging) ImagingError_ModeError(); + + imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); + if (!imOut) + return NULL; + + ImagingCopyInfo(imOut, imIn); + + switch (imIn->type) { + case IMAGING_TYPE_INT32: + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + INT32* in = imIn->image32[y]; + INT32* out = imOut->image32[y]; + /* FIXME: add clipping? */ + for (x = 0; x < imIn->xsize; x++) + out[x] = in[x] * scale + offset; + } + ImagingSectionLeave(&cookie); + break; + case IMAGING_TYPE_FLOAT32: + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + FLOAT32* in = (FLOAT32*) imIn->image32[y]; + FLOAT32* out = (FLOAT32*) imOut->image32[y]; + for (x = 0; x < imIn->xsize; x++) + out[x] = in[x] * scale + offset; + } + ImagingSectionLeave(&cookie); + break; + case IMAGING_TYPE_SPECIAL: + if (strcmp(imIn->mode,"I;16") == 0) { + ImagingSectionEnter(&cookie); + for (y = 0; y < imIn->ysize; y++) { + UINT16* in = (UINT16 *)imIn->image[y]; + UINT16* out = (UINT16 *)imOut->image[y]; + /* FIXME: add clipping? */ + for (x = 0; x < imIn->xsize; x++) + out[x] = in[x] * scale + offset; + } + ImagingSectionLeave(&cookie); + break; + } + /* FALL THROUGH */ + default: + ImagingDelete(imOut); + return (Imaging) ImagingError_ValueError("internal error"); + } + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c new file mode 100755 index 00000000000..1b76a6a0fab --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c @@ -0,0 +1,1610 @@ +/* + * The Python Imaging Library + * $Id$ + * + * image quantizer + * + * history: + * 1998-09-10 tjs Contributed + * 1998-12-29 fl Added to PIL 1.0b1 + * 2004-02-21 fl Fixed bogus free() on quantization error + * 2005-02-07 fl Limit number of colors to 256 + * + * Written by Toby J Sargeant . + * + * Copyright (c) 1998 by Toby J Sargeant + * Copyright (c) 1998-2004 by Secret Labs AB. All rights reserved. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +#include +#include +#include +#include + +#include "Quant.h" + +#include "QuantDefines.h" +#include "QuantHash.h" +#include "QuantHeap.h" + +#define NO_OUTPUT + +typedef struct { + unsigned long scale; +} PixelHashData; + +typedef struct _PixelList { + struct _PixelList *next[3],*prev[3]; + Pixel p; + unsigned int flag:1; + int count; +} PixelList; + +typedef struct _BoxNode { + struct _BoxNode *l,*r; + PixelList *head[3],*tail[3]; + int axis; + int volume; + unsigned long pixelCount; +} BoxNode; + +#define _SQR(x) ((x)*(x)) +#define _DISTSQR(p1,p2) \ + _SQR((int)((p1)->c.r)-(int)((p2)->c.r))+ \ + _SQR((int)((p1)->c.g)-(int)((p2)->c.g))+ \ + _SQR((int)((p1)->c.b)-(int)((p2)->c.b)) + +#define MAX_HASH_ENTRIES 65536 + +#define PIXEL_HASH(r,g,b) \ + (((unsigned int)(r) )*463 ^ \ + ((unsigned int)(g)<< 8)*10069 ^ \ + ((unsigned int)(b)<<16)*64997) + +#define PIXEL_UNSCALE(p,q,s) \ + ((q)->c.r=(p)->c.r<<(s)), \ + ((q)->c.g=(p)->c.g<<(s)), \ + ((q)->c.b=(p)->c.b<<(s)) + +#define PIXEL_SCALE(p,q,s)\ + ((q)->c.r=(p)->c.r>>(s)), \ + ((q)->c.g=(p)->c.g>>(s)), \ + ((q)->c.b=(p)->c.b>>(s)) + +static unsigned long +unshifted_pixel_hash(const HashTable h, const void *p) +{ + Pixel *pixel=(Pixel *)&p; + unsigned long hash=PIXEL_HASH(pixel->c.r, + pixel->c.g, + pixel->c.b); + return hash; +} + +static int +unshifted_pixel_cmp(const HashTable h, const void *a, const void *b) +{ + Pixel *pixel1=(Pixel *)&a; + Pixel *pixel2=(Pixel *)&b; + if (pixel1->c.r==pixel2->c.r) { + if (pixel1->c.g==pixel2->c.g) { + if (pixel1->c.b==pixel2->c.b) { + return 0; + } else { + return (int)(pixel1->c.b)-(int)(pixel2->c.b); + } + } else { + return (int)(pixel1->c.g)-(int)(pixel2->c.g); + } + } else { + return (int)(pixel1->c.r)-(int)(pixel2->c.r); + } +} + +static unsigned long +pixel_hash(const HashTable h,const void *p) +{ + PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); + Pixel *pixel=(Pixel *)&p; + unsigned long hash=PIXEL_HASH(pixel->c.r>>d->scale, + pixel->c.g>>d->scale, + pixel->c.b>>d->scale); + return hash; +} + +static int +pixel_cmp(const HashTable h,const void *a,const void *b) +{ + PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); + Pixel *pixel1=(Pixel *)&a; + Pixel *pixel2=(Pixel *)&b; + unsigned long A,B; + A=PIXEL_HASH(pixel1->c.r>>d->scale, + pixel1->c.g>>d->scale, + pixel1->c.b>>d->scale); + B=PIXEL_HASH(pixel2->c.r>>d->scale, + pixel2->c.g>>d->scale, + pixel2->c.b>>d->scale); + return (A==B)?0:((Ascale=0; + timer=timer3=clock(); + for (i=0;iMAX_HASH_ENTRIES) { + d->scale++; +#ifndef NO_OUTPUT + printf ("rehashing - new scale: %d\n",(int)d->scale); +#endif + timer2=clock(); + hashtable_rehash_compute(hash,rehash_collide); + timer2=clock()-timer2; +#ifndef NO_OUTPUT + printf ("rehash took %f sec\n",timer2/(double)CLOCKS_PER_SEC); +#endif + timer+=timer2; + } + } +#ifndef NO_OUTPUT + printf ("inserts took %f sec\n",(clock()-timer)/(double)CLOCKS_PER_SEC); +#endif +#ifndef NO_OUTPUT + printf ("total %f sec\n",(clock()-timer3)/(double)CLOCKS_PER_SEC); +#endif + return hash; +} + +static void +destroy_pixel_hash(HashTable hash) +{ + PixelHashData *d=(PixelHashData *)hashtable_get_user_data(hash); + if (d) free(d); + hashtable_free(hash); +} + + +/* 1. hash quantized pixels. */ +/* 2. create R,G,B lists of sorted quantized pixels. */ +/* 3. median cut. */ +/* 4. build hash table from median cut boxes. */ +/* 5. for each pixel, compute entry in hash table, and hence median cut box. */ +/* 6. compute median cut box pixel averages. */ +/* 7. map each pixel to nearest average. */ + +static int +compute_box_volume(BoxNode *b) +{ + unsigned char rl,rh,gl,gh,bl,bh; + if (b->volume>=0) return b->volume; + if (!b->head[0]) { + b->volume=0; + } else { + rh=b->head[0]->p.c.r; + rl=b->tail[0]->p.c.r; + gh=b->head[1]->p.c.g; + gl=b->tail[1]->p.c.g; + bh=b->head[2]->p.c.b; + bl=b->tail[2]->p.c.b; + b->volume=(rh-rl+1)*(gh-gl+1)*(bh-bl+1); + } + return b->volume; +} + +static void +hash_to_list(HashTable h, const void *key, const void *val, void *u) +{ + PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); + PixelList **pl=(PixelList **)u; + PixelList *p; + Pixel *pixel=(Pixel *)&key; + int i; + Pixel q; + int count=*(int *)&val; + + PIXEL_SCALE(pixel,&q,d->scale); + + p=malloc(sizeof(PixelList)); + if (!p) return; + + p->flag=0; + p->p=q; + p->count=count; + for (i=0;i<3;i++) { + p->next[i]=pl[i]; + p->prev[i]=NULL; + if (pl[i]) pl[i]->prev[i]=p; + pl[i]=p; + } +} + +static PixelList * +mergesort_pixels(PixelList *head, int i) +{ + PixelList *c,*t,*a,*b,*p; + if (!head||!head->next[i]) { + if (head) { + head->next[i]=NULL; + head->prev[i]=NULL; + } + return head; + } + for (c=t=head;c&&t;c=c->next[i],t=(t->next[i])?t->next[i]->next[i]:NULL); + if (c) { + if (c->prev[i]) c->prev[i]->next[i]=NULL; + c->prev[i]=NULL; + } + a=mergesort_pixels(head,i); + b=mergesort_pixels(c,i); + head=NULL; + p=NULL; + while (a&&b) { + if (a->p.a.v[i]>b->p.a.v[i]) { + c=a; + a=a->next[i]; + } else { + c=b; + b=b->next[i]; + } + c->prev[i]=p; + c->next[i]=NULL; + if (p) p->next[i]=c; + p=c; + if (!head) head=c; + } + if (a) { + c->next[i]=a; + a->prev[i]=c; + } else if (b) { + c->next[i]=b; + b->prev[i]=c; + } + return head; +} + +#if defined(TEST_MERGESORT) || defined(TEST_SORTED) +static int +test_sorted(PixelList *pl[3]) +{ + int i,n,l; + PixelList *t; + + for(i=0;i<3;i++) { + n=0; + l=256; + for (t=pl[i];t;t=t->next[i]) { + if (lp.a.v[i]) return 0; + l=t->p.a.v[i]; + } + } + return 1; +} +#endif + +static int +box_heap_cmp(const Heap h, const void *A, const void *B) +{ + BoxNode *a=(BoxNode *)A; + BoxNode *b=(BoxNode *)B; + return (int)a->pixelCount-(int)b->pixelCount; +} + +#define LUMINANCE(p) (77*(p)->c.r+150*(p)->c.g+29*(p)->c.b) + +static int +splitlists(PixelList *h[3], + PixelList *t[3], + PixelList *nh[2][3], + PixelList *nt[2][3], + unsigned long nCount[2], + int axis, + unsigned long pixelCount) +{ + unsigned long left; + + PixelList *l,*r,*c,*n; + int i; + int nRight,nLeft; + int splitColourVal; + +#ifdef TEST_SPLIT + { + PixelList *_prevTest,*_nextTest; + int _i,_nextCount[3],_prevCount[3]; + for (_i=0;_i<3;_i++) { + for (_nextCount[_i]=0,_nextTest=h[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++); + for (_prevCount[_i]=0,_prevTest=t[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++); + if (_nextTest!=t[_i]) { + printf ("next-list of axis %d does not end at tail\n",_i); + exit(1); + } + if (_prevTest!=h[_i]) { + printf ("prev-list of axis %d does not end at head\n",_i); + exit(1); + } + for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]); + for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]); + if (_nextTest!=h[_i]) { + printf ("next-list of axis %d does not loop back to head\n",_i); + exit(1); + } + if (_prevTest!=t[_i]) { + printf ("prev-list of axis %d does not loop back to tail\n",_i); + exit(1); + } + } + for (_i=1;_i<3;_i++) { + if (_prevCount[_i]!=_prevCount[_i-1] || + _nextCount[_i]!=_nextCount[_i-1] || + _prevCount[_i]!=_nextCount[_i]) { + printf ("{%d %d %d} {%d %d %d}\n", + _prevCount[0], + _prevCount[1], + _prevCount[2], + _nextCount[0], + _nextCount[1], + _nextCount[2]); + exit(1); + } + } + } +#endif + nCount[0]=nCount[1]=0; + nLeft=nRight=0; + for (left=0,c=h[axis];c;) { + left=left+c->count; + nCount[0]+=c->count; + c->flag=0; + nLeft++; + c=c->next[axis]; + if (left*2>pixelCount) { + break; + } + } + if (c) { + splitColourVal=c->prev[axis]->p.a.v[axis]; + for (;c;c=c->next[axis]) { + if (splitColourVal!=c->p.a.v[axis]) { + break; + } + c->flag=0; + nLeft++; + nCount[0]+=c->count; + } + } + for (;c;c=c->next[axis]) { + c->flag=1; + nRight++; + nCount[1]+=c->count; + } + if (!nRight) { + for (c=t[axis],splitColourVal=t[axis]->p.a.v[axis];c;c=c->prev[axis]) { + if (splitColourVal!=c->p.a.v[axis]) { + break; + } + c->flag=1; + nRight++; + nLeft--; + nCount[0]-=c->count; + nCount[1]+=c->count; + } + } +#ifndef NO_OUTPUT + if (!nLeft) { + for (c=h[axis];c;c=c->next[axis]) { + printf ("[%d %d %d]\n",c->p.c.r,c->p.c.g,c->p.c.b); + } + printf ("warning... trivial split\n"); + } +#endif + + for (i=0;i<3;i++) { + l=r=NULL; + nh[0][i]=nt[0][i]=NULL; + nh[1][i]=nt[1][i]=NULL; + for (c=h[i];c;c=n) { + n=c->next[i]; + if (c->flag) { /* move pixel to right list*/ + if (r) r->next[i]=c; else nh[1][i]=c; + c->prev[i]=r; + r=c; + } else { /* move pixel to left list */ + if (l) l->next[i]=c; else nh[0][i]=c; + c->prev[i]=l; + l=c; + } + } + if (l) l->next[i]=NULL; + if (r) r->next[i]=NULL; + nt[0][i]=l; + nt[1][i]=r; + } + return 1; +} + +static int +split(BoxNode *node) +{ + unsigned char rl,rh,gl,gh,bl,bh; + int f[3]; + int best,axis; + int i; + PixelList *heads[2][3]; + PixelList *tails[2][3]; + unsigned long newCounts[2]; + BoxNode *left,*right; + + rh=node->head[0]->p.c.r; + rl=node->tail[0]->p.c.r; + gh=node->head[1]->p.c.g; + gl=node->tail[1]->p.c.g; + bh=node->head[2]->p.c.b; + bl=node->tail[2]->p.c.b; +#ifdef TEST_SPLIT + printf ("splitting node [%d %d %d] [%d %d %d] ",rl,gl,bl,rh,gh,bh); +#endif + f[0]=(rh-rl)*77; + f[1]=(gh-gl)*150; + f[2]=(bh-bl)*29; + + best=f[0]; + axis=0; + for (i=1;i<3;i++) { + if (besttail[_i]->next[_i]) { + printf ("tail is not tail\n"); + printf ("node->tail[%d]->next[%d]=%p\n",_i,_i,node->tail[_i]->next[_i]); + } + if (node->head[_i]->prev[_i]) { + printf ("head is not head\n"); + printf ("node->head[%d]->prev[%d]=%p\n",_i,_i,node->head[_i]->prev[_i]); + } + } + + for (_i=0;_i<3;_i++) { + for (_nextCount[_i]=0,_nextTest=node->head[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++); + for (_prevCount[_i]=0,_prevTest=node->tail[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++); + if (_nextTest!=node->tail[_i]) { + printf ("next-list of axis %d does not end at tail\n",_i); + } + if (_prevTest!=node->head[_i]) { + printf ("prev-list of axis %d does not end at head\n",_i); + } + for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]); + for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]); + if (_nextTest!=node->head[_i]) { + printf ("next-list of axis %d does not loop back to head\n",_i); + } + if (_prevTest!=node->tail[_i]) { + printf ("prev-list of axis %d does not loop back to tail\n",_i); + } + } + for (_i=1;_i<3;_i++) { + if (_prevCount[_i]!=_prevCount[_i-1] || + _nextCount[_i]!=_nextCount[_i-1] || + _prevCount[_i]!=_nextCount[_i]) { + printf ("{%d %d %d} {%d %d %d}\n", + _prevCount[0], + _prevCount[1], + _prevCount[2], + _nextCount[0], + _nextCount[1], + _nextCount[2]); + } + } + } +#endif + node->axis=axis; + if (!splitlists(node->head, + node->tail, + heads, + tails, + newCounts, + axis, + node->pixelCount)) { +#ifndef NO_OUTPUT + printf ("list split failed.\n"); +#endif + return 0; + } +#ifdef TEST_SPLIT + if (!test_sorted(heads[0])) { + printf ("bug in split"); + exit(1); + } + if (!test_sorted(heads[1])) { + printf ("bug in split"); + exit(1); + } +#endif + left=malloc(sizeof(BoxNode)); + right=malloc(sizeof(BoxNode)); + if (!left||!right) { + return 0; + } + for(i=0;i<3;i++) { + left->head[i]=heads[0][i]; + left->tail[i]=tails[0][i]; + right->head[i]=heads[1][i]; + right->tail[i]=tails[1][i]; + node->head[i]=NULL; + node->tail[i]=NULL; + } +#ifdef TEST_SPLIT + if (left->head[0]) { + rh=left->head[0]->p.c.r; + rl=left->tail[0]->p.c.r; + gh=left->head[1]->p.c.g; + gl=left->tail[1]->p.c.g; + bh=left->head[2]->p.c.b; + bl=left->tail[2]->p.c.b; + printf (" left node [%3d %3d %3d] [%3d %3d %3d]\n",rl,gl,bl,rh,gh,bh); + } + if (right->head[0]) { + rh=right->head[0]->p.c.r; + rl=right->tail[0]->p.c.r; + gh=right->head[1]->p.c.g; + gl=right->tail[1]->p.c.g; + bh=right->head[2]->p.c.b; + bl=right->tail[2]->p.c.b; + printf (" right node [%3d %3d %3d] [%3d %3d %3d]\n",rl,gl,bl,rh,gh,bh); + } +#endif + left->l=left->r=NULL; + right->l=right->r=NULL; + left->axis=right->axis=-1; + left->volume=right->volume=-1; + left->pixelCount=newCounts[0]; + right->pixelCount=newCounts[1]; + node->l=left; + node->r=right; + return 1; +} + +static BoxNode * +median_cut(PixelList *hl[3], + unsigned long imPixelCount, + int nPixels) +{ + PixelList *tl[3]; + int i; + BoxNode *root; + Heap h; + BoxNode *thisNode; + + h=ImagingQuantHeapNew(box_heap_cmp); + root=malloc(sizeof(BoxNode)); + if (!root) { ImagingQuantHeapFree(h); return NULL; } + for(i=0;i<3;i++) { + for (tl[i]=hl[i];tl[i]&&tl[i]->next[i];tl[i]=tl[i]->next[i]); + root->head[i]=hl[i]; + root->tail[i]=tl[i]; + } + root->l=root->r=NULL; + root->axis=-1; + root->volume=-1; + root->pixelCount=imPixelCount; + + ImagingQuantHeapAdd(h,(void *)root); + while (--nPixels) { + do { + if (!ImagingQuantHeapRemove(h,(void **)&thisNode)) { + goto done; + } + } while (compute_box_volume(thisNode)==1); + if (!split(thisNode)) { +#ifndef NO_OUTPUT + printf ("Oops, split failed...\n"); +#endif + exit (1); + } + ImagingQuantHeapAdd(h,(void *)(thisNode->l)); + ImagingQuantHeapAdd(h,(void *)(thisNode->r)); + } +done: + ImagingQuantHeapFree(h); + return root; +} + +static void +free_box_tree(BoxNode *n) +{ + PixelList *p,*pp; + if (n->l) free_box_tree(n->l); + if (n->r) free_box_tree(n->r); + for (p=n->head[0];p;p=pp) { + pp=p->next[0]; + free(p); + } + free(n); +} + +#ifdef TEST_SPLIT_INTEGRITY +static int +checkContained(BoxNode *n,Pixel *pp) +{ + if (n->l&&n->r) { + return checkContained(n->l,pp)+checkContained(n->r,pp); + } + if (n->l||n->r) { +#ifndef NO_OUTPUT + printf ("box tree is dead\n"); +#endif + return 0; + } + if ( + pp->c.r<=n->head[0]->p.c.r && + pp->c.r>=n->tail[0]->p.c.r && + pp->c.g<=n->head[1]->p.c.g && + pp->c.g>=n->tail[1]->p.c.g && + pp->c.b<=n->head[2]->p.c.b && + pp->c.b>=n->tail[2]->p.c.b) { + return 1; + } + return 0; +} +#endif + +static int +annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box) +{ + PixelList *p; + PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); + Pixel q; + if (n->l&&n->r) { + return annotate_hash_table(n->l,h,box) && annotate_hash_table(n->r,h,box); + } + if (n->l||n->r) { +#ifndef NO_OUTPUT + printf ("box tree is dead\n"); +#endif + return 0; + } + for (p=n->head[0];p;p=p->next[0]) { + PIXEL_UNSCALE(&(p->p),&q,d->scale); + if (!hashtable_insert(h,(void *)q.v,(void *)*box)) { +#ifndef NO_OUTPUT + printf ("hashtable insert failed\n"); +#endif + return 0; + } + } + if (n->head[0]) (*box)++; + return 1; +} + +static int +_sort_ulong_ptr_keys(const void *a, const void *b) +{ + unsigned long A=**(unsigned long **)a; + unsigned long B=**(unsigned long **)b; + return (A==B)?0:((A*(skRow[k]));k--) { + skRow[k]=skRow[k-1]; + } + if (k!=j) skRow[k]=skElt; + } + } + return 1; +} + +static int +build_distance_tables(unsigned long *avgDist, + unsigned long **avgDistSortKey, + Pixel *p, + unsigned long nEntries) +{ + unsigned long i,j; + + for (i=0;i1) { + printf ("pixel in two boxes\n"); + for(i=0;i<3;i++) free (avg[i]); + free(count); + return 0; + } +#endif + if (!hashtable_lookup(medianBoxHash,(void *)pixelData[i].v,(void **)&paletteEntry)) { +#ifndef NO_OUTPUT + printf ("pixel lookup failed\n"); +#endif + for(i=0;i<3;i++) free (avg[i]); + free(count); + return 0; + } + if (paletteEntry>=nPaletteEntries) { +#ifndef NO_OUTPUT + printf ("panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",(int)paletteEntry,(int)nPaletteEntries); +#endif + for(i=0;i<3;i++) free (avg[i]); + free(count); + return 0; + } + avg[0][paletteEntry]+=pixelData[i].c.r; + avg[1][paletteEntry]+=pixelData[i].c.g; + avg[2][paletteEntry]+=pixelData[i].c.b; + count[paletteEntry]++; + } + p=malloc(sizeof(Pixel)*nPaletteEntries); + if (!p) { + for(i=0;i<3;i++) free (avg[i]); + free(count); + return 0; + } + for (i=0;i=nPaletteEntries) { +#ifndef NO_OUTPUT + printf ("scream\n"); +#endif + return 0; + } + avg[0][qp[i]]+=pixelData[i].c.r; + avg[1][qp[i]]+=pixelData[i].c.g; + avg[2][qp[i]]+=pixelData[i].c.b; + count[qp[i]]++; + } + for (i=0;i + { + unsigned long bestmatch,bestdist,dist; + HashTable h2; + printf ("nearest neighbour search (full search)..."); fflush(stdout); timer=clock(); + h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); + for (i=0;inew),pixel); + if (data->secondPixel || newDistdata->furthestDistance) { + data->furthestDistance=oldDist; + data->furthest.v=pixel->v; + } +} + +int +quantize2(Pixel *pixelData, + unsigned long nPixels, + unsigned long nQuantPixels, + Pixel **palette, + unsigned long *paletteLength, + unsigned long **quantizedPixels, + int kmeans) +{ + HashTable h; + unsigned long i; + unsigned long mean[3]; + Pixel *p; + DistanceData data; + + unsigned long *qp; + unsigned long *avgDist; + unsigned long **avgDistSortKey; + + p=malloc(sizeof(Pixel)*nQuantPixels); + if (!p) return 0; + mean[0]=mean[1]=mean[2]=0; + h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); + for (i=0;i 256) + /* FIXME: for colors > 256, consider returning an RGB image + instead (see @PIL205) */ + return (Imaging) ImagingError_ValueError("bad number of colors"); + + if (strcmp(im->mode, "L") != 0 && strcmp(im->mode, "P") != 0 && + strcmp(im->mode, "RGB")) + return ImagingError_ModeError(); + + p = malloc(sizeof(Pixel) * im->xsize * im->ysize); + if (!p) + return ImagingError_MemoryError(); + + /* collect statistics */ + + /* FIXME: maybe we could load the hash tables directly from the + image data? */ + + if (!strcmp(im->mode, "L")) { + /* greyscale */ + + /* FIXME: converting a "L" image to "P" with 256 colors + should be done by a simple copy... */ + + for (i = y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++, i++) + p[i].c.r = p[i].c.g = p[i].c.b = im->image8[y][x]; + + } else if (!strcmp(im->mode, "P")) { + /* palette */ + + pp = im->palette->palette; + + for (i = y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++, i++) { + v = im->image8[y][x]; + p[i].c.r = pp[v*4+0]; + p[i].c.g = pp[v*4+1]; + p[i].c.b = pp[v*4+2]; + } + + } else if (!strcmp(im->mode, "RGB")) { + /* true colour */ + + for (i = y = 0; y < im->ysize; y++) + for (x = 0; x < im->xsize; x++, i++) + p[i].v = im->image32[y][x]; + + } else { + free(p); + return (Imaging) ImagingError_ValueError("internal error"); + } + + switch (mode) { + case 0: + /* median cut */ + result = quantize( + p, + im->xsize*im->ysize, + colors, + &palette, + &paletteLength, + &newData, + kmeans + ); + break; + case 1: + /* maximum coverage */ + result = quantize2( + p, + im->xsize*im->ysize, + colors, + &palette, + &paletteLength, + &newData, + kmeans + ); + break; + default: + result = 0; + break; + } + + free(p); + + if (result) { + + imOut = ImagingNew("P", im->xsize, im->ysize); + + for (i = y = 0; y < im->ysize; y++) + for (x=0; x < im->xsize; x++) + imOut->image8[y][x] = (unsigned char) newData[i++]; + + free(newData); + + pp = imOut->palette->palette; + + for (i = j = 0; i < (int) paletteLength; i++) { + *pp++ = palette[i].c.r; + *pp++ = palette[i].c.g; + *pp++ = palette[i].c.b; + *pp++ = 255; + } + for (; i < 256; i++) { + *pp++ = 0; + *pp++ = 0; + *pp++ = 0; + *pp++ = 255; + } + + free(palette); + + return imOut; + + } else { + + return (Imaging) ImagingError_ValueError("quantization error"); + + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h new file mode 100755 index 00000000000..0de485a1a1a --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h @@ -0,0 +1,40 @@ +/* + * The Python Imaging Library + * $Id$ + * + * image quantizer + * + * Written by Toby J Sargeant . + * + * See the README file for information on usage and redistribution. + */ + +#ifndef __QUANT_H__ +#define __QUANT_H__ + +typedef union { + struct { + unsigned char r,g,b,a; + } c; + struct { + unsigned char v[4]; + } a; + unsigned long v; +} Pixel; + +int quantize(Pixel *, + unsigned long, + unsigned long, + Pixel **, + unsigned long *, + unsigned long **, + int); + +int quantize2(Pixel *, + unsigned long, + unsigned long, + Pixel **, + unsigned long *, + unsigned long **, + int); +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h new file mode 100755 index 00000000000..5b080104e1a --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h @@ -0,0 +1,25 @@ +/* + * The Python Imaging Library + * $Id$ + * + * image quantizer + * + * Written by Toby J Sargeant . + * + * See the README file for information on usage and redistribution. + */ + +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#if 0 + +void *newMalloc(size_t,const char *,const char *,int); +void newFree(void *,const char *,const char *,int); +void print_malloc_stats(); +#define malloc(x) newMalloc(x,__FILE__,__FUNCTION__,__LINE__) +#define free(x) newFree(x,__FILE__,__FUNCTION__,__LINE__) + +#endif + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c new file mode 100755 index 00000000000..e6438402dd7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c @@ -0,0 +1,477 @@ +/* + * The Python Imaging Library + * $Id$ + * + * hash tables used by the image quantizer + * + * history: + * 98-09-10 tjs Contributed + * 98-12-29 fl Added to PIL 1.0b1 + * + * Written by Toby J Sargeant . + * + * Copyright (c) 1998 by Toby J Sargeant + * Copyright (c) 1998 by Secret Labs AB + * + * See the README file for information on usage and redistribution. + */ + +#include +#include +#include +#include + +#include "QuantHash.h" +#include "QuantDefines.h" + +typedef struct _IntHashNode { + struct _IntHashNode *next; + void *key,*value; +} IntHashNode; + +typedef struct _IntHashTable { + IntHashNode **table; + unsigned long length; + unsigned long count; + HashFunc hashFunc; + HashCmpFunc cmpFunc; + DestroyFunc keyDestroyFunc; + DestroyFunc valDestroyFunc; + void *userData; +} IntHashTable; + +#define MIN_LENGTH 11 +#define RESIZE_FACTOR 3 + +static int _hashtable_insert_node(IntHashTable *,IntHashNode *,int,int,CollisionFunc); +#if 0 +static int _hashtable_test(IntHashTable *); +#endif + +HashTable hashtable_new(HashFunc hf,HashCmpFunc cf) { + IntHashTable *h; + h=malloc(sizeof(IntHashTable)); + if (!h) { return NULL; } + h->hashFunc=hf; + h->cmpFunc=cf; + h->keyDestroyFunc=NULL; + h->valDestroyFunc=NULL; + h->length=MIN_LENGTH; + h->count=0; + h->userData=NULL; + h->table=malloc(sizeof(IntHashNode *)*h->length); + if (!h->table) { free(h); return NULL; } + memset (h->table,0,sizeof(IntHashNode *)*h->length); + return (HashTable)h; +} + +static void _hashtable_destroy(HashTable H,const void *key,const void *val,void *u) { + IntHashTable *h=(IntHashTable *)H; + if (h->keyDestroyFunc&&key) { + h->keyDestroyFunc((HashTable)h,(void *)key); + } + if (h->valDestroyFunc&&val) { + h->valDestroyFunc((HashTable)h,(void *)val); + } +} + +static unsigned long _findPrime(unsigned long start,int dir) { + static int unit[]={0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0}; + unsigned long t; + while (start>1) { + if (!unit[start&0x0f]) { + start+=dir; + continue; + } + for (t=2;t=sqrt((double)start)) { + break; + } + start+=dir; + } + return start; +} + +static void _hashtable_rehash(IntHashTable *h, + CollisionFunc cf, + unsigned long newSize) { + IntHashNode **oldTable=h->table; + unsigned long i; + IntHashNode *n,*nn; + unsigned long oldSize; + oldSize=h->length; + h->table=malloc(sizeof(IntHashNode *)*newSize); + if (!h->table) { + h->table=oldTable; + return; + } + h->length=newSize; + h->count=0; + memset (h->table,0,sizeof(IntHashNode *)*h->length); + for (i=0;inext; + _hashtable_insert_node(h,n,0,0,cf); + } + } + free(oldTable); +} + +static void _hashtable_resize(IntHashTable *h) { + unsigned long newSize; + unsigned long oldSize; + oldSize=h->length; + newSize=oldSize; + if (h->count*RESIZE_FACTORlength) { + newSize=_findPrime(h->length/2-1,-1); + } else if (h->length*RESIZE_FACTORcount) { + newSize=_findPrime(h->length*2+1,+1); + } + if (newSizelength;i++) { + for (n=h->table[i];n&&n->next;n=n->next) { + j=h->cmpFunc((HashTable)h,n->key,n->next->key); + printf ("%c",j?(j<0?'-':'+'):'='); + } + printf ("\n"); + } + return 0; +} +#endif + +static int _hashtable_insert_node(IntHashTable *h,IntHashNode *node,int resize,int update,CollisionFunc cf) { + unsigned long hash=h->hashFunc((HashTable)h,node->key)%h->length; + IntHashNode **n,*nv; + int i; + + for (n=&(h->table[hash]);*n;n=&((*n)->next)) { + nv=*n; + i=h->cmpFunc((HashTable)h,nv->key,node->key); + if (!i) { + if (cf) { + nv->key=node->key; + cf((HashTable)h,&(nv->key),&(nv->value),node->key,node->value); + free(node); + return 1; + } else { + if (h->valDestroyFunc) { + h->valDestroyFunc((HashTable)h,nv->value); + } + if (h->keyDestroyFunc) { + h->keyDestroyFunc((HashTable)h,nv->key); + } + nv->key=node->key; + nv->value=node->value; + free(node); + return 1; + } + } else if (i>0) { + break; + } + } + if (!update) { + node->next=*n; + *n=node; + h->count++; + if (resize) _hashtable_resize(h); + return 1; + } else { + return 0; + } +} + +static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int update) { + IntHashNode **n,*nv; + IntHashNode *t; + int i; + unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + + for (n=&(h->table[hash]);*n;n=&((*n)->next)) { + nv=*n; + i=h->cmpFunc((HashTable)h,nv->key,key); + if (!i) { + if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,nv->value); } + nv->value=val; + return 1; + } else if (i>0) { + break; + } + } + if (!update) { + t=malloc(sizeof(IntHashNode)); + if (!t) return 0; + t->next=*n; + *n=t; + t->key=key; + t->value=val; + h->count++; + if (resize) _hashtable_resize(h); + return 1; + } else { + return 0; + } +} + +static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,void *newVal,int resize) { + IntHashNode **n,*nv; + IntHashNode *t; + int i; + unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + + for (n=&(h->table[hash]);*n;n=&((*n)->next)) { + nv=*n; + i=h->cmpFunc((HashTable)h,nv->key,key); + if (!i) { + *retVal=nv->value; + return 1; + } else if (i>0) { + break; + } + } + t=malloc(sizeof(IntHashNode)); + if (!t) return 0; + t->next=*n; + *n=t; + t->key=key; + t->value=newVal; + *retVal=newVal; + h->count++; + if (resize) _hashtable_resize(h); + return 1; +} + +int hashtable_insert_or_update_computed(HashTable H, + void *key, + ComputeFunc newFunc, + ComputeFunc existsFunc) { + IntHashTable *h=(IntHashTable *)H; + IntHashNode **n,*nv; + IntHashNode *t; + int i; + unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + + for (n=&(h->table[hash]);*n;n=&((*n)->next)) { + nv=*n; + i=h->cmpFunc((HashTable)h,nv->key,key); + if (!i) { + void *old=nv->value; + if (existsFunc) { + existsFunc(H,nv->key,&(nv->value)); + if (nv->value!=old) { + if (h->valDestroyFunc) { + h->valDestroyFunc((HashTable)h,old); + } + } + } else { + return 0; + } + return 1; + } else if (i>0) { + break; + } + } + t=malloc(sizeof(IntHashNode)); + if (!t) return 0; + t->key=key; + t->next=*n; + *n=t; + if (newFunc) { + newFunc(H,t->key,&(t->value)); + } else { + free(t); + return 0; + } + h->count++; + _hashtable_resize(h); + return 1; +} + +int hashtable_update(HashTable H,void *key,void *val) { + IntHashTable *h=(IntHashTable *)H; + return _hashtable_insert(h,key,val,1,0); +} + +int hashtable_insert(HashTable H,void *key,void *val) { + IntHashTable *h=(IntHashTable *)H; + return _hashtable_insert(h,key,val,1,0); +} + +void hashtable_foreach_update(HashTable H,IteratorUpdateFunc i,void *u) { + IntHashTable *h=(IntHashTable *)H; + IntHashNode *n; + unsigned long x; + + if (h->table) { + for (x=0;xlength;x++) { + for (n=h->table[x];n;n=n->next) { + i((HashTable)h,n->key,(void **)&(n->value),u); + } + } + } +} + +void hashtable_foreach(HashTable H,IteratorFunc i,void *u) { + IntHashTable *h=(IntHashTable *)H; + IntHashNode *n; + unsigned long x; + + if (h->table) { + for (x=0;xlength;x++) { + for (n=h->table[x];n;n=n->next) { + i((HashTable)h,n->key,n->value,u); + } + } + } +} + +void hashtable_free(HashTable H) { + IntHashTable *h=(IntHashTable *)H; + IntHashNode *n,*nn; + unsigned long i; + + if (h->table) { + if (h->keyDestroyFunc || h->keyDestroyFunc) { + hashtable_foreach(H,_hashtable_destroy,NULL); + } + for (i=0;ilength;i++) { + for (n=h->table[i];n;n=nn) { + nn=n->next; + free(n); + } + } + free(h->table); + } + free(h); +} + +DestroyFunc hashtable_set_value_destroy_func(HashTable H,DestroyFunc d) { + IntHashTable *h=(IntHashTable *)H; + DestroyFunc r=h->valDestroyFunc; + h->valDestroyFunc=d; + return r; +} + +DestroyFunc hashtable_set_key_destroy_func(HashTable H,DestroyFunc d) { + IntHashTable *h=(IntHashTable *)H; + DestroyFunc r=h->keyDestroyFunc; + h->keyDestroyFunc=d; + return r; +} + +static int _hashtable_remove(IntHashTable *h, + const void *key, + void **keyRet, + void **valRet, + int resize) { + unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + IntHashNode *n,*p; + int i; + + for (p=NULL,n=h->table[hash];n;p=n,n=n->next) { + i=h->cmpFunc((HashTable)h,n->key,key); + if (!i) { + if (p) p=n->next; else h->table[hash]=n->next; + *keyRet=n->key; + *valRet=n->value; + free(n); + h->count++; + return 1; + } else if (i>0) { + break; + } + } + return 0; +} + +static int _hashtable_delete(IntHashTable *h,const void *key,int resize) { + unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + IntHashNode *n,*p; + int i; + + for (p=NULL,n=h->table[hash];n;p=n,n=n->next) { + i=h->cmpFunc((HashTable)h,n->key,key); + if (!i) { + if (p) p=n->next; else h->table[hash]=n->next; + if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,n->value); } + if (h->keyDestroyFunc) { h->keyDestroyFunc((HashTable)h,n->key); } + free(n); + h->count++; + return 1; + } else if (i>0) { + break; + } + } + return 0; +} + +int hashtable_remove(HashTable H,const void *key,void **keyRet,void **valRet) { + IntHashTable *h=(IntHashTable *)H; + return _hashtable_remove(h,key,keyRet,valRet,1); +} + +int hashtable_delete(HashTable H,const void *key) { + IntHashTable *h=(IntHashTable *)H; + return _hashtable_delete(h,key,1); +} + +void hashtable_rehash_compute(HashTable H,CollisionFunc cf) { + IntHashTable *h=(IntHashTable *)H; + _hashtable_rehash(h,cf,h->length); +} + +void hashtable_rehash(HashTable H) { + IntHashTable *h=(IntHashTable *)H; + _hashtable_rehash(h,NULL,h->length); +} + +int hashtable_lookup_or_insert(HashTable H,void *key,void **valp,void *val) { + IntHashTable *h=(IntHashTable *)H; + return _hashtable_lookup_or_insert(h,key,valp,val,1); +} + +int hashtable_lookup(const HashTable H,const void *key,void **valp) { + IntHashTable *h=(IntHashTable *)H; + unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + IntHashNode *n; + int i; + + for (n=h->table[hash];n;n=n->next) { + i=h->cmpFunc((HashTable)h,n->key,key); + if (!i) { + *valp=n->value; + return 1; + } else if (i>0) { + break; + } + } + return 0; +} + +unsigned long hashtable_get_count(const HashTable H) { + IntHashTable *h=(IntHashTable *)H; + return h->count; +} + +void *hashtable_get_user_data(const HashTable H) { + IntHashTable *h=(IntHashTable *)H; + return h->userData; +} + +void *hashtable_set_user_data(HashTable H,void *data) { + IntHashTable *h=(IntHashTable *)H; + void *r=h->userData; + h->userData=data; + return r; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h new file mode 100755 index 00000000000..b98b56eaa4c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h @@ -0,0 +1,36 @@ +/* + * The Python Imaging Library + * $Id$ + * + * image quantizer + * + * Written by Toby J Sargeant . + * + * See the README file for information on usage and redistribution. + */ + +#ifndef __HASH_H__ +#define __HASH_H__ + +#include "QuantTypes.h" + +HashTable hashtable_new(HashFunc,HashCmpFunc); +void hashtable_free(HashTable); +void hashtable_foreach(HashTable,IteratorFunc,void *); +void hashtable_foreach_update(HashTable,IteratorUpdateFunc,void *); +int hashtable_insert(HashTable,void *,void *); +int hashtable_update(HashTable,void *,void *); +int hashtable_lookup(const HashTable,const void *,void **); +int hashtable_lookup_or_insert(HashTable,void *,void **,void *); +int hashtable_insert_or_update_computed(HashTable,void *,ComputeFunc,ComputeFunc); +int hashtable_delete(HashTable,const void *); +int hashtable_remove(HashTable,const void *,void **,void **); +void *hashtable_set_user_data(HashTable,void *); +void *hashtable_get_user_data(const HashTable); +DestroyFunc hashtable_set_key_destroy_func(HashTable,DestroyFunc); +DestroyFunc hashtable_set_value_destroy_func(HashTable,DestroyFunc); +unsigned long hashtable_get_count(const HashTable); +void hashtable_rehash(HashTable); +void hashtable_rehash_compute(HashTable,CollisionFunc); + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c new file mode 100755 index 00000000000..9332a5cd71f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c @@ -0,0 +1,150 @@ +/* + * The Python Imaging Library + * $Id$ + * + * heap data type used by the image quantizer + * + * history: + * 98-09-10 tjs Contributed + * 98-12-29 fl Added to PIL 1.0b1 + * + * Written by Toby J Sargeant . + * + * Copyright (c) 1998 by Toby J Sargeant + * Copyright (c) 1998 by Secret Labs AB + * + * See the README file for information on usage and redistribution. + */ + +#include +#include +#include +#include + +#include "QuantHash.h" +#include "QuantDefines.h" + +typedef struct { + void **heap; + int heapsize; + int heapcount; + HeapCmpFunc cf; +} IntHeap; + +#define INITIAL_SIZE 256 + +#define DEBUG + +#ifdef DEBUG +static int _heap_test(Heap); +#endif + +void ImagingQuantHeapFree(Heap H) { + IntHeap *h=(IntHeap *)H; + free(h->heap); + free(h); +} + +static int _heap_grow(IntHeap *h,int newsize) { + void *newheap; + if (!newsize) newsize=h->heapsize<<1; + if (newsizeheapsize) return 0; + newheap=malloc(sizeof(void *)*newsize); + if (!newheap) return 0; + memcpy(newheap,h->heap,sizeof(void *)*h->heapsize); + free(h->heap); + h->heap=newheap; + h->heapsize=newsize; + return 1; +} + +#ifdef DEBUG +static int _heap_test(Heap H) { + IntHeap *h=(IntHeap *)H; + int k; + for (k=1;k*2<=h->heapcount;k++) { + if (h->cf(H,h->heap[k],h->heap[k*2])<0) { + printf ("heap is bad\n"); + return 0; + } + if (k*2+1<=h->heapcount && h->cf(H,h->heap[k],h->heap[k*2+1])<0) { + printf ("heap is bad\n"); + return 0; + } + } + return 1; +} +#endif + +int ImagingQuantHeapRemove(Heap H,void **r) { + IntHeap *h=(IntHeap *)H; + int k,l; + void *v; + + if (!h->heapcount) { + return 0; + } + *r=h->heap[1]; + v=h->heap[h->heapcount--]; + for (k=1;k*2<=h->heapcount;k=l) { + l=k*2; + if (lheapcount) { + if (h->cf(H,h->heap[l],h->heap[l+1])<0) { + l++; + } + } + if (h->cf(H,v,h->heap[l])>0) { + break; + } + h->heap[k]=h->heap[l]; + } + h->heap[k]=v; +#ifdef DEBUG + if (!_heap_test(H)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); } +#endif + return 1; +} + +int ImagingQuantHeapAdd(Heap H,void *val) { + IntHeap *h=(IntHeap *)H; + int k; + if (h->heapcount==h->heapsize-1) { + _heap_grow(h,0); + } + k=++h->heapcount; + while (k!=1) { + if (h->cf(H,val,h->heap[k/2])<=0) { + break; + } + h->heap[k]=h->heap[k/2]; + k>>=1; + } + h->heap[k]=val; +#ifdef DEBUG + if (!_heap_test(H)) { printf ("oops - heap_add messed up the heap\n"); exit(1); } +#endif + return 1; +} + +int ImagingQuantHeapTop(Heap H,void **r) { + IntHeap *h=(IntHeap *)H; + if (!h->heapcount) { + return 0; + } + *r=h->heap[1]; + return 1; +} + +Heap *ImagingQuantHeapNew(HeapCmpFunc cf) { + IntHeap *h; + + h=malloc(sizeof(IntHeap)); + if (!h) return NULL; + h->heapsize=INITIAL_SIZE; + h->heap=malloc(sizeof(void *)*h->heapsize); + if (!h->heap) { free(h); return NULL; } + h->heapcount=0; + h->cf=cf; + return (Heap)h; +} + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h new file mode 100755 index 00000000000..5a213c42ab8 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h @@ -0,0 +1,23 @@ +/* + * The Python Imaging Library + * $Id$ + * + * image quantizer + * + * Written by Toby J Sargeant . + * + * See the README file for information on usage and redistribution. + */ + +#ifndef __HEAP_H__ +#define __HEAP_H__ + +#include "QuantTypes.h" + +void ImagingQuantHeapFree(Heap); +int ImagingQuantHeapRemove(Heap,void **); +int ImagingQuantHeapAdd(Heap,void *); +int ImagingQuantHeapTop(Heap,void **); +Heap *ImagingQuantHeapNew(HeapCmpFunc); + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h new file mode 100755 index 00000000000..308b51c1324 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h @@ -0,0 +1,28 @@ +/* + * The Python Imaging Library + * $Id$ + * + * image quantizer + * + * Written by Toby J Sargeant . + * + * See the README file for information on usage and redistribution. + */ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +typedef void *HashTable; +typedef void *Heap; + +typedef unsigned long (*HashFunc)(const HashTable,const void *); +typedef int (*HashCmpFunc)(const HashTable,const void *,const void *); +typedef void (*IteratorFunc)(const HashTable,const void *,const void *,void *); +typedef void (*IteratorUpdateFunc)(const HashTable,const void *,void **,void *); +typedef void (*DestroyFunc)(const HashTable,void *); +typedef void (*ComputeFunc)(const HashTable,const void *,void **); +typedef void (*CollisionFunc)(const HashTable,void **,void **,void *,void *); + +typedef int (*HeapCmpFunc)(const Heap,const void *,const void *); + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c new file mode 100755 index 00000000000..84090f7510e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c @@ -0,0 +1,105 @@ +/* + * The Python Imaging Library + * $Id$ + * + * min, max, median filters + * + * history: + * 2002-06-08 fl Created + * + * Copyright (c) Secret Labs AB 2002. All rights reserved. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + +/* Fast rank algorithm (due to Wirth), based on public domain code + by Nicolas Devillard, available at http://ndevilla.free.fr */ + +#define SWAP(type,a,b) { register type t=(a);(a)=(b);(b)=t; } + +#define MakeRankFunction(type)\ +static type Rank##type(type a[], int n, int k)\ +{\ + register int i, j, l, m;\ + register type x;\ + l = 0; m = n-1;\ + while (l < m) {\ + x = a[k];\ + i = l;\ + j = m;\ + do {\ + while (a[i] < x) i++;\ + while (x < a[j]) j--;\ + if (i <= j) {\ + SWAP(type, a[i], a[j]);\ + i++; j--;\ + }\ + } while (i <= j);\ + if (j < k) l = i;\ + if (k < i) m = j;\ + }\ + return a[k];\ +} + +MakeRankFunction(UINT8) +MakeRankFunction(INT32) +MakeRankFunction(FLOAT32) + +Imaging +ImagingRankFilter(Imaging im, int size, int rank) +{ + Imaging imOut = NULL; + int x, y; + int i, margin, size2; + + if (!im || im->bands != 1 || im->type == IMAGING_TYPE_SPECIAL) + return (Imaging) ImagingError_ModeError(); + + if (!(size & 1)) + return (Imaging) ImagingError_ValueError("bad filter size"); + + size2 = size * size; + margin = (size-1) / 2; + + if (rank < 0 || rank >= size2) + return (Imaging) ImagingError_ValueError("bad rank value"); + + imOut = ImagingNew(im->mode, im->xsize - 2*margin, im->ysize - 2*margin); + if (!imOut) + return NULL; + +#define RANK_BODY(type) do {\ + type* buf = malloc(size2 * sizeof(type));\ + if (!buf)\ + goto nomemory;\ + for (y = 0; y < imOut->ysize; y++)\ + for (x = 0; x < imOut->xsize; x++) {\ + for (i = 0; i < size; i++)\ + memcpy(buf + i*size, &IMAGING_PIXEL_##type(im, x, y+i),\ + size * sizeof(type));\ + IMAGING_PIXEL_##type(imOut, x, y) = Rank##type(buf, size2, rank);\ + }\ +} while (0) + + if (im->image8) + RANK_BODY(UINT8); + else if (im->type == IMAGING_TYPE_INT32) + RANK_BODY(INT32); + else if (im->type == IMAGING_TYPE_FLOAT32) + RANK_BODY(FLOAT32); + else { + /* safety net (we shouldn't end up here) */ + ImagingDelete(imOut); + return (Imaging) ImagingError_ModeError(); + } + + ImagingCopyInfo(imOut, im); + + return imOut; + +nomemory: + ImagingDelete(imOut); + return (Imaging) ImagingError_MemoryError(); +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h new file mode 100755 index 00000000000..4d28fa54665 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h @@ -0,0 +1,15 @@ +/* Raw.h */ + +typedef struct { + + /* CONFIGURATION */ + + /* Distance between lines (0=no padding) */ + int stride; + + /* PRIVATE (initialized by decoder) */ + + /* Padding between lines */ + int skip; + +} RAWSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c new file mode 100755 index 00000000000..5aadb2b44d7 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c @@ -0,0 +1,89 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for raw (uncompressed) image data + * + * history: + * 96-03-07 fl rewritten + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#include "Raw.h" + + +int +ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + enum { LINE = 1, SKIP }; + RAWSTATE* rawstate = state->context; + + UINT8* ptr; + + if (state->state == 0) { + + /* Initialize context variables */ + + /* get size of image data and padding */ + state->bytes = (state->xsize * state->bits + 7) / 8; + rawstate->skip = (rawstate->stride) ? + rawstate->stride - state->bytes : 0; + + /* check image orientation */ + if (state->ystep < 0) { + state->y = state->ysize-1; + state->ystep = -1; + } else + state->ystep = 1; + + state->state = LINE; + + } + + ptr = buf; + + for (;;) { + + if (state->state == SKIP) { + + /* Skip padding between lines */ + + if (bytes < rawstate->skip) + return ptr - buf; + + ptr += rawstate->skip; + bytes -= rawstate->skip; + + state->state = LINE; + + } + + if (bytes < state->bytes) + return ptr - buf; + + /* Unpack data */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, ptr, state->xsize); + + ptr += state->bytes; + bytes -= state->bytes; + + state->y += state->ystep; + + if (state->y < 0 || state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + + state->state = SKIP; + + } + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c new file mode 100755 index 00000000000..a3b74b8cffc --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c @@ -0,0 +1,89 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * coder for raw data + * + * FIXME: This encoder will fail if the buffer is not large enough to + * hold one full line of data. There's a workaround for this problem + * in ImageFile.py, but it should be solved here instead. + * + * history: + * 96-04-30 fl created + * 97-01-03 fl fixed padding + * + * Copyright (c) Fredrik Lundh 1996-97. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. */ + + +#include "Imaging.h" + +int +ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + UINT8* ptr; + + if (!state->state) { + + /* The "count" field holds the stride, if specified. Fix + things up so "bytes" is the full size, and "count" the + packed size */ + + if (state->count > 0) { + int bytes = state->count; + + /* stride must not be less than real size */ + if (state->count < state->bytes) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + state->count = state->bytes; + state->bytes = bytes; + } else + state->count = state->bytes; + + /* The "ystep" field specifies the orientation */ + + if (state->ystep < 0) { + state->y = state->ysize-1; + state->ystep = -1; + } else + state->ystep = 1; + + state->state = 1; + + } + + if (bytes < state->bytes) { + state->errcode = IMAGING_CODEC_CONFIG; + return 0; + } + + ptr = buf; + + while (bytes >= state->bytes) { + + state->shuffle(ptr, (UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->xsize); + + if (state->bytes > state->count) + /* zero-pad the buffer, if necessary */ + memset(ptr + state->count, 0, state->bytes - state->count); + + ptr += state->bytes; + bytes -= state->bytes; + + state->y += state->ystep; + + if (state->y < 0 || state->y >= state->ysize) { + state->errcode = IMAGING_CODEC_END; + break; + } + + } + + return ptr - buf; + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c new file mode 100755 index 00000000000..76a66c2a5b1 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c @@ -0,0 +1,413 @@ +/* + * The Python Imaging Library + * $Id$ + * + * imaging storage object + * + * This baseline implementation is designed to efficiently handle + * large images, provided they fit into the available memory. + * + * history: + * 1995-06-15 fl Created + * 1995-09-12 fl Updated API, compiles silently under ANSI C++ + * 1995-11-26 fl Compiles silently under Borland 4.5 as well + * 1996-05-05 fl Correctly test status from Prologue + * 1997-05-12 fl Increased THRESHOLD (to speed up Tk interface) + * 1997-05-30 fl Added support for floating point images + * 1997-11-17 fl Added support for "RGBX" images + * 1998-01-11 fl Added support for integer images + * 1998-03-05 fl Exported Prologue/Epilogue functions + * 1998-07-01 fl Added basic "YCrCb" support + * 1998-07-03 fl Attach palette in prologue for "P" images + * 1998-07-09 hk Don't report MemoryError on zero-size images + * 1998-07-12 fl Change "YCrCb" to "YCbCr" (!) + * 1998-10-26 fl Added "I;16" and "I;16B" storage modes (experimental) + * 1998-12-29 fl Fixed allocation bug caused by previous fix + * 1999-02-03 fl Added "RGBa" and "BGR" modes (experimental) + * 2001-04-22 fl Fixed potential memory leak in ImagingCopyInfo + * 2003-09-26 fl Added "LA" and "PA" modes (experimental) + * 2005-10-02 fl Added image counter + * + * Copyright (c) 1998-2005 by Secret Labs AB + * Copyright (c) 1995-2005 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int ImagingNewCount = 0; + +/* -------------------------------------------------------------------- + * Standard image object. + */ + +Imaging +ImagingNewPrologueSubtype(const char *mode, unsigned xsize, unsigned ysize, + int size) +{ + Imaging im; + ImagingSectionCookie cookie; + + im = (Imaging) calloc(1, size); + if (!im) + return (Imaging) ImagingError_MemoryError(); + + /* Setup image descriptor */ + im->xsize = xsize; + im->ysize = ysize; + + im->type = IMAGING_TYPE_UINT8; + + if (strcmp(mode, "1") == 0) { + /* 1-bit images */ + im->bands = im->pixelsize = 1; + im->linesize = xsize; + + } else if (strcmp(mode, "P") == 0) { + /* 8-bit palette mapped images */ + im->bands = im->pixelsize = 1; + im->linesize = xsize; + im->palette = ImagingPaletteNew("RGB"); + + } else if (strcmp(mode, "PA") == 0) { + /* 8-bit palette with alpha */ + im->bands = 2; + im->pixelsize = 4; /* store in image32 memory */ + im->linesize = xsize * 4; + im->palette = ImagingPaletteNew("RGB"); + + } else if (strcmp(mode, "L") == 0) { + /* 8-bit greyscale (luminance) images */ + im->bands = im->pixelsize = 1; + im->linesize = xsize; + + } else if (strcmp(mode, "LA") == 0) { + /* 8-bit greyscale (luminance) with alpha */ + im->bands = 2; + im->pixelsize = 4; /* store in image32 memory */ + im->linesize = xsize * 4; + + } else if (strcmp(mode, "F") == 0) { + /* 32-bit floating point images */ + im->bands = 1; + im->pixelsize = 4; + im->linesize = xsize * 4; + im->type = IMAGING_TYPE_FLOAT32; + + } else if (strcmp(mode, "I") == 0) { + /* 32-bit integer images */ + im->bands = 1; + im->pixelsize = 4; + im->linesize = xsize * 4; + im->type = IMAGING_TYPE_INT32; + + } else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 || strcmp(mode, "I;16B") == 0) { + /* EXPERIMENTAL */ + /* 16-bit raw integer images */ + im->bands = 1; + im->pixelsize = 2; + im->linesize = xsize * 2; + im->type = IMAGING_TYPE_SPECIAL; + + } else if (strcmp(mode, "RGB") == 0) { + /* 24-bit true colour images */ + im->bands = 3; + im->pixelsize = 4; + im->linesize = xsize * 4; + + } else if (strcmp(mode, "BGR;15") == 0) { + /* EXPERIMENTAL */ + /* 15-bit true colour */ + im->bands = 1; + im->pixelsize = 2; + im->linesize = (xsize*2 + 3) & -4; + im->type = IMAGING_TYPE_SPECIAL; + + } else if (strcmp(mode, "BGR;16") == 0) { + /* EXPERIMENTAL */ + /* 16-bit reversed true colour */ + im->bands = 1; + im->pixelsize = 2; + im->linesize = (xsize*2 + 3) & -4; + im->type = IMAGING_TYPE_SPECIAL; + + } else if (strcmp(mode, "BGR;24") == 0) { + /* EXPERIMENTAL */ + /* 24-bit reversed true colour */ + im->bands = 1; + im->pixelsize = 3; + im->linesize = (xsize*3 + 3) & -4; + im->type = IMAGING_TYPE_SPECIAL; + + } else if (strcmp(mode, "BGR;32") == 0) { + /* EXPERIMENTAL */ + /* 32-bit reversed true colour */ + im->bands = 1; + im->pixelsize = 4; + im->linesize = (xsize*4 + 3) & -4; + im->type = IMAGING_TYPE_SPECIAL; + + } else if (strcmp(mode, "RGBX") == 0) { + /* 32-bit true colour images with padding */ + im->bands = im->pixelsize = 4; + im->linesize = xsize * 4; + + } else if (strcmp(mode, "RGBA") == 0) { + /* 32-bit true colour images with alpha */ + im->bands = im->pixelsize = 4; + im->linesize = xsize * 4; + + } else if (strcmp(mode, "RGBa") == 0) { + /* EXPERIMENTAL */ + /* 32-bit true colour images with premultiplied alpha */ + im->bands = im->pixelsize = 4; + im->linesize = xsize * 4; + + } else if (strcmp(mode, "CMYK") == 0) { + /* 32-bit colour separation */ + im->bands = im->pixelsize = 4; + im->linesize = xsize * 4; + + } else if (strcmp(mode, "YCbCr") == 0) { + /* 24-bit video format */ + im->bands = 3; + im->pixelsize = 4; + im->linesize = xsize * 4; + + } else { + free(im); + return (Imaging) ImagingError_ValueError("unrecognized mode"); + } + + /* Setup image descriptor */ + strcpy(im->mode, mode); + + ImagingSectionEnter(&cookie); + + /* Pointer array (allocate at least one line, to avoid MemoryError + exceptions on platforms where calloc(0, x) returns NULL) */ + im->image = (char **) calloc((ysize > 0) ? ysize : 1, sizeof(void *)); + + ImagingSectionLeave(&cookie); + + if (!im->image) { + free(im); + return (Imaging) ImagingError_MemoryError(); + } + + ImagingNewCount++; + + return im; +} + +Imaging +ImagingNewPrologue(const char *mode, unsigned xsize, unsigned ysize) +{ + return ImagingNewPrologueSubtype( + mode, xsize, ysize, sizeof(struct ImagingMemoryInstance) + ); +} + +Imaging +ImagingNewEpilogue(Imaging im) +{ + /* If the raster data allocator didn't setup a destructor, + assume that it couldn't allocate the required amount of + memory. */ + if (!im->destroy) + return (Imaging) ImagingError_MemoryError(); + + /* Initialize alias pointers to pixel data. */ + switch (im->pixelsize) { + case 1: case 2: case 3: + im->image8 = (UINT8 **) im->image; + break; + case 4: + im->image32 = (INT32 **) im->image; + break; + } + + return im; +} + +void +ImagingDelete(Imaging im) +{ + if (!im) + return; + + if (im->palette) + ImagingPaletteDelete(im->palette); + + if (im->destroy) + im->destroy(im); + + if (im->image) + free(im->image); + + free(im); +} + + +/* Array Storage Type */ +/* ------------------ */ +/* Allocate image as an array of line buffers. */ + +static void +ImagingDestroyArray(Imaging im) +{ + int y; + + if (im->image) + for (y = 0; y < im->ysize; y++) + if (im->image[y]) + free(im->image[y]); +} + +Imaging +ImagingNewArray(const char *mode, int xsize, int ysize) +{ + Imaging im; + ImagingSectionCookie cookie; + + int y; + char* p; + + im = ImagingNewPrologue(mode, xsize, ysize); + if (!im) + return NULL; + + ImagingSectionEnter(&cookie); + + /* Allocate image as an array of lines */ + for (y = 0; y < im->ysize; y++) { + p = (char *) malloc(im->linesize); + if (!p) { + ImagingDestroyArray(im); + break; + } + im->image[y] = p; + } + + ImagingSectionLeave(&cookie); + + if (y == im->ysize) + im->destroy = ImagingDestroyArray; + + return ImagingNewEpilogue(im); +} + + +/* Block Storage Type */ +/* ------------------ */ +/* Allocate image as a single block. */ + +static void +ImagingDestroyBlock(Imaging im) +{ + if (im->block) + free(im->block); +} + +Imaging +ImagingNewBlock(const char *mode, int xsize, int ysize) +{ + Imaging im; + int y, i; + int bytes; + + im = ImagingNewPrologue(mode, xsize, ysize); + if (!im) + return NULL; + + /* Use a single block */ + bytes = im->ysize * im->linesize; + if (bytes <= 0) + /* some platforms return NULL for malloc(0); this fix + prevents MemoryError on zero-sized images on such + platforms */ + bytes = 1; + im->block = (char *) malloc(bytes); + + if (im->block) { + + for (y = i = 0; y < im->ysize; y++) { + im->image[y] = im->block + i; + i += im->linesize; + } + + im->destroy = ImagingDestroyBlock; + + } + + return ImagingNewEpilogue(im); +} + +/* -------------------------------------------------------------------- + * Create a new, internally allocated, image. + */ +#if defined(IMAGING_SMALL_MODEL) +#define THRESHOLD 16384L +#else +#define THRESHOLD (2048*2048*4L) +#endif + +Imaging +ImagingNew(const char* mode, int xsize, int ysize) +{ + int bytes; + Imaging im; + + if (strlen(mode) == 1) { + if (mode[0] == 'F' || mode[0] == 'I') + bytes = 4; + else + bytes = 1; + } else + bytes = strlen(mode); /* close enough */ + + if ((long) xsize * ysize * bytes <= THRESHOLD) { + im = ImagingNewBlock(mode, xsize, ysize); + if (im) + return im; + /* assume memory error; try allocating in array mode instead */ + ImagingError_Clear(); + } + + return ImagingNewArray(mode, xsize, ysize); +} + +Imaging +ImagingNew2(const char* mode, Imaging imOut, Imaging imIn) +{ + /* allocate or validate output image */ + + if (imOut) { + /* make sure images match */ + if (strcmp(imOut->mode, mode) != 0 + || imOut->xsize != imIn->xsize + || imOut->ysize != imIn->ysize) { + return ImagingError_Mismatch(); + } + } else { + /* create new image */ + imOut = ImagingNew(mode, imIn->xsize, imIn->ysize); + if (!imOut) + return NULL; + } + + return imOut; +} + +void +ImagingCopyInfo(Imaging destination, Imaging source) +{ + if (source->palette) { + if (destination->palette) + ImagingPaletteDelete(destination->palette); + destination->palette = ImagingPaletteDuplicate(source->palette); + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c new file mode 100755 index 00000000000..bf34d93821f --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c @@ -0,0 +1,112 @@ +/* + * THIS IS WORK IN PROGRESS + * + * The Python Imaging Library. + * $Id$ + * + * decoder for SUN RLE data. + * + * history: + * 97-01-04 fl Created + * + * Copyright (c) Fredrik Lundh 1997. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + int n; + UINT8* ptr; + + ptr = buf; + + for (;;) { + + if (bytes < 1) + return ptr - buf; + + if (ptr[0] == 0x80) { + + if (bytes < 2) + break; + + n = ptr[1]; + + if (n == 0) { + + /* Literal 0x80 (2 bytes) */ + n = 1; + + state->buffer[state->x] = 0x80; + + ptr += 2; + bytes -= 2; + + } else { + + /* Run (3 bytes) */ + if (bytes < 3) + break; + + if (state->x + n > state->bytes) { + /* FIXME: is this correct? */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + memset(state->buffer + state->x, ptr[2], n); + + ptr += 3; + bytes -= 3; + + } + + } else { + + /* Literal (1+n bytes block) */ + n = ptr[0]; + + if (bytes < 1 + n) + break; + + if (state->x + n > state->bytes) { + /* FIXME: is this correct? */ + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + memcpy(state->buffer + state->x, ptr + 1, n); + + ptr += 1 + n; + bytes -= 1 + n; + + } + + state->x += n; + + if (state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + } + + } + + return ptr - buf; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c new file mode 100755 index 00000000000..cad6bc3bcfe --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c @@ -0,0 +1,118 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for Targa RLE data. + * + * history: + * 97-01-04 fl created + * 98-09-11 fl don't one byte per pixel; take orientation into account + * + * Copyright (c) Fredrik Lundh 1997. + * Copyright (c) Secret Labs AB 1997-98. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingTgaRleDecode(Imaging im, ImagingCodecState state, + UINT8* buf, int bytes) +{ + int n, depth; + UINT8* ptr; + + ptr = buf; + + if (state->state == 0) { + + /* check image orientation */ + if (state->ystep < 0) { + state->y = state->ysize-1; + state->ystep = -1; + } else + state->ystep = 1; + + state->state = 1; + + } + + depth = state->count; + + for (;;) { + + if (bytes < 1) + return ptr - buf; + + if (ptr[0] & 0x80) { + + /* Run (1 + pixelsize bytes) */ + + if (bytes < 1 + depth) + break; + + n = depth * ((ptr[0] & 0x7f) + 1); + + if (state->x + n > state->bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + if (depth == 1) + memset(state->buffer + state->x, ptr[1], n); + else { + int i; + for (i = 0; i < n; i += depth) + memcpy(state->buffer + state->x + i, ptr+1, depth); + } + + ptr += 1 + depth; + bytes -= 1 + depth; + + } else { + + /* Literal (1+n+1 bytes block) */ + n = depth * (ptr[0] + 1); + + if (bytes < 1 + n) + break; + + if (state->x + n > state->bytes) { + state->errcode = IMAGING_CODEC_OVERRUN; + return -1; + } + + memcpy(state->buffer + state->x, ptr + 1, n); + + ptr += 1 + n; + bytes -= 1 + n; + + } + + state->x += n; + + if (state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + state->x = 0; + + state->y += state->ystep; + + if (state->y < 0 || state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + + } + + } + + return ptr - buf; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c new file mode 100755 index 00000000000..90a76feb341 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c @@ -0,0 +1,1028 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * code to unpack raw data from various file formats + * + * history: + * 1996-03-07 fl Created (from various decoders) + * 1996-04-19 fl Added band unpackers + * 1996-05-12 fl Published RGB unpackers + * 1996-05-27 fl Added nibble unpacker + * 1996-12-10 fl Added complete set of PNG unpackers + * 1996-12-29 fl Set alpha byte in RGB unpackers + * 1997-01-05 fl Added remaining TGA unpackers + * 1997-01-18 fl Added inverting band unpackers + * 1997-01-25 fl Added FlashPix unpackers + * 1997-05-31 fl Added floating point unpackers + * 1998-02-08 fl Added I unpacker + * 1998-07-01 fl Added YCbCr unpacker + * 1998-07-02 fl Added full set of integer unpackers + * 1998-12-29 fl Added mode field, I;16 unpackers + * 1998-12-30 fl Added RGBX modes + * 1999-02-04 fl Fixed I;16 unpackers + * 2003-05-13 fl Added L/RGB reversed unpackers + * 2003-09-26 fl Added LA/PA and RGBa->RGB unpackers + * + * Copyright (c) 1997-2003 by Secret Labs AB. + * Copyright (c) 1996-1997 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + +#include "Imaging.h" + + +#define R 0 +#define G 1 +#define B 2 +#define X 3 + +#define A 3 + +#define C 0 +#define M 1 +#define Y 2 +#define K 3 + +#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) + +/* byte-swapping macros */ + +#define C16N\ + (tmp[0]=in[0], tmp[1]=in[1]); +#define C16S\ + (tmp[1]=in[0], tmp[0]=in[1]); +#define C32N\ + (tmp[0]=in[0], tmp[1]=in[1], tmp[2]=in[2], tmp[3]=in[3]); +#define C32S\ + (tmp[3]=in[0], tmp[2]=in[1], tmp[1]=in[2], tmp[0]=in[3]); +#define C64N\ + (tmp[0]=in[0], tmp[1]=in[1], tmp[2]=in[2], tmp[3]=in[3],\ + tmp[4]=in[4], tmp[5]=in[5], tmp[6]=in[6], tmp[7]=in[7]); +#define C64S\ + (tmp[7]=in[0], tmp[6]=in[1], tmp[5]=in[2], tmp[4]=in[3],\ + tmp[3]=in[4], tmp[2]=in[5], tmp[1]=in[6], tmp[0]=in[7]); + +#ifdef WORDS_BIGENDIAN +#define C16B C16N +#define C16L C16S +#define C32B C32N +#define C32L C32S +#define C64B C64N +#define C64L C64S +#else +#define C16B C16S +#define C16L C16N +#define C32B C32S +#define C32L C32N +#define C64B C64S +#define C64L C64N +#endif + +/* bit-swapping */ + +static UINT8 BITFLIP[] = { + 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, + 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, + 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, + 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, + 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, + 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, + 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, + 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, + 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, + 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, + 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, + 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, + 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, + 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7, + 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, + 255 +}; + +/* Unpack to "1" image */ + +static void +unpack1(UINT8* out, const UINT8* in, int pixels) +{ + /* bits (msb first, white is non-zero) */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 7: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 6: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 5: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 4: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 3: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 2: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; + case 1: *out++ = (byte & 128) ? 255 : 0; + } + pixels -= 8; + } +} + +static void +unpack1I(UINT8* out, const UINT8* in, int pixels) +{ + /* bits (msb first, white is zero) */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 7: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 6: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 5: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 4: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 3: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 2: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; + case 1: *out++ = (byte & 128) ? 0 : 255; + } + pixels -= 8; + } +} + +static void +unpack1R(UINT8* out, const UINT8* in, int pixels) +{ + /* bits (lsb first, white is non-zero) */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 7: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 6: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 5: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 4: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 3: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 2: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; + case 1: *out++ = (byte & 1) ? 255 : 0; + } + pixels -= 8; + } +} + +static void +unpack1IR(UINT8* out, const UINT8* in, int pixels) +{ + /* bits (lsb first, white is zero) */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 7: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 6: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 5: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 4: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 3: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 2: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; + case 1: *out++ = (byte & 1) ? 0 : 255; + } + pixels -= 8; + } +} + + +/* Unpack to "L" image */ + +static void +unpackL2(UINT8* out, const UINT8* in, int pixels) +{ + /* nibbles */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2; + case 3: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2; + case 2: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2; + case 1: *out++ = ((byte >> 6) & 3) * 255 / 3; + } + pixels -= 4; + } +} + +static void +unpackL4(UINT8* out, const UINT8* in, int pixels) +{ + /* nibbles */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = ((byte >> 4) & 15) * 255 / 15; byte <<= 4; + case 1: *out++ = ((byte >> 4) & 15) * 255 / 15; + } + pixels -= 2; + } +} + +static void +unpackLA(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* LA, pixel interleaved */ + for (i = 0; i < pixels; i++) { + out[R] = out[G] = out[B] = in[0]; + out[A] = in[1]; + in += 2; out += 4; + } +} + +static void +unpackLAL(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* LA, line interleaved */ + for (i = 0; i < pixels; i++) { + out[R] = out[G] = out[B] = in[i]; + out[A] = in[i+pixels]; + out += 4; + } +} + +static void +unpackLI(UINT8* out, const UINT8* in, int pixels) +{ + /* negative */ + int i; + for (i = 0; i < pixels; i++) + out[i] = ~in[i]; +} + +static void +unpackLR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, bit reversed */ + for (i = 0; i < pixels; i++) { + out[i] = BITFLIP[in[i]]; + } +} + +static void +unpackL16(UINT8* out, const UINT8* in, int pixels) +{ + /* int16 (upper byte, little endian) */ + int i; + for (i = 0; i < pixels; i++) { + out[i] = in[1]; + in += 2; + } +} + +static void +unpackL16B(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* int16 (upper byte, big endian) */ + for (i = 0; i < pixels; i++) { + out[i] = in[0]; + in += 2; + } +} + + +/* Unpack to "P" image */ + +static void +unpackP1(UINT8* out, const UINT8* in, int pixels) +{ + /* bits */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte >> 7) & 1; byte <<= 1; + case 7: *out++ = (byte >> 7) & 1; byte <<= 1; + case 6: *out++ = (byte >> 7) & 1; byte <<= 1; + case 5: *out++ = (byte >> 7) & 1; byte <<= 1; + case 4: *out++ = (byte >> 7) & 1; byte <<= 1; + case 3: *out++ = (byte >> 7) & 1; byte <<= 1; + case 2: *out++ = (byte >> 7) & 1; byte <<= 1; + case 1: *out++ = (byte >> 7) & 1; + } + pixels -= 8; + } +} + +static void +unpackP2(UINT8* out, const UINT8* in, int pixels) +{ + /* bit pairs */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte >> 6) & 3; byte <<= 2; + case 3: *out++ = (byte >> 6) & 3; byte <<= 2; + case 2: *out++ = (byte >> 6) & 3; byte <<= 2; + case 1: *out++ = (byte >> 6) & 3; + } + pixels -= 4; + } +} + +static void +unpackP4(UINT8* out, const UINT8* in, int pixels) +{ + /* nibbles */ + while (pixels > 0) { + UINT8 byte = *in++; + switch (pixels) { + default: *out++ = (byte >> 4) & 15; byte <<= 4; + case 1: *out++ = (byte >> 4) & 15; + } + pixels -= 2; + } +} + +static void +unpackP2L(UINT8* out, const UINT8* in, int pixels) +{ + int i, j, m, s; + /* bit layers */ + m = 128; + s = (pixels+7)/8; + for (i = j = 0; i < pixels; i++) { + out[i] = ((in[j] & m) ? 1 : 0) + ((in[j + s] & m) ? 2 : 0); + if ((m >>= 1) == 0) { + m = 128; + j++; + } + } +} + +static void +unpackP4L(UINT8* out, const UINT8* in, int pixels) +{ + int i, j, m, s; + /* bit layers (trust the optimizer ;-) */ + m = 128; + s = (pixels+7)/8; + for (i = j = 0; i < pixels; i++) { + out[i] = ((in[j] & m) ? 1 : 0) + ((in[j + s] & m) ? 2 : 0) + + ((in[j + 2*s] & m) ? 4 : 0) + ((in[j + 3*s] & m) ? 8 : 0); + if ((m >>= 1) == 0) { + m = 128; + j++; + } + } +} + +/* Unpack to "RGB" image */ + +void +ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB triplets */ + for (i = 0; i < pixels; i++) { + out[R] = in[0]; + out[G] = in[1]; + out[B] = in[2]; + out[A] = 255; + out += 4; in += 3; + } +} + +void +unpackRGB16B(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* 16-bit RGB triplets, big-endian order */ + for (i = 0; i < pixels; i++) { + out[R] = in[0]; + out[G] = in[2]; + out[B] = in[4]; + out[A] = 255; + out += 4; in += 6; + } +} + +static void +unpackRGBL(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, line interleaved */ + for (i = 0; i < pixels; i++) { + out[R] = in[i]; + out[G] = in[i+pixels]; + out[B] = in[i+pixels+pixels]; + out[A] = 255; + out += 4; + } +} + +static void +unpackRGBR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, bit reversed */ + for (i = 0; i < pixels; i++) { + out[R] = BITFLIP[in[0]]; + out[G] = BITFLIP[in[1]]; + out[B] = BITFLIP[in[2]]; + out[A] = 255; + out += 4; in += 3; + } +} + +void +ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, reversed bytes */ + for (i = 0; i < pixels; i++) { + out[R] = in[2]; + out[G] = in[1]; + out[B] = in[0]; + out[A] = 255; + out += 4; in += 3; + } +} + +void +ImagingUnpackBGR15(UINT8* out, const UINT8* in, int pixels) +{ + int i, pixel; + /* RGB, reversed bytes, 5 bits per pixel */ + for (i = 0; i < pixels; i++) { + pixel = in[0] + (in[1] << 8); + out[B] = (pixel & 31) * 255 / 31; + out[G] = ((pixel>>5) & 31) * 255 / 31; + out[R] = ((pixel>>10) & 31) * 255 / 31; + out[A] = 255; + out += 4; in += 2; + } +} + +void +ImagingUnpackBGR16(UINT8* out, const UINT8* in, int pixels) +{ + int i, pixel; + /* RGB, reversed bytes, 5/6/5 bits per pixel */ + for (i = 0; i < pixels; i++) { + pixel = in[0] + (in[1] << 8); + out[B] = (pixel & 31) * 255 / 31; + out[G] = ((pixel>>5) & 63) * 255 / 63; + out[R] = ((pixel>>11) & 31) * 255 / 31; + out[A] = 255; + out += 4; in += 2; + } +} + +static void +ImagingUnpackBGRX(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, reversed bytes with padding */ + for (i = 0; i < pixels; i++) { + out[R] = in[2]; + out[G] = in[1]; + out[B] = in[0]; + out[A] = 255; + out += 4; in += 4; + } +} + +static void +ImagingUnpackXRGB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, leading pad */ + for (i = 0; i < pixels; i++) { + out[R] = in[1]; + out[G] = in[2]; + out[B] = in[3]; + out[A] = 255; + out += 4; in += 4; + } +} + +static void +ImagingUnpackXBGR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGB, reversed bytes, leading pad */ + for (i = 0; i < pixels; i++) { + out[R] = in[3]; + out[G] = in[2]; + out[B] = in[1]; + out[A] = 255; + out += 4; in += 4; + } +} + +/* Unpack to "RGBA" image */ + +static void +unpackRGBALA(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* greyscale with alpha */ + for (i = 0; i < pixels; i++) { + out[R] = out[G] = out[B] = in[0]; + out[A] = in[1]; + out += 4; in += 2; + } +} + +static void +unpackRGBALA16B(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* 16-bit greyscale with alpha, big-endian */ + for (i = 0; i < pixels; i++) { + out[R] = out[G] = out[B] = in[0]; + out[A] = in[2]; + out += 4; in += 4; + } +} + +static void +unpackRGBa(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* premultiplied RGBA */ + for (i = 0; i < pixels; i++) { + int a = in[3]; + if (!a) + out[R] = out[G] = out[B] = out[A] = 0; + else { + out[R] = CLIP(in[0] * 255 / a); + out[G] = CLIP(in[1] * 255 / a); + out[B] = CLIP(in[2] * 255 / a); + out[A] = a; + } + out += 4; in += 4; + } +} + +static void +unpackRGBAI(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGBA, inverted RGB bytes (FlashPix) */ + for (i = 0; i < pixels; i++) { + out[R] = ~in[0]; + out[G] = ~in[1]; + out[B] = ~in[2]; + out[A] = in[3]; + out += 4; in += 4; + } +} + +static void +unpackRGBAL(UINT8* out, const UINT8* in, int pixels) +{ + int i; + + /* RGBA, line interleaved */ + for (i = 0; i < pixels; i++) { + out[R] = in[i]; + out[G] = in[i+pixels]; + out[B] = in[i+pixels+pixels]; + out[A] = in[i+pixels+pixels+pixels]; + out += 4; + } +} + +void +unpackRGBA16B(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* 16-bit RGBA, big-endian order */ + for (i = 0; i < pixels; i++) { + out[R] = in[0]; + out[G] = in[2]; + out[B] = in[4]; + out[A] = in[6]; + out += 4; in += 8; + } +} + +static void +unpackARGB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGBA, leading pad */ + for (i = 0; i < pixels; i++) { + out[R] = in[1]; + out[G] = in[2]; + out[B] = in[3]; + out[A] = in[0]; + out += 4; in += 4; + } +} + +static void +unpackABGR(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGBA, reversed bytes */ + for (i = 0; i < pixels; i++) { + out[R] = in[3]; + out[G] = in[2]; + out[B] = in[1]; + out[A] = in[0]; + out += 4; in += 4; + } +} + +static void +unpackBGRA(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* RGBA, reversed bytes */ + for (i = 0; i < pixels; i++) { + out[R] = in[2]; + out[G] = in[1]; + out[B] = in[0]; + out[A] = in[3]; + out += 4; in += 4; + } +} + + +/* Unpack to "CMYK" image */ + +static void +unpackCMYKI(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* CMYK, inverted bytes (Photoshop 2.5) */ + for (i = 0; i < pixels; i++) { + out[C] = ~in[0]; + out[M] = ~in[1]; + out[Y] = ~in[2]; + out[K] = ~in[3]; + out += 4; in += 4; + } +} + +static void +copy1(UINT8* out, const UINT8* in, int pixels) +{ + /* L, P */ + memcpy(out, in, pixels); +} + +static void +copy2(UINT8* out, const UINT8* in, int pixels) +{ + /* I;16 */ + memcpy(out, in, pixels*2); +} + +static void +copy4(UINT8* out, const UINT8* in, int pixels) +{ + /* RGBA, CMYK quadruples */ + memcpy(out, in, 4 * pixels); +} + + +/* Unpack to "I" and "F" images */ + +#define UNPACK_RAW(NAME, GET, INTYPE, OUTTYPE)\ +static void NAME(UINT8* out_, const UINT8* in, int pixels)\ +{\ + int i;\ + OUTTYPE* out = (OUTTYPE*) out_;\ + for (i = 0; i < pixels; i++, in += sizeof(INTYPE))\ + out[i] = (OUTTYPE) ((INTYPE) GET);\ +} + +#define UNPACK(NAME, COPY, INTYPE, OUTTYPE)\ +static void NAME(UINT8* out_, const UINT8* in, int pixels)\ +{\ + int i;\ + OUTTYPE* out = (OUTTYPE*) out_;\ + INTYPE tmp_;\ + UINT8* tmp = (UINT8*) &tmp_;\ + for (i = 0; i < pixels; i++, in += sizeof(INTYPE)) {\ + COPY;\ + out[i] = (OUTTYPE) tmp_;\ + }\ +} + +UNPACK_RAW(unpackI8, in[0], UINT8, INT32) +UNPACK_RAW(unpackI8S, in[0], INT8, INT32) +UNPACK(unpackI16, C16L, UINT16, INT32) +UNPACK(unpackI16S, C16L, INT16, INT32) +UNPACK(unpackI16B, C16B, UINT16, INT32) +UNPACK(unpackI16BS, C16B, INT16, INT32) +UNPACK(unpackI16N, C16N, UINT16, INT32) +UNPACK(unpackI16NS, C16N, INT16, INT32) +UNPACK(unpackI32, C32L, UINT32, INT32) +UNPACK(unpackI32S, C32L, INT32, INT32) +UNPACK(unpackI32B, C32B, UINT32, INT32) +UNPACK(unpackI32BS, C32B, INT32, INT32) +UNPACK(unpackI32N, C32N, UINT32, INT32) +UNPACK(unpackI32NS, C32N, INT32, INT32) + +UNPACK_RAW(unpackF8, in[0], UINT8, FLOAT32) +UNPACK_RAW(unpackF8S, in[0], INT8, FLOAT32) +UNPACK(unpackF16, C16L, UINT16, FLOAT32) +UNPACK(unpackF16S, C16L, INT16, FLOAT32) +UNPACK(unpackF16B, C16B, UINT16, FLOAT32) +UNPACK(unpackF16BS, C16B, INT16, FLOAT32) +UNPACK(unpackF16N, C16N, UINT16, FLOAT32) +UNPACK(unpackF16NS, C16N, INT16, FLOAT32) +UNPACK(unpackF32, C32L, UINT32, FLOAT32) +UNPACK(unpackF32S, C32L, INT32, FLOAT32) +UNPACK(unpackF32B, C32B, UINT32, FLOAT32) +UNPACK(unpackF32BS, C32B, INT32, FLOAT32) +UNPACK(unpackF32N, C32N, UINT32, FLOAT32) +UNPACK(unpackF32NS, C32N, INT32, FLOAT32) +UNPACK(unpackF32F, C32L, FLOAT32, FLOAT32) +UNPACK(unpackF32BF, C32B, FLOAT32, FLOAT32) +UNPACK(unpackF32NF, C32N, FLOAT32, FLOAT32) +#ifdef FLOAT64 +UNPACK(unpackF64F, C64L, FLOAT64, FLOAT32) +UNPACK(unpackF64BF, C64B, FLOAT64, FLOAT32) +UNPACK(unpackF64NF, C64N, FLOAT64, FLOAT32) +#endif + + +/* Misc. unpackers */ + +static void +band0(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* band 0 only */ + for (i = 0; i < pixels; i++) { + out[0] = in[i]; + out += 4; + } +} + +static void +band1(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* band 1 only */ + for (i = 0; i < pixels; i++) { + out[1] = in[i]; + out += 4; + } +} + +static void +band2(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* band 2 only */ + for (i = 0; i < pixels; i++) { + out[2] = in[i]; + out += 4; + } +} + +static void +band3(UINT8* out, const UINT8* in, int pixels) +{ + /* band 3 only */ + int i; + for (i = 0; i < pixels; i++) { + out[3] = in[i]; + out += 4; + } +} + +static void +band0I(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* band 0 only */ + for (i = 0; i < pixels; i++) { + out[0] = ~in[i]; + out += 4; + } +} + +static void +band1I(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* band 1 only */ + for (i = 0; i < pixels; i++) { + out[1] = ~in[i]; + out += 4; + } +} + +static void +band2I(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* band 2 only */ + for (i = 0; i < pixels; i++) { + out[2] = ~in[i]; + out += 4; + } +} + +static void +band3I(UINT8* out, const UINT8* in, int pixels) +{ + /* band 3 only */ + int i; + for (i = 0; i < pixels; i++) { + out[3] = ~in[i]; + out += 4; + } +} + +static struct { + const char* mode; + const char* rawmode; + int bits; + ImagingShuffler unpack; +} unpackers[] = { + + /* raw mode syntax is ";" where "bits" defaults + depending on mode (1 for "1", 8 for "P" and "L", etc), and + "flags" should be given in alphabetical order. if both bits + and flags have their default values, the ; should be left out */ + + /* flags: "I" inverted data; "R" reversed bit order; "B" big + endian byte order (default is little endian); "L" line + interleave, "S" signed, "F" floating point */ + + /* bilevel */ + {"1", "1", 1, unpack1}, + {"1", "1;I", 1, unpack1I}, + {"1", "1;R", 1, unpack1R}, + {"1", "1;IR", 1, unpack1IR}, + + /* greyscale */ + {"L", "L;2", 2, unpackL2}, + {"L", "L;4", 4, unpackL4}, + {"L", "L", 8, copy1}, + {"L", "L;I", 8, unpackLI}, + {"L", "L;R", 8, unpackLR}, + {"L", "L;16", 16, unpackL16}, + {"L", "L;16B", 16, unpackL16B}, + + /* greyscale w. alpha */ + {"LA", "LA", 16, unpackLA}, + {"LA", "LA;L", 16, unpackLAL}, + + /* palette */ + {"P", "P;1", 1, unpackP1}, + {"P", "P;2", 2, unpackP2}, + {"P", "P;2L", 2, unpackP2L}, + {"P", "P;4", 4, unpackP4}, + {"P", "P;4L", 4, unpackP4L}, + {"P", "P", 8, copy1}, + {"P", "P;R", 8, unpackLR}, + + /* palette w. alpha */ + {"PA", "PA", 16, unpackLA}, + {"PA", "PA;L", 16, unpackLAL}, + + /* true colour */ + {"RGB", "RGB", 24, ImagingUnpackRGB}, + {"RGB", "RGB;L", 24, unpackRGBL}, + {"RGB", "RGB;R", 24, unpackRGBR}, + {"RGB", "RGB;16B", 48, unpackRGB16B}, + {"RGB", "BGR", 24, ImagingUnpackBGR}, + {"RGB", "BGR;15", 16, ImagingUnpackBGR15}, + {"RGB", "BGR;16", 16, ImagingUnpackBGR16}, + {"RGB", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */ + {"RGB", "RGBX", 32, copy4}, + {"RGB", "RGBX;L", 32, unpackRGBAL}, + {"RGB", "BGRX", 32, ImagingUnpackBGRX}, + {"RGB", "XRGB", 24, ImagingUnpackXRGB}, + {"RGB", "XBGR", 32, ImagingUnpackXBGR}, + {"RGB", "YCC;P", 24, ImagingUnpackYCC}, + {"RGB", "R", 8, band0}, + {"RGB", "G", 8, band1}, + {"RGB", "B", 8, band2}, + + /* true colour w. alpha */ + {"RGBA", "LA", 16, unpackRGBALA}, + {"RGBA", "LA;16B", 32, unpackRGBALA16B}, + {"RGBA", "RGBA", 32, copy4}, + {"RGBA", "RGBa", 32, unpackRGBa}, + {"RGBA", "RGBA;I", 32, unpackRGBAI}, + {"RGBA", "RGBA;L", 32, unpackRGBAL}, + {"RGBA", "RGBA;16B", 64, unpackRGBA16B}, + {"RGBA", "BGRA", 32, unpackBGRA}, + {"RGBA", "ARGB", 32, unpackARGB}, + {"RGBA", "ABGR", 32, unpackABGR}, + {"RGBA", "YCCA;P", 32, ImagingUnpackYCCA}, + {"RGBA", "R", 8, band0}, + {"RGBA", "G", 8, band1}, + {"RGBA", "B", 8, band2}, + {"RGBA", "A", 8, band3}, + + /* true colour w. padding */ + {"RGBX", "RGB", 24, ImagingUnpackRGB}, + {"RGBX", "RGB;L", 24, unpackRGBL}, + {"RGBX", "RGB;16B", 48, unpackRGB16B}, + {"RGBX", "BGR", 24, ImagingUnpackBGR}, + {"RGBX", "BGR;15", 16, ImagingUnpackBGR15}, + {"RGB", "BGR;16", 16, ImagingUnpackBGR16}, + {"RGBX", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */ + {"RGBX", "RGBX", 32, copy4}, + {"RGBX", "RGBX;L", 32, unpackRGBAL}, + {"RGBX", "BGRX", 32, ImagingUnpackBGRX}, + {"RGBX", "XRGB", 24, ImagingUnpackXRGB}, + {"RGBX", "XBGR", 32, ImagingUnpackXBGR}, + {"RGBX", "YCC;P", 24, ImagingUnpackYCC}, + {"RGBX", "R", 8, band0}, + {"RGBX", "G", 8, band1}, + {"RGBX", "B", 8, band2}, + {"RGBX", "X", 8, band3}, + + /* colour separation */ + {"CMYK", "CMYK", 32, copy4}, + {"CMYK", "CMYK;I", 32, unpackCMYKI}, + {"CMYK", "CMYK;L", 32, unpackRGBAL}, + {"CMYK", "C", 8, band0}, + {"CMYK", "M", 8, band1}, + {"CMYK", "Y", 8, band2}, + {"CMYK", "K", 8, band3}, + {"CMYK", "C;I", 8, band0I}, + {"CMYK", "M;I", 8, band1I}, + {"CMYK", "Y;I", 8, band2I}, + {"CMYK", "K;I", 8, band3I}, + + /* video (YCbCr) */ + {"YCbCr", "YCbCr", 24, ImagingUnpackRGB}, + {"YCbCr", "YCbCr;L", 24, unpackRGBL}, + {"YCbCr", "YCbCrX", 32, copy4}, + {"YCbCr", "YCbCrK", 32, copy4}, + + /* integer variations */ + {"I", "I", 32, copy4}, + {"I", "I;8", 8, unpackI8}, + {"I", "I;8S", 8, unpackI8S}, + {"I", "I;16", 16, unpackI16}, + {"I", "I;16S", 16, unpackI16S}, + {"I", "I;16B", 16, unpackI16B}, + {"I", "I;16BS", 16, unpackI16BS}, + {"I", "I;16N", 16, unpackI16N}, + {"I", "I;16NS", 16, unpackI16NS}, + {"I", "I;32", 32, unpackI32}, + {"I", "I;32S", 32, unpackI32S}, + {"I", "I;32B", 32, unpackI32B}, + {"I", "I;32BS", 32, unpackI32BS}, + {"I", "I;32N", 32, unpackI32N}, + {"I", "I;32NS", 32, unpackI32NS}, + + /* floating point variations */ + {"F", "F", 32, copy4}, + {"F", "F;8", 8, unpackF8}, + {"F", "F;8S", 8, unpackF8S}, + {"F", "F;16", 16, unpackF16}, + {"F", "F;16S", 16, unpackF16S}, + {"F", "F;16B", 16, unpackF16B}, + {"F", "F;16BS", 16, unpackF16BS}, + {"F", "F;16N", 16, unpackF16N}, + {"F", "F;16NS", 16, unpackF16NS}, + {"F", "F;32", 32, unpackF32}, + {"F", "F;32S", 32, unpackF32S}, + {"F", "F;32B", 32, unpackF32B}, + {"F", "F;32BS", 32, unpackF32BS}, + {"F", "F;32N", 32, unpackF32N}, + {"F", "F;32NS", 32, unpackF32NS}, + {"F", "F;32F", 32, unpackF32F}, + {"F", "F;32BF", 32, unpackF32BF}, + {"F", "F;32NF", 32, unpackF32NF}, +#ifdef FLOAT64 + {"F", "F;64F", 64, unpackF64F}, + {"F", "F;64BF", 64, unpackF64BF}, + {"F", "F;64NF", 64, unpackF64NF}, +#endif + + /* storage modes */ + {"I;16", "I;16", 16, copy2}, + {"I;16B", "I;16B", 16, copy2}, + {"I;16L", "I;16L", 16, copy2}, + + {NULL} /* sentinel */ +}; + + +ImagingShuffler +ImagingFindUnpacker(const char* mode, const char* rawmode, int* bits_out) +{ + int i; + + /* find a suitable pixel unpacker */ + for (i = 0; unpackers[i].rawmode; i++) + if (strcmp(unpackers[i].mode, mode) == 0 && + strcmp(unpackers[i].rawmode, rawmode) == 0) { + if (bits_out) + *bits_out = unpackers[i].bits; + return unpackers[i].unpack; + } + + /* FIXME: configure a general unpacker based on the type codes... */ + + return NULL; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c new file mode 100755 index 00000000000..19da1f65443 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c @@ -0,0 +1,162 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * code to convert and unpack PhotoYCC data + * + * history: + * 97-01-25 fl Moved from PcdDecode.c + * + * Copyright (c) Fredrik Lundh 1996-97. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +/* Tables generated by pcdtables.py, based on transforms taken from + the "Colour Space Conversions FAQ" by Roberts/Ford. */ + +static INT16 L[] = { 0, 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 18, +19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, +42, 43, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 62, 64, +65, 67, 68, 69, 71, 72, 73, 75, 76, 77, 79, 80, 82, 83, 84, 86, 87, +88, 90, 91, 92, 94, 95, 96, 98, 99, 101, 102, 103, 105, 106, 107, 109, +110, 111, 113, 114, 115, 117, 118, 120, 121, 122, 124, 125, 126, 128, +129, 130, 132, 133, 134, 136, 137, 139, 140, 141, 143, 144, 145, 147, +148, 149, 151, 152, 153, 155, 156, 158, 159, 160, 162, 163, 164, 166, +167, 168, 170, 171, 173, 174, 175, 177, 178, 179, 181, 182, 183, 185, +186, 187, 189, 190, 192, 193, 194, 196, 197, 198, 200, 201, 202, 204, +205, 206, 208, 209, 211, 212, 213, 215, 216, 217, 219, 220, 221, 223, +224, 225, 227, 228, 230, 231, 232, 234, 235, 236, 238, 239, 240, 242, +243, 245, 246, 247, 249, 250, 251, 253, 254, 255, 257, 258, 259, 261, +262, 264, 265, 266, 268, 269, 270, 272, 273, 274, 276, 277, 278, 280, +281, 283, 284, 285, 287, 288, 289, 291, 292, 293, 295, 296, 297, 299, +300, 302, 303, 304, 306, 307, 308, 310, 311, 312, 314, 315, 317, 318, +319, 321, 322, 323, 325, 326, 327, 329, 330, 331, 333, 334, 336, 337, +338, 340, 341, 342, 344, 345, 346 }; + +static INT16 CB[] = { -345, -343, -341, -338, -336, -334, -332, -329, +-327, -325, -323, -321, -318, -316, -314, -312, -310, -307, -305, +-303, -301, -298, -296, -294, -292, -290, -287, -285, -283, -281, +-278, -276, -274, -272, -270, -267, -265, -263, -261, -258, -256, +-254, -252, -250, -247, -245, -243, -241, -239, -236, -234, -232, +-230, -227, -225, -223, -221, -219, -216, -214, -212, -210, -207, +-205, -203, -201, -199, -196, -194, -192, -190, -188, -185, -183, +-181, -179, -176, -174, -172, -170, -168, -165, -163, -161, -159, +-156, -154, -152, -150, -148, -145, -143, -141, -139, -137, -134, +-132, -130, -128, -125, -123, -121, -119, -117, -114, -112, -110, +-108, -105, -103, -101, -99, -97, -94, -92, -90, -88, -85, -83, -81, +-79, -77, -74, -72, -70, -68, -66, -63, -61, -59, -57, -54, -52, -50, +-48, -46, -43, -41, -39, -37, -34, -32, -30, -28, -26, -23, -21, -19, +-17, -15, -12, -10, -8, -6, -3, -1, 0, 2, 4, 7, 9, 11, 13, 16, 18, 20, +22, 24, 27, 29, 31, 33, 35, 38, 40, 42, 44, 47, 49, 51, 53, 55, 58, +60, 62, 64, 67, 69, 71, 73, 75, 78, 80, 82, 84, 86, 89, 91, 93, 95, +98, 100, 102, 104, 106, 109, 111, 113, 115, 118, 120, 122, 124, 126, +129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 151, 153, 155, 157, +160, 162, 164, 166, 169, 171, 173, 175, 177, 180, 182, 184, 186, 189, +191, 193, 195, 197, 200, 202, 204, 206, 208, 211, 213, 215, 217, 220 }; + +static INT16 GB[] = { 67, 67, 66, 66, 65, 65, 65, 64, 64, 63, 63, 62, +62, 62, 61, 61, 60, 60, 59, 59, 59, 58, 58, 57, 57, 56, 56, 56, 55, +55, 54, 54, 53, 53, 52, 52, 52, 51, 51, 50, 50, 49, 49, 49, 48, 48, +47, 47, 46, 46, 46, 45, 45, 44, 44, 43, 43, 43, 42, 42, 41, 41, 40, +40, 40, 39, 39, 38, 38, 37, 37, 37, 36, 36, 35, 35, 34, 34, 34, 33, +33, 32, 32, 31, 31, 31, 30, 30, 29, 29, 28, 28, 28, 27, 27, 26, 26, +25, 25, 25, 24, 24, 23, 23, 22, 22, 22, 21, 21, 20, 20, 19, 19, 19, +18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 13, 13, 12, 12, 12, 11, +11, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, +1, 1, 0, 0, 0, 0, 0, -1, -1, -2, -2, -2, -3, -3, -4, -4, -5, -5, -5, +-6, -6, -7, -7, -8, -8, -8, -9, -9, -10, -10, -11, -11, -11, -12, -12, +-13, -13, -14, -14, -14, -15, -15, -16, -16, -17, -17, -18, -18, -18, +-19, -19, -20, -20, -21, -21, -21, -22, -22, -23, -23, -24, -24, -24, +-25, -25, -26, -26, -27, -27, -27, -28, -28, -29, -29, -30, -30, -30, +-31, -31, -32, -32, -33, -33, -33, -34, -34, -35, -35, -36, -36, -36, +-37, -37, -38, -38, -39, -39, -39, -40, -40, -41, -41, -42 }; + +static INT16 CR[] = { -249, -247, -245, -243, -241, -239, -238, -236, +-234, -232, -230, -229, -227, -225, -223, -221, -219, -218, -216, +-214, -212, -210, -208, -207, -205, -203, -201, -199, -198, -196, +-194, -192, -190, -188, -187, -185, -183, -181, -179, -178, -176, +-174, -172, -170, -168, -167, -165, -163, -161, -159, -157, -156, +-154, -152, -150, -148, -147, -145, -143, -141, -139, -137, -136, +-134, -132, -130, -128, -127, -125, -123, -121, -119, -117, -116, +-114, -112, -110, -108, -106, -105, -103, -101, -99, -97, -96, -94, +-92, -90, -88, -86, -85, -83, -81, -79, -77, -76, -74, -72, -70, -68, +-66, -65, -63, -61, -59, -57, -55, -54, -52, -50, -48, -46, -45, -43, +-41, -39, -37, -35, -34, -32, -30, -28, -26, -25, -23, -21, -19, -17, +-15, -14, -12, -10, -8, -6, -4, -3, -1, 0, 2, 4, 5, 7, 9, 11, 13, 15, +16, 18, 20, 22, 24, 26, 27, 29, 31, 33, 35, 36, 38, 40, 42, 44, 46, +47, 49, 51, 53, 55, 56, 58, 60, 62, 64, 66, 67, 69, 71, 73, 75, 77, +78, 80, 82, 84, 86, 87, 89, 91, 93, 95, 97, 98, 100, 102, 104, 106, +107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 129, 131, +133, 135, 137, 138, 140, 142, 144, 146, 148, 149, 151, 153, 155, 157, +158, 160, 162, 164, 166, 168, 169, 171, 173, 175, 177, 179, 180, 182, +184, 186, 188, 189, 191, 193, 195, 197, 199, 200, 202, 204, 206, 208, +209, 211, 213, 215 }; + +static INT16 GR[] = { 127, 126, 125, 124, 123, 122, 121, 121, 120, 119, +118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 108, 107, 106, +105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 95, 94, 93, 92, 91, +90, 89, 88, 87, 86, 85, 84, 83, 83, 82, 81, 80, 79, 78, 77, 76, 75, +74, 73, 72, 71, 70, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, +58, 57, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 45, 44, +43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28, +27, 26, 25, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, +11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5, -5, +-6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -18, -19, +-20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -31, -32, +-33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -44, -45, +-46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -56, -57, -58, +-59, -60, -61, -62, -63, -64, -65, -66, -67, -68, -69, -69, -70, -71, +-72, -73, -74, -75, -76, -77, -78, -79, -80, -81, -82, -82, -83, -84, +-85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -94, -95, -96, -97, +-98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -107, -108 }; + +#define R 0 +#define G 1 +#define B 2 +#define A 3 + +#define YCC2RGB(rgb, y, cb, cr) {\ + int l = L[y];\ + int r = l + CR[cr];\ + int g = l + GR[cr] + GB[cb];\ + int b = l + CB[cb];\ + rgb[0] = (r <= 0) ? 0 : (r >= 255) ? 255 : r;\ + rgb[1] = (g <= 0) ? 0 : (g >= 255) ? 255 : g;\ + rgb[2] = (b <= 0) ? 0 : (b >= 255) ? 255 : b;\ +} + +void +ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* PhotoYCC triplets */ + for (i = 0; i < pixels; i++) { + YCC2RGB(out, in[0], in[1], in[2]); + out[A] = 255; + out += 4; in += 3; + } +} + +void +ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* PhotoYCC triplets plus premultiplied alpha */ + for (i = 0; i < pixels; i++) { + /* Divide by alpha */ + UINT8 rgb[3]; + rgb[0] = (in[3] == 0) ? 0 : (((int) in[0] * 255) / in[3]); + rgb[1] = (in[3] == 0) ? 0 : (((int) in[1] * 255) / in[3]); + rgb[2] = (in[3] == 0) ? 0 : (((int) in[2] * 255) / in[3]); + /* Convert non-multiplied data to RGB */ + YCC2RGB(out, rgb[0], rgb[1], rgb[2]); + out[A] = in[3]; + out += 4; in += 4; + } +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c new file mode 100755 index 00000000000..2318262450e --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c @@ -0,0 +1,398 @@ +/* PILusm, a gaussian blur and unsharp masking library for PIL + By Kevin Cazabon, copyright 2003 + kevin_cazabon@hotmail.com + kevin@cazabon.com */ + +/* Originally released under LGPL. Graciously donated to PIL + for distribution under the standard PIL license in 2009." */ + +#include "Python.h" +#include "Imaging.h" + +#define PILUSMVERSION "0.6.1" + +/* version history + +0.6.1 converted to C and added to PIL 1.1.7 + +0.6.0 fixed/improved float radius support (oops!) + now that radius can be a float (properly), changed radius value to + be an actual radius (instead of diameter). So, you should get + similar results from PIL_usm as from other paint programs when + using the SAME values (no doubling of radius required any more). + Be careful, this may "break" software if you had it set for 2x + or 5x the radius as was recommended with earlier versions. + made PILusm thread-friendly (release GIL before lengthly operations, + and re-acquire it before returning to Python). This makes a huge + difference with multi-threaded applications on dual-processor + or "Hyperthreading"-enabled systems (Pentium4, Xeon, etc.) + +0.5.0 added support for float radius values! + +0.4.0 tweaked gaussian curve calculation to be closer to consistent shape + across a wide range of radius values + +0.3.0 changed deviation calculation in gausian algorithm to be dynamic + _gblur now adds 1 to the user-supplied radius before using it so + that a value of "0" returns the original image instead of a + black one. + fixed handling of alpha channel in RGBX, RGBA images + improved speed of gblur by reducing unnecessary checks and assignments + +0.2.0 fixed L-mode image support + +0.1.0 initial release + +*/ + +static inline UINT8 clip(double in) +{ + if (in >= 255.0) + return (UINT8) 255; + if (in <= 0.0) + return (UINT8) 0; + return (UINT8) in; +} + +static Imaging +gblur(Imaging im, Imaging imOut, float floatRadius, int channels, int padding) +{ + ImagingSectionCookie cookie; + + float *maskData = NULL; + int y = 0; + int x = 0; + float z = 0; + float sum = 0.0; + float dev = 0.0; + + float *buffer = NULL; + + int *line = NULL; + UINT8 *line8 = NULL; + + int pix = 0; + float newPixel[4]; + int channel = 0; + int offset = 0; + INT32 newPixelFinals; + + int radius = 0; + float remainder = 0.0; + + int i; + + /* Do the gaussian blur */ + + /* For a symmetrical gaussian blur, instead of doing a radius*radius + matrix lookup, you get the EXACT same results by doing a radius*1 + transform, followed by a 1*radius transform. This reduces the + number of lookups exponentially (10 lookups per pixel for a + radius of 5 instead of 25 lookups). So, we blur the lines first, + then we blur the resulting columns. */ + + /* first, round radius off to the next higher integer and hold the + remainder this is used so we can support float radius values + properly. */ + + remainder = floatRadius - ((int) floatRadius); + floatRadius = ceil(floatRadius); + + /* Next, double the radius and offset by 2.0... that way "0" returns + the original image instead of a black one. We multiply it by 2.0 + so that it is a true "radius", not a diameter (the results match + other paint programs closer that way too). */ + radius = (int) ((floatRadius * 2.0) + 2.0); + + /* create the maskData for the gaussian curve */ + maskData = malloc(radius * sizeof(float)); + /* FIXME: error checking */ + for (x = 0; x < radius; x++) { + z = ((float) (x + 2) / ((float) radius)); + dev = 0.5 + (((float) (radius * radius)) * 0.001); + /* you can adjust this factor to change the shape/center-weighting + of the gaussian */ + maskData[x] = (float) pow((1.0 / sqrt(2.0 * 3.14159265359 * dev)), + ((-(z - 1.0) * -(x - 1.0)) / + (2.0 * dev))); + } + + /* if there's any remainder, multiply the first/last values in + MaskData it. this allows us to support float radius values. */ + if (remainder > 0.0) { + maskData[0] *= remainder; + maskData[radius - 1] *= remainder; + } + + for (x = 0; x < radius; x++) { + /* this is done separately now due to the correction for float + radius values above */ + sum += maskData[x]; + } + + for (i = 0; i < radius; i++) { + maskData[i] *= (1.0 / sum); + /* printf("%f\n", maskData[i]); */ + } + + /* create a temporary memory buffer for the data for the first pass + memset the buffer to 0 so we can use it directly with += */ + + /* don't bother about alpha/padding */ + buffer = calloc((size_t) (im->xsize * im->ysize * channels), + sizeof(float)); + if (buffer == NULL) + return ImagingError_MemoryError(); + + /* be nice to other threads while you go off to lala land */ + ImagingSectionEnter(&cookie); + + /* memset(buffer, 0, sizeof(buffer)); */ + + newPixel[0] = newPixel[1] = newPixel[2] = newPixel[3] = 0; + + /* perform a blur on each line, and place in the temporary storage buffer */ + for (y = 0; y < im->ysize; y++) { + if (channels == 1 && im->image8 != NULL) { + line8 = (UINT8 *) im->image8[y]; + } else { + line = im->image32[y]; + } + for (x = 0; x < im->xsize; x++) { + newPixel[0] = newPixel[1] = newPixel[2] = newPixel[3] = 0; + /* for each neighbor pixel, factor in its value/weighting to the + current pixel */ + for (pix = 0; pix < radius; pix++) { + /* figure the offset of this neighbor pixel */ + offset = + (int) ((-((float) radius / 2.0) + (float) pix) + 0.5); + if (x + offset < 0) + offset = -x; + else if (x + offset >= im->xsize) + offset = im->xsize - x - 1; + + /* add (neighbor pixel value * maskData[pix]) to the current + pixel value */ + if (channels == 1) { + buffer[(y * im->xsize) + x] += + ((float) ((UINT8 *) & line8[x + offset])[0]) * + (maskData[pix]); + } else { + for (channel = 0; channel < channels; channel++) { + buffer[(y * im->xsize * channels) + + (x * channels) + channel] += + ((float) ((UINT8 *) & line[x + offset]) + [channel]) * (maskData[pix]); + } + } + } + } + } + + /* perform a blur on each column in the buffer, and place in the + output image */ + for (x = 0; x < im->xsize; x++) { + for (y = 0; y < im->ysize; y++) { + newPixel[0] = newPixel[1] = newPixel[2] = newPixel[3] = 0; + /* for each neighbor pixel, factor in its value/weighting to the + current pixel */ + for (pix = 0; pix < radius; pix++) { + /* figure the offset of this neighbor pixel */ + offset = + (int) (-((float) radius / 2.0) + (float) pix + 0.5); + if (y + offset < 0) + offset = -y; + else if (y + offset >= im->ysize) + offset = im->ysize - y - 1; + /* add (neighbor pixel value * maskData[pix]) to the current + pixel value */ + for (channel = 0; channel < channels; channel++) { + newPixel[channel] += + (buffer + [((y + offset) * im->xsize * channels) + + (x * channels) + channel]) * (maskData[pix]); + } + } + /* if the image is RGBX or RGBA, copy the 4th channel data to + newPixel, so it gets put in imOut */ + if (strcmp(im->mode, "RGBX") == 0 + || strcmp(im->mode, "RGBA") == 0) { + newPixel[3] = (float) ((UINT8 *) & line[x + offset])[3]; + } + + /* pack the channels into an INT32 so we can put them back in + the PIL image */ + newPixelFinals = 0; + if (channels == 1) { + newPixelFinals = clip(newPixel[0]); + } else { + /* for RGB, the fourth channel isn't used anyways, so just + pack a 0 in there, this saves checking the mode for each + pixel. */ + /* this doesn't work on little-endian machines... fix it! */ + newPixelFinals = + clip(newPixel[0]) | clip(newPixel[1]) << 8 | + clip(newPixel[2]) << 16 | clip(newPixel[3]) << 24; + } + /* set the resulting pixel in imOut */ + if (channels == 1) { + imOut->image8[y][x] = (UINT8) newPixelFinals; + } else { + imOut->image32[y][x] = newPixelFinals; + } + } + } + + /* free the buffer */ + free(buffer); + + /* get the GIL back so Python knows who you are */ + ImagingSectionLeave(&cookie); + + return imOut; +} + +Imaging ImagingGaussianBlur(Imaging im, Imaging imOut, float radius) +{ + int channels = 0; + int padding = 0; + + if (strcmp(im->mode, "RGB") == 0) { + channels = 3; + padding = 1; + } else if (strcmp(im->mode, "RGBA") == 0) { + channels = 3; + padding = 1; + } else if (strcmp(im->mode, "RGBX") == 0) { + channels = 3; + padding = 1; + } else if (strcmp(im->mode, "CMYK") == 0) { + channels = 4; + padding = 0; + } else if (strcmp(im->mode, "L") == 0) { + channels = 1; + padding = 0; + } else + return ImagingError_ModeError(); + + return gblur(im, imOut, radius, channels, padding); +} + +Imaging +ImagingUnsharpMask(Imaging im, Imaging imOut, float radius, int percent, + int threshold) +{ + ImagingSectionCookie cookie; + + Imaging result; + int channel = 0; + int channels = 0; + int padding = 0; + + int x = 0; + int y = 0; + + int *lineIn = NULL; + int *lineOut = NULL; + UINT8 *lineIn8 = NULL; + UINT8 *lineOut8 = NULL; + + int diff = 0; + + INT32 newPixel = 0; + + if (strcmp(im->mode, "RGB") == 0) { + channels = 3; + padding = 1; + } else if (strcmp(im->mode, "RGBA") == 0) { + channels = 3; + padding = 1; + } else if (strcmp(im->mode, "RGBX") == 0) { + channels = 3; + padding = 1; + } else if (strcmp(im->mode, "CMYK") == 0) { + channels = 4; + padding = 0; + } else if (strcmp(im->mode, "L") == 0) { + channels = 1; + padding = 0; + } else + return ImagingError_ModeError(); + + /* first, do a gaussian blur on the image, putting results in imOut + temporarily */ + result = gblur(im, imOut, radius, channels, padding); + if (!result) + return NULL; + + /* now, go through each pixel, compare "normal" pixel to blurred + pixel. if the difference is more than threshold values, apply + the OPPOSITE correction to the amount of blur, multiplied by + percent. */ + + ImagingSectionEnter(&cookie); + + for (y = 0; y < im->ysize; y++) { + if (channels == 1) { + lineIn8 = im->image8[y]; + lineOut8 = imOut->image8[y]; + } else { + lineIn = im->image32[y]; + lineOut = imOut->image32[y]; + } + for (x = 0; x < im->xsize; x++) { + newPixel = 0; + /* compare in/out pixels, apply sharpening */ + if (channels == 1) { + diff = + ((UINT8 *) & lineIn8[x])[0] - + ((UINT8 *) & lineOut8[x])[0]; + if (abs(diff) > threshold) { + /* add the diff*percent to the original pixel */ + imOut->image8[y][x] = + clip((((UINT8 *) & lineIn8[x])[0]) + + (diff * ((float) percent) / 100.0)); + } else { + /* newPixel is the same as imIn */ + imOut->image8[y][x] = ((UINT8 *) & lineIn8[x])[0]; + } + } + + else { + for (channel = 0; channel < channels; channel++) { + diff = (int) ((((UINT8 *) & lineIn[x])[channel]) - + (((UINT8 *) & lineOut[x])[channel])); + if (abs(diff) > threshold) { + /* add the diff*percent to the original pixel + this may not work for little-endian systems, fix it! */ + newPixel = + newPixel | + clip((float) (((UINT8 *) & lineIn[x])[channel]) + + + (diff * + (((float) percent / + 100.0)))) << (channel * 8); + } else { + /* newPixel is the same as imIn + this may not work for little-endian systems, fix it! */ + newPixel = + newPixel | ((UINT8 *) & lineIn[x])[channel] << + (channel * 8); + } + } + if (strcmp(im->mode, "RGBX") == 0 + || strcmp(im->mode, "RGBA") == 0) { + /* preserve the alpha channel + this may not work for little-endian systems, fix it! */ + newPixel = + newPixel | ((UINT8 *) & lineIn[x])[channel] << 24; + } + imOut->image32[y][x] = newPixel; + } + } + } + + ImagingSectionLeave(&cookie); + + return imOut; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c new file mode 100755 index 00000000000..8a203841bef --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c @@ -0,0 +1,81 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for XBM hex image data + * + * history: + * 96-04-13 fl Created + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#define HEX(v) ((v >= '0' && v <= '9') ? v - '0' :\ + (v >= 'a' && v <= 'f') ? v - 'a' + 10 :\ + (v >= 'A' && v <= 'F') ? v - 'A' + 10 : 0) + +int +ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + enum { BYTE = 1, SKIP }; + + UINT8* ptr; + + if (!state->state) + state->state = SKIP; + + ptr = buf; + + for (;;) { + + if (state->state == SKIP) { + + /* Skip forward until next 'x' */ + + while (bytes > 0) { + if (*ptr == 'x') + break; + ptr++; + bytes--; + } + + if (bytes == 0) + return ptr - buf; + + state->state = BYTE; + + } + + if (bytes < 3) + return ptr - buf; + + state->buffer[state->x] = (HEX(ptr[1])<<4) + HEX(ptr[2]); + + if (++state->x >= state->bytes) { + + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y], state->buffer, + state->xsize); + + state->x = 0; + + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + return -1; + } + } + + ptr += 3; + bytes -= 3; + + state->state = SKIP; + + } + +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c new file mode 100755 index 00000000000..e066fd6b583 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c @@ -0,0 +1,106 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * encoder for Xbm data + * + * history: + * 96-11-01 fl created + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + + +int +ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + const char *hex = "0123456789abcdef"; + + UINT8* ptr = buf; + int i, n; + + if (!state->state) { + + /* 8 pixels are stored in no more than 6 bytes */ + state->bytes = 6*(state->xsize+7)/8; + + state->state = 1; + + } + + if (bytes < state->bytes) { + state->errcode = IMAGING_CODEC_MEMORY; + return 0; + } + + ptr = buf; + + while (bytes >= state->bytes) { + + state->shuffle(state->buffer, + (UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->xsize); + + if (state->y < state->ysize-1) { + + /* any line but the last */ + for (n = 0; n < state->xsize; n += 8) { + + i = state->buffer[n/8]; + + *ptr++ = '0'; + *ptr++ = 'x'; + *ptr++ = hex[(i>>4)&15]; + *ptr++ = hex[i&15]; + *ptr++ = ','; + bytes -= 5; + + if (++state->count >= 79/5) { + *ptr++ = '\n'; + bytes--; + state->count = 0; + } + + } + + state->y++; + + } else { + + /* last line */ + for (n = 0; n < state->xsize; n += 8) { + + i = state->buffer[n/8]; + + *ptr++ = '0'; + *ptr++ = 'x'; + *ptr++ = hex[(i>>4)&15]; + *ptr++ = hex[i&15]; + + if (n < state->xsize-8) { + *ptr++ = ','; + if (++state->count >= 79/5) { + *ptr++ = '\n'; + bytes--; + state->count = 0; + } + } else + *ptr++ = '\n'; + + bytes -= 5; + + } + + state->errcode = IMAGING_CODEC_END; + break; + } + } + + return ptr - buf; +} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h new file mode 100755 index 00000000000..d961407e31b --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h @@ -0,0 +1,57 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * declarations for the ZIP codecs + * + * Copyright (c) Fredrik Lundh 1996. + */ + + +#include "zlib.h" + + +/* modes */ +#define ZIP_PNG 0 /* continuous, filtered image data */ +#define ZIP_PNG_PALETTE 1 /* non-continuous data, disable filtering */ +#define ZIP_TIFF_PREDICTOR 2 /* TIFF, with predictor */ +#define ZIP_TIFF 3 /* TIFF, without predictor */ + + +typedef struct { + + /* CONFIGURATION */ + + /* Codec mode */ + int mode; + + /* Optimize (max compression) SLOW!!! */ + int optimize; + + /* Predefined dictionary (experimental) */ + char* dictionary; + int dictionary_size; + + /* PRIVATE CONTEXT (set by decoder/encoder) */ + + z_stream z_stream; /* (de)compression stream */ + + UINT8* previous; /* previous line (allocated) */ + + int last_output; /* # bytes last output by inflate */ + + /* Compressor specific stuff */ + UINT8* prior; /* filter storage (allocated) */ + UINT8* up; + UINT8* average; + UINT8* paeth; + + UINT8* output; /* output data */ + + int prefix; /* size of filter prefix (0 for TIFF data) */ + + int interlaced; /* is the image interlaced? (PNG) */ + + int pass; /* current pass of the interlaced image (PNG) */ + +} ZIPSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c new file mode 100755 index 00000000000..08cdc718964 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c @@ -0,0 +1,271 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * decoder for ZIP (deflated) image data. + * + * history: + * 1996-12-14 fl Created (for PNG) + * 1997-01-15 fl Prepared to read TIFF/ZIP + * 2001-11-19 fl PNG incomplete read patch (from Bernhard Herzog) + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997-2001. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#ifdef HAVE_LIBZ + +#include "Zip.h" + +static const int OFFSET[] = { 7, 3, 3, 1, 1, 0, 0 }; +static const int STARTING_COL[] = { 0, 4, 0, 2, 0, 1, 0 }; +static const int STARTING_ROW[] = { 0, 0, 4, 0, 2, 0, 1 }; +static const int COL_INCREMENT[] = { 8, 8, 4, 4, 2, 2, 1 }; +static const int ROW_INCREMENT[] = { 8, 8, 8, 4, 4, 2, 2 }; + +/* Get the length in bytes of a scanline in the pass specified, + * for interlaced images */ +static int get_row_len(ImagingCodecState state, int pass) +{ + int row_len = (state->xsize + OFFSET[pass]) / COL_INCREMENT[pass]; + return ((row_len * state->bits) + 7) / 8; +} + +/* -------------------------------------------------------------------- */ +/* Decoder */ +/* -------------------------------------------------------------------- */ + +int +ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + ZIPSTATE* context = (ZIPSTATE*) state->context; + int err; + int n; + UINT8* ptr; + int i, bpp; + int row_len; + + if (!state->state) { + + /* Initialization */ + if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) + context->prefix = 1; /* PNG */ + + /* Expand standard buffer to make room for the (optional) filter + prefix, and allocate a buffer to hold the previous line */ + free(state->buffer); + state->buffer = (UINT8*) malloc(state->bytes+1); + context->previous = (UINT8*) malloc(state->bytes+1); + if (!state->buffer || !context->previous) { + state->errcode = IMAGING_CODEC_MEMORY; + return -1; + } + + context->last_output = 0; + + /* Initialize to black */ + memset(context->previous, 0, state->bytes+1); + + /* Setup decompression context */ + context->z_stream.zalloc = (alloc_func) NULL; + context->z_stream.zfree = (free_func) NULL; + context->z_stream.opaque = (voidpf) NULL; + + err = inflateInit(&context->z_stream); + if (err < 0) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + if (context->interlaced) { + context->pass = 0; + state->y = STARTING_ROW[context->pass]; + } + + /* Ready to decode */ + state->state = 1; + + } + + if (context->interlaced) { + row_len = get_row_len(state, context->pass); + } else { + row_len = state->bytes; + } + + /* Setup the source buffer */ + context->z_stream.next_in = buf; + context->z_stream.avail_in = bytes; + + /* Decompress what we've got this far */ + while (context->z_stream.avail_in > 0) { + + context->z_stream.next_out = state->buffer + context->last_output; + context->z_stream.avail_out = + row_len + context->prefix - context->last_output; + + err = inflate(&context->z_stream, Z_NO_FLUSH); + + if (err < 0) { + /* Something went wrong inside the compression library */ + if (err == Z_DATA_ERROR) + state->errcode = IMAGING_CODEC_BROKEN; + else if (err == Z_MEM_ERROR) + state->errcode = IMAGING_CODEC_MEMORY; + else + state->errcode = IMAGING_CODEC_CONFIG; + free(context->previous); + inflateEnd(&context->z_stream); + return -1; + } + + n = row_len + context->prefix - context->z_stream.avail_out; + + if (n < row_len + context->prefix) { + context->last_output = n; + break; /* need more input data */ + } + + /* Apply predictor */ + switch (context->mode) { + case ZIP_PNG: + switch (state->buffer[0]) { + case 0: + break; + case 1: + /* prior */ + bpp = (state->bits + 7) / 8; + for (i = bpp+1; i <= row_len; i++) + state->buffer[i] += state->buffer[i-bpp]; + break; + case 2: + /* up */ + for (i = 1; i <= row_len; i++) + state->buffer[i] += context->previous[i]; + break; + case 3: + /* average */ + bpp = (state->bits + 7) / 8; + for (i = 1; i <= bpp; i++) + state->buffer[i] += context->previous[i]/2; + for (; i <= row_len; i++) + state->buffer[i] += + (state->buffer[i-bpp] + context->previous[i])/2; + break; + case 4: + /* paeth filtering */ + bpp = (state->bits + 7) / 8; + for (i = 1; i <= bpp; i++) + state->buffer[i] += context->previous[i]; + for (; i <= row_len; i++) { + int a, b, c; + int pa, pb, pc; + + /* fetch pixels */ + a = state->buffer[i-bpp]; + b = context->previous[i]; + c = context->previous[i-bpp]; + + /* distances to surrounding pixels */ + pa = abs(b - c); + pb = abs(a - c); + pc = abs(a + b - 2*c); + + /* pick predictor with the shortest distance */ + state->buffer[i] += + (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; + + } + break; + default: + state->errcode = IMAGING_CODEC_UNKNOWN; + free(context->previous); + inflateEnd(&context->z_stream); + return -1; + } + break; + case ZIP_TIFF_PREDICTOR: + bpp = (state->bits + 7) / 8; + for (i = bpp+1; i <= row_len; i++) + state->buffer[i] += state->buffer[i-bpp]; + break; + } + + /* Stuff data into the image */ + if (context->interlaced) { + int col = STARTING_COL[context->pass]; + if (state->bits >= 8) { + /* Stuff pixels in their correct location, one by one */ + for (i = 0; i < row_len; i += ((state->bits + 7) / 8)) { + state->shuffle((UINT8*) im->image[state->y] + + col * im->pixelsize, + state->buffer + context->prefix + i, 1); + col += COL_INCREMENT[context->pass]; + } + } else { + /* Handle case with more than a pixel in each byte */ + int row_bits = ((state->xsize + OFFSET[context->pass]) + / COL_INCREMENT[context->pass]) * state->bits; + for (i = 0; i < row_bits; i += state->bits) { + UINT8 byte = *(state->buffer + context->prefix + (i / 8)); + byte <<= (i % 8); + state->shuffle((UINT8*) im->image[state->y] + + col * im->pixelsize, &byte, 1); + col += COL_INCREMENT[context->pass]; + } + } + /* Find next valid scanline */ + state->y += ROW_INCREMENT[context->pass]; + while (state->y >= state->ysize || row_len <= 0) { + context->pass++; + if (context->pass == 7) { + /* Force exit below */ + state->y = state->ysize; + break; + } + state->y = STARTING_ROW[context->pass]; + row_len = get_row_len(state, context->pass); + /* Since we're moving to the "first" line, the previous line + * should be black to make filters work corectly */ + memset(state->buffer, 0, state->bytes+1); + } + } else { + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, + state->buffer + context->prefix, + state->xsize); + state->y++; + } + + /* all inflate output has been consumed */ + context->last_output = 0; + + if (state->y >= state->ysize || err == Z_STREAM_END) { + + /* The image and the data should end simultaneously */ + /* if (state->y < state->ysize || err != Z_STREAM_END) + state->errcode = IMAGING_CODEC_BROKEN; */ + + free(context->previous); + inflateEnd(&context->z_stream); + return -1; /* end of file (errcode=0) */ + + } + + /* Swap buffer pointers */ + ptr = state->buffer; + state->buffer = context->previous; + context->previous = ptr; + + } + + return bytes; /* consumed all of it */ + +} + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c new file mode 100755 index 00000000000..19b2b778783 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c @@ -0,0 +1,341 @@ +/* + * The Python Imaging Library. + * $Id$ + * + * coder for ZIP (deflated) image data + * + * History: + * 96-12-29 fl created + * 96-12-30 fl adaptive filter selection, encoder tuning + * + * Copyright (c) Fredrik Lundh 1996. + * Copyright (c) Secret Labs AB 1997. + * + * See the README file for information on usage and redistribution. + */ + + +#include "Imaging.h" + +#ifdef HAVE_LIBZ + +#include "Zip.h" + +int +ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) +{ + ZIPSTATE* context = (ZIPSTATE*) state->context; + int err; + UINT8* ptr; + int i, bpp, s, sum; + ImagingSectionCookie cookie; + + if (!state->state) { + + /* Initialization */ + + /* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */ + + /* Expand standard buffer to make room for the filter selector, + and allocate filter buffers */ + free(state->buffer); + state->buffer = (UINT8*) malloc(state->bytes+1); + context->previous = (UINT8*) malloc(state->bytes+1); + context->prior = (UINT8*) malloc(state->bytes+1); + context->up = (UINT8*) malloc(state->bytes+1); + context->average = (UINT8*) malloc(state->bytes+1); + context->paeth = (UINT8*) malloc(state->bytes+1); + if (!state->buffer || !context->previous || !context->prior || + !context->up || !context->average || !context->paeth) { + free(context->paeth); + free(context->average); + free(context->up); + free(context->prior); + free(context->previous); + state->errcode = IMAGING_CODEC_MEMORY; + return -1; + } + + /* Initalise filter buffers */ + state->buffer[0] = 0; + context->prior[0] = 1; + context->up[0] = 2; + context->average[0] = 3; + context->paeth[0] = 4; + + /* Initialise previous buffer to black */ + memset(context->previous, 0, state->bytes+1); + + /* Setup compression context */ + context->z_stream.zalloc = (alloc_func)0; + context->z_stream.zfree = (free_func)0; + context->z_stream.opaque = (voidpf)0; + context->z_stream.next_in = 0; + context->z_stream.avail_in = 0; + + err = deflateInit2(&context->z_stream, + /* compression level */ + (context->optimize) ? Z_BEST_COMPRESSION + : Z_DEFAULT_COMPRESSION, + /* compression method */ + Z_DEFLATED, + /* compression memory resources */ + 15, 9, + /* compression strategy (image data are filtered)*/ + (context->mode == ZIP_PNG) ? Z_FILTERED + : Z_DEFAULT_STRATEGY); + if (err < 0) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + + if (context->dictionary && context->dictionary_size > 0) { + err = deflateSetDictionary(&context->z_stream, (unsigned char *)context->dictionary, + context->dictionary_size); + if (err < 0) { + state->errcode = IMAGING_CODEC_CONFIG; + return -1; + } + } + + /* Ready to decode */ + state->state = 1; + + } + + /* Setup the destination buffer */ + context->z_stream.next_out = buf; + context->z_stream.avail_out = bytes; + if (context->z_stream.next_in && context->z_stream.avail_in > 0) { + /* We have some data from previous round, deflate it first */ + err = deflate(&context->z_stream, Z_NO_FLUSH); + + if (err < 0) { + /* Something went wrong inside the compression library */ + if (err == Z_DATA_ERROR) + state->errcode = IMAGING_CODEC_BROKEN; + else if (err == Z_MEM_ERROR) + state->errcode = IMAGING_CODEC_MEMORY; + else + state->errcode = IMAGING_CODEC_CONFIG; + free(context->paeth); + free(context->average); + free(context->up); + free(context->prior); + free(context->previous); + deflateEnd(&context->z_stream); + return -1; + } + } + + ImagingSectionEnter(&cookie); + for (;;) { + + switch (state->state) { + + case 1: + + /* Compress image data */ + while (context->z_stream.avail_out > 0) { + + if (state->y >= state->ysize) { + /* End of image; now flush compressor buffers */ + state->state = 2; + break; + + } + + /* Stuff image data into the compressor */ + state->shuffle(state->buffer+1, + (UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, + state->xsize); + + state->y++; + + context->output = state->buffer; + + if (context->mode == ZIP_PNG) { + + /* Filter the image data. For each line, select + the filter that gives the least total distance + from zero for the filtered data (taken from + LIBPNG) */ + + bpp = (state->bits + 7) / 8; + + /* 0. No filter */ + for (i = 1, sum = 0; i <= state->bytes; i++) { + UINT8 v = state->buffer[i]; + sum += (v < 128) ? v : 256 - v; + } + + /* 2. Up. We'll test this first to save time when + an image line is identical to the one above. */ + if (sum > 0) { + for (i = 1, s = 0; i <= state->bytes; i++) { + UINT8 v = state->buffer[i] - context->previous[i]; + context->up[i] = v; + s += (v < 128) ? v : 256 - v; + } + if (s < sum) { + context->output = context->up; + sum = s; /* 0 if line was duplicated */ + } + } + + /* 1. Prior */ + if (sum > 0) { + for (i = 1, s = 0; i <= bpp; i++) { + UINT8 v = state->buffer[i]; + context->prior[i] = v; + s += (v < 128) ? v : 256 - v; + } + for (; i <= state->bytes; i++) { + UINT8 v = state->buffer[i] - state->buffer[i-bpp]; + context->prior[i] = v; + s += (v < 128) ? v : 256 - v; + } + if (s < sum) { + context->output = context->prior; + sum = s; /* 0 if line is solid */ + } + } + + /* 3. Average (not very common in real-life images, + so its only used with the optimize option) */ + if (context->optimize && sum > 0) { + for (i = 1, s = 0; i <= bpp; i++) { + UINT8 v = state->buffer[i] - context->previous[i]/2; + context->average[i] = v; + s += (v < 128) ? v : 256 - v; + } + for (; i <= state->bytes; i++) { + UINT8 v = state->buffer[i] - + (state->buffer[i-bpp] + context->previous[i])/2; + context->average[i] = v; + s += (v < 128) ? v : 256 - v; + } + if (s < sum) { + context->output = context->average; + sum = s; + } + } + + /* 4. Paeth */ + if (sum > 0) { + for (i = 1, s = 0; i <= bpp; i++) { + UINT8 v = state->buffer[i] - context->previous[i]; + context->paeth[i] = v; + s += (v < 128) ? v : 256 - v; + } + for (; i <= state->bytes; i++) { + UINT8 v; + int a, b, c; + int pa, pb, pc; + + /* fetch pixels */ + a = state->buffer[i-bpp]; + b = context->previous[i]; + c = context->previous[i-bpp]; + + /* distances to surrounding pixels */ + pa = abs(b - c); + pb = abs(a - c); + pc = abs(a + b - 2*c); + + /* pick predictor with the shortest distance */ + v = state->buffer[i] - + ((pa <= pb && pa <= pc) ? a : + (pb <= pc) ? b : c); + context->paeth[i] = v; + s += (v < 128) ? v : 256 - v; + } + if (s < sum) { + context->output = context->paeth; + sum = s; + } + } + } + + /* Compress this line */ + context->z_stream.next_in = context->output; + context->z_stream.avail_in = state->bytes+1; + + err = deflate(&context->z_stream, Z_NO_FLUSH); + + if (err < 0) { + /* Something went wrong inside the compression library */ + if (err == Z_DATA_ERROR) + state->errcode = IMAGING_CODEC_BROKEN; + else if (err == Z_MEM_ERROR) + state->errcode = IMAGING_CODEC_MEMORY; + else + state->errcode = IMAGING_CODEC_CONFIG; + free(context->paeth); + free(context->average); + free(context->up); + free(context->prior); + free(context->previous); + deflateEnd(&context->z_stream); + ImagingSectionLeave(&cookie); + return -1; + } + + /* Swap buffer pointers */ + ptr = state->buffer; + state->buffer = context->previous; + context->previous = ptr; + + } + + if (context->z_stream.avail_out == 0) + break; /* Buffer full */ + + case 2: + + /* End of image data; flush compressor buffers */ + + while (context->z_stream.avail_out > 0) { + + err = deflate(&context->z_stream, Z_FINISH); + + if (err == Z_STREAM_END) { + + free(context->paeth); + free(context->average); + free(context->up); + free(context->prior); + free(context->previous); + + deflateEnd(&context->z_stream); + + state->errcode = IMAGING_CODEC_END; + + break; + } + + if (context->z_stream.avail_out == 0) + break; /* Buffer full */ + + } + + } + ImagingSectionLeave(&cookie); + return bytes - context->z_stream.avail_out; + + } + + /* Should never ever arrive here... */ + state->errcode = IMAGING_CODEC_CONFIG; + ImagingSectionLeave(&cookie); + return -1; +} + +const char* +ImagingZipVersion(void) +{ + return ZLIB_VERSION; +} + +#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/map.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/map.c new file mode 100755 index 00000000000..f15b8200f8a --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/map.c @@ -0,0 +1,379 @@ +/* + * The Python Imaging Library. + * + * standard memory mapping interface for the Imaging library + * + * history: + * 1998-03-05 fl added Win32 read mapping + * 1999-02-06 fl added "I;16" support + * 2003-04-21 fl added PyImaging_MapBuffer primitive + * + * Copyright (c) 1998-2003 by Secret Labs AB. + * Copyright (c) 2003 by Fredrik Lundh. + * + * See the README file for information on usage and redistribution. + */ + +/* + * FIXME: should move the memory mapping primitives into libImaging! + */ + +#include "Python.h" + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#include "Imaging.h" + +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#undef INT32 +#undef INT64 +#undef UINT32 +#include "windows.h" +#endif + +/* compatibility wrappers (defined in _imaging.c) */ +extern int PyImaging_CheckBuffer(PyObject* buffer); +extern int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr); + +/* -------------------------------------------------------------------- */ +/* Standard mapper */ + +typedef struct { + PyObject_HEAD + char* base; + int size; + int offset; +#ifdef WIN32 + HANDLE hFile; + HANDLE hMap; +#endif +} ImagingMapperObject; + +staticforward PyTypeObject ImagingMapperType; + +ImagingMapperObject* +PyImaging_MapperNew(const char* filename, int readonly) +{ + ImagingMapperObject *mapper; + + ImagingMapperType.ob_type = &PyType_Type; + + mapper = PyObject_New(ImagingMapperObject, &ImagingMapperType); + if (mapper == NULL) + return NULL; + + mapper->base = NULL; + mapper->size = mapper->offset = 0; + +#ifdef WIN32 + mapper->hFile = (HANDLE)-1; + mapper->hMap = (HANDLE)-1; + + /* FIXME: currently supports readonly mappings only */ + mapper->hFile = CreateFile( + filename, + GENERIC_READ, + FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (mapper->hFile == (HANDLE)-1) { + PyErr_SetString(PyExc_IOError, "cannot open file"); + PyObject_Del(mapper); + return NULL; + } + + mapper->hMap = CreateFileMapping( + mapper->hFile, NULL, + PAGE_READONLY, + 0, 0, NULL); + if (mapper->hMap == (HANDLE)-1) { + CloseHandle(mapper->hFile); + PyErr_SetString(PyExc_IOError, "cannot map file"); + PyObject_Del(mapper); + return NULL; + } + + mapper->base = (char*) MapViewOfFile( + mapper->hMap, + FILE_MAP_READ, + 0, 0, 0); + + mapper->size = GetFileSize(mapper->hFile, 0); +#endif + + return mapper; +} + +static void +mapping_dealloc(ImagingMapperObject* mapper) +{ +#ifdef WIN32 + if (mapper->base != 0) + UnmapViewOfFile(mapper->base); + if (mapper->hMap != (HANDLE)-1) + CloseHandle(mapper->hMap); + if (mapper->hFile != (HANDLE)-1) + CloseHandle(mapper->hFile); + mapper->base = 0; + mapper->hMap = mapper->hFile = (HANDLE)-1; +#endif + PyObject_Del(mapper); +} + +/* -------------------------------------------------------------------- */ +/* standard file operations */ + +static PyObject* +mapping_read(ImagingMapperObject* mapper, PyObject* args) +{ + PyObject* buf; + + int size = -1; + if (!PyArg_ParseTuple(args, "|i", &size)) + return NULL; + + /* check size */ + if (size < 0 || mapper->offset + size > mapper->size) + size = mapper->size - mapper->offset; + if (size < 0) + size = 0; + + buf = PyString_FromStringAndSize(NULL, size); + if (!buf) + return NULL; + + if (size > 0) { + memcpy(PyString_AsString(buf), mapper->base + mapper->offset, size); + mapper->offset += size; + } + + return buf; +} + +static PyObject* +mapping_seek(ImagingMapperObject* mapper, PyObject* args) +{ + int offset; + int whence = 0; + if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) + return NULL; + + switch (whence) { + case 0: /* SEEK_SET */ + mapper->offset = offset; + break; + case 1: /* SEEK_CUR */ + mapper->offset += offset; + break; + case 2: /* SEEK_END */ + mapper->offset = mapper->size + offset; + break; + default: + /* FIXME: raise ValueError? */ + break; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* -------------------------------------------------------------------- */ +/* map entire image */ + +extern PyObject*PyImagingNew(Imaging im); + +static void +ImagingDestroyMap(Imaging im) +{ + return; /* nothing to do! */ +} + +static PyObject* +mapping_readimage(ImagingMapperObject* mapper, PyObject* args) +{ + int y, size; + Imaging im; + + char* mode; + int xsize; + int ysize; + int stride; + int orientation; + if (!PyArg_ParseTuple(args, "s(ii)ii", &mode, &xsize, &ysize, + &stride, &orientation)) + return NULL; + + if (stride <= 0) { + /* FIXME: maybe we should call ImagingNewPrologue instead */ + if (!strcmp(mode, "L") || !strcmp(mode, "P")) + stride = xsize; + else if (!strcmp(mode, "I;16") || !strcmp(mode, "I;16B")) + stride = xsize * 2; + else + stride = xsize * 4; + } + + size = ysize * stride; + + if (mapper->offset + size > mapper->size) { + PyErr_SetString(PyExc_IOError, "image file truncated"); + return NULL; + } + + im = ImagingNewPrologue(mode, xsize, ysize); + if (!im) + return NULL; + + /* setup file pointers */ + if (orientation > 0) + for (y = 0; y < ysize; y++) + im->image[y] = mapper->base + mapper->offset + y * stride; + else + for (y = 0; y < ysize; y++) + im->image[ysize-y-1] = mapper->base + mapper->offset + y * stride; + + im->destroy = ImagingDestroyMap; + + if (!ImagingNewEpilogue(im)) + return NULL; + + mapper->offset += size; + + return PyImagingNew(im); +} + +static struct PyMethodDef methods[] = { + /* standard file interface */ + {"read", (PyCFunction)mapping_read, 1}, + {"seek", (PyCFunction)mapping_seek, 1}, + /* extensions */ + {"readimage", (PyCFunction)mapping_readimage, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +mapping_getattr(ImagingMapperObject* self, char* name) +{ + return Py_FindMethod(methods, (PyObject*) self, name); +} + +statichere PyTypeObject ImagingMapperType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "ImagingMapper", /*tp_name*/ + sizeof(ImagingMapperObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)mapping_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)mapping_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_hash*/ +}; + +PyObject* +PyImaging_Mapper(PyObject* self, PyObject* args) +{ + char* filename; + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + return (PyObject*) PyImaging_MapperNew(filename, 1); +} + +/* -------------------------------------------------------------------- */ +/* Buffer mapper */ + +typedef struct ImagingBufferInstance { + struct ImagingMemoryInstance im; + PyObject* target; +} ImagingBufferInstance; + +static void +mapping_destroy_buffer(Imaging im) +{ + ImagingBufferInstance* buffer = (ImagingBufferInstance*) im; + + Py_XDECREF(buffer->target); +} + +PyObject* +PyImaging_MapBuffer(PyObject* self, PyObject* args) +{ + int y, size; + Imaging im; + char* ptr; + int bytes; + + PyObject* target; + char* mode; + char* codec; + PyObject* bbox; + int offset; + int xsize, ysize; + int stride; + int ystep; + + if (!PyArg_ParseTuple(args, "O(ii)sOi(sii)", &target, &xsize, &ysize, + &codec, &bbox, &offset, &mode, &stride, &ystep)) + return NULL; + + if (!PyImaging_CheckBuffer(target)) { + PyErr_SetString(PyExc_TypeError, "expected string or buffer"); + return NULL; + } + + if (stride <= 0) { + if (!strcmp(mode, "L") || !strcmp(mode, "P")) + stride = xsize; + else if (!strncmp(mode, "I;16", 4)) + stride = xsize * 2; + else + stride = xsize * 4; + } + + size = ysize * stride; + + /* check buffer size */ + bytes = PyImaging_ReadBuffer(target, (const void**) &ptr); + if (bytes < 0) { + PyErr_SetString(PyExc_ValueError, "buffer has negative size"); + return NULL; + } + if (offset + size > bytes) { + PyErr_SetString(PyExc_ValueError, "buffer is not large enough"); + return NULL; + } + + im = ImagingNewPrologueSubtype( + mode, xsize, ysize, sizeof(ImagingBufferInstance) + ); + if (!im) + return NULL; + + /* setup file pointers */ + if (ystep > 0) + for (y = 0; y < ysize; y++) + im->image[y] = ptr + offset + y * stride; + else + for (y = 0; y < ysize; y++) + im->image[ysize-y-1] = ptr + offset + y * stride; + + im->destroy = mapping_destroy_buffer; + + Py_INCREF(target); + ((ImagingBufferInstance*) im)->target = target; + + if (!ImagingNewEpilogue(im)) + return NULL; + + return PyImagingNew(im); +} + diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c new file mode 100755 index 00000000000..6bb2ebb547c --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c @@ -0,0 +1,179 @@ +/* + * THIS IS WORK IN PROGRESS. + * + * The Python Imaging Library. + * + * "arrow" outline stuff. the contents of this module + * will be merged with the path module and the rest of + * the arrow graphics package, but not before PIL 1.1. + * use at your own risk. + * + * history: + * 99-01-10 fl Added to PIL (experimental) + * + * Copyright (c) Secret Labs AB 1999. + * Copyright (c) Fredrik Lundh 1999. + * + * See the README file for information on usage and redistribution. + */ + +#include "Python.h" + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#include "Imaging.h" + + +/* -------------------------------------------------------------------- */ +/* Class */ + +typedef struct { + PyObject_HEAD + ImagingOutline outline; +} OutlineObject; + +staticforward PyTypeObject OutlineType; + +#define PyOutline_Check(op) ((op)->ob_type == &OutlineType) + +static OutlineObject* +_outline_new(void) +{ + OutlineObject *self; + + self = PyObject_New(OutlineObject, &OutlineType); + if (self == NULL) + return NULL; + + self->outline = ImagingOutlineNew(); + + return self; +} + +static void +_outline_dealloc(OutlineObject* self) +{ + ImagingOutlineDelete(self->outline); + PyObject_Del(self); +} + +ImagingOutline +PyOutline_AsOutline(PyObject* outline) +{ + if (PyOutline_Check(outline)) + return ((OutlineObject*) outline)->outline; + + return NULL; +} + + +/* -------------------------------------------------------------------- */ +/* Factories */ + +PyObject* +PyOutline_Create(PyObject* self, PyObject* args) +{ + if (!PyArg_ParseTuple(args, ":outline")) + return NULL; + + return (PyObject*) _outline_new(); +} + + +/* -------------------------------------------------------------------- */ +/* Methods */ + +static PyObject* +_outline_move(OutlineObject* self, PyObject* args) +{ + float x0, y0; + if (!PyArg_ParseTuple(args, "ff", &x0, &y0)) + return NULL; + + ImagingOutlineMove(self->outline, x0, y0); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_outline_line(OutlineObject* self, PyObject* args) +{ + float x1, y1; + if (!PyArg_ParseTuple(args, "ff", &x1, &y1)) + return NULL; + + ImagingOutlineLine(self->outline, x1, y1); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_outline_curve(OutlineObject* self, PyObject* args) +{ + float x1, y1, x2, y2, x3, y3; + if (!PyArg_ParseTuple(args, "ffffff", &x1, &y1, &x2, &y2, &x3, &y3)) + return NULL; + + ImagingOutlineCurve(self->outline, x1, y1, x2, y2, x3, y3); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_outline_close(OutlineObject* self, PyObject* args) +{ + if (!PyArg_ParseTuple(args, ":close")) + return NULL; + + ImagingOutlineClose(self->outline); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* +_outline_transform(OutlineObject* self, PyObject* args) +{ + double a[6]; + if (!PyArg_ParseTuple(args, "(dddddd)", a+0, a+1, a+2, a+3, a+4, a+5)) + return NULL; + + ImagingOutlineTransform(self->outline, a); + + Py_INCREF(Py_None); + return Py_None; +} + +static struct PyMethodDef _outline_methods[] = { + {"line", (PyCFunction)_outline_line, 1}, + {"curve", (PyCFunction)_outline_curve, 1}, + {"move", (PyCFunction)_outline_move, 1}, + {"close", (PyCFunction)_outline_close, 1}, + {"transform", (PyCFunction)_outline_transform, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +_outline_getattr(OutlineObject* self, char* name) +{ + return Py_FindMethod(_outline_methods, (PyObject*) self, name); +} + +statichere PyTypeObject OutlineType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Outline", /*tp_name*/ + sizeof(OutlineObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)_outline_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)_outline_getattr, /*tp_getattr*/ + 0 /*tp_setattr*/ +}; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/path.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/path.c new file mode 100755 index 00000000000..f083b971d04 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/path.c @@ -0,0 +1,587 @@ +/* + * The Python Imaging Library. + * + * 2D path utilities + * + * history: + * 1996-11-04 fl Added to PIL (incomplete) + * 1996-11-05 fl Added sequence semantics + * 1997-02-28 fl Fixed getbbox + * 1997-06-12 fl Added id attribute + * 1997-06-14 fl Added slicing and setitem + * 1998-12-29 fl Improved sequence handling (from Richard Jones) + * 1999-01-10 fl Fixed IndexError test for 1.5 (from Fred Drake) + * 2000-10-12 fl Added special cases for tuples and lists + * 2002-10-27 fl Added clipping boilerplate + * 2004-09-19 fl Added tolist(flat) variant + * 2005-05-06 fl Added buffer interface support to path constructor + * + * notes: + * FIXME: fill in remaining slots in the sequence api + * + * Copyright (c) 1997-2005 by Secret Labs AB + * Copyright (c) 1997-2005 by Fredrik Lundh + * + * See the README file for information on usage and redistribution. + */ + + +#include "Python.h" + +#include + +#if PY_VERSION_HEX < 0x01060000 +#define PyObject_New PyObject_NEW +#define PyObject_Del PyMem_DEL +#endif + +#if PY_VERSION_HEX < 0x02050000 +#define Py_ssize_t int +#define lenfunc inquiry +#define ssizeargfunc intargfunc +#define ssizessizeargfunc intintargfunc +#define ssizeobjargproc intobjargproc +#define ssizessizeobjargproc intintobjargproc +#endif + +/* compatibility wrappers (defined in _imaging.c) */ +extern int PyImaging_CheckBuffer(PyObject* buffer); +extern int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr); + +/* -------------------------------------------------------------------- */ +/* Class */ +/* -------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + Py_ssize_t count; + double *xy; + int index; /* temporary use, e.g. in decimate */ +} PyPathObject; + +staticforward PyTypeObject PyPathType; + +static double* +alloc_array(int count) +{ + double* xy; + if (count < 0) { + PyErr_NoMemory(); + return NULL; + } + xy = malloc(2 * count * sizeof(double) + 1); + if (!xy) + PyErr_NoMemory(); + return xy; +} + +static PyPathObject* +path_new(Py_ssize_t count, double* xy, int duplicate) +{ + PyPathObject *path; + + if (duplicate) { + /* duplicate path */ + double* p = alloc_array(count); + if (!p) + return NULL; + memcpy(p, xy, count * 2 * sizeof(double)); + xy = p; + } + + path = PyObject_New(PyPathObject, &PyPathType); + if (path == NULL) + return NULL; + + path->count = count; + path->xy = xy; + + return path; +} + +static void +path_dealloc(PyPathObject* path) +{ + free(path->xy); + PyObject_Del(path); +} + +/* -------------------------------------------------------------------- */ +/* Helpers */ +/* -------------------------------------------------------------------- */ + +#define PyPath_Check(op) ((op)->ob_type == &PyPathType) + +int +PyPath_Flatten(PyObject* data, double **pxy) +{ + int i, j, n; + double *xy; + + if (PyPath_Check(data)) { + /* This was another path object. */ + PyPathObject *path = (PyPathObject*) data; + xy = alloc_array(path->count); + if (!xy) + return -1; + memcpy(xy, path->xy, 2 * path->count * sizeof(double)); + *pxy = xy; + return path->count; + } + + if (PyImaging_CheckBuffer(data)) { + /* Assume the buffer contains floats */ + float* ptr; + int n = PyImaging_ReadBuffer(data, (const void**) &ptr); + n /= 2 * sizeof(float); + xy = alloc_array(n); + if (!xy) + return -1; + for (i = 0; i < n+n; i++) + xy[i] = ptr[i]; + *pxy = xy; + return n; + } + + if (!PySequence_Check(data)) { + PyErr_SetString(PyExc_TypeError, "argument must be sequence"); + return -1; + } + + j = 0; + n = PyObject_Length(data); + /* Just in case __len__ breaks (or doesn't exist) */ + if (PyErr_Occurred()) + return -1; + + /* Allocate for worst case */ + xy = alloc_array(n); + if (!xy) + return -1; + + /* Copy table to path array */ + if (PyList_Check(data)) { + for (i = 0; i < n; i++) { + double x, y; + PyObject *op = PyList_GET_ITEM(data, i); + if (PyFloat_Check(op)) + xy[j++] = PyFloat_AS_DOUBLE(op); + else if (PyInt_Check(op)) + xy[j++] = (float) PyInt_AS_LONG(op); + else if (PyNumber_Check(op)) + xy[j++] = PyFloat_AsDouble(op); + else if (PyArg_ParseTuple(op, "dd", &x, &y)) { + xy[j++] = x; + xy[j++] = y; + } else { + free(xy); + return -1; + } + } + } else if (PyTuple_Check(data)) { + for (i = 0; i < n; i++) { + double x, y; + PyObject *op = PyTuple_GET_ITEM(data, i); + if (PyFloat_Check(op)) + xy[j++] = PyFloat_AS_DOUBLE(op); + else if (PyInt_Check(op)) + xy[j++] = (float) PyInt_AS_LONG(op); + else if (PyNumber_Check(op)) + xy[j++] = PyFloat_AsDouble(op); + else if (PyArg_ParseTuple(op, "dd", &x, &y)) { + xy[j++] = x; + xy[j++] = y; + } else { + free(xy); + return -1; + } + } + } else { + for (i = 0; i < n; i++) { + double x, y; + PyObject *op = PySequence_GetItem(data, i); + if (!op) { + /* treat IndexError as end of sequence */ + if (PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_IndexError)) { + PyErr_Clear(); + break; + } else { + free(xy); + return -1; + } + } + if (PyFloat_Check(op)) + xy[j++] = PyFloat_AS_DOUBLE(op); + else if (PyInt_Check(op)) + xy[j++] = (float) PyInt_AS_LONG(op); + else if (PyNumber_Check(op)) + xy[j++] = PyFloat_AsDouble(op); + else if (PyArg_ParseTuple(op, "dd", &x, &y)) { + xy[j++] = x; + xy[j++] = y; + } else { + Py_DECREF(op); + free(xy); + return -1; + } + Py_DECREF(op); + } + } + + if (j & 1) { + PyErr_SetString(PyExc_ValueError, "wrong number of coordinates"); + free(xy); + return -1; + } + + *pxy = xy; + return j/2; +} + + +/* -------------------------------------------------------------------- */ +/* Factories */ +/* -------------------------------------------------------------------- */ + +PyObject* +PyPath_Create(PyObject* self, PyObject* args) +{ + PyObject* data; + Py_ssize_t count; + double *xy; + + if (PyArg_ParseTuple(args, "i:Path", &count)) { + + /* number of vertices */ + xy = alloc_array(count); + if (!xy) + return NULL; + + } else { + + /* sequence or other path */ + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "O", &data)) + return NULL; + + count = PyPath_Flatten(data, &xy); + if (count < 0) + return NULL; + } + + return (PyObject*) path_new(count, xy, 0); +} + + +/* -------------------------------------------------------------------- */ +/* Methods */ +/* -------------------------------------------------------------------- */ + +static PyObject* +path_compact(PyPathObject* self, PyObject* args) +{ + /* Simple-minded method to shorten path. A point is removed if + the city block distance to the previous point is less than the + given distance */ + int i, j; + double *xy; + + double cityblock = 2.0; + + if (!PyArg_ParseTuple(args, "|d:compact", &cityblock)) + return NULL; + + xy = self->xy; + + /* remove bogus vertices */ + for (i = j = 1; i < self->count; i++) { + if (fabs(xy[j+j-2]-xy[i+i]) + fabs(xy[j+j-1]-xy[i+i+1]) >= cityblock) { + xy[j+j] = xy[i+i]; + xy[j+j+1] = xy[i+i+1]; + j++; + } + } + + i = self->count - j; + self->count = j; + + /* shrink coordinate array */ + self->xy = realloc(self->xy, 2 * self->count * sizeof(double)); + + return Py_BuildValue("i", i); /* number of removed vertices */ +} + +static PyObject* +path_clip_polygon(PyPathObject* self, PyObject* args) +{ + /* Clip path representing a single polygon */ + PyErr_SetString(PyExc_RuntimeError, "not yet implemented"); + return NULL; +} + +static PyObject* +path_clip_polyline(PyPathObject* self, PyObject* args) +{ + /* Clip path representing a single polyline (outline) */ + PyErr_SetString(PyExc_RuntimeError, "not yet implemented"); + return NULL; +} + +static PyObject* +path_getbbox(PyPathObject* self, PyObject* args) +{ + /* Find bounding box */ + int i; + double *xy; + double x0, y0, x1, y1; + + if (!PyArg_ParseTuple(args, ":getbbox")) + return NULL; + + xy = self->xy; + + x0 = x1 = xy[0]; + y0 = y1 = xy[1]; + + for (i = 1; i < self->count; i++) { + if (xy[i+i] < x0) + x0 = xy[i+i]; + if (xy[i+i] > x1) + x1 = xy[i+i]; + if (xy[i+i+1] < y0) + y0 = xy[i+i+1]; + if (xy[i+i+1] > y1) + y1 = xy[i+i+1]; + } + + return Py_BuildValue("dddd", x0, y0, x1, y1); +} + +static PyObject* +path_getitem(PyPathObject* self, int i) +{ + if (i < 0 || i >= self->count) { + PyErr_SetString(PyExc_IndexError, "path index out of range"); + return NULL; + } + + return Py_BuildValue("dd", self->xy[i+i], self->xy[i+i+1]); +} + +static PyObject* +path_getslice(PyPathObject* self, Py_ssize_t ilow, Py_ssize_t ihigh) +{ + /* adjust arguments */ + if (ilow < 0) + ilow = 0; + else if (ilow >= self->count) + ilow = self->count; + if (ihigh < 0) + ihigh = 0; + if (ihigh < ilow) + ihigh = ilow; + else if (ihigh > self->count) + ihigh = self->count; + + return (PyObject*) path_new(ihigh - ilow, self->xy + ilow * 2, 1); +} + +static Py_ssize_t +path_len(PyPathObject* self) +{ + return self->count; +} + +static PyObject* +path_map(PyPathObject* self, PyObject* args) +{ + /* Map coordinate set through function */ + int i; + double *xy; + PyObject* function; + + if (!PyArg_ParseTuple(args, "O:map", &function)) + return NULL; + + xy = self->xy; + + /* apply function to coordinate set */ + for (i = 0; i < self->count; i++) { + double x = xy[i+i]; + double y = xy[i+i+1]; + PyObject* item = PyObject_CallFunction(function, "dd", x, y); + if (!item || !PyArg_ParseTuple(item, "dd", &x, &y)) { + Py_XDECREF(item); + return NULL; + } + xy[i+i] = x; + xy[i+i+1] = y; + Py_DECREF(item); + } + + Py_INCREF(Py_None); + return Py_None; +} + +static int +path_setitem(PyPathObject* self, int i, PyObject* op) +{ + double* xy; + + if (i < 0 || i >= self->count) { + PyErr_SetString(PyExc_IndexError, + "path assignment index out of range"); + return -1; + } + + if (op == NULL) { + PyErr_SetString(PyExc_TypeError, + "cannot delete from path"); + return -1; + } + + xy = &self->xy[i+i]; + + if (!PyArg_ParseTuple(op, "dd", &xy[0], &xy[1])) + return -1; + + return 0; +} + +static PyObject* +path_tolist(PyPathObject* self, PyObject* args) +{ + PyObject *list; + int i; + + int flat = 0; + if (!PyArg_ParseTuple(args, "|i:tolist", &flat)) + return NULL; + + if (flat) { + list = PyList_New(self->count*2); + for (i = 0; i < self->count*2; i++) { + PyObject* item; + item = PyFloat_FromDouble(self->xy[i]); + if (!item) + goto error; + PyList_SetItem(list, i, item); + } + } else { + list = PyList_New(self->count); + for (i = 0; i < self->count; i++) { + PyObject* item; + item = Py_BuildValue("dd", self->xy[i+i], self->xy[i+i+1]); + if (!item) + goto error; + PyList_SetItem(list, i, item); + } + } + + return list; + +error: + Py_DECREF(list); + return NULL; +} + +static PyObject* +path_transform(PyPathObject* self, PyObject* args) +{ + /* Apply affine transform to coordinate set */ + int i; + double *xy; + double a, b, c, d, e, f; + + double wrap = 0.0; + + if (!PyArg_ParseTuple(args, "(dddddd)|d:transform", + &a, &b, &c, &d, &e, &f, + &wrap)) + return NULL; + + xy = self->xy; + + /* transform the coordinate set */ + if (b == 0.0 && d == 0.0) + /* scaling */ + for (i = 0; i < self->count; i++) { + xy[i+i] = a*xy[i+i]+c; + xy[i+i+1] = e*xy[i+i+1]+f; + } + else + /* affine transform */ + for (i = 0; i < self->count; i++) { + double x = xy[i+i]; + double y = xy[i+i+1]; + xy[i+i] = a*x+b*y+c; + xy[i+i+1] = d*x+e*y+f; + } + + /* special treatment of geographical map data */ + if (wrap != 0.0) + for (i = 0; i < self->count; i++) + xy[i+i] = fmod(xy[i+i], wrap); + + Py_INCREF(Py_None); + return Py_None; +} + +static struct PyMethodDef methods[] = { + {"getbbox", (PyCFunction)path_getbbox, 1}, + {"tolist", (PyCFunction)path_tolist, 1}, + {"clip_polygon", (PyCFunction)path_clip_polygon, 1}, + {"clip_polyline", (PyCFunction)path_clip_polyline, 1}, + {"compact", (PyCFunction)path_compact, 1}, + {"map", (PyCFunction)path_map, 1}, + {"transform", (PyCFunction)path_transform, 1}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject* +path_getattr(PyPathObject* self, char* name) +{ + PyObject* res; + + res = Py_FindMethod(methods, (PyObject*) self, name); + if (res) + return res; + + PyErr_Clear(); + + if (strcmp(name, "id") == 0) + return Py_BuildValue("l", (long) self->xy); + + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +static PySequenceMethods path_as_sequence = { + (lenfunc)path_len, /*sq_length*/ + (binaryfunc)0, /*sq_concat*/ + (ssizeargfunc)0, /*sq_repeat*/ + (ssizeargfunc)path_getitem, /*sq_item*/ + (ssizessizeargfunc)path_getslice, /*sq_slice*/ + (ssizeobjargproc)path_setitem, /*sq_ass_item*/ + (ssizessizeobjargproc)0, /*sq_ass_slice*/ +}; + +statichere PyTypeObject PyPathType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "Path", /*tp_name*/ + sizeof(PyPathObject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)path_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)path_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + &path_as_sequence, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ +}; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py new file mode 100755 index 00000000000..22bbe433bf6 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py @@ -0,0 +1,202 @@ +# minimal sanity check + +ROOT = "." + +import os, sys +sys.path.insert(0, ROOT) + +from PIL import Image +from PIL import ImageDraw +from PIL import ImageFilter +from PIL import ImageMath + +try: + Image.core.ping +except ImportError, v: + print "***", v + sys.exit() +except AttributeError: + pass + +def _info(im): + im.load() + return im.format, im.mode, im.size + +def testimage(): + """ + PIL lets you create in-memory images with various pixel types: + + >>> im = Image.new("1", (128, 128)) # monochrome + >>> _info(im) + (None, '1', (128, 128)) + >>> _info(Image.new("L", (128, 128))) # grayscale (luminance) + (None, 'L', (128, 128)) + >>> _info(Image.new("P", (128, 128))) # palette + (None, 'P', (128, 128)) + >>> _info(Image.new("RGB", (128, 128))) # truecolor + (None, 'RGB', (128, 128)) + >>> _info(Image.new("I", (128, 128))) # 32-bit integer + (None, 'I', (128, 128)) + >>> _info(Image.new("F", (128, 128))) # 32-bit floating point + (None, 'F', (128, 128)) + + Or open existing files: + + >>> im = Image.open(os.path.join(ROOT, "Images/lena.gif")) + >>> _info(im) + ('GIF', 'P', (128, 128)) + >>> _info(Image.open(os.path.join(ROOT, "Images/lena.ppm"))) + ('PPM', 'RGB', (128, 128)) + >>> try: + ... _info(Image.open(os.path.join(ROOT, "Images/lena.jpg"))) + ... except IOError, v: + ... print v + ('JPEG', 'RGB', (128, 128)) + + PIL doesn't actually load the image data until it's needed, + or you call the "load" method: + + >>> im = Image.open(os.path.join(ROOT, "Images/lena.ppm")) + >>> print im.im # internal image attribute + None + >>> a = im.load() + >>> type(im.im) + + + You can apply many different operations on images. Most + operations return a new image: + + >>> im = Image.open(os.path.join(ROOT, "Images/lena.ppm")) + >>> _info(im.convert("L")) + (None, 'L', (128, 128)) + >>> _info(im.copy()) + (None, 'RGB', (128, 128)) + >>> _info(im.crop((32, 32, 96, 96))) + (None, 'RGB', (64, 64)) + >>> _info(im.filter(ImageFilter.BLUR)) + (None, 'RGB', (128, 128)) + >>> im.getbands() + ('R', 'G', 'B') + >>> im.getbbox() + (0, 0, 128, 128) + >>> len(im.getdata()) + 16384 + >>> im.getextrema() + ((61, 255), (26, 234), (44, 223)) + >>> im.getpixel((0, 0)) + (223, 162, 133) + >>> len(im.getprojection()) + 2 + >>> len(im.histogram()) + 768 + >>> _info(im.point(range(256)*3)) + (None, 'RGB', (128, 128)) + >>> _info(im.resize((64, 64))) + (None, 'RGB', (64, 64)) + >>> _info(im.rotate(45)) + (None, 'RGB', (128, 128)) + >>> map(_info, im.split()) + [(None, 'L', (128, 128)), (None, 'L', (128, 128)), (None, 'L', (128, 128))] + >>> len(im.convert("1").tobitmap()) + 10456 + >>> len(im.tostring()) + 49152 + >>> _info(im.transform((512, 512), Image.AFFINE, (1,0,0,0,1,0))) + (None, 'RGB', (512, 512)) + >>> _info(im.transform((512, 512), Image.EXTENT, (32,32,96,96))) + (None, 'RGB', (512, 512)) + + The ImageDraw module lets you draw stuff in raster images: + + >>> im = Image.new("L", (128, 128), 64) + >>> d = ImageDraw.ImageDraw(im) + >>> d.line((0, 0, 128, 128), fill=128) + >>> d.line((0, 128, 128, 0), fill=128) + >>> im.getextrema() + (64, 128) + + In 1.1.4, you can specify colors in a number of ways: + + >>> xy = 0, 0, 128, 128 + >>> im = Image.new("RGB", (128, 128), 0) + >>> d = ImageDraw.ImageDraw(im) + >>> d.rectangle(xy, "#f00") + >>> im.getpixel((0, 0)) + (255, 0, 0) + >>> d.rectangle(xy, "#ff0000") + >>> im.getpixel((0, 0)) + (255, 0, 0) + >>> d.rectangle(xy, "rgb(255,0,0)") + >>> im.getpixel((0, 0)) + (255, 0, 0) + >>> d.rectangle(xy, "rgb(100%,0%,0%)") + >>> im.getpixel((0, 0)) + (255, 0, 0) + >>> d.rectangle(xy, "hsl(0, 100%, 50%)") + >>> im.getpixel((0, 0)) + (255, 0, 0) + >>> d.rectangle(xy, "red") + >>> im.getpixel((0, 0)) + (255, 0, 0) + + In 1.1.6, you can use the ImageMath module to do image + calculations. + + >>> im = ImageMath.eval("float(im + 20)", im=im.convert("L")) + >>> im.mode, im.size + ('F', (128, 128)) + + PIL can do many other things, but I'll leave that for another + day. If you're curious, check the handbook, available from: + + http://www.pythonware.com + + Cheers /F + """ + + +def check_module(feature, module): + try: + __import__("PIL." + module) + except ImportError: + print "***", feature, "support not installed" + else: + print "---", feature, "support ok" + +def check_codec(feature, codec): + if codec + "_encoder" not in dir(Image.core): + print "***", feature, "support not installed" + else: + print "---", feature, "support ok" + + +if __name__ == "__main__": + # check build sanity + + exit_status = 0 + + print "-"*68 + print "PIL", Image.VERSION, "TEST SUMMARY " + print "-"*68 + print "Python modules loaded from", os.path.dirname(Image.__file__) + print "Binary modules loaded from", os.path.dirname(Image.core.__file__) + print "-"*68 + check_module("PIL CORE", "_imaging") + check_module("TKINTER", "_imagingtk") + check_codec("JPEG", "jpeg") + check_codec("ZLIB (PNG/ZIP)", "zip") + check_module("FREETYPE2", "_imagingft") + check_module("LITTLECMS", "_imagingcms") + print "-"*68 + + # use doctest to make sure the test program behaves as documented! + import doctest, selftest + print "Running selftest:" + status = doctest.testmod(selftest) + if status[0]: + print "*** %s tests of %d failed." % status + exit_status = 1 + else: + print "--- %s tests passed." % status[1] + + sys.exit(exit_status) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py new file mode 100755 index 00000000000..a76954e0313 --- /dev/null +++ b/tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py @@ -0,0 +1,487 @@ +#!/usr/bin/env python +# +# Setup script for PIL 1.1.5 and later +# +# Usage: python setup.py install +# + +import glob, os, re, struct, string, sys + +# make it possible to run the setup script from another directory +try: + os.chdir(os.path.dirname(sys.argv[0])) +except OSError: + pass + +def libinclude(root): + # map root to (root/lib, root/include) + return os.path.join(root, "lib"), os.path.join(root, "include") + +# -------------------------------------------------------------------- +# Library pointers. +# +# Use None to look for the libraries in well-known library locations. +# Use a string to specify a single directory, for both the library and +# the include files. Use a tuple to specify separate directories: +# (libpath, includepath). Examples: +# +# JPEG_ROOT = "/home/libraries/jpeg-6b" +# TIFF_ROOT = "/opt/tiff/lib", "/opt/tiff/include" +# +# If you have "lib" and "include" directories under a common parent, +# you can use the "libinclude" helper: +# +# TIFF_ROOT = libinclude("/opt/tiff") + +TCL_ROOT = None +JPEG_ROOT = None +ZLIB_ROOT = libinclude(os.path.abspath("../zlib")) +TIFF_ROOT = None +FREETYPE_ROOT = None +LCMS_ROOT = None + +# FIXME: add mechanism to explicitly *disable* the use of a library + +# -------------------------------------------------------------------- +# Identification + +NAME = "PIL" +DESCRIPTION = "Python Imaging Library" +AUTHOR = "Secret Labs AB (PythonWare)", "info@pythonware.com" +HOMEPAGE = "http://www.pythonware.com/products/pil" +DOWNLOAD_URL = "http://effbot.org/downloads/%s-%s.tar.gz" # name, version + +# -------------------------------------------------------------------- +# Core library + +IMAGING = [ + "decode", "encode", "map", "display", "outline", "path", + ] + +LIBIMAGING = [ + "Access", "Antialias", "Bands", "BitDecode", "Blend", "Chops", + "Convert", "ConvertYCbCr", "Copy", "Crc32", "Crop", "Dib", "Draw", + "Effects", "EpsEncode", "File", "Fill", "Filter", "FliDecode", + "Geometry", "GetBBox", "GifDecode", "GifEncode", "HexDecode", + "Histo", "JpegDecode", "JpegEncode", "LzwDecode", "Matrix", + "ModeFilter", "MspDecode", "Negative", "Offset", "Pack", + "PackDecode", "Palette", "Paste", "Quant", "QuantHash", + "QuantHeap", "PcdDecode", "PcxDecode", "PcxEncode", "Point", + "RankFilter", "RawDecode", "RawEncode", "Storage", "SunRleDecode", + "TgaRleDecode", "Unpack", "UnpackYCC", "UnsharpMask", "XbmDecode", + "XbmEncode", "ZipDecode", "ZipEncode" + ] + +# -------------------------------------------------------------------- +# Override settings + +try: + from setup_site import * +except ImportError: + pass + +# -------------------------------------------------------------------- + +from distutils import sysconfig +from distutils.core import Extension, setup +from distutils.command.build_ext import build_ext + +try: + import _tkinter +except ImportError: + _tkinter = None + +def add_directory(path, dir, where=None): + if dir and os.path.isdir(dir) and dir not in path: + if where is None: + path.append(dir) + else: + path.insert(where, dir) + +def find_include_file(self, include): + for directory in self.compiler.include_dirs: + if os.path.isfile(os.path.join(directory, include)): + return 1 + return 0 + +def find_library_file(self, library): + return self.compiler.find_library_file(self.compiler.library_dirs, library) + +def find_version(filename): + for line in open(filename).readlines(): + m = re.search("VERSION\s*=\s*\"([^\"]+)\"", line) + if m: + return m.group(1) + return None + +VERSION = find_version("PIL/Image.py") + +class pil_build_ext(build_ext): + + def build_extensions(self): + + global TCL_ROOT + + library_dirs = [] + include_dirs = [] + + add_directory(include_dirs, "libImaging") + + # + # add platform directories + + if sys.platform == "cygwin": + # pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory + add_directory(library_dirs, os.path.join( + "/usr/lib", "python%s" % sys.version[:3], "config" + )) + + elif sys.platform == "darwin": + # attempt to make sure we pick freetype2 over other versions + add_directory(include_dirs, "/sw/include/freetype2") + add_directory(include_dirs, "/sw/lib/freetype2/include") + # fink installation directories + add_directory(library_dirs, "/sw/lib") + add_directory(include_dirs, "/sw/include") + # darwin ports installation directories + add_directory(library_dirs, "/opt/local/lib") + add_directory(include_dirs, "/opt/local/include") + + add_directory(library_dirs, "/usr/local/lib") + # FIXME: check /opt/stuff directories here? + + prefix = sysconfig.get_config_var("prefix") + if prefix: + add_directory(library_dirs, os.path.join(prefix, "lib")) + add_directory(include_dirs, os.path.join(prefix, "include")) + + # + # locate tkinter libraries + + if _tkinter: + TCL_VERSION = _tkinter.TCL_VERSION[:3] + + if _tkinter and not TCL_ROOT: + # we have Tkinter but the TCL_ROOT variable was not set; + # try to locate appropriate Tcl/Tk libraries + PYVERSION = sys.version[0] + sys.version[2] + TCLVERSION = TCL_VERSION[0] + TCL_VERSION[2] + roots = [ + # common installation directories, mostly for Windows + # (for Unix-style platforms, we'll check in well-known + # locations later) + os.path.join("/py" + PYVERSION, "Tcl"), + os.path.join("/python" + PYVERSION, "Tcl"), + "/Tcl", "/Tcl" + TCLVERSION, "/Tcl" + TCL_VERSION, + os.path.join(os.environ.get("ProgramFiles", ""), "Tcl"), + ] + for TCL_ROOT in roots: + TCL_ROOT = os.path.abspath(TCL_ROOT) + if os.path.isfile(os.path.join(TCL_ROOT, "include", "tk.h")): + # FIXME: use distutils logging (?) + print "--- using Tcl/Tk libraries at", TCL_ROOT + print "--- using Tcl/Tk version", TCL_VERSION + TCL_ROOT = libinclude(TCL_ROOT) + break + else: + TCL_ROOT = None + + # + # add configured kits + + for root in (TCL_ROOT, JPEG_ROOT, TCL_ROOT, TIFF_ROOT, ZLIB_ROOT, + FREETYPE_ROOT, LCMS_ROOT): + if isinstance(root, type(())): + lib_root, include_root = root + else: + lib_root = include_root = root + add_directory(library_dirs, lib_root) + add_directory(include_dirs, include_root) + + # + # add standard directories + + # look for tcl specific subdirectory (e.g debian) + if _tkinter: + tcl_dir = "/usr/include/tcl" + TCL_VERSION + if os.path.isfile(os.path.join(tcl_dir, "tk.h")): + add_directory(include_dirs, tcl_dir) + + # standard locations + add_directory(library_dirs, "/usr/local/lib") + add_directory(include_dirs, "/usr/local/include") + + add_directory(library_dirs, "/usr/lib") + add_directory(include_dirs, "/usr/include") + + # + # insert new dirs *before* default libs, to avoid conflicts + # between Python PYD stub libs and real libraries + + self.compiler.library_dirs = library_dirs + self.compiler.library_dirs + self.compiler.include_dirs = include_dirs + self.compiler.include_dirs + + # + # look for available libraries + + class feature: + zlib = jpeg = tiff = freetype = tcl = tk = lcms = None + feature = feature() + + if find_include_file(self, "zlib.h"): + if find_library_file(self, "z"): + feature.zlib = "z" + elif sys.platform == "win32" and find_library_file(self, "zdll"): + feature.zlib = "zdll" # alternative name + + if find_include_file(self, "jpeglib.h"): + if find_library_file(self, "jpeg"): + feature.jpeg = "jpeg" + elif sys.platform == "win32" and find_library_file(self, "libjpeg"): + feature.jpeg = "libjpeg" # alternative name + + if find_library_file(self, "tiff"): + feature.tiff = "tiff" + + if find_library_file(self, "freetype"): + # look for freetype2 include files + freetype_version = 0 + for dir in self.compiler.include_dirs: + if os.path.isfile(os.path.join(dir, "ft2build.h")): + freetype_version = 21 + dir = os.path.join(dir, "freetype2") + break + dir = os.path.join(dir, "freetype2") + if os.path.isfile(os.path.join(dir, "ft2build.h")): + freetype_version = 21 + break + if os.path.isdir(os.path.join(dir, "freetype")): + freetype_version = 20 + break + if freetype_version: + feature.freetype = "freetype" + feature.freetype_version = freetype_version + if dir: + add_directory(self.compiler.include_dirs, dir, 0) + + if find_include_file(self, "lcms.h"): + if find_library_file(self, "lcms"): + feature.lcms = "lcms" + + if _tkinter and find_include_file(self, "tk.h"): + # the library names may vary somewhat (e.g. tcl84 or tcl8.4) + version = TCL_VERSION[0] + TCL_VERSION[2] + if find_library_file(self, "tcl" + version): + feature.tcl = "tcl" + version + elif find_library_file(self, "tcl" + TCL_VERSION): + feature.tcl = "tcl" + TCL_VERSION + if find_library_file(self, "tk" + version): + feature.tk = "tk" + version + elif find_library_file(self, "tk" + TCL_VERSION): + feature.tk = "tk" + TCL_VERSION + + # + # core library + + files = ["_imaging.c"] + for file in IMAGING: + files.append(file + ".c") + for file in LIBIMAGING: + files.append(os.path.join("libImaging", file + ".c")) + + libs = [] + defs = [] + if feature.jpeg: + libs.append(feature.jpeg) + defs.append(("HAVE_LIBJPEG", None)) + if feature.zlib: + libs.append(feature.zlib) + defs.append(("HAVE_LIBZ", None)) + if sys.platform == "win32": + libs.extend(["kernel32", "user32", "gdi32"]) + if struct.unpack("h", "\0\1")[0] == 1: + defs.append(("WORDS_BIGENDIAN", None)) + + exts = [(Extension( + "_imaging", files, libraries=libs, define_macros=defs + ))] + + # + # additional libraries + + if feature.freetype: + defs = [] + if feature.freetype_version == 20: + defs.append(("USE_FREETYPE_2_0", None)) + exts.append(Extension( + "_imagingft", ["_imagingft.c"], libraries=["freetype"], + define_macros=defs + )) + + if os.path.isfile("_imagingtiff.c") and feature.tiff: + exts.append(Extension( + "_imagingtiff", ["_imagingtiff.c"], libraries=["tiff"] + )) + + if os.path.isfile("_imagingcms.c") and feature.lcms: + extra = [] + if sys.platform == "win32": + extra.extend(["user32", "gdi32"]) + exts.append(Extension( + "_imagingcms", ["_imagingcms.c"], libraries=["lcms"] + extra + )) + + if sys.platform == "darwin": + # locate Tcl/Tk frameworks + frameworks = [] + framework_roots = [ + "/Library/Frameworks", + "/System/Library/Frameworks" + ] + for root in framework_roots: + if (os.path.exists(os.path.join(root, "Tcl.framework")) and + os.path.exists(os.path.join(root, "Tk.framework"))): + print "--- using frameworks at", root + frameworks = ["-framework", "Tcl", "-framework", "Tk"] + dir = os.path.join(root, "Tcl.framework", "Headers") + add_directory(self.compiler.include_dirs, dir, 0) + dir = os.path.join(root, "Tk.framework", "Headers") + add_directory(self.compiler.include_dirs, dir, 1) + break + if frameworks: + exts.append(Extension( + "_imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"], + extra_compile_args=frameworks, extra_link_args=frameworks + )) + feature.tcl = feature.tk = 1 # mark as present + elif feature.tcl and feature.tk: + exts.append(Extension( + "_imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"], + libraries=[feature.tcl, feature.tk] + )) + + if os.path.isfile("_imagingmath.c"): + exts.append(Extension("_imagingmath", ["_imagingmath.c"])) + + self.extensions[:] = exts + + build_ext.build_extensions(self) + + # + # sanity and security checks + + unsafe_zlib = None + + if feature.zlib: + unsafe_zlib = self.check_zlib_version(self.compiler.include_dirs) + + self.summary_report(feature, unsafe_zlib) + + def summary_report(self, feature, unsafe_zlib): + + print "-" * 68 + print "PIL", VERSION, "SETUP SUMMARY" + print "-" * 68 + print "version ", VERSION + v = string.split(sys.version, "[") + print "platform ", sys.platform, string.strip(v[0]) + for v in v[1:]: + print " ", string.strip("[" + v) + print "-" * 68 + + options = [ + (feature.tcl and feature.tk, "TKINTER"), + (feature.jpeg, "JPEG"), + (feature.zlib, "ZLIB (PNG/ZIP)"), + # (feature.tiff, "experimental TIFF G3/G4 read"), + (feature.freetype, "FREETYPE2"), + (feature.lcms, "LITTLECMS"), + ] + + all = 1 + for option in options: + if option[0]: + print "---", option[1], "support available" + else: + print "***", option[1], "support not available", + if option[1] == "TKINTER" and _tkinter: + version = _tkinter.TCL_VERSION + print "(Tcl/Tk %s libraries needed)" % version, + print + all = 0 + + if feature.zlib and unsafe_zlib: + print + print "*** Warning: zlib", unsafe_zlib, + print "may contain a security vulnerability." + print "*** Consider upgrading to zlib 1.2.3 or newer." + print "*** See: http://www.kb.cert.org/vuls/id/238678" + print " http://www.kb.cert.org/vuls/id/680620" + print " http://www.gzip.org/zlib/advisory-2002-03-11.txt" + print + + print "-" * 68 + + if not all: + print "To add a missing option, make sure you have the required" + print "library, and set the corresponding ROOT variable in the" + print "setup.py script." + print + + print "To check the build, run the selftest.py script." + + def check_zlib_version(self, include_dirs): + # look for unsafe versions of zlib + for dir in include_dirs: + zlibfile = os.path.join(dir, "zlib.h") + if os.path.isfile(zlibfile): + break + else: + return + for line in open(zlibfile).readlines(): + m = re.match('#define\s+ZLIB_VERSION\s+"([^"]*)"', line) + if not m: + continue + if m.group(1) < "1.2.3": + return m.group(1) + +# +# build! + +if __name__ == "__main__": + + try: + # add necessary to distutils (for backwards compatibility) + from distutils.dist import DistributionMetadata + DistributionMetadata.classifiers = None + DistributionMetadata.download_url = None + DistributionMetadata.platforms = None + except: + pass + + setup( + author=AUTHOR[0], author_email=AUTHOR[1], + classifiers=[ + "Development Status :: 6 - Mature", + "Topic :: Multimedia :: Graphics", + "Topic :: Multimedia :: Graphics :: Capture :: Digital Camera", + "Topic :: Multimedia :: Graphics :: Capture :: Scanners", + "Topic :: Multimedia :: Graphics :: Capture :: Screen Capture", + "Topic :: Multimedia :: Graphics :: Graphics Conversion", + "Topic :: Multimedia :: Graphics :: Viewers", + ], + cmdclass = {"build_ext": pil_build_ext}, + description=DESCRIPTION, + download_url=DOWNLOAD_URL % (NAME, VERSION), + ext_modules = [Extension("_imaging", ["_imaging.c"])], # dummy + extra_path = "PIL", + license="Python (MIT style)", + long_description=DESCRIPTION, + name=NAME, + package_dir={"": "PIL"}, + packages=[""], + platforms="Python 1.5.2 and later.", + scripts = glob.glob("Scripts/pil*.py"), + url=HOMEPAGE, + version=VERSION, + ) diff --git a/tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt b/tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt new file mode 100755 index 00000000000..12c009018c3 --- /dev/null +++ b/tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt @@ -0,0 +1,397 @@ + + Frequently Asked Questions about ZLIB1.DLL + + +This document describes the design, the rationale, and the usage +of the official DLL build of zlib, named ZLIB1.DLL. If you have +general questions about zlib, you should see the file "FAQ" found +in the zlib distribution, or at the following location: + http://www.gzip.org/zlib/zlib_faq.html + + + 1. What is ZLIB1.DLL, and how can I get it? + + - ZLIB1.DLL is the official build of zlib as a DLL. + (Please remark the character '1' in the name.) + + Pointers to a precompiled ZLIB1.DLL can be found in the zlib + web site at: + http://www.zlib.net/ + + Applications that link to ZLIB1.DLL can rely on the following + specification: + + * The exported symbols are exclusively defined in the source + files "zlib.h" and "zlib.def", found in an official zlib + source distribution. + * The symbols are exported by name, not by ordinal. + * The exported names are undecorated. + * The calling convention of functions is "C" (CDECL). + * The ZLIB1.DLL binary is linked to MSVCRT.DLL. + + The archive in which ZLIB1.DLL is bundled contains compiled + test programs that must run with a valid build of ZLIB1.DLL. + It is recommended to download the prebuilt DLL from the zlib + web site, instead of building it yourself, to avoid potential + incompatibilities that could be introduced by your compiler + and build settings. If you do build the DLL yourself, please + make sure that it complies with all the above requirements, + and it runs with the precompiled test programs, bundled with + the original ZLIB1.DLL distribution. + + If, for any reason, you need to build an incompatible DLL, + please use a different file name. + + + 2. Why did you change the name of the DLL to ZLIB1.DLL? + What happened to the old ZLIB.DLL? + + - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required + compilation settings that were incompatible to those used by + a static build. The DLL settings were supposed to be enabled + by defining the macro ZLIB_DLL, before including "zlib.h". + Incorrect handling of this macro was silently accepted at + build time, resulting in two major problems: + + * ZLIB_DLL was missing from the old makefile. When building + the DLL, not all people added it to the build options. In + consequence, incompatible incarnations of ZLIB.DLL started + to circulate around the net. + + * When switching from using the static library to using the + DLL, applications had to define the ZLIB_DLL macro and + to recompile all the sources that contained calls to zlib + functions. Failure to do so resulted in creating binaries + that were unable to run with the official ZLIB.DLL build. + + The only possible solution that we could foresee was to make + a binary-incompatible change in the DLL interface, in order to + remove the dependency on the ZLIB_DLL macro, and to release + the new DLL under a different name. + + We chose the name ZLIB1.DLL, where '1' indicates the major + zlib version number. We hope that we will not have to break + the binary compatibility again, at least not as long as the + zlib-1.x series will last. + + There is still a ZLIB_DLL macro, that can trigger a more + efficient build and use of the DLL, but compatibility no + longer dependents on it. + + + 3. Can I build ZLIB.DLL from the new zlib sources, and replace + an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? + + - In principle, you can do it by assigning calling convention + keywords to the macros ZEXPORT and ZEXPORTVA. In practice, + it depends on what you mean by "an old ZLIB.DLL", because the + old DLL exists in several mutually-incompatible versions. + You have to find out first what kind of calling convention is + being used in your particular ZLIB.DLL build, and to use the + same one in the new build. If you don't know what this is all + about, you might be better off if you would just leave the old + DLL intact. + + + 4. Can I compile my application using the new zlib interface, and + link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or + earlier? + + - The official answer is "no"; the real answer depends again on + what kind of ZLIB.DLL you have. Even if you are lucky, this + course of action is unreliable. + + If you rebuild your application and you intend to use a newer + version of zlib (post- 1.1.4), it is strongly recommended to + link it to the new ZLIB1.DLL. + + + 5. Why are the zlib symbols exported by name, and not by ordinal? + + - Although exporting symbols by ordinal is a little faster, it + is risky. Any single glitch in the maintenance or use of the + DEF file that contains the ordinals can result in incompatible + builds and frustrating crashes. Simply put, the benefits of + exporting symbols by ordinal do not justify the risks. + + Technically, it should be possible to maintain ordinals in + the DEF file, and still export the symbols by name. Ordinals + exist in every DLL, and even if the dynamic linking performed + at the DLL startup is searching for names, ordinals serve as + hints, for a faster name lookup. However, if the DEF file + contains ordinals, the Microsoft linker automatically builds + an implib that will cause the executables linked to it to use + those ordinals, and not the names. It is interesting to + notice that the GNU linker for Win32 does not suffer from this + problem. + + It is possible to avoid the DEF file if the exported symbols + are accompanied by a "__declspec(dllexport)" attribute in the + source files. You can do this in zlib by predefining the + ZLIB_DLL macro. + + + 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling + convention. Why not use the STDCALL convention? + STDCALL is the standard convention in Win32, and I need it in + my Visual Basic project! + + (For readability, we use CDECL to refer to the convention + triggered by the "__cdecl" keyword, STDCALL to refer to + the convention triggered by "__stdcall", and FASTCALL to + refer to the convention triggered by "__fastcall".) + + - Most of the native Windows API functions (without varargs) use + indeed the WINAPI convention (which translates to STDCALL in + Win32), but the standard C functions use CDECL. If a user + application is intrinsically tied to the Windows API (e.g. + it calls native Windows API functions such as CreateFile()), + sometimes it makes sense to decorate its own functions with + WINAPI. But if ANSI C or POSIX portability is a goal (e.g. + it calls standard C functions such as fopen()), it is not a + sound decision to request the inclusion of , or to + use non-ANSI constructs, for the sole purpose to make the user + functions STDCALL-able. + + The functionality offered by zlib is not in the category of + "Windows functionality", but is more like "C functionality". + + Technically, STDCALL is not bad; in fact, it is slightly + faster than CDECL, and it works with variable-argument + functions, just like CDECL. It is unfortunate that, in spite + of using STDCALL in the Windows API, it is not the default + convention used by the C compilers that run under Windows. + The roots of the problem reside deep inside the unsafety of + the K&R-style function prototypes, where the argument types + are not specified; but that is another story for another day. + + The remaining fact is that CDECL is the default convention. + Even if an explicit convention is hard-coded into the function + prototypes inside C headers, problems may appear. The + necessity to expose the convention in users' callbacks is one + of these problems. + + The calling convention issues are also important when using + zlib in other programming languages. Some of them, like Ada + (GNAT) and Fortran (GNU G77), have C bindings implemented + initially on Unix, and relying on the C calling convention. + On the other hand, the pre- .NET versions of Microsoft Visual + Basic require STDCALL, while Borland Delphi prefers, although + it does not require, FASTCALL. + + In fairness to all possible uses of zlib outside the C + programming language, we choose the default "C" convention. + Anyone interested in different bindings or conventions is + encouraged to maintain specialized projects. The "contrib/" + directory from the zlib distribution already holds a couple + of foreign bindings, such as Ada, C++, and Delphi. + + + 7. I need a DLL for my Visual Basic project. What can I do? + + - Define the ZLIB_WINAPI macro before including "zlib.h", when + building both the DLL and the user application (except that + you don't need to define anything when using the DLL in Visual + Basic). The ZLIB_WINAPI macro will switch on the WINAPI + (STDCALL) convention. The name of this DLL must be different + than the official ZLIB1.DLL. + + Gilles Vollant has contributed a build named ZLIBWAPI.DLL, + with the ZLIB_WINAPI macro turned on, and with the minizip + functionality built in. For more information, please read + the notes inside "contrib/vstudio/readme.txt", found in the + zlib distribution. + + + 8. I need to use zlib in my Microsoft .NET project. What can I + do? + + - Henrik Ravn has contributed a .NET wrapper around zlib. Look + into contrib/dotzlib/, inside the zlib distribution. + + + 9. If my application uses ZLIB1.DLL, should I link it to + MSVCRT.DLL? Why? + + - It is not required, but it is recommended to link your + application to MSVCRT.DLL, if it uses ZLIB1.DLL. + + The executables (.EXE, .DLL, etc.) that are involved in the + same process and are using the C run-time library (i.e. they + are calling standard C functions), must link to the same + library. There are several libraries in the Win32 system: + CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. + Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that + depend on it should also be linked to MSVCRT.DLL. + + +10. Why are you saying that ZLIB1.DLL and my application should + be linked to the same C run-time (CRT) library? I linked my + application and my DLLs to different C libraries (e.g. my + application to a static library, and my DLLs to MSVCRT.DLL), + and everything works fine. + + - If a user library invokes only pure Win32 API (accessible via + and the related headers), its DLL build will work + in any context. But if this library invokes standard C API, + things get more complicated. + + There is a single Win32 library in a Win32 system. Every + function in this library resides in a single DLL module, that + is safe to call from anywhere. On the other hand, there are + multiple versions of the C library, and each of them has its + own separate internal state. Standalone executables and user + DLLs that call standard C functions must link to a C run-time + (CRT) library, be it static or shared (DLL). Intermixing + occurs when an executable (not necessarily standalone) and a + DLL are linked to different CRTs, and both are running in the + same process. + + Intermixing multiple CRTs is possible, as long as their + internal states are kept intact. The Microsoft Knowledge Base + articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 + "HOWTO: Link with the Correct C Run-Time (CRT) Library" + mention the potential problems raised by intermixing. + + If intermixing works for you, it's because your application + and DLLs are avoiding the corruption of each of the CRTs' + internal states, maybe by careful design, or maybe by fortune. + + Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such + as those provided by Borland, raises similar problems. + + +11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? + + - MSVCRT.DLL exists on every Windows 95 with a new service pack + installed, or with Microsoft Internet Explorer 4 or later, and + on all other Windows 4.x or later (Windows 98, Windows NT 4, + or later). It is freely distributable; if not present in the + system, it can be downloaded from Microsoft or from other + software provider for free. + + The fact that MSVCRT.DLL does not exist on a virgin Windows 95 + is not so problematic. Windows 95 is scarcely found nowadays, + Microsoft ended its support a long time ago, and many recent + applications from various vendors, including Microsoft, do not + even run on it. Furthermore, no serious user should run + Windows 95 without a proper update installed. + + +12. Why are you not linking ZLIB1.DLL to + <> ? + + - We considered and abandoned the following alternatives: + + * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or + LIBCMT.LIB) is not a good option. People are using the DLL + mainly to save disk space. If you are linking your program + to a static C library, you may as well consider linking zlib + in statically, too. + + * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because + CRTDLL.DLL is present on every Win32 installation. + Unfortunately, it has a series of problems: it does not + work properly with Microsoft's C++ libraries, it does not + provide support for 64-bit file offsets, (and so on...), + and Microsoft discontinued its support a long time ago. + + * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied + with the Microsoft .NET platform, and Visual C++ 7.0/7.1, + raises problems related to the status of ZLIB1.DLL as a + system component. According to the Microsoft Knowledge Base + article KB326922 "INFO: Redistribution of the Shared C + Runtime Component in Visual C++ .NET", MSVCR70.DLL and + MSVCR71.DLL are not supposed to function as system DLLs, + because they may clash with MSVCRT.DLL. Instead, the + application's installer is supposed to put these DLLs + (if needed) in the application's private directory. + If ZLIB1.DLL depends on a non-system runtime, it cannot + function as a redistributable system component. + + * Linking ZLIB1.DLL to non-Microsoft runtimes, such as + Borland's, or Cygwin's, raises problems related to the + reliable presence of these runtimes on Win32 systems. + It's easier to let the DLL build of zlib up to the people + who distribute these runtimes, and who may proceed as + explained in the answer to Question 14. + + +13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, + how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 + (Visual Studio .NET) or newer? + + - Due to the problems explained in the Microsoft Knowledge Base + article KB326922 (see the previous answer), the C runtime that + comes with the VC7 environment is no longer considered a + system component. That is, it should not be assumed that this + runtime exists, or may be installed in a system directory. + Since ZLIB1.DLL is supposed to be a system component, it may + not depend on a non-system component. + + In order to link ZLIB1.DLL and your application to MSVCRT.DLL + in VC7, you need the library of Visual C++ 6.0 or older. If + you don't have this library at hand, it's probably best not to + use ZLIB1.DLL. + + We are hoping that, in the future, Microsoft will provide a + way to build applications linked to a proper system runtime, + from the Visual C++ environment. Until then, you have a + couple of alternatives, such as linking zlib in statically. + If your application requires dynamic linking, you may proceed + as explained in the answer to Question 14. + + +14. I need to link my own DLL build to a CRT different than + MSVCRT.DLL. What can I do? + + - Feel free to rebuild the DLL from the zlib sources, and link + it the way you want. You should, however, clearly state that + your build is unofficial. You should give it a different file + name, and/or install it in a private directory that can be + accessed by your application only, and is not visible to the + others (i.e. it's neither in the PATH, nor in the SYSTEM or + SYSTEM32 directories). Otherwise, your build may clash with + applications that link to the official build. + + For example, in Cygwin, zlib is linked to the Cygwin runtime + CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. + + +15. May I include additional pieces of code that I find useful, + link them in ZLIB1.DLL, and export them? + + - No. A legitimate build of ZLIB1.DLL must not include code + that does not originate from the official zlib source code. + But you can make your own private DLL build, under a different + file name, as suggested in the previous answer. + + For example, zlib is a part of the VCL library, distributed + with Borland Delphi and C++ Builder. The DLL build of VCL + is a redistributable file, named VCLxx.DLL. + + +16. May I remove some functionality out of ZLIB1.DLL, by enabling + macros like NO_GZCOMPRESS or NO_GZIP at compile time? + + - No. A legitimate build of ZLIB1.DLL must provide the complete + zlib functionality, as implemented in the official zlib source + code. But you can make your own private DLL build, under a + different file name, as suggested in the previous answer. + + +17. I made my own ZLIB1.DLL build. Can I test it for compliance? + + - We prefer that you download the official DLL from the zlib + web site. If you need something peculiar from this DLL, you + can send your suggestion to the zlib mailing list. + + However, in case you do rebuild the DLL yourself, you can run + it with the test programs found in the DLL distribution. + Running these test programs is not a guarantee of compliance, + but a failure can imply a detected problem. + +** + +This document is written and maintained by +Cosmin Truta diff --git a/tools/HitboxExpander/third_party/zlib/README.txt b/tools/HitboxExpander/third_party/zlib/README.txt new file mode 100755 index 00000000000..34a13b344e7 --- /dev/null +++ b/tools/HitboxExpander/third_party/zlib/README.txt @@ -0,0 +1,60 @@ + +What's here +=========== + The official ZLIB1.DLL + + +Source +====== + zlib version 1.2.8 + available at http://www.gzip.org/zlib/ + + +Specification and rationale +=========================== + See the accompanying DLL_FAQ.txt + + +Usage +===== + See the accompanying USAGE.txt + + +Build info +========== + Contributed by Jan Nijtmans. + + Compiler: + i686-w64-mingw32-gcc (GCC) 4.5.3 + Library: + mingw64-i686-runtime/headers: 3.0b_svn5747-1 + Build commands: + i686-w64-mingw32-gcc -c -DASMV contrib/asm686/match.S + i686-w64-mingw32-gcc -c -DASMINF -I. -O3 contrib/inflate86/inffas86.c + make -f win32/Makefile.gcc PREFIX=i686-w64-mingw32- LOC="-mms-bitfields -DASMV -DASMINF" OBJA="inffas86.o match.o" + Finally, from VS commandline (VS2005 or higher): + lib -machine:X86 -name:zlib1.dll -def:zlib.def -out:zdll.lib + +Copyright notice +================ + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + diff --git a/tools/HitboxExpander/third_party/zlib/USAGE.txt b/tools/HitboxExpander/third_party/zlib/USAGE.txt new file mode 100755 index 00000000000..48e594ee572 --- /dev/null +++ b/tools/HitboxExpander/third_party/zlib/USAGE.txt @@ -0,0 +1,89 @@ + +Installing ZLIB1.DLL +==================== + Copy ZLIB1.DLL to the SYSTEM or the SYSTEM32 directory. + + +Using ZLIB1.DLL with Microsoft Visual C++ +========================================= + 1. Install the supplied header files "zlib.h" and "zconf.h" + into a directory found in the INCLUDE path list. + + 2. Install the supplied library file "zdll.lib" into a + directory found in the LIB path list. + + 3. Add "zdll.lib" to your project. + + +Using ZLIB1.DLL with gcc/MinGW +============================== + 1. Install the supplied header files "zlib.h" and "zconf.h" + into the INCLUDE directory. + + 2. Copy the supplied library file "zdll.lib" to "libzdll.a": + cp lib/zdll.lib lib/libzdll.a + + OR + + 2' Build the import library from the supplied "zlib.def": + dlltool -D zlib1.dll -d lib/zlib.def -l lib/libzdll.a + + 3. Install "libzdll.a" into the LIB directory. + + 4. Add "libzdll.a" to your project, or use the -lzdll option. + + +Using ZLIB1.DLL with gcc/Cygwin +=============================== + ZLIB1.DLL is not designed to work with Cygwin. The Cygwin + system has its own DLL build of zlib, named CYGZ.DLL. + + +Using ZLIB1.DLL with Borland C++ +================================ + 1. Install the supplied header files "zlib.h" and "zconf.h" + into a directory found in the INCLUDE path list. + + 2. Build the import library using the IMPLIB tool: + implib -a -c -f lib\zdllbor.lib zlib1.dll + + OR + + 2' Convert the supplied library file "zdll.lib" to OMF format, + using the COFF2OMF tool: + coff2omf lib\zdll.lib lib\zdllbor.lib + + 3. Install "zdllbor.lib" into a directory found in the LIB path + list. + + 4. Add "zdllbor.lib" to your project. + + Notes: + - The modules that are linked with "zdllbor.lib" must be compiled + using a 4-byte alignment (option -a): + bcc32 -a -c myprog.c + bcc32 myprog.obj zdllbor.lib + - If you wish, you may use "zlib1.lib" instead of "zdllbor.lib". + + +Rebuilding ZLIB1.DLL +==================== + Depending on your build environment, use the appropriate + makefile from the win32/ directory, found in the zlib source + distribution. + + Your custom build has to comply with the requirements stated + in DLL_FAQ.txt, including (but not limited to) the following: + - It must be built from an unaltered zlib source distribution. + - It must be linked to MSVCRT.DLL. + - The macros that compile out certain portions of the zlib + code (such as NO_GZCOMPRESS, NO_GZIP) must not be enabled. + - The ZLIB_WINAPI macro must not be enabled. + + Furthermore, it has to run successfully with the test suite + found in this package. + + It is recommended, however, to use the supplied ZLIB1.DLL, + instead of rebuilding it yourself. You should rebuild it + only if you have a special reason. + diff --git a/tools/HitboxExpander/third_party/zlib/include/zconf.h b/tools/HitboxExpander/third_party/zlib/include/zconf.h new file mode 100755 index 00000000000..9987a775530 --- /dev/null +++ b/tools/HitboxExpander/third_party/zlib/include/zconf.h @@ -0,0 +1,511 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/tools/HitboxExpander/third_party/zlib/include/zlib.h b/tools/HitboxExpander/third_party/zlib/include/zlib.h new file mode 100755 index 00000000000..3e0c7672ac5 --- /dev/null +++ b/tools/HitboxExpander/third_party/zlib/include/zlib.h @@ -0,0 +1,1768 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.8, April 28th, 2013 + + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/tools/HitboxExpander/third_party/zlib/lib/zdll.lib b/tools/HitboxExpander/third_party/zlib/lib/zdll.lib new file mode 100755 index 0000000000000000000000000000000000000000..669b186cc5a5cfb531800a670b7abb32bfffae3b GIT binary patch literal 15256 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 literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/zlib/lib/zlib.def b/tools/HitboxExpander/third_party/zlib/lib/zlib.def new file mode 100755 index 00000000000..face655183a --- /dev/null +++ b/tools/HitboxExpander/third_party/zlib/lib/zlib.def @@ -0,0 +1,86 @@ +; zlib data compression library +EXPORTS +; basic functions + zlibVersion + deflate + deflateEnd + inflate + inflateEnd +; advanced functions + deflateSetDictionary + deflateCopy + deflateReset + deflateParams + deflateTune + deflateBound + deflatePending + deflatePrime + deflateSetHeader + inflateSetDictionary + inflateGetDictionary + inflateSync + inflateCopy + inflateReset + inflateReset2 + inflatePrime + inflateMark + inflateGetHeader + inflateBack + inflateBackEnd + zlibCompileFlags +; utility functions + compress + compress2 + compressBound + uncompress + gzopen + gzdopen + gzbuffer + gzsetparams + gzread + gzwrite + gzprintf + gzvprintf + gzputs + gzgets + gzputc + gzgetc + gzungetc + gzflush + gzseek + gzrewind + gztell + gzoffset + gzeof + gzdirect + gzclose + gzclose_r + gzclose_w + gzerror + gzclearerr +; large file functions + gzopen64 + gzseek64 + gztell64 + gzoffset64 + adler32_combine64 + crc32_combine64 +; checksum functions + adler32 + crc32 + adler32_combine + crc32_combine +; various hacks, don't look :) + deflateInit_ + deflateInit2_ + inflateInit_ + inflateInit2_ + inflateBackInit_ + gzgetc_ + zError + inflateSyncPoint + get_crc_table + inflateUndermine + inflateResetKeep + deflateResetKeep + gzopen_w diff --git a/tools/HitboxExpander/third_party/zlib/test/example_d.exe b/tools/HitboxExpander/third_party/zlib/test/example_d.exe new file mode 100755 index 0000000000000000000000000000000000000000..1061952b844918126d263ef1c730546bb4a50107 GIT binary patch literal 38912 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 VBe!Cl8y)|Dbm~97__rzWzXAHFG=%^F literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/zlib/test/minigzip_d.exe b/tools/HitboxExpander/third_party/zlib/test/minigzip_d.exe new file mode 100755 index 0000000000000000000000000000000000000000..e829976d93fec59cc5cc38d4f7af40a6f6b87637 GIT binary patch literal 35840 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 PuYUfY(X0RWTk*dDdX5d7 literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/zlib/zlib1.dll b/tools/HitboxExpander/third_party/zlib/zlib1.dll new file mode 100755 index 0000000000000000000000000000000000000000..9ea38d5cf3e0ddbeaccc0122ce3cdb6c3741a3e1 GIT binary patch literal 107520 zcmd?SeSB2awLd&3Gr#}?XVjq4q6AGXBWM$$ZANIFWHL#BBnCnvtwborl(wKqW&pte z;mnZiZboT+y|=d2TY4|odhf-G0TFd3q)ehw20|eUm4H;|FkFdfAq1QJzH9F@c_UEo z{rsNikLTf|IdA)A?X}lhd%f*Fg+JJAGMh{$3;yr!Hko$fO8;Eq@0I_o$LG=Gc8xY| zAO7z6ol3#GRc4%Y6@~{^Y^boO?=Amp-)U zfjdTx8j)r+UFb@Fe4_9sd{O*%VtS z?vo_k^oHOU|5A;YBa+0pOr}&>k19}o{1cauVu}pKLsT(6Pghft$xnzF_|KkX>JZ-t zelVWf6;sL}pK|sqrY{D0pLlhL_kmSjJZw(~^aK!%wPz5r)B@9j1$Qj^q4$S)Tu-lP z>=>Tu+qm}m=Q5>-?pQ7hHq5|>1^8ZoYv#am3tV?BtgNJ}{!#d|t^ap=Pyg1N7KHA2 zK(;4v1YDV{_~7qf9{sxR_=zkha2PepZMvjf=nnVnIn?$f`qPH*G>#_+Dd$}x;7g@) z?MAt$2PwC_a`}%?M9!Hp=g$sS?tvu_p`e&U%%vE|bC;CMrtbd#_^*`xwM09e9I>RW z$M9o+pQM=B9%f04l^isg0!Mzg_zivG?-t?DPQsbj8WB8_9?}|;?lfF=?l5fsk+i3(N3A>qt`lhh%|qxWwiIN&!#sfsXs`FR!5wyOToXg<;Np*}scd1;nJuV>My?DgG@BSyc9>NlaPcnXA6e-usk zemaMzz!BfD_L>_B?ibpBuP+RQyf^StI}M2_oXttI@=_~HPV0`Macu~pM}pb|`wN6) zLV5H6+6%Eg-mDi0RSE_s{TK^mm-BIV~D?Vdm(_-ZlA;yMKX>^7= zYD(S_;^;0T)Lt`$!0V5&*9qbJnC|Xw0@dE8F9aT}bQwZ5>1)i2#`RHD#F8fP{>g24 z@nx5+W07@CxWqoh2U(E@t$%_d!R@!=)&%;{PG<%Vu<|cJSH2E*h*f>b3Qw{z(~9+l zYG4z}ydY?%8-u$owghCyJtqk$s*W)-P)Y31$4oRiETVOpy*CEVd9P<3y!;F9>)=&i zMut#ZfU}#OF5iRN%$sIO)cgZ#vIt&M^*-<2fA8)V(=Ap!HK!x~A4H$Ac#Fvt%Xq6R8(GYHhfOb$8>eIPEXpYg%tN4s^K3nW&a9G7=-PSu4n#%+l z=g5XxL|;vlyTTOQ{SBHRF~2F`{>YGIkT$&nFM3s8Xy+bl?C-#G6Zn&rei1wVXJDiB z3**a2#+S|g|H<}VcoY)~dYA^vGcCZ}j+sYtq#mprI3Om>n@l4bjc>$TV;11EcG`+6 z!%>B5cSoD{08F%3zNb$Yc;Iz?K2ADMIBwUf?BMm8Ap5|%w}|+?)A34O zIfHxbXf&Bu*)u|FUGh*Zq$vB9cbpO5XVn)zLuJ+)d`*SwwCmyZ!`7?W7tWsupHhEv zfIc}|!XMd(A7hYF^UL>CSK0q-jLD>KOhxfjRHLk;qtJSy;H?AX$>qz5jGp?hI>uBSuY9Tw_D(^s8s{t?OekYBi zdM`nD{vG6DM;romct93(zHmgKau$qvhx*IXX z>WhS(;OpW|_C--eKSYEGl&c$$0R6x>Ygg;++8MjDU#%-9%mkCKQtR@QlosV}T+PPS zVqAw9*P+IBm~pil*Wt!>gmE2dTy4g6lyMzxTm@=cf;OO1>sHko;&l*%7PEs4Pqb@o zYS4SF-FscIxH}^hT&)ZsjyDBuG-ez)e~z`X{o>l9A0=iiwFBAlw}W-WETucqZZ`=@ z8(58(+l7pJG|d_~qSii#0&mfLu-5ZuSZlarT+nty_=4&P|D;I}*gNcfbw|0Cy{G=y z=dAtwC+ZH5t!IXU&zakSXYR2%4zaV`XAQ^f;ZNCb7Y4zbY`|wr{h#^urz$M8`^7H>o;~}vjW1el?lgvEZA?287Hy;-9kaA#(c(8!crIjws6XKo}NGe+5`18L;;+U>^^tb}7vLWVJi#VN7JWWG4;_O)PL49LAoC(cfS@{;H2v z<4Yv)1@2R|o&UWHPloOoq<1X2nnd~mts~X}>IG_ZG zM|!&y&13wDF5mticBuwPYvci%h78e|guS|frb(=Zn-lusP8V?m7HLBsW`x9yYNu0p zxh-(SdpGxyCK2(FF^JXqeAIi}xjkmD6LK^@bTi#fRO?1+dz6f@TGtegStnb9)Fyd?3lVyM}ugDz0b;zvKHg}WQEnMb?xC(cD3$HKIK){5`AIy z2}nLuIF>SbN`P9P{IF&6ls8<9aW~~D*CK%5&d#fK2dh7k;_=gz$`qoYgWledz1gT6(VMLH6??M}+8Y)D*`esh7@-zV z4fp9V`G40T2HJ0UovcHxJD0$oohLulixu>iEQdF1tQJn4ocyX7VX_?IA+Y(Un1N0p zT|&z(0`+R$p~)73+{qT%m*rJLrFL%TsQl}r$ob>HfP(n|qzot&77Pk4q zy!2>r+T+>@Gdh848)#DfHBfD_l4l%%JW%Uw*P)*QwCQZ|eSAKuFF?Ud{=_ubRY*y}`#jftH}q88S1vJo z8kz4Tubk%Sn&>;}^qf?+dx#^h;j1lyZq?sP5AMv2CTAD(v~jmr-7t<``P$5|ux414 zy*!DPh8QjW#)5WitOAY-@$9kOl|mMj|7O?_!hHV@Zj`%})mAjbpV)paREcSsY>hW) zxsJYX{0*Ud<`Q0+>DbQ-+nDdDT4x!}XU^r7a~S$7Y~}R!Aom?*?tHZ_XSBk7C)K*b zR#p{drQ2IR&S<~Ia}eL+7R}S9@Y3y&nJ9>gRYw6dFLAZBsdWY4NxG$SN=75f25lzu z%p7WMhqHoBTdwXXZL45cX-l^&yl^|?1f;nzs$EE0`5(M0THQSa!&hrU1gV+3EaVV) zg&y3K^p}9+&7}VX&Z&VVD3{SKjO)$7ATMp^K)WR^m~4kXz(N>{ZT}ijOM;fG&F&oLYhzuaJuQ}`?y$0bj`PmTLsI++@WDlgW2t3 zhpt%c8k#d-vz*t!1mY4cgu(HWY0hZnG+ya7S1xh3SKb9+9cSN40{GRP^jFR8Bw&^H z;FRysx=;O+SEBm{c!^%2CbWimQo24y<(-X{pE~wB>Z|vPr$cJqS+hG68f~xbi`rq- zR{GTzG(?JIb~-gb_bl;oh-IhiP2iBeU-1?N4qxagu$2m2VCNm5=?ify^|cAo+W=(> zTGg_#q#ix_62`kW*}2B9=B}{^x_zU1+y}yGP-f?Do9KyV2z^`wD0yzOvc{&YwJU3q z9UTtT3$ff}-=BD{mE}Ut82$%ppl3ZZR<9+z+{)K@Hyc#5u?F@6A?4>SGM4$Vq(d%3YJ{NUwM{ZpHgZqqt&_)M4Vc;-t`<7D^b2e^J~vyLY0c@ z&Tde33R+cn98l{vxc*sRNMCD*<15#mLo2*w0mh=m6lYj{GUPZs^@;UFiFF|e23C3! zY^>J!0E*TPPA2LHC$mG~IPFt~yYpG)0#?|-XHJ3Gfp@@dK>nfv-v8<*mfPjpJdS<$-xwZa%~USonUh zFE8AtE#0E<@-2ZQ?E4FRuabuR4n!75pIJ+IXVJTkpk!V~lOq~9uxbb(QTCHx zgcZOc2z6ahI{a%(iEJhlqplsx-1FG9wAhRn@#@}WXBjA|%#OwaG&7J0t3Xz2U>I7? zfO~X_RC8#;In4{~Lp#@KswyIuEL7k$Kefpi#t+7MIK!rBQVp^{lYLPIb{)wz=O2A1VG0?026mBcRr-m7{@hg3yevDWSc!Iqe z`^zqLSh9q<7wA8uO1U)j~h~*`# zfqI&XJS)qy>pO7!T_I&RzJ^=C6j&lgxMU~D6ON@MHMd@?vRRl$!rANNuMk3oXA^?g zzmb}9)2!A9LULBa0+<1_`V38B|5^2J#jAd^`X7W#GtZ|b{VAGI;9tz?m3jarkjpIg ztxJ2jdO#1pYq(ikWmm4JwzZI1wmldEYsXvxfxg!y^5QQKiu{5r)l~yuBlJq-+i@%W z`LL%*dw~3Md$A~0SDlnoviyH0!bpIz_xQ{OkYe1uEN~9=Nwdgiu43**s{fH8Ceu{D z9&g0tR*vCoCOOVlpAmAdQ{8Aqn4n@aR$q1FN}v^@XTw9pXznGNZssLkDejbdh$Zb5 zw68Y)gy61;?nM>MQfA1%m{M!IR)~@&NFOGOsCB;}K}akoMc{Wy0-iW&ae$-yMx zD)hrVt-uL*&k@y5C5Z*wOZ-@}3h$hdh3+NGoscDb4H(a>B!LxMKH)QSGP-Vo7E_rY zoboWA>0-X^ylOkIoTBcyd;DIAt%td9dj%T`R)?RwWR>raysDKNtU4NTF9v>03Cw}5 z151g%Cj1RU_6cbPCSM1bspQXb z71C-k37(k?Kw}9!2?`TbrSGPXZZ8mt;--Fm>Nn$CMK}i8CT5*v+mHlyG1z~wG|c{2 z45Pmg`Q{e9>MKP2$;4lMc=}*MC~m)sc>3Vwgraa1O1|6=kc_}Z?7>%Q%tIhQI@BLbb**lZZT%||h(;u|6yeoIsNjQ?7ouS*3CD0+NJ1H!^;@=FMqJ4?bpP>^& zM(;ymlF=&&X=@e-y1m(7jYeqo611b%)sw0r7CwX4(fi=S{^0?_UM^DqSlGWvlhS{l zYW`)wJO%!pXp+RS39=r7UjG~6@(N1{Q43~0Ttpr1FGpzk4y->O$2iopea zPu(9~sjeCrM}#Qnm}pYYf14H?0x|bpkr_gN)NEKOo|Exgdl>c@ zVU85rd3@$1sQ$W;-*2lLBA58!MKnm=cq`CFB??cPOQ5HC@yVowN!l&(TAXh$Z*aWL zO1v2d*vuu4uvofFGL?E^EENdjp+_M*O33X$o3A~OSN*tdJ`J`H*R>_M?t2IXLj$}V z*L|Z0Nr~YF#^V(U#Ytj$uGpN>bVbeLyO)A@!$9x?yD@rnK>DKhcLs`T{sJa~zX0OS z*$(Kjz7-;(4$Y4=w0BX%51F?Ug-HL22>k~yO{)JbYHj8cp#))JaPC(hD+JJv{ppCp zLkV(cDpBZRR&qJ_Rc(Ly!X=n|=(htf8R(?O`|`zE;`PB$`w?7wS3s=@D@yuP038h` z4)L*B|1C90>)GWcZi3g^p1%a*H{dtuJNNJvCX}j>S@&EH*l%A6SRYhXQb*(42OVhV z$SV%?J?c{qbPsMzY05-=XBCW6FcrlS;BV15Li|T2+G)#pJn@BDpD;Jd?A2Ic%Z^qM{NM zchoC~Sv_}K_()b_VN(&IfcLU+cWlpp1Man6m~ikBsT*HLRaU-pGcTLVi!%AzIXrg> zOg&!a;^ob7(D0%u41SfhIn2|@bMskgD=%%-;sEX-Ib_PWFyHg!4}l4Hl9#u^f5Lsw z_qX4U!g_;s2kTAUkum;o1)H*l+%NSC*>AqR!fn!sTEU#Vx)^$IkK}rj09Gu8KrQkL zR5YtK-v@$u`A+y)xTo2i3llGd0aK0KdEB#`y-BtL>Jm00xvQv&NUl&tBe_DoVrDp< zfsCRQ{Xxu@w$^f+8d!uoL7c*XcofbFcRKt`T_J6(SgrFd=uFUqNim^zR;eNnzy(30ax%OOVM3 zjt8Fz4uL*E3upMu)IgIr#!J%R=Q<9LM8us;?L^#Gc@eW8aZjT0lD8r^C6X&jXdR|U zzvs(}4IJnD&tit|8wZ$x@0_cs&C|6+V#^-0=K*8FSVjqj_KD5Zm;2Ekdmtarrr6(J5;GD4bcFeNJW`z3qw~YBi`4VzeBSv$; zHv*|(hMQVeKZC%{5T2b(oCPXvI77@jG?4!n+;j4CdWUj% zvKB%D%V|D;EWRYO!)o0%(7+Kf^B+J&vr~LZ!>2Lq@a93jt(z2_n*`UEXAkwO2K*o# z?U7>Kt;QYD+h7grw&0Wuwm+E(2^uT(;ituE{?V@wa^INjS4&gwiX&% zzNc5-!3&sJ9}#EwbwKJ3GXGll5D37vmsubK-K&~;3F%G#{~iVun#oXnA9q@}h38t- zr#vlc;5#b5%oLHDkKtqBWfQcH+t^KP?F2XxRR1Zgl3IsH^&f!b)Ht>Zq` z|20TTt>ee4|6i!_qGU`};P|QJvp`TBvdp4qRdj=`OoM@^_Kz=1YCc}H`dDOhOQ?%GpqhzqI*oLdNVHj!4u?2jYsEaDN~ujA#>+7A_S%9Z zg+8sdBGT6lAVCGz+Ja$8yvSNRM=@(53!LWAYk!Ef0IN_Sw04M)R#2SL%I zgo^?z0jAas9cDaIzJbh&&0YtDm<=PkWT7JN9sMK~1CIV1<2Wd<2GQ8*;=3NrdKMLAMf@jfKv>o4s z$V`t{xiMkNRU$DLDkqt8CBmy*LSALGL|$dzD~1aH2O6an!+zmWBewsUwMx&wqj2zWDea1kBVT8**h; z|5x1W#b`|6oC648s1DB&of-{jm(xNGLF6n{=7WW z9y5@(aU!SyY9WOc5b1)dL%J^%-}xU3QqrB^SG8^o`AJzh03v{+NhS$q2|}10x_$gPlzZhWE6HfruKyX^6(rqWWZ*oV|$J z=Xx1Bfb^xE0pF!yty`DmtZKuuL1oJiiqH3%wTRhSj<@6=2tIce zfxya}<3A0~PZBN7Pr_#(9?kNRO8f2$&bP=%3q2MD=MRyOL+J6l!TCew<4}6MBRGGU zd>lrPR{yYj2yH3Kg`U42KV1AO|rlV@j>)6ku*3C?ZAR{3r zZp4~}g{<%>E4r*Goqt5ozp)7Do#-QR|7oJXG$|g&pbrwO;0?ITARN;E$HL(_#Eu~x z4h8#T#rIu^o~dOv@SW=aD|J;g7BXm1;SeV_XoCF7wLl-$rxBoo$%dORqM6GI)W;3k zP=f*g7;FUG3hOwMn@U`TM|`*scRFRIv+|R~Ne~H(cv&VUI3X4U`y;a>i9c<`4rZaU zBt#3+dqey;#QGq(jY1ZH*@^dymS}N>i7F%k!iw_)BDJC=s(%OiB#j2_Z~6;{cE1;j z+89fRJwO;ltQ!kS78bTFT8^-~1eRhF_|QK7w5E?%Kb)F`tH z+;7k!h;TX)VJTiootgB?$EFeqbPRdfr9PG}Zil|SerE^;p~2}l{o|>JTou;h{WQaa zP5rliF7YwQ)PGEDOjA#0P{^$3e*w^-dq6mOPU?>kJ3_1Okw!w| z?)1Hu5##W%H)n*xnkL`W3Dq(GPnsWVt^9QsOu*u<@JX(8|L2c$Sb*-_oGLa82HEB;rX^>Zc}U{uu}@L%s;SXQ}9v zTu>fdbd6>~%1?bEQZN!Cb1&`(Wdw*8s9mvxXb-pWH(m=`g&}h-79v{Hij%}5fHm#G z&%jXMxN0xZt21WOSllmUwy zx0~rtnGN#Be-c>UECbqs+VxzJ<22e}mK~ z+K-a|)%w@k69zVeIyBY@9#jJB6HUi}fm)J4{@EcElEZLb^?7B(cZW;w#Tki+TaZ0TALx9eWIs1Fhqt?>E}IWD`=CP&ubQzWHbG z*pN(`5pupvFsWi6l)e&md;O!xN57muzJwg6XZUi9*5&c4S{H%`1eTHSpG}+6BuBU> zfEBt+(s&8<(wxCxy9R%qIoNB8kMcyLz+KnF5W^AoSQ=L_$MyH#n1R*>@72Q?kk&O_ z^)D7T53Bz9;s*Y#GTc;mN#?#8_qqpvguO5Jzkn1{I2@jE&=n?A=n7#8L{Upq#q^D( zkd`kETec9;^&H&^ZW)+fsdZ&~h0Bh<^?G#I-<9Fh14p)XdG~X7YQ&vFkYl7Xd1V^B zyi>KRlifRskW>$3L=$>jHD0@*iai`_hiJO}k4fCqMjByyX$xtYY)pCUi1<9qk&Gr23jxb=0!%74A7I zpZ{IEVBHD(8kEvVD`*3hMj|O8n1KA!R$4V_UQ;=OV1@9ju)V5(8opOxCn0l>ZTW=d zr&IQFaf*PPr9@m}j@YV6!MtuQJdEW|!8lq@u%cqPQ+0)v6(AN~G)D^!e+|};>HKFb zcP@1<)-(}|lBAT%ax)X}5nhs}de0|U@27%(p9C0@jUm#1@sH)^5E|h{3IhgddxNy7 zHm#Wn5=%9#zqOgBpzSG95$=gxtG8TR>oR%o)z;>iyt6QUg&4%~u3++P?EXXSS?K%_ zXKW+c`#|j8TtuVAdd-Bp69mDKZ3ZgB?yA$}dh1`2paA*bt?wYu%_`V+5Pd|QaNtnV z#gFk(79e}j5MRcAR6%|uzYtHb_oG;%Qn-c(Wd3Rw{vm13>>!}XqM17kXQtnfIuRuUqf*a2N6RGZcPSFL|p0c4C85%X+2%0 zbg!dJv3yw|U(S&)=aN`U%rUMO`r0#FEU%X|@&=GbUN33n^(T!;O@b;SHDrmITmUmK zCqWCM7rg4}g+D{3v~|5SagUAVSylfA)YaC3E*{m^fi6~nE|&MFi^s_o#A=8r*bYC6 zN5nFK8`IuA=u`u!qW&Yua>>;?C3^N}Y<)3aQD_Cr4FotI^fmY+i6^fw@!SR(B#Gw> z5Rbe&)k8)?-XUdQ2s?_t8lkA`#ME9Ik3!hwujCWNI_5hm%0O_nVrPVzXImJ;>`-Ui zR-SERu*9Glx$P7db3^Y*0WnieHx`3b=1%1^(%8&2K4Su#Ie{;q#40E8<>{<4ozI@a zN~XYrM|04Zpt_@^Z56hOA&~p;eiE*wZLhsd#-{HiD;diUfBt*0Hi*m+9^BQR5=bm% z_0mb!fUnqwklRZtx&286Vk1Eoe4}vKk=kdhN2#zt*D9E#PR!dJKxN?iP&Nj%R*>z?r$s^w4V z>pcZXEa!PSy|vIp>>m0A8|fanLakIwG>H%2rVsZb!PTxrC%P%wg9~bBVZ>G-yO4X- zF+?~Z-eWZ>aFP%Cf?R1eY2p^ZvYK?DYQ~#O_UBMA z&_i0m_0_9v_h2RPj$j^ZlO9ernKn1+BhZu}q$b+8F6c2Oh^?jwgHWsy6G=-kp&C0+ zF_sUI0)wJP{1xR(X!lPtcNL?HG1{7fFTJANojN$oT@2uHDWHoy!{d_uMfYZOmx(su zI`gSWeKNLl3w;3VK0*aZ5+D^P_FfEl#Jm+ArB%<{0$D~4lPpW6i|oy1lP{-%KD#3> zmwXcIv0A72L*5w?57CE-9gbh8z8TVD=`44e*s*}Gs=pDRg2mDGox@ig*J2Z=6|VdU zo}%uwKw34<_<#ilEX)BUlx6^%Afr2$izhuBy}=)Cd-)Np`!5^A#518h{zA{Q3+sw0 z{)^sclE(4s#52qlJnIjlF=`+6#WV4me4Zeli+Y}2v|{Vu>wUJ+GiB;id88DvPGX1> zy!bAGqWa-WL2i4O>MuuAARyp4w&fFnSrFtZ+N1`YQ_$po`Bvf^F&FQCrJbwq&- zsorN5dF_LSg`$+Cwy6CUs z6^$QhO7p?(J^19g6M&5XWojW@Cs6sBxR=xRJ2ALMY6zpMBm98!iOHV%74GY`&TfFD z`p?lAi){LQ;DgXWo6>N$3sJ_xj|C>hxh42S?GQx9(JyoxyIU5~I=WfdyBZkRDGG{` zVylW+3AWvnoVZPj4Wf66aU+=KIXB zRbL>?`jX*RpJCNjWAIS!a+F3o|H_c2Cwum<_tG;ci}I=dcl9qvzsPQ>?ld@~Q*Z`J zv_a*Rf%Bgp7oy6$GeP?QHPJmc{-UwICC2-IufNW=EA~hG`vr2nV|r0z%Lo~WOvXVu zVuA9VOT6=)=GmD&_%-Sy`Ro#5;Y&lD3u$KsOwm>se7SQGB$f9=o?X0aIqvQ&$3l}+ zzefrb@4ev>Z6c))aVsTKAXUWxOO=gqBXm zo$`f=VHS(MOMv4I5cu{mP>c3XtXj&as}NZ;oonU!Rb zArj!xp(jc)><72;8RjF2-YHau&Ilu|%p@HQd-y7mf?`LrtRAKp?T$wh2YUMZUr-1b zJ;2;)sy~J*q^q6Bm90rJHZCAvliG^7AC(s&pd#)$;t9M+ltHrZF^O%FQq%Il5Fglv*uTOhxLXwg-?S-(o*YM_Z^8yb$?My807 z>T5WA@4UboK&{L0yKr<&Jb59=JZX0D!39gb;)j>Ltw z@e*JGe&i7}#^G?aKoV9|{cpe#=^Ax&4dZo~ntnk6p zbRK3Ou!{(D`W#S&i3iQtNRSJ%Vr6q#?i{390*U%&{4ol~KkPfrfBK-$G>g+Etg#oM zP0=(zPL+D}N3q|YEM7|3MzGggN{Nu)gz0(>6w;-HnvQOq7UQNwkYqj;TmMI6?hjboBi`gEnaUC8$9dbbMc8 zy~cT)>=4XzF!KT54e{?i>Ty)wUdZ~R)}%L#iz6r)8gbHJiT`e;AFE9xhdjK50R zqXurqPkh%fX0lX^SpOP!2a*>=eg~ULI;Z@>O@kvgW1Fq;yrK(L?gQ$g#+)cZw zEl`5@7f1tjcB#2twBR_p#O$F(%v^FSig;|w8jE8ps>k1AAHY`nT*$SHD{v^0jkU@% zJHP}=7j4ia_a3$wqq3QjHcF4u%tvvo%voPqV)lI}#r_Eb`$N_uAk%+H>7qQi_BIEj$yAHm<^V%4hGP2l&^;mVu@{)vKjV^*26) z%nsj;JPC7nBcEZR&`h>fVMt$~tR0*h)3gWVcnn7~dcMHYLLJh82=TFBB!I%Z-&iSr-9mv46U04zvw984((bYuGA;qi3U!=V|w5^hM7j>I+)38X?VmD7ueL+G9wm2Jc#7w0f5hSGO z0p+zx&Z4yC?dT85VHzPjSwn{3J0d13CK%eo3@CnjD#j=Hw?}`I`!J-JfI@pmg#FW3 zK@{a7YGR~UtUZ}P$q|I6VOgtzU(@K;<|6|A4(=fG&L~Lk^}f!L<=BQZw`koFI$`-q zBnR`g7651&fud?|E4(vST7ds_kaQ+i?;XbWI4)w#0!W`iZuFUw;lXS_MG-z!x!pcKvhBV9jMJbH*hQ+Q|89&C)%SwjT7|oXnC?Ej)W42DtX+&J_6HKU zWTK9y;y7_v4Nw_01BBBY#JBaErk`O|BH1fA={jodFgT@meIk1W#+5}lBfK_4K6-~k z-_;r{IW3T%@T7=t6U%E8@g(&W}wCdh0I6rhks%xrG;XbPI4PP4&E5;7Pc0E?_5b zKxzl7r#)U9gk}c3-z^J@RAAKjd(s{GvNOoeE@Ns@-F}v3_5v2qcQLg_xB9E1-I1V6xpE# z+$-cKPS!Lut6S;Kl(hK40ruj(?6Bc)hq;71o90M5WI>dG=_Yg zU4Xb-e}-Q5v1UHpCwY=S60@OlY*$a|pP)1Z!fPNUQJs{Vz{il=`aSp}$4~YS=m!=L zX~4zM@_ehote6{%=>K= z28|tg1iKs9MQ;lk0Fbg6kFB`ctf?-C1gLVewg8&Vl@zHxdeu4f#GO%$uDEYt~j zAHvY$(O!AjUzN-_Cxn@IIOLY_YN-RH8a$a0W2fLp5lSSO%;d!(QYj?6KcZ=M=aY#3 z8{K;BQ{5?*%W$e4GTz;Dv8LwXOeq+%P~MS_i0vVJu|o&3U8sC{=b^F@Ws;8}b}Isr zO66Ro(&{+x8;jT}Nmg)rI|ZS!+@lS)pOwsszY1fhHI^qeP46n4n;m~jm=WG&@#S`W z$v7vpP;zksq>OXu5Z*}!x@$!fK#^5eS3N$vJYF5sz6>;jQ#OHZu`YvZ{)k*9{ZmN- zb!7T}=_IN~oQaBkIY&hwAn z3M#l2f*Mp%X=Rnd#%_&0V%SJ8I?j8?!x-Afy5eBuR6Y=J%@yOg6@2(1DNa2hj3|Vt#!;6{{Hz zLltIB8h|syNp#4u*ZJ9sn{cXOS8b9!CQ@_HRWvs=s^8N9+;ifGS%>yscdh4>pyv~L zJ|}S~u?Mj~DY!o+CWt9&&Uu|&^ZoSX-_T59Wb5_W_|)Ss?9~q;3}P3c-jM!}6%I`s zQQ2g)irjz^fskNb7~j3wSeM|Z&-!lQ2USOAoVzSj2;7{4(Fz)0iqnS3dFU530E^a( zlP5u>{{lrukfJxt*FdUCMFRp0@gq>LI_~7aCeV62_K8IgYB)l9Xs?Kc)R{l zl=qF3bOM6WSJ2$G#vC1j7=1PR19$=YhO@7ovUdz#sqCT1H91h8D-3aDJS~xu`){G z5uEE#3JWoIBLL#=g81wG$SM!)oG`z9hvL5>!s@ZN0hNfC^%8{)0!bx&;CT@Veu+sz zdE8k!4Ng?DuYJ=cecYz4nQQW1B~#B@W1Q?cm=(8@8b^yWQ7(kL`4GCToCbAujVu1o zP?^`bd^_SWkPEN@udnU+bI?@}@XzT>0B&FS3E#b-e-(XI1XrN1=HnpcCf{0-rw!Dd zfM;C@QsgZ_%oC|!%hyaGw*b7_cq81V^BSevg*QFgEpfG%Hk(SN)`=p9QoFngtU5Lg z&F-XWR&&~8U&B{vKMAP?36qegpk6pBC=dp~q&)3Q!?%HkNub_-2@Ow>kb577K%Jcs zs6GCTOXTXy5n5Ig-zy7*hu2WDtNu*G5K8uP6w`+SYDifMBoo0`Y>vGS^9}Q<2JXct zj@rBNt&jfQHybIZY&h z5&CC^Ux4SZDm7IsQd73&vv?<4ss&{a{KYTg1jA*)pu| zMDZSbNq{Jvg4L&=qh3T1cw}`0JxKkw6j}eIY}aBVwT`P-d<|}20V)7sSFwjJeE>veOVqC~6!SsFNF#_Jma7Ju z;@K0XdO~W=3Up4N372u|Ba)PiTdixzic!^7IMf_=Ud|)z`=$nn;fOq zJc16LCN-? z=s^zLdV8=NH8KAy=e3;R_bgUQqs-T!?(jvmxLMut)xDw2N5T#9`G|r{yxEhD8%vy%S=X4B^WiJ-=yPKEpjAYFj z1{iRRE6Xa-!ppd4J1cw+C%%G+l6mQKBw<8a3bY$wk9I#>66e{N;Sr!gd_0sG0&3bp z@cb8KshMu1ae;*ueLnQPOOcNgUV(f4ZSW!R4|NmAlH28ee3+$l#FFa28nX@6kGRm4 z@(MMZM9s$k4PH{T9m!6K(o03W{ADjmM@(a>*m^34AB!k#X3H(u|H3^uV%x@GtPs09 zvnR3Dnd}GCDo4N!sh@~bkY`OI*Bq&^&_J*IAv(vQTsXuS(!|pY4;y6B!xluoh#psE z^10LW8wCASFyBiUL*x3Y29xSf1Jq#L23EMW`Z&1{uv3v(gozYUXnntO$oZkVF%M0H zGyn5aW>@_bs3TO)E?}k6I0xl{usXChW&atLZJ|3vOK=WE2Qftl&XYJSZr}ynf}2Rv zC}1LdCJAJ%w}1*JdO|{T&YnUuKqWmTppztB2#QzVC8$Ixf<= z#%S?B023DQSCHl&1ho(;;Fpj{jIw&)uY1MYub{6H6@b8(P2kg~uw|1N$PB`T7p72e zWCxP~1_x~-4p|67VTXil#7Ok}NZ$)PTJYO4F9B^Wz?ch1Y>@$Or@G5fd##`ilbRC#8(NmKyPea457#tf3JTEs**~lo{CeInUNq1eU=wiYT)XW$+Fo z{tK$~@Yp)6kdnuA7xjelSp{tnI1m!UQ81EKyg)q3EO|x1lnGJa!;sJSFr=P}_mLz! zfkbDKfI*_X^m))Pt!j=IIqWcE63@4saqIymwh;dS5vrfE6>$(p11sICX907BXA-6d zfokr8hSSWzy#}@=-AHT`wTNRriN#$aC5c#(P5Y7!~V3;G9V3Y6}&h<&2W;qLD+J zDdw~1VhIt2AahEwbuUpYXxSk69L!iO_*^o1y>k!qJg;ix(g(oP|1p0z4A2*B&=;;! zcRZX_TZ*=4L0@PvC5MqN5&g^M$?y2-)U^#>72MLjdA@vbigAB-A z*nlz7Ozj*@P*uP>qXEq>CPDR-914-e#Bz`xj!R|uHLTJ`qQZ0apuV3G2PT%CU-h!Y z?KI<%ad2QAuZRQ zmy-j7z$NR9erLu%3>t?C1LlnP{WABB2 zWG7|Jb27o74tPV3T{?c+F7_f|7W1A@P3;0zvi$~)qEAPQ;7=thhwTRCaKm&KTGKBzyN&* z&E-*^>w+zngM-cV+h{HS0Gg%aZ9UgmoqSmJL;U+wphH4I7C+vCRCz;xSu2R=ATOR^ z9OTgqt&0OS2h)gCJD@ia`Wi}N4_>EU!s>&P1qI9W2^Nzk6ySDq1q##7X!M_{$ z@5Fhc_+cHb-VEJK-Qg{I5QmED^PqqwpfF1)@(2op|E{n;N>DCQmwfN&XAq?83knpy z9`3*ac}0u06T<`;X8kXqnS|x&!scnAOGvD* z_f04uFb5`3VPSgc>nQ*WQ|Loo{5FfPu}AkhhFB0WA%0*^SU;rLNb4tI^xy~RN?(GF zgK0C7$-@hugDPkf6APsyW}8SN&5P~3hHX;V3#66$MeC*8dDfCh)?8RdXuX(wcA`4@ zhLdsTS%|`AcAm8e7c0+NfWBxL!JMpRcw>qE0m+A?H9jgpHSDUN^bYQKnB~6yLBl_D z`FvyAO?{frq+H&=k^yJzDBDjNj$|vD;_vmkx1@hJleX!-hp+;E+X#W1xno7bBjO+^ zE#u1bo$V`D(ot(?!O-n$Zj^PHXHIdn3p|ycq>(@?i`}#x6_Ag2$cP!b(-DMKqRvK~ zz2IHUDA@$P!1lmPt0w{+fXQ&j2s9Q?Ap4*= zmDOYIa!(PfiyEL~r*+EtGxW>E{(l&faK=*p`Yf7|^E?|wE6^XwB2^mtwUsV#l1bN@ zcPPv$mX#jdAe>^^OIUU>%Pzn`h+GmrwMe#2J_&DLBs*0;!8WHN)5K*%2u?zx=g5Wz z+yS=kLC+tB@gwrq&1pTmJq zbe;n3#}M9{v)I$xX~D0JV%5{SzNr?q2Xi~Lj$vxe2>`+KM24x3+o>zlRDT<8h?a?G zK-JiSNjr|y$V-TM?vCV5K><2c3K2V`6U?%*hf!+ze)V%N&MCH;IAfuKm9|%95^Q+ zSN&H3NWB?v*u7S^GEKO{&VQJ3K&M|k1fqN5CosEZ{6y^kP8^|(Luz|H-C9-hWu4qO zjNlNjOidg{aL)T3B&I*Xw*0q7(TU@HYGa~ zQJNQo{*HKI_31_$nA{>){>AIWImEB$u>T4vfS@Rm8-TO`vWIfV!r|gMh!aK2uptGS zmG=XFEjdS~z!OQUD;%05vD5i#JWaK1-KPJiEt-$5^Irmm%}3mjqf0o(~Kkdbu9e$RU+811+S~aBCtTNPpIBYq^3@Rhr%btn`NwUv(|Cb ziV*^Kq4*)Du*rN$&*ScBl!$F4-ro@2^8@n+=i_N@S5&qc{qeQJu-~)31!G83!X8Y+97B(xB z&zisLu@OL_i`jsghrg%HtXcG$?Vwteb$Q$$?faO&$ zp`D3q@e`0+Cze^1wfNC2tMUjf3Rzg=z^Hd|I#o{fKWzt*c95@-whqW0;aMr{sbxg2 z7UYlo9HS9W1Q@>Lrc29FTZN;!#6i+7bJjFIT)Qw5N0_Mosc2BUFj@`#6gRKY3am5^ zKg@C`c}Ec7YM=|MZ|`pp>u1P%x}bd`VlzvdX>upiZ2lRjl9M|Ezh{6KZ$MChx(1zI zwhuE1+YeJ}PdL*9KOi~+X;;~X!g(4|Mq`##|K{sxDvjC3P$DK0Kr~_5uy=6e3Tin$ z4eSFo7tWeiD0#$&c?3;iNGN)cBL;q;>)rVxDogx$4mwI3l+uu+MLFascIh)9& z2%~$;orkeq0K=f)vd2#i!okxl$@Z^+Yv8z?7nYv{)gu0~ub%~fSjd}ZVZx*7mZi^3tTfs{K6M<9YmweT$>a65=2a1)v&Phjokz%+YyJ0q3z2+TO; zJ|(DOx} zMYBdU7IRr(d3RsCy52>DMTWAI2}LUCfBH5 z3am*q)`tQy!Szl-ft%RA^;J>8y_cY`^F+xhZO|h6!^B=fixSvcgBJY>TI>OrAVvFq zXmP&q_!^Sw4Jh1lJ-?I|Yb7miH+#^mq(wB_LyKs(A1x*bk(`dZCsu7@f*cdH=!lRc zleDl3Sb32Fx|QY5RzB89~p@|{4LA%1)yh})jAJ}(^qJsQ!^p`cu8 zteA{uXZ~2#uaI5|-%xhSv$O_Chtkg}0jYb`O0jI^_Ov__`YPe|_CXsTCDbh-5>dP} zqX9Y+40^H)Flwoh$|QqeF+zUL;ib)^*{nt3*a)&uLzZf!6F_TVSx7Hf2bryPBD-J( zZh+TF)?(nn6j6XBfexS@k^SlO;9Dt-R?fr1>e)>{wR}B6`1MO61hZA`)^y|*kV1%r zf!%kzHY2^D4T%LgtCv9q(>%KslmS#`EG4TKFW-h=9mO&nMMeRuUpZdg;lEl`!I{Dk zm7UknPxdT>NA6<)M}mcxu2SgN&qZ7^&!Bh-D=y%kC*fF2=8$KFn@M$~q97&8E}$%f zo(zK*AZ`sA`0ju~W0GX+2bqw;+_ivt)|;~z5qWzyQOB;uyl@lb6}-w?A;~xRnDH8! zF!_`T^CmeYT0UlhY$c#+$Tg>CcJw+6a{ai z!9bWsY6b#KiY_4n@w4qA%!_CD%0ID=TGG!T7X{#~3kdzJLhDe~nt#D00m_zB__geb zRl6|_Ma#%xh~wE8vv%Qn#t0&&n*jOiSkSxmH{c8Gu>t;*PU*z(4IAKDgrj=k8^GOy zeNw^CLqVJ@-vVpkT;5elYG5vD%*e`0XoV3R$cae+0*d>$e%GL_tJ1;%DP~dYc1Wyd zRt!gJGfsPD#WwWA@3o)Xi=JM9@B!8I_N0*MaBin602P<$ycj?tL(7cf@pSIEi*5=BIG~ql(SMv&DjB{J+N>(5SvebP+=F#Hhq-wiTGT(x5O4>W-|Gso*~UY_ud5{ktFQ zQS^V0-~((>3Yh!|jnk|ltdr%cO@gZseh6)8gCaE~eKo}?$asC7qzKGceVS2Y7C=St z^j83epu7REar%FGBLoSn+D`tB^4*v|{D8wq1YLPvs#L!wx-$r^3d{VenbN#ffD#XH_n-Xnbfs~87J z4u(CX1!l-3a#$0X#2id8z*~c&eZfQg>q_vE(cA-H>Lu`%!af`fz9$Gi1oH?!Smi_e z!RK-TK2yX*{!N{JcuV3H1OSP>Q$J}0Y-ZV6RB$b=`M*Y48jZ_^6p65!`wkst+UQ*+ z-hoD$C+eLme&7J|-&+LS@a$whJ7prIZg3e|CI=XPP&=56c}050ZYVK0NV#;klb#yY z-2G-G!ciy>Y3pp{^*T{!X*Rn09FOS z>MdJ{K^UiM>RB`(82I&I5Eh<_EZ00wg9HDCfqYku#Vp^+#WujMCmt;NH`K` z3&DLbJSqaWn|cDbn-JNh$nY~EEsS3*$OZSHuu-IG$T?GQJ2oe-`$PO7V786RZ zqU?};(4;EAL!$2`;(Dp$7#hh?(APi-J+-iT`A3E-1h+zA6pBy8<0pD-Ii(?a0^ZSe zT4-eW)G$n=ve)U`#9nhop>Vr1=tUh~S}O21Y62@64!U5@!^>oC z7=j|N0_iP@yo#uy*Mh{vaG|0;yjcGRrObHn%bb)HTS80MFv@?`kL!3(eqtgGy@j4& zZjgcRDlq*5#auFl&sDr0Dt^QzQ}|4zc&mXeD4t+@FuiuhOd7xb(^E8C@CIK&F@aAQ z1ouxq^mnfv9%B7AN<0F9B5Sve7I%@gt4~KCiN-)V{j?mR?$~QRAB&q5v9;`^2)fDU z??Us`_96`aTs@LXe+mQaa*Q;JU@1I^JovqyljHV!{>q^*C5AwjDghkBwDi@Xh%?ax z)TkG*%jGL8WG_%Nm>{f8Stb3iQ!WAFcW*=Cn?O~Q)c}raVh{v$OLGOl8Z6obCu#7?_uk^WjUM)D}pCZSW{$oHMNxGg&)Y31#B_`HSlqV;4S>N{+z3=DJdve7> z+cW7i=&3M7(2>g^Oje$u)$Ybmo9K;LrbG$~WJr=k(KM1Fv~NYSNL)4I>Gb-W5NKZo zQ;;B4+fAz94Rr_d0mwR&L;?cI$%Hbbz!V?_1_>N52%ibk;iW<3-qY(0 zsG|1?RNUG-zUA&jg)QibSm7PSR9R9Il+5 z++`!}B!hq7!m!$5nWj8cC{mf)T_gGGX~?p|F%vi~yf;%oe+-YJb_0AO8qk3BHN!1Z zDLx&9xUj&EtVLTeoe)%I9hVryyH5bx&Tk?)H&A~LwZ@{07Q#9XDl(! z=8Tj3|8NC?AaZO4)CvX68JAs?wD7w4d%2U*z^B;jJ>ogX{U>oz)}uhWWc+U{y7N(@ zim*A!*1yr;n;lHoxDGjFpBxhU@Px0NJziuoL`L6RI7;|e>r9{T%LrP|AcWzNaY#cue``!l%njHgGZ?1%RI2I$XB?5FJD7JQ^n7^M}TVuo@w zuJmBUv=1lA9=>b!YR;+CJNp?^#v9K})Sg|!C;d47ZJR5PCj~uiLGPp!0dYWtp2Bs) z_gQcuib9G={`_YBNIy#DbjGe?zgr>8eReJ9+U(R`2oc8-|J2vH+UJkfHqD*Hg~voW zIvro-9ay~2yGt>PoVr*eb?ax6C=mNA(ay0xzw0r4z`L7`HgRBmhrsUJFSex;7Xs<) zBcmoZO3dOeZm&k#`?|}wf5FWrF&WNae4Rd4HM!k8qKGjQ)HRu$1?btl4(6z20v3Kswch6;75-e`~aN+JV}Z@ ziZgZ5Kiu`0g;=9T`Nkrc>s3O4UH;!}dqRk-7ct`Z=IaA}ZTvhvF(F@D6{@oEW&5MC zI0DqD>^iQnY&HI$Oeu<9nPB7f_4kLgd|j3PM!AO3j1 z_q7ykKGj$J`L~!eruPxdySC3`SJzThxs}#k?=Ac)W?gJ?eJzz|6N9UMss?8!o~UMI z$t70uFv&-(WDChxtmG#opRj*kbyl*Gv7W@w1l1h1o<>*<*Flw>`%Sx=us;*Qf=`JwEC$~(>9c}9m$ z7uk#NDG0k^Aq9rJq9DoL$nO?@_wu`y-~Ie<CXr&C4xHddPnv)#ygMmS7^h%-eryZ z?dr!&K?x#+fw{_*?Hr+VGxX77GryQqF0qC1;{)(lB3)>!N{~d@9Td+NJf0QWSleHtHbU!G?!4Om2)EDS$nN#O^tgc zXs>Z8m;;{mOTV;Da`5^=|8O&?_GZ5l__;E1n^rz zai)K@nGaqz7-xgiM>))Qq)03c^6~6;p!;-WH{@?fgEE@S4e3QqjBnNPgj{wdy)T^0Q;yJexk3NdN3NSZ!$YHmd- z;S!;Y++VQSDG}-@BxR^C72AGJFgUmRZm7Q%7pymu&rrFQ5nSOrLeud`veyGlbRQ?U zh3^PS$6wzdud8{@WE>_vcm5oHtB6H$*#JlCT&c=WH~l!P3QAvybP4_UL*!XbIg8PX zJP`eP*P|F(Mgyub1%p=nBE46`7@gCVODRnrR=E^NTCw=Pi8WePDsgLSS7r`66QVbF zJ#sXc5d8{|x*B?i4`aY&82J@~ReXz{5FM|gOm!r3zUxsP!Hpl&(hx%3406A9cNhBM^nX>k;;m5H00VEi=*ANy!3lt?znkmbrQcl524DZpslA zD6iF=U6JZ)GV-~7zF%AMpA^W%x^_Qtd(c1EHLu- zB1N;N?=5hBW8ROwOXV^am&{Ucb$PfyvLRJl{yQow3QJ4W$J-^Fspdhd3I2qQMyvUf zs*_VQt$gCojr@oK*Z1$`3l03bz?Hvu-mkp3(}=Vs4VifnTBo`BKSl3{Cs_m7_3A9k zeM$a)ZPW6!d+FWyLtKia0P>XUKq>o1K}A8)50cVKN?AHA7eR2F01}O)>vh#5%R1r2s_a+>3>*<`I@7qc!+8OzS%D^TVF3GZK`ej z%`eS_QRRg2;&;JesFzDOW9A&ct9LT?2X&2+gP?U-@ECVEjU7AfZLf6Y4BKzP+j3n;B({RC}PW3H4AsYs=AJhw_0@Wj|m<-|*x`fi+!JV+g;E}6}hfXvh&@#CaV59^9o~o4nmP8z{a>ki$((lvT1gDQF9fCldkhO@SyAB9tE{vr{~(nzNX5b=LINvL(beLE$@YO<# z?s|Ve-5tW_sos?b{%%WLdT81|u8Bpt)p{`|*P^m`mfFdb3h% zuXB4x$dp>OL|&^GLZf<(bAoTH6>`*cuR%>Z#=W+W^h3L z^>)XbRxf?^LS-}#SRp8gy^z12IA>=qsAH?Oazzgggc~H~Bwe6W4~;wseW-`MJWP&1 z?B_w~MSVHQ!|m~hW*&ro)R#|qxHJCH!h_J0`f`|uZ^a)XJP3WMFGqR!cKo502cb9h z*E%q}hjXR_C zJeZN-JH9hkU}TiTHzxSjEveC~@3oy$t&5E^ir*IAL6xvJtp{tfxMvT31|x-^)#+y) z76)Bg9h~e4rj`g98rx%-5wA1qqjKjT)Q&jr@(lt%?uFt`57mN-0II zTcJy?gF2SUDC%M71b?;HZ4M9O$Uq62Q=dhteaZR2=3-;dDY2BTgqjN(D>)61y~5{c z2K>)nD3nAY{4>5@XUM9IrvSr4sQ5R%9Ip5LOvh%IKcW>I2n*au4}MNwljV1h8Q7{OV?_l& zMO7~e+sJQ=J%m0uzYW=TH8-nT8$LCf%zM*Q&cN3SjDTbfq>j=y1vZo7T>yDluS#SY zH||Y0S4)kX;zaBUN4ina?HwDQGegR(EUPH3e+B?rKkr5br{#vZM_ zOfb-J*qoN0a?*Sfl&BYh^g-IDGKG>SiI_eJH7oaT+Kg%G3K?Tm0}W@5J$8PxOb`{E zKHSEMR$j3U8FPz5$XP5Yf*A^ovaP(OWjssKAf-1*^PHKt(l!fQ>;GxPa@D2ur(lH3 z-pB-6`99-N!;zE=j4T$8R&#;W;qmdNbJK@8@FbwRWz0yoI+DFpKRT%49D`I~tQH6j z)jvk8010(Kigkh;Q}h~vKd2m;k5r`UYx@GJUXaeJ6728LZx6KS zPAmPVpynv{wr9bPajxN0b6RrBDZ7_}jKT5R?*%bK96jhC9D$zfCOtN=0VZh?vzi{! zv2XyRA^L58?EM;3*TRhK0CM(4Z;?;4{)x5%FLITMDJN~Rv7l1hEhtfF1Fsrqy6D3G zEcfR@T+O8rCp%89e0BBzH;A(U(9aMEI7(0SqXYg=5SMZ>;@aWlYCTpHk|@o43I?bN zffB-M+NRj(dXeMQq%&~Yr1C^p^R7!Dq(}$ecCfn!M%^xM)upXS62g?h-`nu1UYXQ2 z?lztu100)PrK2iSzl$?X5twa^_inE@#9`X%*5|AJhu)fLR;-cP#4Tomi+1`vR-YJL znPdct)yh{U!vEC#Fb-z#aeb&Q-_9IUpWYOM*@nX~)C;{jrdMZLtF1y%&Mv#U=(7x& z)gP4S!ErBJwffkfElA8hh2yfIS6FU7FRo;&U3z7JaoBUBYi0Q2bi)X=Yr5TJv%m>u z(p63WipbonC7>+(!da|9=IYhbS>V`|F$4h@i=g~Qt@vK@X`9~6eTn;=1Um3Vf-k-4 zq{CYI{6r&vH@jKI(8u_iK}zsNMfX?285HEgO%EC8?0Ff;fP1fwFKBZ$dmal9CnN#) z$89#wns!0>1N@i&6;)Y-X!;{&#yb!GCW_g)cY*0^95e2nW}ehZY>5IM!*S zz2OL#uiAjueDb1I^_Dm@kyZ5;hgl(OgmHqk3P`$OI3qAjxD*VnY|V2m}yqSIwrqa2K37cEw{2lHXJd|uF?-ajr7f zPYCjt(TAg^>QraL5l2(O0Kbg_8}jI7s>ajI%%*}Aq>yqJB-NWZ_mU_yOhK)Dlgwa< zO|CrrcjN;2CN0H*H=43fG;{`M-`IstwIs*qzRd`G=sS!Z_h62YYz>ZnCRr=}EeM1d z7UyOWN%w2=#zhe)RD%8g34nE6KYZRw*{t;bjU0` z)4r1=8%$3dkL^1PDx*;S$RxcA!&la4@0Xzj9OHjv>2uO=5go&{qe&Hnm)U(@7Vk6r&w_BVs+%P+k_VV@8Sp@+R?P&arT7e)JPHzsPA^=oYis zXe>$=F$+c!pG&=Y7sG8&p|+m9>x6!+hcu*e#7e;z`yYUvWeJlwGULkH*?vo|Q39z& ze2jd?V3>bFa`6fYLeE)^zPS*q& zsFivcxNY$51flSg$QwJks!=dNb-AnOSHych1NyzfVf8_Y$83wB((Iiu>^n~x2#q~f z46S_Vk)*G1Wz)D{sks=T)ayR3*v2+-z-oB(+69{8xE(O zQdKHI@U|JR=YNRkc+KiCLdjAE15{OUzNa3dN8o#EKE%gEf)|@_7K0a2vC0)AbAbNT zb(oW0Mmo4sW-e+;4_2?il`?gC$W;$AvrRoiUge3D^a9U@yH#zau~nB}qI~PT)x-U; zHegu@7wa$b47U&boZqlJ0^2~Di-nB8IhIr4C|)UZ6t|@h5`C@sMZ_$2;v5FM+nA~3 zZ&v%yN{7qSy7*ppmHrlH{{(k4$Birc`kk&l-cKgD+ZJyUoz|U{o{$&url2lR)pB^Q zi$ITf<6DElhN_18shzA+`}6$x*9BJ!2Ql^0U0r)#7}tN>wNi3P*IxQ!*KRE9(YHsW zZ=XZ-|GIB;<9&14eOsdX=5n_!rEiK~7r#Oc|FVBC{p$|r6hk~eubv0`o+AAx zl}`0NLAq3>2lyT${hun`-EEbyU*9#PUsUNn zzRO9!tkO>3K+;P{V-<-RtGRL=+zaY3+-*T;Zg6ViAakYgc|++(^-%xH2p-@1Vz(U1!k7#UVW3>+_)EP^$ertmG6e%Gag;R&AqbH-N0>5NjGODYvrbZ8%Rx*hfStPy4(w;4DR4q0f79GGIRrt+rr248%PiydPB}z78 zAMmD3oXEATLMSJVlgzh~q>U3eLurhBxsCJhLTE?=ccahDkz_Xo{YVYEJN=6jSgd6m z5#=H?Kcj|kNU=QZw%RCwB~c&L+>Iz2aza~{hB{Bh5_cXwz1`u}3iPek9Ou3vIYFP^ zk?H#cUQ|Ij>u}jOjz^{Z_FYS=RzCPL@vM*Js)(>yj6=F=@*Yt~&A82sF76O0(#`qF z3?I5GgX`2rCDXZJfSSt%hCQYGvMo|1OYG4Tf$9BZQdW- zqYkK9Y54l2SaY=pv(Q$|R^a7DL2wE99-2ywR9%l+u$3mgi#SmFA1`#E! zy#cc9&y~D=4@5XiVxTC^i@8B`E(J#FJ?4hh!hAD^iL#~6P+z@swN1YiT}$vMoqC~g zbp)2;)vMv(4$LT^nFZHY9%KJoD*InP1!NjH%)*z*N-$kc&serrg}75M^5rJuR@4%N z^Vs+mp*N{YCXmDSYKi=(w?2lGVA;9&Iff8}>7X2-% zPSW2bO$-R{5dGXaU%6aSv22K^HpYJcHY-GD>^I#GIrA!-rR~3W?Jp|wM55~PEV~Nh z?_=D_`KGhv!PlY>+dGjS@xpMjk*2+lFFkj1UGxVJBJXzl_Y?f^-TL+b-@4nDRKZ36 z#pUVQvcDn5LT(1$%-w6uMDyFY5y0|kLvVK5IU{eQIWyJ#W}3NhJn>qL_s8U?1~aY* zuIk?@3*Fs>4G5WYMst#-%*6~Jh6%Oi-8kuP_U+0@@A!K&r0})!gJcffrvSO3^Wy1 zr8P9CY&WN7jla6yoLZ6)_;~cE4M&SZzP>oz`p;O%sH}{pVYr(cs9eWA$$>Du!jCoY zHRIo(KREE$UX=u*qu^iPLxBS=d3{z=L|e@ADanhKIATX5=ANTm~h)DP8eDs1qRK}_>HEV2p6M$t%M}!GEqWa>jaS6UJXV*Gv_{^Q$ z1q-ulPpy^S#h&P;ui^7JSLK57N#3lnj+*Qbv!y;MaJv+cT4`?_&tL1R;JTjtPRiIN z(z|l>@19RarK%-aVd8aW^SVrLf4IXm2q7VMt)yha#xf;^ppy_ACODQS;U6)TA|Vm* zBqVPdK_kVj^k^z{nqb1+CiW!HirlC|Y%C{%b6GA}Y}v}>uh_*O4gYyFM_^|dPLlhf zSXasJ*Pm>hWE)`ASALSz-k80|T76F-zIkw7w1M;VFXOzwvX6mJZkgTr72+Di9WuVl zo%G~Ba{Y{8z!)#ymS)TvZ_J;lSI<^*v+rf5Ww;-rXhLiyCAk^31}LJ>z{|P@-cICU zEiTq%v$Mv7=!xd!Mdpjr1y`dvd7OFw;>AgovBbM7KTS)i5@(gm$^`!Vy{@XoiNph( zn>E6mHy+eD%^y4-oOlBW$}~FK8@bYlReicS`MT>Ru5gSvT{!F>%-sg;kS zbQ)*T{W?jcnosAN=~=NWuHLDYr{3*~YR@*)QqfVUDM1VDCaslE9n|S+^c`ThSrwhh z6Yx>v+kw+x2FwZn$aDxLq;KgE%H7&eE+GUr_LU#gIqW9qaKwSB!<;uw9q#mD&zbCt z#(qNJpx=vH-Pad62ZnK-L*JDUbPku=vO6XvQr16R;bt!6-MDm!(1w625T|EFzXe7~ zkC1*DcRuNA^j|N)#Jfn}$gH|Y=Bp($c!stzq-F}lt2QTt(WMwG>9!GE*D%4~Wqe+F z>>bhdtBXwrW%Uk>??3Y{!eyD*Ax47tCnTsm1~;D`lgiznz48cU{gM;mRu z^8KS%W|n3KNZoP~R0$yTqz^#E{!{ds7@xD)$Gao;m}KeUzd8OKpI>VH(qE|uS5oh1 zOvGS*svgRfY6poQC0Za5t@K*uvOnF#r^tu*3Johks$0L!j5VtC*2fXx^41uhwY~wt zM?bSR%-DMk%-FzL3|jLy7{6CW@Id^x8BW*Ug@aJ-Ce2AE;MuZ4d_(K5hf-Z9mVV4& zMt0LdMBCzJduuNxc+#hy58o^pYm0;tDi~?c~ib(J=+P z6rhL68Dur5j+dL=okTf!NpDq-N#)ER=B0Nyebe zlep~@>Q#fWMlwd`%mGNd&w59$_jT@pCQXV1kSnl~4I_T|QL4Z(bhVIbD}F_Ndgsu4 zWh|UokNnnxJaR7#!|F&>3{9m*({%49q?$QN3c{~a1<>w_Yo*eU0E{~0fGH52k+<)W zegb)}R{RJR(*>fiOAAEKpdu@~T)YNAs~#$e_lDSqKO!##;RM1oAdGBb(Ng26kSbWf zRk<^3Y#jO*`7Q(`)FrsLzeSeuUd0Dh9DcevDHEJ?ooiscEhS%t`^amsoe;SiP9iER zXNla8)SKHPhZyZG)&B{$)PV68zxY|B`1GnE+o-=@KH{x=$sce6{I)!3rLgP-^JYn- z?@TiX)=G*Eu}B65Wku&yE*-xXo!noDJRIce*A(YwS!^9`W?Iq^y($?CC(KC)(*Y~{ zyaU~2{S68drSLT6V(A5CLd8|76K)oQ(t^Tb6|NkOW*YWt9|!ZQyGV=+t!Azw%b`NF zHl@i)fGQ%iVmgJDGwJKC@u}`fJh7Fpd?0-Z`9{56PeS3(oFL9z)XDaIC#vj{D*=Iv zhawb|q*FK0Nl?J&7*%c4tYmiQk%!FzNmEc%rj^^s8NuwFYpz>D`c$jH2d6Snv5=@3$#x2@g}VL zH;Vuzr5=E3ebp4=qp;-<>Jo&C=%Q)f^G49PpZ zvtB)Lg-Zr+sC-}qqIKQpJL;v0q&zxh;R%LGH{7LwW=Xl$(y2AmAFL)!8|8 zhH#pi&Y`pAx2kjKWAf{+54sywfkGZ{^6$RM-*}UMe@;6^at_^u0eMGJr!?PQ?;T-G z60pA5Y{iDl-<|sI-Qj7?6h4N=@v+N0+)P9`?jO6|Om;PSGmY&m6O=x2alh@_I4m^oRHDt*;=$@2yy!uk3{z6NWsWVEWtwWJmL$l*I0?jz$WCA$Eb zY7Ic_L)pLDh=%j2jDlRdqKo?bxLxX_Uc*(U(Q1N70-VU>akSv627&sR(@wX6myMMUKgC&e?-o%7!FBBo71>Xv#?*% zv}D)&^HNZlxlYdG7tZ4)K8u8_%>N8)Rid<@RI2`#h@;61E>=tx6ipI#>$%@| z_?3wyiqwK2@CMmhMIQF;uweFufeOebr;D$y7H*a&6>xejrud6B(oZ3Br6a?Y_U1eBS_w6Aci~QUZ9z;92XiY!x$JiqP!axP$<}MJ` zQt3NTP_#rq{F_$(0ND9fIt4Iznbao$LcRzXgO_dniu7y;Wr8& z|GV%j9OV<?NXTicjO$#ZnJrB7WK3@RAMME z8!Bu31Y5+lhO)X4Z&RE9ym#w_k5o6f&Slfi;Lb!n6gykt67mf#A^JVemEIj*dd79@#p+AGfZ0}u#XT9Fr^`m18&!#N+2G?|)S;2c9kyIoN z>Y0Ya>B6%fDf5Ky6LDf)cy^XN&G+G~aYka{*?YXdC_KBsyUJ*cSyI|u7(_{E=BomU zb>Bqz3tjw7txJn6{-Hic@1YfokIW3>E@Vdf3WE>?*af9JYV9ijlS`N1u2!I_ z(u%uLir@(WaNN!4=l4Cqt>KoYzyI=3^MOV<(&=i4H~n9kO(?qdO6ywsn1m+~En&Jc`mqQ-=-^N%^kM`$p>M+UTH zO4t&5yT9Slu=UyIywTW8S0WPg!gYZQl-&R>8D+H+ zha{^vBm#d%Pxxc&to)o_^??5vthh&|z9X@sFUp6=KLD8Df!@n^-q_>K5R~t}opIUD zSup2NSlD%lg`2T)4flQbr8cjPU)r&nL6dPH&deo(vjGOL;~RyDD5 z$gn+}3jkit`jTmX`IV3jv{DmW`NjUt$>~%Si;f8oWQ~jv2S6nu^ERjU&8JfJ@bJ^s z!VbIx3iPKk610*gnkIA$7xz73Jv34j2ft-gXKM;hyPFHer_2zpFR@h)T*=JE^H0`N z<2EM|V*D*BSbV=A^r5IkG(E@yBH#4qCBGteCvajEnF)&Z(AYpfgq(koE#kj}+HvVv zC9x?(j8%sH&G;bKiB1r`;wP@#dyCr{XW88x(6jLJ%Z`xZO(Ot-Un*> zU2jQw3r1i`%se{oASBGTevurCxGu~)E;;Rq3m8`#@5kpv+QoIo_dtw7REMIV7vbn% zs_8d|CSt$j+347EPhMVL`%$B#vSU>CcE?B2G;&I~>Zd?bO}|XR*N?jJWo##^05o58 zR(!>2C71D~M@O|%mnt2_MXg?U;C-d>XRBm~s1nrxXQyo>OCqp36^wUDqKa(NlICXL|u}!Bp2B#>p-hrn}GjBJPtwH4j zxVMg(T=6jJ=q64|akceHW`KKsoAO$&J{g=mHh`$^nCM!Ps=ncJw`9H!z>a{Cojp;{f$5NrqLNXnC$JRABX2J$?R$=AQ9bz3-KU9 zw##{aI+tt%r9(AS9Ag9M;}ZEynSZlBI&rrnSZp^AvO!g=g(AVo8yJlQ?{KiV95qf+ z1n3rg)xZ@K2VFi!wOO54#vI03ZCg@=6O2yR!Fk7_J#JM{{gu>KP-fM~?ZUm0horvS zRef$4uNGK3Z=x(TDJ0YBN!IHHsr!#Uv7u zR(^ZBEcj5P$PcHlRSSN2Nv_<*+s#UOg>jM&My{e^qeFa{EIndAS|7)wakAnD+KpVm zKWzM+&427KEqsanwV=#yGxA6-RDxQTm=MC7k&hG11WV*NEbCtuJ4GC&aG;lmOP_nv zapV{k{A=a+q{mJ&v3s0fSo4+jAAcmo zBeN^n0pFFp?%PN=ZKYqEzbeuiia47=+i>t z@YgBUqNJ4^gB%43CFe+3I2C>$m;W$E>$Uz^Xew?ZGkF;8gh)sX*7oy4!J-vEPcnE% zqMD#^#`dGE^JbT(Nl zsg;uW$vDohqr;ez3J8Mi$Rt2uNmz6|x>JhKKN)qcbSoIP`lR9(0KCzp&etP96rc}x z)lWrZq@vHToK-8EtkttbpjGuB;B_xF2tEf;I-X&xlp874S^eRCrqs7q-iLrfb)fhm zQi@)q-ykJjEa4Y;l{^@Hs&n)A3knKm85dZ<#Q#$Z9+~o*+oNh+mG`E~3!{vkm1h#O zE4{-iBs1M^k5--;h3C8M_l%vsqiVex&G=96Ahh?lSzi-fXP17L*Wt;EA;Kh;{@-LC zJF~z^+wB`z2)NE7Rla+s3cVo2~sw++*QeIhAe{Ypm5j81+&>%BZ6F~R`Bp( zaW!{Dn4IZuReIK;Y1V$ zo=_pneXP*Rc_LEC&`ZXO?u^2Zt>aV+UM-+gWZx6A!%hRpeVk6AvA2N~@GL-u_4Wo* zcE6ErZ6M4O2eQUH(`uSFopLrZi1o{+k76QG^dce6OR{O95ag-M5(-e*nI4ZIbg!Y_g-5LsvuG-##faT-gM++L_J5=RC zRw-VhDX=~LhpCR(dlo>^U^X&iRE zOx)ES+WHS2%CY7c&-$Fu&f`Qn$>|j5ZoUo5rGoZad&A+=m587hH0+Fh8wTUV#kY~u z%fK$k*u)ewZ=<$$yF(oBZxGu-|HdsEP3DBg6sMbn&i}OL=B!;xWLY}rcLS6h`uy3?EcA+k12yivvemOdeJTfxUKRV-pYH^PO zEGGq)e@GsICwc`$1w3Z{dad{kO8^pO{~E3IBbl=AdS2!_&J?_StR0iL0XN?zpdX)YL_1X##6uPUX$I??p`ahFqCiYbG3K#Ud9{IY4^H9tz;Cr+TH6!_n?*d z_{(d=rp2V<>*GtUGQpkbZDdKgH?mwkb27E$8m4xlcT|@GMyeeT^N8L!yFr^pK~H zbb~b`@_7s}ed}>17Vm8`Ui2GlJ$aeer%`{l5Ett@L29@)KK`I3$ISt}L4j&TM#R{-nD zAemTFUKLy$l??}3l?am~O%z)%GN~exDKF;pqCj`Q?1+91UU{GqfQO)s;?8R1Nut_B z#dLvp!+B@4Me^m<5MG(H&`DLO=}*MC^+?iJ)VM2d2>P}J^ETHcj#ZbZ%~`01*2fMB zkubG=2ZFxM_(zN#Qnc$?8~vLIIUBzMFunO@QLE@NO)T>KBO-5z@-w06(d2{&mAd*` z0R>y5GrSj*B(WUQwxuaCfb#O2;R5I71yNW}3E z&37^-Lf|tGrpC33YTD%zuNxi`wqkZk_>WD4a1p8azqYMX+7x?SVIUpXXeIBHrp6#K zh)&sU*ey~iJ{F|#8pcybPPEN8fbLrM-$;*7+|wfnQR5u<37na7-{7O3;;!|rDo;>r$u6& z>hf&h5|zL{94oP$y5K@Fys213%_t5$`;CK`mPc-7R!LzojX}ZLPnj0J^o>iY*g1rX4!y^;Uk%PcB=5q<66nL zdCwT}iLSC>B}8+1!~KP>tm@@O#UZl2`t!PAOw1VxYno(I{(jN%=>-5Q|-t=P{Oo}C8!*1eL8nu#5L z5J!%YA1g8)5dFSXZ?O@p;ssq5CrJ@4IL9e<+U~gVu|>4+c)bWDFG#w>=Y18zFctA( zGz|T{3xgE!`*qiU(fGZ`fd7}{cfK3{m5BIdx@Ut^(VEnIj5li1w1Pois1NEomrVO{ zvMSG52&gbHQ8gHgD^CIV&1+imFmrMdg~Ds8bS$m_#$9AJ%~e4W5o@RTc` z-sh9T`8xE9%5T!$$p`w$?C`AJH!&-+o_!MeWPUtER`gMd$wSi%or)ZVSWrbGRB@x^ zaAdg+$v9~e_`2#A6P4f`yY4(ycWyWB_mR3S{slkgL7=w=EjpUVu4?{GNTqi*23rLi z#BFSDy0T9FV%E~`-mD}m{F;J=XTIirs_@KBs5clCoAFwt@<*xfmWm8v&P?6BwaDmG z+hoJja-9s_dXAjhBC91t%0U~12^4`sHbV*t8m2bucrM0U*A8YkSya7o>i8Dl3ZHR| z(~6&i)_S#ki?rOuX9J4QHlvU=hnsghi2!a*-{^1Yqhf3Fio@Ex{m}{1ZFj{Mut$}c zw_8eaI#)S-H^tY6@2|t=a&w3pBi~fl7Iz0ZbC#OhMeU0rBgzA$W zSRNBb(HN#ZHwqThnN<>62N|)uWqun!Tg1XH`*9P5n0_3Ct~1rU;8d;iKt3_ewsKD5 zu9r@Ds&gvGc&dwz0B?d=fVSaQXlqgQW~x2lt|+N%yk<95?;qGGfBQ7^cb~g{|G)@| zgOy7L;hR@Ix2fkQKfd-nd*0&Cqi1*16TA22RX07cr|HUfV=uOcH z?-@%fLtw3}{5ailM)y|_BQl)rhkaotPB#xY{~7vy^kG0~s*_^cbGP>qnkxnq2u8W;j)`Z<6E^)#b(ETG)wC7%=SETxAr9YR{6C<1) z6!}LWdpy}6QeI(yXHk2cXQaoRI@P-ldKY#ViiBYKiw41r+FI*JEVC1&xB2z-7TpWt z7;3&UYajwDG962EWH~{Wt%1-sSuev#xF)Kc2+}B&yxMz}l7uynd-Z8|EwgU5cR+=Z z$r$%)9+>Oafuv{k08ce?Apn_fh_po@kl{kS9hM@!Un`o@0VJCuhq!R#keABSHCalB zP_8Lt1{VW=<3J~P4!c)LUk>C|G=&-mCiAATPpaTQzqaU!4-yh`#htg*K08$!s%`3% z&e#3p{#wBgqi%!1&Unv82H(B=;KxmMiU4esKyIAxg3N=_rn*2s&XNpw?Y^k?++R>W zG*vcUpCA?0?Ta30LIuK5bCt2FkAP<8)yD2p{JSZ%|Gk6nH@)|->y_}aQt6|YsPvG$ zt801>9grOHG67na{_#Mg{72BJSRx6ghUX;^7dQ%olcDicPrx_Pihc5!xAuVZuR@b7 zb1Rx)Js7!EMn)Bbl=s!sS`pQ+1oXy%X=DSX_NZ7C9OsvMDp|z6j%OoSsOgsjBEoK& z;gEMIlOJw82)X>@3X+~xSSk-^op$A|*GeuI$|j~aUw80T=6G0g<<-_C@&R|fnFgMI zVF%tmrYFnbQfw%tZ&9_>Zgf}{1)gMcuy|k1Trx=M>69mY*Y>6DNZ1y|M&7)fIu*w- z{b^WJPwuSj=tH1wF>vA5HQ-em9mvDu^^ntWiH{3+_52fKJQe7$F~6=P6o9!{Pe-3# zBF7b&m&L+UkWHkA>*S}KMUBpqPNrI|8DKxexM(F<1ah3goeu2p;hWOYg94O0)6C0K z1`%RDAosr#MAXH|=pCkLr@aR88epvu=7lZl(x(fh%G$S-gz_D`mekMOXPxxBZz z5|oC8h_Fr$U_akavkjF2|A- zmwTtb76t9=W7 zmAfpPzcO#Bh=B9xE$+9uk`rWcl9wxU19Gs*i&^rN%n~l#P_s;${xro1S@B0LeypN% z*yIPXEYGgjNJ8i($8jEU(9fKhkFlFLX@kFpLMDOI~Gq^Du`OEPd;>2k(~7#S6q zv;mKIkOZE)EsY^BN@K9cxYq<{oHyNN`X{5rIpofuGm&0iB@ijR$m$(AEfd<)5(g=@};_C1nWlXlP zJ;#&pDwx{XKpJCV^E1eT%m2}DsTyoHXmdwlyC#I|@4*6vQM5O~9;2s(IQ`Yxezpby z-X^pkBFIK`EW((~2g$^jHS#5@Bs7bVzXrt-nHYk&OsE0oDd*@f%h*F;ZfKQVk5(dc z8vaV#qHz1j@F6a=D30=Bw2CUrEHaU@4-X})MJb*UDV4qfrf0QGnVV%<&D+R|5Xchc zMc&2%c_Tzgl6D#|5yfe|qooz;s-;>4!VLjf@>(%mR#dDNe}hkqf6pO7@<@oxphedO zqe?55qf&MSU&wI-IgE*4cyH81(&bB7xm0F2?YnC`SpIB_au#Bw=7?YB9S#HFaP*N8 zitG~!RZ9isF#0Ns5x(WHm5eIDa+K#0F`M*IfRs5iLto{s%epy zqHB3YxB~{Fc)y71?4HmU{b2~7J`ieA=go*bp0$mY7fUwM&*`*<*-P0vCLQ2L}Y!QTiUy5cj=&m(1y1$SsESA7Wqnr>5 zemtu#CL%%7VQj17jAT{x9hsyE-J!;lmRKhfqFb!%DdoxqrWqpAHNF=Z9-M>LrxxMv zm@UMaLq%4}YjNe#yqt1l)oKfL`3z@mEEU3O;lgV1i+n_G+s~EP79_z_mu}K>Di9|#*!wm%~Hxl^^$dwHX? z2ctHq-gyG}VOsGpf#j-5=xfIUV4HlNyf(H_rN(`AO-oA&B%p?o+ zMa_&A;nEt3W$h1f4#&K+Wj!-*wNUFPh?cs4H9L+$P@DctnnNpHrdG^ak)(QZ+Be8x zb6TWE(_P)gUK54A)<9S?lWZ84LJUS#^k%lksLux3T~YLCot{3xDf1Zj@|;}`cfjFZ z9(@7IlET9NCtHO(m^$!hgUoXYO^5=j0^?)mljmQu3BH+fxS#>wSQ^a-dNf69^vZozaTWVaQeYdL|E6J zJuVI${R7L()~`6SmHbP<`Q|&aoWtct3~vfeIT34@;NS-r_)G%qb~I zK3c6<(`tN5aUA7eXZl#$afvJ>pay5=o9adzh$mv0V50eo&qDq$jw`38sWQ#r4(jdZy*Ag@Cg%U6@E7tuR zTn0z5{*d8Y1tDw2AIP+IZ(#m}G6f@X;1ESE_?WJ;h~EGzEr6UdnIgl4-}G$%b6$us z!-`~hs;~cP>eNck3!k%)0@-(Cy%)-93as1h)S#+s3?Z=WBb3)F?KwGkuyqH|KMFdv zlJD|&oxm$22wNZn;~4$A{7zOv)fOgha9S#wH<2(`A-n07sR~mHKU|+?xlUk;V80^w zyCc6B=}>(WVM_WZ;=)ZZ1!H^k*DMc$3QsN45SNuLMA__VIN(|n{}ah3=s;miemh=$xIlo zRh1wjI$75EJOrcKngo~7Z)LPZmWwIrb}12-MAlH%)0MW+k4m??JC+KN2_`ZMW7A8FsIf1G9z zAzd!`NxgP!TFD=%FnS$td#D@j`_B@LF|WmUSwYd+&V+^c2h!AXQHTF8G3=U+(;lw$ zi3OFr#lHRndYJ~$6t+gBm4%MX5kb3ppUS1^HC&&qTebhG-=kBezgf z*EQ+*#q6zL6*%JhRP1xHO|=WUcUu*)H>l@ElsT5$q7$%Bc?==Gq|TQfb2+LU;lgJ+ z6TG+LtlQ;JTkus>d|LT1xr@MFurVU%qwvU&-j!bH)e~(^3+HvI#@OD^Siyt^6bzc; z*|3|Vxmr3H8%#rs`+R~Y0BPne@eSU)rTeXx8e^-ds4TX!=jhq@>+c0WIj7l%<9)44 zIbuup4dXIK{KC3Ii6x(x)G1?U@5iX!8BF9g$ZJ!gXtZ7t5d8=v&;E{7p}!@;dq=?i zcNueTa4{=oS1ry|QsJpKLzHtSr{a%t34XB}?-2}DaRphFL*}R#1fkIo8AFgG{>JLT zAwwZ!nYWvGQCz=-M#d5OOnX-LtCwsK_c5{3vVt&6170;oQma}Y#q*4hVHOszStjoErhwr@glqEJi zCipZk)lKLoB%^rEL|W~pYj3_ej2SnF>sI;P_XA181Yg`I9|m!6cVW3XY{6H>F*S1l zP}KVNL3WchPKwGqA}_1uWa$T#9yB384Sm)8zLxVCq2)$fxtNAUkJU>ij}~j`*#b^g zsJ`B=zE|aPzReWc8GBOz>$bnsTSu#Ia3xFmLO)O4r@^2-?MwD;S*I}ApwK5*jg#R5 zh&JdHgYMIjD143^Tin|cy6-(*1fR3yzHhqt^g1(S$zT=G9DQgNmsd2`dy79qZi)OB z9%hWdy9CNkZV2{A?6knV}Gg;CG6|vEm3M8{6?%q|6XlE=lmNzwZS6CD9nB zSEs4l=4xZwv%kvI-<{`!lh3OoP~4ZJjGMtx0PY0$0ZQ-om4AiDg>RwOospIknlLj> zTcNI-;016p;zyF0=i+n`r%F}aHO3+>IXL~NPF4kTdYMzbtKc0AkU4dwlcTQ_veB+) zN1+u9t0EK@D`r@XYDA3q!1`&nep=)Q@udCBW={O5%e{uR&f!KFS<8vpV4~Yqp@LbP z(`nS_>>?nbiDM&K3>(Mz8n5*4C(_52epV7y6{aZ7=!%++98oIghvvUZcsCiH5Kh2~ z2r=NhCFm@2xhv*>MHsa&6VS}Ot+4@0|7woF46wf*aboA~s+`wmvN;ex^PItQ6=Wi1L@+|n5+3+v>-+@10x^LVEjcwGc zA6JvCi;AIN?km3Xn5=)$_*EO33S3*nTLE+QGUI0T%;g;W&SF($%yz^GxXTE%9E$Be zsF<`c+%L0!;!neOKHNv@69)OJU0z*ytP=gS`Xrr?{YJ=8=8w#tp^s1k;~?!7DWPtO ztMQ1uU1_y9<_qm%UR5h_9-S*pQuT)d9cmQ+Lv&S|# z+MeqpZ+Mt#-YniD(AGBdLVQfgVL(TZ^qR4#>~DJ$NK_eFuY%6+1f7480tyS_&4Y5m zM>!$MuaahNu^V*wt~PHD@LBc8Rtb0RvA(uC#ZSgj$^R$2Y zccv^IW{!I&b0auA?Y)n4WT$$FU2FLSJ=5@M(D^HLz6p3RuWS~-E0I49kU3)1c&{{; zIE@FmQWyClye)jY$fgNc;mglOf(3&CDO{pX<7Cm%2Wh?XY*H{it>|nf1h(*nptI&x zDG>XW!mmY7AONQ>I8J)TnX>dcTK$~0!JOj6p^w0C3^6iPLa*lV_B;7e5qB;93~zYu z3*0@Pg>d8im6!mQM;ca8@zE$=baT^igiwuAir6z5)#7Jxq^Fa+Up(d zk2X8lYwdP44n7ITXfT{B;F>N^EO5xMWo#2!e^;oLMO@ytkvR(h?kYWYdbtcHp&0Er%ACFQKBo)sZDJ&^8V zt@mu5&)G#iu^5!qfi3)ooUZV~Q{o`WQy;uDJvjTt^x*C3uAM>eHjWojF(4RXaPq6nEAF_>{>{Wy73^|>$1fgByMh8akV%MJ6g6X@%yW9G{OiwOxlh8leVpovD=+gQ?1MiIDhw^X3p! zn{}*T^k=*^YED-8Iz)Gg@P?X{9BL~DSw=oqo68pRa}oMOyFI0| znaF)TMOEI%I2}N)kGv)_kh^8)IV0@*9anqe2f@w~FD}4(93hBA7Ws(WLXuj^9Ax?U-I}k=e?^bi$?Qa$sx-whSekLF@?4+b;v|Q@4Gz=!0E*eJ2Sw7M!|L#U^2%-o->q*AI^}eEWmb&2+pR zd*^J_zfgSs((ho692O3X9+Q``_?z}2wuWUN;4_f)~0NN;o)?JM#>S|{_K zwCsA{mx2?2Cd@W?A2Y<|3{L-sQ;#CtIL#c_jlLnShIwtaR~>wsCX0Z3d59N!t;3W$ z?RP!+pN-$?GT-x4Wyj3XXvD|(i2hAorPr3<4y(xNG@0jg<@czM1-;zNXay2(aBz(^ z$Q4lGZ^&~@9mp~0eU@qafjLF-QeSOwJ_xNge4*e}oe#S?s&O}iPb956lbE_g%#k^# zv-e(pVoYB1m7W&D6Fc!&;Z)&f$%)ZITpk>b>6gpBdto*DGr6oqvocvZnQmEtKbqS1 zop2UMQ)M(!X;5}kzrPWW5*hI9=IpA=_aL{miAG!6el>&nTpz!66hE)AoTWupp}tW_@$R!ZYdDu1|S-e&QS;5PjLH`!$8BWypX zlM?g$nopl6*n=J!;GJPqZpoy0!>8HXi{4lD?vx;W=Ne)tH|)AonsW9{z!`z3bwNM# zf%C@Bh8Q!`*U@l5%bJHev5Kd725w z|0)yKpKc7^ax;aqPa4B}ZM?Ou?=>8i0_nk@WU5`6J?xOOC#~q1GJvLdj`q&yD+}B%FNl%N;X0pNamEiM*4H+ z+-F6WX^0VD!*>X{f>WPO$DbqE8lky~fRmh!Zwag%SRj4A{n z#L~;m{w&S#bs)-w!?uY(pKqpXTk9OPB+JTPc@S5}ATi%eP-2kczazxki|>3ydrM7f zE}xn=%eF}NNo!<%L_Ni>f<4l!qG}tMk#2yyp@8| zu9qm&qKB|@kF|0upR_&Whl>10c}7MIP-L$X5ly{lNZBv%ja?zghP0So^op&R1*yX4>yl?cWyr{cihrtNq(- z|F+t{pV_~o?Q$LVv(tV~uz#vd!{tC>J=}r)P;80z`i8rj7TnQ(f{WF-V%sILCSYqYP1m7? z)3tZPFk%)Z-^>Xd=RbEqu)h}umHqzZXASric3wSIt5DzoB_4?;MHJHVOQ!Y{v0qb; zy2))-&wUi^^E=+nq{=a{yOYFWIn!`d-lkylu%CHr>?L-J{SH4HB8oIbR0ebr``djj zyvg5hG_)TUQQdXQI5F=gmwW%bYbl;xfBE~W1!=V*BJmu~tC`!JQZGG_K!FWMt6Zmi zyI_yo$K*A#6vt{@hqPr^!gk?T(NX-yk;$)xPn3_K55~uAXOAiPzQK@h&sN-wOLBR5X zLZhbr2oe?7O=aO|X*l8v&+o@2)Fkd7s%CpqhJ_T1e?#7j1lKj8_{$Ij?1V)qSy%H^9B>!``mmm?-9wefyG%=F@<(>R{kjO6b z%W-x>KmM2TkbfH(A7Qh({9pBMXJ_bEiArGoY0zlGO5H0aotnJK@xy!wfLD?awfsi(`O$3XKUS~&)+@Qk>2!p-|u~Il6Lm%ip0^$ zfj-~;b5m+fR&>A{&n^D(zYU)L*#Bzp%mbnN{{Mf+E=wq-sHR9oYQ{EW8AAz`q9_tE z!&ry0Z%K+arIM01w4y~KrAVbcinO4`QW9+x?c48p8NGYIKkxVF{at>)@Ar@2`%aIZ z=XLJc&t1+v_snoUG=g)UrQ>~Kqs7BWiI4}BGHPvxmcrf6H7kyVj4D1MvA^|fmfoF` z_C41mqxC=GwRo;{x=Mz8OR1dyQXN*H)KMg>-09-Lcb6Lqc=jD9m7bTBuZ>%M>TA=8N8IT;_m#WjZm;9n-udFpDV%k4 zPO)(~QMUInt@Mt?{-zmqTk2VX7jNzR(sS>&e}~`HuMI)^R;zuE)RcJK57QB|d^$o@ z&)s&w!E14Hk4!_v?GIXrj8jmMDPKvIy*9Sk*QscQfGT~*`&3pd=cfFp#zh&|8YYa% zs3|y}TX$tBt7yS8x#N>eT+f_5!aseEnppDcMA6ypvX4)QZm&HSZe)G;`O&D_UCNpd z#1e-*3{#Tve3E41wb{%+P%hWSKUSt%zIE3R>9leA#DHU&l1nVp26ol%m0IQdmNN2t zg@m7*6Zb=<4=*9akU#91L_koa>YeY++PBxZ#NJn^n(@d-&~)n4r_S>AQ_D{dy}Q1^ zqkZqad+}+vc3-ThXU=`wWcS9W^p=lP*?~tA#q61eg*NxKu zjh8u7xXIKk&zO6A5ou8H(bMOx^~+eD25F zKLR+@s`*2r9}mcWT`O1Tm?$>8qDa(;qv@0LVTeb~ENj2%52Aw1X87OAf9P@#e~Y`x zyvwAX;gDaJcPX>9acOm-b;plln%dhlXOb&UU#F!NIULw~TtnQj=5(4w-Hi!OjgDu1 z8q_DndKZ<<;9L|@^>y2WVYe(vuR!7i6d|SIHxGJov0ru)WeS&&@5WO^wh0 z(Zsg6lPT|VV~!?m8x_>a=&Fw{&mF4)V z0D<4P;K=*{x>2W#7ImVuq)Z@FO{v?^s;N-Y?Q)1?@GBZGpyxxkR_Tcf`kshXwKe+L zk{iF2Weq)@k|ZC~m^YT$S!ntrraP?Mrrm#u>Lm+Ptwv{YyO=J^cy7lk9lMIlYK{*m z$;z9}OXX7%+tm+LG%(M~UCL(K_LPp^kdr>(W_rpXX`;&2hF&*qE%$TKb%&NHN4L_` z%KYrT_t+_`x5}rd+Go@?D&|#Psr}sYGOhCSJJ&jH=!mwMfW~4+^QEy+%nY}kZmGU?%S!Hxpj-JQ2GOeR68b@B&u#f8` zDrNBtrB@!(u(|eJ*`a2FRs0vY{j?laj7+TS=p6UpAC}}OC?jcM?01sGvejs&df+O8IYGT=Gy0C>D86_ z3U+Rt?(+N|s~hZwz;*H!;Zv1dx<%A2o}UlqpHHxes<*B)+$zzgv;I;su|FwEwQP8@ zMaaTZ7vGHbsHqJNe3y}SI?C?xhO#?#RL4D1Bg~YDj8hKu#O#gS{I$0niZ>0p)bq%x zr}N_GoQlr7=?(8Y$|Uo1Q`AldG}3o!b!x466%%m%uubr7fvVfbNm^DdEryNW*^-x* zdOG4OCA{ugPrD06_EqGm`lKe&G_$iNl;mG({gl=C&A6)j-r{fV)nx&B3Ex}_x0y+2 z6)t5a9V*aJoA^dq(m>ZrYh+jyUGjKKu+6)gfH{VVREcIC(yJxo_Vs7g3Kb)nmR-NxnC)jP!89BS7xeSZ9B`z<F4S#aBLqxlwl5w7-w7Nf5W@z)+imfp@>HBTU zHh8P1?i;6-e5Sdq^6l=Fnit&0Z|BrI+ZxWalnwq`lOxAYOxBDqOl6f6HN0N%qMm-tHzX@}R5Oq&nK@}*00f)aEmNpwNE zmB_+zHQ2LSaVbB51V~VM^VG4s? zOqJDX-v`I8FBvkcHFjvT)huS+#0^I4H(fJ1^-;#y^tB~hCTXSFT;p@5JbMwA^Uy_x zf+af{h8OM|Q1Vptlg>KPi|%frJrB68`-q~bxAAF!M$U%3vES*PUtM)nTr@n9#{W8JTWtw17;N&Cj z391GyCqq6ozpg&^xM6?T6W1cswt$B3&vboCo{G!GwlZgEb`GSrzMh}C=Ow4d<5lb9 z$?dmSzv@UfJoMs>tKajkl0o0D)ZY4<$=~`tPh#GWi3-C%tH#!UnQ}4nQ$)V&N1G0! zdud|DTTNC{m!gx^o6Q!|J$tn)-+kVa^5Mo0yZ0V$(G5794)M1AL-WraF-#rAP)^loO~@(*si?KWJaR^j`iOXD{0 zycn-_|MGNml`B>AohrVVZn>~$`R(&t+7-{`9-UR0b!h{7>e|&eiZa*2B`vF_2Clp@ z{PwwOol_z=&C`#jMtu$3IBAOZreWhd(sr61NI&H0we{`uF-sDVvp?4s1Uc^2N_R0MhCw$EAo@%`N;J3KF zySA3^sR_GS{A`%S@$ww=6KifPKPmg*Mxn{EfkoVb(~r&Ltu62!Q&;M4qkLN8y+a9o zXX>fr$&F=+&1z@vFLF8iNHiXoRNV=8fQ`N46-dDC&GUxsRP$qq1rozO*@IL)f0f)XN3etYf9jj_PJF zyt-bc*vDi*4Y8`wk7++y*8Szy$6X6ntlIjNb!*j1-tlJRM=o|7s@dc9qE;%jK7SJB zJXfy%mAUWPIUjd_)b6^Nwbe$8Hpa!yDf97r!StnRQtz%T$uYmHa_(#3?3yeC?UU*$ zmsHZTvX^R&8)p6ObR5+}WYdNog%9mExh&_wJDl0M>L)gipx^$mdyRi};xFAs*oW1DeP_?!NC3!ujP0F?_o>kmxPKfuDpIo^(z$WU#o`G_eSA36!O}HY) zvCS@Nc$Xot-1y`6*LZvH*Q$*B^Jk4aB|qL={KVzXf_-~e%c>18c(80~osUs!bgg#J zsGu~_51J<48@DH}W=~Fi<(xLb(ZljMUGk%BQ|_#hr>ox_c-ge+`_IEn<1 zds%AJ71B7__8KkW(}Q`>rg`qnW(Rz_l6ZTlui^R7fyptI47b*N`xaO8AC9xfX0*Q# zTfH`aNGD^+NAu-kyT+N7X^iR^Z4o_h+tIq_wbu(=^-NAIc(v%((|HB)_SScYz5Kx+ zZNindT6O(>Y0$$T~b*rz!g-RHM1H>NuqCrWR~X$#UDC3SwKT;KuY;(aaV zXU?zuDn5C_^r16mzdPC;IYu{KF*7;3Tsvb#!&d6dYdz7E@@>wYqkOB~?``3)wkZ8W zjFFbz*7Pj5w{O&+iVq8zto*RbFxlX>C7`a@~vu-;xviZvm!m$yt$d8 zY5B0-;-lA`n8}~?N2XcaKc?w$_TKgv9hW~9t=m0KhAZDSOw!MGcln$hrVk9qB^hkn zly3ih(xh#t95uf-wr47ZxUGvC(xQKJl40JV>B)-I+SsDhWr?Mcsm)IYy?0&sZ9&KM z46}J}MoTQ`TXM|q9K5;qa&;afo@uf4o}1={prSRAara(dzbLpjV!?o8yIWdE4(?tS zlRLA{uX0eKeAFS=-4&;dF2_?6zUS?Hx=mR_#xUD3XpY+YoFU#TD?;v@O>7iQoPO%| z=B{O8(p%a}jxC-pw|C^EW2!c0wNrH#1bw;i{z1oqRG&Gc@(QYAZ_0*m=A80=BOy*s ztP@d^wDi~VoQd0{=bV-dyf`e_zh^^-=YE4suPuA!AFS4md04Wq`EJL^t+frSrBB#u z#~+J3^Q=Tia^u+%sUuD*c=;Dl-*%r0u}LboXdHh3&XT}KtuK1+6wgV#z2eFse#U&S zfZTK6xSwK^dDmVJrnuU9O7I`g|!NXfl338G%L^;1}M*TbT9k55Rbsc7r1nPPXW zYvopa+drTsJUZf<`U3|6FW!Z+pV=^5YlLc|BoPBK-&vQl` zI^nIuihO9Xk@6r!BBPdC)_GS!E9BUUH4-O^M`fLD-QQkvM=x6P+Ma>LC;fEk-1RN; z87fQt*eZFS$Hq{dQACrnRt#M6TVY~3Hp#a*)(4>27l zVsWrsMnU14EOn)mZ}C{FU`5d>?>o{rIjvcX8b8TTXtp1x2i(la9+R zJ9);{ zK!3AXf0x`=`D&Ro=^wiW5c%VlNM;`E8klCeN@{QINXlDZKZ%O(AGl6#2|S<5VSK}o zpa6+y-|whKuDPwm%A9=I#S)Kf3Jqu0%W2;~IzZLdP;|z73$a*_CXdbwxjs$v=t1i{t^CSk zDmg{#%DfYYj}_Er&-Hz5SS1^^rBudRbd1Q5Q}e_%Cto^kQeJpQX1w-smrbrk{$dq% zKXQs|s_7FOGS@C_%pbACtD@kg=UdGP|Ghg!0@DWUl$OYQA#cbImGoI5PB;zPa(2e@ z$0f0Y7a!Bkmp!4%+*G@M$J4vza&ZqkPs%)K8oly%?VUGw9#8RoRP=Gw{luVUJ;=Z1KcnHE%R}=f8E;0tNmpK3zC&Ya<|XUG z>ZP>eA021Tyj8n?x+2-3D2=9ZeD8tNHHP9h>Lk(}8=WSoH~5?_@{XN!ku#&j%~w@K zOQ5~^xJ)_Yg6#U;F5*q9IwGAZ8GR$Du)8A-X5{HmB2K)1>^m zd5q$=!D<=Bb>fLh>C06!7VIGMR0?!HKgctz+};-D=JtcnSG!}uZo1(jpSdMTW6!!Q z_?w>*Js_W|<lG*x0v&z26C#9Soo7Wg) zTG+`9>yG*1-)>WGaY=QFbEB4NSB#x_2RGib!cJ$^14p&Xo0XF(De|S}2h`gW&oUb- znAw-)Mwj;34oJ`0FeoMcrfU@;J*|#z6ZDz8Hmb$p`sq?P$GzEn<<%+dd#UO2TN~># z?5|YiDZXs^T>I{GWm+h=&NU#WZG^dFapMBJq^u$GO3nk7)rV;?gYUD{Eq3s}1?0qG z0>G(KdhF~PrWYkOf3He%)?>Y#s?l0y-#m_Jv>ZLou6doMl&G^(x{!a(M&nS8gYxq) z@m3Qa^P+qwvt!;HYS^3{A*~uNrle&s)1mC`T$_}l7+zzrM|>y!SzGt_@82rU-mOWE ztE$XqB__*BO#=DPG)!AuAs69HBK`3P>(jC_3b2n}(cDVJZ=hBdiojp#S6*-&VH>BUqmn`cz zsg{zvlinDx0uun&17cp?4z@Y`(M?s*Vx=|7yV0;^=_Sc*JpOym>gJ6RDeQi#npd%p zmXzu`)SO=|nY+0s~3qHzT#I zbS3FgVK%`n$L9ppyoUjH>)xH@mi_ZQv(N05sPnr5sIHnsFjUU1nEy@YSSJ zi#4L^ZdSvYd`Y@8`{H_!df@|C9=UhG^2AAQ7wb1(MRa4<#xqUWlc{6^h#p zSs_1YPRYPqCL83ouDB;Vud_vZ_$M!^`ZR|DnK}bxT&-DZntOvsv|h6wwI^!iNRJT{ zR42^%X~b=wtQ`BwlYb^^qlcrmWVyiaM4g_#?B=IgZmc@^;PmHbf>dP zv@LgwbZ-Yd*HffC(g=9Eactg(oN=A>@0vObuc>oq*^bE`x0u?tZOmwmZe^|LAFy3;N zfcd#G=<~*ofZ~;W|EQM>ed%*W{JNP2+@njSJOh>49PLBi9v$cB@D9}7@$x$J#CweB zX`g1l6q~wA>U8DZLuWdSnmr>mBF3)K^XqIi=}KFdlbdE`Jlbz{aeIcfMAy-2=Cj{h zF4s73aYNVAe4umKl<93+Q`fE=;rPbaex9C)k5fdM+5D6Dq#Zt$C3-0Z&VObX#NP#5*--FkiP)2fo~sIscVM52tt8c$JWSIQi&-Ki= zK_y*ZZ`EG;zLlT(W1d9b=iv$yztqR7e#*Q!<)dqUL^si4^R^;!X;%_U^Np30Vvn@N z=699adq1RX`TXAQ$Bl+)H;?+$45#~F*T_FGdt%fW@~*6@C~NJbccW_`GG;!l3y`h9 zm*?Gir?dXVU7f;ZHQaq-x3X{Q-EIr^uhkgtc4^Ufg^N2kkGp(dEB=a#`Sc2>`BfLT zn0`5bd-kltL22d@ z!C|GtM=p=ed9zIAfZmJA`y%E=?mx-4$o@Ft;%?)q-FxG{9o$pCbyxAlu$to%!=9Zm z&nZ8-{KlHX8xLfQ1|BmxHhmzsU@dQ6Y26s#)5!-JV*}hD?y6&+x^#Se=MpKqWWkwcuR2Ts z%(!>9_SM_oq=bZKJ(*C&H zW^2|(moYT0$C*xcOQ#FoUwJ2$cGo;-N#NIWDh63Kvs2VhYGtP}m z)HsEn4V!Xp+CS_V?95WnWjoVHY&@}M_lMhqBdh%nU(X#_zErYB;(|xgqU_+>HnpKA zd-6&a*eW-f-l}-E!Y@9dd2!`r`3q4t0hMwC_k=HEz}kar5!}3OX;V$*$hJ>_NeBBcHmZ+O^TCX+fiUOf)};CT`#8ojRGl zdP17>tK*g)jyGNV7F>U|;DpJ%r?(ba+s7CDcscAY*JL#R{wgc!tGXS}g4eHK zKK@naosDxo9b4Wy-`&`mZk)40I&qXehx4(LL8@p0mlHRQru`&fmg&|A+KNYIa&iF>YDuTc4`Gc{?j$ znE1Q8c#mh?TkG8$PrRs*UOzXsxP#$KST)pO0$_C${W;BZ{)RF4K5@4DXNpN;0^ls= zeEpH*L59jw(heg+XK&wsbHb04i&rWRywVcBNul9}*5UG8<}gL8g#D4~^_RUPJYp#d zq1E}{uZLaR;k56~m`;^+>u*Pl@}?;+s*0TTTH@xLHJ%SGHB-DkTC{(f95crvZKS?~ z=CS)Pw%hIPqvciZ|&n(mlWo;1$zLHed`29qXzx7Tz$wJo!~@#{Lb z5GDPVAyIjTlWr;|Pd_BeZktw`xQzOwIW=;j>-#~|I~II-Cw4$SO8Ju*v{SlKZM7;|6E@7!tmz*$#`UaXnzt%LFh;P$-X~pgRVbmmuC1; z5#Q9?%XqAp86k)WrwY8OfxJLLXbeFZQ;D%*NY2qme3=ZXC@rf7JixbYF z@KD{^NQQ-n@;HH1PeEvC zL~uC%f+;T~f`_FoUQ|9W$S2&F>LuWXQG*2GNGTk#@DHJWmMK&q2&9G!sKF6ozEn?N zPACVNhoaPfR^~sJq5rh_ua}LX=0xzC0To^Ts7yfex7tJATqEKEi zkAqg}FGp`29UW?*Us#x5kPq1vIs$K<-a`Bg#P>r(arl#kh5B9E{iXSRj=ztAF7x`W zp8YZY!k4VEHz$ z;>0jL!Qyl>K21qnj*KrmMErbjd=GM=o|HXMAO=f?5lWKy zT|KE_KqCn0bA*B~_Q_({ly*g;?nfVz8tG+;PAZc0KBYpZ1dCgNd+9pt4{cu!a2*@$vfxQgeY4^52X6 z)#1ittCTMGUqt>gaHFfG#=zbO6#>h^6xgkZj|P--0r*Kl>CMQ0D%`Qa81^0HKL~Dr zpauIllx)vrFavfE;-eF#=7S-GIjS;9QV;G(V2J%y$R9_KlsC|XeHco%_ex*|`z7K_ z!@US#C8qRF?0;OvrHo+L3j5y=_5|34P_n#hz;xJe z5ufbOc|e&^kP@Nv^?w9xd`(39y0HIo8J8Lh`yiBTuN7b#?B|G2_P-k#0eic!|ChjK z!M-o-|3KI}uuntD<0%Eqg8dos$^IvgnL()k1!4b(!A3twUl#U1*{15S4?xNAiC`-1 zHpD0Ue<46SOQ#F_e=%$m*!P6}j|-0!j%#UrMNNu4p4Nhyu-_v-Ssy1b^q2mRg3ZAG zo5KG0fjtg(K9tOF6|jc=8u7{YbO$(Zr89;7zZ5nbcB8QW1+XW>E{BrG(*|G%`@69J z|LXidkMzm@_W)Fc-wh=|0x*Z&g8gLwI|CKislxt`hRuY1OW6Ouu*btb1||DzHL!vG z2Jy-M|Eu%=ny~-95Jm&x^Ppt-Bwz`<1M$i9T!9+wZNmPKgKY}CLD>I%*b`x&g35w* zz!vr=#3%dnug?EV!v5zX%ov2<4;2B+!4%j}5ufZ27cd<57GeL#!ZwC|SJ?mlu(e

|MhCkB4mr`;oB! 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 Date: Tue, 3 Dec 2013 23:26:46 +0200 Subject: [PATCH 2/2] Zip the HitboxExpander libraries --- tools/HitboxExpander/.gitignore | 4 +- tools/HitboxExpander/README | 10 + .../third_party/Imaging-1.1.7.zip | Bin 0 -> 952676 bytes .../third_party/Imaging-1.1.7/BUILDME | 11 - .../third_party/Imaging-1.1.7/CHANGES | 1767 --------- .../third_party/Imaging-1.1.7/CONTENTS | 299 -- .../third_party/Imaging-1.1.7/Docs/effbot.css | 118 - .../third_party/Imaging-1.1.7/Docs/index.html | 103 - .../Imaging-1.1.7/Images/courB08.bdf | 2676 -------------- .../Imaging-1.1.7/Images/courB08.pbm | Bin 1273 -> 0 bytes .../Imaging-1.1.7/Images/courB08.pil | Bin 5143 -> 0 bytes .../third_party/Imaging-1.1.7/Images/lena.gif | Bin 16336 -> 0 bytes .../third_party/Imaging-1.1.7/Images/lena.jpg | Bin 4788 -> 0 bytes .../third_party/Imaging-1.1.7/Images/lena.png | Bin 37723 -> 0 bytes .../third_party/Imaging-1.1.7/Images/lena.ppm | 4 - .../third_party/Imaging-1.1.7/MANIFEST | 279 -- .../third_party/Imaging-1.1.7/PIL.pth | 1 - .../Imaging-1.1.7/PIL/ArgImagePlugin.py | 504 --- .../Imaging-1.1.7/PIL/BdfFontFile.py | 133 - .../Imaging-1.1.7/PIL/BmpImagePlugin.py | 251 -- .../Imaging-1.1.7/PIL/BufrStubImagePlugin.py | 68 - .../Imaging-1.1.7/PIL/ContainerIO.py | 116 - .../Imaging-1.1.7/PIL/CurImagePlugin.py | 88 - .../Imaging-1.1.7/PIL/DcxImagePlugin.py | 78 - .../Imaging-1.1.7/PIL/EpsImagePlugin.py | 349 -- .../third_party/Imaging-1.1.7/PIL/ExifTags.py | 157 - .../Imaging-1.1.7/PIL/FitsStubImagePlugin.py | 73 - .../Imaging-1.1.7/PIL/FliImagePlugin.py | 142 - .../third_party/Imaging-1.1.7/PIL/FontFile.py | 146 - .../Imaging-1.1.7/PIL/FpxImagePlugin.py | 224 -- .../Imaging-1.1.7/PIL/GbrImagePlugin.py | 70 - .../Imaging-1.1.7/PIL/GdImageFile.py | 85 - .../Imaging-1.1.7/PIL/GifImagePlugin.py | 407 -- .../Imaging-1.1.7/PIL/GimpGradientFile.py | 124 - .../Imaging-1.1.7/PIL/GimpPaletteFile.py | 61 - .../Imaging-1.1.7/PIL/GribStubImagePlugin.py | 68 - .../Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py | 70 - .../Imaging-1.1.7/PIL/IcnsImagePlugin.py | 211 -- .../Imaging-1.1.7/PIL/IcoImagePlugin.py | 86 - .../Imaging-1.1.7/PIL/ImImagePlugin.py | 336 -- .../third_party/Imaging-1.1.7/PIL/Image.py | 2127 ----------- .../Imaging-1.1.7/PIL/ImageChops.py | 302 -- .../third_party/Imaging-1.1.7/PIL/ImageCms.py | 786 ---- .../Imaging-1.1.7/PIL/ImageColor.py | 263 -- .../Imaging-1.1.7/PIL/ImageDraw.py | 378 -- .../Imaging-1.1.7/PIL/ImageDraw2.py | 105 - .../Imaging-1.1.7/PIL/ImageEnhance.py | 90 - .../Imaging-1.1.7/PIL/ImageFile.py | 528 --- .../Imaging-1.1.7/PIL/ImageFileIO.py | 39 - .../Imaging-1.1.7/PIL/ImageFilter.py | 289 -- .../Imaging-1.1.7/PIL/ImageFont.py | 390 -- .../third_party/Imaging-1.1.7/PIL/ImageGL.py | 28 - .../Imaging-1.1.7/PIL/ImageGrab.py | 71 - .../Imaging-1.1.7/PIL/ImageMath.py | 207 -- .../Imaging-1.1.7/PIL/ImageMode.py | 50 - .../third_party/Imaging-1.1.7/PIL/ImageOps.py | 439 --- .../Imaging-1.1.7/PIL/ImagePalette.py | 184 - .../Imaging-1.1.7/PIL/ImagePath.py | 71 - .../third_party/Imaging-1.1.7/PIL/ImageQt.py | 84 - .../Imaging-1.1.7/PIL/ImageSequence.py | 38 - .../Imaging-1.1.7/PIL/ImageShow.py | 163 - .../Imaging-1.1.7/PIL/ImageStat.py | 164 - .../third_party/Imaging-1.1.7/PIL/ImageTk.py | 296 -- .../Imaging-1.1.7/PIL/ImageTransform.py | 95 - .../third_party/Imaging-1.1.7/PIL/ImageWin.py | 215 -- .../Imaging-1.1.7/PIL/ImtImagePlugin.py | 93 - .../Imaging-1.1.7/PIL/IptcImagePlugin.py | 288 -- .../Imaging-1.1.7/PIL/JpegImagePlugin.py | 492 --- .../Imaging-1.1.7/PIL/McIdasImagePlugin.py | 70 - .../Imaging-1.1.7/PIL/MicImagePlugin.py | 95 - .../Imaging-1.1.7/PIL/MpegImagePlugin.py | 82 - .../Imaging-1.1.7/PIL/MspImagePlugin.py | 103 - .../Imaging-1.1.7/PIL/OleFileIO.py | 528 --- .../third_party/Imaging-1.1.7/PIL/PSDraw.py | 199 - .../Imaging-1.1.7/PIL/PaletteFile.py | 55 - .../Imaging-1.1.7/PIL/PalmImagePlugin.py | 225 -- .../Imaging-1.1.7/PIL/PcdImagePlugin.py | 76 - .../Imaging-1.1.7/PIL/PcfFontFile.py | 256 -- .../Imaging-1.1.7/PIL/PcxImagePlugin.py | 167 - .../Imaging-1.1.7/PIL/PdfImagePlugin.py | 211 -- .../Imaging-1.1.7/PIL/PixarImagePlugin.py | 71 - .../Imaging-1.1.7/PIL/PngImagePlugin.py | 620 ---- .../Imaging-1.1.7/PIL/PpmImagePlugin.py | 131 - .../Imaging-1.1.7/PIL/PsdImagePlugin.py | 291 -- .../Imaging-1.1.7/PIL/SgiImagePlugin.py | 92 - .../Imaging-1.1.7/PIL/SpiderImagePlugin.py | 294 -- .../Imaging-1.1.7/PIL/SunImagePlugin.py | 86 - .../third_party/Imaging-1.1.7/PIL/TarIO.py | 57 - .../Imaging-1.1.7/PIL/TgaImagePlugin.py | 201 - .../Imaging-1.1.7/PIL/TiffImagePlugin.py | 860 ----- .../third_party/Imaging-1.1.7/PIL/TiffTags.py | 209 -- .../Imaging-1.1.7/PIL/WalImageFile.py | 126 - .../Imaging-1.1.7/PIL/WmfImagePlugin.py | 167 - .../Imaging-1.1.7/PIL/XVThumbImagePlugin.py | 73 - .../Imaging-1.1.7/PIL/XbmImagePlugin.py | 94 - .../Imaging-1.1.7/PIL/XpmImagePlugin.py | 129 - .../third_party/Imaging-1.1.7/PIL/__init__.py | 12 - .../Imaging-1.1.7/PIL/_imaging.pyd | Bin 193536 -> 0 bytes .../Imaging-1.1.7/PIL/_imagingmath.pyd | Bin 14848 -> 0 bytes .../third_party/Imaging-1.1.7/README | 300 -- .../third_party/Imaging-1.1.7/Sane/CHANGES | 34 - .../third_party/Imaging-1.1.7/Sane/README | 22 - .../third_party/Imaging-1.1.7/Sane/_sane.c | 1325 ------- .../Imaging-1.1.7/Sane/demo_numarray.py | 39 - .../Imaging-1.1.7/Sane/demo_pil.py | 33 - .../third_party/Imaging-1.1.7/Sane/sane.py | 289 -- .../Imaging-1.1.7/Sane/sanedoc.txt | 294 -- .../third_party/Imaging-1.1.7/Sane/setup.py | 24 - .../third_party/Imaging-1.1.7/Scripts/README | 83 - .../Imaging-1.1.7/Scripts/enhancer.py | 53 - .../Imaging-1.1.7/Scripts/explode.py | 107 - .../Imaging-1.1.7/Scripts/gifmaker.py | 135 - .../Imaging-1.1.7/Scripts/painter.py | 72 - .../Imaging-1.1.7/Scripts/pilconvert.py | 96 - .../Imaging-1.1.7/Scripts/pildriver.py | 524 --- .../Imaging-1.1.7/Scripts/pilfile.py | 94 - .../Imaging-1.1.7/Scripts/pilfont.py | 54 - .../Imaging-1.1.7/Scripts/pilprint.py | 93 - .../Imaging-1.1.7/Scripts/player.py | 121 - .../Imaging-1.1.7/Scripts/thresholder.py | 68 - .../Imaging-1.1.7/Scripts/viewer.py | 46 - .../third_party/Imaging-1.1.7/Tk/booster.txt | 108 - .../third_party/Imaging-1.1.7/Tk/install.txt | 41 - .../Imaging-1.1.7/Tk/pilbitmap.txt | 149 - .../third_party/Imaging-1.1.7/Tk/tkImaging.c | 265 -- .../third_party/Imaging-1.1.7/_imaging.c | 3281 ----------------- .../third_party/Imaging-1.1.7/_imagingcms.c | 608 --- .../third_party/Imaging-1.1.7/_imagingft.c | 502 --- .../third_party/Imaging-1.1.7/_imagingmath.c | 284 -- .../third_party/Imaging-1.1.7/_imagingtk.c | 70 - .../build/temp.win32-2.7/Release/_imaging.exp | Bin 670 -> 0 bytes .../build/temp.win32-2.7/Release/_imaging.lib | Bin 1736 -> 0 bytes .../temp.win32-2.7/Release/_imagingmath.exp | Bin 690 -> 0 bytes .../temp.win32-2.7/Release/_imagingmath.lib | Bin 1882 -> 0 bytes .../third_party/Imaging-1.1.7/decode.c | 689 ---- .../third_party/Imaging-1.1.7/display.c | 836 ----- .../third_party/Imaging-1.1.7/doctest.py | 1111 ------ .../third_party/Imaging-1.1.7/encode.c | 540 --- .../Imaging-1.1.7/libImaging/Access.c | 255 -- .../Imaging-1.1.7/libImaging/Antialias.c | 307 -- .../Imaging-1.1.7/libImaging/Bands.c | 129 - .../Imaging-1.1.7/libImaging/Bit.h | 30 - .../Imaging-1.1.7/libImaging/BitDecode.c | 138 - .../Imaging-1.1.7/libImaging/Blend.c | 79 - .../Imaging-1.1.7/libImaging/Chops.c | 148 - .../Imaging-1.1.7/libImaging/Convert.c | 1132 ------ .../Imaging-1.1.7/libImaging/ConvertYCbCr.c | 387 -- .../Imaging-1.1.7/libImaging/Copy.c | 58 - .../Imaging-1.1.7/libImaging/Crc32.c | 87 - .../Imaging-1.1.7/libImaging/Crop.c | 61 - .../Imaging-1.1.7/libImaging/Dib.c | 311 -- .../Imaging-1.1.7/libImaging/Draw.c | 1167 ------ .../Imaging-1.1.7/libImaging/Effects.c | 373 -- .../Imaging-1.1.7/libImaging/EpsEncode.c | 80 - .../Imaging-1.1.7/libImaging/Except.c | 83 - .../Imaging-1.1.7/libImaging/File.c | 193 - .../Imaging-1.1.7/libImaging/Fill.c | 101 - .../Imaging-1.1.7/libImaging/Filter.c | 179 - .../Imaging-1.1.7/libImaging/FliDecode.c | 205 - .../Imaging-1.1.7/libImaging/Geometry.c | 959 ----- .../Imaging-1.1.7/libImaging/GetBBox.c | 316 -- .../Imaging-1.1.7/libImaging/Gif.h | 109 - .../Imaging-1.1.7/libImaging/GifDecode.c | 297 -- .../Imaging-1.1.7/libImaging/GifEncode.c | 319 -- .../Imaging-1.1.7/libImaging/HexDecode.c | 67 - .../Imaging-1.1.7/libImaging/Histo.c | 169 - .../Imaging-1.1.7/libImaging/ImDib.h | 64 - .../Imaging-1.1.7/libImaging/ImPlatform.h | 72 - .../Imaging-1.1.7/libImaging/Imaging.h | 497 --- .../Imaging-1.1.7/libImaging/Jpeg.h | 104 - .../Imaging-1.1.7/libImaging/JpegDecode.c | 267 -- .../Imaging-1.1.7/libImaging/JpegEncode.c | 284 -- .../Imaging-1.1.7/libImaging/Lzw.h | 52 - .../Imaging-1.1.7/libImaging/LzwDecode.c | 230 -- .../Imaging-1.1.7/libImaging/Matrix.c | 74 - .../Imaging-1.1.7/libImaging/ModeFilter.c | 78 - .../Imaging-1.1.7/libImaging/MspDecode.c | 91 - .../Imaging-1.1.7/libImaging/Negative.c | 42 - .../Imaging-1.1.7/libImaging/Offset.c | 61 - .../Imaging-1.1.7/libImaging/Pack.c | 566 --- .../Imaging-1.1.7/libImaging/PackDecode.c | 92 - .../Imaging-1.1.7/libImaging/Palette.c | 316 -- .../Imaging-1.1.7/libImaging/Paste.c | 555 --- .../Imaging-1.1.7/libImaging/PcdDecode.c | 78 - .../Imaging-1.1.7/libImaging/PcxDecode.c | 75 - .../Imaging-1.1.7/libImaging/PcxEncode.c | 148 - .../Imaging-1.1.7/libImaging/Point.c | 263 -- .../Imaging-1.1.7/libImaging/Quant.c | 1610 -------- .../Imaging-1.1.7/libImaging/Quant.h | 40 - .../Imaging-1.1.7/libImaging/QuantDefines.h | 25 - .../Imaging-1.1.7/libImaging/QuantHash.c | 477 --- .../Imaging-1.1.7/libImaging/QuantHash.h | 36 - .../Imaging-1.1.7/libImaging/QuantHeap.c | 150 - .../Imaging-1.1.7/libImaging/QuantHeap.h | 23 - .../Imaging-1.1.7/libImaging/QuantTypes.h | 28 - .../Imaging-1.1.7/libImaging/RankFilter.c | 105 - .../Imaging-1.1.7/libImaging/Raw.h | 15 - .../Imaging-1.1.7/libImaging/RawDecode.c | 89 - .../Imaging-1.1.7/libImaging/RawEncode.c | 89 - .../Imaging-1.1.7/libImaging/Storage.c | 413 --- .../Imaging-1.1.7/libImaging/SunRleDecode.c | 112 - .../Imaging-1.1.7/libImaging/TgaRleDecode.c | 118 - .../Imaging-1.1.7/libImaging/Unpack.c | 1028 ------ .../Imaging-1.1.7/libImaging/UnpackYCC.c | 162 - .../Imaging-1.1.7/libImaging/UnsharpMask.c | 398 -- .../Imaging-1.1.7/libImaging/XbmDecode.c | 81 - .../Imaging-1.1.7/libImaging/XbmEncode.c | 106 - .../Imaging-1.1.7/libImaging/Zip.h | 57 - .../Imaging-1.1.7/libImaging/ZipDecode.c | 271 -- .../Imaging-1.1.7/libImaging/ZipEncode.c | 341 -- .../third_party/Imaging-1.1.7/map.c | 379 -- .../third_party/Imaging-1.1.7/outline.c | 179 - .../third_party/Imaging-1.1.7/path.c | 587 --- .../third_party/Imaging-1.1.7/selftest.py | 202 - .../third_party/Imaging-1.1.7/setup.py | 487 --- tools/HitboxExpander/third_party/zlib.zip | Bin 0 -> 141415 bytes .../third_party/zlib/DLL_FAQ.txt | 397 -- .../third_party/zlib/README.txt | 60 - .../HitboxExpander/third_party/zlib/USAGE.txt | 89 - .../third_party/zlib/include/zconf.h | 511 --- .../third_party/zlib/include/zlib.h | 1768 --------- .../third_party/zlib/lib/zdll.lib | Bin 15256 -> 0 bytes .../third_party/zlib/lib/zlib.def | 86 - .../third_party/zlib/test/example_d.exe | Bin 38912 -> 0 bytes .../third_party/zlib/test/minigzip_d.exe | Bin 35840 -> 0 bytes .../HitboxExpander/third_party/zlib/zlib1.dll | Bin 107520 -> 0 bytes 226 files changed, 12 insertions(+), 57619 deletions(-) create mode 100755 tools/HitboxExpander/README create mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7.zip delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pbm delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pil delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.gif delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.jpg delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.png delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.ppm delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/MANIFEST delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL.pth delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ArgImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imaging.pyd delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imagingmath.pyd delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/README delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.exp delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.lib delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.exp delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.lib delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/decode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/display.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/LzwDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/map.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/path.c delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py delete mode 100755 tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py create mode 100755 tools/HitboxExpander/third_party/zlib.zip delete mode 100755 tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt delete mode 100755 tools/HitboxExpander/third_party/zlib/README.txt delete mode 100755 tools/HitboxExpander/third_party/zlib/USAGE.txt delete mode 100755 tools/HitboxExpander/third_party/zlib/include/zconf.h delete mode 100755 tools/HitboxExpander/third_party/zlib/include/zlib.h delete mode 100755 tools/HitboxExpander/third_party/zlib/lib/zdll.lib delete mode 100755 tools/HitboxExpander/third_party/zlib/lib/zlib.def delete mode 100755 tools/HitboxExpander/third_party/zlib/test/example_d.exe delete mode 100755 tools/HitboxExpander/third_party/zlib/test/minigzip_d.exe delete mode 100755 tools/HitboxExpander/third_party/zlib/zlib1.dll diff --git a/tools/HitboxExpander/.gitignore b/tools/HitboxExpander/.gitignore index 8e987a0b84b..ec7f5fd7c18 100644 --- a/tools/HitboxExpander/.gitignore +++ b/tools/HitboxExpander/.gitignore @@ -1,3 +1,3 @@ -*.obj -pythondoc-PIL.*.html +Imaging-1.1.7/ +zlib/ diff --git a/tools/HitboxExpander/README b/tools/HitboxExpander/README new file mode 100755 index 00000000000..df9cb5babb0 --- /dev/null +++ b/tools/HitboxExpander/README @@ -0,0 +1,10 @@ +Setup: Unzip the zip files in third_party/ so that you have the directories +third_party/Imaging-1.1.7/ and third_party/zlib/. + +Usage: python hitbox_expander.py + +This tool expands the hitbox of the given image by 1 pixel. +Works by changing some of the fully-transparent pixels to alpha=1 black pixels. +Naked human eye usually cannot notice the difference. + +No space carps or corgis have been used or injured in the production of this tool. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7.zip b/tools/HitboxExpander/third_party/Imaging-1.1.7.zip new file mode 100755 index 0000000000000000000000000000000000000000..a9af836b11ab3576d5a2e810f47a1fd43ad0ceae GIT binary patch literal 952676 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%0D-d>Y-#L?P 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Ⓣ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%0DU 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�^`><*!RGVse?W+eO2WkhY`~sD#VFyhf+j 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

>9O~wI*=_mjv_y*@r<@av3c> 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

Pk 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≪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 Pb2u5^ioApmNksnvOiJ&= literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME b/tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME deleted file mode 100755 index a3c6295376f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/BUILDME +++ /dev/null @@ -1,11 +0,0 @@ -# $Id$ -# quick build (for lazy programmers). for more information on the -# build process, see the README file. - -if [ "$1" = "clean" ]; then - python setup.py clean - rm -f *.so PIL/*.so -fi - -python setup.py build_ext -i -python selftest.py diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES b/tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES deleted file mode 100755 index b516d32bbd8..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/CHANGES +++ /dev/null @@ -1,1767 +0,0 @@ --*- coding: utf-8 -*- - -The Python Imaging Library -$Id$ - -ACKNOWLEDGEMENTS: PIL wouldn't be what it is without the help of: -David Ascher, Phil Austin, Douglas Bagnall, Larry Bates, Anthony -Baxter, William Baxter, Denis Benoit, Jan Blom, Duncan Booth, Alexey -Borzenkov, Jeff Breidenbach, Roger Burnham, Zac Burns, Gene Cash, -Kevin Cazabon, Fred Clare, Greg Coats, Chris Cogdon, Greg Couch, Bill -Crutchfield, Abel Deuring, Tim Docker, Fred Drake, Graham Dumpleton, -Matthew Ellis, Eric Etheridge, Daniel Fetchinson, Robin Friedrich, -Pier Paolo Glave, Federico Di Gregorio, Markus Gritsch, Daniel -Haertle, Greg Hamilton, Mark Hammond, Bernhard Herzog, Rob Hooft, Bob -Ippolito, Jack Jansen, Bill Janssen, Edward Jones, Richard Jones, -Håkan Karlsson, Robert Kern, David Kirtley, Bob Klimek, Matthias -Klose, Andrew Kuchling, Magnus Källström, Victor Lacina, Ben Last, -Hamish Lawson, Cesare Leonardi, Andrew MacIntyre, Jan Matejek, Naveen -Michaud-Agrawal, Gordon McMillan, Skip Montanaro, Fredrik Nehr, -Russell Nelson, Luciano Nocera, Travis Oliphant, Piet van Oostrum, -Richard Oudkerk, Paul Pharr, Andres Polit, Conrado Porto Lopes Gouvêa, -Eric Raymond, Victor Reijs, Bertil Reinhammar, Nicholas Riley, Don -Rozenberg, Toby Sargeant, Barry Scott, Les Schaffer, Joel Shprentz, -Klamer Shutte, Gene Skonicki, Niki Spahiev, D. Alan Stewart, Perry -Stoll, Paul Svensson, Ulrik Svensson, Miki Tebeka, Michael van -Tellingen, Ivan Tkatchev, Dan Torop, Adam Twardoch, Rune Uhlin, Dmitry -Vasiliev, Sasha Voynow, Charles Waldman, Collin Winter, Dan Wolfe, -Ka-Ping Yee, and many others (if your name should be on this list, let -me know.) - -*** Changes from release 1.1.6 to 1.1.7 *** - -This section may not be fully complete. For changes since this file -was last updated, see the repository revision history: - - http://bitbucket.org/effbot/pil-2009-raclette/changesets/ - -(1.1.7 final) - -+ Set GIF loop info property to the number of iterations if a NETSCAPE - loop extension is present, instead of always setting it to 1 (from - Valentino Volonghi). - -(1.1.7c1 released) - -+ Improved PNG compression (from Alexey Borzenkov). - -+ Read interlaced PNG files (from Conrado Porto Lopes Gouvêa) - -+ Added various TGA improvements from Alexey Borzenkov, including - support for specifying image orientation. - -+ Bumped block threshold to 16 megabytes, made size estimation a bit - more accurate. This speeds up allocation of large images. - -+ Fixed rounding error in ImagingDrawWideLine. - - "gormish" writes: ImagingDrawWideLine() in Draw.c has a bug in every - version I've seen, which leads to different width lines depending on - the order of the points in the line. This is especially bad at some - angles where a 'width=2' line can completely disappear. - -+ Added support for RGBA mode to the SGI module (based on code by - Karsten Hiddemann). - -+ Handle repeated IPTC tags (adapted from a patch by Eric Bruning). - - Eric writes: According to the specification, some IPTC tags can be - repeated, e.g., tag 2:25 (keywords). PIL 1.1.6 only retained the last - instance of that tag. Below is a patch to store all tags. If there are - multiple tag instances, they are stored in a (python) list. Single tag - instances remain as strings. - -+ Fixed potential crash in ImageFilter for small target images - (reported by Zac Burns and Daniel Fetchinson). - -+ Use BMP instead of JPEG as temporary show format on Mac OS X. - -+ Fixed putpixel/new for I;16 with colors > 255. - -+ Added integer power support to ImagingMath. - -+ Added limited support for I;16L mode (explicit little endian). - -+ Moved WMF support into Image.core; enable WMF rendering by default - if renderer is available. - -+ Mark the ARG plugin as obsolete. - -+ Added version query mechanism to ImageCms and ImageFont, for - debugging. - -+ Added (experimental) ImageCms function for fetching the ICC profile - for the current display (currently Windows only). - - Added HWND/HDC support to ImageCms.get_display_profile(). - -+ Added WMF renderer (Windows only). - -+ Added ImagePointHandler and ImageTransformHandler mixins; made - ImageCmsTransform work with im.point. - -+ Fixed potential endless loop in the XVThumbnail reader (from Nikolai - Ugelvik). - -+ Added Kevin Cazabon's pyCMS package. - - The C code has been moved to _imagingcms.c, the Python interface - module is installed as PIL.ImageCMS. - - Added support for in-memory ICC profiles. - - Unified buildTransform and buildTransformFromOpenProfiles. - - The profile can now be either a filename, a profile object, or a - file-like object containing an in-memory profile. - - Additional fixes from Florian Böch: - - Very nice - it just needs LCMS flags support so we can use black - point compensation and softproofing :) See attached patches. They - also fix a naming issue which could cause confusion - display - profile (ImageCms wording) actually means proof profile (lcms - wording), so I changed variable names and docstrings where - applicable. Patches are tested under Python 2.6. - -+ Improved support for layer names in PSD files (from Sylvain Baubeau) - - Sylvain writes: I needed to be able to retrieve the names of the - layers in a PSD files. But PsdImagePlugin.py didn't do the job so I - wrote this very small patch. - -+ Improved RGBA support for ImageTk for 8.4 and newer (from Con - Radchenko). - - This replaces the slow run-length based encoding model with true - compositing at the Tk level. - -+ Added support for 16- and 32-bit images to McIdas loader. - - Based on file samples and stand-alone reader code provided by Craig - Swank. - -+ Added ImagePalette support to putpalette. - -+ Fixed problem with incremental parsing of PNG files. - -+ Make selftest.py report non-zero status on failure (from Mark - Sienkiewicz) - -+ Add big endian save support and multipage infrastructure to the TIFF - writer (from Sebastian Haase). - -+ Handle files with GPS IFD but no basic EXIF IFD (reported by Kurt - Schwehr). - -+ Added zTXT support (from Andrew Kuchling via Lowell Alleman). - -+ Fixed potential infinite loop bug in ImageFont (from Guilherme Polo). - -+ Added sample ICC profiles (from Kevin Cazabon) - -+ Fixed array interface for I, F, and RGBA/RGBX images. - -+ Added Chroma subsampling support for JPEG (from Justin Huff). - - Justin writes: Attached is a patch (against PIL 1.1.6) to provide - control over the chroma subsampling done by the JPEG encoder. This - is often useful for reducing compression artifacts around edges of - clipart and text. - -+ Added USM/Gaussian Blur code from Kevin Cazabon. - -+ Fixed bug w. uninitialized image data when cropping outside the - source image. - -+ Use ImageShow to implement the Image.show method. - - Most notably, this picks the 'display' utility when available. It - also allows application code to register new display utilities via - the ImageShow registry. - -+ Release the GIL in the PNG compressor (from Michael van Tellingen). - -+ Revised JPEG CMYK handling. - - Always assume Adobe behaviour, both when reading and writing (based on - a patch by Kevin Cazabon, and test data by Tim V. and Charlie Clark, and - additional debugging by Michael van Tellingen). - -+ Support for preserving ICC profiles (by Florian Böch via Tim Hatch). - - Florian writes: - - It's a beta, so still needs some testing, but should allow you to: - - retain embedded ICC profiles when saving from/to JPEG, PNG, TIFF. - Existing code doesn't need to be changed. - - access embedded profiles in JPEG, PNG, PSD, TIFF. - - It also includes patches for TIFF to retain IPTC, Photoshop and XMP - metadata when saving as TIFF again, read/write TIFF resolution - information correctly, and to correct inverted CMYK JPEG files. - -+ Fixed potential memory leak in median cut quantizer (from Evgeny Salmin). - -+ Fixed OverflowError when reading upside-down BMP images. - -+ Added resolution save option for PDF files. - - Andreas Kostyrka writes: I've included a patched PdfImagePlugin.py - based on 1.1.6 as included in Ubuntu, that supports a "resolution" - save option. Not great, but it makes the PDF saving more useful by - allowing PDFs that are not exactly 72dpi. - -+ Look for Tcl/Tk include files in version-specific include directory - (from Encolpe Degoute). - -+ Fixed grayscale rounding error in ImageColor.getcolor (from Tim - Hatch). - -+ Fixed calculation of mean value in ImageEnhance.Contrast (reported - by "roop" and Scott David Daniels). - -+ Fixed truetype positioning when first character has a negative left - bearing (from Ned Batchelder): - - Ned writes: In PIL 1.1.6, ImageDraw.text will position the string - incorrectly if the first character has a negative left bearing. To - see the problem, show a string like "///" in an italic font. The - first slash will be clipped at the left, and the string will be - mis-positioned. - -+ Fixed resolution unit bug in tiff reader/writer (based on code by - Florian Höch, Gary Bloom, and others). - -+ Added simple transparency support for RGB images (reported by - Sebastian Spaeth). - -+ Added support for Unicode filenames in ImageFont.truetype (from Donn - Ingle). - -+ Fixed potential crash in ImageFont.getname method (from Donn Ingle). - -+ Fixed encoding issue in PIL/WalImageFile (from Santiago M. Mola). - -*** Changes from release 1.1.5 to 1.1.6 *** - -(1.1.6 released) - -+ Fixed some 64-bit compatibility warnings for Python 2.5. - -+ Added threading support for the Sane driver (from Abel Deuring). - -(1.1.6b2 released) - -+ Added experimental "floodfill" function to the ImageDraw module - (based on code by Eric Raymond). - -+ The default arguments for "frombuffer" doesn't match "fromstring" - and the documentation; this is a bug, and will most likely be fixed - in a future version. In this release, PIL prints a warning message - instead. To silence the warning, change any calls of the form - "frombuffer(mode, size, data)" to - - frombuffer(mode, size, data, "raw", mode, 0, 1) - -+ Added "fromarray" function, which takes an object implementing the - NumPy array interface and creates a PIL Image from it. (from Travis - Oliphant). - -+ Added NumPy array interface support (__array_interface__) to the - Image class (based on code by Travis Oliphant). - - This allows you to easily convert between PIL image memories and - NumPy arrays: - - import numpy, Image - - im = Image.open('lena.jpg') - - a = numpy.asarray(im) # a is readonly - - im = Image.fromarray(a) - -+ Fixed CMYK polarity for JPEG images, by treating all images as - "Adobe CMYK" images. (thanks to Cesare Leonardi and Kevin Cazabon - for samples, debugging, and patches). - -(1.1.6b1 released) - -+ Added 'expand' option to the Image 'rotate' method. If true, the - output image is made large enough to hold the entire rotated image. - -+ Changed the ImageDraw 'line' method to always draw the last pixel in - a polyline, independent of line angle. - -+ Fixed bearing calculation and clipping in the ImageFont truetype - renderer; this could lead to clipped text, or crashes in the low- - level _imagingft module. (based on input from Adam Twardoch and - others). - -+ Added ImageQt wrapper module, for converting PIL Image objects to - QImage objects in an efficient way. - -+ Fixed 'getmodebands' to return the number of bands also for "PA" - and "LA" modes. Added 'getmodebandnames' helper that return the - band names. - -(1.1.6a2 released) - -+ Added float/double support to the TIFF loader (from Russell - Nelson). - -+ Fixed broken use of realloc() in path.c (from Jan Matejek) - -+ Added save support for Spider images (from William Baxter). - -+ Fixed broken 'paste' and 'resize' operations in pildriver - (from Bill Janssen). - -+ Added support for duplex scanning to the Sane interface (Abel - Deuring). - -(1.1.6a1 released) - -+ Fixed a memory leak in "convert(mode)", when converting from - L to P. - -+ Added pixel access object. The "load" method now returns a - access object that can be used to directly get and set pixel - values, using ordinary [x, y] notation: - - pixel = im.load() - v = pixel[x, y] - pixel[x, y] = v - - If you're accessing more than a few pixels, this is a lot - faster than using getpixel/putpixel. - -+ Fixed building on Cygwin (from Miki Tebeka). - -+ Fixed "point(callable)" on unloaded images (reported by Håkan - Karlsson). - -+ Fixed size bug in ImageWin.ImageWindow constructor (from Victor - Reijs) - -+ Fixed ImageMath float() and int() operations for Python 2.4 - (reported by Don Rozenberg). - -+ Fixed "RuntimeError: encoder error -8 in tostring" problem for - wide "RGB", "I", and "F" images. - -+ Fixed line width calculation. - -(1.1.6a0 released) - -+ Fixed byte order issue in Image.paste(ink) (from Ka-Ping Yee). - -+ Fixed off-by-0.5 errors in the ANTIALIAS code (based on input - from Douglas Bagnall). - -+ Added buffer interface support to the Path constructor. If - a buffer is provided, it is assumed to contain a flat array - of float coordinates (e.g. array.array('f', seq)). - -+ Added new ImageMath module. - -+ Fixed ImageOps.equalize when used with a small number of distinct - values (reported by David Kirtley). - -+ Fixed potential integer division in PSDraw.image (from Eric Etheridge). - -*** Changes from release 1.1 to 1.1.5 *** - -(1.1.5c2 and 1.1.5 final released) - -+ Added experimental PERSPECTIVE transform method (from Jeff Breiden- - bach). - -(1.1.5c1 released) - -+ Make sure "thumbnail" never generates zero-wide or zero-high images - (reported by Gene Skonicki) - -+ Fixed a "getcolors" bug that could result in a zero count for some - colors (reported by Richard Oudkerk). - -+ Changed default "convert" palette to avoid "rounding errors" when - round-tripping white source pixels (reported by Henryk Gerlach and - Jeff Epler). - -(1.1.5b3 released) - -+ Don't crash in "quantize" method if the number of colors requested - is larger than 256. This release raises a ValueError exception; - future versions may return a mode "RGB" image instead (reported - by Richard Oudkerk). - -+ Added WBMP read/write support (based on code by Duncan Booth). - -(1.1.5b2 released) - -+ Added DPI read/write support to the PNG codec. The decoder sets - the info["dpi"] attribute for PNG files with appropriate resolution - settings. The encoder uses the "dpi" option (based on code by Niki - Spahiev). - -+ Added limited support for "point" mappings from mode "I" to mode "L". - Only 16-bit values are supported (other values are clipped), the lookup - table must contain exactly 65536 entries, and the mode argument must be - set to "L". - -+ Added support for Mac OS X icns files (based on code by Bob Ippolito). - -+ Added "ModeFilter" support to the ImageFilter module. - -+ Added support for Spider images (from William Baxter). See the - comments in PIL/SpiderImagePlugin.py for more information on this - format. - -(1.1.5b1 released) - -+ Added new Sane release (from Ralph Heinkel). See the Sane/README - and Sane/CHANGES files for more information. - -+ Added experimental PngInfo chunk container to the PngImageFile - module. This can be used to add arbitrary chunks to a PNG file. - Create a PngInfo instance, use "add" or "add_text" to add chunks, - and pass the instance as the "pnginfo" option when saving the - file. - -+ Added "getpalette" method. This returns the palette as a list, - or None if the image has no palette. To modify the palette, use - "getpalette" to fetch the current palette, modify the list, and - put it back using "putpalette". - -+ Added optional flattening to the ImagePath "tolist" method. - tolist() or tolist(0) returns a list of 2-tuples, as before. - tolist(1) returns a flattened list instead. - -(1.1.5a5 released) - -+ Fixed BILINEAR/BICUBIC/ANTIALIAS filtering for mode "LA". - -+ Added "getcolors()" method. This is similar to the existing histo- - gram method, but looks at color values instead of individual layers, - and returns an unsorted list of (count, color) tuples. - - By default, the method returns None if finds more than 256 colors. - If you need to look for more colors, you can pass in a limit (this - is used to allocate internal tables, so you probably don't want to - pass in too large values). - -+ Build improvements: Fixed building under AIX, improved detection of - FreeType2 and Mac OS X framework libraries, and more. Many thanks - to everyone who helped test the new "setup.py" script! - -(1.1.5a4 released) - -+ The "save" method now looks for a file format driver before - creating the file. - -+ Don't use antialiased truetype fonts when drawing in mode "P", "I", - and "F" images. - -+ Rewrote the "setup.py" file. The new version scans for available - support libraries, and configures both the libImaging core library - and the bindings in one step. - - To use specific versions of the libraries, edit the ROOT variables - in the setup.py file. - -+ Removed threaded "show" viewer; use the old "show" implementation - instead (Windows). - -+ Added deprecation warnings to Image.offset, ImageDraw.setink, and - ImageDraw.setfill. - -+ Added width option to ImageDraw.line(). The current implementation - works best for straight lines; it does not support line joins, so - polylines won't look good. - -+ ImageDraw.Draw is now a factory function instead of a class. If - you need to create custom draw classes, inherit from the ImageDraw - class. All other code should use the factory function. - -+ Fixed loading of certain PCX files (problem reported by Greg - Hamilton, who also provided samples). - -+ Changed _imagingft.c to require FreeType 2.1 or newer. The - module can still be built with earlier versions; see comments - in _imagingft.c for details. - -(1.1.5a3 released) - -+ Added 'getim' method, which returns a PyCObject wrapping an - Imaging pointer. The description string is set to IMAGING_MAGIC. - See Imaging.h for pointer and string declarations. - -+ Fixed reading of TIFF JPEG images (problem reported by Ulrik - Svensson). - -+ Made ImageColor work under Python 1.5.2 - -+ Fixed division by zero "equalize" on very small images (from - Douglas Bagnall). - -(1.1.5a2 released) - -+ The "paste" method now supports the alternative "paste(im, mask)" - syntax (in this case, the box defaults to im's bounding box). - -+ The "ImageFile.Parser" class now works also for PNG files with - more than one IDAT block. - -+ Added DPI read/write to the TIFF codec, and fixed writing of - rational values. The decoder sets the info["dpi"] attribute - for TIFF files with appropriate resolution settings. The - encoder uses the "dpi" option. - -+ Disable interlacing for small (or narrow) GIF images, to - work around what appears to be a hard-to-find bug in PIL's - GIF encoder. - -+ Fixed writing of mode "P" PDF images. Made mode "1" PDF - images smaller. - -+ Made the XBM reader a bit more robust; the file may now start - with a few whitespace characters. - -+ Added support for enhanced metafiles to the WMF driver. The - separate PILWMF kit lets you render both placeable WMF files - and EMF files as raster images. See - - http://effbot.org/downloads#pilwmf - -(1.1.5a1 released) - -+ Replaced broken WMF driver with a WMF stub plugin (see below). - -+ Fixed writing of mode "1", "L", and "CMYK" PDF images (based on - input from Nicholas Riley and others). - -+ Fixed adaptive palette conversion for zero-width or zero-height - images (from Chris Cogdon) - -+ Fixed reading of PNG images from QuickTime 6 (from Paul Pharr) - -+ Added support for StubImageFile plugins, including stub plugins - for BUFR, FITS, GRIB, and HDF5 files. A stub plugin can identify - a given file format, but relies on application code to open and - save files in that format. - -+ Added optional "encoding" argument to the ImageFont.truetype - factory. This argument can be used to specify non-Unicode character - maps for fonts that support that. For example, to draw text using - the Microsoft Symbol font, use: - - font = ImageFont.truetype("symbol.ttf", 16, encoding="symb") - draw.text((0, 0), unichr(0xF000 + 0xAA)) - - (note that the symbol font uses characters in the 0xF000-0xF0FF - range) - - Common encodings are "unic" (Unicode), "symb" (Microsoft Symbol), - "ADOB" (Adobe Standard), "ADBE" (Adobe Expert), and "armn" (Apple - Roman). See the FreeType documentation for more information. - -+ Made "putalpha" a bit more robust; you can now attach an alpha - layer to a plain "L" or "RGB" image, and you can also specify - constant alphas instead of alpha layers (using integers or colour - names). - -+ Added experimental "LA" mode support. - - An "LA" image is an "L" image with an attached transparency layer. - Note that support for "LA" is not complete; some operations may - fail or produce unexpected results. - -+ Added "RankFilter", "MinFilter", "MedianFilter", and "MaxFilter" - classes to the ImageFilter module. - -+ Improved support for applications using multiple threads; PIL - now releases the global interpreter lock for many CPU-intensive - operations (based on work by Kevin Cazabon). - -+ Ignore Unicode characters in the PCF loader (from Andres Polit) - -+ Fixed typo in OleFileIO.loadfat, which could affect loading of - FlashPix and Image Composer images (Daniel Haertle) - -+ Fixed building on platforms that have Freetype but don't have - Tcl/Tk (Jack Jansen, Luciano Nocera, Piet van Oostrum and others) - -+ Added EXIF GPSInfo read support for JPEG files. To extract - GPSInfo information, open the file, extract the exif dictionary, - and check for the key 0x8825 (GPSInfo). If present, it contains - a dictionary mapping GPS keys to GPS values. For a list of keys, - see the EXIF specification. - - The "ExifTags" module contains a GPSTAGS dictionary mapping GPS - tags to tag names. - -+ Added DPI read support to the PCX and DCX codecs (info["dpi"]). - -+ The "show" methods now uses a built-in image viewer on Windows. - This viewer creates an instance of the ImageWindow class (see - below) and keeps it running in a separate thread. NOTE: This - was disabled in 1.1.5a4. - -+ Added experimental "Window" and "ImageWindow" classes to the - ImageWin module. These classes allow you to create a WCK-style - toplevel window, and use it to display raster data. - -+ Fixed some Python 1.5.2 issues (to build under 1.5.2, use the - Makefile.pre.in/Setup.in approach) - -+ Added support for the TIFF FillOrder tag. PIL can read mode "1", - "L", "P" and "RGB" images with non-standard FillOrder (based on - input from Jeff Breidenbach). - -(1.1.4 final released) - -+ Fixed ImageTk build problem on Unix. - -(1.1.4b2 released) - -+ Improved building on Mac OS X (from Jack Jansen). - -+ Improved building on Windows with MinGW (from Klamer Shutte). - -+ If no font is specified, ImageDraw now uses the embedded default - font. Use the "load" or "truetype" methods to load a real font. - -+ Added embedded default font to the ImageFont module (currently - an 8-pixel Courier font, taken from the X window distribution). - -(1.1.4b1 released) - -+ Added experimental EXIF support for JPEG files. To extract EXIF - information from a JPEG file, open the file as usual, and call the - "_getexif" method. If successful, this method returns a dictionary - mapping EXIF TIFF tags to values. If the file does not contain EXIF - data, the "_getexif" method returns None. - - The "ExifTags" module contains a dictionary mapping tags to tag - names. - - This interface will most likely change in future versions. - -+ Fixed a bug when using the "transparency" option with the GIF - writer. - -+ Added limited support for "bitfield compression" in BMP files - and DIB buffers, for 15-bit, 16-bit, and 32-bit images. This - also fixes a problem with ImageGrab module when copying screen- - dumps from the clipboard on 15/16/32-bit displays. - -+ Added experimental WAL (Quake 2 textures) loader. To use this - loader, import WalImageFile and call the "open" method in that - module. - -(1.1.4a4 released) - -+ Added updated SANE driver (Andrew Kuchling, Abel Deuring) - -+ Use Python's "mmap" module on non-Windows platforms to read some - uncompressed formats using memory mapping. Also added a "frombuffer" - function that allows you to access the contents of an existing string - or buffer object as if it were an image object. - -+ Fixed a memory leak that could appear when processing mode "P" - images (from Pier Paolo Glave) - -+ Ignore Unicode characters in the BDF loader (from Graham Dumpleton) - -(1.1.4a3 released; windows only) - -+ Added experimental RGBA-on-RGB drawing support. To use RGBA - colours on an RGB image, pass "RGBA" as the second string to - the ImageDraw.Draw constructor. - -+ Added support for non-ASCII strings (Latin-1) and Unicode - to the truetype font renderer. - -+ The ImageWin "Dib" object can now be constructed directly from - an image object. - -+ The ImageWin module now allows you use window handles as well - as device contexts. To use a window handle, wrap the handle in - an ImageWin.HWND object, and pass in this object instead of the - device context. - -(1.1.4a2 released) - -+ Improved support for 16-bit unsigned integer images (mode "I;16"). - This includes TIFF reader support, and support for "getextrema" - and "point" (from Klamer Shutte). - -+ Made the BdfFontFile reader a bit more robust (from Kevin Cazabon - and Dmitry Vasiliev) - -+ Changed TIFF writer to always write Compression tag, even when - using the default compression (from Greg Couch). - -+ Added "show" support for Mac OS X (from Dan Wolfe). - -+ Added clipboard support to the "ImageGrab" module (Windows only). - The "grabclipboard" function returns an Image object, a list of - filenames (not in 1.1.4), or None if neither was found. - -(1.1.4a1 released) - -+ Improved support for drawing RGB data in palette images. You can - now use RGB tuples or colour names (see below) when drawing in a - mode "P" image. The drawing layer automatically assigns color - indexes, as long as you don't use more than 256 unique colours. - -+ Moved self test from MiniTest/test.py to ./selftest.py. - -+ Added support for CSS3-style color strings to most places that - accept colour codes/tuples. This includes the "ImageDraw" module, - the Image "new" function, and the Image "paste" method. - - Colour strings can use one of the following formats: "#f00", - "#ff0000", "rgb(255,0,0)", "rgb(100%,0%,0%)", "hsl(0, 100%, 50%)", - or "red" (most X11-style colour names are supported). See the - documentation for the "ImageColor" module for more information. - -+ Fixed DCX decoder (based on input from Larry Bates) - -+ Added "IptcImagePlugin.getiptcinfo" helper to extract IPTC/NAA - newsphoto properties from JPEG, TIFF, or IPTC files. - -+ Support for TrueType/OpenType fonts has been added to - the standard distribution. You need the freetype 2.0 - library. - -+ Made the PCX reader a bit more robust when reading 2-bit - and 4-bit PCX images with odd image sizes. - -+ Added "Kernel" class to the ImageFilter module. This class - allows you to filter images with user-defined 3x3 and 5x5 - convolution kernels. - -+ Added "putdata" support for mode "I", "F" and "RGB". - -+ The GIF writer now supports the transparency option (from - Denis Benoit). - -+ A HTML version of the module documentation is now shipped - with the source code distribution. You'll find the files in - the Doc subdirectory. - -+ Added support for Palm pixmaps (from Bill Janssen). This - change was listed for 1.1.3, but the "PalmImagePlugin" driver - didn't make it into the distribution. - -+ Improved decoder error messages. - -(1.1.3 final released) - -+ Made setup.py look for old versions of zlib. For some back- - ground, see: http://www.gzip.org/zlib/advisory-2002-03-11.txt - -(1.1.3c2 released) - -+ Added setup.py file (tested on Unix and Windows). You still - need to build libImaging/imaging.lib in the traditional way, - but the setup.py script takes care of the rest. - - The old Setup.in/Makefile.pre.in build method is still - supported. - -+ Fixed segmentation violation in ANTIALIAS filter (an internal - buffer wasn't properly allocated). - -(1.1.3c1 released) - -+ Added ANTIALIAS downsampling filter for high-quality "resize" - and "thumbnail" operations. Also added filter option to the - "thumbnail" operation; the default value is NEAREST, but this - will most likely change in future versions. - -+ Fixed plugin loader to be more robust if the __file__ - variable isn't set. - -+ Added seek/tell support (for layers) to the PhotoShop - loader. Layer 0 is the main image. - -+ Added new (but experimental) "ImageOps" module, which provides - shortcuts for commonly used operations on entire images. - -+ Don't mess up when loading PNG images if the decoder leaves - data in the output buffer. This could cause internal errors - on some PNG images, with some versions of ZLIB. (Bug report - and patch provided by Bernhard Herzog.) - -+ Don't mess up on Unicode filenames. - -+ Don't mess up when drawing on big endian platforms. - -+ Made the TIFF loader a bit more robust; it can now read some - more slightly broken TIFF files (based on input from Ted Wright, - Bob Klimek, and D. Alan Stewart) - -+ Added OS/2 EMX build files (from Andrew MacIntyre) - -+ Change "ImageFont" to reject image files if they don't have the - right mode. Older versions could leak memory for "P" images. - (Bug reported by Markus Gritsch). - -+ Renamed some internal functions to avoid potential build - problem on Mac OS X. - -+ Added DL_EXPORT where relevant (for Cygwin, based on input - from Robert Yodlowski) - -+ (re)moved bogus __init__ call in BdfFontFile (bug spotted - by Fred Clare) - -+ Added "ImageGrab" support (Windows only) - -+ Added support for XBM hotspots (based on code contributed by - Bernhard Herzog). - -+ Added write support for more TIFF tags, namely the Artist, - Copyright, DateTime, ResolutionUnit, Software, XResolution and - YResolution tags (from Greg Couch) - -+ Added TransposedFont wrapper to ImageFont module - -+ Added "optimize" flag to GIF encoder. If optimize is present - and non-zero, PIL will work harder to create a small file. - -+ Raise "EOFError" (not IndexError) when reading beyond the - end of a TIFF sequence. - -+ Support rewind ("seek(0)") for GIF and TIFF sequences. - -+ Load grayscale GIF images as mode "L" - -+ Added DPI read/write support to the JPEG codec. The decoder - sets the info["dpi"] attribute for JPEG files with JFIF dpi - settings. The encoder uses the "dpi" option: - - im = Image.open("file.jpg") - dpi = im.info["dpi"] # raises KeyError if DPI not known - im.save("out.jpg", dpi=dpi) - - Note that PIL doesn't always preserve the "info" attribute - for normal image operations. - -(1.1.2c1 and 1.1.2 final released) - -+ Adapted to Python 2.1. Among other things, all uses of the - "regex" module has been repleased with "re". - -+ Fixed attribute error when reading large PNG files (this bug - was introduced in maintenance code released after the 1.1.1 - release) - -+ Ignore non-string objects in sys.path - -+ Fixed Image.transform(EXTENT) for negative xoffsets - -+ Fixed loading of image plugins if PIL is installed as a package. - (The plugin loader now always looks in the directory where the - Image.py module itself is found, even if that directory isn't on - the standard search path) - -+ The Png plugin has been added to the list of preloaded standard - formats - -+ Fixed bitmap/text drawing in fill mode. - -+ Fixed "getextrema" to work also for multiband images. - -+ Added transparency support for L and P images to the PNG codec. - -+ Improved support for read-only images. The "load" method now - sets the "readonly" attribute for memory-mapped images. Operations - that modifies an image in place (such as "paste" and drawing operations) - creates an in-memory copy of the image, if necessary. (before this - change, any attempt to modify a memory-mapped image resulted in a - core dump...) - -+ Added special cases for lists everywhere PIL expects a sequence. - This should speed up things like "putdata" and drawing operations. - -+ The Image.offset method is deprecated. Use the ImageChops.offset - function instead. - -+ Changed ImageChops operators to copy palette and info dictionary - from the first image argument. - -(1.1.1 released) - -+ Additional fixes for Python 1.6/2.0, including TIFF "save" bug. - -+ Changed "init" to properly load plugins when PIL is used as a - package. - -+ Fixed broken "show" method (on Unix) - -*** Changes from release 1.0 to 1.1 *** - -+ Adapted to Python 1.6 ("append" and other method changes) - -+ Fixed Image.paste when pasting with solid colour and matte - layers ("L" or "RGBA" masks) (bug reported by Robert Kern) - -+ To make it easier to distribute prebuilt versions of PIL, - the tkinit binding stuff has been moved to a separate - extension module, named "_imagingtk". - -*** Changes from release 0.3b2 to 1.0 final *** - -+ If there's no 16-bit integer (like on a Cray T3E), set - INT16 to the smallest integer available. Most of the - library works just fine anyway (from Bill Crutchfield) - -+ Tweaks to make drawing work on big-endian platforms. - -(1.0c2 released) - -+ If PIL is built with the WITH_TKINTER flag, ImageTk can - automatically hook into a standard Tkinter build. You - no longer need to build your own Tkinter to use the - ImageTk module. - - The old way still works, though. For more information, - see Tk/install.txt. - -+ Some tweaks to ImageTk to support multiple Tk interpreters - (from Greg Couch). - -+ ImageFont "load_path" now scans directory mentioned in .pth - files (from Richard Jones). - -(1.0c1 released) - -+ The TIFF plugin has been rewritten. The new plugin fully - supports all major PIL image modes (including F and I). - -+ The ImageFile module now includes a Parser class, which can - be used to incrementally decode an image file (while down- - loading it from the net, for example). See the handbook for - details. - -+ "show" now converts non-standard modes to "L" or "RGB" (as - appropriate), rather than writing weird things to disk for - "xv" to choke upon. (bug reported by Les Schaffer). - -(1.0b2 released) - -+ Major speedups for rotate, transform(EXTENT), and transform(AFFINE) - when using nearest neighbour resampling. - -+ Modified ImageDraw to be compatible with the Arrow graphics - interface. See the handbook for details. - -+ PIL now automatically loads file codecs when used as a package - (from The Dragon De Monsyne). Also included an __init__.py file - in the standard distribution. - -+ The GIF encoder has been modified to produce much smaller files. - - PIL now uses a run-length encoding method to encode GIF files. - On a random selection of GIF images grabbed from the web, this - version makes the images about twice as large as the original - LZW files, where the earlier version made them over 5 times - larger. YMMV, of course. - -+ Added PCX write support (works with "1", "P", "L", and "RGB") - -+ Added "bitmap" and "textsize" methods to ImageDraw. - -+ Improved font rendering code. Fixed a bug or two, and moved - most of the time critical stuff to C. - -+ Removed "bdf2pil.py". Use "pilfont.py" instead! - -+ Improved 16-bit support (still experimental, though). - - The following methods now support "I;16" and "I;16B" images: - "getpixel", "copy", "convert" (to and from mode "I"), "resize", - "rotate", and "transform" with nearest neighbour filters, and - "save" using the IM format. The "new" and "open" functions - also work as expected. On Windows, 16-bit files are memory - mapped. - - NOTE: ALL other operations are still UNDEFINED on 16-bit images. - -+ The "paste" method now supports constant sources. - - Just pass a colour value (a number or a tuple, depending on - the target image mode) instead of the source image. - - This was in fact implemented in an inefficient way in - earlier versions (the "paste" method generated a temporary - source image if you passed it a colour instead of an image). - In this version, this is handled on the C level instead. - -+ Added experimental "RGBa" mode support. - - An "RGBa" image is an RGBA image where the colour components - have have been premultipled with the alpha value. PIL allows - you to convert an RGBA image to an RGBa image, and to paste - RGBa images on top of RGB images. Since this saves a bunch - of multiplications and shifts, it is typically about twice - as fast an ordinary RGBA paste. - -+ Eliminated extra conversion step when pasting "RGBA" or "RGBa" - images on top of "RGB" images. - -+ Fixed Image.BICUBIC resampling for "RGB" images. - -+ Fixed PCX image file handler to properly read 8-bit PCX - files (bug introduced in 1.0b1, reported by Bernhard - Herzog) - -+ Fixed PSDraw "image" method to restore the coordinate - system. - -+ Fixed "blend" problem when applied to images that was - not already loaded (reported by Edward C. Jones) - -+ Fixed -f option to "pilconvert.py" (from Anthony Baxter) - -(1.0b1 released) - -+ Added Toby J. Sargeant's quantization package. To enable - quantization, use the "palette" option to "convert": - - imOut = im.convert("P", palette=Image.ADAPTIVE) - - This can be used with "L", "P", and "RGB" images. In this - version, dithering cannot be used with adaptive palettes. - - Note: ADAPTIVE currently maps to median cut quantization - with 256 colours. The quantization package also contains - a maximum coverage quantizer, which will be supported by - future versions of PIL. - -+ Added Eric S. Raymond's "pildriver" image calculator to the - distribution. See the docstring for more information. - -+ The "offset" method no longer dumps core if given positive - offsets (from Charles Waldman). - -+ Fixed a resource leak that could cause ImageWin to run out of - GDI resources (from Roger Burnham). - -+ Added "arc", "chord", and "pieslice" methods to ImageDraw (inspired - by code contributed by Richard Jones). - -+ Added experimental 16-bit support, via modes "I;16" (little endian - data) and "I;16B" (big endian). Only a few methods properly support - such images (see above). - -+ Added XV thumbnail file handler (from Gene Cash). - -+ Fixed BMP image file handler to handle palette images with small - palettes (from Rob Hooft). - -+ Fixed Sun raster file handler for palette images (from Charles - Waldman). - -+ Improved various internal error messages. - -+ Fixed Path constructor to handle arbitrary sequence objects. This - also affects the ImageDraw class (from Richard Jones). - -+ Fixed a bug in JpegDecode that caused PIL to report "decoder error - -2" for some progressive JPEG files (reported by Magnus Källström, - who also provided samples). - -+ Fixed a bug in JpegImagePlugin that caused PIL to hang when loading - JPEG files using 16-bit quantization tables. - -+ The Image "transform" method now supports Image.QUAD transforms. - The data argument is an 8-tuple giving the upper left, lower - left, lower right, and upper right corner of the source quadri- - lateral. Also added Image.MESH transform which takes a list - of quadrilaterals. - -+ The Image "resize", "rotate", and "transform" methods now support - Image.BILINEAR (2x2) and Image.BICUBIC (4x4) resampling filters. - Filters can be used with all transform methods. - -+ The ImageDraw "rectangle" method now includes both the right - and the bottom edges when drawing filled rectangles. - -+ The TGA decoder now works properly for runlength encoded images - which have more than one byte per pixel. - -+ "getbands" on an YCbCr image now returns ("Y", "Cb", "Cr") - -+ Some file drivers didn't handle the optional "modify" argument - to the load method. This resulted in exceptions when you used - "paste" (and other methods that modify an image in place) on a - newly opened file. - -*** Changes from release 0.2 (b5) to 0.3 (b2) *** - -(0.3b2 released) - -The test suite includes 825 individual tests. - -+ An Image "getbands" method has been added. It returns a tuple - containing the individual band names for this image. To figure - out how many bands an image has, use "len(im.getbands())". - -+ An Image "putpixel" method has been added. - -+ The Image "point" method can now be used to convert "L" images - to any other format, via a lookup table. That table should - contain 256 values for each band in the output image. - -+ Some file drivers (including FLI/FLC, GIF, and IM) accidently - overwrote the offset method with an internal attribute. All - drivers have been updated to use private attributes where - possible. - -+ The Image "histogram" method now works for "I" and "F" images. - For these modes, PIL divides the range between the min and - max values used in the image into 256 bins. You can also - pass in your own min and max values via the "extrema" option: - - h = im.histogram(extrema=(0, 255)) - -+ An Image "getextrema" method has been added. It returns the - min and max values used in the image. In this release, this - works for single band images only. - -+ Changed the PNG driver to load and save mode "I" images as - 16-bit images. When saving, values outside the range 0..65535 - are clipped. - -+ Fixed ImageFont.py to work with the new "pilfont" compiler. - -+ Added JPEG "save" and "draft" support for mode "YCbCr" images. - Note that if you save an "YCbCr" image as a JPEG file and read - it back, it is read as an RGB file. To get around this, you - can use the "draft" method: - - im = Image.open("color.jpg") - im.draft("YCbCr", im.size) - -+ Read "RGBA" TGA images. Also fixed the orientation bug; all - images should now come out the right way. - -+ Changed mode name (and internal representation) from "YCrCb" - to "YCbCr" (!) - *** WARNING: MAY BREAK EXISTING CODE *** - -(0.3b1 released) - -The test suite includes 750 individual tests. - -+ The "pilfont" package is now included in the standard PIL - distribution. The pilfont utility can be used to convert - X BDF and PCF raster font files to a format understood by - the ImageFont module. - -+ GIF files are now interlaced by default. To write a - non-interlaced file, pass interlace=0 to the "save" - method. - -+ The default string format has changed for the "fromstring" - and "tostring" methods. - *** WARNING: MAY BREAK EXISTING CODE *** - - NOTE: If no extra arguments are given, the first line in - the string buffer is the top line of the image, instead of - the bottom line. For RGB images, the string now contains - 3 bytes per pixel instead of 4. These changes were made - to make the methods compatible with the "fromstring" - factory function. - - To get the old behaviour, use the following syntax: - - data = im.tostring("raw", "RGBX", 0, -1) - im.fromstring(data, "raw", "RGBX", 0, -1) - -+ "new" no longer gives a MemoryError if the width or height - is zero (this only happened on platforms where malloc(0) - or calloc(0) returns NULL). - -+ "new" now adds a default palette object to "P" images. - -+ You can now convert directly between all modes supported by - PIL. When converting colour images to "P", PIL defaults to - a "web" palette and dithering. When converting greyscale - images to "1", PIL uses a thresholding and dithering. - -+ Added a "dither" option to "convert". By default, "convert" - uses floyd-steinberg error diffusion for "P" and "1" targets, - so this option is only used to *disable* dithering. Allowed - values are NONE (no dithering) or FLOYDSTEINBERG (default). - - imOut = im.convert("P", dither=Image.NONE) - -+ Added a full set of "I" decoders. You can use "fromstring" - (and file decoders) to read any standard integer type as an - "I" image. - -+ Added some support for "YCbCr" images (creation, conversion - from/to "L" and "RGB", IM YCC load/save) - -+ "getpixel" now works properly with fractional coordinates. - -+ ImageDraw "setink" now works with "I", "F", "RGB", "RGBA", - "RGBX", "CMYK", and "YCbCr" images. - -+ ImImagePlugin no longer attaches palettes to "RGB" images. - -+ Various minor fixes. - -(0.3a4 released) - -+ Added experimental IPTC/NAA support. - -+ Eliminated AttributeError exceptions after "crop" (from - Skip Montanaro) - -+ Reads some uncompressed formats via memory mapping (this - is currently supported on Win32 only) - -+ Fixed some last minute glitches in the last alpha release - (Types instead of types in Image.py, version numbers, etc.) - -+ Eliminated some more bogus compiler warnings. - -+ Various fixes to make PIL compile and run smoother on Macs - (from Jack Jansen). - -+ Fixed "fromstring" and "tostring" for mode "I" images. - -(0.3a3 released) - -The test suite includes 530 individual tests. - -+ Eliminated unexpected side-effect in "paste" with matte. "paste" - now works properly also if compiled with "gcc". - -+ Adapted to Python 1.5 (build issues only) - -+ Fixed the ImageDraw "point" method to draw also the last - point (!). - -+ Added "I" and "RGBX" support to Image.new. - -+ The plugin path is now properly prepended to the module search - path when a plugin module is imported. - -+ Added "draw" method to the ImageWin.Dib class. This is used by - Topaz to print images on Windows printers. - -+ "convert" now supports conversions from "P" to "1" and "F". - -+ "paste" can now take a colour instead of an image as the first argument. - The colour must match the colour argument given to the new function, and - match the mode of the target image. - -+ Fixed "paste" to allow a mask also for mode "F" images. - -+ The BMP driver now saves mode "1" images. When loading images, the mode - is set to "L" for 8-bit files with greyscale palettes, and to "P" for - other 8-bit files. - -+ The IM driver now reads and saves "1" images (file modes "0 1" or "L 1"). - -+ The JPEG and GIF drivers now saves "1" images. For JPEG, the image - is saved as 8-bit greyscale (it will load as mode "L"). For GIF, the - image will be loaded as a "P" image. - -+ Fixed a potential buffer overrun in the GIF encoder. - -(0.3a2 released) - -The test suite includes 400 individual tests. - -+ Improvements to the test suite revealed a number of minor bugs, which - are all fixed. Note that crop/paste, 32-bit ImageDraw, and ImageFont - are still weak spots in this release. - -+ Added "putpalette" method to the Image class. You can use this - to add or modify the palette for "P" and "L" images. If a palette - is added to an "L" image, it is automatically converted to a "P" - image. - -+ Fixed ImageDraw to properly handle 32-bit image memories - ("RGB", "RGBA", "CMYK", "F") - -+ Fixed "fromstring" and "tostring" not to mess up the mode attribute - in default mode. - -+ Changed ImPlatform.h to work on CRAY's (don't have one at home, so I - haven't tried it). The previous version assumed that either "short" - or "int" were 16-bit wide. PIL still won't compile on platforms where - neither "short", "int" nor "long" are 32-bit wide. - -+ Added file= and data= keyword arguments to PhotoImage and BitmapImage. - This allows you to use them as drop-in replacements for the corre- - sponding Tkinter classes. - -+ Removed bogus references to the crack coder (ImagingCrack). - -(0.3a1 released) - -+ Make sure image is loaded in "tostring". - -+ Added floating point packer (native 32-bit floats only). - -*** Changes from release 0.1b1 to 0.2 (b5) *** - -+ Modified "fromstring" and "tostring" methods to use file codecs. - Also added "fromstring" factory method to create an image directly - from data in a string. - -+ Added support for 32-bit floating point images (mode "F"). You - can convert between "L" and "F" images, and apply a subset of the - available image processing methods on the "F" image. You can also - read virtually any data format into a floating point image memory; - see the section on "Decoding Floating Point Data" in the handbook - for more information. - -(0.2b5 released; on windows only) - -+ Fixed the tobitmap() method to work properly for small bitmaps. - -+ Added RMS and standard deviation to the ImageStat.Stat class. Also - modified the constructor to take an optional feature mask, and also - to accept either an image or a list containing the histogram data. - -+ The BitmapImage code in ImageTk can now use a special bitmap - decoder, which has to be patched into Tk. See the "Tk/pilbitmap.txt" - file for details. If not installed, bitmaps are transferred to Tk as - XBM strings. - -+ The PhotoImage code in ImageTk now uses a Tcl command ("PyImagingPaste") - instead of a special image type. This gives somewhat better performance, - and also allows PIL to support transparency. - *** WARNING: TKAPPINIT MUST BE MODIFIED *** - -+ ImageTk now honours the alpha layer in RGBA images. Only fully - transparent pixels are made transparent (that is, the alpha layer - is treated as a mask). To treat the alpha laters as a matte, you - must paste the image on the background before handing it over to - ImageTk. - -+ Added McIdas reader (supports 8-bit images only). - -+ PIL now preloads drivers for BMP, GIF, JPEG, PPM, and TIFF. As - long as you only load and save these formats, you don't have to - wait for a full scan for drivers. To force scanning, call the - Image.init() function. - -+ The "seek" and "tell" methods are now always available, also for - single-frame images. - -+ Added optional mask argument to histogram method. The mask may - be an "1" or "L" image with the same size as the original image. - Only pixels where the mask is non-zero are included in the - histogram. - -+ The "paste" method now allows you to specify only the lower left - corner (a 2-tuple), instead of the full region (a 4-tuple). - -+ Reverted to old plugin scanning model; now scans all directory - names in the path when looking for plugins. - -+ Added PIXAR raster support. Only uncompressed ("dumped") RGB - images can currently be read (based on information provided - by Greg Coats). - -+ Added FlashPix (FPX) read support. Reads all pixel formats, but - only the highest resolution is read, and the viewing transform is - currently ignored. - -+ Made PNG encoding somewhat more efficient in "optimize" mode; a - bug in 0.2b4 didn't enable all predictor filters when optimized - storage were requested. - -+ Added Microsoft Image Composer (MIC) read support. When opened, - the first sprite in the file is loaded. You can use the seek method - to load additional sprites from the file. - -+ Properly reads "P" and "CMYK" PSD images. - -+ "pilconvert" no longer optimizes by default; use the -o option to - make the file as small as possible (at the expense of speed); use - the -q option to set the quality when compressing to JPEG. - -+ Fixed "crop" not to drop the palette for "P" images. - -+ Added and verified FLC support. - -+ Paste with "L" or "RGBA" alpha is now several times faster on most - platforms. - -+ Changed Image.new() to initialize the image to black, as described - in the handbook. To get an uninitialized image, use None as the - colour. - -+ Fixed the PDF encoder to produce a valid header; Acrobat no longer - complains when you load PDF images created by PIL. - -+ PIL only scans fully-qualified directory names in the path when - looking for plugins. - *** WARNING: MAY BREAK EXISTING CODE *** - -+ Faster implementation of "save" used when filename is given, - or when file object has "fileno" and "flush" methods. - -+ Don't crash in "crop" if region extends outside the source image. - -+ Eliminated a massive memory leak in the "save" function. - -+ The GIF decoder doesn't crash if the code size is set to an illegal - value. This could happen since another bug didn't handle local - palettes properly if they didn't have the same size as the - global palette (not very common). - -+ Added predictor support (TIFF 6.0 section 14) to the TIFF decoder. - -+ Fixed palette and padding problems in BMP driver. Now properly - writes "1", "L", "P" and "RGB" images. - -+ Fixed getpixel()/getdata() to return correct pixel values. - -+ Added PSD (PhotoShop) read support. Reads both uncompressed - and compressed images of most types. - -+ Added GIF write support (writes "uncompressed" GIF files only, - due to unresolvable licensing issues). The "gifmaker.py" script - can be used to create GIF animations. - -+ Reads 8-bit "L" and "P" TGA images. Also reads 16-bit "RGB" - images. - -+ Added FLI read support. This driver has only been tested - on a few FLI samples. - -+ Reads 2-bit and 4-bit PCX images. - -+ Added MSP read and write support. Both version 1 and 2 can be - read, but only version 1 (uncompressed) files are written. - -+ Fixed a bug in the FLI/FLC identification code that caused the - driver to raise an exception when parsing valid FLI/FLC files. - -+ Improved performance when loading file format plugins, and when - opening files. - -+ Added GIF animation support, via the "seek" and "tell" methods. - You can use "player.py" to play an animated GIF file. - -+ Removed MNG support, since the spec is changing faster than I - can change the code. I've added support for the experimental - ARG format instead. Contact me for more information on this - format. - -+ Added keyword options to the "save" method. The following options - are currently supported: - - format option description - -------------------------------------------------------- - JPEG optimize minimize output file at the - expense of compression speed. - - JPEG progressive enable progressive output. the - option value is ignored. - - JPEG quality set compression quality (1-100). - the default value is 75. - - JPEG smooth smooth dithered images. value - is strengh (1-100). default is - off (0). - - PNG optimize minimize output file at the - expense of compression speed. - - Expect more options in future releases. Also note that - file writers silently ignore unknown options. - -+ Plugged memory leaks in the PNG and TIFF decoders. - -+ Added PNG write support. - -+ (internal) RGB unpackers and converters now set the pad byte - to 255 (full opacity). - -+ Properly handles the "transparency" property for GIF, PNG - and XPM files. - -+ Added a "putalpha" method, allowing you to attach a "1" or "L" - image as the alpha layer to an "RGBA" image. - -+ Various improvements to the sample scripts: - - "pilconvert" Carries out some extra tricks in order to make - the resulting file as small as possible. - - "explode" (NEW) Split an image sequence into individual frames. - - "gifmaker" (NEW) Convert a sequence file into a GIF animation. - Note that the GIF encoder create "uncompressed" GIF - files, so animations created by this script are - rather large (typically 2-5 times the compressed - sizes). - - "image2py" (NEW) Convert a single image to a python module. See - comments in this script for details. - - "player" If multiple images are given on the command line, - they are interpreted as frames in a sequence. The - script assumes that they all have the same size. - Also note that this script now can play FLI/FLC - and GIF animations. - - This player can also execute embedded Python - animation applets (ARG format only). - - "viewer" Transparent images ("P" with transparency property, - and "RGBA") are superimposed on the standard Tk back- - ground. - -+ Fixed colour argument to "new". For multilayer images, pass a - tuple: (Red, Green, Blue), (Red, Green, Blue, Alpha), or (Cyan, - Magenta, Yellow, Black). - -+ Added XPM (X pixmap) read support. - -(0.2b3 released) - -+ Added MNG (multi-image network graphics) read support. "Ming" - is a proposed animation standard, based on the PNG file format. - - You can use the "player" sample script to display some flavours - of this format. The MNG standard is still under development, - as is this driver. More information, including sample files, - can be found at - -+ Added a "verify" method to images loaded from file. This method - scans the file for errors, without actually decoding the image - data, and raises a suitable exception if it finds any problems. - Currently implemented for PNG and MNG files only. - -+ Added support for interlaced GIF images. - -+ Added PNG read support -- if linked with the ZLIB compression library, - PIL reads all kinds of PNG images, except interlaced files. - -+ Improved PNG identification support -- doesn't mess up on unknown - chunks, identifies all possible PNG modes, and verifies checksum - on PNG header chunks. - -+ Added an experimental reader for placable Windows Meta Files (WMF). - This reader is still very incomplete, but it illustrates how PIL's - drawing capabilities can be used to render vector and metafile - formats. - -+ Added restricted drivers for images from Image Tools (greyscale - only) and LabEye/IFUNC (common interchange modes only). - -+ Some minor improvements to the sample scripts provided in the - "Scripts" directory. - -+ The test images have been moved to the "Images" directory. - -(0.2b2 released) -(0.2b1 released; Windows only) - -+ Fixed filling of complex polygons. The ImageDraw "line" and - "polygon" methods also accept Path objects. - -+ The ImageTk "PhotoImage" object can now be constructed directly - from an image. You can also pass the object itself to Tkinter, - instead of using the "image" attribute. Finally, using "paste" - on a displayed image automatically updates the display. - -+ The ImageTk "BitmapImage" object allows you to create transparent - overlays from 1-bit images. You can pass the object itself to - Tkinter. The constructor takes the same arguments as the Tkinter - BitmapImage class; use the "foreground" option to set the colour - of the overlay. - -+ Added a "putdata" method to the Image class. This can be used to - load a 1-layer image with data from a sequence object or a string. - An optional floating point scale and offset can be used to adjust - the data to fit into the 8-bit pixel range. Also see the "getdata" - method. - -+ Added the EXTENT method to the Image "transform" method. This can - be used to quickly crop, stretch, shrink, or mirror a subregion - from another image. - -+ Adapted to Python 1.4. - -+ Added a project makefile for Visual C++ 4.x. This allows you to - easily build a dynamically linked version of PIL for Windows 95 - and NT. - -+ A Tk "booster" patch for Windows is available. It gives dramatic - performance improvements for some displays. Has been tested with - Tk 4.2 only, but is likely to work with Tk 4.1 as well. See the Tk - subdirectory for details. - -+ You can now save 1-bit images in the XBM format. In addition, the - Image class now provides a "tobitmap" method which returns a string - containing an XBM representation of the image. Quite handy to use - with Tk. - -+ More conversions, including "RGB" to "1" and more. - -(0.2a1 released) - -+ Where earlier versions accepted lists, this version accepts arbitrary - Python sequences (including strings, in some cases). A few resource - leaks were plugged in the process. - -+ The Image "paste" method now allows the box to extend outside - the target image. The size of the box, the image to be pasted, - and the optional mask must still match. - -+ The ImageDraw module now supports filled polygons, outlined and - filled ellipses, and text. Font support is rudimentary, though. - -+ The Image "point" method now takes an optional mode argument, - allowing you to convert the image while translating it. Currently, - this can only be used to convert "L" or "P" images to "1" images - (creating thresholded images or "matte" masks). - -+ An Image "getpixel" method has been added. For single band images, - it returns the pixel value at a given position as an integer. - For n-band images, it returns an n-tuple of integers. - -+ An Image "getdata" method has been added. It returns a sequence - object representing the image as a 1-dimensional array. Only len() - and [] can be used with this sequence. This method returns a - reference to the existing image data, so changes in the image - will be immediately reflected in the sequence object. - -+ Fixed alignment problems in the Windows BMP writer. - -+ If converting an "RGB" image to "RGB" or "L", you can give a second - argument containing a colour conversion matrix. - -+ An Image "getbbox" method has been added. It returns the bounding - box of data in an image, considering the value 0 as background. - -+ An Image "offset" method has been added. It returns a new image - where the contents of the image have been offset the given distance - in X and/or Y direction. Data wraps between edges. - -+ Saves PDF images. The driver creates a binary PDF 1.1 files, using - JPEG compression for "L", "RGB", and "CMYK" images, and hex encoding - (same as for PostScript) for other formats. - -+ The "paste" method now accepts "1" masks. Zero means transparent, - any other pixel value means opaque. This is faster than using an - "L" transparency mask. - -+ Properly writes EPS files (and properly prints images to postscript - printers as well). - -+ Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR - files. Cursor animations are not supported. - -+ Fixed alignment problems in the Sun raster loader. - -+ Added "draft" and "thumbnail" methods. The draft method is used - to optimize loading of JPEG and PCD files, the thumbnail method is - used to create a thumbnail representation of an image. - -+ Added Windows display support, via the ImageWin class (see the - handbook for details). - -+ Added raster conversion for EPS files. This requires GNU or Aladdin - Ghostscript, and probably works on UNIX only. - -+ Reads PhotoCD (PCD) images. The base resolution (768x512) can be - read from a PhotoCD file. - -+ Eliminated some compiler warnings. Bindings now compile cleanly in C++ - mode. Note that the Imaging library itself must be compiled in C mode. - -+ Added "bdf2pil.py", which converts BDF fonts into images with associated - metrics. This is definitely work in progress. For info, see description - in script for details. - -+ Fixed a bug in the "ImageEnhance.py" module. - -+ Fixed a bug in the netpbm save hack in "GifImagePlugin.py" - -+ Fixed 90 and 270 degree rotation of rectangular images. - -+ Properly reads 8-bit TIFF palette-color images. - -+ Reads plane separated RGB and CMYK TIFF images. - -+ Added driver debug mode. This is enabled by setting Image.DEBUG - to a non-zero value. Try the -D option to "pilfile.py" and see what - happens. - -+ Don't crash on "atend" constructs in PostScript files. - -+ Only the Image module imports _imaging directly. Other modules - should refer to the binding module as "Image.core". - -*** Changes from release 0.0 to 0.1 (b1) *** - -+ A handbook is available (distributed separately). - -+ The coordinate system is changed so that (0,0) is now located - in the upper left corner. This is in compliancy with ISO 12087 - and 90% of all other image processing and graphics libraries. - -+ Modes "1" (bilevel) and "P" (palette) have been introduced. Note - that bilevel images are stored with one byte per pixel. - -+ The Image "crop" and "paste" methods now accepts None as the - box argument, to refer to the full image (self, that is). - -+ The Image "crop" method now works properly. - -+ The Image "point" method is now available. You can use either a - lookup table or a function taking one argument. - -+ The Image join function has been renamed to "merge". - -+ An Image "composite" function has been added. It is identical - to copy() followed by paste(mask). - -+ An Image "eval" function has been added. It is currently identical - to point(function); that is, only a single image can be processed. - -+ A set of channel operations has been added. See the "ImageChops" - module, test_chops.py, and the handbook for details. - -+ Added the "pilconvert" utility, which converts image files. Note - that the number of output formats are still quite restricted. - -+ Added the "pilfile" utility, which quickly identifies image files - (without loading them, in most cases). - -+ Added the "pilprint" utility, which prints image files to Postscript - printers. - -+ Added a rudimentary version of the "pilview" utility, which is - simple image viewer based on Tk. Only File/Exit and Image/Next - works properly. - -+ An interface to Tk has been added. See "Lib/ImageTk.py" and README - for details. - -+ An interface to Jack Jansen's Img library has been added (thanks to - Jack). This allows you to read images through the Img extensions file - format handlers. See the file "Lib/ImgExtImagePlugin.py" for details. - -+ Postscript printing is provided through the PSDraw module. See the - handbook for details. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS b/tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS deleted file mode 100755 index 8846fb94547..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/CONTENTS +++ /dev/null @@ -1,299 +0,0 @@ -Imaging/README - -Imaging/CHANGES - -Imaging/CONTENTS -Imaging/MANIFEST - -Imaging/BUILDME - -Imaging/setup.py - -Imaging/selftest.py -Imaging/doctest.py - -Imaging/libImaging/Imaging.h -Imaging/libImaging/ImDib.h -Imaging/libImaging/ImPlatform.h - -Imaging/libImaging/Quant.h -Imaging/libImaging/QuantHash.h -Imaging/libImaging/QuantHeap.h -Imaging/libImaging/QuantDefines.h -Imaging/libImaging/QuantTypes.h - -Imaging/libImaging/Access.c -Imaging/libImaging/Antialias.c -Imaging/libImaging/Bands.c -Imaging/libImaging/Blend.c -Imaging/libImaging/Chops.c -Imaging/libImaging/Convert.c -Imaging/libImaging/ConvertYCbCr.c -Imaging/libImaging/Copy.c -Imaging/libImaging/Crc32.c -Imaging/libImaging/Crop.c -Imaging/libImaging/Dib.c -Imaging/libImaging/Draw.c -Imaging/libImaging/Effects.c -Imaging/libImaging/Except.c -Imaging/libImaging/File.c -Imaging/libImaging/Fill.c -Imaging/libImaging/Filter.c -Imaging/libImaging/Geometry.c -Imaging/libImaging/GetBBox.c -Imaging/libImaging/Histo.c -Imaging/libImaging/Matrix.c -Imaging/libImaging/ModeFilter.c -Imaging/libImaging/Negative.c -Imaging/libImaging/Offset.c -Imaging/libImaging/Pack.c -Imaging/libImaging/Palette.c -Imaging/libImaging/Paste.c -Imaging/libImaging/Point.c -Imaging/libImaging/Quant.c -Imaging/libImaging/QuantHash.c -Imaging/libImaging/QuantHeap.c -Imaging/libImaging/RankFilter.c -Imaging/libImaging/Storage.c -Imaging/libImaging/Unpack.c -Imaging/libImaging/UnpackYCC.c -Imaging/libImaging/UnsharpMask.c - -Imaging/libImaging/Bit.h -Imaging/libImaging/Gif.h -Imaging/libImaging/Jpeg.h -Imaging/libImaging/Lzw.h -Imaging/libImaging/Raw.h -Imaging/libImaging/Zip.h -Imaging/libImaging/BitDecode.c -Imaging/libImaging/EpsEncode.c -Imaging/libImaging/FliDecode.c -Imaging/libImaging/GifDecode.c -Imaging/libImaging/GifEncode.c -Imaging/libImaging/HexDecode.c -Imaging/libImaging/JpegDecode.c -Imaging/libImaging/JpegEncode.c -Imaging/libImaging/LzwDecode.c -Imaging/libImaging/MspDecode.c -Imaging/libImaging/PackDecode.c -Imaging/libImaging/PcdDecode.c -Imaging/libImaging/PcxEncode.c -Imaging/libImaging/PcxDecode.c -Imaging/libImaging/RawDecode.c -Imaging/libImaging/RawEncode.c -Imaging/libImaging/SunRleDecode.c -Imaging/libImaging/TgaRleDecode.c -Imaging/libImaging/XbmDecode.c -Imaging/libImaging/XbmEncode.c -Imaging/libImaging/ZipDecode.c -Imaging/libImaging/ZipEncode.c - -Imaging/_imaging.c -Imaging/decode.c -Imaging/encode.c -Imaging/display.c -Imaging/map.c -Imaging/outline.c -Imaging/path.c - -Imaging/_imagingtk.c -Imaging/_imagingft.c -Imaging/_imagingcms.c -Imaging/_imagingmath.c - -Imaging/PIL.pth -Imaging/PIL/__init__.py -Imaging/PIL/ArgImagePlugin.py -Imaging/PIL/BdfFontFile.py -Imaging/PIL/BmpImagePlugin.py -Imaging/PIL/BufrStubImagePlugin.py -Imaging/PIL/ContainerIO.py -Imaging/PIL/CurImagePlugin.py -Imaging/PIL/DcxImagePlugin.py -Imaging/PIL/EpsImagePlugin.py -Imaging/PIL/ExifTags.py -Imaging/PIL/FitsStubImagePlugin.py -Imaging/PIL/FliImagePlugin.py -Imaging/PIL/FontFile.py -Imaging/PIL/FpxImagePlugin.py -Imaging/PIL/GbrImagePlugin.py -Imaging/PIL/GdImageFile.py -Imaging/PIL/GifImagePlugin.py -Imaging/PIL/GimpGradientFile.py -Imaging/PIL/GimpPaletteFile.py -Imaging/PIL/GribStubImagePlugin.py -Imaging/PIL/Hdf5StubImagePlugin.py -Imaging/PIL/IcoImagePlugin.py -Imaging/PIL/IcnsImagePlugin.py -Imaging/PIL/Image.py -Imaging/PIL/ImageChops.py -Imaging/PIL/ImageCms.py -Imaging/PIL/ImageColor.py -Imaging/PIL/ImageDraw.py -Imaging/PIL/ImageDraw2.py -Imaging/PIL/ImageEnhance.py -Imaging/PIL/ImageFile.py -Imaging/PIL/ImageFileIO.py -Imaging/PIL/ImageFilter.py -Imaging/PIL/ImageFont.py -Imaging/PIL/ImageGL.py -Imaging/PIL/ImageGrab.py -Imaging/PIL/ImageMath.py -Imaging/PIL/ImageMode.py -Imaging/PIL/ImageOps.py -Imaging/PIL/ImagePalette.py -Imaging/PIL/ImagePath.py -Imaging/PIL/ImageQt.py -Imaging/PIL/ImageSequence.py -Imaging/PIL/ImageShow.py -Imaging/PIL/ImageStat.py -Imaging/PIL/ImageTk.py -Imaging/PIL/ImageTransform.py -Imaging/PIL/ImageWin.py -Imaging/PIL/ImImagePlugin.py -Imaging/PIL/ImtImagePlugin.py -Imaging/PIL/IptcImagePlugin.py -Imaging/PIL/JpegImagePlugin.py -Imaging/PIL/McIdasImagePlugin.py -Imaging/PIL/MicImagePlugin.py -Imaging/PIL/MpegImagePlugin.py -Imaging/PIL/MspImagePlugin.py -Imaging/PIL/OleFileIO.py -Imaging/PIL/PaletteFile.py -Imaging/PIL/PalmImagePlugin.py -Imaging/PIL/PcdImagePlugin.py -Imaging/PIL/PcfFontFile.py -Imaging/PIL/PcxImagePlugin.py -Imaging/PIL/PdfImagePlugin.py -Imaging/PIL/PixarImagePlugin.py -Imaging/PIL/PngImagePlugin.py -Imaging/PIL/PpmImagePlugin.py -Imaging/PIL/PsdImagePlugin.py -Imaging/PIL/PSDraw.py -Imaging/PIL/SgiImagePlugin.py -Imaging/PIL/SpiderImagePlugin.py -Imaging/PIL/SunImagePlugin.py -Imaging/PIL/TarIO.py -Imaging/PIL/TgaImagePlugin.py -Imaging/PIL/TiffImagePlugin.py -Imaging/PIL/TiffTags.py -Imaging/PIL/WalImageFile.py -Imaging/PIL/WmfImagePlugin.py -Imaging/PIL/XbmImagePlugin.py -Imaging/PIL/XpmImagePlugin.py -Imaging/PIL/XVThumbImagePlugin.py - -Imaging/Docs/index.html -Imaging/Docs/effbot.css -Imaging/Docs/pythondoc-PIL.ArgImagePlugin.html -Imaging/Docs/pythondoc-PIL.BdfFontFile.html -Imaging/Docs/pythondoc-PIL.BmpImagePlugin.html -Imaging/Docs/pythondoc-PIL.BufrStubImagePlugin.html -Imaging/Docs/pythondoc-PIL.ContainerIO.html -Imaging/Docs/pythondoc-PIL.CurImagePlugin.html -Imaging/Docs/pythondoc-PIL.DcxImagePlugin.html -Imaging/Docs/pythondoc-PIL.EpsImagePlugin.html -Imaging/Docs/pythondoc-PIL.ExifTags.html -Imaging/Docs/pythondoc-PIL.FitsStubImagePlugin.html -Imaging/Docs/pythondoc-PIL.FliImagePlugin.html -Imaging/Docs/pythondoc-PIL.FontFile.html -Imaging/Docs/pythondoc-PIL.FpxImagePlugin.html -Imaging/Docs/pythondoc-PIL.GbrImagePlugin.html -Imaging/Docs/pythondoc-PIL.GdImageFile.html -Imaging/Docs/pythondoc-PIL.GifImagePlugin.html -Imaging/Docs/pythondoc-PIL.GimpGradientFile.html -Imaging/Docs/pythondoc-PIL.GimpPaletteFile.html -Imaging/Docs/pythondoc-PIL.GribStubImagePlugin.html -Imaging/Docs/pythondoc-PIL.Hdf5StubImagePlugin.html -Imaging/Docs/pythondoc-PIL.IcoImagePlugin.html -Imaging/Docs/pythondoc-PIL.IcnsImagePlugin.html -Imaging/Docs/pythondoc-PIL.Image.html -Imaging/Docs/pythondoc-PIL.ImageChops.html -Imaging/Docs/pythondoc-PIL.ImageColor.html -Imaging/Docs/pythondoc-PIL.ImageDraw.html -Imaging/Docs/pythondoc-PIL.ImageEnhance.html -Imaging/Docs/pythondoc-PIL.ImageFile.html -Imaging/Docs/pythondoc-PIL.ImageFileIO.html -Imaging/Docs/pythondoc-PIL.ImageFilter.html -Imaging/Docs/pythondoc-PIL.ImageFont.html -Imaging/Docs/pythondoc-PIL.ImageGL.html -Imaging/Docs/pythondoc-PIL.ImageGrab.html -Imaging/Docs/pythondoc-PIL.ImageOps.html -Imaging/Docs/pythondoc-PIL.ImagePalette.html -Imaging/Docs/pythondoc-PIL.ImagePath.html -Imaging/Docs/pythondoc-PIL.ImageSequence.html -Imaging/Docs/pythondoc-PIL.ImageStat.html -Imaging/Docs/pythondoc-PIL.ImageTk.html -Imaging/Docs/pythondoc-PIL.ImageTransform.html -Imaging/Docs/pythondoc-PIL.ImageWin.html -Imaging/Docs/pythondoc-PIL.ImImagePlugin.html -Imaging/Docs/pythondoc-PIL.ImtImagePlugin.html -Imaging/Docs/pythondoc-PIL.IptcImagePlugin.html -Imaging/Docs/pythondoc-PIL.JpegImagePlugin.html -Imaging/Docs/pythondoc-PIL.McIdasImagePlugin.html -Imaging/Docs/pythondoc-PIL.MicImagePlugin.html -Imaging/Docs/pythondoc-PIL.MpegImagePlugin.html -Imaging/Docs/pythondoc-PIL.MspImagePlugin.html -Imaging/Docs/pythondoc-PIL.OleFileIO.html -Imaging/Docs/pythondoc-PIL.PaletteFile.html -Imaging/Docs/pythondoc-PIL.PalmImagePlugin.html -Imaging/Docs/pythondoc-PIL.PcdImagePlugin.html -Imaging/Docs/pythondoc-PIL.PcfFontFile.html -Imaging/Docs/pythondoc-PIL.PcxImagePlugin.html -Imaging/Docs/pythondoc-PIL.PdfImagePlugin.html -Imaging/Docs/pythondoc-PIL.PixarImagePlugin.html -Imaging/Docs/pythondoc-PIL.PngImagePlugin.html -Imaging/Docs/pythondoc-PIL.PpmImagePlugin.html -Imaging/Docs/pythondoc-PIL.PsdImagePlugin.html -Imaging/Docs/pythondoc-PIL.PSDraw.html -Imaging/Docs/pythondoc-PIL.SgiImagePlugin.html -Imaging/Docs/pythondoc-PIL.SpiderImagePlugin.html -Imaging/Docs/pythondoc-PIL.SunImagePlugin.html -Imaging/Docs/pythondoc-PIL.TarIO.html -Imaging/Docs/pythondoc-PIL.TgaImagePlugin.html -Imaging/Docs/pythondoc-PIL.TiffImagePlugin.html -Imaging/Docs/pythondoc-PIL.TiffTags.html -Imaging/Docs/pythondoc-PIL.WalImageFile.html -Imaging/Docs/pythondoc-PIL.WmfImagePlugin.html -Imaging/Docs/pythondoc-PIL.XbmImagePlugin.html -Imaging/Docs/pythondoc-PIL.XpmImagePlugin.html -Imaging/Docs/pythondoc-PIL.XVThumbImagePlugin.html - -Imaging/Scripts/pilconvert.py -Imaging/Scripts/pildriver.py -Imaging/Scripts/pilfile.py -Imaging/Scripts/pilfont.py -Imaging/Scripts/pilprint.py - -Imaging/Images/lena.gif -Imaging/Images/lena.png -Imaging/Images/lena.ppm -Imaging/Images/lena.jpg - -Imaging/Images/courB08.bdf -Imaging/Images/courB08.pbm -Imaging/Images/courB08.pil - -Imaging/Sane/README -Imaging/Sane/CHANGES -Imaging/Sane/setup.py -Imaging/Sane/sanedoc.txt -Imaging/Sane/_sane.c -Imaging/Sane/sane.py -Imaging/Sane/demo_numarray.py -Imaging/Sane/demo_pil.py - -Imaging/Scripts/README -Imaging/Scripts/enhancer.py -Imaging/Scripts/explode.py -Imaging/Scripts/gifmaker.py -Imaging/Scripts/painter.py -Imaging/Scripts/player.py -Imaging/Scripts/viewer.py -Imaging/Scripts/thresholder.py - -Imaging/Tk/tkImaging.c -Imaging/Tk/install.txt -Imaging/Tk/booster.txt -Imaging/Tk/pilbitmap.txt - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css b/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css deleted file mode 100755 index b03ae458cdc..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/effbot.css +++ /dev/null @@ -1,118 +0,0 @@ -/* effbot.css */ - -BODY { - font: 100% Georgia, Times, serif; - color: black; - margin: 0px 20px 0px 20px; -} - -#effbot-body { - background: white; - padding: 10px 40px 10px 40px; - max-width: 50em; -} - -#effbot-menu { - display: none; -} - -.adsense { - background: #f8fff8; - border: 1px solid #084; - padding: 10px 4px 4px 4px; -} - -.sidebar { - border: 1px solid #000; - float: right; clear: right; - width: 200px; - background: white; - padding: 10px; - margin: 0px -25px 10px 0px; -} - -/* visual style */ - -P { - line-height: 1.3em; -} - -CODE, PRE { - font: 100% "Courier New", Courier, Monaco, monospace; - color: #042; margin-left: 20px; -} - -H1, H2, H3 { - font-family: Georgia, Times, serif; - color: #084; margin-top: 30px; -} - -H1, H2, { border-top: 1px solid #084; } - -H4, H5, H6 { - font-family: Georgia, Times, serif; - color: #084; margin-top: 15px; -} - -A:link, A:hover { color: #084; } -A:visited { color: #404040; } - -UL LI { list-style-type: square; } - -.title { margin-bottom: 2px; color: #084; } -.info { font-size: 80%; color: #084; margin-top: 0px; } - -.bluebox { color: #084; margin-top: 10px; } - -.highlight { background: #cfc; } -.mark { color: #084; } -.small { font-size: 80%; } -.display { background: #eee; padding: 20px; } - -.note { - background: #efe; - border-top: 1px solid #084; - border-bottom: 1px solid #084; - padding: 2px 20px; -} - -.example { - border-top: medium solid #084; - border-bottom: medium solid #084; - padding: 5px; -} - -.figure { - border-top: medium solid #084; - border-bottom: medium solid #084; - padding: 5px; -} - -.fixme { - background: #eee; - border: 1px solid #084; - padding: 2x 20px; -} - -.simpletable { - border: 1px solid #084; - border-collapse: collapse; -} - -.simpletable TH { - text-align: left; - background: #cfc; - border: 1px solid #084; - margin: 0px; - padding: 1px 5px; -} - -.simpletable TD { - border: 1px solid #084; - margin: 0px; - padding: 5px; -} - -/* xmldiff markup */ -.new { text-decoration: underline; color: red; background: #fff0f0; } -.old { text-decoration: line-through; color: blue; background: #f0f0ff; } diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html b/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html deleted file mode 100755 index fbc76a99dfb..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Docs/index.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - -The Python Imaging Library - - - -

The Python Imaging Library

- -

Online Resources

- -
-
Python Imaging Library (official product page at pythonware.com)
-
Python Imaging Library (development page at effbot.org)
-
- -

Package Contents

- -

The following pages are generated from pythondoc markup in the source files.

- -
-
The PIL.Image Module
-
The PIL.ImageChops Module
-
The PIL.ImageColor Module
-
The PIL.ImageDraw Module
-
The PIL.ImageEnhance Module
-
The PIL.ImageFile Module
-
The PIL.ImageFileIO Module
-
The PIL.ImageFilter Module
-
The PIL.ImageFont Module
-
The PIL.ImageGL Module
-
The PIL.ImageGrab Module
-
The PIL.ImageMath Module
-
The PIL.ImageMode Module
-
The PIL.ImageOps Module
-
The PIL.ImagePalette Module
-
The PIL.ImagePath Module
-
The PIL.ImageQt Module
-
The PIL.ImageSequence Module
-
The PIL.ImageStat Module
-
The PIL.ImageTk Module
-
The PIL.ImageTransform Module
-
The PIL.ImageWin Module
-
 
-
The PIL.ArgImagePlugin Module
-
The PIL.BdfFontFile Module
-
The PIL.BmpImagePlugin Module
-
The PIL.BufrStubImagePlugin Module
-
The PIL.ContainerIO Module
-
The PIL.CurImagePlugin Module
-
The PIL.DcxImagePlugin Module
-
The PIL.EpsImagePlugin Module
-
The PIL.ExifTags Module
-
The PIL.FitsStubImagePlugin Module
-
The PIL.FliImagePlugin Module
-
The PIL.FontFile Module
-
The PIL.FpxImagePlugin Module
-
The PIL.GbrImagePlugin Module
-
The PIL.GdImageFile Module
-
The PIL.GifImagePlugin Module
-
The PIL.GimpGradientFile Module
-
The PIL.GimpPaletteFile Module
-
The PIL.GribStubImagePlugin Module
-
The PIL.Hdf5StubImagePlugin Module
-
The PIL.IcnsImagePlugin Module
-
The PIL.IcoImagePlugin Module
-
The PIL.ImImagePlugin Module
-
The PIL.ImtImagePlugin Module
-
The PIL.IptcImagePlugin Module
-
The PIL.JpegImagePlugin Module
-
The PIL.McIdasImagePlugin Module
-
The PIL.MicImagePlugin Module
-
The PIL.MpegImagePlugin Module
-
The PIL.MspImagePlugin Module
-
The PIL.OleFileIO Module
-
The PIL.PSDraw Module
-
The PIL.PaletteFile Module
-
The PIL.PalmImagePlugin Module
-
The PIL.PcdImagePlugin Module
-
The PIL.PcfFontFile Module
-
The PIL.PcxImagePlugin Module
-
The PIL.PdfImagePlugin Module
-
The PIL.PixarImagePlugin Module
-
The PIL.PngImagePlugin Module
-
The PIL.PpmImagePlugin Module
-
The PIL.PsdImagePlugin Module
-
The PIL.SgiImagePlugin Module
-
The PIL.SunImagePlugin Module
-
The PIL.TarIO Module
-
The PIL.TgaImagePlugin Module
-
The PIL.TiffImagePlugin Module
-
The PIL.TiffTags Module
-
The PIL.WalImageFile Module
-
The PIL.WbmpImagePlugin Module
-
The PIL.WmfImagePlugin Module
-
The PIL.XVThumbImagePlugin Module
-
The PIL.XbmImagePlugin Module
-
The PIL.XpmImagePlugin Module
-
- - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf deleted file mode 100755 index 5a48895d1de..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.bdf +++ /dev/null @@ -1,2676 +0,0 @@ -STARTFONT 2.1 -COMMENT $XConsortium: courB08.bdf,v 1.5 94/04/10 21:46:11 gildea Exp $ -COMMENT -COMMENT Copyright 1984, 1987 Adobe Systems, Inc. -COMMENT Portions Copyright 1988 Digital Equipment Corporation -COMMENT -COMMENT Adobe is a registered trademark of Adobe Systems, Inc. Permission -COMMENT to use these trademarks is hereby granted only in association with the -COMMENT images described in this file. -COMMENT -COMMENT Permission to use, copy, modify, and distribute this software and -COMMENT its documentation for any purpose and without fee is hereby granted, -COMMENT provided that the above copyright notices appear in all copies and -COMMENT that both those copyright notices and this permission notice appear -COMMENT in supporting documentation, and that the names of Adobe Systems and -COMMENT Digital Equipment Corporation not be used in advertising or -COMMENT publicity pertaining to distribution of the software without -COMMENT specific, written prior permission. Adobe Systems and Digital -COMMENT Equipment Corporation make no representations about the suitability -COMMENT of this software for any purpose. It is provided "as is" without -COMMENT express or implied warranty. -COMMENT -COMMENT ADOBE SYSTEMS AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL -COMMENT WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED -COMMENT WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ADOBE -COMMENT SYSTEMS AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, -COMMENT INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -COMMENT RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -COMMENT CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -COMMENT CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -COMMENT -COMMENT -FONT -Adobe-Courier-Bold-R-Normal--11-80-100-100-M-60-ISO8859-1 -SIZE 8 100 100 -FONTBOUNDINGBOX 8 11 -1 -2 -STARTPROPERTIES 22 -COMMENT Begin LogicalFontDescription -FONTNAME_REGISTRY "" -FAMILY_NAME "Courier" -FOUNDRY "Adobe" -WEIGHT_NAME "Bold" -SLANT "R" -SETWIDTH_NAME "Normal" -ADD_STYLE_NAME "" -PIXEL_SIZE 11 -POINT_SIZE 80 -RESOLUTION_X 100 -RESOLUTION_Y 100 -SPACING "M" -AVERAGE_WIDTH 60 -CHARSET_REGISTRY "ISO8859" -CHARSET_ENCODING "1" -COMMENT END LogicalFontDescription -CHARSET_COLLECTIONS "ASCII ISO8859-1 ADOBE-STANDARD" -FACE_NAME "Courier Bold" -COPYRIGHT "Copyright (c) 1987 Adobe Systems, Inc., Portions Copyright 1988 Digital Equipment Corp." -COMMENT ***** end of inserted font properties -FONT_ASCENT 8 -FONT_DESCENT 2 -CAP_HEIGHT 6 -X_HEIGHT 5 -ENDPROPERTIES -CHARS 194 -STARTCHAR space -ENCODING 32 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 1 1 0 0 -BITMAP -00 -ENDCHAR -STARTCHAR exclam -ENCODING 33 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 2 6 1 0 -BITMAP -C0 -C0 -C0 -C0 -00 -C0 -ENDCHAR -STARTCHAR quotedbl -ENCODING 34 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 3 1 3 -BITMAP -A0 -A0 -A0 -ENDCHAR -STARTCHAR numbersign -ENCODING 35 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 -1 -BITMAP -50 -50 -F8 -50 -50 -F8 -50 -50 -ENDCHAR -STARTCHAR dollar -ENCODING 36 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 9 0 -1 -BITMAP -20 -78 -C8 -F0 -78 -18 -D8 -F0 -20 -ENDCHAR -STARTCHAR percent -ENCODING 37 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -E0 -A8 -F0 -20 -78 -A8 -38 -ENDCHAR -STARTCHAR ampersand -ENCODING 38 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -38 -60 -30 -7C -D8 -7C -ENDCHAR -STARTCHAR quoteright -ENCODING 39 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 3 1 4 -BITMAP -60 -40 -80 -ENDCHAR -STARTCHAR parenleft -ENCODING 40 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 8 1 -1 -BITMAP -20 -40 -C0 -C0 -C0 -C0 -40 -20 -ENDCHAR -STARTCHAR parenright -ENCODING 41 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 8 1 -1 -BITMAP -80 -40 -60 -60 -60 -60 -40 -80 -ENDCHAR -STARTCHAR asterisk -ENCODING 42 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 4 0 3 -BITMAP -20 -F0 -60 -90 -ENDCHAR -STARTCHAR plus -ENCODING 43 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 1 -BITMAP -20 -20 -F8 -20 -20 -ENDCHAR -STARTCHAR comma -ENCODING 44 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 3 1 -2 -BITMAP -60 -40 -80 -ENDCHAR -STARTCHAR minus -ENCODING 45 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 1 0 3 -BITMAP -F8 -ENDCHAR -STARTCHAR period -ENCODING 46 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 2 1 1 0 -BITMAP -C0 -ENDCHAR -STARTCHAR slash -ENCODING 47 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 8 1 -1 -BITMAP -10 -10 -20 -20 -40 -40 -80 -80 -ENDCHAR -STARTCHAR zero -ENCODING 48 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -70 -D8 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR one -ENCODING 49 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -30 -F0 -30 -30 -30 -30 -FC -ENDCHAR -STARTCHAR two -ENCODING 50 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -70 -D8 -18 -30 -60 -D8 -F8 -ENDCHAR -STARTCHAR three -ENCODING 51 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -70 -D8 -18 -70 -18 -D8 -70 -ENDCHAR -STARTCHAR four -ENCODING 52 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -18 -38 -58 -D8 -FC -18 -18 -ENDCHAR -STARTCHAR five -ENCODING 53 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -F8 -C0 -F0 -D8 -18 -98 -F0 -ENDCHAR -STARTCHAR six -ENCODING 54 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -70 -D8 -C0 -F0 -D8 -D8 -70 -ENDCHAR -STARTCHAR seven -ENCODING 55 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -F8 -D8 -18 -30 -30 -60 -60 -ENDCHAR -STARTCHAR eight -ENCODING 56 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -70 -D8 -D8 -70 -D8 -D8 -70 -ENDCHAR -STARTCHAR nine -ENCODING 57 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -70 -D8 -D8 -78 -18 -D8 -70 -ENDCHAR -STARTCHAR colon -ENCODING 58 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 2 4 1 0 -BITMAP -C0 -00 -00 -C0 -ENDCHAR -STARTCHAR semicolon -ENCODING 59 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 6 0 -2 -BITMAP -60 -00 -00 -60 -40 -80 -ENDCHAR -STARTCHAR less -ENCODING 60 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 5 0 1 -BITMAP -30 -60 -C0 -60 -30 -ENDCHAR -STARTCHAR equal -ENCODING 61 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 3 0 2 -BITMAP -F0 -00 -F0 -ENDCHAR -STARTCHAR greater -ENCODING 62 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 5 1 1 -BITMAP -C0 -60 -30 -60 -C0 -ENDCHAR -STARTCHAR question -ENCODING 63 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -70 -98 -30 -60 -00 -60 -ENDCHAR -STARTCHAR at -ENCODING 64 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 -1 -BITMAP -70 -C8 -98 -A8 -A8 -9C -C0 -70 -ENDCHAR -STARTCHAR A -ENCODING 65 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR B -ENCODING 66 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -F8 -6C -78 -6C -6C -F8 -ENDCHAR -STARTCHAR C -ENCODING 67 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -78 -D8 -C0 -C0 -D8 -70 -ENDCHAR -STARTCHAR D -ENCODING 68 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -F8 -6C -6C -6C -6C -F8 -ENDCHAR -STARTCHAR E -ENCODING 69 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -FC -60 -78 -60 -6C -FC -ENDCHAR -STARTCHAR F -ENCODING 70 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -FC -60 -78 -60 -60 -F0 -ENDCHAR -STARTCHAR G -ENCODING 71 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -70 -D8 -C0 -F8 -D8 -78 -ENDCHAR -STARTCHAR H -ENCODING 72 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -EE -6C -7C -6C -6C -EE -ENDCHAR -STARTCHAR I -ENCODING 73 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 6 0 0 -BITMAP -F0 -60 -60 -60 -60 -F0 -ENDCHAR -STARTCHAR J -ENCODING 74 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -3C -18 -18 -D8 -D8 -70 -ENDCHAR -STARTCHAR K -ENCODING 75 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -EC -68 -70 -78 -6C -F6 -ENDCHAR -STARTCHAR L -ENCODING 76 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -F0 -60 -60 -60 -6C -FC -ENDCHAR -STARTCHAR M -ENCODING 77 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -C4 -6C -6C -7C -54 -D4 -ENDCHAR -STARTCHAR N -ENCODING 78 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -EE -74 -74 -6C -6C -E4 -ENDCHAR -STARTCHAR O -ENCODING 79 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -70 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR P -ENCODING 80 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -F8 -6C -6C -78 -60 -F0 -ENDCHAR -STARTCHAR Q -ENCODING 81 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 -1 -BITMAP -70 -D8 -D8 -D8 -D8 -70 -18 -ENDCHAR -STARTCHAR R -ENCODING 82 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -F8 -6C -6C -78 -6C -F6 -ENDCHAR -STARTCHAR S -ENCODING 83 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -78 -C8 -F0 -38 -98 -F0 -ENDCHAR -STARTCHAR T -ENCODING 84 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -FC -B4 -30 -30 -30 -78 -ENDCHAR -STARTCHAR U -ENCODING 85 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -EE -6C -6C -6C -6C -38 -ENDCHAR -STARTCHAR V -ENCODING 86 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -EE -6C -28 -38 -38 -10 -ENDCHAR -STARTCHAR W -ENCODING 87 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -D6 -54 -54 -7C -38 -28 -ENDCHAR -STARTCHAR X -ENCODING 88 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 0 0 -BITMAP -CC -78 -30 -30 -78 -CC -ENDCHAR -STARTCHAR Y -ENCODING 89 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -E6 -66 -3C -18 -18 -3C -ENDCHAR -STARTCHAR Z -ENCODING 90 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -F8 -D8 -30 -60 -D8 -F8 -ENDCHAR -STARTCHAR bracketleft -ENCODING 91 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 8 1 -1 -BITMAP -E0 -C0 -C0 -C0 -C0 -C0 -C0 -E0 -ENDCHAR -STARTCHAR backslash -ENCODING 92 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 8 0 -1 -BITMAP -80 -80 -40 -40 -20 -20 -10 -10 -ENDCHAR -STARTCHAR bracketright -ENCODING 93 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 8 1 -1 -BITMAP -E0 -60 -60 -60 -60 -60 -60 -E0 -ENDCHAR -STARTCHAR asciicircum -ENCODING 94 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 3 0 4 -BITMAP -20 -70 -D8 -ENDCHAR -STARTCHAR underscore -ENCODING 95 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 1 0 -2 -BITMAP -FC -ENDCHAR -STARTCHAR quoteleft -ENCODING 96 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 3 1 4 -BITMAP -C0 -40 -20 -ENDCHAR -STARTCHAR a -ENCODING 97 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 0 0 -BITMAP -70 -D8 -78 -D8 -FC -ENDCHAR -STARTCHAR b -ENCODING 98 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 -1 0 -BITMAP -E0 -60 -78 -6C -6C -6C -F8 -ENDCHAR -STARTCHAR c -ENCODING 99 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 0 -BITMAP -70 -D8 -C0 -D8 -70 -ENDCHAR -STARTCHAR d -ENCODING 100 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -38 -18 -78 -D8 -D8 -D8 -7C -ENDCHAR -STARTCHAR e -ENCODING 101 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 0 -BITMAP -70 -D8 -F8 -C0 -78 -ENDCHAR -STARTCHAR f -ENCODING 102 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -38 -60 -F8 -60 -60 -60 -F8 -ENDCHAR -STARTCHAR g -ENCODING 103 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 -2 -BITMAP -6C -D8 -D8 -D8 -78 -18 -F0 -ENDCHAR -STARTCHAR h -ENCODING 104 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 -1 0 -BITMAP -E0 -60 -78 -6C -6C -6C -6C -ENDCHAR -STARTCHAR i -ENCODING 105 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -30 -00 -F0 -30 -30 -30 -FC -ENDCHAR -STARTCHAR j -ENCODING 106 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 9 0 -2 -BITMAP -30 -00 -F0 -30 -30 -30 -30 -30 -E0 -ENDCHAR -STARTCHAR k -ENCODING 107 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 0 -BITMAP -E0 -60 -6C -78 -70 -78 -6E -ENDCHAR -STARTCHAR l -ENCODING 108 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -F0 -30 -30 -30 -30 -30 -FC -ENDCHAR -STARTCHAR m -ENCODING 109 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 -1 0 -BITMAP -F8 -7C -54 -54 -54 -ENDCHAR -STARTCHAR n -ENCODING 110 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 -1 0 -BITMAP -D8 -6C -6C -6C -6C -ENDCHAR -STARTCHAR o -ENCODING 111 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 0 -BITMAP -70 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR p -ENCODING 112 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 -1 -2 -BITMAP -F8 -6C -6C -6C -78 -60 -F0 -ENDCHAR -STARTCHAR q -ENCODING 113 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 -2 -BITMAP -6C -D8 -D8 -D8 -78 -18 -3C -ENDCHAR -STARTCHAR r -ENCODING 114 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 0 0 -BITMAP -DC -74 -60 -60 -F0 -ENDCHAR -STARTCHAR s -ENCODING 115 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 0 0 -BITMAP -78 -E0 -78 -1C -F8 -ENDCHAR -STARTCHAR t -ENCODING 116 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -60 -60 -F8 -60 -60 -6C -38 -ENDCHAR -STARTCHAR u -ENCODING 117 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 5 -1 0 -BITMAP -EC -6C -6C -6C -3E -ENDCHAR -STARTCHAR v -ENCODING 118 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 -1 0 -BITMAP -EC -6C -38 -38 -10 -ENDCHAR -STARTCHAR w -ENCODING 119 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 5 -1 0 -BITMAP -D6 -54 -7C -3C -28 -ENDCHAR -STARTCHAR x -ENCODING 120 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 0 0 -BITMAP -EC -78 -30 -78 -DC -ENDCHAR -STARTCHAR y -ENCODING 121 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 -2 -BITMAP -EE -6C -6C -28 -38 -30 -E0 -ENDCHAR -STARTCHAR z -ENCODING 122 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 0 -BITMAP -F8 -B0 -60 -D8 -F8 -ENDCHAR -STARTCHAR braceleft -ENCODING 123 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 8 1 -1 -BITMAP -30 -60 -60 -C0 -60 -60 -60 -30 -ENDCHAR -STARTCHAR bar -ENCODING 124 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 1 7 2 -1 -BITMAP -80 -80 -80 -80 -80 -80 -80 -ENDCHAR -STARTCHAR braceright -ENCODING 125 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 8 0 -1 -BITMAP -C0 -60 -60 -30 -60 -60 -60 -C0 -ENDCHAR -STARTCHAR asciitilde -ENCODING 126 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 2 0 3 -BITMAP -68 -B0 -ENDCHAR -STARTCHAR exclamdown -ENCODING 161 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 2 7 1 -2 -BITMAP -C0 -00 -C0 -C0 -C0 -C0 -C0 -ENDCHAR -STARTCHAR cent -ENCODING 162 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 -1 -BITMAP -20 -20 -78 -C8 -C0 -78 -20 -20 -ENDCHAR -STARTCHAR sterling -ENCODING 163 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -38 -68 -20 -F8 -20 -64 -F8 -ENDCHAR -STARTCHAR currency -ENCODING 164 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 1 -BITMAP -88 -70 -50 -70 -88 -ENDCHAR -STARTCHAR yen -ENCODING 165 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -CC -48 -FC -30 -FC -30 -78 -ENDCHAR -STARTCHAR brokenbar -ENCODING 166 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 1 9 2 -2 -BITMAP -80 -80 -80 -80 -00 -80 -80 -80 -80 -ENDCHAR -STARTCHAR section -ENCODING 167 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 -1 -BITMAP -78 -48 -60 -90 -48 -30 -90 -F0 -ENDCHAR -STARTCHAR dieresis -ENCODING 168 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 1 1 5 -BITMAP -A0 -ENDCHAR -STARTCHAR copyright -ENCODING 169 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -30 -48 -B4 -A4 -B4 -48 -30 -ENDCHAR -STARTCHAR ordfeminine -ENCODING 170 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 5 1 2 -BITMAP -E0 -10 -D0 -00 -F0 -ENDCHAR -STARTCHAR guillemotleft -ENCODING 171 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 5 -1 0 -BITMAP -36 -6C -D8 -6C -36 -ENDCHAR -STARTCHAR logicalnot -ENCODING 172 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 3 0 2 -BITMAP -F8 -08 -08 -ENDCHAR -STARTCHAR hyphen -ENCODING 173 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 1 0 3 -BITMAP -F8 -ENDCHAR -STARTCHAR registered -ENCODING 174 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 0 0 -BITMAP -38 -44 -BA -B2 -AA -44 -38 -ENDCHAR -STARTCHAR macron -ENCODING 175 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 1 0 5 -BITMAP -F0 -ENDCHAR -STARTCHAR degree -ENCODING 176 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 3 0 4 -BITMAP -60 -90 -60 -ENDCHAR -STARTCHAR plusminus -ENCODING 177 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 6 0 0 -BITMAP -20 -20 -F8 -20 -00 -F8 -ENDCHAR -STARTCHAR twosuperior -ENCODING 178 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 4 1 3 -BITMAP -60 -A0 -40 -E0 -ENDCHAR -STARTCHAR threesuperior -ENCODING 179 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 4 1 3 -BITMAP -E0 -40 -20 -C0 -ENDCHAR -STARTCHAR acute -ENCODING 180 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 2 2 2 5 -BITMAP -40 -80 -ENDCHAR -STARTCHAR mu -ENCODING 181 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 -2 -BITMAP -EC -6C -6C -6C -7E -40 -40 -ENDCHAR -STARTCHAR paragraph -ENCODING 182 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 -1 -BITMAP -7C -A8 -A8 -68 -28 -28 -28 -6C -ENDCHAR -STARTCHAR periodcentered -ENCODING 183 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 2 1 1 3 -BITMAP -C0 -ENDCHAR -STARTCHAR cedilla -ENCODING 184 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 3 1 -2 -BITMAP -40 -20 -C0 -ENDCHAR -STARTCHAR onesuperior -ENCODING 185 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 3 4 1 3 -BITMAP -C0 -40 -40 -E0 -ENDCHAR -STARTCHAR ordmasculine -ENCODING 186 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 5 1 2 -BITMAP -60 -90 -60 -00 -F0 -ENDCHAR -STARTCHAR guillemotright -ENCODING 187 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 5 -1 0 -BITMAP -D8 -6C -36 -6C -D8 -ENDCHAR -STARTCHAR onequarter -ENCODING 188 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 0 -BITMAP -C0 -44 -48 -F4 -2C -5E -04 -ENDCHAR -STARTCHAR onehalf -ENCODING 189 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 0 -BITMAP -C0 -44 -48 -F6 -2A -44 -0E -ENDCHAR -STARTCHAR threequarters -ENCODING 190 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 0 -BITMAP -E0 -44 -28 -D4 -2C -5E -04 -ENDCHAR -STARTCHAR questiondown -ENCODING 191 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 -2 -BITMAP -30 -00 -30 -30 -60 -C8 -70 -ENDCHAR -STARTCHAR Agrave -ENCODING 192 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -20 -10 -00 -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR Aacute -ENCODING 193 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -10 -20 -00 -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR Acircumflex -ENCODING 194 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -10 -28 -00 -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR Atilde -ENCODING 195 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -34 -48 -00 -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR Adieresis -ENCODING 196 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 8 -1 0 -BITMAP -28 -00 -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR Aring -ENCODING 197 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -30 -48 -30 -78 -38 -28 -7C -6C -EE -ENDCHAR -STARTCHAR AE -ENCODING 198 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -7E -3A -6C -78 -DA -DE -ENDCHAR -STARTCHAR Ccedilla -ENCODING 199 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 -2 -BITMAP -78 -D8 -C0 -C0 -D8 -70 -10 -60 -ENDCHAR -STARTCHAR Egrave -ENCODING 200 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 9 -1 0 -BITMAP -20 -10 -00 -FC -64 -78 -60 -6C -FC -ENDCHAR -STARTCHAR Eacute -ENCODING 201 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 9 -1 0 -BITMAP -10 -20 -00 -FC -64 -78 -60 -6C -FC -ENDCHAR -STARTCHAR Ecircumflex -ENCODING 202 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 9 -1 0 -BITMAP -20 -50 -00 -FC -64 -78 -60 -6C -FC -ENDCHAR -STARTCHAR Edieresis -ENCODING 203 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 -1 0 -BITMAP -50 -00 -FC -64 -78 -60 -6C -FC -ENDCHAR -STARTCHAR Igrave -ENCODING 204 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 9 0 0 -BITMAP -40 -20 -00 -F0 -60 -60 -60 -60 -F0 -ENDCHAR -STARTCHAR Iacute -ENCODING 205 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 9 0 0 -BITMAP -20 -40 -00 -F0 -60 -60 -60 -60 -F0 -ENDCHAR -STARTCHAR Icircumflex -ENCODING 206 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 9 0 0 -BITMAP -40 -A0 -00 -F0 -60 -60 -60 -60 -F0 -ENDCHAR -STARTCHAR Idieresis -ENCODING 207 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 4 8 0 0 -BITMAP -A0 -00 -F0 -60 -60 -60 -60 -F0 -ENDCHAR -STARTCHAR Eth -ENCODING 208 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -F8 -6C -F4 -64 -6C -F8 -ENDCHAR -STARTCHAR Ntilde -ENCODING 209 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -34 -48 -00 -EE -64 -74 -7C -6C -EC -ENDCHAR -STARTCHAR Ograve -ENCODING 210 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 9 0 0 -BITMAP -40 -20 -00 -70 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR Oacute -ENCODING 211 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 9 0 0 -BITMAP -20 -40 -00 -70 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR Ocircumflex -ENCODING 212 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 9 0 0 -BITMAP -20 -50 -00 -70 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR Otilde -ENCODING 213 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 9 0 0 -BITMAP -68 -90 -00 -70 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR Odieresis -ENCODING 214 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -50 -00 -70 -D8 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR multiply -ENCODING 215 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 1 -BITMAP -88 -50 -20 -50 -88 -ENDCHAR -STARTCHAR Oslash -ENCODING 216 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -3A -6C -7C -6C -6C -B8 -ENDCHAR -STARTCHAR Ugrave -ENCODING 217 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -20 -10 -00 -EE -6C -6C -6C -6C -38 -ENDCHAR -STARTCHAR Uacute -ENCODING 218 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -08 -10 -00 -EE -6C -6C -6C -6C -38 -ENDCHAR -STARTCHAR Ucircumflex -ENCODING 219 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -10 -28 -00 -EE -6C -6C -6C -6C -38 -ENDCHAR -STARTCHAR Udieresis -ENCODING 220 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 8 -1 0 -BITMAP -28 -00 -EE -6C -6C -6C -6C -38 -ENDCHAR -STARTCHAR Yacute -ENCODING 221 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 0 -BITMAP -04 -08 -00 -E6 -66 -3C -18 -18 -3C -ENDCHAR -STARTCHAR Thorn -ENCODING 222 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 6 -1 0 -BITMAP -E0 -78 -6C -6C -78 -E0 -ENDCHAR -STARTCHAR germandbls -ENCODING 223 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 6 -1 0 -BITMAP -38 -68 -7C -66 -66 -EC -ENDCHAR -STARTCHAR agrave -ENCODING 224 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -20 -10 -00 -70 -98 -78 -D8 -FC -ENDCHAR -STARTCHAR aacute -ENCODING 225 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -10 -20 -00 -70 -98 -78 -D8 -FC -ENDCHAR -STARTCHAR acircumflex -ENCODING 226 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -20 -50 -00 -70 -98 -78 -D8 -FC -ENDCHAR -STARTCHAR atilde -ENCODING 227 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -68 -90 -00 -70 -98 -78 -D8 -FC -ENDCHAR -STARTCHAR adieresis -ENCODING 228 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -50 -00 -70 -98 -78 -D8 -FC -ENDCHAR -STARTCHAR aring -ENCODING 229 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 9 0 0 -BITMAP -30 -48 -30 -00 -70 -98 -78 -D8 -FC -ENDCHAR -STARTCHAR ae -ENCODING 230 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 -1 0 -BITMAP -6C -B4 -7C -B0 -DC -ENDCHAR -STARTCHAR ccedilla -ENCODING 231 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 -2 -BITMAP -70 -D8 -C0 -D8 -70 -10 -60 -ENDCHAR -STARTCHAR egrave -ENCODING 232 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -40 -20 -00 -70 -D8 -F8 -C0 -78 -ENDCHAR -STARTCHAR eacute -ENCODING 233 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -20 -40 -00 -70 -D8 -F8 -C0 -78 -ENDCHAR -STARTCHAR ecircumflex -ENCODING 234 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -20 -50 -00 -70 -D8 -F8 -C0 -78 -ENDCHAR -STARTCHAR edieresis -ENCODING 235 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -50 -00 -70 -D8 -F8 -C0 -78 -ENDCHAR -STARTCHAR igrave -ENCODING 236 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -20 -10 -00 -70 -30 -30 -30 -FC -ENDCHAR -STARTCHAR iacute -ENCODING 237 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -10 -20 -00 -70 -30 -30 -30 -FC -ENDCHAR -STARTCHAR icircumflex -ENCODING 238 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 8 0 0 -BITMAP -20 -50 -00 -70 -30 -30 -30 -FC -ENDCHAR -STARTCHAR idieresis -ENCODING 239 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -50 -00 -70 -30 -30 -30 -FC -ENDCHAR -STARTCHAR eth -ENCODING 240 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -D0 -60 -B0 -78 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR ntilde -ENCODING 241 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 8 -1 0 -BITMAP -34 -48 -00 -D8 -6C -6C -6C -6E -ENDCHAR -STARTCHAR ograve -ENCODING 242 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -40 -20 -00 -70 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR oacute -ENCODING 243 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -20 -40 -00 -70 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR ocircumflex -ENCODING 244 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -20 -50 -00 -70 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR otilde -ENCODING 245 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 8 0 0 -BITMAP -68 -90 -00 -70 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR odieresis -ENCODING 246 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 0 -BITMAP -50 -00 -70 -D8 -D8 -D8 -70 -ENDCHAR -STARTCHAR divide -ENCODING 247 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 5 0 1 -BITMAP -20 -00 -F8 -00 -20 -ENDCHAR -STARTCHAR oslash -ENCODING 248 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 5 7 0 -1 -BITMAP -08 -70 -D8 -F8 -D8 -70 -80 -ENDCHAR -STARTCHAR ugrave -ENCODING 249 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 8 -1 0 -BITMAP -20 -10 -00 -EC -6C -6C -6C -3E -ENDCHAR -STARTCHAR uacute -ENCODING 250 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 8 -1 0 -BITMAP -10 -20 -00 -EC -6C -6C -6C -3E -ENDCHAR -STARTCHAR ucircumflex -ENCODING 251 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 8 -1 0 -BITMAP -10 -28 -00 -EC -6C -6C -6C -3E -ENDCHAR -STARTCHAR udieresis -ENCODING 252 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 0 -BITMAP -28 -00 -EC -6C -6C -6C -3E -ENDCHAR -STARTCHAR yacute -ENCODING 253 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 10 -1 -2 -BITMAP -08 -10 -00 -EE -6C -6C -28 -38 -30 -F0 -ENDCHAR -STARTCHAR thorn -ENCODING 254 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 9 -1 -2 -BITMAP -E0 -60 -78 -6C -6C -6C -78 -60 -F0 -ENDCHAR -STARTCHAR ydieresis -ENCODING 255 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 9 -1 -2 -BITMAP -28 -00 -EE -6C -6C -28 -38 -30 -F0 -ENDCHAR -STARTCHAR trademark -ENCODING 8482 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 4 -1 3 -BITMAP -F6 -5E -5A -5A -ENDCHAR -STARTCHAR perthousand -ENCODING 8240 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 7 0 0 -BITMAP -60 -A8 -D0 -60 -6C -B4 -D8 -ENDCHAR -STARTCHAR oe -ENCODING 339 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 6 5 0 0 -BITMAP -6C -B4 -BC -B0 -6C -ENDCHAR -STARTCHAR fl -ENCODING 64258 -SWIDTH 600 0 -DWIDTH 6 0 -BBX 7 7 -1 0 -BITMAP -3C -6C -FC -6C -6C -6C -FE -ENDCHAR -ENDFONT diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pbm b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pbm deleted file mode 100755 index aedce1a3117bc80edcc8edb5ec92ece84639a346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1273 zcmYk5e@s(X6vxlwcCS?m)FA;WunHK-h+0JLlwU<)$^=ALGhr@!fS|@8I>IQMSQ>flgW=L;}wQD6p*-~ZbHkd!pQhF+*+XR-D8N^`QzrClkYj7b8_!J z8XvdGVWIm%0C0%j9Jw6;d2#+?f;+%}b?;sP9vdAQu27zbR4Buc6*+LP#mBZXpi4YD zbD`Ffc`}sN+eU44M!@LUg$ZmLs|lqiezIj2c^K<;MXlX+*`1@4o;M%rX^psKXiyb+ z91n&ZnR#qYd#vUokx0@L;nXiL@GJOy;*#jNBCbRr;m{cWhqD9wj*xV0=g@LZvcj0~ z?n3{DzFo%y?{t0taJZ;FVOZ9zny$3yoq1{Gp$9i`j@7(ucXjOjaf52{pJz_xHHY4H z>3VHxlrDj|7;&1k_cV(Fw(69n1BH*;uKrQJsI59yDUkjTXIJ%hG5=SPgbYcVgssp%O&Q#7fQmZ6%rFCxBXP0-_)gOY z?*ohjlq#Ydrq_+!$?svOzI@i;e4W8y68V5;fBM~4153kUVbr}93px$Ly1Hw2Y_p21 zp2zW$nL83N0N9zmlB814zTM}DoR5}};4YM8+Yh?zi+v&9{_QjFfz^PB1P~c6qY`WJ z2f?tJz7f+W5WAjg0D;`rQXrY|YuYhf`kA3c)0pOZG3h+v#?5MZAmCuLxMb>B9i^bC zr!zQide>hbB)N|C1*69XmbI`aaJzMnDNL%Zmr1=SirOPhKW||_&L7YG!LA#9?t`UG7G0hW`@PWwDq!A?Ng|?SXLlA+n7f<2Zu6g{)jX68Z{sz->>M< zY=qPaU7aJTeBT3uwxGrJXGf=fBf_n>siesL1@O7_U@RWwcW_2@RnVjM zy}sH@;cLet{ne)hDa$uq_n2;@V0B=f`HRmDdX}#{d=+?lF**H2XF0y(fmH#g*nk|w5 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pil b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/courB08.pil deleted file mode 100755 index 28982c0fa7339e8c3bbb2bbdd5b08663bfcbcc49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5143 zcmeH~-;0(-6vxlZuDU&fmSz%)uox(YX@)Gih%1y(N-8XBD5l^KSTKziEfiVASWpoa z6hVbTL=?q~wHv)qFT_AgP(!=0AcU}s^}@(q*Y)XhW}f#j@B9N1?830`_w$}P=ggU( z@6wMKZ`|@lXVDt|-k;f8e7K-}K_NqbLlyWhD==Jxm!-HW3CAa8u6!X4`k&SSsjT?br774+*%#PIzJ6U^tC-rU78xfal$9khl#QcJfW#R6(pbJki%hCw zIASysV-l>nicw?Duy-u3_8mlvOr?kV6OF<6rt)z*(PE5}Z#`OMrj6qzc7te<*;a!x zjCD4w#aJ9~3#>JXtK(>;wZ*Z8x@fF6+QNjX-9p-;j4gsKO_=swN?V>V?Yo?|Dr2i) zYcsYMwjpC1U>zCjfNiOmqwYHATWDWe{gipMNM|)iTGK{q+6nu*s;QI%uvci2o%D!x zjoU7I=UuRG&0jyC99m>wtZ7&q>SG`6aI~}aau{~Z`bK}pU?(%Xldw}6I|VzN zv9qv?nZJv$ONpK4a*1{&v1<%kx&kryF6u0u+bSC z4SOrHkTdpZaT7DUiLl9u9pgZYn_97IpQFXSo9s8v1GKmq6|33JfXzzmhLtbT;##UT z$wxeUw77Z6p61L!i)*Xdv7R;OHrm3tcBw%)!_eXu+ddlLTh-#0*&5gNtXkZP%x(p2 zbz-M|SJT!dcADQh*e08|7I^o^>nkNwUUuFFb+u+8U30wHNlc z*@b%_Elzij`qOu!?#q5!S=o7*#wbNMNBT~5x>@|NDu%vA8_NN-_@?U2uKc0JkE;BI zy;{CPiyu?B&sB?m+j7x;`3fz*_Qn+6KI~Pr_{m9(5kZTemW)kvnFfC^vE%+gi=Sop zM|hW@#kVl>Skv%6MT?(Xy|2Q(Mclctc@@*TXbkQnKcCXjmvcOvr)cr%dy;n(TKr+)b1Iy`09=_ z#vSE5t$uocc(nL$tnYIjBU*fy-CL1$!MZcn4Lgvr1F$2;`hq|1BYz^+gl<_Co#>xrj6LmpGu8`x zma%8BK4WogeXv0rTiE+(Y4EmQLY>jlpu3zp*YZP4L-iZc7{3u4#>W`O#=|BV3-ill z6|A5!sXuffqhxHwLS4{>yvZ-m7&qjCF8GZZ7}-RB6JX8JpRs1xl#ES*P0!eL*aybK z{y-NpN8Zr5VSe@h9N2uzFTADDg?uFXf>yh*KhTAIVtqrM(S!=E%B!@w!wBpJLWC=+X35cePhnMVci+) zhV9STe%PUm9fBP-7RPoJcHD9a>knPXcUDtf2M%4x>1b#9orax{{*0Z6^<=CEcG+00 j!DZO>I)5Hr$d9Zp>We?k&!Y?Z+2&mPdUPSb$k=}Y_2lj% diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.gif b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.gif deleted file mode 100755 index 64a9b93c89b6a22d4760777b34790a57344da9cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16336 zcmWlAiC@g?`~G{GeQTz5s;Q<`o0>>XtM|;bOp8nlk}$0%!n9F@_bg3=${-9nOeAq| z#(D-}S|o(Y8gkC0&~f4na!$_2>HG70{($>_U9abU?&Z4fCow638=i*(DDV#e2wcNX z)T0-!3^&I`KdfJJV8yZx8R?IXqBmF1|MKiubFp%D2>0qS-C*0!_nm0ly4-tPYY)^P zdUdU1>zYkvf_bL>6&0E5bHkI)N;2MbH0{q$ooHKWP?z7?l=ExT-hb|*YvaW|`zjXs zM!vp#er&5)zdrAg{=n&+_`TJ;$DZ|X$XA;VZrQ)@m#Z=OC#n_KJUDZ7Vq71e56x5 zc>YYgx}{LCaO`Nw`L)>(4r&KAYfUHg6P@kK1(loU<#inEsV~}c7A;Tp=RK*)SR2hh zuw_qumiWN(jH?=SxI;6n-+Mq>wzWc+8?o@6Uei~#v^*vA^MiehISH@3_m3Rgq?YU$ z*5-Has2D!Dd9Ntp;M)94`}UWm6nq@)?A0IpS$p{7*^S@FPW|3{X2X)rkGEuB*4C?2 zg;S%Qk2`-JJh^A0WBvIpd1D9HKH9P5`_O^TlC(2!T`@IEz@mlqnwymey_g~gaCHutUO);^(?Fa7f+}yCf zc}$ac7Twk+TUWZQboBm>Vfl*Gne!)}-RR6uO!bPW4GX+*th4vP!9CK(uf3bLkzsA*d)>{UxUtCzLaZ0nRRY?JM5OBZx* zDd;RKYRg;JtI-xF6c6v0et+3Mtj^gk)%0%NJiJxXRwC`JS<|*Kw=g7XqI1u%W@RT@ z*0y|p@6OF_Wo5M~^9w`bCwiO9=B*oUT5>u+tF5}CHnVtmSM8W)O(&}Sxk=re%zu1R zIr-bE)nT!nCv_iAmOi@FI(BHw>e!5Tmv&z{)SBuV+N-H(ljhgvl#HoYpW54y>J#6# zId}Mywn5$&2>dwz|1AK7Y2Y@YIkAu878*GQrkxj8nHh49- z&CT-{1}=mag%mxFtfXX|I{K{OX1{J^)U%b>`k-lCcC>y+SW=HRqzBm-WbJjUY4rrB zye%ctpV(sS_~^|&_NJtNzZ!OVo!zNsR0QHENqFxPM$pogp(pmYC8`d5hVNN9uGyuj ze3Fx2_3Vt-b{BF6C`dmNS!w%(mtYkg6M4kt5$9A8uAyp<|KCI4@su5y*!Ixju47fb zPZO`Rfrv7E?j6IlNATaT7uR`8{KuzHz4UdOZMXMQIq72Wr)N&vOP=g7C}w?RPUw3W zm;XRbD{5Kb1DwV3sarZMtzcQBkEX_L;&NWmAy2vJ$zKSlJ+a zSW)}cq1R!3x~(#-y;_qMuSKyBE9E54+>6lkQYX zDb$-{(Eurh*tN!P;?UolSjhd17K{z)6G0ycdnlueSvp%U)V|*y-StrFPeJ_fD+-Wa!$n zXjk6j+1!<*#>~xHXrOF^-=imCtl`Ir9Sc5clG7WTj%g5#weK)zI7Si& zlRp!$TkBuf2X@a2Jox0(*KSJaA1{vRLq1=$SsL10kJ|@1#_M(*bXm}K-VL$26*vLN z<5n%KvXcnMxSsNk6WjylCi1Sw|k8k#WEjyiW7WADIicD(0SLdk5o z_V??myhjxoAAUr{7Q$EC|OL*?Xfk|h_uV@?x!M>$GJl- zK8bTS=XI2LxhHKy>zD0i=Er=ut%(> zT?{U-)=9zAHojdH9h6;pysh&M)%9|StMx-s@a}H|%N*YCQzZ*MCOUk5GU?2*-d~m8 zk6RrV40;qE>Ekf&5mwzod5O!UO%((zwYqcH4oVx$`pR=2HL0x4A!JE&AH^mEcjcrP z&L17!0@m7EU2jvAO{f!V*)naY<^0=tQ5avq97CEt20jrvdyV{ z7Kc(xD@)+jU2&mDS{2lxiIh>q^;&WKKHJwG@qY~;Q&Vu)+XnNTUQK87BGrQ^lI7w0 zOD@kfM~07}bWxec7v)DTF}SV;>#8=WtXE2I#g+&9y-+7mZ;cF;(T$YzCihU5sAKpV z#W`z8#<;xyYI%1atQEfC-XW$1-xF`U%}ki#ULBk>B3G~`pLB_NloX5%K5-!q8#vgw zCR=WQrnV@0h+!4ofY90u#|p)Rp%_~jWR4GiyHM7&Bc`Wr$hyrDSS;`sd1^MP?_Y|0 zTc1C{wq1~1$2c1j?vH#%MP6XgG;&{6orKpSDDG*iEI_1|GKITMQ*$ocw-PFo&Bidf zNX|B~U9!dAGlw;Jn=HA@v{4YvV%LXUSV-ecO~cToPjxR|T-wLn-+2Dvfz!u~7gfeh zU0l`AR7m1kSf=iAi#v8EYe0bPuoZ-VH7bV99*zdBUo?%-QaNj3&DSHErH34nH)He4 zrBjMIeG4E5j63NO0Sb98`B zByP|MvIIc(b$#R4H3d#Vh=0g3P9w=M%N0NL7yWYpK4OSZQ!+tU-&s))Vr=0t1ai61 zRbMfgPW;r9&W4G(v*29=kyFStd6^G3M120>ny0Hg;{kME{t-Ar*yC1wN1>t;w zyb#+EyDSZaoi^#}d)s-i6Spt*TIJB_ysO(#jj8qjG!E1!f6HrHpET|18a;IPAK+Ul zE=r}rM$mb*>G5BQYj#3uZEWn}4y@}#jzhVT{dUQtgvEzO;MFFO?ljdy{#O!)94R>c z!2fP!^vAgo%h`69ucF{)q;5@f3$1q$SaV|CZM;Uk8#nuXvfQXh!&fz$2!1HM zP73#ea5&%oii{SFg0*vq286mau}q6lUvO5{qVRuTgq@=Vzbf!)FYc`f{znA%>Y>y8 zVBf^-NMm@d4U4J4{fPw2Gvhxz_F8q$CvvaDaunD_$G&85{`V6!{Yt9n1&Zln;%S7u z$EesfR9H^mGS7a)*Y#wqp4NaRbjA5!ttX}%07i!t&n>>P*Lk@(W2iDbUx@XPf>~mW zEgkzx1ilm()*O%Sky17p@qsgf`zz|L^MfmS6;XR*tjgVQC_xuC(V2nSOUDKl67K<# zJQQmu0`C~t@_fNXRST>+xG#xYT96IvMGzN>&(u|=DRCGSbesW|NGTYUc&&ZaxEUU| z8S?^75NVT5fmv>#X{Qo76(@TW0yG)FKOjJudhJBV=b&i^?!~Q0j7Bw?B>>+IV{7>cAL@d|5^|2UtCei*e3hI3! zGKcaZTR`7SF9Gti^oyD-u>X^&d^((V6SOnZ@KT_<8hfuE7-U;5<44vaRGF&$m5;l< z$C`5^fWn*jTRjju%lfI9dLfURTR?Ovb2!bxSR+=G#*t*mTV;vKhb_cM-zYCb!+q=K{of{Xz{n-ISH!}jCgWf16iB8^F0_Cvr zK5Tr*ZKBBMr#;zC+984xg-QFuiLG!tw|T)V=rG+1ct%)lw93%KWDV(@hLmp+nt|<2 zBAT6vx=OnzQ4jrdJ876h`AQ%Yc}Oj16PL3(@=20pEBG2m*sQ~UXe*F0Ju4B)m}tfh z6VZ}|X_g5$?THW? zEhKOe*#TXYZ;WC{=IMQL3-!=mGZcW}zV6>+XV#z`%59yrOo)gx>fNW1x-TmizF&DB zB@!JLm$ivs>Kwc+EFnT$OegywI4TE2rIRQ07}m*}v%v8RCuQIJn$&kSjZ*Rq1SsVB z7Xurk0N|(wvO@@OzSX23r{%MkZg?^elFzf{P~Y7uNyuq?AO#9C;h~ORyW%LA+(q`9~K=?TSQ)AD(*f$eH2>ky-S0!6V+%}wk2!;qV}{Y z_pr^F_*=Vi1B+MBHfkK<~vXV~@BRtt63OR7W)NJNK= z^^lz&TC_fXhGyv-%qC}qdJDMVEeW0>=2pwVXye{nzDwSGIrvtA=|xYx6Jr+@KmIWAz1(xN0?5+IlEr;3ILu|7Do;Wi= zTVRb10KoklPShQAwbN&!8pGhUg+l4Jch;mK8#lyO1pksy(F0HuO<*XVFs5-B&@=95 zQ}&|1$s+J6ilZVp9}SkO!G13y#{Js5W}U@{ywD8o==H zRb#-G)h5DvI;qgGf5w~K-MXy5Hl7GiIq_0h{SQQVew)1s$GTrMWmXoidI6?W~*QQ!5Uz9oEVZho}yn}en}*H zu>azoA-KYS%iQcP#7KyXQ(fInnk&XXLQb$t&xb8BfbWrIj`bD*zuT5-&}`wPUQ;QG zHUoGqn=_rAP(dm#d8ykK%)aqLx;aUDB1M1Ys=x8t9a~{Ui`{TSw%s=X;odZ?2)by`sUx>=kI~|| zDwyB~;1f;wV!iyvWALtV*Y$R)w`k!5cH^-+9NmmPZRssUdwn!`{MC!!j@>xnO#Z|% z;^Rqe378emO?5e2_h@fKPZ9N!dGwB>X`(X$I`6OFem!1t_yJuv43Pd?nIuK>$#SAl zy3;6@{FLP|zKSF@C5}od1oXP%CZEkGFBgGTS%!BUD*qG~yIn8QVFkGl?ab4-3G)@W zq18tWQBA-n4(^2a)>_A+wgF>+7)oY?hsCA+PovThI6#L9VE3W{z3wfp;K`lOZ-;NX zbgh4P^z4P#7W{`_gcW=1*W3iwtqO?KS3~ zYedh^(jQTxF+AUgRfikf0^N@qKT~4#4QIOBqZZLr5~<4*v2@LN#M|8 z?uJ`XA{s8qyptK*Lv=Ahr$ws_Y`qGOtm0eSA=D6p!p_9c+(--1V7?v1(h>5m(ud3| zn5l!<^Ycj7`h5jP#hC@7jWdrQP9)cGsKmR(xVE6I?nS>(YiP|^G+!ON|GwP#GCN*z z-0*mTY5BQshj0G7o!ytlP>LN`!eM#?A_$ z-B$A4Go)K zeTzOuUVTg}#ccXJV}Hz($eYxf@BYwfa8yG+BTBpM&QcGmL&e1F?U<*W!urmvg&HD9 z3O_M*CF#g7(HrkM)T*WMTn#3hLoL@}&Hd#661KKAoNe8Qzo3B^nSYcO=tSo{mw(`N z`rYtVhdmCxN+@otOn;&?fnMxe(MJ17WYe_6^CZ>iY*HM)-2|OMlC&am^d&0Y!gxd= z(*eahF>x0FJ{3`~naFGnHVLI@Pzqa0`i(<0TmCr29y-*wRv=xFPcGV}KGz}zWb3g% zy6?lryq8{kc8l8*28NnqUazjb8?q>vz`<&PG|E|avGmsO3!c!%X5R)#?P5}0Y-Z>~ zM(UKV>zj2v7JR~??l)7Pu!$r9TMrPA1JF4(W-gnSZ?sx!CdP|Es&v7b_^o}^kwf9Q zI~v>~Q?}4-6@$Waa)zwOe-x}vbk*TC%M1y3EEh+R>JaRxj_s^@=N%sJyXfGoWx+Fa zV7mo$Gm|pKt_IOGbhdq0uZTkD6h54SI2`IrDWP7EO=FX7*_5{cw#Wh(v2ih0K!X{_ zl2+!%HvQMPc123ZRDC()EF>_&NtK-~e$Ybc=C3Dy#+!hP6K_j9A?GbV)(`MEx?p@G zxn^(MPp30=z-S3TWxM^dR~+l}1)_7Pf5sQiO{FRbV7-(y*NmBKf!Rh) zDkEVj8^4QACLL-$FaxY+gFxRKtd4m42q+X26A`O&H17W@;@)@T@{z~i<8XgJPfmRG z^`($}QO5e`A$Yhe{IqFBr1|deRS?tkyyp}c4Sa5w+G5y=e>h+?iPldoONu@D`+{$MGx00LK!_R4HsK2at3r+&JIspZ zAj?O*W%qN4yC}hH3f+xH1xuk0)O~$UNRe*))s!)KHf~XeQ@rzK z+N?i5E{-$?t+BuI=ASbi7d(hOB|4wYJT98&U3zFF}F5 zPI675>*CE^EJj)>?e9%h-=d~Er$T43zp%v0)aIR7ER z`m}48g293SI1f@G~=a8aM{e z{ce0iPP(oG;gxcNe1E9@v>0xo@VGY_6dws-HW5ow)S%^mSl#ydajoU1$~bHM7IB ziS}>Ln*#qY1$z}uXN&i<>4ewYnQ`1Ad}6P`$f9R3+R4jXv;s^51o&*ld6*!ph;|>W zA+Xc@?044}k{&WeAV(YryxtIwO{LW%0nM{xj={Zu zM_4>QUv#41WOc`cNgRNID+IasIbB`!#A{&QZGmeuii@dscmCf>#nTrinEibf^CSVw z6f*cL+D<0UJxN>tcAeFd%X;UahKIX9%FkZ1oSw_nDQc^YJu^dmsEdXOuW9^-f=a-_ zMdCq^wBQL@O|0#}EkFKey+;5~?M9Sy}anJ*{05@yejNS0~ zZ^Ot&6yd&r$Q zEBa{FS<$U)yHH$>ri<)$tp3J@_BrfHw)1kKVpX{qVof0SSvoW@V7hq_DJB0ohLN zT)d8BMWZX$Tsm?$H#fU}&G%;bLPu%%zYlkI$E#>tZ1%fOp$~Vz{*c{a;k zxT_yy<8o&Qnf(EuudQFT*+b=4dyzG)=>b)!!?QOap6RQabAP9-bok=BR8iaw|Bk41 zHQSb?G1_%#>^TD$1Pmu33_s3kV6}DA4{_^4tu)e}F>w)IWjR5+JtcC4$8)14~5BM76#N~O}d|`DB^5!~;6IMoK?4K*_ z#=by$W>5aF&TVZsQ3Qat{PZie76HZD^{(;>3gRVs6wiJIYwD;hUX%xZ%tq%dL-3J0 zf$N6qpgA05D|T8Wv*vPKu|kg3$f0fV4F=RVE=-Sxw4V7z2G|&|Ew(B^~T6=YbVD8A5|*D)v`?AJ&|k2 za>1@gFR3)C5gTO8>vn9RK;wYx?oyen{cJR}V|Edf+r=3dZwr*VBR#?CGO-25GSM=lOP>&|RhYLm`BiTm60&$i@f^?Qnm_mqbX zsLsN_EK_oN*-b%}GKnm>lR0qKlU=m<#rP(eEikFeRUdK6KNAMUnVE?bF=fiy# z9KeRDToINSZzLso$?OVV$qo;JGt80K=@;$v7$^T3m@N4kL%m}3+5$3)Gpm(Xj1l+YBYK|aaj3}551oUG(B(f+2D$+nUj0U{*u1}+|>Q~05EZ~RZ#4B-ld_$1lRuezbxhr*UQRNXVs6>;NNN(GM=r`ju+yec3qC=ytl$m^(uDW+uG(BQj82zmN&x zrKrLHQ4Q)U6SDI*Zda=!RHzE!p>x@2q*jHS!qJCf*KbuOnxXaX2WBClyAaFf#jwxT z@4Jeh#gQ>gfC$B|oaW-)xOg-UPvF*92q8Bi6sf~yk1Hw0p8~VN!({m#CN7y14eQ|u zErz5G{ed=$V|}e;yKfS5?+PAIk@f95XvfjyY7+3$IU|4W0!_%faihHnoI9rKEtwmt zQ9f13;T&&QFe|}vhm`og1JiXsk-HWEJ%YDl*kj!_{4F@mX2G&QBE)D@Zdgb z>HZUN(BUK0coqWST5&uJ7|is^dpIu`Q78iM`XP50sq3;?!h1a^wtsH#XL&j2RB|9l zLtCYvQ&OgyHX88x=9tUwsXYT&?f0}*(fh0DSe6b>rSE??-ouv5imPR*L%6a$-#HZ! znGP);mk&-3WQgI-1i-1IedR7Wpi#ClL52{XF`;y@$bK0BHuR&}Y@fWy{)%yB8XdEY zeLqlxCx1|;f8Mzk#?Lg$mk)#M$8q`0IgK@~Bm>^~-S5nHsD)Jj7iK=5sR*IRvV?Gy z4wF2N-WWlwSUA=BRE!Rs!L7>_D}uOnj?Jnd$+SbFg}pc%NbJCg&8$DI;e3MJoe3ux zaa1EVawxje0@h6V`i#%hN8>BmDcKf~S_Fko-BYzdhz{dchF@TkCnMM1_k-SM;F^0K zU3b5^_mpB)Qb{P**+u?ie00@?MCl{^C8?{~aLllEq)?Rt(Gvq8TWw=TM=aSuS4Hew zN5uJSFhx4h4?sm`z)QO=($rLFtn(AchsNV$szqF;PYq%AY8@_8E343;iHT9@D#TQ4e56nTD$g31&thgT7u~CAh8P6ZSnrvQ zIt&Q_YSqxssamWMH&;>Ts8ivdz&yH-*jphBy*r}~r^Y~07nK!g-CUj0W>d;WAw;Oo z{$)Xe)4$=35pA>e7#bI*8Sr@Svs}?LSAv2;P~7g3xxnGKCOg_*pne9yG!+F4EI$;3 z1Eh2?NF<9;W57uF{|#cDd_jMLN~Fg#*l7N^Y_qn>#bPa*k~fDc$&;RPot$H&2 zpKs2(C1~)}leU#Fsx)+FHjXZlXVU9UAq(uPF~iodr~b^c4tNbg_Ws=LoNCm%1GBzk z$R)eJs$*VZJigLYkGlt4-h=1H0}D(0(=0OA4(w`fefoD-cOovzh}%d&y`-`U5f17A zW{;Dl`RSNw1<8!AHUs$T$B9c9Ro!bQy&t^&ayqkS4*ZV3KNf>4m-r_M@!qdI7Fy%x z`zlfZ*$nZ%WsX~AqZxZ3h0^hv==1X$TI+H8j* zk%TEaRe=<9!LpN`q=+Vji_ddvK&PDWHP|&iM z1=C+S5)wGp2t#xMYQL+Rea>!z2rnZsTSW6cUh=x=Fy43R0PATWPg?jmuB(#d0Afi{Nv zEML$YIG(YJY&?a|wzT)Z!rh6_uWI~#U>@o^Pf?`{5d-G~KgsRQ@JivEA|aG0`2ilH zTa=V2th>;*go&)-j*)%w4jho`3r5oq*_>_);M$ZI2v;Kb=(ljb_d;3dLN~FTV#Y>v zEb&I`0wfL`vr4Q}I>rJH{b12JymXK(Gp4n?x_0n2N;i$^?hSK$^f{6DGd5Z?u%qI?!BB zot3HdNZ5NHKkZ7YJ53M z9)T=aL9frC!?qUed~JP+QGsaCDg)$UQJOE&N~^OM&|^iqf>CeqvQJ6@HGZ`T7i$75 z?yBNE`2^oiSH-m>RFz&Ww;oc&ilE`$rT9~0CtfN%`>}uTT~UMkeDC8JmX1x`6i%%M z-ytX84WW+N_0Br5SXiGVRc49d#o4o;pz_2qD9C`RP-AV?bqwPn0NCZCi$3RDIWkYt zC0P>Lj!P96YY^0N=!u_X?yoK=5LKU_{byD-klZiB5^xM()RzFoCkh%b*GF>Umd5nU zXJzx!fPrhnm?@>}loDgv={8OMQQ?5Wgs4qVQLk(~Q>*f!tH@gXpBsCZqfnkNY^=b= znN(>K4AF>M6J%${HJM$ih4IeW2MZ#bR6kmh%5kNmR=)Fa@v@uu(okTN2wHa;6-?vS zPpMc&)$B`(Vm4Yf^(!683M4$sa{gzwHr?4$=2rg~`_?2T+qtJ*&N9dys&PJBXtN0N zV$+TiBbo%%*U-Vu9K4+r=M)H+Xca%l<5H*OwkC896Y?{luAbZ98?)91z`y!usur3ilHX0Fozb~w zJI`B>pI)UzJ*7=CkLR7}lL;)#LlDe*1K{@o5@>LAExf`P4)Rra`3`$k%Q)HpmGH@i z`E_fDez48Y>V_6%b2fL*NV)zD&l7Ln#1#^<_f;^T)^=kqKpytQea=q^6`Q3xDPFt(q2roi2Mv%6TREDMC>vXtus=%_(~EF;gCr*WIA?F9yRFa5-Ya^pOvQ z7QJ+GK=ZsbW4GJGUe1Bhf!%=ZeOKQ8f{vC8%(hg&m+r;&eB)5YvGT+>dY95aRe4j2 z?X$aNwPK)d|!UtKqPh}>K9KDP0bIL+#F_lX4QWOu~7+`XWqWB+a*?p>&A34&zz}H_nBv2&CVjcGT9@*e{qbyHJ)L09@|FLnme>8k?~## zCR%`FMPJa}!p&}D40tKGf^~uU+);w(jb;#X@F#S|`^9Is;;?VOVFzhlfwm{2deRvU zQCm;&Z*!Kj0dn9ANyYvB%XEG_tc7YR&w=PDVul$xhNhr!_0BrwnZa2>GtbpYRgppL z1qAym-*`vXW;Tuhj=~9`iQwTy5aMgcd41*5Qlx&`h5Oi3IpdnhBJf`-9Jy_?qyKdS zT{M+1^wJ>K3fr{EW(6UF5XK5)qyr3EHqJBIY1n9~vrguusH`4zA_JVw=>fRiilre* zv~>fQ74~+`dOSX1@b4M+E2Kz=&&naT$I-m8d>G739%*8J%RkC+f3j}G}f*hOs| z$lPID+7Cg_C%CV-1~1UN(+K|3kXylgZV1Wtkka~`O9sZ~k26uiNmsj)woi%pV9`+w zhJ9Pn_hxb7$W3|`JKvR`iE#8gAb>%h!L z?RMDC%;AP*4ZtOB*!4PUd&peCY) z46I>LiSO5LciUP;Tgx4%5csRQ#}rmCfWaZsM8>~ zeyk9u4^b9SG8}pCZS1iOQZ9*f{Bs_x3uO#I`W7Ko(CETi6eB0W2`ZbG*(VC4Psn$1Qc(z8RPjUxaW% z80RlV8#Pra8|N2<%mw#t^z5f1d?10jZ2-1}Kz& z6N1ObFKm1q;%5c)J*X_hdJWtLJzGe`5%+W05d>bpjn9az#QRDpmFN|7>2FQbOgf3ls>ardDk(2!KfY2OOwmSXIA z+7>G>2cOyv?koY5&+Q&bZO_W%{O(KDOGKb|7JBd>X_w;>M1jv1O*?oKx?5~R_N=e# zqF5yhOrg@cPzhr5ziNT)B@|{zP+)_Z*U)Dj!)o@o{jROI9SE_a_aC90lJRwDL`X^t>*xaaYR+KBa~H>?%$ zF?;pBr1zqzqXRTQ*9-xXfLcM{`>Z_60S><%)XTn*oQC9)zv-gv=4V(qm0m*_ijzxNjlPOO#)pk*PDUqAav47DrfeibfXYWAJ~Qb24TtdG?~ z_phDriflW%B0A+_e1rB@&~NEm0X1qpU~@OSuMDl3dg8r1){11EZ?zfWF<&D`LIZ)i z<((iapOZksEOHWlYDm7uQW5%P+joizaOV$wjo^H0STef%`hxqo;Oar#-RnnOuDy`? z`y&l>LiWJDLra0bEvWTy500j`sACa;DpkY_*)z7E>{=1hanzb(iu0YIQw6_@VK0-? zmi_hB7qz?FaWkH2Np;$mDAl8ZzRlTkJ@Hv0>-1=x7P}L9MwagFj)Z6 z75kt2yh!1wbPyCx0B|M!cHt48qo#Aw^~JhhW}P2N{qH(N_&}(Oc{+&C$v)z%NR-+x zoHnoTdT!-54u=Od$O@XpmxS8h2LKzg?ew$)hh)C0rjOJg>P)`org^H4sWX0JE*e(y zPs&gxp)1;O$5)30cgjFvmw4(9Y`Jtn;LD1M|enOk#y*&7>D{x9hHA8Gl4~N|q0zl!pAg2Q~QPSKSx}!Q2Q6he* zQ4r8iV6nO)n&p9U$=B7g#w10Ac^7T(#Iw)1CVUwd1_7=b+AyyYwbr_H!h_(#36qnHRJ*E%n{L4&&Udp-kC~4#bYY^LxCj z;TSaQ6mOoND3GeyL~p?PF6@biBYh9QjEARB$MnqZhe@$+?>IK#e=lYLJP1H%F^433 z7K%!Fxl%u=;E@2zve z>@d_ZIsmelEh!EH3_UY>q_EOD`zj-62(<1*mQQ=1ZWM%eqRaisp&2Zv3-Y-pcsB7h z8(QKv0me2PC)h_k{Necw7#spd_d_6MoOqdW&u{c^6HtF3o$mIZR;jLNQ)k8SOQGXKXJ5(xlBEXf+%dwLnNJoCiK~`o6C$hs0@tn-? z4^Kh1#+Jg46{lp*9Ms7GyNmn-aftsvsd;w+*=xIucQ)0Vf|gdTpWuTLxapHYvnagiQoH74|sKe0pl6I0OCKPaPI7ZF>sKj%l18wY*d6*3xbv16;+fq zw6RapT{Eh?{j$1jn4qm~7vEQ7JCreV^;XN^F@myj`g50y_=w=p^`*llf_u576l&MH zG`HW0jjPi$<5;R7TSZaM+rTNF<_zrJ#``H3jFq545(J#&(+qDmPCyI;4-kPtXdU(Y zJ92YRG^OblyLX?f)q~1`eH-|W(X!An1*ezUhTJhru-3*Byc!B)^InD&R6y;^SI8&%fPoj? z0iXOAV5R1TSpdj@1Z&9zkep51P8+d1k z$N}z2EIa>TtAobnP8~f_S|6HO?q~tfNFW-3soA_|k~bH)TWtdu*&o6$S%xw~7dhts z_^iVKYP;>|1Vvd65Bo=~{3U?OB>q1+i$YVPQ=&yp1ktDJDj}|Gz)?`biD`x^>Ux#qd{glZ6bih zMO|xoAl>o(z2f4_z56^Mk8w?ekQbW^5CV6;r~Rp?r8orwkWbISH4Mwnwo_JI))cp~e$QMsSC*NlQv!Q^JxZisiBF$fQ{f+oP}ESbxkdC>07 zJ>e#ceYJox4#m6D@|Zu29y#G5qbcj)3xH#%v3!ox1IdFbHP7+;;XoZQR|p3HfU}lF zVnf*e?6d7%9ByAhDlcU3hnHX9a80u?QLBb|dTeG(f48J{vz%o{x!=-{?lsLuCVV$8grl6&m48*i{Av` zEbNj0Yeyg`YzRC%%6&+B+l`y>!H46L%1eI$fCd-h0CMPG??~Y7^5hm8@V56;*Bg5K z-2Rzg%K6X*%PwfPwXXo*Yz$!uKD=EFj?2M7wW%4PDu0Qi)VoNKwh1(%A=EXCAL4~) znFM5`ENH6oR_^@ae#o{G$K*oJMxV6V{9vZcmJKKZc}qBe5Hi*+ zdwc8?pX0{;8o>g$7k4oVdAPu}VBS%3+!=1&3{b)d%JK;+4G0@N9wg)galBx(>kLLQ JABO>={vU+{Ez$r0 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.jpg b/tools/HitboxExpander/third_party/Imaging-1.1.7/Images/lena.jpg deleted file mode 100755 index ed01c4e6769b3f01b13d78c6ee4e99e123d36464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4788 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 su#|>TAcLF_$&DnbW):V1EW/>e7Eޘkqrdpom|uwphp]݋Yr[XF[L`LhOgOhPmUgRiQmPoWsR{WxTxT~^Ё[[Wρ]ρZӄ]˅n~\ԁZҁV҃]؁VӃ^~VЁ[ςa҆e҂[ց^}VyU~Ẃc~YӁX|\́Z|[~^υgՀYЂ^σ_΂aЁ\}XЀ[Ђb}Z̀cЁb~W}Ý`{Z{bybnZlSh\wlψnٓquwzz~ndhߘgޝjcoޚpۛmޘfۖiٗo֓kޝmˁ٢ݟ֕ץjdMkXvWy[|Tx`zZt]k}_Ҁ`ԋg^RgIYW'7X/DZ-8a1:f6=hfzkjvmrmwijo`ٍ_pMYM\J`LjQlQiMeIeMfPjPgNrQwPxT{\ǁ]YyR͂]΁ZЃÝaȀĝdσaӁYтZцfֆc}X{UӂaуcЅl{V}TxS|\{^^}_|\|W|Xр^^ԁ]́`ρ]чez]ɀZ΄bρ\}Y}]W}\^Ѕ`}]w`{bnWpZlZsbσhהyݜ|w{ysޟrrnfgnkߝvۜvژlڕcהfّl֔ky՘ٟޤˌnNkTuTuUz\xdxVx]|`ȃ`ъgYIT/DW-D^3D\*7e5Bj5A^2Y-?Z,>e6Ba.:`3Bd4=Z,6hgxzyxoirndlja؈\fKSDZGYJpedLePeQeQbPcHkMrRx\x[}_vWxW{WȀf{[yU|c}\|\{W~Ỳ^c|X}Wуbс^υmԁczW}[zT~YzPtRySvVxQsTyV~[a̓f́dρc~Y~`̀dρd|VˁdzZUˁ]{WxVx_uYu^t^lVr^̂iԋlԓzٕsܞ{xޟwݚsrtߚhgߙlޚkߙfߙmݘlڕkِjڏ`׌]֍_ˈڤާޥƅdOkRqYoS|`ʃaaQ[.>W-AW*:\3C`3B`4@`7Ib,:_-:Z);ljyt|gqfwefkk]ۈYjQRE`O`LcOjUbJbIfMfOhRkSw^xSvSY{Zc|[ʂg{WÝeщsZh}\Ѕg~YҀbԃdҁ]|Vфc~U~]Y~bzfɃuȫȨyhvX|UvTz\z]y[ǀac]͂b|[^΁d}Pʂdσà_y`w]nToRk\s_ƁkӊkՒtؘyۘtܖmޝxߜ|ܛsjߜqmhcߝqߙhdٕo֌aڐdڎ]ُcԐmmЋݦ߫י՚bjSkSo]}[^OY+:U+;U)?`1D\1Bk>Jb3Ci7H_/;_/;]1?rnprua[ޓbmemsshߋ\oR[PWG_LdPeOhQeOjNeMkMsUpRvSxUxV}W}VV~]ρ^~Z]҅hYyZҁb{]τd[ЄbՄX}V}eˑ̟ΡղѴضƴԼԯջs[sYʁgyY{Xǃl~g΂a}]{XЁi~a~_~`xRw\s\rckWpa|^؊gבn֑s׏nܗrۖqݙspܕhmޖilegۖlߖgۏ^֏a׏fڏ\֌]ԍgՑdă٨ޤˉkQpW|`\LT%8X1HX0D`0>c7Ab6@a8Gf>La-:[):c/b2;i;H_-8d3?^4F\+8c1:\*6],9gruqYفN{LيZhdmolg܄VkOM@UG[FaM_H_IdMbLgOfOkRpQtUzTyRyZzV~[~]zYX|[ҁ\\}Z{^фkɄq͕x_ĉqƏz~Ȕ˔|͔tɓŐʑv͞Ӣ{ղׯҺҷլټջȥİoUsZ|ce{_x_ЀcwXw]y[oSrXpQiSm]oS`׌iٓlܕw֒oۓoڔs֕w٘uܝmܔhܔiڒhܗkّb܎`ݑhڑm؍g،aَ`َdٍ^Ջ_х^uکާڗxXX,AQ';U&8W0Ae9Ce1>h8G`3<[2E`/Ag9Fa8L[,=_.:jhkgYnBlKۇ[fsmnknXoOYKLHVK\SngdJaLaIfKhTnUqPvRv[|\zZyPzQzVЀ_сiс_̀ayWӇk֕qʐuj„n~mvhj|srƐ̤ǜǬѦұɧԩװѶܷįůjZlRpVzcy]zas[zav^t]sUp_lYfNpZ}j׈gܒnޔmُjۓj۔kۓuۓnܗokٍaۍ`׏fܒfېfܑaڑh׍e،eڍ]ێZ܍]ڏ_։_؎dɊܠ孾pLT-AY-EX/?a2@j8Gc4Ei=K`.?X+@d3Ac5Fb1A^-:g29roa_xIRAqKی\erjmm_܌^lIJDTIVG]K]NaJjNfOfPjUoZsZsLrSrRuR{]}`vY|\}azWz\ymRzevUzg|hzf|ąlt‹włeńkͥǟԡyӰ׷ۺԽڹ޿ִŸٿǫlYkTubvWs]uWs[sVpTpWjPh^lU`،mߔmܔnݓjܐmڒkגqےoݓlޙoېdهZ`ތ\ۗlލ]َ`ڍiՊ`ێbՌdؒjّj،`؏_mۥwK&=U*=W*:Z.?j;Gc5Ag4@\,:T(=^->^/:V+7_.;f6AW'4uhڄR^EJDqMۉVmmiuel߇YjOF>M?[NZKbRaNaOeReMdIjOqZrStZuSxWw_v[π^b}[{ZyWrPoZv\u\pxmzd}lÈvt̑xĉtɉkNJq˗~ӣ}ӲҳԦ|ӸֶܾٷབྷڿãźìǺȰӽfTjYiRoUpXr\r_p[iYjNaPoY_ߎcnݘtiۏm֎jӎi֏l܍iڔqߓfڏfޏdސcݐaۑiٍeސc،cُeܐhݏ_܎`܎aޔjޕfˆuU';V*@T,CZ.d3>f4>g6A_1>Q(;e;Ga1?U,?c5En@LkNHULWKYJfX~bܐllohmjӇji\f19^0EaXwZۋfnޑlߎbߏc_ݍ`ߎhfmxAET%9\3AY*Y,@n:BY.;X5D].<]4EmHYR`ytȑwјunԞy[JWNYH^QVCZPjNڊ[ftxv}cوjjPNJKFWIaN`QdRcN`HdOiYgRq[sSsPt[wZ{_uZ{XsXnTnUpWrWoRn`}tpuygye^Ҋfǐ|ǎqёnŇlϏjˑx΋tΑzݲĕŦʪʰʴͼϰŨþ̼̯Ǧıǚj\JAM?YM_L}[܍hznlnj؈fdKk08R)dQԈkݑjdaَhތ`ލhihftRX+j5\0Di9OjeȑwƍsɒuО֥٣~UG[H^N]LVH]UudڈUio}zpa݄UhTLFKA\QaKe]hZhMcObNaMpWmTnPwTvWoXrP|W^JaMkQsWlUjVtXmYulx_~dȏnǍ{ΆkʉkҔxȆlǀpÅhχg͉brܲ޿ƴƵݺùİ®пѽŰ̼Ͷϸʱкпt;SIvX܍grlouݗuՆciUw:?]-=_.;[(7s45aJ{SՎkڊ\ކU܌`iyLW)9V+<_0Aa2=f0=c6i5@c7AP(?}KU̖ĊpǓ{ӡzӟvԢ}أyYHXIZO[NXFQEjOؑkdjrsvi܋\nVOFOKVH]NaK`GeOaPgTm]mSmYoRtYmPk^Ȁ`TiYfUsYnSsTlTu^vZ}Wi̅lυeЎiƂh΀]щnďyyhn^zpߵ⽙߼ผݯշǰŷɽ۽ʶȷʾ̹κֿθнȚXPJFpL܈afkߗqguևdgRx>K`.C](4^,6S".p=EϿչپӿؓob/AU*<[.@^1=f1=h9Ff;Gh9K`8H^-8^0Gh8Hb1;[/=d7KyїyŇpÍwԣӠxӟ|ҟ՞yXK\LYK[O]RUFkOՌhlww䦈mc؉^fHEBPGVFXG^J^NbL]IeWmVeOjOmSpOeOϊ`efUiPmUq]|UmWsW{jiZʁi΁_ώn~nЈap̆jxWyfrfʙܲݯ亓جׯƱԯţŰīIJ˸¦ŷ̻ܿòн϶ȼ̹úGAnWԇlqlhskֈhkSr;A[)7Z'8U'8Q.AγմնпԱL&AQ,CZ-Ah3@d3?gAKa2?`1?d5Cb4Dc4Gja3>d1=V.A_0[2Dd5Cc0:_/9\.=d6Jm8Cf3^.8[,=d2Cf4?W*6Z-BuӛȏzЙףzҠ՝|֞јzӝ֛yјzҙvdM`FcOdPaH`IqHߌ]ߘipsssmߎ]nKOCMCYKbTbKaG`IhP`IeLkOlLlRYKڥ᥄zThQmVbMaPqQqZ_YyY|cfU{[ubД֚ښnғqЗxxl۠ئ؟رۤӢפ׼޸Ӕ{ۻ۩ү࿪ڲױܼ׮߿۬װ׵߽ػԷپĶ׼įĸӵѼƽرߓ`iïԫֵױԿϴȴʸDZʷιͼѿ޺L'@W2G\2Da2A^0>]+:Z-:d3@c8Io>N^cϓ|Д~Βx֞}֠֠}֞~ӟ~֠{њ}̖јzіxgNdPgQgKaH`HqMۊ_lgkuushoQJc3A^->k>Pj7?a3].Aa5Aa2?[)7a0;Y-=Pay|ӗ{Ғr͗Ԟ֠ӢٟաҜҞҝ~ѝԞ}ԛs֚qbI_LWHaLbMbLpKۊXfvuuvi`jMMENG\FdSdTbI^IbOaM`FhMfF`GeM{{cݒjٌe}Xk\]NhQkMˌqՍkρ`Їgϋc~f֏q֐n̑ϏvԜuʘۢx֕~Ӓw٦ڞxܚۭڟ~إ۠Օ}ݱۣ՝f̞׫֮٨ܯث۸دէҬԭմʠѧʥбܺIJαȶñܾİűȲȵ̺ͼͺϻșׯ}kҡܷ˹N%9W)5c8D^0:U+:f6>\-:n?R`hՕxԗ˓؞գӟ~֚wӝҝ՞zҙx՜rМ~ҟ{Ӝ~њ{^G]I]J^H[HaOnLߍ[fuppqkekRSKRNXK`K\L^J^HcMaDgNdHcM]I}Q}ޛzڑqyVчfv[cIdN׋iՎpԇhʃgǃdɂfוxևa͎zՑjʋsАxԖxҐuӔ|ܡyٙ~ٕ֝t՞ћѢۥ۫юpŕ׬ۭۡӟٱخӤק֢֨ӜǗʟݭ⼋è͵Ǭî­ŰŪȵʺ̸˵ʹҺʛШĉt٩͗иS.@Y1K[1=a8@];MY*;c2@\/EyG\v֚|ΐ{ΖӞ}ӠОқњxӞӡ՞Л}ϝwΚyΙv՚w]FcO_JbNaJfIvVߌ\mtsx{hkqRK@J@XG_NfRaK]D`HcMbMcL`FWG^~s]RڂS_uObGэi֊j˃hǁd|`~kٓoυcזuВv|pĉ~Ӗyьjؔuڡڙ~ԕɏϝuvX^˖ך{ݣ٢ؤ|ќݥ؛ҠӢТЫј{ėڹٲ̳ãڻոۿůDzƯ˷̺˺ʴͽǴΥŌzϚjl`بI$=V+?a8J]3AX.?iBPc1=d6Jae֘yє̓yҝנؠy՞Ӛzњtԛ~՞}ӜК|П{Ӝ}НԜs]JbNcJdPcLhQuRZospxluZkKKAPGZFbS_K^F_F`LfN_GbH]FTFؒNÇnTY[^ۈVoa΁ax_̃iˑ|ňuڎkъqҏl{fDŽn͌vЊ`ԖyҔ}ӖSZ}mgUYjj_aʐ̙\ct٠ة‰~ררxh7LʛƎڪڻdzȪƭڽİƲȳưȴ͸ɲ̹йҿһҧƙzQJcWտoL"6Y-?`18[(7_0Cl9?\1Ei7Ltٜw̒ϗ~ԟ{٢|֠ӚzНњ|Ԝzҟ|Ӝ~Ԛ|Лwѝ|ϜΜ|dTcTdSbLaPeLwRWisqw|ncqRLCKATEbQ^HcLdOeLhOaGbJ`BVDPËe\YcXo^t\{er{oȉuЇcЇi͏u}n΂eɇtʆmύtהzӑsq͊qxmjk]hZeoE\֦أqE_\krqai_2KlEb^nR,I̜彙СԵŪܾƬñõŭɺɸʲɶη̻˵θϳΞXDTH\NxkڹT,AT)<_/=a.9X)7f3=^/:X0FdgҖЕ͔֢ӟ֝Ӟ՟zКwќ|Ӛ{Ϝ|ҜzΛЛ~̙ЙyԚy^KgQbQ_MeMmEtL[brlspgisOPHK@TJ]JdP_GcMfRaL`JbHdMXDcExjjVً\[vaq_tYÀljaȂj͉nȄnҎqʀdȄm҈iȅlȉwӑzʎemĉ~q{dityegpYpmHed;\c;ZtNoX.?P'AS4VL,NԘtӥȸȫèìūįDZȴȯɺмͻϿȫ|PRF`RZI`Pq_ݴѲD5R-@[0Bb3Ba3>V+8i9CY.Ve^3Id]5M?1E&Bͳu̱ũĦƪ©ĩݾåñ׿ۿī°͸ɬһͮ\MRGTEVH\Niaʗ湘˨a03U'=X,=c3A`.=^-?c2_1?`4A`5Cd3>_,;[-SfA[U_c@RZ-EqFYX+@oFjM\a1Ec8UsgQ'Ata@4_lٝlnݴǦٷԱջ׵ѵЯմظ°Ĥг~PSpBJv~xަyvr鷒͟a.1U';\-8_.;l8Ab7?a1;^-7d4>`>O\7KpmғsϒxӞף~֥ԤӦ֣ԣҞҟѝΟ͝Μ͝˛ʙ}Ζt͖ykViWfRdKdGfGrNVjrotuyauPNFGCWH\IcObJ_KbMaJeM`KfLeF`FZLܱڥ䭄qYIӌo̅oʉ{b^zh{bzny`σkՊoϊv|h:Gc4Ad5D]+6f28X0Ae:N|Ǐxʑ|֤|ڧ~ק֤بסѣҢӡ~Ѡ͜ҝΜ̙͛͟͝ΘjSmWiPgUbL\CoNۊ^aw|son`uRJ?NGNH[J_NaJgQaKbM^GcPiLhNiQbLWKݵ}谀}wS{_͆prf{c΀d~jvcrq̇w|vpfg[ii>XZlY.EQ&AoB`huP$8a2P^1=[.@a/Db5Nf>TW-NpQWn~⼒Ῡª׺ѵϱԷԮѨ׷պչֻ׵Ī竉SRooRTezkvǓ婁 ⷃV,<\.9U%4b3?h5@k9Ap?G^1;U)8\+>c6Bb8NXXsqК֨٨ע~ԥբ֢ԣ֡ўңҢНќ|Ϛ͝}ʘ{Ǖ~˖|jWjViRcMgS_NiM֊`mypuqkgxYKCF[/CqH_vkm~ӣ٦գףץաԣ֣ա|Ӡϛ|ќyџ~͝Нx̝˘zϛ|ȕqXkVkS_J`KZFgJڃUgxkxyvdwVIDHDXJUGeObP_L_J^MbLcLjPqXyeoS_OЂPٔčwwd|d_T{hzg}yȇpτkqr̃nqusAVf;Qh9SaqCZ\2KZ3PpB^evK_X-?]/@`4FZ.>W1D\4Mh|}XjҪխֵҰ̩ѴϮӰײаͪĥ뿩ĭŮġwaHHSmvP_ÊzSBT$5S):^/@f;Ji8?m;Bi6Ba0W+AU]plјo4AY,<[/i4;rDRe8Dj4@]-;_0>`/=e5D_.Ftnv}q–ӤդץԤզ}Πՠѣ֥ӣ}ҡҟzӣџѠѝzНИq͗vjVhRbOfUdQ]JjOه_j{uzvuhuQRJK=OC]N_JbQeNfW_KiSeNlRnTsRmUgIcK͍֚gSgNoZwmp]΄qmY{g{hhnR%;[oZ.>W)@].B]5OwPlqHZb8SSo`9\|Pi~W{O);F!7e_ĞӤ׮ڿҪ΢ɟѵհߢ笉컞ǪäȩǨ˭϶ͳ촏lJJE\/APQwDQ͝]0HY3E]-:c1:f1>f6Ej8Bh3;g6F\'4f19X1?uHTuuƐx˛}ēv˘Ԥ֩ӥӤ|Ң~գҤբԠћyРҠ~ϝ{͟~Ιz̖wʔ{cNlXiVdNbO[EcN؆^hrz|srdzZPJQITD]MeOkUl[cJhOhYfMgT{RrXvTlN`P贃jPwimQh^͂dw\PSxHQIQ[_\.D[nU*Ea2>_0A`4Af69Z-EhiĐo|iΘwўʗyė˓~˘}͜ϞѢ}ӟzԣСңРԤ~М{ћzҜwҝ}Θ~̕}lTgQeOgRgT[EfHԅajzwusnepWSMSJUE^ScOfUjWgQbJaQcNԆbrQqQtWsSmZS伕tPoPr\}hȄyׅkg[Y[`4GT&:f9Wo@K[.Ik>QlAUa7KX)AqG_g7SfX{[,?k@_C9Y]Єl̒ܪۭ׫ѦؾӳѬ̦ؑn訄䮑ĪɹʲͱһѷӺɨzWBa.;Q":vJRϤ]6IfI`i8Di:Fh=Fl>Gr^/X-;RWȓrɘ~צ|ңѣϜ}ɜ~̜{ɗ}ɛs~ŒuǑuǓxʚ~͟Ϛyʙ|Ν~Λ֛{ϔwfPcQfQcN]H[BdK؊ag}쫀ꮆtuuvWTLOHYR_OgSgZeSmXeSgRlSpZsWpTkIoLfGӌfʁQtQXՌxlmr8DXrO$Ck?TmIrf;VU(>l=VSgZ(;a7Mf?Td:L_1EoEl}RuH7a}ڠpsbzۜzۯֹں׷˧Νܝែ䥂鮑笄賙붛Ůɵǩ˪ͯϴҴѮ︗tTPFU,BR(APZ٭HO_,:d=Ok<@m?Ji?Ja5]3AnASsmŒ}ԣsئԢНuΠԤҦӥϡ͞|ǘvwsÓz|ēДqɚ|dQfP_LdPeM`F_KՂYrw{뱂xplwUPJRNZO`ShQfV`OcM_QgYkQrPuWuYwYٖpݥ[S#4U&:mgy]qRb.FpFRN$@\4MqS&4h8H]0Ch?UV)=[,C`3Kf6IX/Bi8T[wQ(?yr_Pŷۥܹ̙ӤܿͯG@eQtc|hؓ䥍뵘뵒걎벑췚áᄀšȦɨͰ̪뮈oRt7?Y&3P%9_tݹ^Zn>Gc8Ji=LrIRh[2J]a|jȗzѢҝzԞyϝ}Ϟ|ϝzӠў~С̚z͛͞vǙĕy|v‰qiTfPfPaF`C^K\HՄ[wv{o{pkv^RNOHRK]LeTbKbPeTjMfHkRsXoUrSz[ooVo=G[(AڃPUISRb5LT.S}YzoS'=g;XmLZc:NW0AV'9P%8lnMr[T)D`:EĀeʛݪܹཛྷ͚ػíɑoֈkޖzהx}eKB=;XMҍt鯐紘箌쯊¨ęß鹏f^UH@C=X'6O*AsCU٬ÌwY-?}HLm;Cn>I\4C]0vKgS(?^7HyL_P!0\)6U*ClqX1=E 8Ҟsz߲ƭҨֱƩlO~_Ҋnӊn{^ӉldXVGYNw]壁骊ꮍ칚춙궏mY_[h^lVrNZCs:@Q(sHUÙp_yDLf;@me1;c0;S&>RXr̘|֤}ՠ~ӜϚv՜r͜zјvΞΝxϝ|ИrϘzʘwʜxə}ʛʚƖ~zÕ}`J_P^Q\LZLQCXIт\jzvnv{ezTMEOGTETE^JcJ_H_JaJ\HaZӥfސ[uizb2AIHH"CxY|NmfeA:|Wtg>R}^rV,EL#6U)BxS&:]'7K);K#:ɕg۹ܤ|߷̷޿۽Jh.5l29h5Ac-8rNano[-9\(9V=ׇ`Ղc܍pu꧄レ̰ʥuXf4A_2CGHv=@d/=kJQ(AmdŠnvՠҞvМϗxϗyΗtәnԢӞϛyΝ}ЙwƖxΜ|Ȗv˖{ȚǙ}|z{x{dM\K]F`LYGPES?ׂVgol~]yOHCNFYIePaI^HgPdJ\EWH~Ić~fܑkd][̐sGOK*EoPtb=V}_L&@nHlbpQ)=Z->]7Mf>HW,AV(6d2C^.>Z,@b8WQ&Eul`ܤtීڸȶŠPIN?i6e19j7Ce1a-5h/7f6AW*RX}t̗ћ}ӞҞ}ΘoМ{ϙx͖~Ҝ}њuʗxϚ|Ηy̗ʔnÔyÒwyz|ru~w~ɣdLdQaK`O[MM@QF|Optyz{zkyRVGYLaJhMjSnThOC5n4BUiӯ캎^3JO&M`/:g6EM#4W8[̛{ԖtٹƺeO{]}j׋oʅtZOn`Œκ綋ܑmpX}Wx\Ձcލs驈ʰYKǀty״ҏD<{>Eq5>Z/Bb3EW_Z`ˢ}JTSW`1>[-8[0>j9?\/Bf_kÌwԞΛ|ϜzϗwЛ{ӘsϗyϙwИvћs̘v˘zΕw̒sĕÔ{{qqxyϢڭ}෌hPhUfOXCVHRGK<ՁUhv}﹂voӀUVJYIdKiLpTqSӛxV'9ni֙{ƊƓtOa`/b4EtBG|hčpϝ|ѝz͚ЗxǗ{ϖ|ϗuʝʗy͖t̜͗wʓmƌvvzutx֧ݴ丄潄辉iVbPaNXKUFMAH:|Sjxv|wmՁOSCS@`JdHnOiNՊTƋȨxERmE[~RcT';[3OZ6\ĜpZ5R`:NlEc[jva4?W-CX);`2@[-:^.?X+9G0J":ӛsŌzڦٱȱ\GcHӄgيtݒy{ܑqݏp۔yݐoԉtؔ|ەzܟڔ؜{b؉pׁdقm祍һҹڪڕ{Ӈpςo}dgR_J[D|?@W(9b2BOUNXbktAAl8?X&6pDEY)4KPËsuϜzѡ˔tΘy͖yʕ|ʖx˓r͗zȓw͖xȓrʓwȒwǑtwluvϜy߳缅亄齀鼀aM^HWIPGREC=D;|UctwaQVJZG^EiLnQmPoWיxpgjgc8Qfc>VP.Ni:Y\|uiF^uPoT+H`7TuRunNbwpm_0@X,Dܹjv\__1;U%4e:?T(=f\{u͜Н}ϛx͖pΘw˗|͘xʕw̕yɕwǔȕwvď}opجŒ鿄羇~꽂YEWJTJODM?A9EBzNnuwu{riҁ]VDP?YAcFpYoXufk˪iC]`9Qe9S{MnhXL"9Q+F^8Z{zWgDg{i@Xp@JY+>`3BX,9T,CU,CU(;|RÌ㴌ѻD;jNxZҀh܋rᖁ}檋奇豖䫒嬒魑橐⭔ޜ~ܓ~ێoډjbz[}˷⸝ݨݚ}ݍmۆj~cz`dMo/5f-6j06zBFm:C߯ux{IIpAOW)8c1:_->ziqɏtӟxΝϖv̕u˚ȕ|ȗ|ɒxŒx˔vƒuÐru}uvuتčŃ}꿄}VHWLOIROK>~>;A?zWc諁}w|mӀYPGN?YDkfщkŀotBK`Rh?Xc7OtQwvNmtQuaT*D[6Ih?[rsLTK'Fzuh]4G\.>W/FT.DO*Cvplٴ¬ϱT%7MAoKy`ׄgوir{处讓벓笔簕簌鲗孌ᥐۓxޕy܌u܅a܃iߑvʶ㸛ऎកܐyچvՄk}^gMt>Gm;Eh4Bm7Bc/Dⴕf6Bg4:`5@`/9h4?Žuuјyӡz͞zʙzɗɓv͕sȔxÔwĒxÑzwđtÑytpqեzʼnć€|迅’ƘUJOEIDOIJCy;6>?{Uptvy{ﰁ_|QXHQG]HnamVo`ytxMaXv^|rF\^6R`^6Um]8UY0HZ.E[/HV)@_4LyIWi:Me5>P'Dlcic\/BY4JS)AN&7[2GÃfÄtὣM'Cr=Cl9?k5?c-?ڬ˨a/:[)7e5?_1=VNɓn‡oԠzРzΘtɜƖw˗~ɒvĖ~ǑuɓÏyyusΞ纃|}Ą‚鿎Ɛɞ˩JGFBOKJDC`3B_3C[0DX5I\.C~C?p:EqcXzuN+DH 6M!9csdĩĮvP(;k17UHtRx\ڂh݅aqzm袀겒鰄筑筋{㟃ݎhތhۉe{Y݀Xې|麧㻦ުߞڐrىoۄjvZTGg3>g1;m3R&6uADr9o3:o/3vXj{x{we~OQAMCZGdbzWisGh\|^d8Zbu^{\Y5@J$8W-Ha2CV.Da2H^o[ZznuZt;^,|?=i.;i/6wYlux{c}WPAKI|ofljuluE`[s\vNizPoa:^yX5Y_^0Qi>SY0LkDRS*EBMD}\rt}|{oՃ`TGMCYGcIoajqan^u}xxMmI&N__yUzyW}}b~L#;f`dojtYsmJ$9S)dXYCoRx[~[ځ`ކkދqpruw|堁{ttoڎz܀[߀ZցfՎ߾缡䦆ݛՑ}ӄmxXX,;X1GU-D]3AIHs=Aj6ҠzTQcґbʔrԜu̝˜~͘}ΝŐwÔwȖȒoʓp~rxz̗s뼁z{ȏќќΘ͚ѝӧҧҭӧԱLAI@E?I@|>=GCh`ьsz詁jx~tmԃ\VHSFTE\Kӗ|mPk|Rll>M[0B[0Ra9Ng@awQseyVnyk>X`rRYL%5M'@Ɛ~ϴͬZNuem?9W(<^+9h3>k:@mmL|`؁\~]߅gfmߊmblqޕwsvܓuݓoږyࠃ宔ͳ婒ξ绖ܜڌpΉvofZ->V0FW.?a5Jj=KPIJB{DAe2>X'>IH^Vˈtݜvz뱄~|o؃SSFFEsn^ZiRjyqDWkg:I_2JaAVw\sQe]yhGhuMrqV2Rw@)EqCRņyϼȫ¯O=\PȵT/FT)>k`e2?m9>f4>UM]*3a*:VKSJ`CyQ}WXރ`^gg܆erݏo݈`܋k܏oِtݑrtjly砇夈Ջj΄rΉvY/FX.>a6DX/C_3@v>CPHF>}ABd/8X&<zub|`Ր_̔lϚuϚu̚x˛~Ǖ}ƓvɘxÓ|wƑtƓ{tvooڦtzʈѠӛњӤЙϠҤѪծӫԬѪm5=q78x<V,?PH]*7b.:n=>{B=a+4_/>FCNF`IwW؁]ڄa|R߃Xއchik]=YAqF|MyOuNqGjEnO|K؉gC8jNlTےu|fT/JW-AX,?W-;b8Fh3>x<:ROk2=zC@\&8e`̓Zّ\͐o͚uΚu͜}ɕyǕ{Ɣv’}yŔvur’t‘ysiުsƅΔӤԢѝљНџҥӧձԮԯ٪j:Eo:@z<;|A@z?DYTfWЎo}ux{{j҅aTQ˗NGe`ĉSd}Tq]7LkCW\9RnF`{T`=[c|Xuj^}uaB^|Rnݑeۄjټj^thsW/=_-7V3Bi58_,9i39i68p>Cx=@d.Bw8:VQ[CpRwTzPրW܃`݇`fnsفb؁[sWnLvW|X݁ezZ}n吀囑݅vԋu܊n֌j\0FV3I`7CV-Fa2=zFIk7?LLRIe0@a]X+;PPԈVَ`̗|МvΘtɗuǕxɗ|}Ó•~x|vnvy̐ӘңјНњӢҤҦԯ֧լթԪh8Dp7<{@@A>x:?SPbRΊnrꮌsrzp}}vǖHDQMƍgXcla1MnASO&8P'D|Piw]`EcV3Tlk^z\7YbcsYÝ[NɌyټP-C[9Kc5CW,=\-8s<=a.;i58t?CHGd0;D?RIGAgKtUuQ|S~Tڄfۋjksm܂Z؀\ނXy]kꝆﱔقwՐx܌i[JY.GX.?e4@Z):d5l9>h6A~LI_4FVSOH}EE`DnNrPwP`Ӂd؁eއbދkp܋i܆a]|Tރab|꓁upԕܗyʆmW*@U/FV-A_0C\,=b-4f17E=w=CRLDC^Yh8CuFTΝ֡ؓfʚv̞yʛz͛xȖx˛|Ț}ĕyy~~srr{c}֣֢ԡћ֨֨ը֧֮Оϛ͔ˑΙc3?g5>p::o9=q69]LUKτdܘs|x|lՁTREEQѦ`Ynl_1Nq|Y+?X2Ng[0NnOv}Vuza>[cChxpwާk穈m9FY5L\4Gf6Ag4:X-Bj58c4@r=Cf9CvBEq?B_/>QRRMw@CT>eIeEnLvZ{W؂`׃cۇhޏrގqۅhۂ]V~WuVv[rX{\ࠅڏ{Ӑor6:U+CQ%<\/Be6CyDEk7=o9>WIEB]Qt>=UGl6Bj;IҫڡՔiʛtřt͜˙vȗuǖvΝvƘ|Řyxw{y}lwdÅکأ՟թ֧٫ٴңΗ͔̗МРϚ_2Bg1Ag1:e/9}?>iPfZ΃iۓin검zxyׂUVO?HabT^g:Ur]1DE"A|_~iA]O0\ߔvbHb`[wqvoi–w{]S.DZ4HX->g7i7A\5Gg6?e0:`.=^,;k9i7@j;Bm6=I>:2WCbGjP{[\ֆe؋pىgڎlq{ݖs~䥌魐x䢄ޕ{ӕsV&9I@W0IY1E]6In[,Bծܥz̛|ˠ~ǜyɜȖy|țŖƘy{Ŕxq{kugǑ۬ڣ֤եԥԟӥ֧ԦңϗΑС͘\2@d7C[-?U0DXPgTeUІcޓjzzv찅|rրSTHIFdZ[\`8IW0LzQ_e:LO1RWp\:TiCegAW_=Y”|v[˕hD_kktCRg7JW/E\3G\1El;Ek9AZ/Bk9BW(7m=@^.=`/>n8;v:9h7>l8D?u99u4.K=[=nP|W~Y׉kڐwۓ|z{穉壇穈奋樊अړyNJuS';r>FS3HT/J\4Ip>A\,;m7;`/:aTNNI@OHSCYUZ+F׮ٝwȕ|ˢ˛vŚŖxĕ|ēv“yĘ~ŕuzz|xt{lrϜܯؠԢӠ֧բ֢ԠН͗Θ̘͙Ǝ],?d5A^1B\->yCDaLrS҆`ߖmu{w}~lօXNE|BF\Yb:Ic8JQ1Hesb8O[0Ki@[S.GD!JimGhkiqsSek`qERZ8L[0D[0CV/Dj;D{BDV-?F@a2=`2@[,:]-7h6@c2:d2;md)1??\HtTtU}aтkގlܒoޓt~奊簗䥄妌}ՓvmRW*>Y3M_h^MKHCLAXJYV\,CڭڢƖÕzƘ}ęęŘxww{xuvj}՞ݮ֞ѓԟצئԟџΐʑǏ꾌{qFZ+?].@W+?v@>C=<3QD`Kj`y`ыsՏuܔw|~ݘ{ޖu֎nłgYDR-<\4EX3N];Q]4IsCGg8Dg5?i:E`[]XPMNK_SVG]1Gڰҕk}f}gjx~}Ŕz}x}yxvwqfد~ףڨ֜՛ӞԗЗϓϑČw͇Ku:8Y+9R+>f5@`3BV)W+@PMNLR)=}DAW-=]2Cb0>^0=[-=a.:m=Aj5:m9Dj5:s;;NAPBmVzgԅh׆j֐uЉpܒuِqߜ|ޠߞ۠{ߥ⪉߰޻{QZU9NW1IY4H\5FoAM^4Bc7EJI\QRIUOLLZQICj:Dөcz^mWsfz]itnvŒww{urpzotoŒעӘҙϗҝѕϖʊ渇ΙtHCQ#7Q*=d2>u<He5@_-BY.?a.D^3DQK\-@Z+?c4B_/:a1Ae4Ad6Bu@Gu@Dg4Ai6CTI`OxYσe~_~_҄cȄmчi؍oۓvٔp֖yבrוyנ߯âɤūuW?U_;LfI)?R+D}N^b9MV/HlHTQgnBXN(C[}ob?[|]ksvOxytZ=Q^0Ax@Fh;HV2GTNX.=Y+Dm8Bc3=h5>UThMz_|_~a{`΄lЊqډf܊aِr׊j׉iאrڗy{㳍忝ĝƟȡ̪ΪwM-=M)>Q'9k:CIE~GILITQQI~EDMP֕g~gɏqjaqxctfiZfWg[j_sni_obiXlcj^ĊэȉЖҗИї٫|QFZ.Y0>_3HvG!;j9PiyK[L%>S)Kw\qTmfkmj~c4Eg7CCBa3CS&U';f6?_3GX-Bg9Ci=GKJk6Aa0EyDFc7@PKfVtWvZ`ρaʂeڊh؍lܓuٍnوlْtەxݟ᫄崌鿙徚žɠ̦ͪҮֵya6=e9G{GLyGHQG{CCk4:zmЕu͒sȔywmw}{r{kxmnaqdZUt`ƂYbRVPĆҘВ֜қ͖؛jszUgm?RlE[c<[ikoM&F`9UkEbb@\yX}k|K#CP*Id2GR.FN)BOJf3Bd9KR1Fb2@g=Ib1>]4Ii4At?FcI`0>WRo\qWф^~]{d֋o܆aَi،n؆dىgڑlܜ{䧃⭉嵐溘弗澘şɢͣϫӱ׷_6MtAIsBC~JFw>@\(=Ȏ{ΔuϚyė}zswxxpu|pxpyqnfyVȄXj[ʈ\˓՞Ԡ֠ˉ뿃gOW*>PGYLXKRLgW_N\S\Iut{ZNa,9PB҉hpxwostuiE Ewg{_z^x`׈k܍i׈lێmڊfݍgڏlݕwxݟ}⩇~孂䱍渌뻑뿑Ɲ̦Τӷֺؽfi}C>r;;~FAHHP(C٪ˑpœvȖtrtnzwuuonoyizYȆYuNިuӟ՚ԗ՜ňןiB?zDG^N_SZLjUz`MQL`UsEQ~tna.9SC׌`z뱀~wj݌Zy~g6>P(@P&;b6AV,8W0Bk8FS.BQ*Gc{sJbK(A\6@O&BY;X|VfQ.HnFalJpxu}j<;a8[ͺM&8M$7w@Eh8Ab0@S)@^2E~MO_0Q1G^1C[/Jp^:LX&3J!=aP-GoEeanMd{XhDeolp{D#@H%q;@~DFa-h{W{sMpalnuVxa~c3K]3OszN+EP&9}CAOEc4AU.@Y3GvACb.:_2?l6>`NpIZG`,;bSqOف\؀bۇ_܅_܇eݑm܋eݐkݒkiޘtuݜy}㬄届沉溗꽐ĚʨдҴ־߻k:;e/9^,7a+7՚rËjɖxʑlǔwl{rvtuqzhyfːls{ϗ٥֚Ә~͊OXQ`MVOfToVmZ^NYNgYkdi_R):a3F«{O&;G<ٌ`xs}vjߋa~{M)Ce7MX-Cc:Jb;HV.C]7LS-JZnbxH"=qJT]/DQ%;[7RaP%:iCO_6GY*ԏiƔyȓxrsƑspsmmn|syezcܩvԛՠΑ՜١ԙȁُX]I\K_PfOsXu\ZNZLk[dW`X_^G3U%:zȭ}[)3z88هWw||x}pۉYrV.Ie>LN$9T*9[,?]3JR-Hyl>Ie7IK'@S*@vJ\bf5@c05f2@o;Dj?Id09_-=v=BrQ^|^[DyCAiXzP׃g܈gވiߊcډdۇ`݌f߅^݌hݐnڝ~rߜxwߡ᧊㯎䳍帎彝åɬϱϴӻھ߼scF0kYϋdϟzȕurÏnqqptnmrzhw[꾆١ԗѕ֠ؤҐ}uK_HXE_LlWoPcQ^P`Pg[khaZVVJ!4U(>|ªh4:|>BڈZr{ypvrؑlsg?PU-BQ-CU,9[)9V,JwReO1SoxSeZ/BW.?d:HP(ՃWx~~}kیb~xNXW)=\8IV*=_7FV1DQ/AZ4G\muFYS,>mKY[6GV-A_8OU1?V-Hqd>WL*IknU(;V+0L':\39j;=`.9f8DmՃZmxutzpօ`mrk8EfpH^W,KnFVB!;g@]`zvpU/GO&9m6m@LvLPq?E}bi7?c2Y\wGI}>?҃^n~讁곃fڒkÇ|vGRd=NW.BO)EY4Peq]5ET,CkCWc9M\0?X/AL(?{WxX->a=VzUq[6SbV;L|frkDhrmW-=L#8tBFc6>s>Ei4QkCVc:Qc?Te8LW3Hc8OY2Gy]xgCi^>Uz`xh<[hHo}H$8j:@S(Y2DR+<\6IoJ_rGXZk;DR'5`09Z'5Z,:_05k7?SGnKvS}]xXi7IWKӂ[ڈeهdݐuߋggݐqߍdhi݊_ۉ`݊`ލbߐeߕoߕquޛq~ᩃ᫆⮅縒佛ɮɭռտӼڹͅU[GVHWGcMp[w`xpnupǎnӜfђ^ˇV͈XÑۣՒaxNfJSGUGfOMBTIlf`WbZYXkh^YVUu>?N(:N#5^1CƱoju<=}Omwy{wmakkR]Q)@V*;[-=U+MV/Eg?SZ6Ke8F`6DX,AO$5Q(>X.?iRu~[\:TbnF]c;SjXrl>G^0X)8V(8g26KGeFxVsRvN]Ae9MeVWڈh؆_ސqݑnbފjdZhۈ^څ[ވ^ڌgފ]ݓlvޚvݚsߞpx੄~߱廘ƩϷжӸӸ۾ʏwSIaXF@GBQ@]M]QcTnbsfqʖ}ԢrɒiŇ_՘hђަېWjPS@MCZPSIMEaX`T_[_W`\jfa]~JGm59N%9E0^4Iȯ|mz=;uRn~y{tޓ`psYcM%?f;LQ0JP(AU/Ci>KU4Kc9HW3Gj@Mg:QgNAMFKCbZncUP[TZRf``^WWk;@k7@_/:nS);V.@]2E]4G_8MW2Jd;T[4Hi=Qf=I^/CjBSR+?X1@`S'4X)7h.8F?hKxNvU{U{6/g3>mYӃZ݋_߆`ڈhލaދ_aߎinސk_ߋcۅY݆[܊[ۅYۍeܒnەomޙnwzঃⴑ㳉世ĪǬ̳ϾԿپدNC`KhZfU^SQEIFp;Ae38Z+5U+6xBI߯Ƃ]}ӍωܖSRAs9;JFWLIGYSlh^N[Y\SYSli]ZxJIs>>g2<\VPK\`~ƳͷxBAsHy}}{qoXzKYR%7W0GgAPX0FR(<\2@X7Oc`5GsL]S)>I(Iksb}V0EW0?V+5R&6R%8U0?Z*?PEYHrNtUwPC6W'9XMӀY؄Wن[݊e܋f݆]]ifߓo\fۊ_ݍjڍh݈\ފc݊^ڎfߒekܘqݛy|ߥyߩ崏㺕ƭɳͻҾԻսٸeX^Mk[o\gZ_U]VGEtEM_/9O'=DDƋ́ݙ[yԏqP?m57{@>LCHHQPi_cWPOTJTJf`ttYWzIJr@Dk6>[VZRlj­ƷFAsSpttwlcN{jQ_Z1EU,C[3BV-=X+=Y5IW1DV0DR*=pGYX0Be=RU-CW0He9JN$8j?MZ6MhCVn@U^:Sh}wT/E`1>T)r0P!3WE~W~Vׄ^نc߉aӆeߎaދ\cݍdݏq݋_ޒo\ފcߋh݋^ݏh،iډ^da۔itޟ|ߣާ{㱒㶗㽠çȳ͹ѽѸٿԵWMj`m[dUaR\QUJyF@k:?`,9IL|{uƄgYCg3;j5=LFz?CNJbV^RROOOLFZWqrfaUWSRo:BrBKQMqnroŮȯPFqRoxq봂vvcSrm_3Eb9JT3GZ1C^6HV,@a8HQ)@X4LcF]iBQT,CrK[g=R\6GV/Gf}^8TnB^a:UoOfxl?S[4@p?HV+=R);X-;O)7S%,a1:MAhKiJeIO!,a-7cEtOxQ؄W؄Wۉ]܈Wۍkދa܊eތhލcߋaސifݑjߌecߌ\ޏbމ^ڋgݐiۑiܒeܙtޟwߤ}|ᧀ௑⸖你ŭͰϸҽԻծMBf^hYeUg\bUbWUUNJVO\K}՗}גZ]Lw@?m5;LGE@I@aVlcZX}KPNL[Wkgmj^^XXtDGwGIg6_3HoFXY/Dc;P`=QU0GyVrvP`O(~`hW3JjIhsNx\6GfE\O*FX/6Q)9Z.:\*4}B;Q=i29O&4j6>T@cGuSxW~U؃ZԁZ؆_܌^ۅ[ߒkގoߊaefߑdjjݒiߍb܌gފXۍe݌a݋\݌]ܓklޙrޡ|ृz⯋ඕ忢ìǭϸѽҿհRIZPeYl\g\g^dY^Ya]\SbZwƈؖTRHLFz>C~F>GBLKb^ph_WNMu>ALM`Xoeida`yDGp>Fb2:~W[]dz~Ưi_pJޛjv|}l΍oNVN'@S+@T1?a9Mo?Q\6J`6F[1Ha3IW/HuZsR/G]usJ^I)@aqM#2pLsx_:Xbuo~T2GQ*>V-?\1>Z)7X(6U'5l7>NCYDeMqSwQyRрU~T|QԂ\׆bڊgۈ[݈_݅Y݋dbߍ`݌gߒnkސgݎdލaތb܉[`ޑi܏dޒiouࣁ⩄ⱏ亘亥俣ū̳лؼyRJb[eUgZqccbf\t`lXnV{WxTUKPGUI[PPFFEaZga^TJF{IMwBHc^pnrqccZ`vGLq=Aq>A_0;d:DiXb=WvM(Fmew@8tI]U.?gGbysRhiCSL$6Z7ER&5a,/t95Ni8Aa3>`4:`1:g@H_hκ˰ƯrrYޚs}x}}wQZh?K]3IV*?O(6_4FjAOb8Pg?Ua@NO)@S+LnQ/DmF^sC_[>QhGdV0FgCf39}AjDkHrHyWuM{MҁZ}S|Q؃SـS؃XڂX܆\ވ[ކ[ۅ^W݊^߉[ސonjjݐiihjkmߐ`ߗlutvޟqyߦ~ⱈ೏以㾡ŮɴϸмһԳLGUQYKf^g\sgt\~_~buYqSoQ~WwPiS`^g][[SVMPNIMFbYzkysh`W[r??c1= 2: - self.id = i16(s) - if len(s) >= 4: - self.count = i16(s[2:4]) - if len(s) >= 6: - self.repair = i16(s[4:6]) - else: - self.repair = None - - if Image.DEBUG: - print "AFRM", self.id, self.count - - return s - - def chunk_ADEF(self, offset, bytes): - "ADEF -- store image" - - # assertions - if self.count != 0: - raise SyntaxError, "misplaced ADEF chunk" - - self.show = 0 - self.id = 0 - self.count = 1 - self.repair = None - - s = self.fp.read(bytes) - if len(s) >= 2: - self.id = i16(s) - if len(s) >= 4: - self.count = i16(s[2:4]) - - if Image.DEBUG: - print "ADEF", self.id, self.count - - return s - - def chunk_NAME(self, offset, bytes): - "NAME -- name the current image" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced NAME chunk" - - name = self.fp.read(bytes) - self.names[self.id] = name - - return name - - def chunk_AEND(self, offset, bytes): - "AEND -- end of animation" - - if Image.DEBUG: - print "AEND" - - self.eof = 1 - - raise EOFError, "end of ARG file" - - def __getmodesize(self, s, full=1): - - size = i32(s), i32(s[4:]) - - try: - mode, rawmode = _MODES[(ord(s[8]), ord(s[9]))] - except: - raise SyntaxError, "unknown image mode" - - if full: - if ord(s[12]): - pass # interlace not yet supported - if ord(s[11]): - raise SyntaxError, "unknown filter category" - - return size, mode, rawmode - - def chunk_PAST(self, offset, bytes): - "PAST -- paste one image into another" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced PAST chunk" - - if self.repair is not None: - # we must repair the target image before we - # start pasting - - # brute force; a better solution would be to - # update only the dirty rectangles in images[id]. - # note that if images[id] doesn't exist, it must - # be created - - self.images[self.id] = self.images[self.repair].copy() - self.repair = None - - s = self.fp.read(bytes) - im = self.images[i16(s)] - x, y = i32(s[2:6]), i32(s[6:10]) - bbox = x, y, im.size[0]+x, im.size[1]+y - - if im.mode in ["RGBA"]: - # paste with transparency - # FIXME: should handle P+transparency as well - self.images[self.id].paste(im, bbox, im) - else: - # paste without transparency - self.images[self.id].paste(im, bbox) - - self.action = ("PAST",) - self.__store() - - return s - - def chunk_BLNK(self, offset, bytes): - "BLNK -- create blank image" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced BLNK chunk" - - s = self.fp.read(bytes) - size, mode, rawmode = self.__getmodesize(s, 0) - - # store image (FIXME: handle colour) - self.action = ("BLNK",) - self.im = Image.core.fill(mode, size, 0) - self.__store() - - return s - - def chunk_IHDR(self, offset, bytes): - "IHDR -- full image follows" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced IHDR chunk" - - # image header - s = self.fp.read(bytes) - size, mode, rawmode = self.__getmodesize(s) - - # decode and store image - self.action = ("IHDR",) - self.im = Image.core.new(mode, size) - self.decoder = Image.core.zip_decoder(rawmode) - self.decoder.setimage(self.im, (0,0) + size) - self.data = "" - - return s - - def chunk_DHDR(self, offset, bytes): - "DHDR -- delta image follows" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced DHDR chunk" - - s = self.fp.read(bytes) - - size, mode, rawmode = self.__getmodesize(s) - - # delta header - diff = ord(s[13]) - offs = i32(s[14:18]), i32(s[18:22]) - - bbox = offs + (offs[0]+size[0], offs[1]+size[1]) - - if Image.DEBUG: - print "DHDR", diff, bbox - - # FIXME: decode and apply image - self.action = ("DHDR", diff, bbox) - - # setup decoder - self.im = Image.core.new(mode, size) - - self.decoder = Image.core.zip_decoder(rawmode) - self.decoder.setimage(self.im, (0,0) + size) - - self.data = "" - - return s - - def chunk_JHDR(self, offset, bytes): - "JHDR -- JPEG image follows" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced JHDR chunk" - - # image header - s = self.fp.read(bytes) - size, mode, rawmode = self.__getmodesize(s, 0) - - # decode and store image - self.action = ("JHDR",) - self.im = Image.core.new(mode, size) - self.decoder = Image.core.jpeg_decoder(rawmode) - self.decoder.setimage(self.im, (0,0) + size) - self.data = "" - - return s - - def chunk_UHDR(self, offset, bytes): - "UHDR -- uncompressed image data follows (EXPERIMENTAL)" - - # assertions - if self.count == 0: - raise SyntaxError, "misplaced UHDR chunk" - - # image header - s = self.fp.read(bytes) - size, mode, rawmode = self.__getmodesize(s, 0) - - # decode and store image - self.action = ("UHDR",) - self.im = Image.core.new(mode, size) - self.decoder = Image.core.raw_decoder(rawmode) - self.decoder.setimage(self.im, (0,0) + size) - self.data = "" - - return s - - def chunk_IDAT(self, offset, bytes): - "IDAT -- image data block" - - # pass compressed chunks through the decoder - s = self.fp.read(bytes) - self.data = self.data + s - n, e = self.decoder.decode(self.data) - if n < 0: - # end of image - if e < 0: - raise IOError, "decoder error %d" % e - else: - self.data = self.data[n:] - - return s - - def chunk_DEND(self, offset, bytes): - return self.chunk_IEND(offset, bytes) - - def chunk_JEND(self, offset, bytes): - return self.chunk_IEND(offset, bytes) - - def chunk_UEND(self, offset, bytes): - return self.chunk_IEND(offset, bytes) - - def chunk_IEND(self, offset, bytes): - "IEND -- end of image" - - # we now have a new image. carry out the operation - # defined by the image header. - - # won't need these anymore - del self.decoder - del self.data - - self.__store() - - return self.fp.read(bytes) - - def __store(self): - - # apply operation - cid = self.action[0] - - if cid in ["BLNK", "IHDR", "JHDR", "UHDR"]: - # store - self.images[self.id] = self.im - - elif cid == "DHDR": - # paste - cid, mode, bbox = self.action - im0 = self.images[self.id] - im1 = self.im - if mode == 0: - im1 = im1.chop_add_modulo(im0.crop(bbox)) - im0.paste(im1, bbox) - - self.count = self.count - 1 - - if self.count == 0 and self.show: - self.im = self.images[self.id] - raise EOFError # end of this frame - - def chunk_PLTE(self, offset, bytes): - "PLTE -- palette data" - - s = self.fp.read(bytes) - if self.mode == "P": - self.palette = ImagePalette.raw("RGB", s) - return s - - def chunk_sYNC(self, offset, bytes): - "SYNC -- reset decoder" - - if self.count != 0: - raise SyntaxError, "misplaced sYNC chunk" - - s = self.fp.read(bytes) - self.__reset() - return s - - -# -------------------------------------------------------------------- -# ARG reader - -def _accept(prefix): - return prefix[:8] == MAGIC - -## -# Image plugin for the experimental Animated Raster Graphics format. - -class ArgImageFile(ImageFile.ImageFile): - - format = "ARG" - format_description = "Animated raster graphics" - - def _open(self): - - if Image.warnings: - Image.warnings.warn( - "The ArgImagePlugin driver is obsolete, and will be removed " - "from a future release of PIL. If you rely on this module, " - "please contact the PIL authors.", - RuntimeWarning - ) - - if self.fp.read(8) != MAGIC: - raise SyntaxError, "not an ARG file" - - self.arg = ArgStream(self.fp) - - # read and process the first chunk (AHDR) - - cid, offset, bytes = self.arg.read() - - if cid != "AHDR": - raise SyntaxError, "expected an AHDR chunk" - - s = self.arg.call(cid, offset, bytes) - - self.arg.crc(cid, s) - - # image characteristics - self.mode = self.arg.mode - self.size = self.arg.size - - def load(self): - - if self.arg.im is None: - self.seek(0) - - # image data - self.im = self.arg.im - self.palette = self.arg.palette - - # set things up for further processing - Image.Image.load(self) - - def seek(self, frame): - - if self.arg.eof: - raise EOFError, "end of animation" - - self.fp = self.arg.fp - - while 1: - - # - # process chunks - - cid, offset, bytes = self.arg.read() - - if self.arg.eof: - raise EOFError, "end of animation" - - try: - s = self.arg.call(cid, offset, bytes) - except EOFError: - break - - except "glurk": # AttributeError - if Image.DEBUG: - print cid, bytes, "(unknown)" - s = self.fp.read(bytes) - - self.arg.crc(cid, s) - - self.fp.read(4) # ship extra CRC - - def tell(self): - return 0 - - def verify(self): - "Verify ARG file" - - # back up to first chunk - self.fp.seek(8) - - self.arg.verify(self) - self.arg.close() - - self.fp = None - -# -# -------------------------------------------------------------------- - -Image.register_open("ARG", ArgImageFile, _accept) - -Image.register_extension("ARG", ".arg") - -Image.register_mime("ARG", "video/x-arg") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py deleted file mode 100755 index 47b5f05c84a..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BdfFontFile.py +++ /dev/null @@ -1,133 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# bitmap distribution font (bdf) file parser -# -# history: -# 1996-05-16 fl created (as bdf2pil) -# 1997-08-25 fl converted to FontFile driver -# 2001-05-25 fl removed bogus __init__ call -# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev) -# 2003-04-22 fl more robustification (from Graham Dumpleton) -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1997-2003 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -import Image -import FontFile - -import string - -# -------------------------------------------------------------------- -# parse X Bitmap Distribution Format (BDF) -# -------------------------------------------------------------------- - -bdf_slant = { - "R": "Roman", - "I": "Italic", - "O": "Oblique", - "RI": "Reverse Italic", - "RO": "Reverse Oblique", - "OT": "Other" -} - -bdf_spacing = { - "P": "Proportional", - "M": "Monospaced", - "C": "Cell" -} - -def bdf_char(f): - - # skip to STARTCHAR - while 1: - s = f.readline() - if not s: - return None - if s[:9] == "STARTCHAR": - break - id = string.strip(s[9:]) - - # load symbol properties - props = {} - while 1: - s = f.readline() - if not s or s[:6] == "BITMAP": - break - i = string.find(s, " ") - props[s[:i]] = s[i+1:-1] - - # load bitmap - bitmap = [] - while 1: - s = f.readline() - if not s or s[:7] == "ENDCHAR": - break - bitmap.append(s[:-1]) - bitmap = string.join(bitmap, "") - - [x, y, l, d] = map(int, string.split(props["BBX"])) - [dx, dy] = map(int, string.split(props["DWIDTH"])) - - bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y) - - try: - im = Image.fromstring("1", (x, y), bitmap, "hex", "1") - except ValueError: - # deal with zero-width characters - im = Image.new("1", (x, y)) - - return id, int(props["ENCODING"]), bbox, im - -## -# Font file plugin for the X11 BDF format. - -class BdfFontFile(FontFile.FontFile): - - def __init__(self, fp): - - FontFile.FontFile.__init__(self) - - s = fp.readline() - if s[:13] != "STARTFONT 2.1": - raise SyntaxError, "not a valid BDF file" - - props = {} - comments = [] - - while 1: - s = fp.readline() - if not s or s[:13] == "ENDPROPERTIES": - break - i = string.find(s, " ") - props[s[:i]] = s[i+1:-1] - if s[:i] in ["COMMENT", "COPYRIGHT"]: - if string.find(s, "LogicalFontDescription") < 0: - comments.append(s[i+1:-1]) - - font = string.split(props["FONT"], "-") - - font[4] = bdf_slant[string.upper(font[4])] - font[11] = bdf_spacing[string.upper(font[11])] - - ascent = int(props["FONT_ASCENT"]) - descent = int(props["FONT_DESCENT"]) - - fontname = string.join(font[1:], ";") - - # print "#", fontname - # for i in comments: - # print "#", i - - font = [] - while 1: - c = bdf_char(fp) - if not c: - break - id, ch, (xy, dst, src), im = c - if ch >= 0 and ch < len(self.glyph): - self.glyph[ch] = xy, dst, src, im diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py deleted file mode 100755 index 09c0a2141d3..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BmpImagePlugin.py +++ /dev/null @@ -1,251 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# BMP file handler -# -# Windows (and OS/2) native bitmap storage format. -# -# history: -# 1995-09-01 fl Created -# 1996-04-30 fl Added save -# 1997-08-27 fl Fixed save of 1-bit images -# 1998-03-06 fl Load P images as L where possible -# 1998-07-03 fl Load P images as 1 where possible -# 1998-12-29 fl Handle small palettes -# 2002-12-30 fl Fixed load of 1-bit palette images -# 2003-04-21 fl Fixed load of 1-bit monochrome images -# 2003-04-23 fl Added limited support for BI_BITFIELDS compression -# -# Copyright (c) 1997-2003 by Secret Labs AB -# Copyright (c) 1995-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.7" - - -import string -import Image, ImageFile, ImagePalette - - -# -# -------------------------------------------------------------------- -# Read BMP file - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - - -BIT2MODE = { - # bits => mode, rawmode - 1: ("P", "P;1"), - 4: ("P", "P;4"), - 8: ("P", "P"), - 16: ("RGB", "BGR;15"), - 24: ("RGB", "BGR"), - 32: ("RGB", "BGRX") -} - -def _accept(prefix): - return prefix[:2] == "BM" - -## -# Image plugin for the Windows BMP format. - -class BmpImageFile(ImageFile.ImageFile): - - format = "BMP" - format_description = "Windows Bitmap" - - def _bitmap(self, header = 0, offset = 0): - - if header: - self.fp.seek(header) - - read = self.fp.read - - # CORE/INFO - s = read(4) - s = s + ImageFile._safe_read(self.fp, i32(s)-4) - - if len(s) == 12: - - # OS/2 1.0 CORE - bits = i16(s[10:]) - self.size = i16(s[4:]), i16(s[6:]) - compression = 0 - lutsize = 3 - colors = 0 - direction = -1 - - elif len(s) in [40, 64]: - - # WIN 3.1 or OS/2 2.0 INFO - bits = i16(s[14:]) - self.size = i32(s[4:]), i32(s[8:]) - compression = i32(s[16:]) - lutsize = 4 - colors = i32(s[32:]) - direction = -1 - if s[11] == '\xff': - # upside-down storage - self.size = self.size[0], 2**32 - self.size[1] - direction = 0 - - else: - raise IOError("Unsupported BMP header type (%d)" % len(s)) - - if not colors: - colors = 1 << bits - - # MODE - try: - self.mode, rawmode = BIT2MODE[bits] - except KeyError: - raise IOError("Unsupported BMP pixel depth (%d)" % bits) - - if compression == 3: - # BI_BITFIELDS compression - mask = i32(read(4)), i32(read(4)), i32(read(4)) - if bits == 32 and mask == (0xff0000, 0x00ff00, 0x0000ff): - rawmode = "BGRX" - elif bits == 16 and mask == (0x00f800, 0x0007e0, 0x00001f): - rawmode = "BGR;16" - elif bits == 16 and mask == (0x007c00, 0x0003e0, 0x00001f): - rawmode = "BGR;15" - else: - # print bits, map(hex, mask) - raise IOError("Unsupported BMP bitfields layout") - elif compression != 0: - raise IOError("Unsupported BMP compression (%d)" % compression) - - # LUT - if self.mode == "P": - palette = [] - greyscale = 1 - if colors == 2: - indices = (0, 255) - else: - indices = range(colors) - for i in indices: - rgb = read(lutsize)[:3] - if rgb != chr(i)*3: - greyscale = 0 - palette.append(rgb) - if greyscale: - if colors == 2: - self.mode = rawmode = "1" - else: - self.mode = rawmode = "L" - else: - self.mode = "P" - self.palette = ImagePalette.raw( - "BGR", string.join(palette, "") - ) - - if not offset: - offset = self.fp.tell() - - self.tile = [("raw", - (0, 0) + self.size, - offset, - (rawmode, ((self.size[0]*bits+31)>>3)&(~3), direction))] - - self.info["compression"] = compression - - def _open(self): - - # HEAD - s = self.fp.read(14) - if s[:2] != "BM": - raise SyntaxError("Not a BMP file") - offset = i32(s[10:]) - - self._bitmap(offset=offset) - - -class DibImageFile(BmpImageFile): - - format = "DIB" - format_description = "Windows Bitmap" - - def _open(self): - self._bitmap() - -# -# -------------------------------------------------------------------- -# Write BMP file - -def o16(i): - return chr(i&255) + chr(i>>8&255) - -def o32(i): - return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) - -SAVE = { - "1": ("1", 1, 2), - "L": ("L", 8, 256), - "P": ("P", 8, 256), - "RGB": ("BGR", 24, 0), -} - -def _save(im, fp, filename, check=0): - - try: - rawmode, bits, colors = SAVE[im.mode] - except KeyError: - raise IOError("cannot write mode %s as BMP" % im.mode) - - if check: - return check - - stride = ((im.size[0]*bits+7)/8+3)&(~3) - header = 40 # or 64 for OS/2 version 2 - offset = 14 + header + colors * 4 - image = stride * im.size[1] - - # bitmap header - fp.write("BM" + # file type (magic) - o32(offset+image) + # file size - o32(0) + # reserved - o32(offset)) # image data offset - - # bitmap info header - fp.write(o32(header) + # info header size - o32(im.size[0]) + # width - o32(im.size[1]) + # height - o16(1) + # planes - o16(bits) + # depth - o32(0) + # compression (0=uncompressed) - o32(image) + # size of bitmap - o32(1) + o32(1) + # resolution - o32(colors) + # colors used - o32(colors)) # colors important - - fp.write("\000" * (header - 40)) # padding (for OS/2 format) - - if im.mode == "1": - for i in (0, 255): - fp.write(chr(i) * 4) - elif im.mode == "L": - for i in range(256): - fp.write(chr(i) * 4) - elif im.mode == "P": - fp.write(im.im.getpalette("RGB", "BGRX")) - - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))]) - -# -# -------------------------------------------------------------------- -# Registry - -Image.register_open(BmpImageFile.format, BmpImageFile, _accept) -Image.register_save(BmpImageFile.format, _save) - -Image.register_extension(BmpImageFile.format, ".bmp") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py deleted file mode 100755 index 4b111b393ab..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/BufrStubImagePlugin.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# BUFR stub adapter -# -# Copyright (c) 1996-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFile - -_handler = None - -## -# Install application-specific BUFR image handler. -# -# @param handler Handler object. - -def register_handler(handler): - global _handler - _handler = handler - -# -------------------------------------------------------------------- -# Image adapter - -def _accept(prefix): - return prefix[:4] == "BUFR" or prefix[:4] == "ZCZC" - -class BufrStubImageFile(ImageFile.StubImageFile): - - format = "BUFR" - format_description = "BUFR" - - def _open(self): - - offset = self.fp.tell() - - if not _accept(self.fp.read(8)): - raise SyntaxError("Not a BUFR file") - - self.fp.seek(offset) - - # make something up - self.mode = "F" - self.size = 1, 1 - - loader = self._load() - if loader: - loader.open(self) - - def _load(self): - return _handler - -def _save(im, fp, filename): - if _handler is None or not hasattr("_handler", "save"): - raise IOError("BUFR save handler not installed") - _handler.save(im, fp, filename) - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept) -Image.register_save(BufrStubImageFile.format, _save) - -Image.register_extension(BufrStubImageFile.format, ".bufr") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py deleted file mode 100755 index dff50e6bfda..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ContainerIO.py +++ /dev/null @@ -1,116 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# a class to read from a container file -# -# History: -# 1995-06-18 fl Created -# 1995-09-07 fl Added readline(), readlines() -# -# Copyright (c) 1997-2001 by Secret Labs AB -# Copyright (c) 1995 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -## -# A file object that provides read access to a part of an existing -# file (for example a TAR file). - -class ContainerIO: - - ## - # Create file object. - # - # @param file Existing file. - # @param offset Start of region, in bytes. - # @param length Size of region, in bytes. - - def __init__(self, file, offset, length): - self.fh = file - self.pos = 0 - self.offset = offset - self.length = length - self.fh.seek(offset) - - ## - # Always false. - - def isatty(self): - return 0 - - ## - # Move file pointer. - # - # @param offset Offset in bytes. - # @param mode Starting position. Use 0 for beginning of region, 1 - # for current offset, and 2 for end of region. You cannot move - # the pointer outside the defined region. - - def seek(self, offset, mode = 0): - if mode == 1: - self.pos = self.pos + offset - elif mode == 2: - self.pos = self.length + offset - else: - self.pos = offset - # clamp - self.pos = max(0, min(self.pos, self.length)) - self.fh.seek(self.offset + self.pos) - - ## - # Get current file pointer. - # - # @return Offset from start of region, in bytes. - - def tell(self): - return self.pos - - ## - # Read data. - # - # @def read(bytes=0) - # @param bytes Number of bytes to read. If omitted or zero, - # read until end of region. - # @return An 8-bit string. - - def read(self, n = 0): - if n: - n = min(n, self.length - self.pos) - else: - n = self.length - self.pos - if not n: # EOF - return "" - self.pos = self.pos + n - return self.fh.read(n) - - ## - # Read a line of text. - # - # @return An 8-bit string. - - def readline(self): - s = "" - while 1: - c = self.read(1) - if not c: - break - s = s + c - if c == "\n": - break - return s - - ## - # Read multiple lines of text. - # - # @return A list of 8-bit strings. - - def readlines(self): - l = [] - while 1: - s = self.readline() - if not s: - break - l.append(s) - return l diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py deleted file mode 100755 index 6a126e701c5..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/CurImagePlugin.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# Windows Cursor support for PIL -# -# notes: -# uses BmpImagePlugin.py to read the bitmap data. -# -# history: -# 96-05-27 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.1" - -import Image, BmpImagePlugin - - -# -# -------------------------------------------------------------------- - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - - -def _accept(prefix): - return prefix[:4] == "\0\0\2\0" - -## -# Image plugin for Windows Cursor files. - -class CurImageFile(BmpImagePlugin.BmpImageFile): - - format = "CUR" - format_description = "Windows Cursor" - - def _open(self): - - offset = self.fp.tell() - - # check magic - s = self.fp.read(6) - if not _accept(s): - raise SyntaxError, "not an CUR file" - - # pick the largest cursor in the file - m = "" - for i in range(i16(s[4:])): - s = self.fp.read(16) - if not m: - m = s - elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]): - m = s - #print "width", ord(s[0]) - #print "height", ord(s[1]) - #print "colors", ord(s[2]) - #print "reserved", ord(s[3]) - #print "hotspot x", i16(s[4:]) - #print "hotspot y", i16(s[6:]) - #print "bytes", i32(s[8:]) - #print "offset", i32(s[12:]) - - # load as bitmap - self._bitmap(i32(m[12:]) + offset) - - # patch up the bitmap height - self.size = self.size[0], self.size[1]/2 - d, e, o, a = self.tile[0] - self.tile[0] = d, (0,0)+self.size, o, a - - return - - -# -# -------------------------------------------------------------------- - -Image.register_open("CUR", CurImageFile, _accept) - -Image.register_extension("CUR", ".cur") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py deleted file mode 100755 index 32da7d831a6..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/DcxImagePlugin.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# DCX file handling -# -# DCX is a container file format defined by Intel, commonly used -# for fax applications. Each DCX file consists of a directory -# (a list of file offsets) followed by a set of (usually 1-bit) -# PCX files. -# -# History: -# 1995-09-09 fl Created -# 1996-03-20 fl Properly derived from PcxImageFile. -# 1998-07-15 fl Renamed offset attribute to avoid name clash -# 2002-07-30 fl Fixed file handling -# -# Copyright (c) 1997-98 by Secret Labs AB. -# Copyright (c) 1995-96 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.2" - -import Image - -from PcxImagePlugin import PcxImageFile - -MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then? - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - -def _accept(prefix): - return i32(prefix) == MAGIC - -## -# Image plugin for the Intel DCX format. - -class DcxImageFile(PcxImageFile): - - format = "DCX" - format_description = "Intel DCX" - - def _open(self): - - # Header - s = self.fp.read(4) - if i32(s) != MAGIC: - raise SyntaxError, "not a DCX file" - - # Component directory - self._offset = [] - for i in range(1024): - offset = i32(self.fp.read(4)) - if not offset: - break - self._offset.append(offset) - - self.__fp = self.fp - self.seek(0) - - def seek(self, frame): - if frame >= len(self._offset): - raise EOFError("attempt to seek outside DCX directory") - self.frame = frame - self.fp = self.__fp - self.fp.seek(self._offset[frame]) - PcxImageFile._open(self) - - def tell(self): - return self.frame - - -Image.register_open("DCX", DcxImageFile, _accept) - -Image.register_extension("DCX", ".dcx") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py deleted file mode 100755 index 1927b32276b..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/EpsImagePlugin.py +++ /dev/null @@ -1,349 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# EPS file handling -# -# History: -# 1995-09-01 fl Created (0.1) -# 1996-05-18 fl Don't choke on "atend" fields, Ghostscript interface (0.2) -# 1996-08-22 fl Don't choke on floating point BoundingBox values -# 1996-08-23 fl Handle files from Macintosh (0.3) -# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) -# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5) -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1995-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.5" - -import re, string -import Image, ImageFile - -# -# -------------------------------------------------------------------- - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - -def o32(i): - return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) - -split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$") -field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$") - -def Ghostscript(tile, size, fp): - """Render an image using Ghostscript (Unix only)""" - - # Unpack decoder tile - decoder, tile, offset, data = tile[0] - length, bbox = data - - import tempfile, os - - file = tempfile.mktemp() - - # Build ghostscript command - command = ["gs", - "-q", # quite mode - "-g%dx%d" % size, # set output geometry (pixels) - "-dNOPAUSE -dSAFER", # don't pause between pages, safe mode - "-sDEVICE=ppmraw", # ppm driver - "-sOutputFile=%s" % file,# output file - "- >/dev/null 2>/dev/null"] - - command = string.join(command) - - # push data through ghostscript - try: - gs = os.popen(command, "w") - # adjust for image origin - if bbox[0] != 0 or bbox[1] != 0: - gs.write("%d %d translate\n" % (-bbox[0], -bbox[1])) - fp.seek(offset) - while length > 0: - s = fp.read(8192) - if not s: - break - length = length - len(s) - gs.write(s) - status = gs.close() - if status: - raise IOError("gs failed (status %d)" % status) - im = Image.core.open_ppm(file) - finally: - try: os.unlink(file) - except: pass - - return im - - -class PSFile: - """Wrapper that treats either CR or LF as end of line.""" - def __init__(self, fp): - self.fp = fp - self.char = None - def __getattr__(self, id): - v = getattr(self.fp, id) - setattr(self, id, v) - return v - def seek(self, offset, whence=0): - self.char = None - self.fp.seek(offset, whence) - def tell(self): - pos = self.fp.tell() - if self.char: - pos = pos - 1 - return pos - def readline(self): - s = "" - if self.char: - c = self.char - self.char = None - else: - c = self.fp.read(1) - while c not in "\r\n": - s = s + c - c = self.fp.read(1) - if c == "\r": - self.char = self.fp.read(1) - if self.char == "\n": - self.char = None - return s + "\n" - - -def _accept(prefix): - return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5L - -## -# Image plugin for Encapsulated Postscript. This plugin supports only -# a few variants of this format. - -class EpsImageFile(ImageFile.ImageFile): - """EPS File Parser for the Python Imaging Library""" - - format = "EPS" - format_description = "Encapsulated Postscript" - - def _open(self): - - # FIXME: should check the first 512 bytes to see if this - # really is necessary (platform-dependent, though...) - - fp = PSFile(self.fp) - - # HEAD - s = fp.read(512) - if s[:4] == "%!PS": - offset = 0 - fp.seek(0, 2) - length = fp.tell() - elif i32(s) == 0xC6D3D0C5L: - offset = i32(s[4:]) - length = i32(s[8:]) - fp.seek(offset) - else: - raise SyntaxError, "not an EPS file" - - fp.seek(offset) - - box = None - - self.mode = "RGB" - self.size = 1, 1 # FIXME: huh? - - # - # Load EPS header - - s = fp.readline() - - while s: - - if len(s) > 255: - raise SyntaxError, "not an EPS file" - - if s[-2:] == '\r\n': - s = s[:-2] - elif s[-1:] == '\n': - s = s[:-1] - - try: - m = split.match(s) - except re.error, v: - raise SyntaxError, "not an EPS file" - - if m: - k, v = m.group(1, 2) - self.info[k] = v - if k == "BoundingBox": - try: - # Note: The DSC spec says that BoundingBox - # fields should be integers, but some drivers - # put floating point values there anyway. - box = map(int, map(float, string.split(v))) - self.size = box[2] - box[0], box[3] - box[1] - self.tile = [("eps", (0,0) + self.size, offset, - (length, box))] - except: - pass - - else: - - m = field.match(s) - - if m: - k = m.group(1) - if k == "EndComments": - break - if k[:8] == "PS-Adobe": - self.info[k[:8]] = k[9:] - else: - self.info[k] = "" - else: - raise IOError, "bad EPS header" - - s = fp.readline() - - if s[:1] != "%": - break - - - # - # Scan for an "ImageData" descriptor - - while s[0] == "%": - - if len(s) > 255: - raise SyntaxError, "not an EPS file" - - if s[-2:] == '\r\n': - s = s[:-2] - elif s[-1:] == '\n': - s = s[:-1] - - if s[:11] == "%ImageData:": - - [x, y, bi, mo, z3, z4, en, id] =\ - string.split(s[11:], maxsplit=7) - - x = int(x); y = int(y) - - bi = int(bi) - mo = int(mo) - - en = int(en) - - if en == 1: - decoder = "eps_binary" - elif en == 2: - decoder = "eps_hex" - else: - break - if bi != 8: - break - if mo == 1: - self.mode = "L" - elif mo == 2: - self.mode = "LAB" - elif mo == 3: - self.mode = "RGB" - else: - break - - if id[:1] == id[-1:] == '"': - id = id[1:-1] - - # Scan forward to the actual image data - while 1: - s = fp.readline() - if not s: - break - if s[:len(id)] == id: - self.size = x, y - self.tile2 = [(decoder, - (0, 0, x, y), - fp.tell(), - 0)] - return - - s = fp.readline() - if not s: - break - - if not box: - raise IOError, "cannot determine EPS bounding box" - - def load(self): - # Load EPS via Ghostscript - if not self.tile: - return - self.im = Ghostscript(self.tile, self.size, self.fp) - self.mode = self.im.mode - self.size = self.im.size - self.tile = [] - -# -# -------------------------------------------------------------------- - -def _save(im, fp, filename, eps=1): - """EPS Writer for the Python Imaging Library.""" - - # - # make sure image data is available - im.load() - - # - # determine postscript image mode - if im.mode == "L": - operator = (8, 1, "image") - elif im.mode == "RGB": - operator = (8, 3, "false 3 colorimage") - elif im.mode == "CMYK": - operator = (8, 4, "false 4 colorimage") - else: - raise ValueError, "image mode is not supported" - - if eps: - # - # write EPS header - fp.write("%!PS-Adobe-3.0 EPSF-3.0\n") - fp.write("%%Creator: PIL 0.1 EpsEncode\n") - #fp.write("%%CreationDate: %s"...) - fp.write("%%%%BoundingBox: 0 0 %d %d\n" % im.size) - fp.write("%%Pages: 1\n") - fp.write("%%EndComments\n") - fp.write("%%Page: 1 1\n") - fp.write("%%ImageData: %d %d " % im.size) - fp.write("%d %d 0 1 1 \"%s\"\n" % operator) - - # - # image header - fp.write("gsave\n") - fp.write("10 dict begin\n") - fp.write("/buf %d string def\n" % (im.size[0] * operator[1])) - fp.write("%d %d scale\n" % im.size) - fp.write("%d %d 8\n" % im.size) # <= bits - fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])) - fp.write("{ currentfile buf readhexstring pop } bind\n") - fp.write("%s\n" % operator[2]) - - ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)]) - - fp.write("\n%%%%EndBinary\n") - fp.write("grestore end\n") - fp.flush() - -# -# -------------------------------------------------------------------- - -Image.register_open(EpsImageFile.format, EpsImageFile, _accept) - -Image.register_save(EpsImageFile.format, _save) - -Image.register_extension(EpsImageFile.format, ".ps") -Image.register_extension(EpsImageFile.format, ".eps") - -Image.register_mime(EpsImageFile.format, "application/postscript") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py deleted file mode 100755 index b033aad35e8..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ExifTags.py +++ /dev/null @@ -1,157 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# EXIF tags -# -# Copyright (c) 2003 by Secret Labs AB -# -# See the README file for information on usage and redistribution. -# - -## -# This module provides constants and clear-text names for various -# well-known EXIF tags. -## - -## -# Maps EXIF tags to tag names. - -TAGS = { - - # possibly incomplete - 0x0100: "ImageWidth", - 0x0101: "ImageLength", - 0x0102: "BitsPerSample", - 0x0103: "Compression", - 0x0106: "PhotometricInterpretation", - 0x010e: "ImageDescription", - 0x010f: "Make", - 0x0110: "Model", - 0x0111: "StripOffsets", - 0x0112: "Orientation", - 0x0115: "SamplesPerPixel", - 0x0116: "RowsPerStrip", - 0x0117: "StripByteConunts", - 0x011a: "XResolution", - 0x011a: "XResolution", - 0x011b: "YResolution", - 0x011b: "YResolution", - 0x011c: "PlanarConfiguration", - 0x0128: "ResolutionUnit", - 0x0128: "ResolutionUnit", - 0x012d: "TransferFunction", - 0x0131: "Software", - 0x0132: "DateTime", - 0x013b: "Artist", - 0x013e: "WhitePoint", - 0x013f: "PrimaryChromaticities", - 0x0201: "JpegIFOffset", - 0x0202: "JpegIFByteCount", - 0x0211: "YCbCrCoefficients", - 0x0211: "YCbCrCoefficients", - 0x0212: "YCbCrSubSampling", - 0x0213: "YCbCrPositioning", - 0x0213: "YCbCrPositioning", - 0x0214: "ReferenceBlackWhite", - 0x0214: "ReferenceBlackWhite", - 0x1000: "RelatedImageFileFormat", - 0x1001: "RelatedImageLength", - 0x1001: "RelatedImageWidth", - 0x828d: "CFARepeatPatternDim", - 0x828e: "CFAPattern", - 0x828f: "BatteryLevel", - 0x8298: "Copyright", - 0x829a: "ExposureTime", - 0x829d: "FNumber", - 0x8769: "ExifOffset", - 0x8773: "InterColorProfile", - 0x8822: "ExposureProgram", - 0x8824: "SpectralSensitivity", - 0x8825: "GPSInfo", - 0x8827: "ISOSpeedRatings", - 0x8828: "OECF", - 0x8829: "Interlace", - 0x882a: "TimeZoneOffset", - 0x882b: "SelfTimerMode", - 0x9000: "ExifVersion", - 0x9003: "DateTimeOriginal", - 0x9004: "DateTimeDigitized", - 0x9101: "ComponentsConfiguration", - 0x9102: "CompressedBitsPerPixel", - 0x9201: "ShutterSpeedValue", - 0x9202: "ApertureValue", - 0x9203: "BrightnessValue", - 0x9204: "ExposureBiasValue", - 0x9205: "MaxApertureValue", - 0x9206: "SubjectDistance", - 0x9207: "MeteringMode", - 0x9208: "LightSource", - 0x9209: "Flash", - 0x920a: "FocalLength", - 0x920b: "FlashEnergy", - 0x920c: "SpatialFrequencyResponse", - 0x920d: "Noise", - 0x9211: "ImageNumber", - 0x9212: "SecurityClassification", - 0x9213: "ImageHistory", - 0x9214: "SubjectLocation", - 0x9215: "ExposureIndex", - 0x9216: "TIFF/EPStandardID", - 0x927c: "MakerNote", - 0x9286: "UserComment", - 0x9290: "SubsecTime", - 0x9291: "SubsecTimeOriginal", - 0x9292: "SubsecTimeDigitized", - 0xa000: "FlashPixVersion", - 0xa001: "ColorSpace", - 0xa002: "ExifImageWidth", - 0xa003: "ExifImageHeight", - 0xa004: "RelatedSoundFile", - 0xa005: "ExifInteroperabilityOffset", - 0xa20b: "FlashEnergy", - 0xa20c: "SpatialFrequencyResponse", - 0xa20e: "FocalPlaneXResolution", - 0xa20f: "FocalPlaneYResolution", - 0xa210: "FocalPlaneResolutionUnit", - 0xa214: "SubjectLocation", - 0xa215: "ExposureIndex", - 0xa217: "SensingMethod", - 0xa300: "FileSource", - 0xa301: "SceneType", - 0xa302: "CFAPattern", - -} - -## -# Maps EXIF GSP tags to tag names. - -GPSTAGS = { - 0: "GPSVersionID", - 1: "GPSLatitudeRef", - 2: "GPSLatitude", - 3: "GPSLongitudeRef", - 4: "GPSLongitude", - 5: "GPSAltitudeRef", - 6: "GPSAltitude", - 7: "GPSTimeStamp", - 8: "GPSSatellites", - 9: "GPSStatus", - 10: "GPSMeasureMode", - 11: "GPSDOP", - 12: "GPSSpeedRef", - 13: "GPSSpeed", - 14: "GPSTrackRef", - 15: "GPSTrack", - 16: "GPSImgDirectionRef", - 17: "GPSImgDirection", - 18: "GPSMapDatum", - 19: "GPSDestLatitudeRef", - 20: "GPSDestLatitude", - 21: "GPSDestLongitudeRef", - 22: "GPSDestLongitude", - 23: "GPSDestBearingRef", - 24: "GPSDestBearing", - 25: "GPSDestDistanceRef", - 26: "GPSDestDistance" -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py deleted file mode 100755 index ac8be80a908..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FitsStubImagePlugin.py +++ /dev/null @@ -1,73 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# FITS stub adapter -# -# Copyright (c) 1998-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFile - -_handler = None - -## -# Install application-specific FITS image handler. -# -# @param handler Handler object. - -def register_handler(handler): - global _handler - _handler = handler - -# -------------------------------------------------------------------- -# Image adapter - -def _accept(prefix): - return prefix[:6] == "SIMPLE" - -class FITSStubImageFile(ImageFile.StubImageFile): - - format = "FITS" - format_description = "FITS" - - def _open(self): - - offset = self.fp.tell() - - if not _accept(self.fp.read(6)): - raise SyntaxError("Not a FITS file") - - # FIXME: add more sanity checks here; mandatory header items - # include SIMPLE, BITPIX, NAXIS, etc. - - self.fp.seek(offset) - - # make something up - self.mode = "F" - self.size = 1, 1 - - loader = self._load() - if loader: - loader.open(self) - - def _load(self): - return _handler - - -def _save(im, fp, filename): - if _handler is None or not hasattr("_handler", "save"): - raise IOError("FITS save handler not installed") - _handler.save(im, fp, filename) - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open(FITSStubImageFile.format, FITSStubImageFile, _accept) -Image.register_save(FITSStubImageFile.format, _save) - -Image.register_extension(FITSStubImageFile.format, ".fit") -Image.register_extension(FITSStubImageFile.format, ".fits") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py deleted file mode 100755 index 706c36a7f68..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FliImagePlugin.py +++ /dev/null @@ -1,142 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# FLI/FLC file handling. -# -# History: -# 95-09-01 fl Created -# 97-01-03 fl Fixed parser, setup decoder tile -# 98-07-15 fl Renamed offset attribute to avoid name clash -# -# Copyright (c) Secret Labs AB 1997-98. -# Copyright (c) Fredrik Lundh 1995-97. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.2" - -import Image, ImageFile, ImagePalette -import string - - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - -# -# decoder - -def _accept(prefix): - return i16(prefix[4:6]) in [0xAF11, 0xAF12] - -## -# Image plugin for the FLI/FLC animation format. Use the seek -# method to load individual frames. - -class FliImageFile(ImageFile.ImageFile): - - format = "FLI" - format_description = "Autodesk FLI/FLC Animation" - - def _open(self): - - # HEAD - s = self.fp.read(128) - magic = i16(s[4:6]) - if magic not in [0xAF11, 0xAF12]: - raise SyntaxError, "not an FLI/FLC file" - - # image characteristics - self.mode = "P" - self.size = i16(s[8:10]), i16(s[10:12]) - - # animation speed - duration = i32(s[16:20]) - if magic == 0xAF11: - duration = (duration * 1000) / 70 - self.info["duration"] = duration - - # look for palette - palette = map(lambda a: (a,a,a), range(256)) - - s = self.fp.read(16) - - self.__offset = 128 - - if i16(s[4:6]) == 0xF100: - # prefix chunk; ignore it - self.__offset = self.__offset + i32(s) - s = self.fp.read(16) - - if i16(s[4:6]) == 0xF1FA: - # look for palette chunk - s = self.fp.read(6) - if i16(s[4:6]) == 11: - self._palette(palette, 2) - elif i16(s[4:6]) == 4: - self._palette(palette, 0) - - palette = map(lambda (r,g,b): chr(r)+chr(g)+chr(b), palette) - self.palette = ImagePalette.raw("RGB", string.join(palette, "")) - - # set things up to decode first frame - self.frame = -1 - self.__fp = self.fp - - self.seek(0) - - def _palette(self, palette, shift): - # load palette - - i = 0 - for e in range(i16(self.fp.read(2))): - s = self.fp.read(2) - i = i + ord(s[0]) - n = ord(s[1]) - if n == 0: - n = 256 - s = self.fp.read(n * 3) - for n in range(0, len(s), 3): - r = ord(s[n]) << shift - g = ord(s[n+1]) << shift - b = ord(s[n+2]) << shift - palette[i] = (r, g, b) - i = i + 1 - - def seek(self, frame): - - if frame != self.frame + 1: - raise ValueError, "cannot seek to frame %d" % frame - self.frame = frame - - # move to next frame - self.fp = self.__fp - self.fp.seek(self.__offset) - - s = self.fp.read(4) - if not s: - raise EOFError - - framesize = i32(s) - - self.decodermaxblock = framesize - self.tile = [("fli", (0,0)+self.size, self.__offset, None)] - - self.__offset = self.__offset + framesize - - def tell(self): - - return self.frame - -# -# registry - -Image.register_open("FLI", FliImageFile, _accept) - -Image.register_extension("FLI", ".fli") -Image.register_extension("FLI", ".flc") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py deleted file mode 100755 index d9d8eb38a69..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FontFile.py +++ /dev/null @@ -1,146 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# base class for raster font file parsers -# -# history: -# 1997-06-05 fl created -# 1997-08-19 fl restrict image width -# -# Copyright (c) 1997-1998 by Secret Labs AB -# Copyright (c) 1997-1998 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import os -import Image - -import marshal - -try: - import zlib -except ImportError: - zlib = None - -WIDTH = 800 - -def puti16(fp, values): - # write network order (big-endian) 16-bit sequence - for v in values: - if v < 0: - v = v + 65536 - fp.write(chr(v>>8&255) + chr(v&255)) - -## -# Base class for raster font file handlers. - -class FontFile: - - bitmap = None - - def __init__(self): - - self.info = {} - self.glyph = [None] * 256 - - def __getitem__(self, ix): - return self.glyph[ix] - - def compile(self): - "Create metrics and bitmap" - - if self.bitmap: - return - - # create bitmap large enough to hold all data - h = w = maxwidth = 0 - lines = 1 - for glyph in self: - if glyph: - d, dst, src, im = glyph - h = max(h, src[3] - src[1]) - w = w + (src[2] - src[0]) - if w > WIDTH: - lines = lines + 1 - w = (src[2] - src[0]) - maxwidth = max(maxwidth, w) - - xsize = maxwidth - ysize = lines * h - - if xsize == 0 and ysize == 0: - return "" - - self.ysize = h - - # paste glyphs into bitmap - self.bitmap = Image.new("1", (xsize, ysize)) - self.metrics = [None] * 256 - x = y = 0 - for i in range(256): - glyph = self[i] - if glyph: - d, dst, src, im = glyph - xx, yy = src[2] - src[0], src[3] - src[1] - x0, y0 = x, y - x = x + xx - if x > WIDTH: - x, y = 0, y + h - x0, y0 = x, y - x = xx - s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0 - self.bitmap.paste(im.crop(src), s) - # print chr(i), dst, s - self.metrics[i] = d, dst, s - - - def save1(self, filename): - "Save font in version 1 format" - - self.compile() - - # font data - self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG") - - # font metrics - fp = open(os.path.splitext(filename)[0] + ".pil", "wb") - fp.write("PILfont\n") - fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!! - fp.write("DATA\n") - for id in range(256): - m = self.metrics[id] - if not m: - puti16(fp, [0] * 10) - else: - puti16(fp, m[0] + m[1] + m[2]) - fp.close() - - - def save2(self, filename): - "Save font in version 2 format" - - # THIS IS WORK IN PROGRESS - - self.compile() - - data = marshal.dumps((self.metrics, self.info)) - - if zlib: - data = "z" + zlib.compress(data, 9) - else: - data = "u" + data - - fp = open(os.path.splitext(filename)[0] + ".pil", "wb") - - fp.write("PILfont2\n" + self.name + "\n" + "DATA\n") - - fp.write(data) - - self.bitmap.save(fp, "PNG") - - fp.close() - - - save = save1 # for now diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py deleted file mode 100755 index b78fe8c70e9..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/FpxImagePlugin.py +++ /dev/null @@ -1,224 +0,0 @@ -# -# THIS IS WORK IN PROGRESS -# -# The Python Imaging Library. -# $Id$ -# -# FlashPix support for PIL -# -# History: -# 97-01-25 fl Created (reads uncompressed RGB images only) -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.1" - - -import Image, ImageFile -from OleFileIO import * - - -# we map from colour field tuples to (mode, rawmode) descriptors -MODES = { - # opacity - (0x00007ffe): ("A", "L"), - # monochrome - (0x00010000,): ("L", "L"), - (0x00018000, 0x00017ffe): ("RGBA", "LA"), - # photo YCC - (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"), - (0x00028000, 0x00028001, 0x00028002, 0x00027ffe): ("RGBA", "YCCA;P"), - # standard RGB (NIFRGB) - (0x00030000, 0x00030001, 0x00030002): ("RGB","RGB"), - (0x00038000, 0x00038001, 0x00038002, 0x00037ffe): ("RGBA","RGBA"), -} - -# -# -------------------------------------------------------------------- - -def _accept(prefix): - return prefix[:8] == MAGIC - -## -# Image plugin for the FlashPix images. - -class FpxImageFile(ImageFile.ImageFile): - - format = "FPX" - format_description = "FlashPix" - - def _open(self): - # - # read the OLE directory and see if this is a likely - # to be a FlashPix file - - try: - self.ole = OleFileIO(self.fp) - except IOError: - raise SyntaxError, "not an FPX file; invalid OLE file" - - if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": - raise SyntaxError, "not an FPX file; bad root CLSID" - - self._open_index(1) - - def _open_index(self, index = 1): - # - # get the Image Contents Property Set - - prop = self.ole.getproperties([ - "Data Object Store %06d" % index, - "\005Image Contents" - ]) - - # size (highest resolution) - - self.size = prop[0x1000002], prop[0x1000003] - - size = max(self.size) - i = 1 - while size > 64: - size = size / 2 - i = i + 1 - self.maxid = i - 1 - - # mode. instead of using a single field for this, flashpix - # requires you to specify the mode for each channel in each - # resolution subimage, and leaves it to the decoder to make - # sure that they all match. for now, we'll cheat and assume - # that this is always the case. - - id = self.maxid << 16 - - s = prop[0x2000002|id] - - colors = [] - for i in range(i32(s, 4)): - # note: for now, we ignore the "uncalibrated" flag - colors.append(i32(s, 8+i*4) & 0x7fffffff) - - self.mode, self.rawmode = MODES[tuple(colors)] - - # load JPEG tables, if any - self.jpeg = {} - for i in range(256): - id = 0x3000001|(i << 16) - if prop.has_key(id): - self.jpeg[i] = prop[id] - - # print len(self.jpeg), "tables loaded" - - self._open_subimage(1, self.maxid) - - def _open_subimage(self, index = 1, subimage = 0): - # - # setup tile descriptors for a given subimage - - stream = [ - "Data Object Store %06d" % index, - "Resolution %04d" % subimage, - "Subimage 0000 Header" - ] - - fp = self.ole.openstream(stream) - - # skip prefix - p = fp.read(28) - - # header stream - s = fp.read(36) - - size = i32(s, 4), i32(s, 8) - tilecount = i32(s, 12) - tilesize = i32(s, 16), i32(s, 20) - channels = i32(s, 24) - offset = i32(s, 28) - length = i32(s, 32) - - # print size, self.mode, self.rawmode - - if size != self.size: - raise IOError, "subimage mismatch" - - # get tile descriptors - fp.seek(28 + offset) - s = fp.read(i32(s, 12) * length) - - x = y = 0 - xsize, ysize = size - xtile, ytile = tilesize - self.tile = [] - - for i in range(0, len(s), length): - - compression = i32(s, i+8) - - if compression == 0: - self.tile.append(("raw", (x,y,x+xtile,y+ytile), - i32(s, i) + 28, (self.rawmode))) - - elif compression == 1: - - # FIXME: the fill decoder is not implemented - self.tile.append(("fill", (x,y,x+xtile,y+ytile), - i32(s, i) + 28, (self.rawmode, s[12:16]))) - - elif compression == 2: - - internal_color_conversion = ord(s[14]) - jpeg_tables = ord(s[15]) - rawmode = self.rawmode - - if internal_color_conversion: - # The image is stored as usual (usually YCbCr). - if rawmode == "RGBA": - # For "RGBA", data is stored as YCbCrA based on - # negative RGB. The following trick works around - # this problem : - jpegmode, rawmode = "YCbCrK", "CMYK" - else: - jpegmode = None # let the decoder decide - - else: - # The image is stored as defined by rawmode - jpegmode = rawmode - - self.tile.append(("jpeg", (x,y,x+xtile,y+ytile), - i32(s, i) + 28, (rawmode, jpegmode))) - - # FIXME: jpeg tables are tile dependent; the prefix - # data must be placed in the tile descriptor itself! - - if jpeg_tables: - self.tile_prefix = self.jpeg[jpeg_tables] - - else: - raise IOError, "unknown/invalid compression" - - x = x + xtile - if x >= xsize: - x, y = 0, y + ytile - if y >= ysize: - break # isn't really required - - self.stream = stream - self.fp = None - - def load(self): - - if not self.fp: - self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"]) - - ImageFile.ImageFile.load(self) - -# -# -------------------------------------------------------------------- - -Image.register_open("FPX", FpxImageFile, _accept) - -Image.register_extension("FPX", ".fpx") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py deleted file mode 100755 index c71a0f77f9c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GbrImagePlugin.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# load a GIMP brush file -# -# History: -# 96-03-14 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFile - -def i32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24L) - -def _accept(prefix): - return i32(prefix) >= 20 and i32(prefix[4:8]) == 1 - -## -# Image plugin for the GIMP brush format. - -class GbrImageFile(ImageFile.ImageFile): - - format = "GBR" - format_description = "GIMP brush file" - - def _open(self): - - header_size = i32(self.fp.read(4)) - version = i32(self.fp.read(4)) - if header_size < 20 or version != 1: - raise SyntaxError, "not a GIMP brush" - - width = i32(self.fp.read(4)) - height = i32(self.fp.read(4)) - bytes = i32(self.fp.read(4)) - if width <= 0 or height <= 0 or bytes != 1: - raise SyntaxError, "not a GIMP brush" - - comment = self.fp.read(header_size - 20)[:-1] - - self.mode = "L" - self.size = width, height - - self.info["comment"] = comment - - # Since the brush is so small, we read the data immediately - self.data = self.fp.read(width * height) - - def load(self): - - if not self.data: - return - - # create an image out of the brush data block - self.im = Image.core.new(self.mode, self.size) - self.im.fromstring(self.data) - self.data = "" - -# -# registry - -Image.register_open("GBR", GbrImageFile, _accept) - -Image.register_extension("GBR", ".gbr") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py deleted file mode 100755 index b5f1dd25d79..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GdImageFile.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# GD file handling -# -# History: -# 1996-04-12 fl Created -# -# Copyright (c) 1997 by Secret Labs AB. -# Copyright (c) 1996 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - - -# NOTE: This format cannot be automatically recognized, so the -# class is not registered for use with Image.open(). To open a -# gd file, use the GdImageFile.open() function instead. - -# THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This -# implementation is provided for convenience and demonstrational -# purposes only. - - -__version__ = "0.1" - -import ImageFile, ImagePalette - -def i16(c): - return ord(c[1]) + (ord(c[0])<<8) - -## -# Image plugin for the GD uncompressed format. Note that this format -# is not supported by the standard Image.open function. To use -# this plugin, you have to import the GdImageFile module and -# use the GdImageFile.open function. - -class GdImageFile(ImageFile.ImageFile): - - format = "GD" - format_description = "GD uncompressed images" - - def _open(self): - - # Header - s = self.fp.read(775) - - self.mode = "L" # FIXME: "P" - self.size = i16(s[0:2]), i16(s[2:4]) - - # transparency index - tindex = i16(s[5:7]) - if tindex < 256: - self.info["transparent"] = tindex - - self.palette = ImagePalette.raw("RGB", s[7:]) - - self.tile = [("raw", (0,0)+self.size, 775, ("L", 0, -1))] - -## -# Load texture from a GD image file. -# -# @param filename GD file name, or an opened file handle. -# @param mode Optional mode. In this version, if the mode argument -# is given, it must be "r". -# @return An image instance. -# @exception IOError If the image could not be read. - -def open(fp, mode = "r"): - - if mode != "r": - raise ValueError("bad mode") - - if type(fp) == type(""): - import __builtin__ - filename = fp - fp = __builtin__.open(fp, "rb") - else: - filename = "" - - try: - return GdImageFile(fp, filename) - except SyntaxError: - raise IOError("cannot identify this image file") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py deleted file mode 100755 index 4d03493b544..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GifImagePlugin.py +++ /dev/null @@ -1,407 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# GIF file handling -# -# History: -# 1995-09-01 fl Created -# 1996-12-14 fl Added interlace support -# 1996-12-30 fl Added animation support -# 1997-01-05 fl Added write support, fixed local colour map bug -# 1997-02-23 fl Make sure to load raster data in getdata() -# 1997-07-05 fl Support external decoder (0.4) -# 1998-07-09 fl Handle all modes when saving (0.5) -# 1998-07-15 fl Renamed offset attribute to avoid name clash -# 2001-04-16 fl Added rewind support (seek to frame 0) (0.6) -# 2001-04-17 fl Added palette optimization (0.7) -# 2002-06-06 fl Added transparency support for save (0.8) -# 2004-02-24 fl Disable interlacing for small images -# -# Copyright (c) 1997-2004 by Secret Labs AB -# Copyright (c) 1995-2004 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.9" - - -import Image, ImageFile, ImagePalette - - -# -------------------------------------------------------------------- -# Helpers - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def o16(i): - return chr(i&255) + chr(i>>8&255) - - -# -------------------------------------------------------------------- -# Identify/read GIF files - -def _accept(prefix): - return prefix[:6] in ["GIF87a", "GIF89a"] - -## -# Image plugin for GIF images. This plugin supports both GIF87 and -# GIF89 images. - -class GifImageFile(ImageFile.ImageFile): - - format = "GIF" - format_description = "Compuserve GIF" - - global_palette = None - - def data(self): - s = self.fp.read(1) - if s and ord(s): - return self.fp.read(ord(s)) - return None - - def _open(self): - - # Screen - s = self.fp.read(13) - if s[:6] not in ["GIF87a", "GIF89a"]: - raise SyntaxError, "not a GIF file" - - self.info["version"] = s[:6] - - self.size = i16(s[6:]), i16(s[8:]) - - self.tile = [] - - flags = ord(s[10]) - - bits = (flags & 7) + 1 - - if flags & 128: - # get global palette - self.info["background"] = ord(s[11]) - # check if palette contains colour indices - p = self.fp.read(3<= 3 and ord(block[0]) == 1: - self.info["loop"] = i16(block[1:3]) - while self.data(): - pass - - elif s == ",": - # - # local image - # - s = self.fp.read(9) - - # extent - x0, y0 = i16(s[0:]), i16(s[2:]) - x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:]) - flags = ord(s[8]) - - interlace = (flags & 64) != 0 - - if flags & 128: - bits = (flags & 7) + 1 - self.palette =\ - ImagePalette.raw("RGB", self.fp.read(3<%s" % (file, filename)) - else: - os.system("ppmquant 256 %s | ppmtogif >%s" % (file, filename)) - try: os.unlink(file) - except: pass - - -# -------------------------------------------------------------------- -# GIF utilities - -def getheader(im, info=None): - """Return a list of strings representing a GIF header""" - - optimize = info and info.get("optimize", 0) - - s = [ - "GIF87a" + # magic - o16(im.size[0]) + # size - o16(im.size[1]) + - chr(7 + 128) + # flags: bits + palette - chr(0) + # background - chr(0) # reserved/aspect - ] - - if optimize: - # minimize color palette - i = 0 - maxcolor = 0 - for count in im.histogram(): - if count: - maxcolor = i - i = i + 1 - else: - maxcolor = 256 - - # global palette - if im.mode == "P": - # colour palette - s.append(im.im.getpalette("RGB")[:maxcolor*3]) - else: - # greyscale - for i in range(maxcolor): - s.append(chr(i) * 3) - - return s - -def getdata(im, offset = (0, 0), **params): - """Return a list of strings representing this image. - The first string is a local image header, the rest contains - encoded image data.""" - - class collector: - data = [] - def write(self, data): - self.data.append(data) - - im.load() # make sure raster data is available - - fp = collector() - - try: - im.encoderinfo = params - - # local image header - fp.write("," + - o16(offset[0]) + # offset - o16(offset[1]) + - o16(im.size[0]) + # size - o16(im.size[1]) + - chr(0) + # flags - chr(8)) # bits - - ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])]) - - fp.write("\0") # end of image data - - finally: - del im.encoderinfo - - return fp.data - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open(GifImageFile.format, GifImageFile, _accept) -Image.register_save(GifImageFile.format, _save) -Image.register_extension(GifImageFile.format, ".gif") -Image.register_mime(GifImageFile.format, "image/gif") - -# -# Uncomment the following line if you wish to use NETPBM/PBMPLUS -# instead of the built-in "uncompressed" GIF encoder - -# Image.register_save(GifImageFile.format, _save_netpbm) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py deleted file mode 100755 index 1a850dc53f7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpGradientFile.py +++ /dev/null @@ -1,124 +0,0 @@ -# -# Python Imaging Library -# $Id$ -# -# stuff to read (and render) GIMP gradient files -# -# History: -# 97-08-23 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - -from math import pi, log, sin, sqrt -import string - -# -------------------------------------------------------------------- -# Stuff to translate curve segments to palette values (derived from -# the corresponding code in GIMP, written by Federico Mena Quintero. -# See the GIMP distribution for more information.) -# - -EPSILON = 1e-10 - -def linear(middle, pos): - if pos <= middle: - if middle < EPSILON: - return 0.0 - else: - return 0.5 * pos / middle - else: - pos = pos - middle - middle = 1.0 - middle - if middle < EPSILON: - return 1.0 - else: - return 0.5 + 0.5 * pos / middle - -def curved(middle, pos): - return pos ** (log(0.5) / log(max(middle, EPSILON))) - -def sine(middle, pos): - return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0 - -def sphere_increasing(middle, pos): - return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2) - -def sphere_decreasing(middle, pos): - return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2) - -SEGMENTS = [ linear, curved, sine, sphere_increasing, sphere_decreasing ] - -class GradientFile: - - gradient = None - - def getpalette(self, entries = 256): - - palette = [] - - ix = 0 - x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] - - for i in range(entries): - - x = i / float(entries-1) - - while x1 < x: - ix = ix + 1 - x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] - - w = x1 - x0 - - if w < EPSILON: - scale = segment(0.5, 0.5) - else: - scale = segment((xm - x0) / w, (x - x0) / w) - - # expand to RGBA - r = chr(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5)) - g = chr(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5)) - b = chr(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5)) - a = chr(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5)) - - # add to palette - palette.append(r + g + b + a) - - return string.join(palette, ""), "RGBA" - -## -# File handler for GIMP's gradient format. - -class GimpGradientFile(GradientFile): - - def __init__(self, fp): - - if fp.readline()[:13] != "GIMP Gradient": - raise SyntaxError, "not a GIMP gradient file" - - count = int(fp.readline()) - - gradient = [] - - for i in range(count): - - s = string.split(fp.readline()) - w = map(float, s[:11]) - - x0, x1 = w[0], w[2] - xm = w[1] - rgb0 = w[3:7] - rgb1 = w[7:11] - - segment = SEGMENTS[int(s[11])] - cspace = int(s[12]) - - if cspace != 0: - raise IOError, "cannot handle HSV colour space" - - gradient.append((x0, x1, xm, rgb0, rgb1, segment)) - - self.gradient = gradient diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py deleted file mode 100755 index aba85b71f33..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GimpPaletteFile.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Python Imaging Library -# $Id$ -# -# stuff to read GIMP palette files -# -# History: -# 1997-08-23 fl Created -# 2004-09-07 fl Support GIMP 2.0 palette files. -# -# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. -# Copyright (c) Fredrik Lundh 1997-2004. -# -# See the README file for information on usage and redistribution. -# - -import re, string - -## -# File handler for GIMP's palette format. - -class GimpPaletteFile: - - rawmode = "RGB" - - def __init__(self, fp): - - self.palette = map(lambda i: chr(i)*3, range(256)) - - if fp.readline()[:12] != "GIMP Palette": - raise SyntaxError, "not a GIMP palette file" - - i = 0 - - while i <= 255: - - s = fp.readline() - - if not s: - break - # skip fields and comment lines - if re.match("\w+:|#", s): - continue - if len(s) > 100: - raise SyntaxError, "bad palette file" - - v = tuple(map(int, string.split(s)[:3])) - if len(v) != 3: - raise ValueError, "bad palette entry" - - if 0 <= i <= 255: - self.palette[i] = chr(v[0]) + chr(v[1]) + chr(v[2]) - - i = i + 1 - - self.palette = string.join(self.palette, "") - - - def getpalette(self): - - return self.palette, self.rawmode diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py deleted file mode 100755 index e232f90db7e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/GribStubImagePlugin.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# GRIB stub adapter -# -# Copyright (c) 1996-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFile - -_handler = None - -## -# Install application-specific GRIB image handler. -# -# @param handler Handler object. - -def register_handler(handler): - global _handler - _handler = handler - -# -------------------------------------------------------------------- -# Image adapter - -def _accept(prefix): - return prefix[0:4] == "GRIB" and prefix[7] == chr(1) - -class GribStubImageFile(ImageFile.StubImageFile): - - format = "GRIB" - format_description = "GRIB" - - def _open(self): - - offset = self.fp.tell() - - if not _accept(self.fp.read(8)): - raise SyntaxError("Not a GRIB file") - - self.fp.seek(offset) - - # make something up - self.mode = "F" - self.size = 1, 1 - - loader = self._load() - if loader: - loader.open(self) - - def _load(self): - return _handler - -def _save(im, fp, filename): - if _handler is None or not hasattr("_handler", "save"): - raise IOError("GRIB save handler not installed") - _handler.save(im, fp, filename) - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept) -Image.register_save(GribStubImageFile.format, _save) - -Image.register_extension(GribStubImageFile.format, ".grib") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py deleted file mode 100755 index bc5e3743339..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Hdf5StubImagePlugin.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# HDF5 stub adapter -# -# Copyright (c) 2000-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFile - -_handler = None - -## -# Install application-specific HDF5 image handler. -# -# @param handler Handler object. - -def register_handler(handler): - global _handler - _handler = handler - -# -------------------------------------------------------------------- -# Image adapter - -def _accept(prefix): - return prefix[:8] == "\x89HDF\r\n\x1a\n" - -class HDF5StubImageFile(ImageFile.StubImageFile): - - format = "HDF5" - format_description = "HDF5" - - def _open(self): - - offset = self.fp.tell() - - if not _accept(self.fp.read(8)): - raise SyntaxError("Not an HDF file") - - self.fp.seek(offset) - - # make something up - self.mode = "F" - self.size = 1, 1 - - loader = self._load() - if loader: - loader.open(self) - - def _load(self): - return _handler - - -def _save(im, fp, filename): - if _handler is None or not hasattr("_handler", "save"): - raise IOError("HDF5 save handler not installed") - _handler.save(im, fp, filename) - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept) -Image.register_save(HDF5StubImageFile.format, _save) - -Image.register_extension(HDF5StubImageFile.format, ".h5") -Image.register_extension(HDF5StubImageFile.format, ".hdf") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py deleted file mode 100755 index 4d68fa232f9..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcnsImagePlugin.py +++ /dev/null @@ -1,211 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# Mac OS X icns file decoder, based on icns.py by Bob Ippolito. -# -# history: -# 2004-10-09 fl Turned into a PIL plugin; removed 2.3 dependencies. -# -# Copyright (c) 2004 by Bob Ippolito. -# Copyright (c) 2004 by Secret Labs. -# Copyright (c) 2004 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFile -import string, struct - -HEADERSIZE = 8 - -def nextheader(fobj): - return struct.unpack('>4sI', fobj.read(HEADERSIZE)) - -def read_32t(fobj, (start, length), (width, height)): - # The 128x128 icon seems to have an extra header for some reason. - fobj.seek(start) - sig = fobj.read(4) - if sig != '\x00\x00\x00\x00': - raise SyntaxError, 'Unknown signature, expecting 0x00000000' - return read_32(fobj, (start + 4, length - 4), (width, height)) - -def read_32(fobj, (start, length), size): - """ - Read a 32bit RGB icon resource. Seems to be either uncompressed or - an RLE packbits-like scheme. - """ - fobj.seek(start) - sizesq = size[0] * size[1] - if length == sizesq * 3: - # uncompressed ("RGBRGBGB") - indata = fobj.read(length) - im = Image.frombuffer("RGB", size, indata, "raw", "RGB", 0, 1) - else: - # decode image - im = Image.new("RGB", size, None) - for band_ix in range(3): - data = [] - bytesleft = sizesq - while bytesleft > 0: - byte = fobj.read(1) - if not byte: - break - byte = ord(byte) - if byte & 0x80: - blocksize = byte - 125 - byte = fobj.read(1) - for i in range(blocksize): - data.append(byte) - else: - blocksize = byte + 1 - data.append(fobj.read(blocksize)) - bytesleft = bytesleft - blocksize - if bytesleft <= 0: - break - if bytesleft != 0: - raise SyntaxError( - "Error reading channel [%r left]" % bytesleft - ) - band = Image.frombuffer( - "L", size, string.join(data, ""), "raw", "L", 0, 1 - ) - im.im.putband(band.im, band_ix) - return {"RGB": im} - -def read_mk(fobj, (start, length), size): - # Alpha masks seem to be uncompressed - fobj.seek(start) - band = Image.frombuffer( - "L", size, fobj.read(size[0]*size[1]), "raw", "L", 0, 1 - ) - return {"A": band} - -class IcnsFile: - - SIZES = { - (128, 128): [ - ('it32', read_32t), - ('t8mk', read_mk), - ], - (48, 48): [ - ('ih32', read_32), - ('h8mk', read_mk), - ], - (32, 32): [ - ('il32', read_32), - ('l8mk', read_mk), - ], - (16, 16): [ - ('is32', read_32), - ('s8mk', read_mk), - ], - } - - def __init__(self, fobj): - """ - fobj is a file-like object as an icns resource - """ - # signature : (start, length) - self.dct = dct = {} - self.fobj = fobj - sig, filesize = nextheader(fobj) - if sig != 'icns': - raise SyntaxError, 'not an icns file' - i = HEADERSIZE - while i < filesize: - sig, blocksize = nextheader(fobj) - i = i + HEADERSIZE - blocksize = blocksize - HEADERSIZE - dct[sig] = (i, blocksize) - fobj.seek(blocksize, 1) - i = i + blocksize - - def itersizes(self): - sizes = [] - for size, fmts in self.SIZES.items(): - for (fmt, reader) in fmts: - if self.dct.has_key(fmt): - sizes.append(size) - break - return sizes - - def bestsize(self): - sizes = self.itersizes() - if not sizes: - raise SyntaxError, "No 32bit icon resources found" - return max(sizes) - - def dataforsize(self, size): - """ - Get an icon resource as {channel: array}. Note that - the arrays are bottom-up like windows bitmaps and will likely - need to be flipped or transposed in some way. - """ - dct = {} - for code, reader in self.SIZES[size]: - desc = self.dct.get(code) - if desc is not None: - dct.update(reader(self.fobj, desc, size)) - return dct - - def getimage(self, size=None): - if size is None: - size = self.bestsize() - channels = self.dataforsize(size) - im = channels.get("RGB").copy() - try: - im.putalpha(channels["A"]) - except KeyError: - pass - return im - -## -# Image plugin for Mac OS icons. - -class IcnsImageFile(ImageFile.ImageFile): - """ - PIL read-only image support for Mac OS .icns files. - Chooses the best resolution, but will possibly load - a different size image if you mutate the size attribute - before calling 'load'. - - The info dictionary has a key 'sizes' that is a list - of sizes that the icns file has. - """ - - format = "ICNS" - format_description = "Mac OS icns resource" - - def _open(self): - self.icns = IcnsFile(self.fp) - self.mode = 'RGBA' - self.size = self.icns.bestsize() - self.info['sizes'] = self.icns.itersizes() - # Just use this to see if it's loaded or not yet. - self.tile = ('',) - - def load(self): - Image.Image.load(self) - if not self.tile: - return - self.load_prepare() - # This is likely NOT the best way to do it, but whatever. - im = self.icns.getimage(self.size) - self.im = im.im - self.mode = im.mode - self.size = im.size - self.fp = None - self.icns = None - self.tile = () - self.load_end() - - -Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == 'icns') -Image.register_extension("ICNS", '.icns') - -if __name__ == '__main__': - import os, sys - im = Image.open(open(sys.argv[1], "rb")) - im.save("out.png") - os.startfile("out.png") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py deleted file mode 100755 index 94846dc0ca0..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IcoImagePlugin.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# Windows Icon support for PIL -# -# Notes: -# uses BmpImagePlugin.py to read the bitmap data. -# -# History: -# 96-05-27 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.1" - -import Image, BmpImagePlugin - - -# -# -------------------------------------------------------------------- - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - - -def _accept(prefix): - return prefix[:4] == "\0\0\1\0" - -## -# Image plugin for Windows Icon files. - -class IcoImageFile(BmpImagePlugin.BmpImageFile): - - format = "ICO" - format_description = "Windows Icon" - - def _open(self): - - # check magic - s = self.fp.read(6) - if not _accept(s): - raise SyntaxError, "not an ICO file" - - # pick the largest icon in the file - m = "" - for i in range(i16(s[4:])): - s = self.fp.read(16) - if not m: - m = s - elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]): - m = s - #print "width", ord(s[0]) - #print "height", ord(s[1]) - #print "colors", ord(s[2]) - #print "reserved", ord(s[3]) - #print "planes", i16(s[4:]) - #print "bitcount", i16(s[6:]) - #print "bytes", i32(s[8:]) - #print "offset", i32(s[12:]) - - # load as bitmap - self._bitmap(i32(m[12:])) - - # patch up the bitmap height - self.size = self.size[0], self.size[1]/2 - d, e, o, a = self.tile[0] - self.tile[0] = d, (0,0)+self.size, o, a - - return - - -# -# -------------------------------------------------------------------- - -Image.register_open("ICO", IcoImageFile, _accept) - -Image.register_extension("ICO", ".ico") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py deleted file mode 100755 index a76dcf04ed3..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImImagePlugin.py +++ /dev/null @@ -1,336 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# IFUNC IM file handling for PIL -# -# history: -# 1995-09-01 fl Created. -# 1997-01-03 fl Save palette images -# 1997-01-08 fl Added sequence support -# 1997-01-23 fl Added P and RGB save support -# 1997-05-31 fl Read floating point images -# 1997-06-22 fl Save floating point images -# 1997-08-27 fl Read and save 1-bit images -# 1998-06-25 fl Added support for RGB+LUT images -# 1998-07-02 fl Added support for YCC images -# 1998-07-15 fl Renamed offset attribute to avoid name clash -# 1998-12-29 fl Added I;16 support -# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) -# 2003-09-26 fl Added LA/PA support -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1995-2001 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.7" - -import re, string -import Image, ImageFile, ImagePalette - - -# -------------------------------------------------------------------- -# Standard tags - -COMMENT = "Comment" -DATE = "Date" -EQUIPMENT = "Digitalization equipment" -FRAMES = "File size (no of images)" -LUT = "Lut" -NAME = "Name" -SCALE = "Scale (x,y)" -SIZE = "Image size (x*y)" -MODE = "Image type" - -TAGS = { COMMENT:0, DATE:0, EQUIPMENT:0, FRAMES:0, LUT:0, NAME:0, - SCALE:0, SIZE:0, MODE:0 } - -OPEN = { - # ifunc93/p3cfunc formats - "0 1 image": ("1", "1"), - "L 1 image": ("1", "1"), - "Greyscale image": ("L", "L"), - "Grayscale image": ("L", "L"), - "RGB image": ("RGB", "RGB;L"), - "RLB image": ("RGB", "RLB"), - "RYB image": ("RGB", "RLB"), - "B1 image": ("1", "1"), - "B2 image": ("P", "P;2"), - "B4 image": ("P", "P;4"), - "X 24 image": ("RGB", "RGB"), - "L 32 S image": ("I", "I;32"), - "L 32 F image": ("F", "F;32"), - # old p3cfunc formats - "RGB3 image": ("RGB", "RGB;T"), - "RYB3 image": ("RGB", "RYB;T"), - # extensions - "LA image": ("LA", "LA;L"), - "RGBA image": ("RGBA", "RGBA;L"), - "RGBX image": ("RGBX", "RGBX;L"), - "CMYK image": ("CMYK", "CMYK;L"), - "YCC image": ("YCbCr", "YCbCr;L"), -} - -# ifunc95 extensions -for i in ["8", "8S", "16", "16S", "32", "32F"]: - OPEN["L %s image" % i] = ("F", "F;%s" % i) - OPEN["L*%s image" % i] = ("F", "F;%s" % i) -for i in ["16", "16L", "16B"]: - OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i) - OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i) -for i in ["32S"]: - OPEN["L %s image" % i] = ("I", "I;%s" % i) - OPEN["L*%s image" % i] = ("I", "I;%s" % i) -for i in range(2, 33): - OPEN["L*%s image" % i] = ("F", "F;%s" % i) - - -# -------------------------------------------------------------------- -# Read IM directory - -split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$") - -def number(s): - try: - return int(s) - except ValueError: - return float(s) - -## -# Image plugin for the IFUNC IM file format. - -class ImImageFile(ImageFile.ImageFile): - - format = "IM" - format_description = "IFUNC Image Memory" - - def _open(self): - - # Quick rejection: if there's not an LF among the first - # 100 bytes, this is (probably) not a text header. - - if not "\n" in self.fp.read(100): - raise SyntaxError, "not an IM file" - self.fp.seek(0) - - n = 0 - - # Default values - self.info[MODE] = "L" - self.info[SIZE] = (512, 512) - self.info[FRAMES] = 1 - - self.rawmode = "L" - - while 1: - - s = self.fp.read(1) - - # Some versions of IFUNC uses \n\r instead of \r\n... - if s == "\r": - continue - - if not s or s[0] == chr(0) or s[0] == chr(26): - break - - # FIXME: this may read whole file if not a text file - s = s + self.fp.readline() - - if len(s) > 100: - raise SyntaxError, "not an IM file" - - if s[-2:] == '\r\n': - s = s[:-2] - elif s[-1:] == '\n': - s = s[:-1] - - try: - m = split.match(s) - except re.error, v: - raise SyntaxError, "not an IM file" - - if m: - - k, v = m.group(1,2) - - # Convert value as appropriate - if k in [FRAMES, SCALE, SIZE]: - v = string.replace(v, "*", ",") - v = tuple(map(number, string.split(v, ","))) - if len(v) == 1: - v = v[0] - elif k == MODE and OPEN.has_key(v): - v, self.rawmode = OPEN[v] - - # Add to dictionary. Note that COMMENT tags are - # combined into a list of strings. - if k == COMMENT: - if self.info.has_key(k): - self.info[k].append(v) - else: - self.info[k] = [v] - else: - self.info[k] = v - - if TAGS.has_key(k): - n = n + 1 - - else: - - raise SyntaxError, "Syntax error in IM header: " + s - - if not n: - raise SyntaxError, "Not an IM file" - - # Basic attributes - self.size = self.info[SIZE] - self.mode = self.info[MODE] - - # Skip forward to start of image data - while s and s[0] != chr(26): - s = self.fp.read(1) - if not s: - raise SyntaxError, "File truncated" - - if self.info.has_key(LUT): - # convert lookup table to palette or lut attribute - palette = self.fp.read(768) - greyscale = 1 # greyscale palette - linear = 1 # linear greyscale palette - for i in range(256): - if palette[i] == palette[i+256] == palette[i+512]: - if palette[i] != chr(i): - linear = 0 - else: - greyscale = 0 - if self.mode == "L" or self.mode == "LA": - if greyscale: - if not linear: - self.lut = map(ord, palette[:256]) - else: - if self.mode == "L": - self.mode = self.rawmode = "P" - elif self.mode == "LA": - self.mode = self.rawmode = "PA" - self.palette = ImagePalette.raw("RGB;L", palette) - elif self.mode == "RGB": - if not greyscale or not linear: - self.lut = map(ord, palette) - - self.frame = 0 - - self.__offset = offs = self.fp.tell() - - self.__fp = self.fp # FIXME: hack - - if self.rawmode[:2] == "F;": - - # ifunc95 formats - try: - # use bit decoder (if necessary) - bits = int(self.rawmode[2:]) - if bits not in [8, 16, 32]: - self.tile = [("bit", (0,0)+self.size, offs, - (bits, 8, 3, 0, -1))] - return - except ValueError: - pass - - if self.rawmode in ["RGB;T", "RYB;T"]: - # Old LabEye/3PC files. Would be very surprised if anyone - # ever stumbled upon such a file ;-) - size = self.size[0] * self.size[1] - self.tile = [("raw", (0,0)+self.size, offs, ("G", 0, -1)), - ("raw", (0,0)+self.size, offs+size, ("R", 0, -1)), - ("raw", (0,0)+self.size, offs+2*size, ("B", 0, -1))] - else: - # LabEye/IFUNC files - self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))] - - def seek(self, frame): - - if frame < 0 or frame >= self.info[FRAMES]: - raise EOFError, "seek outside sequence" - - if self.frame == frame: - return - - self.frame = frame - - if self.mode == "1": - bits = 1 - else: - bits = 8 * len(self.mode) - - size = ((self.size[0] * bits + 7) / 8) * self.size[1] - offs = self.__offset + frame * size - - self.fp = self.__fp - - self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))] - - def tell(self): - - return self.frame - -# -# -------------------------------------------------------------------- -# Save IM files - -SAVE = { - # mode: (im type, raw mode) - "1": ("0 1", "1"), - "L": ("Greyscale", "L"), - "LA": ("LA", "LA;L"), - "P": ("Greyscale", "P"), - "PA": ("LA", "PA;L"), - "I": ("L 32S", "I;32S"), - "I;16": ("L 16", "I;16"), - "I;16L": ("L 16L", "I;16L"), - "I;16B": ("L 16B", "I;16B"), - "F": ("L 32F", "F;32F"), - "RGB": ("RGB", "RGB;L"), - "RGBA": ("RGBA", "RGBA;L"), - "RGBX": ("RGBX", "RGBX;L"), - "CMYK": ("CMYK", "CMYK;L"), - "YCbCr": ("YCC", "YCbCr;L") -} - -def _save(im, fp, filename, check=0): - - try: - type, rawmode = SAVE[im.mode] - except KeyError: - raise ValueError, "Cannot save %s images as IM" % im.mode - - try: - frames = im.encoderinfo["frames"] - except KeyError: - frames = 1 - - if check: - return check - - fp.write("Image type: %s image\r\n" % type) - if filename: - fp.write("Name: %s\r\n" % filename) - fp.write("Image size (x*y): %d*%d\r\n" % im.size) - fp.write("File size (no of images): %d\r\n" % frames) - if im.mode == "P": - fp.write("Lut: 1\r\n") - fp.write("\000" * (511-fp.tell()) + "\032") - if im.mode == "P": - fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))]) - -# -# -------------------------------------------------------------------- -# Registry - -Image.register_open("IM", ImImageFile) -Image.register_save("IM", _save) - -Image.register_extension("IM", ".im") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py deleted file mode 100755 index 77a532afad0..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/Image.py +++ /dev/null @@ -1,2127 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# the Image class wrapper -# -# partial release history: -# 1995-09-09 fl Created -# 1996-03-11 fl PIL release 0.0 (proof of concept) -# 1996-04-30 fl PIL release 0.1b1 -# 1999-07-28 fl PIL release 1.0 final -# 2000-06-07 fl PIL release 1.1 -# 2000-10-20 fl PIL release 1.1.1 -# 2001-05-07 fl PIL release 1.1.2 -# 2002-03-15 fl PIL release 1.1.3 -# 2003-05-10 fl PIL release 1.1.4 -# 2005-03-28 fl PIL release 1.1.5 -# 2006-12-02 fl PIL release 1.1.6 -# 2009-11-15 fl PIL release 1.1.7 -# -# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved. -# Copyright (c) 1995-2009 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -VERSION = "1.1.7" - -try: - import warnings -except ImportError: - warnings = None - -class _imaging_not_installed: - # module placeholder - def __getattr__(self, id): - raise ImportError("The _imaging C module is not installed") - -try: - # give Tk a chance to set up the environment, in case we're - # using an _imaging module linked against libtcl/libtk (use - # __import__ to hide this from naive packagers; we don't really - # depend on Tk unless ImageTk is used, and that module already - # imports Tkinter) - __import__("FixTk") -except ImportError: - pass - -try: - # If the _imaging C module is not present, you can still use - # the "open" function to identify files, but you cannot load - # them. Note that other modules should not refer to _imaging - # directly; import Image and use the Image.core variable instead. - import _imaging - core = _imaging - del _imaging -except ImportError, v: - core = _imaging_not_installed() - if str(v)[:20] == "Module use of python" and warnings: - # The _imaging C module is present, but not compiled for - # the right version (windows only). Print a warning, if - # possible. - warnings.warn( - "The _imaging extension was built for another version " - "of Python; most PIL functions will be disabled", - RuntimeWarning - ) - -import ImageMode -import ImagePalette - -import os, string, sys - -# type stuff -from types import IntType, StringType, TupleType - -try: - UnicodeStringType = type(unicode("")) - ## - # (Internal) Checks if an object is a string. If the current - # Python version supports Unicode, this checks for both 8-bit - # and Unicode strings. - def isStringType(t): - return isinstance(t, StringType) or isinstance(t, UnicodeStringType) -except NameError: - def isStringType(t): - return isinstance(t, StringType) - -## -# (Internal) Checks if an object is a tuple. - -def isTupleType(t): - return isinstance(t, TupleType) - -## -# (Internal) Checks if an object is an image object. - -def isImageType(t): - return hasattr(t, "im") - -## -# (Internal) Checks if an object is a string, and that it points to a -# directory. - -def isDirectory(f): - return isStringType(f) and os.path.isdir(f) - -from operator import isNumberType, isSequenceType - -# -# Debug level - -DEBUG = 0 - -# -# Constants (also defined in _imagingmodule.c!) - -NONE = 0 - -# transpose -FLIP_LEFT_RIGHT = 0 -FLIP_TOP_BOTTOM = 1 -ROTATE_90 = 2 -ROTATE_180 = 3 -ROTATE_270 = 4 - -# transforms -AFFINE = 0 -EXTENT = 1 -PERSPECTIVE = 2 -QUAD = 3 -MESH = 4 - -# resampling filters -NONE = 0 -NEAREST = 0 -ANTIALIAS = 1 # 3-lobed lanczos -LINEAR = BILINEAR = 2 -CUBIC = BICUBIC = 3 - -# dithers -NONE = 0 -NEAREST = 0 -ORDERED = 1 # Not yet implemented -RASTERIZE = 2 # Not yet implemented -FLOYDSTEINBERG = 3 # default - -# palettes/quantizers -WEB = 0 -ADAPTIVE = 1 - -# categories -NORMAL = 0 -SEQUENCE = 1 -CONTAINER = 2 - -# -------------------------------------------------------------------- -# Registries - -ID = [] -OPEN = {} -MIME = {} -SAVE = {} -EXTENSION = {} - -# -------------------------------------------------------------------- -# Modes supported by this version - -_MODEINFO = { - # NOTE: this table will be removed in future versions. use - # getmode* functions or ImageMode descriptors instead. - - # official modes - "1": ("L", "L", ("1",)), - "L": ("L", "L", ("L",)), - "I": ("L", "I", ("I",)), - "F": ("L", "F", ("F",)), - "P": ("RGB", "L", ("P",)), - "RGB": ("RGB", "L", ("R", "G", "B")), - "RGBX": ("RGB", "L", ("R", "G", "B", "X")), - "RGBA": ("RGB", "L", ("R", "G", "B", "A")), - "CMYK": ("RGB", "L", ("C", "M", "Y", "K")), - "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr")), - - # Experimental modes include I;16, I;16L, I;16B, RGBa, BGR;15, and - # BGR;24. Use these modes only if you know exactly what you're - # doing... - -} - -try: - byteorder = sys.byteorder -except AttributeError: - import struct - if struct.unpack("h", "\0\1")[0] == 1: - byteorder = "big" - else: - byteorder = "little" - -if byteorder == 'little': - _ENDIAN = '<' -else: - _ENDIAN = '>' - -_MODE_CONV = { - # official modes - "1": ('|b1', None), # broken - "L": ('|u1', None), - "I": (_ENDIAN + 'i4', None), - "F": (_ENDIAN + 'f4', None), - "P": ('|u1', None), - "RGB": ('|u1', 3), - "RGBX": ('|u1', 4), - "RGBA": ('|u1', 4), - "CMYK": ('|u1', 4), - "YCbCr": ('|u1', 4), -} - -def _conv_type_shape(im): - shape = im.size[1], im.size[0] - typ, extra = _MODE_CONV[im.mode] - if extra is None: - return shape, typ - else: - return shape+(extra,), typ - - -MODES = _MODEINFO.keys() -MODES.sort() - -# raw modes that may be memory mapped. NOTE: if you change this, you -# may have to modify the stride calculation in map.c too! -_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B") - -## -# Gets the "base" mode for given mode. This function returns "L" for -# images that contain grayscale data, and "RGB" for images that -# contain color data. -# -# @param mode Input mode. -# @return "L" or "RGB". -# @exception KeyError If the input mode was not a standard mode. - -def getmodebase(mode): - return ImageMode.getmode(mode).basemode - -## -# Gets the storage type mode. Given a mode, this function returns a -# single-layer mode suitable for storing individual bands. -# -# @param mode Input mode. -# @return "L", "I", or "F". -# @exception KeyError If the input mode was not a standard mode. - -def getmodetype(mode): - return ImageMode.getmode(mode).basetype - -## -# Gets a list of individual band names. Given a mode, this function -# returns a tuple containing the names of individual bands (use -# {@link #getmodetype} to get the mode used to store each individual -# band. -# -# @param mode Input mode. -# @return A tuple containing band names. The length of the tuple -# gives the number of bands in an image of the given mode. -# @exception KeyError If the input mode was not a standard mode. - -def getmodebandnames(mode): - return ImageMode.getmode(mode).bands - -## -# Gets the number of individual bands for this mode. -# -# @param mode Input mode. -# @return The number of bands in this mode. -# @exception KeyError If the input mode was not a standard mode. - -def getmodebands(mode): - return len(ImageMode.getmode(mode).bands) - -# -------------------------------------------------------------------- -# Helpers - -_initialized = 0 - -## -# Explicitly loads standard file format drivers. - -def preinit(): - "Load standard file format drivers." - - global _initialized - if _initialized >= 1: - return - - try: - import BmpImagePlugin - except ImportError: - pass - try: - import GifImagePlugin - except ImportError: - pass - try: - import JpegImagePlugin - except ImportError: - pass - try: - import PpmImagePlugin - except ImportError: - pass - try: - import PngImagePlugin - except ImportError: - pass -# try: -# import TiffImagePlugin -# except ImportError: -# pass - - _initialized = 1 - -## -# Explicitly initializes the Python Imaging Library. This function -# loads all available file format drivers. - -def init(): - "Load all file format drivers." - - global _initialized - if _initialized >= 2: - return 0 - - visited = {} - - directories = sys.path - - try: - directories = directories + [os.path.dirname(__file__)] - except NameError: - pass - - # only check directories (including current, if present in the path) - for directory in filter(isDirectory, directories): - fullpath = os.path.abspath(directory) - if visited.has_key(fullpath): - continue - for file in os.listdir(directory): - if file[-14:] == "ImagePlugin.py": - f, e = os.path.splitext(file) - try: - sys.path.insert(0, directory) - try: - __import__(f, globals(), locals(), []) - finally: - del sys.path[0] - except ImportError: - if DEBUG: - print "Image: failed to import", - print f, ":", sys.exc_value - visited[fullpath] = None - - if OPEN or SAVE: - _initialized = 2 - return 1 - -# -------------------------------------------------------------------- -# Codec factories (used by tostring/fromstring and ImageFile.load) - -def _getdecoder(mode, decoder_name, args, extra=()): - - # tweak arguments - if args is None: - args = () - elif not isTupleType(args): - args = (args,) - - try: - # get decoder - decoder = getattr(core, decoder_name + "_decoder") - # print decoder, (mode,) + args + extra - return apply(decoder, (mode,) + args + extra) - except AttributeError: - raise IOError("decoder %s not available" % decoder_name) - -def _getencoder(mode, encoder_name, args, extra=()): - - # tweak arguments - if args is None: - args = () - elif not isTupleType(args): - args = (args,) - - try: - # get encoder - encoder = getattr(core, encoder_name + "_encoder") - # print encoder, (mode,) + args + extra - return apply(encoder, (mode,) + args + extra) - except AttributeError: - raise IOError("encoder %s not available" % encoder_name) - - -# -------------------------------------------------------------------- -# Simple expression analyzer - -class _E: - def __init__(self, data): self.data = data - def __coerce__(self, other): return self, _E(other) - def __add__(self, other): return _E((self.data, "__add__", other.data)) - def __mul__(self, other): return _E((self.data, "__mul__", other.data)) - -def _getscaleoffset(expr): - stub = ["stub"] - data = expr(_E(stub)).data - try: - (a, b, c) = data # simplified syntax - if (a is stub and b == "__mul__" and isNumberType(c)): - return c, 0.0 - if (a is stub and b == "__add__" and isNumberType(c)): - return 1.0, c - except TypeError: pass - try: - ((a, b, c), d, e) = data # full syntax - if (a is stub and b == "__mul__" and isNumberType(c) and - d == "__add__" and isNumberType(e)): - return c, e - except TypeError: pass - raise ValueError("illegal expression") - - -# -------------------------------------------------------------------- -# Implementation wrapper - -## -# This class represents an image object. To create Image objects, use -# the appropriate factory functions. There's hardly ever any reason -# to call the Image constructor directly. -# -# @see #open -# @see #new -# @see #fromstring - -class Image: - - format = None - format_description = None - - def __init__(self): - # FIXME: take "new" parameters / other image? - # FIXME: turn mode and size into delegating properties? - self.im = None - self.mode = "" - self.size = (0, 0) - self.palette = None - self.info = {} - self.category = NORMAL - self.readonly = 0 - - def _new(self, im): - new = Image() - new.im = im - new.mode = im.mode - new.size = im.size - new.palette = self.palette - if im.mode == "P": - new.palette = ImagePalette.ImagePalette() - try: - new.info = self.info.copy() - except AttributeError: - # fallback (pre-1.5.2) - new.info = {} - for k, v in self.info: - new.info[k] = v - return new - - _makeself = _new # compatibility - - def _copy(self): - self.load() - self.im = self.im.copy() - self.readonly = 0 - - def _dump(self, file=None, format=None): - import tempfile - if not file: - file = tempfile.mktemp() - self.load() - if not format or format == "PPM": - self.im.save_ppm(file) - else: - file = file + "." + format - self.save(file, format) - return file - - def __repr__(self): - return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % ( - self.__class__.__module__, self.__class__.__name__, - self.mode, self.size[0], self.size[1], - id(self) - ) - - def __getattr__(self, name): - if name == "__array_interface__": - # numpy array interface support - new = {} - shape, typestr = _conv_type_shape(self) - new['shape'] = shape - new['typestr'] = typestr - new['data'] = self.tostring() - return new - raise AttributeError(name) - - ## - # Returns a string containing pixel data. - # - # @param encoder_name What encoder to use. The default is to - # use the standard "raw" encoder. - # @param *args Extra arguments to the encoder. - # @return An 8-bit string. - - def tostring(self, encoder_name="raw", *args): - "Return image as a binary string" - - # may pass tuple instead of argument list - if len(args) == 1 and isTupleType(args[0]): - args = args[0] - - if encoder_name == "raw" and args == (): - args = self.mode - - self.load() - - # unpack data - e = _getencoder(self.mode, encoder_name, args) - e.setimage(self.im) - - bufsize = max(65536, self.size[0] * 4) # see RawEncode.c - - data = [] - while 1: - l, s, d = e.encode(bufsize) - data.append(d) - if s: - break - if s < 0: - raise RuntimeError("encoder error %d in tostring" % s) - - return string.join(data, "") - - ## - # Returns the image converted to an X11 bitmap. This method - # only works for mode "1" images. - # - # @param name The name prefix to use for the bitmap variables. - # @return A string containing an X11 bitmap. - # @exception ValueError If the mode is not "1" - - def tobitmap(self, name="image"): - "Return image as an XBM bitmap" - - self.load() - if self.mode != "1": - raise ValueError("not a bitmap") - data = self.tostring("xbm") - return string.join(["#define %s_width %d\n" % (name, self.size[0]), - "#define %s_height %d\n"% (name, self.size[1]), - "static char %s_bits[] = {\n" % name, data, "};"], "") - - ## - # Loads this image with pixel data from a string. - #

- # This method is similar to the {@link #fromstring} function, but - # loads data into this image instead of creating a new image - # object. - - def fromstring(self, data, decoder_name="raw", *args): - "Load data to image from binary string" - - # may pass tuple instead of argument list - if len(args) == 1 and isTupleType(args[0]): - args = args[0] - - # default format - if decoder_name == "raw" and args == (): - args = self.mode - - # unpack data - d = _getdecoder(self.mode, decoder_name, args) - d.setimage(self.im) - s = d.decode(data) - - if s[0] >= 0: - raise ValueError("not enough image data") - if s[1] != 0: - raise ValueError("cannot decode image data") - - ## - # Allocates storage for the image and loads the pixel data. In - # normal cases, you don't need to call this method, since the - # Image class automatically loads an opened image when it is - # accessed for the first time. - # - # @return An image access object. - - def load(self): - "Explicitly load pixel data." - if self.im and self.palette and self.palette.dirty: - # realize palette - apply(self.im.putpalette, self.palette.getdata()) - self.palette.dirty = 0 - self.palette.mode = "RGB" - self.palette.rawmode = None - if self.info.has_key("transparency"): - self.im.putpalettealpha(self.info["transparency"], 0) - self.palette.mode = "RGBA" - if self.im: - return self.im.pixel_access(self.readonly) - - ## - # Verifies the contents of a file. For data read from a file, this - # method attempts to determine if the file is broken, without - # actually decoding the image data. If this method finds any - # problems, it raises suitable exceptions. If you need to load - # the image after using this method, you must reopen the image - # file. - - def verify(self): - "Verify file contents." - pass - - ## - # Returns a converted copy of this image. For the "P" mode, this - # method translates pixels through the palette. If mode is - # omitted, a mode is chosen so that all information in the image - # and the palette can be represented without a palette. - #

- # The current version supports all possible conversions between - # "L", "RGB" and "CMYK." - #

- # When translating a colour image to black and white (mode "L"), - # the library uses the ITU-R 601-2 luma transform: - #

- # L = R * 299/1000 + G * 587/1000 + B * 114/1000 - #

- # When translating a greyscale image into a bilevel image (mode - # "1"), all non-zero values are set to 255 (white). To use other - # thresholds, use the {@link #Image.point} method. - # - # @def convert(mode, matrix=None, **options) - # @param mode The requested mode. - # @param matrix An optional conversion matrix. If given, this - # should be 4- or 16-tuple containing floating point values. - # @param options Additional options, given as keyword arguments. - # @keyparam dither Dithering method, used when converting from - # mode "RGB" to "P". - # Available methods are NONE or FLOYDSTEINBERG (default). - # @keyparam palette Palette to use when converting from mode "RGB" - # to "P". Available palettes are WEB or ADAPTIVE. - # @keyparam colors Number of colors to use for the ADAPTIVE palette. - # Defaults to 256. - # @return An Image object. - - def convert(self, mode=None, data=None, dither=None, - palette=WEB, colors=256): - "Convert to other pixel format" - - if not mode: - # determine default mode - if self.mode == "P": - self.load() - if self.palette: - mode = self.palette.mode - else: - mode = "RGB" - else: - return self.copy() - - self.load() - - if data: - # matrix conversion - if mode not in ("L", "RGB"): - raise ValueError("illegal conversion") - im = self.im.convert_matrix(mode, data) - return self._new(im) - - if mode == "P" and palette == ADAPTIVE: - im = self.im.quantize(colors) - return self._new(im) - - # colourspace conversion - if dither is None: - dither = FLOYDSTEINBERG - - try: - im = self.im.convert(mode, dither) - except ValueError: - try: - # normalize source image and try again - im = self.im.convert(getmodebase(self.mode)) - im = im.convert(mode, dither) - except KeyError: - raise ValueError("illegal conversion") - - return self._new(im) - - def quantize(self, colors=256, method=0, kmeans=0, palette=None): - - # methods: - # 0 = median cut - # 1 = maximum coverage - - # NOTE: this functionality will be moved to the extended - # quantizer interface in a later version of PIL. - - self.load() - - if palette: - # use palette from reference image - palette.load() - if palette.mode != "P": - raise ValueError("bad mode for palette image") - if self.mode != "RGB" and self.mode != "L": - raise ValueError( - "only RGB or L mode images can be quantized to a palette" - ) - im = self.im.convert("P", 1, palette.im) - return self._makeself(im) - - im = self.im.quantize(colors, method, kmeans) - return self._new(im) - - ## - # Copies this image. Use this method if you wish to paste things - # into an image, but still retain the original. - # - # @return An Image object. - - def copy(self): - "Copy raster data" - - self.load() - im = self.im.copy() - return self._new(im) - - ## - # Returns a rectangular region from this image. The box is a - # 4-tuple defining the left, upper, right, and lower pixel - # coordinate. - #

- # This is a lazy operation. Changes to the source image may or - # may not be reflected in the cropped image. To break the - # connection, call the {@link #Image.load} method on the cropped - # copy. - # - # @param The crop rectangle, as a (left, upper, right, lower)-tuple. - # @return An Image object. - - def crop(self, box=None): - "Crop region from image" - - self.load() - if box is None: - return self.copy() - - # lazy operation - return _ImageCrop(self, box) - - ## - # Configures the image file loader so it returns a version of the - # image that as closely as possible matches the given mode and - # size. For example, you can use this method to convert a colour - # JPEG to greyscale while loading it, or to extract a 128x192 - # version from a PCD file. - #

- # Note that this method modifies the Image object in place. If - # the image has already been loaded, this method has no effect. - # - # @param mode The requested mode. - # @param size The requested size. - - def draft(self, mode, size): - "Configure image decoder" - - pass - - def _expand(self, xmargin, ymargin=None): - if ymargin is None: - ymargin = xmargin - self.load() - return self._new(self.im.expand(xmargin, ymargin, 0)) - - ## - # Filters this image using the given filter. For a list of - # available filters, see the ImageFilter module. - # - # @param filter Filter kernel. - # @return An Image object. - # @see ImageFilter - - def filter(self, filter): - "Apply environment filter to image" - - self.load() - - if callable(filter): - filter = filter() - if not hasattr(filter, "filter"): - raise TypeError("filter argument should be ImageFilter.Filter instance or class") - - if self.im.bands == 1: - return self._new(filter.filter(self.im)) - # fix to handle multiband images since _imaging doesn't - ims = [] - for c in range(self.im.bands): - ims.append(self._new(filter.filter(self.im.getband(c)))) - return merge(self.mode, ims) - - ## - # Returns a tuple containing the name of each band in this image. - # For example, getbands on an RGB image returns ("R", "G", "B"). - # - # @return A tuple containing band names. - - def getbands(self): - "Get band names" - - return ImageMode.getmode(self.mode).bands - - ## - # Calculates the bounding box of the non-zero regions in the - # image. - # - # @return The bounding box is returned as a 4-tuple defining the - # left, upper, right, and lower pixel coordinate. If the image - # is completely empty, this method returns None. - - def getbbox(self): - "Get bounding box of actual data (non-zero pixels) in image" - - self.load() - return self.im.getbbox() - - ## - # Returns a list of colors used in this image. - # - # @param maxcolors Maximum number of colors. If this number is - # exceeded, this method returns None. The default limit is - # 256 colors. - # @return An unsorted list of (count, pixel) values. - - def getcolors(self, maxcolors=256): - "Get colors from image, up to given limit" - - self.load() - if self.mode in ("1", "L", "P"): - h = self.im.histogram() - out = [] - for i in range(256): - if h[i]: - out.append((h[i], i)) - if len(out) > maxcolors: - return None - return out - return self.im.getcolors(maxcolors) - - ## - # Returns the contents of this image as a sequence object - # containing pixel values. The sequence object is flattened, so - # that values for line one follow directly after the values of - # line zero, and so on. - #

- # Note that the sequence object returned by this method is an - # internal PIL data type, which only supports certain sequence - # operations. To convert it to an ordinary sequence (e.g. for - # printing), use list(im.getdata()). - # - # @param band What band to return. The default is to return - # all bands. To return a single band, pass in the index - # value (e.g. 0 to get the "R" band from an "RGB" image). - # @return A sequence-like object. - - def getdata(self, band = None): - "Get image data as sequence object." - - self.load() - if band is not None: - return self.im.getband(band) - return self.im # could be abused - - ## - # Gets the the minimum and maximum pixel values for each band in - # the image. - # - # @return For a single-band image, a 2-tuple containing the - # minimum and maximum pixel value. For a multi-band image, - # a tuple containing one 2-tuple for each band. - - def getextrema(self): - "Get min/max value" - - self.load() - if self.im.bands > 1: - extrema = [] - for i in range(self.im.bands): - extrema.append(self.im.getband(i).getextrema()) - return tuple(extrema) - return self.im.getextrema() - - ## - # Returns a PyCObject that points to the internal image memory. - # - # @return A PyCObject object. - - def getim(self): - "Get PyCObject pointer to internal image memory" - - self.load() - return self.im.ptr - - - ## - # Returns the image palette as a list. - # - # @return A list of color values [r, g, b, ...], or None if the - # image has no palette. - - def getpalette(self): - "Get palette contents." - - self.load() - try: - return map(ord, self.im.getpalette()) - except ValueError: - return None # no palette - - - ## - # Returns the pixel value at a given position. - # - # @param xy The coordinate, given as (x, y). - # @return The pixel value. If the image is a multi-layer image, - # this method returns a tuple. - - def getpixel(self, xy): - "Get pixel value" - - self.load() - return self.im.getpixel(xy) - - ## - # Returns the horizontal and vertical projection. - # - # @return Two sequences, indicating where there are non-zero - # pixels along the X-axis and the Y-axis, respectively. - - def getprojection(self): - "Get projection to x and y axes" - - self.load() - x, y = self.im.getprojection() - return map(ord, x), map(ord, y) - - ## - # Returns a histogram for the image. The histogram is returned as - # a list of pixel counts, one for each pixel value in the source - # image. If the image has more than one band, the histograms for - # all bands are concatenated (for example, the histogram for an - # "RGB" image contains 768 values). - #

- # A bilevel image (mode "1") is treated as a greyscale ("L") image - # by this method. - #

- # If a mask is provided, the method returns a histogram for those - # parts of the image where the mask image is non-zero. The mask - # image must have the same size as the image, and be either a - # bi-level image (mode "1") or a greyscale image ("L"). - # - # @def histogram(mask=None) - # @param mask An optional mask. - # @return A list containing pixel counts. - - def histogram(self, mask=None, extrema=None): - "Take histogram of image" - - self.load() - if mask: - mask.load() - return self.im.histogram((0, 0), mask.im) - if self.mode in ("I", "F"): - if extrema is None: - extrema = self.getextrema() - return self.im.histogram(extrema) - return self.im.histogram() - - ## - # (Deprecated) Returns a copy of the image where the data has been - # offset by the given distances. Data wraps around the edges. If - # yoffset is omitted, it is assumed to be equal to xoffset. - #

- # This method is deprecated. New code should use the offset - # function in the ImageChops module. - # - # @param xoffset The horizontal distance. - # @param yoffset The vertical distance. If omitted, both - # distances are set to the same value. - # @return An Image object. - - def offset(self, xoffset, yoffset=None): - "(deprecated) Offset image in horizontal and/or vertical direction" - if warnings: - warnings.warn( - "'offset' is deprecated; use 'ImageChops.offset' instead", - DeprecationWarning, stacklevel=2 - ) - import ImageChops - return ImageChops.offset(self, xoffset, yoffset) - - ## - # Pastes another image into this image. The box argument is either - # a 2-tuple giving the upper left corner, a 4-tuple defining the - # left, upper, right, and lower pixel coordinate, or None (same as - # (0, 0)). If a 4-tuple is given, the size of the pasted image - # must match the size of the region. - #

- # If the modes don't match, the pasted image is converted to the - # mode of this image (see the {@link #Image.convert} method for - # details). - #

- # Instead of an image, the source can be a integer or tuple - # containing pixel values. The method then fills the region - # with the given colour. When creating RGB images, you can - # also use colour strings as supported by the ImageColor module. - #

- # If a mask is given, this method updates only the regions - # indicated by the mask. You can use either "1", "L" or "RGBA" - # images (in the latter case, the alpha band is used as mask). - # Where the mask is 255, the given image is copied as is. Where - # the mask is 0, the current value is preserved. Intermediate - # values can be used for transparency effects. - #

- # Note that if you paste an "RGBA" image, the alpha band is - # ignored. You can work around this by using the same image as - # both source image and mask. - # - # @param im Source image or pixel value (integer or tuple). - # @param box An optional 4-tuple giving the region to paste into. - # If a 2-tuple is used instead, it's treated as the upper left - # corner. If omitted or None, the source is pasted into the - # upper left corner. - #

- # If an image is given as the second argument and there is no - # third, the box defaults to (0, 0), and the second argument - # is interpreted as a mask image. - # @param mask An optional mask image. - # @return An Image object. - - def paste(self, im, box=None, mask=None): - "Paste other image into region" - - if isImageType(box) and mask is None: - # abbreviated paste(im, mask) syntax - mask = box; box = None - - if box is None: - # cover all of self - box = (0, 0) + self.size - - if len(box) == 2: - # lower left corner given; get size from image or mask - if isImageType(im): - size = im.size - elif isImageType(mask): - size = mask.size - else: - # FIXME: use self.size here? - raise ValueError( - "cannot determine region size; use 4-item box" - ) - box = box + (box[0]+size[0], box[1]+size[1]) - - if isStringType(im): - import ImageColor - im = ImageColor.getcolor(im, self.mode) - - elif isImageType(im): - im.load() - if self.mode != im.mode: - if self.mode != "RGB" or im.mode not in ("RGBA", "RGBa"): - # should use an adapter for this! - im = im.convert(self.mode) - im = im.im - - self.load() - if self.readonly: - self._copy() - - if mask: - mask.load() - self.im.paste(im, box, mask.im) - else: - self.im.paste(im, box) - - ## - # Maps this image through a lookup table or function. - # - # @param lut A lookup table, containing 256 values per band in the - # image. A function can be used instead, it should take a single - # argument. The function is called once for each possible pixel - # value, and the resulting table is applied to all bands of the - # image. - # @param mode Output mode (default is same as input). In the - # current version, this can only be used if the source image - # has mode "L" or "P", and the output has mode "1". - # @return An Image object. - - def point(self, lut, mode=None): - "Map image through lookup table" - - self.load() - - if isinstance(lut, ImagePointHandler): - return lut.point(self) - - if not isSequenceType(lut): - # if it isn't a list, it should be a function - if self.mode in ("I", "I;16", "F"): - # check if the function can be used with point_transform - scale, offset = _getscaleoffset(lut) - return self._new(self.im.point_transform(scale, offset)) - # for other modes, convert the function to a table - lut = map(lut, range(256)) * self.im.bands - - if self.mode == "F": - # FIXME: _imaging returns a confusing error message for this case - raise ValueError("point operation not supported for this mode") - - return self._new(self.im.point(lut, mode)) - - ## - # Adds or replaces the alpha layer in this image. If the image - # does not have an alpha layer, it's converted to "LA" or "RGBA". - # The new layer must be either "L" or "1". - # - # @param im The new alpha layer. This can either be an "L" or "1" - # image having the same size as this image, or an integer or - # other color value. - - def putalpha(self, alpha): - "Set alpha layer" - - self.load() - if self.readonly: - self._copy() - - if self.mode not in ("LA", "RGBA"): - # attempt to promote self to a matching alpha mode - try: - mode = getmodebase(self.mode) + "A" - try: - self.im.setmode(mode) - except (AttributeError, ValueError): - # do things the hard way - im = self.im.convert(mode) - if im.mode not in ("LA", "RGBA"): - raise ValueError # sanity check - self.im = im - self.mode = self.im.mode - except (KeyError, ValueError): - raise ValueError("illegal image mode") - - if self.mode == "LA": - band = 1 - else: - band = 3 - - if isImageType(alpha): - # alpha layer - if alpha.mode not in ("1", "L"): - raise ValueError("illegal image mode") - alpha.load() - if alpha.mode == "1": - alpha = alpha.convert("L") - else: - # constant alpha - try: - self.im.fillband(band, alpha) - except (AttributeError, ValueError): - # do things the hard way - alpha = new("L", self.size, alpha) - else: - return - - self.im.putband(alpha.im, band) - - ## - # Copies pixel data to this image. This method copies data from a - # sequence object into the image, starting at the upper left - # corner (0, 0), and continuing until either the image or the - # sequence ends. The scale and offset values are used to adjust - # the sequence values: pixel = value*scale + offset. - # - # @param data A sequence object. - # @param scale An optional scale value. The default is 1.0. - # @param offset An optional offset value. The default is 0.0. - - def putdata(self, data, scale=1.0, offset=0.0): - "Put data from a sequence object into an image." - - self.load() - if self.readonly: - self._copy() - - self.im.putdata(data, scale, offset) - - ## - # Attaches a palette to this image. The image must be a "P" or - # "L" image, and the palette sequence must contain 768 integer - # values, where each group of three values represent the red, - # green, and blue values for the corresponding pixel - # index. Instead of an integer sequence, you can use an 8-bit - # string. - # - # @def putpalette(data) - # @param data A palette sequence (either a list or a string). - - def putpalette(self, data, rawmode="RGB"): - "Put palette data into an image." - - if self.mode not in ("L", "P"): - raise ValueError("illegal image mode") - self.load() - if isinstance(data, ImagePalette.ImagePalette): - palette = ImagePalette.raw(data.rawmode, data.palette) - else: - if not isStringType(data): - data = string.join(map(chr, data), "") - palette = ImagePalette.raw(rawmode, data) - self.mode = "P" - self.palette = palette - self.palette.mode = "RGB" - self.load() # install new palette - - ## - # Modifies the pixel at the given position. The colour is given as - # a single numerical value for single-band images, and a tuple for - # multi-band images. - #

- # Note that this method is relatively slow. For more extensive - # changes, use {@link #Image.paste} or the ImageDraw module - # instead. - # - # @param xy The pixel coordinate, given as (x, y). - # @param value The pixel value. - # @see #Image.paste - # @see #Image.putdata - # @see ImageDraw - - def putpixel(self, xy, value): - "Set pixel value" - - self.load() - if self.readonly: - self._copy() - - return self.im.putpixel(xy, value) - - ## - # Returns a resized copy of this image. - # - # @def resize(size, filter=NEAREST) - # @param size The requested size in pixels, as a 2-tuple: - # (width, height). - # @param filter An optional resampling filter. This can be - # one of NEAREST (use nearest neighbour), BILINEAR - # (linear interpolation in a 2x2 environment), BICUBIC - # (cubic spline interpolation in a 4x4 environment), or - # ANTIALIAS (a high-quality downsampling filter). - # If omitted, or if the image has mode "1" or "P", it is - # set NEAREST. - # @return An Image object. - - def resize(self, size, resample=NEAREST): - "Resize image" - - if resample not in (NEAREST, BILINEAR, BICUBIC, ANTIALIAS): - raise ValueError("unknown resampling filter") - - self.load() - - if self.mode in ("1", "P"): - resample = NEAREST - - if resample == ANTIALIAS: - # requires stretch support (imToolkit & PIL 1.1.3) - try: - im = self.im.stretch(size, resample) - except AttributeError: - raise ValueError("unsupported resampling filter") - else: - im = self.im.resize(size, resample) - - return self._new(im) - - ## - # Returns a rotated copy of this image. This method returns a - # copy of this image, rotated the given number of degrees counter - # clockwise around its centre. - # - # @def rotate(angle, filter=NEAREST) - # @param angle In degrees counter clockwise. - # @param filter An optional resampling filter. This can be - # one of NEAREST (use nearest neighbour), BILINEAR - # (linear interpolation in a 2x2 environment), or BICUBIC - # (cubic spline interpolation in a 4x4 environment). - # If omitted, or if the image has mode "1" or "P", it is - # set NEAREST. - # @param expand Optional expansion flag. If true, expands the output - # image to make it large enough to hold the entire rotated image. - # If false or omitted, make the output image the same size as the - # input image. - # @return An Image object. - - def rotate(self, angle, resample=NEAREST, expand=0): - "Rotate image. Angle given as degrees counter-clockwise." - - if expand: - import math - angle = -angle * math.pi / 180 - matrix = [ - math.cos(angle), math.sin(angle), 0.0, - -math.sin(angle), math.cos(angle), 0.0 - ] - def transform(x, y, (a, b, c, d, e, f)=matrix): - return a*x + b*y + c, d*x + e*y + f - - # calculate output size - w, h = self.size - xx = [] - yy = [] - for x, y in ((0, 0), (w, 0), (w, h), (0, h)): - x, y = transform(x, y) - xx.append(x) - yy.append(y) - w = int(math.ceil(max(xx)) - math.floor(min(xx))) - h = int(math.ceil(max(yy)) - math.floor(min(yy))) - - # adjust center - x, y = transform(w / 2.0, h / 2.0) - matrix[2] = self.size[0] / 2.0 - x - matrix[5] = self.size[1] / 2.0 - y - - return self.transform((w, h), AFFINE, matrix, resample) - - if resample not in (NEAREST, BILINEAR, BICUBIC): - raise ValueError("unknown resampling filter") - - self.load() - - if self.mode in ("1", "P"): - resample = NEAREST - - return self._new(self.im.rotate(angle, resample)) - - ## - # Saves this image under the given filename. If no format is - # specified, the format to use is determined from the filename - # extension, if possible. - #

- # Keyword options can be used to provide additional instructions - # to the writer. If a writer doesn't recognise an option, it is - # silently ignored. The available options are described later in - # this handbook. - #

- # You can use a file object instead of a filename. In this case, - # you must always specify the format. The file object must - # implement the seek, tell, and write - # methods, and be opened in binary mode. - # - # @def save(file, format=None, **options) - # @param file File name or file object. - # @param format Optional format override. If omitted, the - # format to use is determined from the filename extension. - # If a file object was used instead of a filename, this - # parameter should always be used. - # @param **options Extra parameters to the image writer. - # @return None - # @exception KeyError If the output format could not be determined - # from the file name. Use the format option to solve this. - # @exception IOError If the file could not be written. The file - # may have been created, and may contain partial data. - - def save(self, fp, format=None, **params): - "Save image to file or stream" - - if isStringType(fp): - filename = fp - else: - if hasattr(fp, "name") and isStringType(fp.name): - filename = fp.name - else: - filename = "" - - # may mutate self! - self.load() - - self.encoderinfo = params - self.encoderconfig = () - - preinit() - - ext = string.lower(os.path.splitext(filename)[1]) - - if not format: - try: - format = EXTENSION[ext] - except KeyError: - init() - try: - format = EXTENSION[ext] - except KeyError: - raise KeyError(ext) # unknown extension - - try: - save_handler = SAVE[string.upper(format)] - except KeyError: - init() - save_handler = SAVE[string.upper(format)] # unknown format - - if isStringType(fp): - import __builtin__ - fp = __builtin__.open(fp, "wb") - close = 1 - else: - close = 0 - - try: - save_handler(self, fp, filename) - finally: - # do what we can to clean up - if close: - fp.close() - - ## - # Seeks to the given frame in this sequence file. If you seek - # beyond the end of the sequence, the method raises an - # EOFError exception. When a sequence file is opened, the - # library automatically seeks to frame 0. - #

- # Note that in the current version of the library, most sequence - # formats only allows you to seek to the next frame. - # - # @param frame Frame number, starting at 0. - # @exception EOFError If the call attempts to seek beyond the end - # of the sequence. - # @see #Image.tell - - def seek(self, frame): - "Seek to given frame in sequence file" - - # overridden by file handlers - if frame != 0: - raise EOFError - - ## - # Displays this image. This method is mainly intended for - # debugging purposes. - #

- # On Unix platforms, this method saves the image to a temporary - # PPM file, and calls the xv utility. - #

- # On Windows, it saves the image to a temporary BMP file, and uses - # the standard BMP display utility to show it (usually Paint). - # - # @def show(title=None) - # @param title Optional title to use for the image window, - # where possible. - - def show(self, title=None, command=None): - "Display image (for debug purposes only)" - - _show(self, title=title, command=command) - - ## - # Split this image into individual bands. This method returns a - # tuple of individual image bands from an image. For example, - # splitting an "RGB" image creates three new images each - # containing a copy of one of the original bands (red, green, - # blue). - # - # @return A tuple containing bands. - - def split(self): - "Split image into bands" - - if self.im.bands == 1: - ims = [self.copy()] - else: - ims = [] - self.load() - for i in range(self.im.bands): - ims.append(self._new(self.im.getband(i))) - return tuple(ims) - - ## - # Returns the current frame number. - # - # @return Frame number, starting with 0. - # @see #Image.seek - - def tell(self): - "Return current frame number" - - return 0 - - ## - # Make this image into a thumbnail. This method modifies the - # image to contain a thumbnail version of itself, no larger than - # the given size. This method calculates an appropriate thumbnail - # size to preserve the aspect of the image, calls the {@link - # #Image.draft} method to configure the file reader (where - # applicable), and finally resizes the image. - #

- # Note that the bilinear and bicubic filters in the current - # version of PIL are not well-suited for thumbnail generation. - # You should use ANTIALIAS unless speed is much more - # important than quality. - #

- # Also note that this function modifies the Image object in place. - # If you need to use the full resolution image as well, apply this - # method to a {@link #Image.copy} of the original image. - # - # @param size Requested size. - # @param resample Optional resampling filter. This can be one - # of NEAREST, BILINEAR, BICUBIC, or - # ANTIALIAS (best quality). If omitted, it defaults - # to NEAREST (this will be changed to ANTIALIAS in a - # future version). - # @return None - - def thumbnail(self, size, resample=NEAREST): - "Create thumbnail representation (modifies image in place)" - - # FIXME: the default resampling filter will be changed - # to ANTIALIAS in future versions - - # preserve aspect ratio - x, y = self.size - if x > size[0]: y = max(y * size[0] / x, 1); x = size[0] - if y > size[1]: x = max(x * size[1] / y, 1); y = size[1] - size = x, y - - if size == self.size: - return - - self.draft(None, size) - - self.load() - - try: - im = self.resize(size, resample) - except ValueError: - if resample != ANTIALIAS: - raise - im = self.resize(size, NEAREST) # fallback - - self.im = im.im - self.mode = im.mode - self.size = size - - self.readonly = 0 - - # FIXME: the different tranform methods need further explanation - # instead of bloating the method docs, add a separate chapter. - - ## - # Transforms this image. This method creates a new image with the - # given size, and the same mode as the original, and copies data - # to the new image using the given transform. - #

- # @def transform(size, method, data, resample=NEAREST) - # @param size The output size. - # @param method The transformation method. This is one of - # EXTENT (cut out a rectangular subregion), AFFINE - # (affine transform), PERSPECTIVE (perspective - # transform), QUAD (map a quadrilateral to a - # rectangle), or MESH (map a number of source quadrilaterals - # in one operation). - # @param data Extra data to the transformation method. - # @param resample Optional resampling filter. It can be one of - # NEAREST (use nearest neighbour), BILINEAR - # (linear interpolation in a 2x2 environment), or - # BICUBIC (cubic spline interpolation in a 4x4 - # environment). If omitted, or if the image has mode - # "1" or "P", it is set to NEAREST. - # @return An Image object. - - def transform(self, size, method, data=None, resample=NEAREST, fill=1): - "Transform image" - - if isinstance(method, ImageTransformHandler): - return method.transform(size, self, resample=resample, fill=fill) - if hasattr(method, "getdata"): - # compatibility w. old-style transform objects - method, data = method.getdata() - if data is None: - raise ValueError("missing method data") - im = new(self.mode, size, None) - if method == MESH: - # list of quads - for box, quad in data: - im.__transformer(box, self, QUAD, quad, resample, fill) - else: - im.__transformer((0, 0)+size, self, method, data, resample, fill) - - return im - - def __transformer(self, box, image, method, data, - resample=NEAREST, fill=1): - - # FIXME: this should be turned into a lazy operation (?) - - w = box[2]-box[0] - h = box[3]-box[1] - - if method == AFFINE: - # change argument order to match implementation - data = (data[2], data[0], data[1], - data[5], data[3], data[4]) - elif method == EXTENT: - # convert extent to an affine transform - x0, y0, x1, y1 = data - xs = float(x1 - x0) / w - ys = float(y1 - y0) / h - method = AFFINE - data = (x0 + xs/2, xs, 0, y0 + ys/2, 0, ys) - elif method == PERSPECTIVE: - # change argument order to match implementation - data = (data[2], data[0], data[1], - data[5], data[3], data[4], - data[6], data[7]) - elif method == QUAD: - # quadrilateral warp. data specifies the four corners - # given as NW, SW, SE, and NE. - nw = data[0:2]; sw = data[2:4]; se = data[4:6]; ne = data[6:8] - x0, y0 = nw; As = 1.0 / w; At = 1.0 / h - data = (x0, (ne[0]-x0)*As, (sw[0]-x0)*At, - (se[0]-sw[0]-ne[0]+x0)*As*At, - y0, (ne[1]-y0)*As, (sw[1]-y0)*At, - (se[1]-sw[1]-ne[1]+y0)*As*At) - else: - raise ValueError("unknown transformation method") - - if resample not in (NEAREST, BILINEAR, BICUBIC): - raise ValueError("unknown resampling filter") - - image.load() - - self.load() - - if image.mode in ("1", "P"): - resample = NEAREST - - self.im.transform2(box, image.im, method, data, resample, fill) - - ## - # Returns a flipped or rotated copy of this image. - # - # @param method One of FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, - # ROTATE_90, ROTATE_180, or ROTATE_270. - - def transpose(self, method): - "Transpose image (flip or rotate in 90 degree steps)" - - self.load() - im = self.im.transpose(method) - return self._new(im) - -# -------------------------------------------------------------------- -# Lazy operations - -class _ImageCrop(Image): - - def __init__(self, im, box): - - Image.__init__(self) - - x0, y0, x1, y1 = box - if x1 < x0: - x1 = x0 - if y1 < y0: - y1 = y0 - - self.mode = im.mode - self.size = x1-x0, y1-y0 - - self.__crop = x0, y0, x1, y1 - - self.im = im.im - - def load(self): - - # lazy evaluation! - if self.__crop: - self.im = self.im.crop(self.__crop) - self.__crop = None - - if self.im: - return self.im.pixel_access(self.readonly) - - # FIXME: future versions should optimize crop/paste - # sequences! - -# -------------------------------------------------------------------- -# Abstract handlers. - -class ImagePointHandler: - # used as a mixin by point transforms (for use with im.point) - pass - -class ImageTransformHandler: - # used as a mixin by geometry transforms (for use with im.transform) - pass - -# -------------------------------------------------------------------- -# Factories - -# -# Debugging - -def _wedge(): - "Create greyscale wedge (for debugging only)" - - return Image()._new(core.wedge("L")) - -## -# Creates a new image with the given mode and size. -# -# @param mode The mode to use for the new image. -# @param size A 2-tuple, containing (width, height) in pixels. -# @param color What colour to use for the image. Default is black. -# If given, this should be a single integer or floating point value -# for single-band modes, and a tuple for multi-band modes (one value -# per band). When creating RGB images, you can also use colour -# strings as supported by the ImageColor module. If the colour is -# None, the image is not initialised. -# @return An Image object. - -def new(mode, size, color=0): - "Create a new image" - - if color is None: - # don't initialize - return Image()._new(core.new(mode, size)) - - if isStringType(color): - # css3-style specifier - - import ImageColor - color = ImageColor.getcolor(color, mode) - - return Image()._new(core.fill(mode, size, color)) - -## -# Creates an image memory from pixel data in a string. -#

-# In its simplest form, this function takes three arguments -# (mode, size, and unpacked pixel data). -#

-# Note that this function decodes pixel data only, not entire images. -# If you have an entire image in a string, wrap it in a -# StringIO object, and use {@link #open} to load it. -# -# @param mode The image mode. -# @param size The image size. -# @param data An 8-bit string containing raw data for the given mode. -# @param decoder_name What decoder to use. -# @param *args Additional parameters for the given decoder. -# @return An Image object. - -def fromstring(mode, size, data, decoder_name="raw", *args): - "Load image from string" - - # may pass tuple instead of argument list - if len(args) == 1 and isTupleType(args[0]): - args = args[0] - - if decoder_name == "raw" and args == (): - args = mode - - im = new(mode, size) - im.fromstring(data, decoder_name, args) - return im - -## -# (New in 1.1.4) Creates an image memory from pixel data in a string -# or byte buffer. -#

-# This function is similar to {@link #fromstring}, but uses data in -# the byte buffer, where possible. This means that changes to the -# original buffer object are reflected in this image). Not all modes -# can share memory; supported modes include "L", "RGBX", "RGBA", and -# "CMYK". -#

-# Note that this function decodes pixel data only, not entire images. -# If you have an entire image file in a string, wrap it in a -# StringIO object, and use {@link #open} to load it. -#

-# In the current version, the default parameters used for the "raw" -# decoder differs from that used for {@link fromstring}. This is a -# bug, and will probably be fixed in a future release. The current -# release issues a warning if you do this; to disable the warning, -# you should provide the full set of parameters. See below for -# details. -# -# @param mode The image mode. -# @param size The image size. -# @param data An 8-bit string or other buffer object containing raw -# data for the given mode. -# @param decoder_name What decoder to use. -# @param *args Additional parameters for the given decoder. For the -# default encoder ("raw"), it's recommended that you provide the -# full set of parameters: -# frombuffer(mode, size, data, "raw", mode, 0, 1). -# @return An Image object. -# @since 1.1.4 - -def frombuffer(mode, size, data, decoder_name="raw", *args): - "Load image from string or buffer" - - # may pass tuple instead of argument list - if len(args) == 1 and isTupleType(args[0]): - args = args[0] - - if decoder_name == "raw": - if args == (): - if warnings: - warnings.warn( - "the frombuffer defaults may change in a future release; " - "for portability, change the call to read:\n" - " frombuffer(mode, size, data, 'raw', mode, 0, 1)", - RuntimeWarning, stacklevel=2 - ) - args = mode, 0, -1 # may change to (mode, 0, 1) post-1.1.6 - if args[0] in _MAPMODES: - im = new(mode, (1,1)) - im = im._new( - core.map_buffer(data, size, decoder_name, None, 0, args) - ) - im.readonly = 1 - return im - - return fromstring(mode, size, data, decoder_name, args) - - -## -# (New in 1.1.6) Creates an image memory from an object exporting -# the array interface (using the buffer protocol). -# -# If obj is not contiguous, then the tostring method is called -# and {@link frombuffer} is used. -# -# @param obj Object with array interface -# @param mode Mode to use (will be determined from type if None) -# @return An image memory. - -def fromarray(obj, mode=None): - arr = obj.__array_interface__ - shape = arr['shape'] - ndim = len(shape) - try: - strides = arr['strides'] - except KeyError: - strides = None - if mode is None: - try: - typekey = (1, 1) + shape[2:], arr['typestr'] - mode, rawmode = _fromarray_typemap[typekey] - except KeyError: - # print typekey - raise TypeError("Cannot handle this data type") - else: - rawmode = mode - if mode in ["1", "L", "I", "P", "F"]: - ndmax = 2 - elif mode == "RGB": - ndmax = 3 - else: - ndmax = 4 - if ndim > ndmax: - raise ValueError("Too many dimensions.") - - size = shape[1], shape[0] - if strides is not None: - obj = obj.tostring() - - return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) - -_fromarray_typemap = { - # (shape, typestr) => mode, rawmode - # first two members of shape are set to one - # ((1, 1), "|b1"): ("1", "1"), # broken - ((1, 1), "|u1"): ("L", "L"), - ((1, 1), "|i1"): ("I", "I;8"), - ((1, 1), "i2"): ("I", "I;16B"), - ((1, 1), "i4"): ("I", "I;32B"), - ((1, 1), "f4"): ("F", "F;32BF"), - ((1, 1), "f8"): ("F", "F;64BF"), - ((1, 1, 3), "|u1"): ("RGB", "RGB"), - ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), - } - -# shortcuts -_fromarray_typemap[((1, 1), _ENDIAN + "i4")] = ("I", "I") -_fromarray_typemap[((1, 1), _ENDIAN + "f4")] = ("F", "F") - -## -# Opens and identifies the given image file. -#

-# This is a lazy operation; this function identifies the file, but the -# actual image data is not read from the file until you try to process -# the data (or call the {@link #Image.load} method). -# -# @def open(file, mode="r") -# @param file A filename (string) or a file object. The file object -# must implement read, seek, and tell methods, -# and be opened in binary mode. -# @param mode The mode. If given, this argument must be "r". -# @return An Image object. -# @exception IOError If the file cannot be found, or the image cannot be -# opened and identified. -# @see #new - -def open(fp, mode="r"): - "Open an image file, without loading the raster data" - - if mode != "r": - raise ValueError("bad mode") - - if isStringType(fp): - import __builtin__ - filename = fp - fp = __builtin__.open(fp, "rb") - else: - filename = "" - - prefix = fp.read(16) - - preinit() - - for i in ID: - try: - factory, accept = OPEN[i] - if not accept or accept(prefix): - fp.seek(0) - return factory(fp, filename) - except (SyntaxError, IndexError, TypeError): - pass - - if init(): - - for i in ID: - try: - factory, accept = OPEN[i] - if not accept or accept(prefix): - fp.seek(0) - return factory(fp, filename) - except (SyntaxError, IndexError, TypeError): - pass - - raise IOError("cannot identify image file") - -# -# Image processing. - -## -# Creates a new image by interpolating between two input images, using -# a constant alpha. -# -#

-#    out = image1 * (1.0 - alpha) + image2 * alpha
-# 
-# -# @param im1 The first image. -# @param im2 The second image. Must have the same mode and size as -# the first image. -# @param alpha The interpolation alpha factor. If alpha is 0.0, a -# copy of the first image is returned. If alpha is 1.0, a copy of -# the second image is returned. There are no restrictions on the -# alpha value. If necessary, the result is clipped to fit into -# the allowed output range. -# @return An Image object. - -def blend(im1, im2, alpha): - "Interpolate between images." - - im1.load() - im2.load() - return im1._new(core.blend(im1.im, im2.im, alpha)) - -## -# Creates a new image by interpolating between two input images, -# using the mask as alpha. -# -# @param image1 The first image. -# @param image2 The second image. Must have the same mode and -# size as the first image. -# @param mask A mask image. This image can can have mode -# "1", "L", or "RGBA", and must have the same size as the -# other two images. - -def composite(image1, image2, mask): - "Create composite image by blending images using a transparency mask" - - image = image2.copy() - image.paste(image1, None, mask) - return image - -## -# Applies the function (which should take one argument) to each pixel -# in the given image. If the image has more than one band, the same -# function is applied to each band. Note that the function is -# evaluated once for each possible pixel value, so you cannot use -# random components or other generators. -# -# @def eval(image, function) -# @param image The input image. -# @param function A function object, taking one integer argument. -# @return An Image object. - -def eval(image, *args): - "Evaluate image expression" - - return image.point(args[0]) - -## -# Creates a new image from a number of single-band images. -# -# @param mode The mode to use for the output image. -# @param bands A sequence containing one single-band image for -# each band in the output image. All bands must have the -# same size. -# @return An Image object. - -def merge(mode, bands): - "Merge a set of single band images into a new multiband image." - - if getmodebands(mode) != len(bands) or "*" in mode: - raise ValueError("wrong number of bands") - for im in bands[1:]: - if im.mode != getmodetype(mode): - raise ValueError("mode mismatch") - if im.size != bands[0].size: - raise ValueError("size mismatch") - im = core.new(mode, bands[0].size) - for i in range(getmodebands(mode)): - bands[i].load() - im.putband(bands[i].im, i) - return bands[0]._new(im) - -# -------------------------------------------------------------------- -# Plugin registry - -## -# Register an image file plugin. This function should not be used -# in application code. -# -# @param id An image format identifier. -# @param factory An image file factory method. -# @param accept An optional function that can be used to quickly -# reject images having another format. - -def register_open(id, factory, accept=None): - id = string.upper(id) - ID.append(id) - OPEN[id] = factory, accept - -## -# Registers an image MIME type. This function should not be used -# in application code. -# -# @param id An image format identifier. -# @param mimetype The image MIME type for this format. - -def register_mime(id, mimetype): - MIME[string.upper(id)] = mimetype - -## -# Registers an image save function. This function should not be -# used in application code. -# -# @param id An image format identifier. -# @param driver A function to save images in this format. - -def register_save(id, driver): - SAVE[string.upper(id)] = driver - -## -# Registers an image extension. This function should not be -# used in application code. -# -# @param id An image format identifier. -# @param extension An extension used for this format. - -def register_extension(id, extension): - EXTENSION[string.lower(extension)] = string.upper(id) - - -# -------------------------------------------------------------------- -# Simple display support. User code may override this. - -def _show(image, **options): - # override me, as necessary - apply(_showxv, (image,), options) - -def _showxv(image, title=None, **options): - import ImageShow - apply(ImageShow.show, (image, title), options) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py deleted file mode 100755 index 82861fc7a2c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageChops.py +++ /dev/null @@ -1,302 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# standard channel operations -# -# History: -# 1996-03-24 fl Created -# 1996-08-13 fl Added logical operations (for "1" images) -# 2000-10-12 fl Added offset method (from Image.py) -# -# Copyright (c) 1997-2000 by Secret Labs AB -# Copyright (c) 1996-2000 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image - -## -# The ImageChops module contains a number of arithmetical image -# operations, called channel operations ("chops"). These can be -# used for various purposes, including special effects, image -# compositions, algorithmic painting, and more. -#

-# At this time, channel operations are only implemented for 8-bit -# images (e.g. "L" and "RGB"). -#

-# Most channel operations take one or two image arguments and returns -# a new image. Unless otherwise noted, the result of a channel -# operation is always clipped to the range 0 to MAX (which is 255 for -# all modes supported by the operations in this module). -## - -## -# Return an image with the same size as the given image, but filled -# with the given pixel value. -# -# @param image Reference image. -# @param value Pixel value. -# @return An image object. - -def constant(image, value): - "Fill a channel with a given grey level" - - return Image.new("L", image.size, value) - -## -# Copy image. -# -# @param image Source image. -# @return A copy of the source image. - -def duplicate(image): - "Create a copy of a channel" - - return image.copy() - -## -# Inverts an image -# (MAX - image). -# -# @param image Source image. -# @return An image object. - -def invert(image): - "Invert a channel" - - image.load() - return image._new(image.im.chop_invert()) - -## -# Compare images, and return lighter pixel value -# (max(image1, image2)). -#

-# Compares the two images, pixel by pixel, and returns a new image -# containing the lighter values. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def lighter(image1, image2): - "Select the lighter pixels from each image" - - image1.load() - image2.load() - return image1._new(image1.im.chop_lighter(image2.im)) - -## -# Compare images, and return darker pixel value -# (min(image1, image2)). -#

-# Compares the two images, pixel by pixel, and returns a new image -# containing the darker values. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def darker(image1, image2): - "Select the darker pixels from each image" - - image1.load() - image2.load() - return image1._new(image1.im.chop_darker(image2.im)) - -## -# Calculate absolute difference -# (abs(image1 - image2)). -#

-# Returns the absolute value of the difference between the two images. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def difference(image1, image2): - "Subtract one image from another" - - image1.load() - image2.load() - return image1._new(image1.im.chop_difference(image2.im)) - -## -# Superimpose positive images -# (image1 * image2 / MAX). -#

-# Superimposes two images on top of each other. If you multiply an -# image with a solid black image, the result is black. If you multiply -# with a solid white image, the image is unaffected. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def multiply(image1, image2): - "Superimpose two positive images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_multiply(image2.im)) - -## -# Superimpose negative images -# (MAX - ((MAX - image1) * (MAX - image2) / MAX)). -#

-# Superimposes two inverted images on top of each other. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def screen(image1, image2): - "Superimpose two negative images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_screen(image2.im)) - -## -# Add images -# ((image1 + image2) / scale + offset). -#

-# Adds two images, dividing the result by scale and adding the -# offset. If omitted, scale defaults to 1.0, and offset to 0.0. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def add(image1, image2, scale=1.0, offset=0): - "Add two images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_add(image2.im, scale, offset)) - -## -# Subtract images -# ((image1 - image2) / scale + offset). -#

-# Subtracts two images, dividing the result by scale and adding the -# offset. If omitted, scale defaults to 1.0, and offset to 0.0. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def subtract(image1, image2, scale=1.0, offset=0): - "Subtract two images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_subtract(image2.im, scale, offset)) - -## -# Add images without clipping -# ((image1 + image2) % MAX). -#

-# Adds two images, without clipping the result. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def add_modulo(image1, image2): - "Add two images without clipping" - - image1.load() - image2.load() - return image1._new(image1.im.chop_add_modulo(image2.im)) - -## -# Subtract images without clipping -# ((image1 - image2) % MAX). -#

-# Subtracts two images, without clipping the result. -# -# @param image1 First image. -# @param image1 Second image. -# @return An image object. - -def subtract_modulo(image1, image2): - "Subtract two images without clipping" - - image1.load() - image2.load() - return image1._new(image1.im.chop_subtract_modulo(image2.im)) - -## -# Logical AND -# (image1 and image2). - -def logical_and(image1, image2): - "Logical and between two images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_and(image2.im)) - -## -# Logical OR -# (image1 or image2). - -def logical_or(image1, image2): - "Logical or between two images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_or(image2.im)) - -## -# Logical XOR -# (image1 xor image2). - -def logical_xor(image1, image2): - "Logical xor between two images" - - image1.load() - image2.load() - return image1._new(image1.im.chop_xor(image2.im)) - -## -# Blend images using constant transparency weight. -#

-# Same as the blend function in the Image module. - -def blend(image1, image2, alpha): - "Blend two images using a constant transparency weight" - - return Image.blend(image1, image2, alpha) - -## -# Create composite using transparency mask. -#

-# Same as the composite function in the Image module. - -def composite(image1, image2, mask): - "Create composite image by blending images using a transparency mask" - - return Image.composite(image1, image2, mask) - -## -# Offset image data. -#

-# Returns a copy of the image where data has been offset by the given -# distances. Data wraps around the edges. If yoffset is omitted, it -# is assumed to be equal to xoffset. -# -# @param image Source image. -# @param xoffset The horizontal distance. -# @param yoffset The vertical distance. If omitted, both -# distances are set to the same value. -# @return An Image object. - -def offset(image, xoffset, yoffset=None): - "Offset image in horizontal and/or vertical direction" - if yoffset is None: - yoffset = xoffset - image.load() - return image._new(image.im.offset(xoffset, yoffset)) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py deleted file mode 100755 index b8a6dca71d9..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageCms.py +++ /dev/null @@ -1,786 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# optional color managment support, based on Kevin Cazabon's PyCMS -# library. -# -# History: -# 2009-03-08 fl Added to PIL. -# -# Copyright (C) 2002-2003 Kevin Cazabon -# Copyright (c) 2009 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. See -# below for the original description. -# - -DESCRIPTION = """ -pyCMS - - a Python / PIL interface to the littleCMS ICC Color Management System - Copyright (C) 2002-2003 Kevin Cazabon - kevin@cazabon.com - http://www.cazabon.com - - pyCMS home page: http://www.cazabon.com/pyCMS - littleCMS home page: http://www.littlecms.com - (littleCMS is Copyright (C) 1998-2001 Marti Maria) - - Originally released under LGPL. Graciously donated to PIL in - March 2009, for distribution under the standard PIL license - - The pyCMS.py module provides a "clean" interface between Python/PIL and - pyCMSdll, taking care of some of the more complex handling of the direct - pyCMSdll functions, as well as error-checking and making sure that all - relevant data is kept together. - - While it is possible to call pyCMSdll functions directly, it's not highly - recommended. - - Version History: - - 0.1.0 pil mod March 10, 2009 - - Renamed display profile to proof profile. The proof - profile is the profile of the device that is being - simulated, not the profile of the device which is - actually used to display/print the final simulation - (that'd be the output profile) - also see LCMSAPI.txt - input colorspace -> using 'renderingIntent' -> proof - colorspace -> using 'proofRenderingIntent' -> output - colorspace - - Added LCMS FLAGS support. - Added FLAGS["SOFTPROOFING"] as default flag for - buildProofTransform (otherwise the proof profile/intent - would be ignored). - - 0.1.0 pil March 2009 - added to PIL, as PIL.ImageCms - - 0.0.2 alpha Jan 6, 2002 - - Added try/except statements arount type() checks of - potential CObjects... Python won't let you use type() - on them, and raises a TypeError (stupid, if you ask me!) - - Added buildProofTransformFromOpenProfiles() function. - Additional fixes in DLL, see DLL code for details. - - 0.0.1 alpha first public release, Dec. 26, 2002 - - Known to-do list with current version (of Python interface, not pyCMSdll): - - none - -""" - -VERSION = "0.1.0 pil" - -# --------------------------------------------------------------------. - -import Image -import _imagingcms - -core = _imagingcms - -# -# intent/direction values - -INTENT_PERCEPTUAL = 0 -INTENT_RELATIVE_COLORIMETRIC = 1 -INTENT_SATURATION = 2 -INTENT_ABSOLUTE_COLORIMETRIC = 3 - -DIRECTION_INPUT = 0 -DIRECTION_OUTPUT = 1 -DIRECTION_PROOF = 2 - -# -# flags - -FLAGS = { - "MATRIXINPUT": 1, - "MATRIXOUTPUT": 2, - "MATRIXONLY": (1|2), - "NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot - "NOPRELINEARIZATION": 16, # Don't create prelinearization tables on precalculated transforms (internal use) - "GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink) - "NOTCACHE": 64, # Inhibit 1-pixel cache - "NOTPRECALC": 256, - "NULLTRANSFORM": 512, # Don't transform anyway - "HIGHRESPRECALC": 1024, # Use more memory to give better accurancy - "LOWRESPRECALC": 2048, # Use less memory to minimize resouces - "WHITEBLACKCOMPENSATION": 8192, - "BLACKPOINTCOMPENSATION": 8192, - "GAMUTCHECK": 4096, # Out of Gamut alarm - "SOFTPROOFING": 16384, # Do softproofing - "PRESERVEBLACK": 32768, # Black preservation - "NODEFAULTRESOURCEDEF": 16777216, # CRD special - "GRIDPOINTS": lambda n: ((n) & 0xFF) << 16 # Gridpoints -} - -_MAX_FLAG = 0 -for flag in FLAGS.values(): - if isinstance(flag, type(0)): - _MAX_FLAG = _MAX_FLAG | flag - -# --------------------------------------------------------------------. -# Experimental PIL-level API -# --------------------------------------------------------------------. - -## -# Profile. - -class ImageCmsProfile: - - def __init__(self, profile): - # accepts a string (filename), a file-like object, or a low-level - # profile object - if Image.isStringType(profile): - self._set(core.profile_open(profile), profile) - elif hasattr(profile, "read"): - self._set(core.profile_fromstring(profile.read())) - else: - self._set(profile) # assume it's already a profile - - def _set(self, profile, filename=None): - self.profile = profile - self.filename = filename - if profile: - self.product_name = profile.product_name - self.product_info = profile.product_info - else: - self.product_name = None - self.product_info = None - -## -# Transform. This can be used with the procedural API, or with the -# standard {@link Image.point} method. - -class ImageCmsTransform(Image.ImagePointHandler): - - def __init__(self, input, output, input_mode, output_mode, - intent=INTENT_PERCEPTUAL, - proof=None, proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0): - if proof is None: - self.transform = core.buildTransform( - input.profile, output.profile, - input_mode, output_mode, - intent, - flags - ) - else: - self.transform = core.buildProofTransform( - input.profile, output.profile, proof.profile, - input_mode, output_mode, - intent, proof_intent, - flags - ) - # Note: inputMode and outputMode are for pyCMS compatibility only - self.input_mode = self.inputMode = input_mode - self.output_mode = self.outputMode = output_mode - - def point(self, im): - return self.apply(im) - - def apply(self, im, imOut=None): - im.load() - if imOut is None: - imOut = Image.new(self.output_mode, im.size, None) - result = self.transform.apply(im.im.id, imOut.im.id) - return imOut - - def apply_in_place(self, im): - im.load() - if im.mode != self.output_mode: - raise ValueError("mode mismatch") # wrong output mode - result = self.transform.apply(im.im.id, im.im.id) - return im - -## -# (experimental) Fetches the profile for the current display device. -# Returns None if the profile is not known. - -def get_display_profile(handle=None): - import sys - if sys.platform == "win32": - import ImageWin - if isinstance(handle, ImageWin.HDC): - profile = core.get_display_profile_win32(handle, 1) - else: - profile = core.get_display_profile_win32(handle or 0) - else: - try: - get = _imagingcms.get_display_profile - except AttributeError: - return None - else: - profile = get() - return ImageCmsProfile(profile) - -# --------------------------------------------------------------------. -# pyCMS compatible layer -# --------------------------------------------------------------------. - -## -# (pyCMS) Exception class. This is used for all errors in the pyCMS API. - -class PyCMSError(Exception): - pass - -## -# (pyCMS) Applies an ICC transformation to a given image, mapping from -# inputProfile to outputProfile. - -def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL, outputMode=None, inPlace=0, flags=0): - """ - ImageCms.profileToProfile(im, inputProfile, outputProfile, - [renderingIntent], [outputMode], [inPlace]) - - Returns either None or a new PIL image object, depending on value of - inPlace (see below). - - im = an open PIL image object (i.e. Image.new(...) or - Image.open(...), etc.) - inputProfile = string, as a valid filename path to the ICC input - profile you wish to use for this image, or a profile object - outputProfile = string, as a valid filename path to the ICC output - profile you wish to use for this image, or a profile object - renderingIntent = integer (0-3) specifying the rendering intent you - wish to use for the transform - INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) - INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) - INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) - INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) - - see the pyCMS documentation for details on rendering intents and - what they do. - outputMode = a valid PIL mode for the output image (i.e. "RGB", "CMYK", - etc.). Note: if rendering the image "inPlace", outputMode MUST be - the same mode as the input, or omitted completely. If omitted, the - outputMode will be the same as the mode of the input image (im.mode) - inPlace = BOOL (1 = TRUE, None or 0 = FALSE). If TRUE, the original - image is modified in-place, and None is returned. If FALSE - (default), a new Image object is returned with the transform - applied. - flags = integer (0-...) specifying additional flags - - If the input or output profiles specified are not valid filenames, a - PyCMSError will be raised. If inPlace == TRUE and outputMode != im.mode, - a PyCMSError will be raised. If an error occurs during application of - the profiles, a PyCMSError will be raised. If outputMode is not a mode - supported by the outputProfile (or by pyCMS), a PyCMSError will be - raised. - - This function applies an ICC transformation to im from inputProfile's - color space to outputProfile's color space using the specified rendering - intent to decide how to handle out-of-gamut colors. - - OutputMode can be used to specify that a color mode conversion is to - be done using these profiles, but the specified profiles must be able - to handle that mode. I.e., if converting im from RGB to CMYK using - profiles, the input profile must handle RGB data, and the output - profile must handle CMYK data. - - """ - - if outputMode is None: - outputMode = im.mode - - if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3): - raise PyCMSError("renderingIntent must be an integer between 0 and 3") - - if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG): - raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG) - - try: - if not isinstance(inputProfile, ImageCmsProfile): - inputProfile = ImageCmsProfile(inputProfile) - if not isinstance(outputProfile, ImageCmsProfile): - outputProfile = ImageCmsProfile(outputProfile) - transform = ImageCmsTransform( - inputProfile, outputProfile, im.mode, outputMode, renderingIntent, flags=flags - ) - if inPlace: - transform.apply_in_place(im) - imOut = None - else: - imOut = transform.apply(im) - except (IOError, TypeError, ValueError), v: - raise PyCMSError(v) - - return imOut - -## -# (pyCMS) Opens an ICC profile file. - -def getOpenProfile(profileFilename): - """ - ImageCms.getOpenProfile(profileFilename) - - Returns a CmsProfile class object. - - profileFilename = string, as a valid filename path to the ICC profile - you wish to open, or a file-like object. - - The PyCMSProfile object can be passed back into pyCMS for use in creating - transforms and such (as in ImageCms.buildTransformFromOpenProfiles()). - - If profileFilename is not a vaild filename for an ICC profile, a - PyCMSError will be raised. - - """ - - try: - return ImageCmsProfile(profileFilename) - except (IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Builds an ICC transform mapping from the inputProfile to the -# outputProfile. Use applyTransform to apply the transform to a given -# image. - -def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, flags=0): - """ - ImageCms.buildTransform(inputProfile, outputProfile, inMode, outMode, - [renderingIntent]) - - Returns a CmsTransform class object. - - inputProfile = string, as a valid filename path to the ICC input - profile you wish to use for this transform, or a profile object - outputProfile = string, as a valid filename path to the ICC output - profile you wish to use for this transform, or a profile object - inMode = string, as a valid PIL mode that the appropriate profile also - supports (i.e. "RGB", "RGBA", "CMYK", etc.) - outMode = string, as a valid PIL mode that the appropriate profile also - supports (i.e. "RGB", "RGBA", "CMYK", etc.) - renderingIntent = integer (0-3) specifying the rendering intent you - wish to use for the transform - INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) - INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) - INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) - INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) - see the pyCMS documentation for details on rendering intents and - what they do. - flags = integer (0-...) specifying additional flags - - If the input or output profiles specified are not valid filenames, a - PyCMSError will be raised. If an error occurs during creation of the - transform, a PyCMSError will be raised. - - If inMode or outMode are not a mode supported by the outputProfile (or - by pyCMS), a PyCMSError will be raised. - - This function builds and returns an ICC transform from the inputProfile - to the outputProfile using the renderingIntent to determine what to do - with out-of-gamut colors. It will ONLY work for converting images that - are in inMode to images that are in outMode color format (PIL mode, - i.e. "RGB", "RGBA", "CMYK", etc.). - - Building the transform is a fair part of the overhead in - ImageCms.profileToProfile(), so if you're planning on converting multiple - images using the same input/output settings, this can save you time. - Once you have a transform object, it can be used with - ImageCms.applyProfile() to convert images without the need to re-compute - the lookup table for the transform. - - The reason pyCMS returns a class object rather than a handle directly - to the transform is that it needs to keep track of the PIL input/output - modes that the transform is meant for. These attributes are stored in - the "inMode" and "outMode" attributes of the object (which can be - manually overridden if you really want to, but I don't know of any - time that would be of use, or would even work). - - """ - - if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3): - raise PyCMSError("renderingIntent must be an integer between 0 and 3") - - if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG): - raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG) - - try: - if not isinstance(inputProfile, ImageCmsProfile): - inputProfile = ImageCmsProfile(inputProfile) - if not isinstance(outputProfile, ImageCmsProfile): - outputProfile = ImageCmsProfile(outputProfile) - return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags) - except (IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Builds an ICC transform mapping from the inputProfile to the -# outputProfile, but tries to simulate the result that would be -# obtained on the proofProfile device. - -def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC, flags=FLAGS["SOFTPROOFING"]): - """ - ImageCms.buildProofTransform(inputProfile, outputProfile, proofProfile, - inMode, outMode, [renderingIntent], [proofRenderingIntent]) - - Returns a CmsTransform class object. - - inputProfile = string, as a valid filename path to the ICC input - profile you wish to use for this transform, or a profile object - outputProfile = string, as a valid filename path to the ICC output - (monitor, usually) profile you wish to use for this transform, - or a profile object - proofProfile = string, as a valid filename path to the ICC proof - profile you wish to use for this transform, or a profile object - inMode = string, as a valid PIL mode that the appropriate profile also - supports (i.e. "RGB", "RGBA", "CMYK", etc.) - outMode = string, as a valid PIL mode that the appropriate profile also - supports (i.e. "RGB", "RGBA", "CMYK", etc.) - renderingIntent = integer (0-3) specifying the rendering intent you - wish to use for the input->proof (simulated) transform - INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) - INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) - INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) - INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) - see the pyCMS documentation for details on rendering intents and - what they do. - proofRenderingIntent = integer (0-3) specifying the rendering intent - you wish to use for proof->output transform - INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) - INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) - INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) - INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) - see the pyCMS documentation for details on rendering intents and - what they do. - flags = integer (0-...) specifying additional flags - - If the input, output, or proof profiles specified are not valid - filenames, a PyCMSError will be raised. - - If an error occurs during creation of the transform, a PyCMSError will - be raised. - - If inMode or outMode are not a mode supported by the outputProfile - (or by pyCMS), a PyCMSError will be raised. - - This function builds and returns an ICC transform from the inputProfile - to the outputProfile, but tries to simulate the result that would be - obtained on the proofProfile device using renderingIntent and - proofRenderingIntent to determine what to do with out-of-gamut - colors. This is known as "soft-proofing". It will ONLY work for - converting images that are in inMode to images that are in outMode - color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.). - - Usage of the resulting transform object is exactly the same as with - ImageCms.buildTransform(). - - Proof profiling is generally used when using an output device to get a - good idea of what the final printed/displayed image would look like on - the proofProfile device when it's quicker and easier to use the - output device for judging color. Generally, this means that the - output device is a monitor, or a dye-sub printer (etc.), and the simulated - device is something more expensive, complicated, or time consuming - (making it difficult to make a real print for color judgement purposes). - - Soft-proofing basically functions by adjusting the colors on the - output device to match the colors of the device being simulated. However, - when the simulated device has a much wider gamut than the output - device, you may obtain marginal results. - - """ - - if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3): - raise PyCMSError("renderingIntent must be an integer between 0 and 3") - - if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG): - raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG) - - try: - if not isinstance(inputProfile, ImageCmsProfile): - inputProfile = ImageCmsProfile(inputProfile) - if not isinstance(outputProfile, ImageCmsProfile): - outputProfile = ImageCmsProfile(outputProfile) - if not isinstance(proofProfile, ImageCmsProfile): - proofProfile = ImageCmsProfile(proofProfile) - return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags) - except (IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -buildTransformFromOpenProfiles = buildTransform -buildProofTransformFromOpenProfiles = buildProofTransform - -## -# (pyCMS) Applies a transform to a given image. - -def applyTransform(im, transform, inPlace=0): - """ - ImageCms.applyTransform(im, transform, [inPlace]) - - Returns either None, or a new PIL Image object, depending on the value - of inPlace (see below) - - im = a PIL Image object, and im.mode must be the same as the inMode - supported by the transform. - transform = a valid CmsTransform class object - inPlace = BOOL (1 == TRUE, 0 or None == FALSE). If TRUE, im is - modified in place and None is returned, if FALSE, a new Image - object with the transform applied is returned (and im is not - changed). The default is FALSE. - - If im.mode != transform.inMode, a PyCMSError is raised. - - If inPlace == TRUE and transform.inMode != transform.outMode, a - PyCMSError is raised. - - If im.mode, transfer.inMode, or transfer.outMode is not supported by - pyCMSdll or the profiles you used for the transform, a PyCMSError is - raised. - - If an error occurs while the transform is being applied, a PyCMSError - is raised. - - This function applies a pre-calculated transform (from - ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) to an - image. The transform can be used for multiple images, saving - considerable calcuation time if doing the same conversion multiple times. - - If you want to modify im in-place instead of receiving a new image as - the return value, set inPlace to TRUE. This can only be done if - transform.inMode and transform.outMode are the same, because we can't - change the mode in-place (the buffer sizes for some modes are - different). The default behavior is to return a new Image object of - the same dimensions in mode transform.outMode. - - """ - - try: - if inPlace: - transform.apply_in_place(im) - imOut = None - else: - imOut = transform.apply(im) - except (TypeError, ValueError), v: - raise PyCMSError(v) - - return imOut - -## -# (pyCMS) Creates a profile. - -def createProfile(colorSpace, colorTemp=-1): - """ - ImageCms.createProfile(colorSpace, [colorTemp]) - - Returns a CmsProfile class object - - colorSpace = string, the color space of the profile you wish to create. - Currently only "LAB", "XYZ", and "sRGB" are supported. - colorTemp = positive integer for the white point for the profile, in - degrees Kelvin (i.e. 5000, 6500, 9600, etc.). The default is for - D50 illuminant if omitted (5000k). colorTemp is ONLY applied to - LAB profiles, and is ignored for XYZ and sRGB. - - If colorSpace not in ["LAB", "XYZ", "sRGB"], a PyCMSError is raised - - If using LAB and colorTemp != a positive integer, a PyCMSError is raised. - - If an error occurs while creating the profile, a PyCMSError is raised. - - Use this function to create common profiles on-the-fly instead of - having to supply a profile on disk and knowing the path to it. It - returns a normal CmsProfile object that can be passed to - ImageCms.buildTransformFromOpenProfiles() to create a transform to apply - to images. - - """ - if colorSpace not in ["LAB", "XYZ", "sRGB"]: - raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace) - - if colorSpace == "LAB": - if type(colorTemp) == type(5000.0): - colorTemp = int(colorTemp + 0.5) - if type (colorTemp) != type (5000): - raise PyCMSError("Color temperature must be a positive integer, \"%s\" not valid" % colorTemp) - - try: - return core.createProfile(colorSpace, colorTemp) - except (TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Gets the internal product name for the given profile. - -def getProfileName(profile): - """ - ImageCms.getProfileName(profile) - - Returns a string containing the internal name of the profile as stored - in an ICC tag. - - profile = EITHER a valid CmsProfile object, OR a string of the - filename of an ICC profile. - - If profile isn't a valid CmsProfile object or filename to a profile, - a PyCMSError is raised If an error occurs while trying to obtain the - name tag, a PyCMSError is raised. - - Use this function to obtain the INTERNAL name of the profile (stored - in an ICC tag in the profile itself), usually the one used when the - profile was originally created. Sometimes this tag also contains - additional information supplied by the creator. - - """ - try: - # add an extra newline to preserve pyCMS compatibility - if not isinstance(profile, ImageCmsProfile): - profile = ImageCmsProfile(profile) - return profile.profile.product_name + "\n" - except (AttributeError, IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Gets the internal product information for the given profile. - -def getProfileInfo(profile): - """ - ImageCms.getProfileInfo(profile) - - Returns a string containing the internal profile information stored in - an ICC tag. - - profile = EITHER a valid CmsProfile object, OR a string of the - filename of an ICC profile. - - If profile isn't a valid CmsProfile object or filename to a profile, - a PyCMSError is raised. - - If an error occurs while trying to obtain the info tag, a PyCMSError - is raised - - Use this function to obtain the information stored in the profile's - info tag. This often contains details about the profile, and how it - was created, as supplied by the creator. - - """ - try: - if not isinstance(profile, ImageCmsProfile): - profile = ImageCmsProfile(profile) - # add an extra newline to preserve pyCMS compatibility - return profile.product_info + "\n" - except (AttributeError, IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Gets the default intent name for the given profile. - -def getDefaultIntent(profile): - """ - ImageCms.getDefaultIntent(profile) - - Returns integer 0-3 specifying the default rendering intent for this - profile. - INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) - INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) - INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) - INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) - see the pyCMS documentation for details on rendering intents and - what they do. - - profile = EITHER a valid CmsProfile object, OR a string of the - filename of an ICC profile. - - If profile isn't a valid CmsProfile object or filename to a profile, - a PyCMSError is raised. - - If an error occurs while trying to obtain the default intent, a - PyCMSError is raised. - - Use this function to determine the default (and usually best optomized) - rendering intent for this profile. Most profiles support multiple - rendering intents, but are intended mostly for one type of conversion. - If you wish to use a different intent than returned, use - ImageCms.isIntentSupported() to verify it will work first. - """ - try: - if not isinstance(profile, ImageCmsProfile): - profile = ImageCmsProfile(profile) - return profile.profile.rendering_intent - except (AttributeError, IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Checks if a given intent is supported. - -def isIntentSupported(profile, intent, direction): - """ - ImageCms.isIntentSupported(profile, intent, direction) - - Returns 1 if the intent/direction are supported, -1 if they are not. - - profile = EITHER a valid CmsProfile object, OR a string of the - filename of an ICC profile. - intent = integer (0-3) specifying the rendering intent you wish to use - with this profile - INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL) - INTENT_RELATIVE_COLORIMETRIC =1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC) - INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION) - INTENT_ABSOLUTE_COLORIMETRIC =3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC) - see the pyCMS documentation for details on rendering intents and - what they do. - direction = integer specifing if the profile is to be used for input, - output, or proof - INPUT = 0 (or use ImageCms.DIRECTION_INPUT) - OUTPUT = 1 (or use ImageCms.DIRECTION_OUTPUT) - PROOF = 2 (or use ImageCms.DIRECTION_PROOF) - - Use this function to verify that you can use your desired - renderingIntent with profile, and that profile can be used for the - input/output/proof profile as you desire. - - Some profiles are created specifically for one "direction", can cannot - be used for others. Some profiles can only be used for certain - rendering intents... so it's best to either verify this before trying - to create a transform with them (using this function), or catch the - potential PyCMSError that will occur if they don't support the modes - you select. - - """ - try: - if not isinstance(profile, ImageCmsProfile): - profile = ImageCmsProfile(profile) - # FIXME: I get different results for the same data w. different - # compilers. Bug in LittleCMS or in the binding? - if profile.profile.is_intent_supported(intent, direction): - return 1 - else: - return -1 - except (AttributeError, IOError, TypeError, ValueError), v: - raise PyCMSError(v) - -## -# (pyCMS) Fetches versions. - -def versions(): - import sys - return ( - VERSION, core.littlecms_version, sys.version.split()[0], Image.VERSION - ) - -# -------------------------------------------------------------------- - -if __name__ == "__main__": - # create a cheap manual from the __doc__ strings for the functions above - - import ImageCms - import string - print __doc__ - - for f in dir(pyCMS): - print "="*80 - print "%s" %f - - try: - exec ("doc = ImageCms.%s.__doc__" %(f)) - if string.find(doc, "pyCMS") >= 0: - # so we don't get the __doc__ string for imported modules - print doc - except AttributeError: - pass diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py deleted file mode 100755 index c3cca46db8f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageColor.py +++ /dev/null @@ -1,263 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# map CSS3-style colour description strings to RGB -# -# History: -# 2002-10-24 fl Added support for CSS-style color strings -# 2002-12-15 fl Added RGBA support -# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2 -# 2004-07-19 fl Fixed gray/grey spelling issues -# 2009-03-05 fl Fixed rounding error in grayscale calculation -# -# Copyright (c) 2002-2004 by Secret Labs AB -# Copyright (c) 2002-2004 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image -import re, string - -try: - x = int("a", 16) -except TypeError: - # python 1.5.2 doesn't support int(x,b) - str2int = string.atoi -else: - str2int = int - -## -# Convert color string to RGB tuple. -# -# @param color A CSS3-style colour string. -# @return An RGB-tuple. -# @exception ValueError If the color string could not be interpreted -# as an RGB value. - -def getrgb(color): - # FIXME: add RGBA support - try: - rgb = colormap[color] - except KeyError: - try: - # fall back on case-insensitive lookup - rgb = colormap[string.lower(color)] - except KeyError: - rgb = None - # found color in cache - if rgb: - if isinstance(rgb, type(())): - return rgb - colormap[color] = rgb = getrgb(rgb) - return rgb - # check for known string formats - m = re.match("#\w\w\w$", color) - if m: - return ( - str2int(color[1]*2, 16), - str2int(color[2]*2, 16), - str2int(color[3]*2, 16) - ) - m = re.match("#\w\w\w\w\w\w$", color) - if m: - return ( - str2int(color[1:3], 16), - str2int(color[3:5], 16), - str2int(color[5:7], 16) - ) - m = re.match("rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) - if m: - return ( - str2int(m.group(1)), - str2int(m.group(2)), - str2int(m.group(3)) - ) - m = re.match("rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) - if m: - return ( - int((str2int(m.group(1)) * 255) / 100.0 + 0.5), - int((str2int(m.group(2)) * 255) / 100.0 + 0.5), - int((str2int(m.group(3)) * 255) / 100.0 + 0.5) - ) - m = re.match("hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) - if m: - from colorsys import hls_to_rgb - rgb = hls_to_rgb( - float(m.group(1)) / 360.0, - float(m.group(3)) / 100.0, - float(m.group(2)) / 100.0, - ) - return ( - int(rgb[0] * 255 + 0.5), - int(rgb[1] * 255 + 0.5), - int(rgb[2] * 255 + 0.5) - ) - raise ValueError("unknown color specifier: %r" % color) - -def getcolor(color, mode): - # same as getrgb, but converts the result to the given mode - color = getrgb(color) - if mode == "RGB": - return color - if mode == "RGBA": - r, g, b = color - return r, g, b, 255 - if Image.getmodebase(mode) == "L": - r, g, b = color - return (r*299 + g*587 + b*114)/1000 - return color - -colormap = { - # X11 colour table (from "CSS3 module: Color working draft"), with - # gray/grey spelling issues fixed. This is a superset of HTML 4.0 - # colour names used in CSS 1. - "aliceblue": "#f0f8ff", - "antiquewhite": "#faebd7", - "aqua": "#00ffff", - "aquamarine": "#7fffd4", - "azure": "#f0ffff", - "beige": "#f5f5dc", - "bisque": "#ffe4c4", - "black": "#000000", - "blanchedalmond": "#ffebcd", - "blue": "#0000ff", - "blueviolet": "#8a2be2", - "brown": "#a52a2a", - "burlywood": "#deb887", - "cadetblue": "#5f9ea0", - "chartreuse": "#7fff00", - "chocolate": "#d2691e", - "coral": "#ff7f50", - "cornflowerblue": "#6495ed", - "cornsilk": "#fff8dc", - "crimson": "#dc143c", - "cyan": "#00ffff", - "darkblue": "#00008b", - "darkcyan": "#008b8b", - "darkgoldenrod": "#b8860b", - "darkgray": "#a9a9a9", - "darkgrey": "#a9a9a9", - "darkgreen": "#006400", - "darkkhaki": "#bdb76b", - "darkmagenta": "#8b008b", - "darkolivegreen": "#556b2f", - "darkorange": "#ff8c00", - "darkorchid": "#9932cc", - "darkred": "#8b0000", - "darksalmon": "#e9967a", - "darkseagreen": "#8fbc8f", - "darkslateblue": "#483d8b", - "darkslategray": "#2f4f4f", - "darkslategrey": "#2f4f4f", - "darkturquoise": "#00ced1", - "darkviolet": "#9400d3", - "deeppink": "#ff1493", - "deepskyblue": "#00bfff", - "dimgray": "#696969", - "dimgrey": "#696969", - "dodgerblue": "#1e90ff", - "firebrick": "#b22222", - "floralwhite": "#fffaf0", - "forestgreen": "#228b22", - "fuchsia": "#ff00ff", - "gainsboro": "#dcdcdc", - "ghostwhite": "#f8f8ff", - "gold": "#ffd700", - "goldenrod": "#daa520", - "gray": "#808080", - "grey": "#808080", - "green": "#008000", - "greenyellow": "#adff2f", - "honeydew": "#f0fff0", - "hotpink": "#ff69b4", - "indianred": "#cd5c5c", - "indigo": "#4b0082", - "ivory": "#fffff0", - "khaki": "#f0e68c", - "lavender": "#e6e6fa", - "lavenderblush": "#fff0f5", - "lawngreen": "#7cfc00", - "lemonchiffon": "#fffacd", - "lightblue": "#add8e6", - "lightcoral": "#f08080", - "lightcyan": "#e0ffff", - "lightgoldenrodyellow": "#fafad2", - "lightgreen": "#90ee90", - "lightgray": "#d3d3d3", - "lightgrey": "#d3d3d3", - "lightpink": "#ffb6c1", - "lightsalmon": "#ffa07a", - "lightseagreen": "#20b2aa", - "lightskyblue": "#87cefa", - "lightslategray": "#778899", - "lightslategrey": "#778899", - "lightsteelblue": "#b0c4de", - "lightyellow": "#ffffe0", - "lime": "#00ff00", - "limegreen": "#32cd32", - "linen": "#faf0e6", - "magenta": "#ff00ff", - "maroon": "#800000", - "mediumaquamarine": "#66cdaa", - "mediumblue": "#0000cd", - "mediumorchid": "#ba55d3", - "mediumpurple": "#9370db", - "mediumseagreen": "#3cb371", - "mediumslateblue": "#7b68ee", - "mediumspringgreen": "#00fa9a", - "mediumturquoise": "#48d1cc", - "mediumvioletred": "#c71585", - "midnightblue": "#191970", - "mintcream": "#f5fffa", - "mistyrose": "#ffe4e1", - "moccasin": "#ffe4b5", - "navajowhite": "#ffdead", - "navy": "#000080", - "oldlace": "#fdf5e6", - "olive": "#808000", - "olivedrab": "#6b8e23", - "orange": "#ffa500", - "orangered": "#ff4500", - "orchid": "#da70d6", - "palegoldenrod": "#eee8aa", - "palegreen": "#98fb98", - "paleturquoise": "#afeeee", - "palevioletred": "#db7093", - "papayawhip": "#ffefd5", - "peachpuff": "#ffdab9", - "peru": "#cd853f", - "pink": "#ffc0cb", - "plum": "#dda0dd", - "powderblue": "#b0e0e6", - "purple": "#800080", - "red": "#ff0000", - "rosybrown": "#bc8f8f", - "royalblue": "#4169e1", - "saddlebrown": "#8b4513", - "salmon": "#fa8072", - "sandybrown": "#f4a460", - "seagreen": "#2e8b57", - "seashell": "#fff5ee", - "sienna": "#a0522d", - "silver": "#c0c0c0", - "skyblue": "#87ceeb", - "slateblue": "#6a5acd", - "slategray": "#708090", - "slategrey": "#708090", - "snow": "#fffafa", - "springgreen": "#00ff7f", - "steelblue": "#4682b4", - "tan": "#d2b48c", - "teal": "#008080", - "thistle": "#d8bfd8", - "tomato": "#ff6347", - "turquoise": "#40e0d0", - "violet": "#ee82ee", - "wheat": "#f5deb3", - "white": "#ffffff", - "whitesmoke": "#f5f5f5", - "yellow": "#ffff00", - "yellowgreen": "#9acd32", -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py deleted file mode 100755 index 5217a7366fe..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw.py +++ /dev/null @@ -1,378 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# drawing interface operations -# -# History: -# 1996-04-13 fl Created (experimental) -# 1996-08-07 fl Filled polygons, ellipses. -# 1996-08-13 fl Added text support -# 1998-06-28 fl Handle I and F images -# 1998-12-29 fl Added arc; use arc primitive to draw ellipses -# 1999-01-10 fl Added shape stuff (experimental) -# 1999-02-06 fl Added bitmap support -# 1999-02-11 fl Changed all primitives to take options -# 1999-02-20 fl Fixed backwards compatibility -# 2000-10-12 fl Copy on write, when necessary -# 2001-02-18 fl Use default ink for bitmap/text also in fill mode -# 2002-10-24 fl Added support for CSS-style color strings -# 2002-12-10 fl Added experimental support for RGBA-on-RGB drawing -# 2002-12-11 fl Refactored low-level drawing API (work in progress) -# 2004-08-26 fl Made Draw() a factory function, added getdraw() support -# 2004-09-04 fl Added width support to line primitive -# 2004-09-10 fl Added font mode handling -# 2006-06-19 fl Added font bearing support (getmask2) -# -# Copyright (c) 1997-2006 by Secret Labs AB -# Copyright (c) 1996-2006 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageColor - -try: - import warnings -except ImportError: - warnings = None - -## -# A simple 2D drawing interface for PIL images. -#

-# Application code should use the Draw factory, instead of -# directly. - -class ImageDraw: - - ## - # Create a drawing instance. - # - # @param im The image to draw in. - # @param mode Optional mode to use for color values. For RGB - # images, this argument can be RGB or RGBA (to blend the - # drawing into the image). For all other modes, this argument - # must be the same as the image mode. If omitted, the mode - # defaults to the mode of the image. - - def __init__(self, im, mode=None): - im.load() - if im.readonly: - im._copy() # make it writable - blend = 0 - if mode is None: - mode = im.mode - if mode != im.mode: - if mode == "RGBA" and im.mode == "RGB": - blend = 1 - else: - raise ValueError("mode mismatch") - if mode == "P": - self.palette = im.palette - else: - self.palette = None - self.im = im.im - self.draw = Image.core.draw(self.im, blend) - self.mode = mode - if mode in ("I", "F"): - self.ink = self.draw.draw_ink(1, mode) - else: - self.ink = self.draw.draw_ink(-1, mode) - if mode in ("1", "P", "I", "F"): - # FIXME: fix Fill2 to properly support matte for I+F images - self.fontmode = "1" - else: - self.fontmode = "L" # aliasing is okay for other modes - self.fill = 0 - self.font = None - - ## - # Set the default pen color. - - def setink(self, ink): - # compatibility - if warnings: - warnings.warn( - "'setink' is deprecated; use keyword arguments instead", - DeprecationWarning, stacklevel=2 - ) - if Image.isStringType(ink): - ink = ImageColor.getcolor(ink, self.mode) - if self.palette and not Image.isNumberType(ink): - ink = self.palette.getcolor(ink) - self.ink = self.draw.draw_ink(ink, self.mode) - - ## - # Set the default background color. - - def setfill(self, onoff): - # compatibility - if warnings: - warnings.warn( - "'setfill' is deprecated; use keyword arguments instead", - DeprecationWarning, stacklevel=2 - ) - self.fill = onoff - - ## - # Set the default font. - - def setfont(self, font): - # compatibility - self.font = font - - ## - # Get the current default font. - - def getfont(self): - if not self.font: - # FIXME: should add a font repository - import ImageFont - self.font = ImageFont.load_default() - return self.font - - def _getink(self, ink, fill=None): - if ink is None and fill is None: - if self.fill: - fill = self.ink - else: - ink = self.ink - else: - if ink is not None: - if Image.isStringType(ink): - ink = ImageColor.getcolor(ink, self.mode) - if self.palette and not Image.isNumberType(ink): - ink = self.palette.getcolor(ink) - ink = self.draw.draw_ink(ink, self.mode) - if fill is not None: - if Image.isStringType(fill): - fill = ImageColor.getcolor(fill, self.mode) - if self.palette and not Image.isNumberType(fill): - fill = self.palette.getcolor(fill) - fill = self.draw.draw_ink(fill, self.mode) - return ink, fill - - ## - # Draw an arc. - - def arc(self, xy, start, end, fill=None): - ink, fill = self._getink(fill) - if ink is not None: - self.draw.draw_arc(xy, start, end, ink) - - ## - # Draw a bitmap. - - def bitmap(self, xy, bitmap, fill=None): - bitmap.load() - ink, fill = self._getink(fill) - if ink is None: - ink = fill - if ink is not None: - self.draw.draw_bitmap(xy, bitmap.im, ink) - - ## - # Draw a chord. - - def chord(self, xy, start, end, fill=None, outline=None): - ink, fill = self._getink(outline, fill) - if fill is not None: - self.draw.draw_chord(xy, start, end, fill, 1) - if ink is not None: - self.draw.draw_chord(xy, start, end, ink, 0) - - ## - # Draw an ellipse. - - def ellipse(self, xy, fill=None, outline=None): - ink, fill = self._getink(outline, fill) - if fill is not None: - self.draw.draw_ellipse(xy, fill, 1) - if ink is not None: - self.draw.draw_ellipse(xy, ink, 0) - - ## - # Draw a line, or a connected sequence of line segments. - - def line(self, xy, fill=None, width=0): - ink, fill = self._getink(fill) - if ink is not None: - self.draw.draw_lines(xy, ink, width) - - ## - # (Experimental) Draw a shape. - - def shape(self, shape, fill=None, outline=None): - # experimental - shape.close() - ink, fill = self._getink(outline, fill) - if fill is not None: - self.draw.draw_outline(shape, fill, 1) - if ink is not None: - self.draw.draw_outline(shape, ink, 0) - - ## - # Draw a pieslice. - - def pieslice(self, xy, start, end, fill=None, outline=None): - ink, fill = self._getink(outline, fill) - if fill is not None: - self.draw.draw_pieslice(xy, start, end, fill, 1) - if ink is not None: - self.draw.draw_pieslice(xy, start, end, ink, 0) - - ## - # Draw one or more individual pixels. - - def point(self, xy, fill=None): - ink, fill = self._getink(fill) - if ink is not None: - self.draw.draw_points(xy, ink) - - ## - # Draw a polygon. - - def polygon(self, xy, fill=None, outline=None): - ink, fill = self._getink(outline, fill) - if fill is not None: - self.draw.draw_polygon(xy, fill, 1) - if ink is not None: - self.draw.draw_polygon(xy, ink, 0) - - ## - # Draw a rectangle. - - def rectangle(self, xy, fill=None, outline=None): - ink, fill = self._getink(outline, fill) - if fill is not None: - self.draw.draw_rectangle(xy, fill, 1) - if ink is not None: - self.draw.draw_rectangle(xy, ink, 0) - - ## - # Draw text. - - def text(self, xy, text, fill=None, font=None, anchor=None): - ink, fill = self._getink(fill) - if font is None: - font = self.getfont() - if ink is None: - ink = fill - if ink is not None: - try: - mask, offset = font.getmask2(text, self.fontmode) - xy = xy[0] + offset[0], xy[1] + offset[1] - except AttributeError: - try: - mask = font.getmask(text, self.fontmode) - except TypeError: - mask = font.getmask(text) - self.draw.draw_bitmap(xy, mask, ink) - - ## - # Get the size of a given string, in pixels. - - def textsize(self, text, font=None): - if font is None: - font = self.getfont() - return font.getsize(text) - -## -# A simple 2D drawing interface for PIL images. -# -# @param im The image to draw in. -# @param mode Optional mode to use for color values. For RGB -# images, this argument can be RGB or RGBA (to blend the -# drawing into the image). For all other modes, this argument -# must be the same as the image mode. If omitted, the mode -# defaults to the mode of the image. - -def Draw(im, mode=None): - try: - return im.getdraw(mode) - except AttributeError: - return ImageDraw(im, mode) - -# experimental access to the outline API -try: - Outline = Image.core.outline -except: - Outline = None - -## -# (Experimental) A more advanced 2D drawing interface for PIL images, -# based on the WCK interface. -# -# @param im The image to draw in. -# @param hints An optional list of hints. -# @return A (drawing context, drawing resource factory) tuple. - -def getdraw(im=None, hints=None): - # FIXME: this needs more work! - # FIXME: come up with a better 'hints' scheme. - handler = None - if not hints or "nicest" in hints: - try: - import _imagingagg - handler = _imagingagg - except ImportError: - pass - if handler is None: - import ImageDraw2 - handler = ImageDraw2 - if im: - im = handler.Draw(im) - return im, handler - -## -# (experimental) Fills a bounded region with a given color. -# -# @param image Target image. -# @param xy Seed position (a 2-item coordinate tuple). -# @param value Fill color. -# @param border Optional border value. If given, the region consists of -# pixels with a color different from the border color. If not given, -# the region consists of pixels having the same color as the seed -# pixel. - -def floodfill(image, xy, value, border=None): - "Fill bounded region." - # based on an implementation by Eric S. Raymond - pixel = image.load() - x, y = xy - try: - background = pixel[x, y] - if background == value: - return # seed point already has fill color - pixel[x, y] = value - except IndexError: - return # seed point outside image - edge = [(x, y)] - if border is None: - while edge: - newedge = [] - for (x, y) in edge: - for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)): - try: - p = pixel[s, t] - except IndexError: - pass - else: - if p == background: - pixel[s, t] = value - newedge.append((s, t)) - edge = newedge - else: - while edge: - newedge = [] - for (x, y) in edge: - for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)): - try: - p = pixel[s, t] - except IndexError: - pass - else: - if p != value and p != border: - pixel[s, t] = value - newedge.append((s, t)) - edge = newedge diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py deleted file mode 100755 index dbf1a1f8893..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageDraw2.py +++ /dev/null @@ -1,105 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# WCK-style drawing interface operations -# -# History: -# 2003-12-07 fl created -# 2005-05-15 fl updated; added to PIL as ImageDraw2 -# 2005-05-15 fl added text support -# 2005-05-20 fl added arc/chord/pieslice support -# -# Copyright (c) 2003-2005 by Secret Labs AB -# Copyright (c) 2003-2005 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageColor, ImageDraw, ImageFont, ImagePath - -class Pen: - def __init__(self, color, width=1, opacity=255): - self.color = ImageColor.getrgb(color) - self.width = width - -class Brush: - def __init__(self, color, opacity=255): - self.color = ImageColor.getrgb(color) - -class Font: - def __init__(self, color, file, size=12): - # FIXME: add support for bitmap fonts - self.color = ImageColor.getrgb(color) - self.font = ImageFont.truetype(file, size) - -class Draw: - - def __init__(self, image, size=None, color=None): - if not hasattr(image, "im"): - image = Image.new(image, size, color) - self.draw = ImageDraw.Draw(image) - self.image = image - self.transform = None - - def flush(self): - return self.image - - def render(self, op, xy, pen, brush=None): - # handle color arguments - outline = fill = None; width = 1 - if isinstance(pen, Pen): - outline = pen.color - width = pen.width - elif isinstance(brush, Pen): - outline = brush.color - width = brush.width - if isinstance(brush, Brush): - fill = brush.color - elif isinstance(pen, Brush): - fill = pen.color - # handle transformation - if self.transform: - xy = ImagePath.Path(xy) - xy.transform(self.transform) - # render the item - if op == "line": - self.draw.line(xy, fill=outline, width=width) - else: - getattr(self.draw, op)(xy, fill=fill, outline=outline) - - def settransform(self, (xoffset, yoffset)): - self.transform = (1, 0, xoffset, 0, 1, yoffset) - - def arc(self, xy, start, end, *options): - self.render("arc", xy, start, end, *options) - - def chord(self, xy, start, end, *options): - self.render("chord", xy, start, end, *options) - - def ellipse(self, xy, *options): - self.render("ellipse", xy, *options) - - def line(self, xy, *options): - self.render("line", xy, *options) - - def pieslice(self, xy, start, end, *options): - self.render("pieslice", xy, start, end, *options) - - def polygon(self, xy, *options): - self.render("polygon", xy, *options) - - def rectangle(self, xy, *options): - self.render("rectangle", xy, *options) - - def symbol(self, xy, symbol, *options): - raise NotImplementedError("not in this version") - - def text(self, xy, text, font): - if self.transform: - xy = ImagePath.Path(xy) - xy.transform(self.transform) - self.draw.text(xy, text, font=font.font, fill=font.color) - - def textsize(self, text, font): - return self.draw.textsize(text, font=font.font) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py deleted file mode 100755 index 86a19e650e2..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageEnhance.py +++ /dev/null @@ -1,90 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# image enhancement classes -# -# For a background, see "Image Processing By Interpolation and -# Extrapolation", Paul Haeberli and Douglas Voorhies. Available -# at http://www.sgi.com/grafica/interp/index.html -# -# History: -# 1996-03-23 fl Created -# 2009-06-16 fl Fixed mean calculation -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - -import Image, ImageFilter, ImageStat - -class _Enhance: - - ## - # Returns an enhanced image. The enhancement factor is a floating - # point value controlling the enhancement. Factor 1.0 always - # returns a copy of the original image, lower factors mean less - # colour (brightness, contrast, etc), and higher values more. - # There are no restrictions on this value. - # - # @param factor Enhancement factor. - # @return An enhanced image. - - def enhance(self, factor): - return Image.blend(self.degenerate, self.image, factor) - -## -# Color enhancement object. -#

-# This class can be used to adjust the colour balance of an image, in -# a manner similar to the controls on a colour TV set. An enhancement -# factor of 0.0 gives a black and white image, a factor of 1.0 gives -# the original image. - -class Color(_Enhance): - "Adjust image colour balance" - def __init__(self, image): - self.image = image - self.degenerate = image.convert("L").convert(image.mode) - -## -# Contrast enhancement object. -#

-# This class can be used to control the contrast of an image, similar -# to the contrast control on a TV set. An enhancement factor of 0.0 -# gives a solid grey image, factor 1.0 gives the original image. - -class Contrast(_Enhance): - "Adjust image contrast" - def __init__(self, image): - self.image = image - mean = int(ImageStat.Stat(image.convert("L")).mean[0] + 0.5) - self.degenerate = Image.new("L", image.size, mean).convert(image.mode) - -## -# Brightness enhancement object. -#

-# This class can be used to control the brighntess of an image. An -# enhancement factor of 0.0 gives a black image, factor 1.0 gives the -# original image. - -class Brightness(_Enhance): - "Adjust image brightness" - def __init__(self, image): - self.image = image - self.degenerate = Image.new(image.mode, image.size, 0) - -## -# Sharpness enhancement object. -#

-# This class can be used to adjust the sharpness of an image. The -# enhancement factor 0.0 gives a blurred image, 1.0 gives the original -# image, and a factor of 2.0 gives a sharpened image. - -class Sharpness(_Enhance): - "Adjust image sharpness" - def __init__(self, image): - self.image = image - self.degenerate = image.filter(ImageFilter.SMOOTH) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py deleted file mode 100755 index 8a97c1b5b34..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFile.py +++ /dev/null @@ -1,528 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# base class for image file handlers -# -# history: -# 1995-09-09 fl Created -# 1996-03-11 fl Fixed load mechanism. -# 1996-04-15 fl Added pcx/xbm decoders. -# 1996-04-30 fl Added encoders. -# 1996-12-14 fl Added load helpers -# 1997-01-11 fl Use encode_to_file where possible -# 1997-08-27 fl Flush output in _save -# 1998-03-05 fl Use memory mapping for some modes -# 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B" -# 1999-05-31 fl Added image parser -# 2000-10-12 fl Set readonly flag on memory-mapped images -# 2002-03-20 fl Use better messages for common decoder errors -# 2003-04-21 fl Fall back on mmap/map_buffer if map is not available -# 2003-10-30 fl Added StubImageFile class -# 2004-02-25 fl Made incremental parser more robust -# -# Copyright (c) 1997-2004 by Secret Labs AB -# Copyright (c) 1995-2004 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image -import traceback, string, os - -MAXBLOCK = 65536 - -SAFEBLOCK = 1024*1024 - -ERRORS = { - -1: "image buffer overrun error", - -2: "decoding error", - -3: "unknown error", - -8: "bad configuration", - -9: "out of memory error" -} - -def raise_ioerror(error): - try: - message = Image.core.getcodecstatus(error) - except AttributeError: - message = ERRORS.get(error) - if not message: - message = "decoder error %d" % error - raise IOError(message + " when reading image file") - -# -# -------------------------------------------------------------------- -# Helpers - -def _tilesort(t1, t2): - # sort on offset - return cmp(t1[2], t2[2]) - -# -# -------------------------------------------------------------------- -# ImageFile base class - -## -# Base class for image file handlers. - -class ImageFile(Image.Image): - "Base class for image file format handlers." - - def __init__(self, fp=None, filename=None): - Image.Image.__init__(self) - - self.tile = None - self.readonly = 1 # until we know better - - self.decoderconfig = () - self.decodermaxblock = MAXBLOCK - - if Image.isStringType(fp): - # filename - self.fp = open(fp, "rb") - self.filename = fp - else: - # stream - self.fp = fp - self.filename = filename - - try: - self._open() - except IndexError, v: # end of data - if Image.DEBUG > 1: - traceback.print_exc() - raise SyntaxError, v - except TypeError, v: # end of data (ord) - if Image.DEBUG > 1: - traceback.print_exc() - raise SyntaxError, v - except KeyError, v: # unsupported mode - if Image.DEBUG > 1: - traceback.print_exc() - raise SyntaxError, v - except EOFError, v: # got header but not the first frame - if Image.DEBUG > 1: - traceback.print_exc() - raise SyntaxError, v - - if not self.mode or self.size[0] <= 0: - raise SyntaxError, "not identified by this driver" - - def draft(self, mode, size): - "Set draft mode" - - pass - - def verify(self): - "Check file integrity" - - # raise exception if something's wrong. must be called - # directly after open, and closes file when finished. - self.fp = None - - def load(self): - "Load image data based on tile list" - - pixel = Image.Image.load(self) - - if self.tile is None: - raise IOError("cannot load this image") - if not self.tile: - return pixel - - self.map = None - - readonly = 0 - - if self.filename and len(self.tile) == 1: - # try memory mapping - d, e, o, a = self.tile[0] - if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES: - try: - if hasattr(Image.core, "map"): - # use built-in mapper - self.map = Image.core.map(self.filename) - self.map.seek(o) - self.im = self.map.readimage( - self.mode, self.size, a[1], a[2] - ) - else: - # use mmap, if possible - import mmap - file = open(self.filename, "r+") - size = os.path.getsize(self.filename) - # FIXME: on Unix, use PROT_READ etc - self.map = mmap.mmap(file.fileno(), size) - self.im = Image.core.map_buffer( - self.map, self.size, d, e, o, a - ) - readonly = 1 - except (AttributeError, EnvironmentError, ImportError): - self.map = None - - self.load_prepare() - - # look for read/seek overrides - try: - read = self.load_read - except AttributeError: - read = self.fp.read - - try: - seek = self.load_seek - except AttributeError: - seek = self.fp.seek - - if not self.map: - - # sort tiles in file order - self.tile.sort(_tilesort) - - try: - # FIXME: This is a hack to handle TIFF's JpegTables tag. - prefix = self.tile_prefix - except AttributeError: - prefix = "" - - for d, e, o, a in self.tile: - d = Image._getdecoder(self.mode, d, a, self.decoderconfig) - seek(o) - try: - d.setimage(self.im, e) - except ValueError: - continue - b = prefix - t = len(b) - while 1: - s = read(self.decodermaxblock) - if not s: - self.tile = [] - raise IOError("image file is truncated (%d bytes not processed)" % len(b)) - b = b + s - n, e = d.decode(b) - if n < 0: - break - b = b[n:] - t = t + n - - self.tile = [] - self.readonly = readonly - - self.fp = None # might be shared - - if not self.map and e < 0: - raise_ioerror(e) - - # post processing - if hasattr(self, "tile_post_rotate"): - # FIXME: This is a hack to handle rotated PCD's - self.im = self.im.rotate(self.tile_post_rotate) - self.size = self.im.size - - self.load_end() - - return Image.Image.load(self) - - def load_prepare(self): - # create image memory if necessary - if not self.im or\ - self.im.mode != self.mode or self.im.size != self.size: - self.im = Image.core.new(self.mode, self.size) - # create palette (optional) - if self.mode == "P": - Image.Image.load(self) - - def load_end(self): - # may be overridden - pass - - # may be defined for contained formats - # def load_seek(self, pos): - # pass - - # may be defined for blocked formats (e.g. PNG) - # def load_read(self, bytes): - # pass - -## -# Base class for stub image loaders. -#

-# A stub loader is an image loader that can identify files of a -# certain format, but relies on external code to load the file. - -class StubImageFile(ImageFile): - "Base class for stub image loaders." - - def _open(self): - raise NotImplementedError( - "StubImageFile subclass must implement _open" - ) - - def load(self): - loader = self._load() - if loader is None: - raise IOError("cannot find loader for this %s file" % self.format) - image = loader.load(self) - assert image is not None - # become the other object (!) - self.__class__ = image.__class__ - self.__dict__ = image.__dict__ - - ## - # (Hook) Find actual image loader. - - def _load(self): - raise NotImplementedError( - "StubImageFile subclass must implement _load" - ) - -## -# (Internal) Support class for the Parser file. - -class _ParserFile: - # parser support class. - - def __init__(self, data): - self.data = data - self.offset = 0 - - def close(self): - self.data = self.offset = None - - def tell(self): - return self.offset - - def seek(self, offset, whence=0): - if whence == 0: - self.offset = offset - elif whence == 1: - self.offset = self.offset + offset - else: - # force error in Image.open - raise IOError("illegal argument to seek") - - def read(self, bytes=0): - pos = self.offset - if bytes: - data = self.data[pos:pos+bytes] - else: - data = self.data[pos:] - self.offset = pos + len(data) - return data - - def readline(self): - # FIXME: this is slow! - s = "" - while 1: - c = self.read(1) - if not c: - break - s = s + c - if c == "\n": - break - return s - -## -# Incremental image parser. This class implements the standard -# feed/close consumer interface. - -class Parser: - - incremental = None - image = None - data = None - decoder = None - finished = 0 - - ## - # (Consumer) Reset the parser. Note that you can only call this - # method immediately after you've created a parser; parser - # instances cannot be reused. - - def reset(self): - assert self.data is None, "cannot reuse parsers" - - ## - # (Consumer) Feed data to the parser. - # - # @param data A string buffer. - # @exception IOError If the parser failed to parse the image file. - - def feed(self, data): - # collect data - - if self.finished: - return - - if self.data is None: - self.data = data - else: - self.data = self.data + data - - # parse what we have - if self.decoder: - - if self.offset > 0: - # skip header - skip = min(len(self.data), self.offset) - self.data = self.data[skip:] - self.offset = self.offset - skip - if self.offset > 0 or not self.data: - return - - n, e = self.decoder.decode(self.data) - - if n < 0: - # end of stream - self.data = None - self.finished = 1 - if e < 0: - # decoding error - self.image = None - raise_ioerror(e) - else: - # end of image - return - self.data = self.data[n:] - - elif self.image: - - # if we end up here with no decoder, this file cannot - # be incrementally parsed. wait until we've gotten all - # available data - pass - - else: - - # attempt to open this file - try: - try: - fp = _ParserFile(self.data) - im = Image.open(fp) - finally: - fp.close() # explicitly close the virtual file - except IOError: - pass # not enough data - else: - flag = hasattr(im, "load_seek") or hasattr(im, "load_read") - if flag or len(im.tile) != 1: - # custom load code, or multiple tiles - self.decode = None - else: - # initialize decoder - im.load_prepare() - d, e, o, a = im.tile[0] - im.tile = [] - self.decoder = Image._getdecoder( - im.mode, d, a, im.decoderconfig - ) - self.decoder.setimage(im.im, e) - - # calculate decoder offset - self.offset = o - if self.offset <= len(self.data): - self.data = self.data[self.offset:] - self.offset = 0 - - self.image = im - - ## - # (Consumer) Close the stream. - # - # @return An image object. - # @exception IOError If the parser failed to parse the image file. - - def close(self): - # finish decoding - if self.decoder: - # get rid of what's left in the buffers - self.feed("") - self.data = self.decoder = None - if not self.finished: - raise IOError("image was incomplete") - if not self.image: - raise IOError("cannot parse this image") - if self.data: - # incremental parsing not possible; reopen the file - # not that we have all data - try: - fp = _ParserFile(self.data) - self.image = Image.open(fp) - finally: - self.image.load() - fp.close() # explicitly close the virtual file - return self.image - -# -------------------------------------------------------------------- - -## -# (Helper) Save image body to file. -# -# @param im Image object. -# @param fp File object. -# @param tile Tile list. - -def _save(im, fp, tile): - "Helper to save image based on tile list" - - im.load() - if not hasattr(im, "encoderconfig"): - im.encoderconfig = () - tile.sort(_tilesort) - # FIXME: make MAXBLOCK a configuration parameter - bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c - try: - fh = fp.fileno() - fp.flush() - except AttributeError: - # compress to Python file-compatible object - for e, b, o, a in tile: - e = Image._getencoder(im.mode, e, a, im.encoderconfig) - if o > 0: - fp.seek(o, 0) - e.setimage(im.im, b) - while 1: - l, s, d = e.encode(bufsize) - fp.write(d) - if s: - break - if s < 0: - raise IOError("encoder error %d when writing image file" % s) - else: - # slight speedup: compress to real file object - for e, b, o, a in tile: - e = Image._getencoder(im.mode, e, a, im.encoderconfig) - if o > 0: - fp.seek(o, 0) - e.setimage(im.im, b) - s = e.encode_to_file(fh, bufsize) - if s < 0: - raise IOError("encoder error %d when writing image file" % s) - try: - fp.flush() - except: pass - - -## -# Reads large blocks in a safe way. Unlike fp.read(n), this function -# doesn't trust the user. If the requested size is larger than -# SAFEBLOCK, the file is read block by block. -# -# @param fp File handle. Must implement a read method. -# @param size Number of bytes to read. -# @return A string containing up to size bytes of data. - -def _safe_read(fp, size): - if size <= 0: - return "" - if size <= SAFEBLOCK: - return fp.read(size) - data = [] - while size > 0: - block = fp.read(min(size, SAFEBLOCK)) - if not block: - break - data.append(block) - size = size - len(block) - return string.join(data, "") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py deleted file mode 100755 index c12a25738c1..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFileIO.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# kludge to get basic ImageFileIO functionality -# -# History: -# 1998-08-06 fl Recreated -# -# Copyright (c) Secret Labs AB 1998-2002. -# -# See the README file for information on usage and redistribution. -# - -from StringIO import StringIO - -## -# The ImageFileIO module can be used to read an image from a -# socket, or any other stream device. -#

-# This module is deprecated. New code should use the Parser -# class in the ImageFile module instead. -# -# @see ImageFile#Parser - -class ImageFileIO(StringIO): - - ## - # Adds buffering to a stream file object, in order to - # provide seek and tell methods required - # by the Image.open method. The stream object must - # implement read and close methods. - # - # @param fp Stream file handle. - # @see Image#open - - def __init__(self, fp): - data = fp.read() - StringIO.__init__(self, data) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py deleted file mode 100755 index 918bab177c1..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFilter.py +++ /dev/null @@ -1,289 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# standard filters -# -# History: -# 1995-11-27 fl Created -# 2002-06-08 fl Added rank and mode filters -# 2003-09-15 fl Fixed rank calculation in rank filter; added expand call -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1995-2002 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -class Filter: - pass - -## -# Convolution filter kernel. - -class Kernel(Filter): - - ## - # Create a convolution kernel. The current version only - # supports 3x3 and 5x5 integer and floating point kernels. - #

- # In the current version, kernels can only be applied to - # "L" and "RGB" images. - # - # @def __init__(size, kernel, **options) - # @param size Kernel size, given as (width, height). In - # the current version, this must be (3,3) or (5,5). - # @param kernel A sequence containing kernel weights. - # @param **options Optional keyword arguments. - # @keyparam scale Scale factor. If given, the result for each - # pixel is divided by this value. The default is the sum - # of the kernel weights. - # @keyparam offset Offset. If given, this value is added to the - # result, after it has been divided by the scale factor. - - def __init__(self, size, kernel, scale=None, offset=0): - if scale is None: - # default scale is sum of kernel - scale = reduce(lambda a,b: a+b, kernel) - if size[0] * size[1] != len(kernel): - raise ValueError("not enough coefficients in kernel") - self.filterargs = size, scale, offset, kernel - - def filter(self, image): - if image.mode == "P": - raise ValueError("cannot filter palette images") - return apply(image.filter, self.filterargs) - -class BuiltinFilter(Kernel): - def __init__(self): - pass - -## -# Rank filter. - -class RankFilter(Filter): - name = "Rank" - - ## - # Create a rank filter. The rank filter sorts all pixels in - # a window of the given size, and returns the rank'th value. - # - # @param size The kernel size, in pixels. - # @param rank What pixel value to pick. Use 0 for a min filter, - # size*size/2 for a median filter, size*size-1 for a max filter, - # etc. - - def __init__(self, size, rank): - self.size = size - self.rank = rank - - def filter(self, image): - if image.mode == "P": - raise ValueError("cannot filter palette images") - image = image.expand(self.size/2, self.size/2) - return image.rankfilter(self.size, self.rank) - -## -# Median filter. Picks the median pixel value in a window with the -# given size. - -class MedianFilter(RankFilter): - name = "Median" - - ## - # Create a median filter. - # - # @param size The kernel size, in pixels. - - def __init__(self, size=3): - self.size = size - self.rank = size*size/2 - -## -# Min filter. Picks the lowest pixel value in a window with the given -# size. - -class MinFilter(RankFilter): - name = "Min" - - ## - # Create a min filter. - # - # @param size The kernel size, in pixels. - - def __init__(self, size=3): - self.size = size - self.rank = 0 - -## -# Max filter. Picks the largest pixel value in a window with the -# given size. - -class MaxFilter(RankFilter): - name = "Max" - - ## - # Create a max filter. - # - # @param size The kernel size, in pixels. - - def __init__(self, size=3): - self.size = size - self.rank = size*size-1 - -## -# Mode filter. Picks the most frequent pixel value in a box with the -# given size. Pixel values that occur only once or twice are ignored; -# if no pixel value occurs more than twice, the original pixel value -# is preserved. - -class ModeFilter(Filter): - name = "Mode" - - ## - # Create a mode filter. - # - # @param size The kernel size, in pixels. - - def __init__(self, size=3): - self.size = size - def filter(self, image): - return image.modefilter(self.size) - -## -# Gaussian blur filter. - -class GaussianBlur(Filter): - name = "GaussianBlur" - - def __init__(self, radius=2): - self.radius = 2 - def filter(self, image): - return image.gaussian_blur(self.radius) - -## -# Unsharp mask filter. - -class UnsharpMask(Filter): - name = "UnsharpMask" - - def __init__(self, radius=2, percent=150, threshold=3): - self.radius = 2 - self.percent = percent - self.threshold = threshold - def filter(self, image): - return image.unsharp_mask(self.radius, self.percent, self.threshold) - -## -# Simple blur filter. - -class BLUR(BuiltinFilter): - name = "Blur" - filterargs = (5, 5), 16, 0, ( - 1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1 - ) - -## -# Simple contour filter. - -class CONTOUR(BuiltinFilter): - name = "Contour" - filterargs = (3, 3), 1, 255, ( - -1, -1, -1, - -1, 8, -1, - -1, -1, -1 - ) - -## -# Simple detail filter. - -class DETAIL(BuiltinFilter): - name = "Detail" - filterargs = (3, 3), 6, 0, ( - 0, -1, 0, - -1, 10, -1, - 0, -1, 0 - ) - -## -# Simple edge enhancement filter. - -class EDGE_ENHANCE(BuiltinFilter): - name = "Edge-enhance" - filterargs = (3, 3), 2, 0, ( - -1, -1, -1, - -1, 10, -1, - -1, -1, -1 - ) - -## -# Simple stronger edge enhancement filter. - -class EDGE_ENHANCE_MORE(BuiltinFilter): - name = "Edge-enhance More" - filterargs = (3, 3), 1, 0, ( - -1, -1, -1, - -1, 9, -1, - -1, -1, -1 - ) - -## -# Simple embossing filter. - -class EMBOSS(BuiltinFilter): - name = "Emboss" - filterargs = (3, 3), 1, 128, ( - -1, 0, 0, - 0, 1, 0, - 0, 0, 0 - ) - -## -# Simple edge-finding filter. - -class FIND_EDGES(BuiltinFilter): - name = "Find Edges" - filterargs = (3, 3), 1, 0, ( - -1, -1, -1, - -1, 8, -1, - -1, -1, -1 - ) - -## -# Simple smoothing filter. - -class SMOOTH(BuiltinFilter): - name = "Smooth" - filterargs = (3, 3), 13, 0, ( - 1, 1, 1, - 1, 5, 1, - 1, 1, 1 - ) - -## -# Simple stronger smoothing filter. - -class SMOOTH_MORE(BuiltinFilter): - name = "Smooth More" - filterargs = (5, 5), 100, 0, ( - 1, 1, 1, 1, 1, - 1, 5, 5, 5, 1, - 1, 5, 44, 5, 1, - 1, 5, 5, 5, 1, - 1, 1, 1, 1, 1 - ) - -## -# Simple sharpening filter. - -class SHARPEN(BuiltinFilter): - name = "Sharpen" - filterargs = (3, 3), 16, 0, ( - -2, -2, -2, - -2, 32, -2, - -2, -2, -2 - ) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py deleted file mode 100755 index 3ea2f2f8efd..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageFont.py +++ /dev/null @@ -1,390 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PIL raster font management -# -# History: -# 1996-08-07 fl created (experimental) -# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3 -# 1999-02-06 fl rewrote most font management stuff in C -# 1999-03-17 fl take pth files into account in load_path (from Richard Jones) -# 2001-02-17 fl added freetype support -# 2001-05-09 fl added TransposedFont wrapper class -# 2002-03-04 fl make sure we have a "L" or "1" font -# 2002-12-04 fl skip non-directory entries in the system path -# 2003-04-29 fl add embedded default font -# 2003-09-27 fl added support for truetype charmap encodings -# -# Todo: -# Adapt to PILFONT2 format (16-bit fonts, compressed, single file) -# -# Copyright (c) 1997-2003 by Secret Labs AB -# Copyright (c) 1996-2003 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image -import os, string, sys - -class _imagingft_not_installed: - # module placeholder - def __getattr__(self, id): - raise ImportError("The _imagingft C module is not installed") - -try: - import _imagingft - core = _imagingft - del _imagingft -except ImportError: - core = _imagingft_not_installed() - -# FIXME: add support for pilfont2 format (see FontFile.py) - -# -------------------------------------------------------------------- -# Font metrics format: -# "PILfont" LF -# fontdescriptor LF -# (optional) key=value... LF -# "DATA" LF -# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox) -# -# To place a character, cut out srcbox and paste at dstbox, -# relative to the character position. Then move the character -# position according to dx, dy. -# -------------------------------------------------------------------- - -## -# The ImageFont module defines a class with the same name. -# Instances of this class store bitmap fonts, and are used with the -# text method of the ImageDraw class. -#

-# PIL uses it's own font file format to store bitmap fonts. You can -# use the pilfont utility to convert BDF and PCF font -# descriptors (X window font formats) to this format. -#

-# Starting with version 1.1.4, PIL can be configured to support -# TrueType and OpenType fonts. For earlier version, TrueType -# support is only available as part of the imToolkit package -# -# @see ImageDraw#ImageDraw.text -# @see pilfont - -class ImageFont: - "PIL font wrapper" - - def _load_pilfont(self, filename): - - file = open(filename, "rb") - - for ext in (".png", ".gif", ".pbm"): - try: - fullname = os.path.splitext(filename)[0] + ext - image = Image.open(fullname) - except: - pass - else: - if image and image.mode in ("1", "L"): - break - else: - raise IOError("cannot find glyph data file") - - self.file = fullname - - return self._load_pilfont_data(file, image) - - def _load_pilfont_data(self, file, image): - - # read PILfont header - if file.readline() != "PILfont\n": - raise SyntaxError("Not a PILfont file") - d = string.split(file.readline(), ";") - self.info = [] # FIXME: should be a dictionary - while True: - s = file.readline() - if not s or s == "DATA\n": - break - self.info.append(s) - - # read PILfont metrics - data = file.read(256*20) - - # check image - if image.mode not in ("1", "L"): - raise TypeError("invalid font image mode") - - image.load() - - self.font = Image.core.font(image.im, data) - - # delegate critical operations to internal type - self.getsize = self.font.getsize - self.getmask = self.font.getmask - -## -# Wrapper for FreeType fonts. Application code should use the -# truetype factory function to create font objects. - -class FreeTypeFont: - "FreeType font wrapper (requires _imagingft service)" - - def __init__(self, file, size, index=0, encoding=""): - # FIXME: use service provider instead - self.font = core.getfont(file, size, index, encoding) - - def getname(self): - return self.font.family, self.font.style - - def getmetrics(self): - return self.font.ascent, self.font.descent - - def getsize(self, text): - return self.font.getsize(text)[0] - - def getmask(self, text, mode=""): - return self.getmask2(text, mode)[0] - - def getmask2(self, text, mode="", fill=Image.core.fill): - size, offset = self.font.getsize(text) - im = fill("L", size, 0) - self.font.render(text, im.id, mode=="1") - return im, offset - -## -# Wrapper that creates a transposed font from any existing font -# object. -# -# @param font A font object. -# @param orientation An optional orientation. If given, this should -# be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM, -# Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270. - -class TransposedFont: - "Wrapper for writing rotated or mirrored text" - - def __init__(self, font, orientation=None): - self.font = font - self.orientation = orientation # any 'transpose' argument, or None - - def getsize(self, text): - w, h = self.font.getsize(text) - if self.orientation in (Image.ROTATE_90, Image.ROTATE_270): - return h, w - return w, h - - def getmask(self, text, mode=""): - im = self.font.getmask(text, mode) - if self.orientation is not None: - return im.transpose(self.orientation) - return im - -## -# Load font file. This function loads a font object from the given -# bitmap font file, and returns the corresponding font object. -# -# @param filename Name of font file. -# @return A font object. -# @exception IOError If the file could not be read. - -def load(filename): - "Load a font file." - f = ImageFont() - f._load_pilfont(filename) - return f - -## -# Load a TrueType or OpenType font file, and create a font object. -# This function loads a font object from the given file, and creates -# a font object for a font of the given size. -#

-# This function requires the _imagingft service. -# -# @param filename A truetype font file. Under Windows, if the file -# is not found in this filename, the loader also looks in Windows -# fonts directory -# @param size The requested size, in points. -# @param index Which font face to load (default is first available face). -# @param encoding Which font encoding to use (default is Unicode). Common -# encodings are "unic" (Unicode), "symb" (Microsoft Symbol), "ADOB" -# (Adobe Standard), "ADBE" (Adobe Expert), and "armn" (Apple Roman). -# See the FreeType documentation for more information. -# @return A font object. -# @exception IOError If the file could not be read. - -def truetype(filename, size, index=0, encoding=""): - "Load a truetype font file." - try: - return FreeTypeFont(filename, size, index, encoding) - except IOError: - if sys.platform == "win32": - # check the windows font repository - # NOTE: must use uppercase WINDIR, to work around bugs in - # 1.5.2's os.environ.get() - windir = os.environ.get("WINDIR") - if windir: - filename = os.path.join(windir, "fonts", filename) - return FreeTypeFont(filename, size, index, encoding) - raise - -## -# Load font file. Same as load, but searches for a bitmap font along -# the Python path. -# -# @param filename Name of font file. -# @return A font object. -# @exception IOError If the file could not be read. -# @see #load - -def load_path(filename): - "Load a font file, searching along the Python path." - for dir in sys.path: - if Image.isDirectory(dir): - try: - return load(os.path.join(dir, filename)) - except IOError: - pass - raise IOError("cannot find font file") - -## -# Load a (probably rather ugly) default font. -# -# @return A font object. - -def load_default(): - "Load a default font." - from StringIO import StringIO - import base64 - f = ImageFont() - f._load_pilfont_data( - # courB08 - StringIO(base64.decodestring(''' -UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA -BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL -AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA -AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB -ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A -BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB -//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA -AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH -AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA -ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv -AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/ -/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 -AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA -AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG -AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA -BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA -AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA -2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF -AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// -+gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA -////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA -BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv -AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA -AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA -AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA -BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// -//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA -AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF -AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB -mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn -AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA -AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 -AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA -Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB -//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA -AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ -AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC -DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ -AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/ -+wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5 -AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/ -///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG -AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA -BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA -Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC -eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG -AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// -+gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA -////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA -BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT -AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A -AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA -Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA -Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// -//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA -AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ -AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA -LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 -AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA -AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 -AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA -AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG -AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA -EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK -AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA -pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG -AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// -+QAGAAIAzgAKANUAEw== -''')), Image.open(StringIO(base64.decodestring(''' -iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u -Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9 -M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g -LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F -IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA -Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 -NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx -in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 -SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY -AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt -y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG -ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY -lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H -/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 -AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 -c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ -/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw -pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv -oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR -evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA -AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v// -Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR -w7IkEbzhVQAAAABJRU5ErkJggg== -''')))) - return f - -if __name__ == "__main__": - # create font data chunk for embedding - import base64, os, sys - font = "../Images/courB08" - print " f._load_pilfont_data(" - print " # %s" % os.path.basename(font) - print " StringIO(base64.decodestring('''" - base64.encode(open(font + ".pil", "rb"), sys.stdout) - print "''')), Image.open(StringIO(base64.decodestring('''" - base64.encode(open(font + ".pbm", "rb"), sys.stdout) - print "'''))))" diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py deleted file mode 100755 index 5c58b6ca918..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGL.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# OpenGL pixmap/texture interface (requires imToolkit OpenGL extensions) -# -# History: -# 2003-09-13 fl Added -# -# Copyright (c) Secret Labs AB 2003. -# -# See the README file for information on usage and redistribution. -# - -## -# OpenGL pixmap/texture interface (requires imToolkit OpenGL -# extensions.) -## - -import _imaginggl - -## -# Texture factory. - -class TextureFactory: - pass # overwritten by the _imaginggl module - -from _imaginggl import * diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py deleted file mode 100755 index 9bcd804d3a3..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageGrab.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# screen grabber (windows only) -# -# History: -# 2001-04-26 fl created -# 2001-09-17 fl use builtin driver, if present -# 2002-11-19 fl added grabclipboard support -# -# Copyright (c) 2001-2002 by Secret Labs AB -# Copyright (c) 2001-2002 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image - -## -# (New in 1.1.3) The ImageGrab module can be used to copy -# the contents of the screen to a PIL image memory. -#

-# The current version works on Windows only.

-# -# @since 1.1.3 -## - -try: - # built-in driver (1.1.3 and later) - grabber = Image.core.grabscreen -except AttributeError: - # stand-alone driver (pil plus) - import _grabscreen - grabber = _grabscreen.grab - -## -# (New in 1.1.3) Take a snapshot of the screen. The pixels inside the -# bounding box are returned as an "RGB" image. If the bounding box is -# omitted, the entire screen is copied. -# -# @param bbox What region to copy. Default is the entire screen. -# @return An image -# @since 1.1.3 - -def grab(bbox=None): - size, data = grabber() - im = Image.fromstring( - "RGB", size, data, - # RGB, 32-bit line padding, origo in lower left corner - "raw", "BGR", (size[0]*3 + 3) & -4, -1 - ) - if bbox: - im = im.crop(bbox) - return im - -## -# (New in 1.1.4) Take a snapshot of the clipboard image, if any. -# -# @return An image, a list of filenames, or None if the clipboard does -# not contain image data or filenames. Note that if a list is -# returned, the filenames may not represent image files. -# @since 1.1.4 - -def grabclipboard(): - debug = 0 # temporary interface - data = Image.core.grabclipboard(debug) - if Image.isStringType(data): - import BmpImagePlugin, StringIO - return BmpImagePlugin.DibImageFile(StringIO.StringIO(data)) - return data diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py deleted file mode 100755 index 56c42a45a9d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMath.py +++ /dev/null @@ -1,207 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# a simple math add-on for the Python Imaging Library -# -# History: -# 1999-02-15 fl Original PIL Plus release -# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 -# 2005-09-12 fl Fixed int() and float() for Python 2.4.1 -# -# Copyright (c) 1999-2005 by Secret Labs AB -# Copyright (c) 2005 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image -import _imagingmath - -VERBOSE = 0 - -def _isconstant(v): - return isinstance(v, type(0)) or isinstance(v, type(0.0)) - -class _Operand: - # wraps an image operand, providing standard operators - - def __init__(self, im): - self.im = im - - def __fixup(self, im1): - # convert image to suitable mode - if isinstance(im1, _Operand): - # argument was an image. - if im1.im.mode in ("1", "L"): - return im1.im.convert("I") - elif im1.im.mode in ("I", "F"): - return im1.im - else: - raise ValueError, "unsupported mode: %s" % im1.im.mode - else: - # argument was a constant - if _isconstant(im1) and self.im.mode in ("1", "L", "I"): - return Image.new("I", self.im.size, im1) - else: - return Image.new("F", self.im.size, im1) - - def apply(self, op, im1, im2=None, mode=None): - im1 = self.__fixup(im1) - if im2 is None: - # unary operation - out = Image.new(mode or im1.mode, im1.size, None) - im1.load() - try: - op = getattr(_imagingmath, op+"_"+im1.mode) - except AttributeError: - raise TypeError, "bad operand type for '%s'" % op - _imagingmath.unop(op, out.im.id, im1.im.id) - else: - # binary operation - im2 = self.__fixup(im2) - if im1.mode != im2.mode: - # convert both arguments to floating point - if im1.mode != "F": im1 = im1.convert("F") - if im2.mode != "F": im2 = im2.convert("F") - if im1.mode != im2.mode: - raise ValueError, "mode mismatch" - if im1.size != im2.size: - # crop both arguments to a common size - size = (min(im1.size[0], im2.size[0]), - min(im1.size[1], im2.size[1])) - if im1.size != size: im1 = im1.crop((0, 0) + size) - if im2.size != size: im2 = im2.crop((0, 0) + size) - out = Image.new(mode or im1.mode, size, None) - else: - out = Image.new(mode or im1.mode, im1.size, None) - im1.load(); im2.load() - try: - op = getattr(_imagingmath, op+"_"+im1.mode) - except AttributeError: - raise TypeError, "bad operand type for '%s'" % op - _imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id) - return _Operand(out) - - # unary operators - def __nonzero__(self): - # an image is "true" if it contains at least one non-zero pixel - return self.im.getbbox() is not None - def __abs__(self): - return self.apply("abs", self) - def __pos__(self): - return self - def __neg__(self): - return self.apply("neg", self) - - # binary operators - def __add__(self, other): - return self.apply("add", self, other) - def __radd__(self, other): - return self.apply("add", other, self) - def __sub__(self, other): - return self.apply("sub", self, other) - def __rsub__(self, other): - return self.apply("sub", other, self) - def __mul__(self, other): - return self.apply("mul", self, other) - def __rmul__(self, other): - return self.apply("mul", other, self) - def __div__(self, other): - return self.apply("div", self, other) - def __rdiv__(self, other): - return self.apply("div", other, self) - def __mod__(self, other): - return self.apply("mod", self, other) - def __rmod__(self, other): - return self.apply("mod", other, self) - def __pow__(self, other): - return self.apply("pow", self, other) - def __rpow__(self, other): - return self.apply("pow", other, self) - - # bitwise - def __invert__(self): - return self.apply("invert", self) - def __and__(self, other): - return self.apply("and", self, other) - def __rand__(self, other): - return self.apply("and", other, self) - def __or__(self, other): - return self.apply("or", self, other) - def __ror__(self, other): - return self.apply("or", other, self) - def __xor__(self, other): - return self.apply("xor", self, other) - def __rxor__(self, other): - return self.apply("xor", other, self) - def __lshift__(self, other): - return self.apply("lshift", self, other) - def __rshift__(self, other): - return self.apply("rshift", self, other) - - # logical - def __eq__(self, other): - return self.apply("eq", self, other) - def __ne__(self, other): - return self.apply("ne", self, other) - def __lt__(self, other): - return self.apply("lt", self, other) - def __le__(self, other): - return self.apply("le", self, other) - def __gt__(self, other): - return self.apply("gt", self, other) - def __ge__(self, other): - return self.apply("ge", self, other) - -# conversions -def imagemath_int(self): - return _Operand(self.im.convert("I")) -def imagemath_float(self): - return _Operand(self.im.convert("F")) - -# logical -def imagemath_equal(self, other): - return self.apply("eq", self, other, mode="I") -def imagemath_notequal(self, other): - return self.apply("ne", self, other, mode="I") - -def imagemath_min(self, other): - return self.apply("min", self, other) -def imagemath_max(self, other): - return self.apply("max", self, other) - -def imagemath_convert(self, mode): - return _Operand(self.im.convert(mode)) - -ops = {} -for k, v in globals().items(): - if k[:10] == "imagemath_": - ops[k[10:]] = v - -## -# Evaluates an image expression. -# -# @param expression A string containing a Python-style expression. -# @keyparam options Values to add to the evaluation context. You -# can either use a dictionary, or one or more keyword arguments. -# @return The evaluated expression. This is usually an image object, -# but can also be an integer, a floating point value, or a pixel -# tuple, depending on the expression. - -def eval(expression, _dict={}, **kw): - - # build execution namespace - args = ops.copy() - args.update(_dict) - args.update(kw) - for k, v in args.items(): - if hasattr(v, "im"): - args[k] = _Operand(v) - - import __builtin__ - out =__builtin__.eval(expression, args) - try: - return out.im - except AttributeError: - return out diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py deleted file mode 100755 index 1d5df1c6dca..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageMode.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# standard mode descriptors -# -# History: -# 2006-03-20 fl Added -# -# Copyright (c) 2006 by Secret Labs AB. -# Copyright (c) 2006 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -# mode descriptor cache -_modes = {} - -## -# Wrapper for mode strings. - -class ModeDescriptor: - - def __init__(self, mode, bands, basemode, basetype): - self.mode = mode - self.bands = bands - self.basemode = basemode - self.basetype = basetype - - def __str__(self): - return self.mode - -## -# Gets a mode descriptor for the given mode. - -def getmode(mode): - if not _modes: - # initialize mode cache - import Image - # core modes - for m, (basemode, basetype, bands) in Image._MODEINFO.items(): - _modes[m] = ModeDescriptor(m, bands, basemode, basetype) - # extra experimental modes - _modes["LA"] = ModeDescriptor("LA", ("L", "A"), "L", "L") - _modes["PA"] = ModeDescriptor("PA", ("P", "A"), "RGB", "L") - # mapping modes - _modes["I;16"] = ModeDescriptor("I;16", "I", "L", "L") - _modes["I;16L"] = ModeDescriptor("I;16L", "I", "L", "L") - _modes["I;16B"] = ModeDescriptor("I;16B", "I", "L", "L") - return _modes[mode] diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py deleted file mode 100755 index b51d78e258b..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageOps.py +++ /dev/null @@ -1,439 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# standard image operations -# -# History: -# 2001-10-20 fl Created -# 2001-10-23 fl Added autocontrast operator -# 2001-12-18 fl Added Kevin's fit operator -# 2004-03-14 fl Fixed potential division by zero in equalize -# 2005-05-05 fl Fixed equalize for low number of values -# -# Copyright (c) 2001-2004 by Secret Labs AB -# Copyright (c) 2001-2004 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image -import operator - -## -# (New in 1.1.3) The ImageOps module contains a number of -# 'ready-made' image processing operations. This module is somewhat -# experimental, and most operators only work on L and RGB images. -# -# @since 1.1.3 -## - -# -# helpers - -def _border(border): - if type(border) is type(()): - if len(border) == 2: - left, top = right, bottom = border - elif len(border) == 4: - left, top, right, bottom = border - else: - left = top = right = bottom = border - return left, top, right, bottom - -def _color(color, mode): - if Image.isStringType(color): - import ImageColor - color = ImageColor.getcolor(color, mode) - return color - -def _lut(image, lut): - if image.mode == "P": - # FIXME: apply to lookup table, not image data - raise NotImplementedError("mode P support coming soon") - elif image.mode in ("L", "RGB"): - if image.mode == "RGB" and len(lut) == 256: - lut = lut + lut + lut - return image.point(lut) - else: - raise IOError, "not supported for this image mode" - -# -# actions - -## -# Maximize (normalize) image contrast. This function calculates a -# histogram of the input image, removes cutoff percent of the -# lightest and darkest pixels from the histogram, and remaps the image -# so that the darkest pixel becomes black (0), and the lightest -# becomes white (255). -# -# @param image The image to process. -# @param cutoff How many percent to cut off from the histogram. -# @param ignore The background pixel value (use None for no background). -# @return An image. - -def autocontrast(image, cutoff=0, ignore=None): - "Maximize image contrast, based on histogram" - histogram = image.histogram() - lut = [] - for layer in range(0, len(histogram), 256): - h = histogram[layer:layer+256] - if ignore is not None: - # get rid of outliers - try: - h[ignore] = 0 - except TypeError: - # assume sequence - for ix in ignore: - h[ix] = 0 - if cutoff: - # cut off pixels from both ends of the histogram - # get number of pixels - n = 0 - for ix in range(256): - n = n + h[ix] - # remove cutoff% pixels from the low end - cut = n * cutoff / 100 - for lo in range(256): - if cut > h[lo]: - cut = cut - h[lo] - h[lo] = 0 - else: - h[lo] = h[lo] - cut - cut = 0 - if cut <= 0: - break - # remove cutoff% samples from the hi end - cut = n * cutoff / 100 - for hi in range(255, -1, -1): - if cut > h[hi]: - cut = cut - h[hi] - h[hi] = 0 - else: - h[hi] = h[hi] - cut - cut = 0 - if cut <= 0: - break - # find lowest/highest samples after preprocessing - for lo in range(256): - if h[lo]: - break - for hi in range(255, -1, -1): - if h[hi]: - break - if hi <= lo: - # don't bother - lut.extend(range(256)) - else: - scale = 255.0 / (hi - lo) - offset = -lo * scale - for ix in range(256): - ix = int(ix * scale + offset) - if ix < 0: - ix = 0 - elif ix > 255: - ix = 255 - lut.append(ix) - return _lut(image, lut) - -## -# Colorize grayscale image. The black and white -# arguments should be RGB tuples; this function calculates a colour -# wedge mapping all black pixels in the source image to the first -# colour, and all white pixels to the second colour. -# -# @param image The image to colourize. -# @param black The colour to use for black input pixels. -# @param white The colour to use for white input pixels. -# @return An image. - -def colorize(image, black, white): - "Colorize a grayscale image" - assert image.mode == "L" - black = _color(black, "RGB") - white = _color(white, "RGB") - red = []; green = []; blue = [] - for i in range(256): - red.append(black[0]+i*(white[0]-black[0])/255) - green.append(black[1]+i*(white[1]-black[1])/255) - blue.append(black[2]+i*(white[2]-black[2])/255) - image = image.convert("RGB") - return _lut(image, red + green + blue) - -## -# Remove border from image. The same amount of pixels are removed -# from all four sides. This function works on all image modes. -# -# @param image The image to crop. -# @param border The number of pixels to remove. -# @return An image. -# @see Image#Image.crop - -def crop(image, border=0): - "Crop border off image" - left, top, right, bottom = _border(border) - return image.crop( - (left, top, image.size[0]-right, image.size[1]-bottom) - ) - -## -# Deform the image. -# -# @param image The image to deform. -# @param deformer A deformer object. Any object that implements a -# getmesh method can be used. -# @param resample What resampling filter to use. -# @return An image. - -def deform(image, deformer, resample=Image.BILINEAR): - "Deform image using the given deformer" - return image.transform( - image.size, Image.MESH, deformer.getmesh(image), resample - ) - -## -# Equalize the image histogram. This function applies a non-linear -# mapping to the input image, in order to create a uniform -# distribution of grayscale values in the output image. -# -# @param image The image to equalize. -# @param mask An optional mask. If given, only the pixels selected by -# the mask are included in the analysis. -# @return An image. - -def equalize(image, mask=None): - "Equalize image histogram" - if image.mode == "P": - image = image.convert("RGB") - h = image.histogram(mask) - lut = [] - for b in range(0, len(h), 256): - histo = filter(None, h[b:b+256]) - if len(histo) <= 1: - lut.extend(range(256)) - else: - step = (reduce(operator.add, histo) - histo[-1]) / 255 - if not step: - lut.extend(range(256)) - else: - n = step / 2 - for i in range(256): - lut.append(n / step) - n = n + h[i+b] - return _lut(image, lut) - -## -# Add border to the image -# -# @param image The image to expand. -# @param border Border width, in pixels. -# @param fill Pixel fill value (a colour value). Default is 0 (black). -# @return An image. - -def expand(image, border=0, fill=0): - "Add border to image" - left, top, right, bottom = _border(border) - width = left + image.size[0] + right - height = top + image.size[1] + bottom - out = Image.new(image.mode, (width, height), _color(fill, image.mode)) - out.paste(image, (left, top)) - return out - -## -# Returns a sized and cropped version of the image, cropped to the -# requested aspect ratio and size. -#

-# The fit function was contributed by Kevin Cazabon. -# -# @param size The requested output size in pixels, given as a -# (width, height) tuple. -# @param method What resampling method to use. Default is Image.NEAREST. -# @param bleed Remove a border around the outside of the image (from all -# four edges. The value is a decimal percentage (use 0.01 for one -# percent). The default value is 0 (no border). -# @param centering Control the cropping position. Use (0.5, 0.5) for -# center cropping (e.g. if cropping the width, take 50% off of the -# left side, and therefore 50% off the right side). (0.0, 0.0) -# will crop from the top left corner (i.e. if cropping the width, -# take all of the crop off of the right side, and if cropping the -# height, take all of it off the bottom). (1.0, 0.0) will crop -# from the bottom left corner, etc. (i.e. if cropping the width, -# take all of the crop off the left side, and if cropping the height -# take none from the top, and therefore all off the bottom). -# @return An image. - -def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)): - """ - This method returns a sized and cropped version of the image, - cropped to the aspect ratio and size that you request. - """ - - # by Kevin Cazabon, Feb 17/2000 - # kevin@cazabon.com - # http://www.cazabon.com - - # ensure inputs are valid - if type(centering) != type([]): - centering = [centering[0], centering[1]] - - if centering[0] > 1.0 or centering[0] < 0.0: - centering [0] = 0.50 - if centering[1] > 1.0 or centering[1] < 0.0: - centering[1] = 0.50 - - if bleed > 0.49999 or bleed < 0.0: - bleed = 0.0 - - # calculate the area to use for resizing and cropping, subtracting - # the 'bleed' around the edges - - # number of pixels to trim off on Top and Bottom, Left and Right - bleedPixels = ( - int((float(bleed) * float(image.size[0])) + 0.5), - int((float(bleed) * float(image.size[1])) + 0.5) - ) - - liveArea = ( - bleedPixels[0], bleedPixels[1], image.size[0] - bleedPixels[0] - 1, - image.size[1] - bleedPixels[1] - 1 - ) - - liveSize = (liveArea[2] - liveArea[0], liveArea[3] - liveArea[1]) - - # calculate the aspect ratio of the liveArea - liveAreaAspectRatio = float(liveSize[0])/float(liveSize[1]) - - # calculate the aspect ratio of the output image - aspectRatio = float(size[0]) / float(size[1]) - - # figure out if the sides or top/bottom will be cropped off - if liveAreaAspectRatio >= aspectRatio: - # liveArea is wider than what's needed, crop the sides - cropWidth = int((aspectRatio * float(liveSize[1])) + 0.5) - cropHeight = liveSize[1] - else: - # liveArea is taller than what's needed, crop the top and bottom - cropWidth = liveSize[0] - cropHeight = int((float(liveSize[0])/aspectRatio) + 0.5) - - # make the crop - leftSide = int(liveArea[0] + (float(liveSize[0]-cropWidth) * centering[0])) - if leftSide < 0: - leftSide = 0 - topSide = int(liveArea[1] + (float(liveSize[1]-cropHeight) * centering[1])) - if topSide < 0: - topSide = 0 - - out = image.crop( - (leftSide, topSide, leftSide + cropWidth, topSide + cropHeight) - ) - - # resize the image and return it - return out.resize(size, method) - -## -# Flip the image vertically (top to bottom). -# -# @param image The image to flip. -# @return An image. - -def flip(image): - "Flip image vertically" - return image.transpose(Image.FLIP_TOP_BOTTOM) - -## -# Convert the image to grayscale. -# -# @param image The image to convert. -# @return An image. - -def grayscale(image): - "Convert to grayscale" - return image.convert("L") - -## -# Invert (negate) the image. -# -# @param image The image to invert. -# @return An image. - -def invert(image): - "Invert image (negate)" - lut = [] - for i in range(256): - lut.append(255-i) - return _lut(image, lut) - -## -# Flip image horizontally (left to right). -# -# @param image The image to mirror. -# @return An image. - -def mirror(image): - "Flip image horizontally" - return image.transpose(Image.FLIP_LEFT_RIGHT) - -## -# Reduce the number of bits for each colour channel. -# -# @param image The image to posterize. -# @param bits The number of bits to keep for each channel (1-8). -# @return An image. - -def posterize(image, bits): - "Reduce the number of bits per color channel" - lut = [] - mask = ~(2**(8-bits)-1) - for i in range(256): - lut.append(i & mask) - return _lut(image, lut) - -## -# Invert all pixel values above a threshold. -# -# @param image The image to posterize. -# @param threshold All pixels above this greyscale level are inverted. -# @return An image. - -def solarize(image, threshold=128): - "Invert all values above threshold" - lut = [] - for i in range(256): - if i < threshold: - lut.append(i) - else: - lut.append(255-i) - return _lut(image, lut) - -# -------------------------------------------------------------------- -# PIL USM components, from Kevin Cazabon. - -def gaussian_blur(im, radius=None): - """ PIL_usm.gblur(im, [radius])""" - - if radius is None: - radius = 5.0 - - im.load() - - return im.im.gaussian_blur(radius) - -gblur = gaussian_blur - -def unsharp_mask(im, radius=None, percent=None, threshold=None): - """ PIL_usm.usm(im, [radius, percent, threshold])""" - - if radius is None: - radius = 5.0 - if percent is None: - percent = 150 - if threshold is None: - threshold = 3 - - im.load() - - return im.im.unsharp_mask(radius, percent, threshold) - -usm = unsharp_mask diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py deleted file mode 100755 index 6efee299891..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePalette.py +++ /dev/null @@ -1,184 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# image palette object -# -# History: -# 1996-03-11 fl Rewritten. -# 1997-01-03 fl Up and running. -# 1997-08-23 fl Added load hack -# 2001-04-16 fl Fixed randint shadow bug in random() -# -# Copyright (c) 1997-2001 by Secret Labs AB -# Copyright (c) 1996-1997 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import array -import Image, ImageColor - -## -# Colour palette wrapper for palette mapped images. - -class ImagePalette: - "Colour palette for palette mapped images" - - def __init__(self, mode = "RGB", palette = None): - self.mode = mode - self.rawmode = None # if set, palette contains raw data - self.palette = palette or range(256)*len(self.mode) - self.colors = {} - self.dirty = None - if len(self.mode)*256 != len(self.palette): - raise ValueError, "wrong palette size" - - def getdata(self): - # experimental: get palette contents in format suitable - # for the low-level im.putpalette primitive - if self.rawmode: - return self.rawmode, self.palette - return self.mode + ";L", self.tostring() - - def tostring(self): - # experimental: convert palette to string - if self.rawmode: - raise ValueError("palette contains raw palette data") - if Image.isStringType(self.palette): - return self.palette - return array.array("B", self.palette).tostring() - - def getcolor(self, color): - # experimental: given an rgb tuple, allocate palette entry - if self.rawmode: - raise ValueError("palette contains raw palette data") - if Image.isTupleType(color): - try: - return self.colors[color] - except KeyError: - # allocate new color slot - if Image.isStringType(self.palette): - self.palette = map(int, self.palette) - index = len(self.colors) - if index >= 256: - raise ValueError("cannot allocate more than 256 colors") - self.colors[color] = index - self.palette[index] = color[0] - self.palette[index+256] = color[1] - self.palette[index+512] = color[2] - self.dirty = 1 - return index - else: - raise ValueError("unknown color specifier: %r" % color) - - def save(self, fp): - # (experimental) save palette to text file - if self.rawmode: - raise ValueError("palette contains raw palette data") - if type(fp) == type(""): - fp = open(fp, "w") - fp.write("# Palette\n") - fp.write("# Mode: %s\n" % self.mode) - for i in range(256): - fp.write("%d" % i) - for j in range(i, len(self.palette), 256): - fp.write(" %d" % self.palette[j]) - fp.write("\n") - fp.close() - -# -------------------------------------------------------------------- -# Internal - -def raw(rawmode, data): - palette = ImagePalette() - palette.rawmode = rawmode - palette.palette = data - palette.dirty = 1 - return palette - -# -------------------------------------------------------------------- -# Factories - -def _make_linear_lut(black, white): - lut = [] - if black == 0: - for i in range(256): - lut.append(white*i/255) - else: - raise NotImplementedError # FIXME - return lut - -def _make_gamma_lut(exp, mode="RGB"): - lut = [] - for i in range(256): - lut.append(int(((i / 255.0) ** exp) * 255.0 + 0.5)) - return lut - -def new(mode, data): - return Image.core.new_palette(mode, data) - -def negative(mode="RGB"): - palette = range(256) - palette.reverse() - return ImagePalette(mode, palette * len(mode)) - -def random(mode="RGB"): - from random import randint - palette = [] - for i in range(256*len(mode)): - palette.append(randint(0, 255)) - return ImagePalette(mode, palette) - -def sepia(white="#fff0c0"): - r, g, b = ImageColor.getrgb(white) - r = _make_linear_lut(0, r) - g = _make_linear_lut(0, g) - b = _make_linear_lut(0, b) - return ImagePalette("RGB", r + g + b) - -def wedge(mode="RGB"): - return ImagePalette(mode, range(256) * len(mode)) - -def load(filename): - - # FIXME: supports GIMP gradients only - - fp = open(filename, "rb") - - lut = None - - if not lut: - try: - import GimpPaletteFile - fp.seek(0) - p = GimpPaletteFile.GimpPaletteFile(fp) - lut = p.getpalette() - except (SyntaxError, ValueError): - pass - - if not lut: - try: - import GimpGradientFile - fp.seek(0) - p = GimpGradientFile.GimpGradientFile(fp) - lut = p.getpalette() - except (SyntaxError, ValueError): - pass - - if not lut: - try: - import PaletteFile - fp.seek(0) - p = PaletteFile.PaletteFile(fp) - lut = p.getpalette() - except (SyntaxError, ValueError): - pass - - if not lut: - raise IOError, "cannot load palette" - - return lut # data, rawmode - - -# add some psuedocolour palettes as well diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py deleted file mode 100755 index 721fd944998..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImagePath.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# path interface -# -# History: -# 1996-11-04 fl Created -# 2002-04-14 fl Added documentation stub class -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - -import Image - -## -# Path wrapper. - -class Path: - - ## - # Creates a path object. - # - # @param xy Sequence. The sequence can contain 2-tuples [(x, y), ...] - # or a flat list of numbers [x, y, ...]. - - def __init__(self, xy): - pass - - ## - # Compacts the path, by removing points that are close to each - # other. This method modifies the path in place. - - def compact(self, distance=2): - pass - - ## - # Gets the bounding box. - - def getbbox(self): - pass - - ## - # Maps the path through a function. - - def map(self, function): - pass - - ## - # Converts the path to Python list. - # - # @param flat By default, this function returns a list of 2-tuples - # [(x, y), ...]. If this argument is true, it returns a flat - # list [x, y, ...] instead. - # @return A list of coordinates. - - def tolist(self, flat=0): - pass - - ## - # Transforms the path. - - def transform(self, matrix): - pass - - -# override with C implementation -Path = Image.core.path diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py deleted file mode 100755 index 50ee07d6c12..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageQt.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# a simple Qt image interface. -# -# history: -# 2006-06-03 fl: created -# 2006-06-04 fl: inherit from QImage instead of wrapping it -# 2006-06-05 fl: removed toimage helper; move string support to ImageQt -# -# Copyright (c) 2006 by Secret Labs AB -# Copyright (c) 2006 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image - -from PyQt4.QtGui import QImage, qRgb - -## -# (Internal) Turns an RGB color into a Qt compatible color integer. - -def rgb(r, g, b): - # use qRgb to pack the colors, and then turn the resulting long - # into a negative integer with the same bitpattern. - return (qRgb(r, g, b) & 0xffffff) - 0x1000000 - -## -# An PIL image wrapper for Qt. This is a subclass of PyQt4's QImage -# class. -# -# @param im A PIL Image object, or a file name (given either as Python -# string or a PyQt string object). - -class ImageQt(QImage): - - def __init__(self, im): - - data = None - colortable = None - - # handle filename, if given instead of image name - if hasattr(im, "toUtf8"): - # FIXME - is this really the best way to do this? - im = unicode(im.toUtf8(), "utf-8") - if Image.isStringType(im): - im = Image.open(im) - - if im.mode == "1": - format = QImage.Format_Mono - elif im.mode == "L": - format = QImage.Format_Indexed8 - colortable = [] - for i in range(256): - colortable.append(rgb(i, i, i)) - elif im.mode == "P": - format = QImage.Format_Indexed8 - colortable = [] - palette = im.getpalette() - for i in range(0, len(palette), 3): - colortable.append(rgb(*palette[i:i+3])) - elif im.mode == "RGB": - data = im.tostring("raw", "BGRX") - format = QImage.Format_RGB32 - elif im.mode == "RGBA": - try: - data = im.tostring("raw", "BGRA") - except SystemError: - # workaround for earlier versions - r, g, b, a = im.split() - im = Image.merge("RGBA", (b, g, r, a)) - format = QImage.Format_ARGB32 - else: - raise ValueError("unsupported image mode %r" % im.mode) - - # must keep a reference, or Qt will crash! - self.__data = data or im.tostring() - - QImage.__init__(self, self.__data, im.size[0], im.size[1], format) - - if colortable: - self.setColorTable(colortable) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py deleted file mode 100755 index e94ca0b1ebc..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageSequence.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# sequence support classes -# -# history: -# 1997-02-20 fl Created -# -# Copyright (c) 1997 by Secret Labs AB. -# Copyright (c) 1997 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -## -# This class implements an iterator object that can be used to loop -# over an image sequence. - -class Iterator: - - ## - # Create an iterator. - # - # @param im An image object. - - def __init__(self, im): - if not hasattr(im, "seek"): - raise AttributeError("im must have seek method") - self.im = im - - def __getitem__(self, ix): - try: - if ix: - self.im.seek(ix) - return self.im - except EOFError: - raise IndexError # end of sequence diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py deleted file mode 100755 index 05270f440f2..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageShow.py +++ /dev/null @@ -1,163 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# im.show() drivers -# -# History: -# 2008-04-06 fl Created -# -# Copyright (c) Secret Labs AB 2008. -# -# See the README file for information on usage and redistribution. -# - -import Image -import os, sys - -_viewers = [] - -def register(viewer, order=1): - try: - if issubclass(viewer, Viewer): - viewer = viewer() - except TypeError: - pass # raised if viewer wasn't a class - if order > 0: - _viewers.append(viewer) - elif order < 0: - _viewers.insert(0, viewer) - -## -# Displays a given image. -# -# @param image An image object. -# @param title Optional title. Not all viewers can display the title. -# @param **options Additional viewer options. -# @return True if a suitable viewer was found, false otherwise. - -def show(image, title=None, **options): - for viewer in _viewers: - if viewer.show(image, title=title, **options): - return 1 - return 0 - -## -# Base class for viewers. - -class Viewer: - - # main api - - def show(self, image, **options): - - # save temporary image to disk - if image.mode[:4] == "I;16": - # @PIL88 @PIL101 - # "I;16" isn't an 'official' mode, but we still want to - # provide a simple way to show 16-bit images. - base = "L" - # FIXME: auto-contrast if max() > 255? - else: - base = Image.getmodebase(image.mode) - if base != image.mode and image.mode != "1": - image = image.convert(base) - - self.show_image(image, **options) - - # hook methods - - format = None - - def get_format(self, image): - # return format name, or None to save as PGM/PPM - return self.format - - def get_command(self, file, **options): - raise NotImplementedError - - def save_image(self, image): - # save to temporary file, and return filename - return image._dump(format=self.get_format(image)) - - def show_image(self, image, **options): - # display given image - return self.show_file(self.save_image(image), **options) - - def show_file(self, file, **options): - # display given file - os.system(self.get_command(file, **options)) - return 1 - -# -------------------------------------------------------------------- - -if sys.platform == "win32": - - class WindowsViewer(Viewer): - format = "BMP" - def get_command(self, file, **options): - return "start /wait %s && del /f %s" % (file, file) - - register(WindowsViewer) - -elif sys.platform == "darwin": - - class MacViewer(Viewer): - format = "BMP" - def get_command(self, file, **options): - # on darwin open returns immediately resulting in the temp - # file removal while app is opening - command = "open -a /Applications/Preview.app" - command = "(%s %s; sleep 20; rm -f %s)&" % (command, file, file) - return command - - register(MacViewer) - -else: - - # unixoids - - def which(executable): - path = os.environ.get("PATH") - if not path: - return None - for dirname in path.split(os.pathsep): - filename = os.path.join(dirname, executable) - if os.path.isfile(filename): - # FIXME: make sure it's executable - return filename - return None - - class UnixViewer(Viewer): - def show_file(self, file, **options): - command, executable = self.get_command_ex(file, **options) - command = "(%s %s; rm -f %s)&" % (command, file, file) - os.system(command) - return 1 - - # implementations - - class DisplayViewer(UnixViewer): - def get_command_ex(self, file, **options): - command = executable = "display" - return command, executable - - if which("display"): - register(DisplayViewer) - - class XVViewer(UnixViewer): - def get_command_ex(self, file, title=None, **options): - # note: xv is pretty outdated. most modern systems have - # imagemagick's display command instead. - command = executable = "xv" - if title: - # FIXME: do full escaping - command = command + " -name \"%s\"" % title - return command, executable - - if which("xv"): - register(XVViewer) - -if __name__ == "__main__": - # usage: python ImageShow.py imagefile [title] - print show(Image.open(sys.argv[1]), *sys.argv[2:]) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py deleted file mode 100755 index 9ebdab03018..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageStat.py +++ /dev/null @@ -1,164 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# global image statistics -# -# History: -# 1996-04-05 fl Created -# 1997-05-21 fl Added mask; added rms, var, stddev attributes -# 1997-08-05 fl Added median -# 1998-07-05 hk Fixed integer overflow error -# -# Notes: -# This class shows how to implement delayed evaluation of attributes. -# To get a certain value, simply access the corresponding attribute. -# The __getattr__ dispatcher takes care of the rest. -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996-97. -# -# See the README file for information on usage and redistribution. -# - -import Image -import operator, math - -## -# The ImageStat module calculates global statistics for an -# image, or a region of an image. -## - -## -# Calculate statistics for the given image. If a mask is included, -# only the regions covered by that mask are included in the -# statistics. - -class Stat: - "Get image or feature statistics" - - ## - # Create a statistics object. - # - # @def __init__(image, mask=None) - # @param image A PIL image, or a precalculate histogram. - # @param mask An optional mask. - - def __init__(self, image_or_list, mask = None): - try: - if mask: - self.h = image_or_list.histogram(mask) - else: - self.h = image_or_list.histogram() - except AttributeError: - self.h = image_or_list # assume it to be a histogram list - if type(self.h) != type([]): - raise TypeError, "first argument must be image or list" - self.bands = range(len(self.h) / 256) - - def __getattr__(self, id): - "Calculate missing attribute" - if id[:4] == "_get": - raise AttributeError, id - # calculate missing attribute - v = getattr(self, "_get" + id)() - setattr(self, id, v) - return v - - def _getextrema(self): - "Get min/max values for each band in the image" - - def minmax(histogram): - n = 255 - x = 0 - for i in range(256): - if histogram[i]: - n = min(n, i) - x = max(x, i) - return n, x # returns (255, 0) if there's no data in the histogram - - v = [] - for i in range(0, len(self.h), 256): - v.append(minmax(self.h[i:])) - return v - - def _getcount(self): - "Get total number of pixels in each layer" - - v = [] - for i in range(0, len(self.h), 256): - v.append(reduce(operator.add, self.h[i:i+256])) - return v - - def _getsum(self): - "Get sum of all pixels in each layer" - - v = [] - for i in range(0, len(self.h), 256): - sum = 0.0 - for j in range(256): - sum = sum + j * self.h[i+j] - v.append(sum) - return v - - def _getsum2(self): - "Get squared sum of all pixels in each layer" - - v = [] - for i in range(0, len(self.h), 256): - sum2 = 0.0 - for j in range(256): - sum2 = sum2 + (j ** 2) * float(self.h[i+j]) - v.append(sum2) - return v - - def _getmean(self): - "Get average pixel level for each layer" - - v = [] - for i in self.bands: - v.append(self.sum[i] / self.count[i]) - return v - - def _getmedian(self): - "Get median pixel level for each layer" - - v = [] - for i in self.bands: - s = 0 - l = self.count[i]/2 - b = i * 256 - for j in range(256): - s = s + self.h[b+j] - if s > l: - break - v.append(j) - return v - - def _getrms(self): - "Get RMS for each layer" - - v = [] - for i in self.bands: - v.append(math.sqrt(self.sum2[i] / self.count[i])) - return v - - - def _getvar(self): - "Get variance for each layer" - - v = [] - for i in self.bands: - n = self.count[i] - v.append((self.sum2[i]-(self.sum[i]**2.0)/n)/n) - return v - - def _getstddev(self): - "Get standard deviation for each layer" - - v = [] - for i in self.bands: - v.append(math.sqrt(self.var[i])) - return v - -Global = Stat # compatibility diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py deleted file mode 100755 index 8618139a538..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTk.py +++ /dev/null @@ -1,296 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# a Tk display interface -# -# History: -# 96-04-08 fl Created -# 96-09-06 fl Added getimage method -# 96-11-01 fl Rewritten, removed image attribute and crop method -# 97-05-09 fl Use PyImagingPaste method instead of image type -# 97-05-12 fl Minor tweaks to match the IFUNC95 interface -# 97-05-17 fl Support the "pilbitmap" booster patch -# 97-06-05 fl Added file= and data= argument to image constructors -# 98-03-09 fl Added width and height methods to Image classes -# 98-07-02 fl Use default mode for "P" images without palette attribute -# 98-07-02 fl Explicitly destroy Tkinter image objects -# 99-07-24 fl Support multiple Tk interpreters (from Greg Couch) -# 99-07-26 fl Automatically hook into Tkinter (if possible) -# 99-08-15 fl Hook uses _imagingtk instead of _imaging -# -# Copyright (c) 1997-1999 by Secret Labs AB -# Copyright (c) 1996-1997 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Tkinter, Image - -## -# The ImageTk module contains support to create and modify -# Tkinter BitmapImage and PhotoImage objects. -#

-# For examples, see the demo programs in the Scripts -# directory. -## - -# -------------------------------------------------------------------- -# Check for Tkinter interface hooks - -_pilbitmap_ok = None - -def _pilbitmap_check(): - global _pilbitmap_ok - if _pilbitmap_ok is None: - try: - im = Image.new("1", (1,1)) - Tkinter.BitmapImage(data="PIL:%d" % im.im.id) - _pilbitmap_ok = 1 - except Tkinter.TclError: - _pilbitmap_ok = 0 - return _pilbitmap_ok - -# -------------------------------------------------------------------- -# PhotoImage - -## -# Creates a Tkinter-compatible photo image. This can be used -# everywhere Tkinter expects an image object. If the image is an RGBA -# image, pixels having alpha 0 are treated as transparent. - -class PhotoImage: - - ## - # Create a photo image object. The constructor takes either - # a PIL image, or a mode and a size. Alternatively, you can - # use the file or data options to initialize - # the photo image object. - #

- # @def __init__(image=None, size=None, **options) - # @param image Either a PIL image, or a mode string. If a - # mode string is used, a size must also be given. - # @param size If the first argument is a mode string, this - # defines the size of the image. - # @keyparam file A filename to load the image from (using - # Image.open(file)). - # @keyparam data An 8-bit string containing image data (as - # loaded from an image file). - - def __init__(self, image=None, size=None, **kw): - - # Tk compatibility: file or data - if image is None: - if kw.has_key("file"): - image = Image.open(kw["file"]) - del kw["file"] - elif kw.has_key("data"): - from StringIO import StringIO - image = Image.open(StringIO(kw["data"])) - del kw["data"] - - if hasattr(image, "mode") and hasattr(image, "size"): - # got an image instead of a mode - mode = image.mode - if mode == "P": - # palette mapped data - image.load() - try: - mode = image.palette.mode - except AttributeError: - mode = "RGB" # default - size = image.size - kw["width"], kw["height"] = size - else: - mode = image - image = None - - if mode not in ["1", "L", "RGB", "RGBA"]: - mode = Image.getmodebase(mode) - - self.__mode = mode - self.__size = size - self.__photo = apply(Tkinter.PhotoImage, (), kw) - self.tk = self.__photo.tk - if image: - self.paste(image) - - def __del__(self): - name = self.__photo.name - self.__photo.name = None - try: - self.__photo.tk.call("image", "delete", name) - except: - pass # ignore internal errors - - ## - # Get the Tkinter photo image identifier. This method is - # automatically called by Tkinter whenever a PhotoImage object is - # passed to a Tkinter method. - # - # @return A Tkinter photo image identifier (a string). - - def __str__(self): - return str(self.__photo) - - ## - # Get the width of the image. - # - # @return The width, in pixels. - - def width(self): - return self.__size[0] - - ## - # Get the height of the image. - # - # @return The height, in pixels. - - def height(self): - return self.__size[1] - - ## - # Paste a PIL image into the photo image. Note that this can - # be very slow if the photo image is displayed. - # - # @param im A PIL image. The size must match the target region. - # If the mode does not match, the image is converted to the - # mode of the bitmap image. - # @param box A 4-tuple defining the left, upper, right, and - # lower pixel coordinate. If None is given instead of a - # tuple, all of the image is assumed. - - def paste(self, im, box=None): - - # convert to blittable - im.load() - image = im.im - if image.isblock() and im.mode == self.__mode: - block = image - else: - block = image.new_block(self.__mode, im.size) - image.convert2(block, image) # convert directly between buffers - - tk = self.__photo.tk - - try: - tk.call("PyImagingPhoto", self.__photo, block.id) - except Tkinter.TclError, v: - # activate Tkinter hook - try: - import _imagingtk - try: - _imagingtk.tkinit(tk.interpaddr(), 1) - except AttributeError: - _imagingtk.tkinit(id(tk), 0) - tk.call("PyImagingPhoto", self.__photo, block.id) - except (ImportError, AttributeError, Tkinter.TclError): - raise # configuration problem; cannot attach to Tkinter - -# -------------------------------------------------------------------- -# BitmapImage - -## -# Create a Tkinter-compatible bitmap image. This can be used -# everywhere Tkinter expects an image object. - -class BitmapImage: - - ## - # Create a Tkinter-compatible bitmap image. - #

- # The given image must have mode "1". Pixels having value 0 are - # treated as transparent. Options, if any, are passed on to - # Tkinter. The most commonly used option is foreground, - # which is used to specify the colour for the non-transparent - # parts. See the Tkinter documentation for information on how to - # specify colours. - # - # @def __init__(image=None, **options) - # @param image A PIL image. - - def __init__(self, image=None, **kw): - - # Tk compatibility: file or data - if image is None: - if kw.has_key("file"): - image = Image.open(kw["file"]) - del kw["file"] - elif kw.has_key("data"): - from StringIO import StringIO - image = Image.open(StringIO(kw["data"])) - del kw["data"] - - self.__mode = image.mode - self.__size = image.size - - if _pilbitmap_check(): - # fast way (requires the pilbitmap booster patch) - image.load() - kw["data"] = "PIL:%d" % image.im.id - self.__im = image # must keep a reference - else: - # slow but safe way - kw["data"] = image.tobitmap() - self.__photo = apply(Tkinter.BitmapImage, (), kw) - - def __del__(self): - name = self.__photo.name - self.__photo.name = None - try: - self.__photo.tk.call("image", "delete", name) - except: - pass # ignore internal errors - - ## - # Get the width of the image. - # - # @return The width, in pixels. - - def width(self): - return self.__size[0] - - ## - # Get the height of the image. - # - # @return The height, in pixels. - - def height(self): - return self.__size[1] - - ## - # Get the Tkinter bitmap image identifier. This method is - # automatically called by Tkinter whenever a BitmapImage object - # is passed to a Tkinter method. - # - # @return A Tkinter bitmap image identifier (a string). - - def __str__(self): - return str(self.__photo) - -## -# Copies the contents of a PhotoImage to a PIL image memory. - -def getimage(photo): - photo.tk.call("PyImagingPhotoGet", photo) - -# -------------------------------------------------------------------- -# Helper for the Image.show method. - -def _show(image, title): - - class UI(Tkinter.Label): - def __init__(self, master, im): - if im.mode == "1": - self.image = BitmapImage(im, foreground="white", master=master) - else: - self.image = PhotoImage(im, master=master) - Tkinter.Label.__init__(self, master, image=self.image, - bg="black", bd=0) - - if not Tkinter._default_root: - raise IOError, "tkinter not initialized" - top = Tkinter.Toplevel() - if title: - top.title(title) - UI(top, image).pack() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py deleted file mode 100755 index cc323d3b990..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageTransform.py +++ /dev/null @@ -1,95 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# transform wrappers -# -# History: -# 2002-04-08 fl Created -# -# Copyright (c) 2002 by Secret Labs AB -# Copyright (c) 2002 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -import Image - -class Transform(Image.ImageTransformHandler): - def __init__(self, data): - self.data = data - def getdata(self): - return self.method, self.data - def transform(self, size, image, **options): - # can be overridden - method, data = self.getdata() - return image.transform(size, method, data, **options) - -## -# Define an affine image transform. -#

-# This function takes a 6-tuple (a, b, c, d, e, f) which -# contain the first two rows from an affine transform matrix. For -# each pixel (x, y) in the output image, the new value is -# taken from a position (a x + b y + c, -# d x + e y + f) in the input image, rounded to -# nearest pixel. -#

-# This function can be used to scale, translate, rotate, and shear the -# original image. -# -# @def AffineTransform(matrix) -# @param matrix A 6-tuple (a, b, c, d, e, f) containing -# the first two rows from an affine transform matrix. -# @see Image#Image.transform - -class AffineTransform(Transform): - method = Image.AFFINE - -## -# Define a transform to extract a subregion from an image. -#

-# Maps a rectangle (defined by two corners) from the image to a -# rectangle of the given size. The resulting image will contain -# data sampled from between the corners, such that (x0, y0) -# in the input image will end up at (0,0) in the output image, -# and (x1, y1) at size. -#

-# This method can be used to crop, stretch, shrink, or mirror an -# arbitrary rectangle in the current image. It is slightly slower than -# crop, but about as fast as a corresponding resize -# operation. -# -# @def ExtentTransform(bbox) -# @param bbox A 4-tuple (x0, y0, x1, y1) which specifies -# two points in the input image's coordinate system. -# @see Image#Image.transform - -class ExtentTransform(Transform): - method = Image.EXTENT - -## -# Define an quad image transform. -#

-# Maps a quadrilateral (a region defined by four corners) from the -# image to a rectangle of the given size. -# -# @def QuadTransform(xy) -# @param xy An 8-tuple (x0, y0, x1, y1, x2, y2, y3, y3) which -# contain the upper left, lower left, lower right, and upper right -# corner of the source quadrilateral. -# @see Image#Image.transform - -class QuadTransform(Transform): - method = Image.QUAD - -## -# Define an mesh image transform. A mesh transform consists of one -# or more individual quad transforms. -# -# @def MeshTransform(data) -# @param data A list of (bbox, quad) tuples. -# @see Image#Image.transform - -class MeshTransform(Transform): - method = Image.MESH diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py deleted file mode 100755 index f98725f74ac..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImageWin.py +++ /dev/null @@ -1,215 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# a Windows DIB display interface -# -# History: -# 1996-05-20 fl Created -# 1996-09-20 fl Fixed subregion exposure -# 1997-09-21 fl Added draw primitive (for tzPrint) -# 2003-05-21 fl Added experimental Window/ImageWindow classes -# 2003-09-05 fl Added fromstring/tostring methods -# -# Copyright (c) Secret Labs AB 1997-2003. -# Copyright (c) Fredrik Lundh 1996-2003. -# -# See the README file for information on usage and redistribution. -# - -import Image - -## -# The ImageWin module contains support to create and display -# images under Windows 95/98, NT, 2000 and later. - -class HDC: - def __init__(self, dc): - self.dc = dc - def __int__(self): - return self.dc - -class HWND: - def __init__(self, wnd): - self.wnd = wnd - def __int__(self): - return self.wnd - -## -# Create a Windows bitmap with the given mode and size. The mode can -# be one of "1", "L", "P", or "RGB". -# -# If the display requires a palette, this constructor creates a -# suitable palette and associates it with the image. For an "L" image, -# 128 greylevels are allocated. For an "RGB" image, a 6x6x6 colour -# cube is used, together with 20 greylevels. -# -# To make sure that palettes work properly under Windows, you must -# call the palette method upon certain events from Windows. - -class Dib: - - ## - # Create Windows bitmap. - # - # @param image Either a PIL image, or a mode string. If a - # mode string is used, a size must also be given. The - # mode can be one of "1", "L", "P", or "RGB". - # @param size If the first argument is a mode string, this - # defines the size of the image. - - def __init__(self, image, size=None): - if hasattr(image, "mode") and hasattr(image, "size"): - mode = image.mode - size = image.size - else: - mode = image - image = None - if mode not in ["1", "L", "P", "RGB"]: - mode = Image.getmodebase(mode) - self.image = Image.core.display(mode, size) - self.mode = mode - self.size = size - if image: - self.paste(image) - - ## - # Copy the bitmap contents to a device context. - # - # @param handle Device context (HDC), cast to a Python integer, - # or a HDC or HWND instance. In PythonWin, you can use the - # GetHandleAttrib method of the CDC class to get - # a suitable handle. - - def expose(self, handle): - if isinstance(handle, HWND): - dc = self.image.getdc(handle) - try: - result = self.image.expose(dc) - finally: - self.image.releasedc(handle, dc) - else: - result = self.image.expose(handle) - return result - - def draw(self, handle, dst, src=None): - if not src: - src = (0,0) + self.size - if isinstance(handle, HWND): - dc = self.image.getdc(handle) - try: - result = self.image.draw(dc, dst, src) - finally: - self.image.releasedc(handle, dc) - else: - result = self.image.draw(handle, dst, src) - return result - - ## - # Installs the palette associated with the image in the - # given device context. - #

- # This method should be called upon QUERYNEWPALETTE - # and PALETTECHANGED events from Windows. If this - # method returns a non-zero value, one or more display - # palette entries were changed, and the image should be - # redrawn. - # - # @param handle Device context (HDC), cast to a Python integer, - # or an HDC or HWND instance. - # @return A true value if one or more entries were changed - # (this indicates that the image should be redrawn). - - def query_palette(self, handle): - if isinstance(handle, HWND): - handle = self.image.getdc(handle) - try: - result = self.image.query_palette(handle) - finally: - self.image.releasedc(handle, handle) - else: - result = self.image.query_palette(handle) - return result - - ## - # Paste a PIL image into the bitmap image. - # - # @param im A PIL image. The size must match the target region. - # If the mode does not match, the image is converted to the - # mode of the bitmap image. - # @param box A 4-tuple defining the left, upper, right, and - # lower pixel coordinate. If None is given instead of a - # tuple, all of the image is assumed. - - def paste(self, im, box=None): - im.load() - if self.mode != im.mode: - im = im.convert(self.mode) - if box: - self.image.paste(im.im, box) - else: - self.image.paste(im.im) - - ## - # Load display memory contents from string buffer. - # - # @param buffer A string buffer containing display data (usually - # data returned from tostring) - - def fromstring(self, buffer): - return self.image.fromstring(buffer) - - ## - # Copy display memory contents to string buffer. - # - # @return A string buffer containing display data. - - def tostring(self): - return self.image.tostring() - - -## -# Create a Window with the given title size. - -class Window: - - def __init__(self, title="PIL", width=None, height=None): - self.hwnd = Image.core.createwindow( - title, self.__dispatcher, width or 0, height or 0 - ) - - def __dispatcher(self, action, *args): - return apply(getattr(self, "ui_handle_" + action), args) - - def ui_handle_clear(self, dc, x0, y0, x1, y1): - pass - - def ui_handle_damage(self, x0, y0, x1, y1): - pass - - def ui_handle_destroy(self): - pass - - def ui_handle_repair(self, dc, x0, y0, x1, y1): - pass - - def ui_handle_resize(self, width, height): - pass - - def mainloop(self): - Image.core.eventloop() - -## -# Create an image window which displays the given image. - -class ImageWindow(Window): - - def __init__(self, image, title="PIL"): - if not isinstance(image, Dib): - image = Dib(image) - self.image = image - width, height = image.size - Window.__init__(self, title, width=width, height=height) - - def ui_handle_repair(self, dc, x0, y0, x1, y1): - self.image.draw(dc, (x0, y0, x1, y1)) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py deleted file mode 100755 index bf5611b8a63..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/ImtImagePlugin.py +++ /dev/null @@ -1,93 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# IM Tools support for PIL -# -# history: -# 1996-05-27 fl Created (read 8-bit images only) -# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.2) -# -# Copyright (c) Secret Labs AB 1997-2001. -# Copyright (c) Fredrik Lundh 1996-2001. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.2" - -import re - -import Image, ImageFile - -# -# -------------------------------------------------------------------- - -field = re.compile(r"([a-z]*) ([^ \r\n]*)") - -## -# Image plugin for IM Tools images. - -class ImtImageFile(ImageFile.ImageFile): - - format = "IMT" - format_description = "IM Tools" - - def _open(self): - - # Quick rejection: if there's not a LF among the first - # 100 bytes, this is (probably) not a text header. - - if not "\n" in self.fp.read(100): - raise SyntaxError, "not an IM file" - self.fp.seek(0) - - xsize = ysize = 0 - - while 1: - - s = self.fp.read(1) - if not s: - break - - if s == chr(12): - - # image data begins - self.tile = [("raw", (0,0)+self.size, - self.fp.tell(), - (self.mode, 0, 1))] - - break - - else: - - # read key/value pair - # FIXME: dangerous, may read whole file - s = s + self.fp.readline() - if len(s) == 1 or len(s) > 100: - break - if s[0] == "*": - continue # comment - - m = field.match(s) - if not m: - break - k, v = m.group(1,2) - if k == "width": - xsize = int(v) - self.size = xsize, ysize - elif k == "height": - ysize = int(v) - self.size = xsize, ysize - elif k == "pixel" and v == "n8": - self.mode = "L" - - -# -# -------------------------------------------------------------------- - -Image.register_open("IMT", ImtImageFile) - -# -# no extension registered (".im" is simply too common) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py deleted file mode 100755 index acea5d18b40..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/IptcImagePlugin.py +++ /dev/null @@ -1,288 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# IPTC/NAA file handling -# -# history: -# 1995-10-01 fl Created -# 1998-03-09 fl Cleaned up and added to PIL -# 2002-06-18 fl Added getiptcinfo helper -# -# Copyright (c) Secret Labs AB 1997-2002. -# Copyright (c) Fredrik Lundh 1995. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.3" - - -import Image, ImageFile -import os, tempfile - - -COMPRESSION = { - 1: "raw", - 5: "jpeg" -} - -PAD = chr(0) * 4 - -# -# Helpers - -def i16(c): - return ord(c[1]) + (ord(c[0])<<8) - -def i32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) - -def i(c): - return i32((PAD + c)[-4:]) - -def dump(c): - for i in c: - print "%02x" % ord(i), - print - -## -# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields -# from TIFF and JPEG files, use the getiptcinfo function. - -class IptcImageFile(ImageFile.ImageFile): - - format = "IPTC" - format_description = "IPTC/NAA" - - def getint(self, key): - return i(self.info[key]) - - def field(self): - # - # get a IPTC field header - s = self.fp.read(5) - if not len(s): - return None, 0 - - tag = ord(s[1]), ord(s[2]) - - # syntax - if ord(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9: - raise SyntaxError, "invalid IPTC/NAA file" - - # field size - size = ord(s[3]) - if size > 132: - raise IOError, "illegal field length in IPTC/NAA file" - elif size == 128: - size = 0 - elif size > 128: - size = i(self.fp.read(size-128)) - else: - size = i16(s[3:]) - - return tag, size - - def _is_raw(self, offset, size): - # - # check if the file can be mapped - - # DISABLED: the following only slows things down... - return 0 - - self.fp.seek(offset) - t, sz = self.field() - if sz != size[0]: - return 0 - y = 1 - while 1: - self.fp.seek(sz, 1) - t, s = self.field() - if t != (8, 10): - break - if s != sz: - return 0 - y = y + 1 - return y == size[1] - - def _open(self): - - # load descriptive fields - while 1: - offset = self.fp.tell() - tag, size = self.field() - if not tag or tag == (8,10): - break - if size: - tagdata = self.fp.read(size) - else: - tagdata = None - if tag in self.info.keys(): - if isinstance(self.info[tag], list): - self.info[tag].append(tagdata) - else: - self.info[tag] = [self.info[tag], tagdata] - else: - self.info[tag] = tagdata - - # print tag, self.info[tag] - - # mode - layers = ord(self.info[(3,60)][0]) - component = ord(self.info[(3,60)][1]) - if self.info.has_key((3,65)): - id = ord(self.info[(3,65)][0])-1 - else: - id = 0 - if layers == 1 and not component: - self.mode = "L" - elif layers == 3 and component: - self.mode = "RGB"[id] - elif layers == 4 and component: - self.mode = "CMYK"[id] - - # size - self.size = self.getint((3,20)), self.getint((3,30)) - - # compression - try: - compression = COMPRESSION[self.getint((3,120))] - except KeyError: - raise IOError, "Unknown IPTC image compression" - - # tile - if tag == (8,10): - if compression == "raw" and self._is_raw(offset, self.size): - self.tile = [(compression, (offset, size + 5, -1), - (0, 0, self.size[0], self.size[1]))] - else: - self.tile = [("iptc", (compression, offset), - (0, 0, self.size[0], self.size[1]))] - - def load(self): - - if len(self.tile) != 1 or self.tile[0][0] != "iptc": - return ImageFile.ImageFile.load(self) - - type, tile, box = self.tile[0] - - encoding, offset = tile - - self.fp.seek(offset) - - # Copy image data to temporary file - outfile = tempfile.mktemp() - o = open(outfile, "wb") - if encoding == "raw": - # To simplify access to the extracted file, - # prepend a PPM header - o.write("P5\n%d %d\n255\n" % self.size) - while 1: - type, size = self.field() - if type != (8, 10): - break - while size > 0: - s = self.fp.read(min(size, 8192)) - if not s: - break - o.write(s) - size = size - len(s) - o.close() - - try: - try: - # fast - self.im = Image.core.open_ppm(outfile) - except: - # slightly slower - im = Image.open(outfile) - im.load() - self.im = im.im - finally: - try: os.unlink(outfile) - except: pass - - -Image.register_open("IPTC", IptcImageFile) - -Image.register_extension("IPTC", ".iim") - -## -# Get IPTC information from TIFF, JPEG, or IPTC file. -# -# @param im An image containing IPTC data. -# @return A dictionary containing IPTC information, or None if -# no IPTC information block was found. - -def getiptcinfo(im): - - import TiffImagePlugin, JpegImagePlugin - import StringIO - - data = None - - if isinstance(im, IptcImageFile): - # return info dictionary right away - return im.info - - elif isinstance(im, JpegImagePlugin.JpegImageFile): - # extract the IPTC/NAA resource - try: - app = im.app["APP13"] - if app[:14] == "Photoshop 3.0\x00": - app = app[14:] - # parse the image resource block - offset = 0 - while app[offset:offset+4] == "8BIM": - offset = offset + 4 - # resource code - code = JpegImagePlugin.i16(app, offset) - offset = offset + 2 - # resource name (usually empty) - name_len = ord(app[offset]) - name = app[offset+1:offset+1+name_len] - offset = 1 + offset + name_len - if offset & 1: - offset = offset + 1 - # resource data block - size = JpegImagePlugin.i32(app, offset) - offset = offset + 4 - if code == 0x0404: - # 0x0404 contains IPTC/NAA data - data = app[offset:offset+size] - break - offset = offset + size - if offset & 1: - offset = offset + 1 - except (AttributeError, KeyError): - pass - - elif isinstance(im, TiffImagePlugin.TiffImageFile): - # get raw data from the IPTC/NAA tag (PhotoShop tags the data - # as 4-byte integers, so we cannot use the get method...) - try: - type, data = im.tag.tagdata[TiffImagePlugin.IPTC_NAA_CHUNK] - except (AttributeError, KeyError): - pass - - if data is None: - return None # no properties - - # create an IptcImagePlugin object without initializing it - class FakeImage: - pass - im = FakeImage() - im.__class__ = IptcImageFile - - # parse the IPTC information chunk - im.info = {} - im.fp = StringIO.StringIO(data) - - try: - im._open() - except (IndexError, KeyError): - pass # expected failure - - return im.info diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py deleted file mode 100755 index 933abf3c244..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/JpegImagePlugin.py +++ /dev/null @@ -1,492 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# JPEG (JFIF) file handling -# -# See "Digital Compression and Coding of Continous-Tone Still Images, -# Part 1, Requirements and Guidelines" (CCITT T.81 / ISO 10918-1) -# -# History: -# 1995-09-09 fl Created -# 1995-09-13 fl Added full parser -# 1996-03-25 fl Added hack to use the IJG command line utilities -# 1996-05-05 fl Workaround Photoshop 2.5 CMYK polarity bug -# 1996-05-28 fl Added draft support, JFIF version (0.1) -# 1996-12-30 fl Added encoder options, added progression property (0.2) -# 1997-08-27 fl Save mode 1 images as BW (0.3) -# 1998-07-12 fl Added YCbCr to draft and save methods (0.4) -# 1998-10-19 fl Don't hang on files using 16-bit DQT's (0.4.1) -# 2001-04-16 fl Extract DPI settings from JFIF files (0.4.2) -# 2002-07-01 fl Skip pad bytes before markers; identify Exif files (0.4.3) -# 2003-04-25 fl Added experimental EXIF decoder (0.5) -# 2003-06-06 fl Added experimental EXIF GPSinfo decoder -# 2003-09-13 fl Extract COM markers -# 2009-09-06 fl Added icc_profile support (from Florian Hoech) -# 2009-03-06 fl Changed CMYK handling; always use Adobe polarity (0.6) -# 2009-03-08 fl Added subsampling support (from Justin Huff). -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1995-1996 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.6" - -import array, struct -import string -import Image, ImageFile - -def i16(c,o=0): - return ord(c[o+1]) + (ord(c[o])<<8) - -def i32(c,o=0): - return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24) - -# -# Parser - -def Skip(self, marker): - n = i16(self.fp.read(2))-2 - ImageFile._safe_read(self.fp, n) - -def APP(self, marker): - # - # Application marker. Store these in the APP dictionary. - # Also look for well-known application markers. - - n = i16(self.fp.read(2))-2 - s = ImageFile._safe_read(self.fp, n) - - app = "APP%d" % (marker&15) - - self.app[app] = s # compatibility - self.applist.append((app, s)) - - if marker == 0xFFE0 and s[:4] == "JFIF": - # extract JFIF information - self.info["jfif"] = version = i16(s, 5) # version - self.info["jfif_version"] = divmod(version, 256) - # extract JFIF properties - try: - jfif_unit = ord(s[7]) - jfif_density = i16(s, 8), i16(s, 10) - except: - pass - else: - if jfif_unit == 1: - self.info["dpi"] = jfif_density - self.info["jfif_unit"] = jfif_unit - self.info["jfif_density"] = jfif_density - elif marker == 0xFFE1 and s[:5] == "Exif\0": - # extract Exif information (incomplete) - self.info["exif"] = s # FIXME: value will change - elif marker == 0xFFE2 and s[:5] == "FPXR\0": - # extract FlashPix information (incomplete) - self.info["flashpix"] = s # FIXME: value will change - elif marker == 0xFFE2 and s[:12] == "ICC_PROFILE\0": - # Since an ICC profile can be larger than the maximum size of - # a JPEG marker (64K), we need provisions to split it into - # multiple markers. The format defined by the ICC specifies - # one or more APP2 markers containing the following data: - # Identifying string ASCII "ICC_PROFILE\0" (12 bytes) - # Marker sequence number 1, 2, etc (1 byte) - # Number of markers Total of APP2's used (1 byte) - # Profile data (remainder of APP2 data) - # Decoders should use the marker sequence numbers to - # reassemble the profile, rather than assuming that the APP2 - # markers appear in the correct sequence. - self.icclist.append(s) - elif marker == 0xFFEE and s[:5] == "Adobe": - self.info["adobe"] = i16(s, 5) - # extract Adobe custom properties - try: - adobe_transform = ord(s[1]) - except: - pass - else: - self.info["adobe_transform"] = adobe_transform - -def COM(self, marker): - # - # Comment marker. Store these in the APP dictionary. - - n = i16(self.fp.read(2))-2 - s = ImageFile._safe_read(self.fp, n) - - self.app["COM"] = s # compatibility - self.applist.append(("COM", s)) - -def SOF(self, marker): - # - # Start of frame marker. Defines the size and mode of the - # image. JPEG is colour blind, so we use some simple - # heuristics to map the number of layers to an appropriate - # mode. Note that this could be made a bit brighter, by - # looking for JFIF and Adobe APP markers. - - n = i16(self.fp.read(2))-2 - s = ImageFile._safe_read(self.fp, n) - self.size = i16(s[3:]), i16(s[1:]) - - self.bits = ord(s[0]) - if self.bits != 8: - raise SyntaxError("cannot handle %d-bit layers" % self.bits) - - self.layers = ord(s[5]) - if self.layers == 1: - self.mode = "L" - elif self.layers == 3: - self.mode = "RGB" - elif self.layers == 4: - self.mode = "CMYK" - else: - raise SyntaxError("cannot handle %d-layer images" % self.layers) - - if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]: - self.info["progressive"] = self.info["progression"] = 1 - - if self.icclist: - # fixup icc profile - self.icclist.sort() # sort by sequence number - if ord(self.icclist[0][13]) == len(self.icclist): - profile = [] - for p in self.icclist: - profile.append(p[14:]) - icc_profile = string.join(profile, "") - else: - icc_profile = None # wrong number of fragments - self.info["icc_profile"] = icc_profile - self.icclist = None - - for i in range(6, len(s), 3): - t = s[i:i+3] - # 4-tuples: id, vsamp, hsamp, qtable - self.layer.append((t[0], ord(t[1])/16, ord(t[1])&15, ord(t[2]))) - -def DQT(self, marker): - # - # Define quantization table. Support baseline 8-bit tables - # only. Note that there might be more than one table in - # each marker. - - # FIXME: The quantization tables can be used to estimate the - # compression quality. - - n = i16(self.fp.read(2))-2 - s = ImageFile._safe_read(self.fp, n) - while len(s): - if len(s) < 65: - raise SyntaxError("bad quantization table marker") - v = ord(s[0]) - if v/16 == 0: - self.quantization[v&15] = array.array("b", s[1:65]) - s = s[65:] - else: - return # FIXME: add code to read 16-bit tables! - # raise SyntaxError, "bad quantization table element size" - - -# -# JPEG marker table - -MARKER = { - 0xFFC0: ("SOF0", "Baseline DCT", SOF), - 0xFFC1: ("SOF1", "Extended Sequential DCT", SOF), - 0xFFC2: ("SOF2", "Progressive DCT", SOF), - 0xFFC3: ("SOF3", "Spatial lossless", SOF), - 0xFFC4: ("DHT", "Define Huffman table", Skip), - 0xFFC5: ("SOF5", "Differential sequential DCT", SOF), - 0xFFC6: ("SOF6", "Differential progressive DCT", SOF), - 0xFFC7: ("SOF7", "Differential spatial", SOF), - 0xFFC8: ("JPG", "Extension", None), - 0xFFC9: ("SOF9", "Extended sequential DCT (AC)", SOF), - 0xFFCA: ("SOF10", "Progressive DCT (AC)", SOF), - 0xFFCB: ("SOF11", "Spatial lossless DCT (AC)", SOF), - 0xFFCC: ("DAC", "Define arithmetic coding conditioning", Skip), - 0xFFCD: ("SOF13", "Differential sequential DCT (AC)", SOF), - 0xFFCE: ("SOF14", "Differential progressive DCT (AC)", SOF), - 0xFFCF: ("SOF15", "Differential spatial (AC)", SOF), - 0xFFD0: ("RST0", "Restart 0", None), - 0xFFD1: ("RST1", "Restart 1", None), - 0xFFD2: ("RST2", "Restart 2", None), - 0xFFD3: ("RST3", "Restart 3", None), - 0xFFD4: ("RST4", "Restart 4", None), - 0xFFD5: ("RST5", "Restart 5", None), - 0xFFD6: ("RST6", "Restart 6", None), - 0xFFD7: ("RST7", "Restart 7", None), - 0xFFD8: ("SOI", "Start of image", None), - 0xFFD9: ("EOI", "End of image", None), - 0xFFDA: ("SOS", "Start of scan", Skip), - 0xFFDB: ("DQT", "Define quantization table", DQT), - 0xFFDC: ("DNL", "Define number of lines", Skip), - 0xFFDD: ("DRI", "Define restart interval", Skip), - 0xFFDE: ("DHP", "Define hierarchical progression", SOF), - 0xFFDF: ("EXP", "Expand reference component", Skip), - 0xFFE0: ("APP0", "Application segment 0", APP), - 0xFFE1: ("APP1", "Application segment 1", APP), - 0xFFE2: ("APP2", "Application segment 2", APP), - 0xFFE3: ("APP3", "Application segment 3", APP), - 0xFFE4: ("APP4", "Application segment 4", APP), - 0xFFE5: ("APP5", "Application segment 5", APP), - 0xFFE6: ("APP6", "Application segment 6", APP), - 0xFFE7: ("APP7", "Application segment 7", APP), - 0xFFE8: ("APP8", "Application segment 8", APP), - 0xFFE9: ("APP9", "Application segment 9", APP), - 0xFFEA: ("APP10", "Application segment 10", APP), - 0xFFEB: ("APP11", "Application segment 11", APP), - 0xFFEC: ("APP12", "Application segment 12", APP), - 0xFFED: ("APP13", "Application segment 13", APP), - 0xFFEE: ("APP14", "Application segment 14", APP), - 0xFFEF: ("APP15", "Application segment 15", APP), - 0xFFF0: ("JPG0", "Extension 0", None), - 0xFFF1: ("JPG1", "Extension 1", None), - 0xFFF2: ("JPG2", "Extension 2", None), - 0xFFF3: ("JPG3", "Extension 3", None), - 0xFFF4: ("JPG4", "Extension 4", None), - 0xFFF5: ("JPG5", "Extension 5", None), - 0xFFF6: ("JPG6", "Extension 6", None), - 0xFFF7: ("JPG7", "Extension 7", None), - 0xFFF8: ("JPG8", "Extension 8", None), - 0xFFF9: ("JPG9", "Extension 9", None), - 0xFFFA: ("JPG10", "Extension 10", None), - 0xFFFB: ("JPG11", "Extension 11", None), - 0xFFFC: ("JPG12", "Extension 12", None), - 0xFFFD: ("JPG13", "Extension 13", None), - 0xFFFE: ("COM", "Comment", COM) -} - - -def _accept(prefix): - return prefix[0] == "\377" - -## -# Image plugin for JPEG and JFIF images. - -class JpegImageFile(ImageFile.ImageFile): - - format = "JPEG" - format_description = "JPEG (ISO 10918)" - - def _open(self): - - s = self.fp.read(1) - - if ord(s[0]) != 255: - raise SyntaxError("not a JPEG file") - - # Create attributes - self.bits = self.layers = 0 - - # JPEG specifics (internal) - self.layer = [] - self.huffman_dc = {} - self.huffman_ac = {} - self.quantization = {} - self.app = {} # compatibility - self.applist = [] - self.icclist = [] - - while 1: - - s = s + self.fp.read(1) - - i = i16(s) - - if MARKER.has_key(i): - name, description, handler = MARKER[i] - # print hex(i), name, description - if handler is not None: - handler(self, i) - if i == 0xFFDA: # start of scan - rawmode = self.mode - if self.mode == "CMYK": - rawmode = "CMYK;I" # assume adobe conventions - self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))] - # self.__offset = self.fp.tell() - break - s = self.fp.read(1) - elif i == 0 or i == 65535: - # padded marker or junk; move on - s = "\xff" - else: - raise SyntaxError("no marker found") - - def draft(self, mode, size): - - if len(self.tile) != 1: - return - - d, e, o, a = self.tile[0] - scale = 0 - - if a[0] == "RGB" and mode in ["L", "YCbCr"]: - self.mode = mode - a = mode, "" - - if size: - scale = max(self.size[0] / size[0], self.size[1] / size[1]) - for s in [8, 4, 2, 1]: - if scale >= s: - break - e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1] - self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s) - scale = s - - self.tile = [(d, e, o, a)] - self.decoderconfig = (scale, 1) - - return self - - def load_djpeg(self): - - # ALTERNATIVE: handle JPEGs via the IJG command line utilities - - import tempfile, os - file = tempfile.mktemp() - os.system("djpeg %s >%s" % (self.filename, file)) - - try: - self.im = Image.core.open_ppm(file) - finally: - try: os.unlink(file) - except: pass - - self.mode = self.im.mode - self.size = self.im.size - - self.tile = [] - - def _getexif(self): - # Extract EXIF information. This method is highly experimental, - # and is likely to be replaced with something better in a future - # version. - import TiffImagePlugin, StringIO - def fixup(value): - if len(value) == 1: - return value[0] - return value - # The EXIF record consists of a TIFF file embedded in a JPEG - # application marker (!). - try: - data = self.info["exif"] - except KeyError: - return None - file = StringIO.StringIO(data[6:]) - head = file.read(8) - exif = {} - # process dictionary - info = TiffImagePlugin.ImageFileDirectory(head) - info.load(file) - for key, value in info.items(): - exif[key] = fixup(value) - # get exif extension - try: - file.seek(exif[0x8769]) - except KeyError: - pass - else: - info = TiffImagePlugin.ImageFileDirectory(head) - info.load(file) - for key, value in info.items(): - exif[key] = fixup(value) - # get gpsinfo extension - try: - file.seek(exif[0x8825]) - except KeyError: - pass - else: - info = TiffImagePlugin.ImageFileDirectory(head) - info.load(file) - exif[0x8825] = gps = {} - for key, value in info.items(): - gps[key] = fixup(value) - return exif - -# -------------------------------------------------------------------- -# stuff to save JPEG files - -RAWMODE = { - "1": "L", - "L": "L", - "RGB": "RGB", - "RGBA": "RGB", - "RGBX": "RGB", - "CMYK": "CMYK;I", # assume adobe conventions - "YCbCr": "YCbCr", -} - -def _save(im, fp, filename): - - try: - rawmode = RAWMODE[im.mode] - except KeyError: - raise IOError("cannot write mode %s as JPEG" % im.mode) - - info = im.encoderinfo - - dpi = info.get("dpi", (0, 0)) - - subsampling = info.get("subsampling", -1) - if subsampling == "4:4:4": - subsampling = 0 - elif subsampling == "4:2:2": - subsampling = 1 - elif subsampling == "4:1:1": - subsampling = 2 - - extra = "" - - icc_profile = info.get("icc_profile") - if icc_profile: - ICC_OVERHEAD_LEN = 14 - MAX_BYTES_IN_MARKER = 65533 - MAX_DATA_BYTES_IN_MARKER = MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN - markers = [] - while icc_profile: - markers.append(icc_profile[:MAX_DATA_BYTES_IN_MARKER]) - icc_profile = icc_profile[MAX_DATA_BYTES_IN_MARKER:] - i = 1 - for marker in markers: - size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker)) - extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker) - i = i + 1 - - # get keyword arguments - im.encoderconfig = ( - info.get("quality", 0), - # "progressive" is the official name, but older documentation - # says "progression" - # FIXME: issue a warning if the wrong form is used (post-1.1.7) - info.has_key("progressive") or info.has_key("progression"), - info.get("smooth", 0), - info.has_key("optimize"), - info.get("streamtype", 0), - dpi[0], dpi[1], - subsampling, - extra, - ) - - ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)]) - -def _save_cjpeg(im, fp, filename): - # ALTERNATIVE: handle JPEGs via the IJG command line utilities. - import os - file = im._dump() - os.system("cjpeg %s >%s" % (file, filename)) - try: os.unlink(file) - except: pass - -# -------------------------------------------------------------------q- -# Registry stuff - -Image.register_open("JPEG", JpegImageFile, _accept) -Image.register_save("JPEG", _save) - -Image.register_extension("JPEG", ".jfif") -Image.register_extension("JPEG", ".jpe") -Image.register_extension("JPEG", ".jpg") -Image.register_extension("JPEG", ".jpeg") - -Image.register_mime("JPEG", "image/jpeg") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py deleted file mode 100755 index 62ee52cf8ff..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/McIdasImagePlugin.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# Basic McIdas support for PIL -# -# History: -# 1997-05-05 fl Created (8-bit images only) -# 2009-03-08 fl Added 16/32-bit support. -# -# Thanks to Richard Jones and Craig Swank for specs and samples. -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.2" - -import struct -import Image, ImageFile - -def _accept(s): - return s[:8] == "\x00\x00\x00\x00\x00\x00\x00\x04" - -## -# Image plugin for McIdas area images. - -class McIdasImageFile(ImageFile.ImageFile): - - format = "MCIDAS" - format_description = "McIdas area file" - - def _open(self): - - # parse area file directory - s = self.fp.read(256) - if not _accept(s) or len(s) != 256: - raise SyntaxError("not an McIdas area file") - - self.area_descriptor_raw = s - self.area_descriptor = w = [0] + list(struct.unpack("!64i", s)) - - # get mode - if w[11] == 1: - mode = rawmode = "L" - elif w[11] == 2: - # FIXME: add memory map support - mode = "I"; rawmode = "I;16B" - elif w[11] == 4: - # FIXME: add memory map support - mode = "I"; rawmode = "I;32B" - else: - raise SyntaxError("unsupported McIdas format") - - self.mode = mode - self.size = w[10], w[9] - - offset = w[34] + w[15] - stride = w[15] + w[10]*w[11]*w[14] - - self.tile = [("raw", (0, 0) + self.size, offset, (rawmode, stride, 1))] - -# -------------------------------------------------------------------- -# registry - -Image.register_open("MCIDAS", McIdasImageFile, _accept) - -# no default extension diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py deleted file mode 100755 index b1a3bba79f7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MicImagePlugin.py +++ /dev/null @@ -1,95 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# Microsoft Image Composer support for PIL -# -# Notes: -# uses TiffImagePlugin.py to read the actual image streams -# -# History: -# 97-01-20 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.1" - - -import Image, TiffImagePlugin -from OleFileIO import * - - -# -# -------------------------------------------------------------------- - - -def _accept(prefix): - return prefix[:8] == MAGIC - -## -# Image plugin for Microsoft's Image Composer file format. - -class MicImageFile(TiffImagePlugin.TiffImageFile): - - format = "MIC" - format_description = "Microsoft Image Composer" - - def _open(self): - - # read the OLE directory and see if this is a likely - # to be a Microsoft Image Composer file - - try: - self.ole = OleFileIO(self.fp) - except IOError: - raise SyntaxError, "not an MIC file; invalid OLE file" - - # find ACI subfiles with Image members (maybe not the - # best way to identify MIC files, but what the... ;-) - - self.images = [] - for file in self.ole.listdir(): - if file[1:] and file[0][-4:] == ".ACI" and file[1] == "Image": - self.images.append(file) - - # if we didn't find any images, this is probably not - # an MIC file. - if not self.images: - raise SyntaxError, "not an MIC file; no image entries" - - self.__fp = self.fp - self.frame = 0 - - if len(self.images) > 1: - self.category = Image.CONTAINER - - self.seek(0) - - def seek(self, frame): - - try: - filename = self.images[frame] - except IndexError: - raise EOFError, "no such frame" - - self.fp = self.ole.openstream(filename) - - TiffImagePlugin.TiffImageFile._open(self) - - self.frame = frame - - def tell(self): - - return self.frame - -# -# -------------------------------------------------------------------- - -Image.register_open("MIC", MicImageFile, _accept) - -Image.register_extension("MIC", ".mic") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py deleted file mode 100755 index c02edee8267..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MpegImagePlugin.py +++ /dev/null @@ -1,82 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# MPEG file handling -# -# History: -# 95-09-09 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1995. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.1" - -import Image, ImageFile - -# -# Bitstream parser - -class BitStream: - - def __init__(self, fp): - self.fp = fp - self.bits = 0 - self.bitbuffer = 0 - - def next(self): - return ord(self.fp.read(1)) - - def peek(self, bits): - while self.bits < bits: - c = self.next() - if c < 0: - self.bits = 0 - continue - self.bitbuffer = (self.bitbuffer << 8) + c - self.bits = self.bits + 8 - return self.bitbuffer >> (self.bits - bits) & (1L << bits) - 1 - - def skip(self, bits): - while self.bits < bits: - self.bitbuffer = (self.bitbuffer << 8) + ord(self.fp.read(1)) - self.bits = self.bits + 8 - self.bits = self.bits - bits - - def read(self, bits): - v = self.peek(bits) - self.bits = self.bits - bits - return v - -## -# Image plugin for MPEG streams. This plugin can identify a stream, -# but it cannot read it. - -class MpegImageFile(ImageFile.ImageFile): - - format = "MPEG" - format_description = "MPEG" - - def _open(self): - - s = BitStream(self.fp) - - if s.read(32) != 0x1B3: - raise SyntaxError, "not an MPEG file" - - self.mode = "RGB" - self.size = s.read(12), s.read(12) - - -# -------------------------------------------------------------------- -# Registry stuff - -Image.register_open("MPEG", MpegImageFile) - -Image.register_extension("MPEG", ".mpg") -Image.register_extension("MPEG", ".mpeg") - -Image.register_mime("MPEG", "video/mpeg") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py deleted file mode 100755 index 9dac36b47b7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/MspImagePlugin.py +++ /dev/null @@ -1,103 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# MSP file handling -# -# This is the format used by the Paint program in Windows 1 and 2. -# -# History: -# 95-09-05 fl Created -# 97-01-03 fl Read/write MSP images -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1995-97. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.1" - -import Image, ImageFile - - -# -# read MSP files - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def _accept(prefix): - return prefix[:4] in ["DanM", "LinS"] - -## -# Image plugin for Windows MSP images. This plugin supports both -# uncompressed (Windows 1.0). - -class MspImageFile(ImageFile.ImageFile): - - format = "MSP" - format_description = "Windows Paint" - - def _open(self): - - # Header - s = self.fp.read(32) - if s[:4] not in ["DanM", "LinS"]: - raise SyntaxError, "not an MSP file" - - # Header checksum - sum = 0 - for i in range(0, 32, 2): - sum = sum ^ i16(s[i:i+2]) - if sum != 0: - raise SyntaxError, "bad MSP checksum" - - self.mode = "1" - self.size = i16(s[4:]), i16(s[6:]) - - if s[:4] == "DanM": - self.tile = [("raw", (0,0)+self.size, 32, ("1", 0, 1))] - else: - self.tile = [("msp", (0,0)+self.size, 32+2*self.size[1], None)] - -# -# write MSP files (uncompressed only) - -def o16(i): - return chr(i&255) + chr(i>>8&255) - -def _save(im, fp, filename): - - if im.mode != "1": - raise IOError, "cannot write mode %s as MSP" % im.mode - - # create MSP header - header = [0] * 16 - - header[0], header[1] = i16("Da"), i16("nM") # version 1 - header[2], header[3] = im.size - header[4], header[5] = 1, 1 - header[6], header[7] = 1, 1 - header[8], header[9] = im.size - - sum = 0 - for h in header: - sum = sum ^ h - header[12] = sum # FIXME: is this the right field? - - # header - for h in header: - fp.write(o16(h)) - - # image body - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 32, ("1", 0, 1))]) - -# -# registry - -Image.register_open("MSP", MspImageFile, _accept) -Image.register_save("MSP", _save) - -Image.register_extension("MSP", ".msp") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py deleted file mode 100755 index 36e598a9be3..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/OleFileIO.py +++ /dev/null @@ -1,528 +0,0 @@ -# -# THIS IS WORK IN PROGRESS -# -# The Python Imaging Library -# $Id$ -# -# stuff to deal with OLE2 Structured Storage files. this module is -# used by PIL to read Image Composer and FlashPix files, but can also -# be used to read other files of this type. -# -# History: -# 1997-01-20 fl Created -# 1997-01-22 fl Fixed 64-bit portability quirk -# 2003-09-09 fl Fixed typo in OleFileIO.loadfat (noted by Daniel Haertle) -# 2004-02-29 fl Changed long hex constants to signed integers -# -# Notes: -# FIXME: sort out sign problem (eliminate long hex constants) -# FIXME: change filename to use "a/b/c" instead of ["a", "b", "c"] -# FIXME: provide a glob mechanism function (using fnmatchcase) -# -# Literature: -# -# "FlashPix Format Specification, Appendix A", Kodak and Microsoft, -# September 1996. -# -# Quotes: -# -# "If this document and functionality of the Software conflict, -# the actual functionality of the Software represents the correct -# functionality" -- Microsoft, in the OLE format specification -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - -import string, StringIO - - -def i16(c, o = 0): - return ord(c[o])+(ord(c[o+1])<<8) - -def i32(c, o = 0): - return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24) - - -MAGIC = '\320\317\021\340\241\261\032\341' - -# -# -------------------------------------------------------------------- -# property types - -VT_EMPTY=0; VT_NULL=1; VT_I2=2; VT_I4=3; VT_R4=4; VT_R8=5; VT_CY=6; -VT_DATE=7; VT_BSTR=8; VT_DISPATCH=9; VT_ERROR=10; VT_BOOL=11; -VT_VARIANT=12; VT_UNKNOWN=13; VT_DECIMAL=14; VT_I1=16; VT_UI1=17; -VT_UI2=18; VT_UI4=19; VT_I8=20; VT_UI8=21; VT_INT=22; VT_UINT=23; -VT_VOID=24; VT_HRESULT=25; VT_PTR=26; VT_SAFEARRAY=27; VT_CARRAY=28; -VT_USERDEFINED=29; VT_LPSTR=30; VT_LPWSTR=31; VT_FILETIME=64; -VT_BLOB=65; VT_STREAM=66; VT_STORAGE=67; VT_STREAMED_OBJECT=68; -VT_STORED_OBJECT=69; VT_BLOB_OBJECT=70; VT_CF=71; VT_CLSID=72; -VT_VECTOR=0x1000; - -# map property id to name (for debugging purposes) - -VT = {} -for k, v in vars().items(): - if k[:3] == "VT_": - VT[v] = k - -# -# -------------------------------------------------------------------- -# Some common document types (root.clsid fields) - -WORD_CLSID = "00020900-0000-0000-C000-000000000046" - - -# -# -------------------------------------------------------------------- - -class _OleStream(StringIO.StringIO): - - """OLE2 Stream - - Returns a read-only file object which can be used to read - the contents of a OLE stream. To open a stream, use the - openstream method in the OleFile class. - - This function can be used with either ordinary streams, - or ministreams, depending on the offset, sectorsize, and - fat table arguments. - """ - - # FIXME: should store the list of sects obtained by following - # the fat chain, and load new sectors on demand instead of - # loading it all in one go. - - def __init__(self, fp, sect, size, offset, sectorsize, fat): - - data = [] - - while sect != -2: # 0xFFFFFFFEL: - fp.seek(offset + sectorsize * sect) - data.append(fp.read(sectorsize)) - sect = fat[sect] - - data = string.join(data, "") - - # print len(data), size - - StringIO.StringIO.__init__(self, data[:size]) - -# -# -------------------------------------------------------------------- - -# FIXME: should add a counter in here to avoid looping forever -# if the tree is broken. - -class _OleDirectoryEntry: - - """OLE2 Directory Entry - - Encapsulates a stream directory entry. Note that the - constructor builds a tree of all subentries, so we only - have to call it with the root object. - """ - - def __init__(self, sidlist, sid): - - # store directory parameters. the caller provides - # a complete list of directory entries, as read from - # the directory stream. - - name, type, sect, size, sids, clsid = sidlist[sid] - - self.sid = sid - self.name = name - self.type = type # 1=storage 2=stream - self.sect = sect - self.size = size - self.clsid = clsid - - # process child nodes, if any - - self.kids = [] - - sid = sidlist[sid][4][2] - - if sid != -1: - - # the directory entries are organized as a red-black tree. - # the following piece of code does an ordered traversal of - # such a tree (at least that's what I hope ;-) - - stack = [self.sid] - - # start at leftmost position - - left, right, child = sidlist[sid][4] - - while left != -1: # 0xFFFFFFFFL: - stack.append(sid) - sid = left - left, right, child = sidlist[sid][4] - - while sid != self.sid: - - self.kids.append(_OleDirectoryEntry(sidlist, sid)) - - # try to move right - left, right, child = sidlist[sid][4] - if right != -1: # 0xFFFFFFFFL: - # and then back to the left - sid = right - while 1: - left, right, child = sidlist[sid][4] - if left == -1: # 0xFFFFFFFFL: - break - stack.append(sid) - sid = left - else: - # couldn't move right; move up instead - while 1: - ptr = stack[-1] - del stack[-1] - left, right, child = sidlist[ptr][4] - if right != sid: - break - sid = right - left, right, child = sidlist[sid][4] - if right != ptr: - sid = ptr - - # in the OLE file, entries are sorted on (length, name). - # for convenience, we sort them on name instead. - - self.kids.sort() - - def __cmp__(self, other): - "Compare entries by name" - - return cmp(self.name, other.name) - - def dump(self, tab = 0): - "Dump this entry, and all its subentries (for debug purposes only)" - - TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)", - "(property)", "(root)"] - - print " "*tab + repr(self.name), TYPES[self.type], - if self.type in (2, 5): - print self.size, "bytes", - print - if self.type in (1, 5) and self.clsid: - print " "*tab + "{%s}" % self.clsid - - for kid in self.kids: - kid.dump(tab + 2) - -# -# -------------------------------------------------------------------- - -## -# This class encapsulates the interface to an OLE 2 structured -# storage file. Use the {@link listdir} and {@link openstream} -# methods to access the contents of this file. - -class OleFileIO: - """OLE container object - - This class encapsulates the interface to an OLE 2 structured - storage file. Use the listdir and openstream methods to access - the contents of this file. - - Object names are given as a list of strings, one for each subentry - level. The root entry should be omitted. For example, the following - code extracts all image streams from a Microsoft Image Composer file: - - ole = OleFileIO("fan.mic") - - for entry in ole.listdir(): - if entry[1:2] == "Image": - fin = ole.openstream(entry) - fout = open(entry[0:1], "wb") - while 1: - s = fin.read(8192) - if not s: - break - fout.write(s) - - You can use the viewer application provided with the Python Imaging - Library to view the resulting files (which happens to be standard - TIFF files). - """ - - def __init__(self, filename = None): - - if filename: - self.open(filename) - - ## - # Open an OLE2 file. - - def open(self, filename): - """Open an OLE2 file""" - - if type(filename) == type(""): - self.fp = open(filename, "rb") - else: - self.fp = filename - - header = self.fp.read(512) - - if len(header) != 512 or header[:8] != MAGIC: - raise IOError, "not an OLE2 structured storage file" - - # file clsid (probably never used, so we don't store it) - clsid = self._clsid(header[8:24]) - - # FIXME: could check version and byte order fields - - self.sectorsize = 1 << i16(header, 30) - self.minisectorsize = 1 << i16(header, 32) - - self.minisectorcutoff = i32(header, 56) - - # Load file allocation tables - self.loadfat(header) - - # Load direcory. This sets both the sidlist (ordered by id) - # and the root (ordered by hierarchy) members. - self.loaddirectory(i32(header, 48)) - - self.ministream = None - self.minifatsect = i32(header, 60) - - def loadfat(self, header): - # Load the FAT table. The header contains a sector numbers - # for the first 109 FAT sectors. Additional sectors are - # described by DIF blocks (FIXME: not yet implemented) - - sect = header[76:512] - fat = [] - for i in range(0, len(sect), 4): - ix = i32(sect, i) - if ix == -2 or ix == -1: # ix == 0xFFFFFFFEL or ix == 0xFFFFFFFFL: - break - s = self.getsect(ix) - fat = fat + map(lambda i, s=s: i32(s, i), range(0, len(s), 4)) - self.fat = fat - - def loadminifat(self): - # Load the MINIFAT table. This is stored in a standard sub- - # stream, pointed to by a header field. - - s = self._open(self.minifatsect).read() - - self.minifat = map(lambda i, s=s: i32(s, i), range(0, len(s), 4)) - - def getsect(self, sect): - # Read given sector - - self.fp.seek(512 + self.sectorsize * sect) - return self.fp.read(self.sectorsize) - - def _unicode(self, s): - # Map unicode string to Latin 1 - - # FIXME: some day, Python will provide an official way to handle - # Unicode strings, but until then, this will have to do... - return filter(ord, s) - - def loaddirectory(self, sect): - # Load the directory. The directory is stored in a standard - # substream, independent of its size. - - # read directory stream - fp = self._open(sect) - - # create list of sid entries - self.sidlist = [] - while 1: - entry = fp.read(128) - if not entry: - break - type = ord(entry[66]) - name = self._unicode(entry[0:0+i16(entry, 64)]) - ptrs = i32(entry, 68), i32(entry, 72), i32(entry, 76) - sect, size = i32(entry, 116), i32(entry, 120) - clsid = self._clsid(entry[80:96]) - self.sidlist.append((name, type, sect, size, ptrs, clsid)) - - # create hierarchical list of directory entries - self.root = _OleDirectoryEntry(self.sidlist, 0) - - def dumpdirectory(self): - # Dump directory (for debugging only) - - self.root.dump() - - def _clsid(self, clsid): - if clsid == "\0" * len(clsid): - return "" - return (("%08X-%04X-%04X-%02X%02X-" + "%02X" * 6) % - ((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) + - tuple(map(ord, clsid[8:16])))) - - def _list(self, files, prefix, node): - # listdir helper - - prefix = prefix + [node.name] - for entry in node.kids: - if entry.kids: - self._list(files, prefix, entry) - else: - files.append(prefix[1:] + [entry.name]) - - def _find(self, filename): - # openstream helper - - node = self.root - for name in filename: - for kid in node.kids: - if kid.name == name: - break - else: - raise IOError, "file not found" - node = kid - return node.sid - - def _open(self, start, size = 0x7FFFFFFF): - # openstream helper. - - if size < self.minisectorcutoff: - # ministream object - if not self.ministream: - self.loadminifat() - self.ministream = self._open(self.sidlist[0][2]) - return _OleStream(self.ministream, start, size, 0, - self.minisectorsize, self.minifat) - - # standard stream - return _OleStream(self.fp, start, size, 512, - self.sectorsize, self.fat) - - ## - # Returns a list of streams stored in this file. - - def listdir(self): - """Return a list of streams stored in this file""" - - files = [] - self._list(files, [], self.root) - return files - - ## - # Opens a stream as a read-only file object. - - def openstream(self, filename): - """Open a stream as a read-only file object""" - - slot = self._find(filename) - name, type, sect, size, sids, clsid = self.sidlist[slot] - if type != 2: - raise IOError, "this file is not a stream" - return self._open(sect, size) - - ## - # Gets a list of properties described in substream. - - def getproperties(self, filename): - """Return properties described in substream""" - - fp = self.openstream(filename) - - data = {} - - # header - s = fp.read(28) - clsid = self._clsid(s[8:24]) - - # format id - s = fp.read(20) - fmtid = self._clsid(s[:16]) - fp.seek(i32(s, 16)) - - # get section - s = "****" + fp.read(i32(fp.read(4))-4) - - for i in range(i32(s, 4)): - - id = i32(s, 8+i*8) - offset = i32(s, 12+i*8) - type = i32(s, offset) - - # test for common types first (should perhaps use - # a dictionary instead?) - - if type == VT_I2: - value = i16(s, offset+4) - if value >= 32768: - value = value - 65536 - elif type == VT_UI2: - value = i16(s, offset+4) - elif type in (VT_I4, VT_ERROR): - value = i32(s, offset+4) - elif type == VT_UI4: - value = i32(s, offset+4) # FIXME - elif type in (VT_BSTR, VT_LPSTR): - count = i32(s, offset+4) - value = s[offset+8:offset+8+count-1] - elif type == VT_BLOB: - count = i32(s, offset+4) - value = s[offset+8:offset+8+count] - elif type == VT_LPWSTR: - count = i32(s, offset+4) - value = self._unicode(s[offset+8:offset+8+count*2]) - elif type == VT_FILETIME: - value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32) - # FIXME: this is a 64-bit int: "number of 100ns periods - # since Jan 1,1601". Should map this to Python time - value = value / 10000000L # seconds - elif type == VT_UI1: - value = ord(s[offset+4]) - elif type == VT_CLSID: - value = self._clsid(s[offset+4:offset+20]) - elif type == VT_CF: - count = i32(s, offset+4) - value = s[offset+8:offset+8+count] - else: - value = None # everything else yields "None" - - # FIXME: add support for VT_VECTOR - - #print "%08x" % id, repr(value), - #print "(%s)" % VT[i32(s, offset) & 0xFFF] - - data[id] = value - - return data - -# -# -------------------------------------------------------------------- -# This script can be used to dump the directory of any OLE2 structured -# storage file. - -if __name__ == "__main__": - - import sys - - for file in sys.argv[1:]: - try: - ole = OleFileIO(file) - print "-" * 68 - print file - print "-" * 68 - ole.dumpdirectory() - for file in ole.listdir(): - if file[-1][0] == "\005": - print file - props = ole.getproperties(file) - props = props.items() - props.sort() - for k, v in props: - print " ", k, v - except IOError, v: - print "***", "cannot read", file, "-", v diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py deleted file mode 100755 index 7309e17b3e2..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PSDraw.py +++ /dev/null @@ -1,199 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# simple postscript graphics interface -# -# History: -# 1996-04-20 fl Created -# 1999-01-10 fl Added gsave/grestore to image method -# 2005-05-04 fl Fixed floating point issue in image (from Eric Etheridge) -# -# Copyright (c) 1997-2005 by Secret Labs AB. All rights reserved. -# Copyright (c) 1996 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -import EpsImagePlugin -import string - -## -# Simple Postscript graphics interface. - -class PSDraw: - - def __init__(self, fp=None): - if not fp: - import sys - fp = sys.stdout - self.fp = fp - - def begin_document(self, id = None): - "Write Postscript DSC header" - # FIXME: incomplete - self.fp.write("%!PS-Adobe-3.0\n" - "save\n" - "/showpage { } def\n" - "%%EndComments\n" - "%%BeginDocument\n") - #self.fp.write(ERROR_PS) # debugging! - self.fp.write(EDROFF_PS) - self.fp.write(VDI_PS) - self.fp.write("%%EndProlog\n") - self.isofont = {} - - def end_document(self): - "Write Postscript DSC footer" - self.fp.write("%%EndDocument\n" - "restore showpage\n" - "%%End\n") - if hasattr(self.fp, "flush"): - self.fp.flush() - - def setfont(self, font, size): - if not self.isofont.has_key(font): - # reencode font - self.fp.write("/PSDraw-%s ISOLatin1Encoding /%s E\n" %\ - (font, font)) - self.isofont[font] = 1 - # rough - self.fp.write("/F0 %d /PSDraw-%s F\n" % (size, font)) - - def setink(self, ink): - print "*** NOT YET IMPLEMENTED ***" - - def line(self, xy0, xy1): - xy = xy0 + xy1 - self.fp.write("%d %d %d %d Vl\n" % xy) - - def rectangle(self, box): - self.fp.write("%d %d M %d %d 0 Vr\n" % box) - - def text(self, xy, text): - text = string.joinfields(string.splitfields(text, "("), "\\(") - text = string.joinfields(string.splitfields(text, ")"), "\\)") - xy = xy + (text,) - self.fp.write("%d %d M (%s) S\n" % xy) - - def image(self, box, im, dpi = None): - "Write an PIL image" - # default resolution depends on mode - if not dpi: - if im.mode == "1": - dpi = 200 # fax - else: - dpi = 100 # greyscale - # image size (on paper) - x = float(im.size[0] * 72) / dpi - y = float(im.size[1] * 72) / dpi - # max allowed size - xmax = float(box[2] - box[0]) - ymax = float(box[3] - box[1]) - if x > xmax: - y = y * xmax / x; x = xmax - if y > ymax: - x = x * ymax / y; y = ymax - dx = (xmax - x) / 2 + box[0] - dy = (ymax - y) / 2 + box[1] - self.fp.write("gsave\n%f %f translate\n" % (dx, dy)) - if (x, y) != im.size: - # EpsImagePlugin._save prints the image at (0,0,xsize,ysize) - sx = x / im.size[0] - sy = y / im.size[1] - self.fp.write("%f %f scale\n" % (sx, sy)) - EpsImagePlugin._save(im, self.fp, None, 0) - self.fp.write("\ngrestore\n") - -# -------------------------------------------------------------------- -# Postscript driver - -# -# EDROFF.PS -- Postscript driver for Edroff 2 -# -# History: -# 94-01-25 fl: created (edroff 2.04) -# -# Copyright (c) Fredrik Lundh 1994. -# - -EDROFF_PS = """\ -/S { show } bind def -/P { moveto show } bind def -/M { moveto } bind def -/X { 0 rmoveto } bind def -/Y { 0 exch rmoveto } bind def -/E { findfont - dup maxlength dict begin - { - 1 index /FID ne { def } { pop pop } ifelse - } forall - /Encoding exch def - dup /FontName exch def - currentdict end definefont pop -} bind def -/F { findfont exch scalefont dup setfont - [ exch /setfont cvx ] cvx bind def -} bind def -""" - -# -# VDI.PS -- Postscript driver for VDI meta commands -# -# History: -# 94-01-25 fl: created (edroff 2.04) -# -# Copyright (c) Fredrik Lundh 1994. -# - -VDI_PS = """\ -/Vm { moveto } bind def -/Va { newpath arcn stroke } bind def -/Vl { moveto lineto stroke } bind def -/Vc { newpath 0 360 arc closepath } bind def -/Vr { exch dup 0 rlineto - exch dup neg 0 exch rlineto - exch neg 0 rlineto - 0 exch rlineto - 100 div setgray fill 0 setgray } bind def -/Tm matrix def -/Ve { Tm currentmatrix pop - translate scale newpath 0 0 .5 0 360 arc closepath - Tm setmatrix -} bind def -/Vf { currentgray exch setgray fill setgray } bind def -""" - -# -# ERROR.PS -- Error handler -# -# History: -# 89-11-21 fl: created (pslist 1.10) -# - -ERROR_PS = """\ -/landscape false def -/errorBUF 200 string def -/errorNL { currentpoint 10 sub exch pop 72 exch moveto } def -errordict begin /handleerror { - initmatrix /Courier findfont 10 scalefont setfont - newpath 72 720 moveto $error begin /newerror false def - (PostScript Error) show errorNL errorNL - (Error: ) show - /errorname load errorBUF cvs show errorNL errorNL - (Command: ) show - /command load dup type /stringtype ne { errorBUF cvs } if show - errorNL errorNL - (VMstatus: ) show - vmstatus errorBUF cvs show ( bytes available, ) show - errorBUF cvs show ( bytes used at level ) show - errorBUF cvs show errorNL errorNL - (Operand stargck: ) show errorNL /ostargck load { - dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL - } forall errorNL - (Execution stargck: ) show errorNL /estargck load { - dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL - } forall - end showpage -} def end -""" diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py deleted file mode 100755 index 3bbd9132778..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PaletteFile.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# Python Imaging Library -# $Id$ -# -# stuff to read simple, teragon-style palette files -# -# History: -# 97-08-23 fl Created -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - -import string - -## -# File handler for Teragon-style palette files. - -class PaletteFile: - - rawmode = "RGB" - - def __init__(self, fp): - - self.palette = map(lambda i: (i, i, i), range(256)) - - while 1: - - s = fp.readline() - - if not s: - break - if s[0] == "#": - continue - if len(s) > 100: - raise SyntaxError, "bad palette file" - - v = map(int, string.split(s)) - try: - [i, r, g, b] = v - except ValueError: - [i, r] = v - g = b = r - - if 0 <= i <= 255: - self.palette[i] = chr(r) + chr(g) + chr(b) - - self.palette = string.join(self.palette, "") - - - def getpalette(self): - - return self.palette, self.rawmode diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py deleted file mode 100755 index 78502313007..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PalmImagePlugin.py +++ /dev/null @@ -1,225 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# - -## -# Image plugin for Palm pixmap images (output only). -## - -__version__ = "1.0" - -import Image, ImageFile - -_Palm8BitColormapValues = ( - ( 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 )) - -# so build a prototype image to be used for palette resampling -def build_prototype_image(): - image = Image.new("L", (1,len(_Palm8BitColormapValues),)) - image.putdata(range(len(_Palm8BitColormapValues))) - palettedata = () - for i in range(len(_Palm8BitColormapValues)): - palettedata = palettedata + _Palm8BitColormapValues[i] - for i in range(256 - len(_Palm8BitColormapValues)): - palettedata = palettedata + (0, 0, 0) - image.putpalette(palettedata) - return image - -Palm8BitColormapImage = build_prototype_image() - -# OK, we now have in Palm8BitColormapImage, a "P"-mode image with the right palette -# -# -------------------------------------------------------------------- - -_FLAGS = { - "custom-colormap": 0x4000, - "is-compressed": 0x8000, - "has-transparent": 0x2000, - } - -_COMPRESSION_TYPES = { - "none": 0xFF, - "rle": 0x01, - "scanline": 0x00, - } - -def o16b(i): - return chr(i>>8&255) + chr(i&255) - -# -# -------------------------------------------------------------------- - -## -# (Internal) Image save plugin for the Palm format. - -def _save(im, fp, filename, check=0): - - if im.mode == "P": - - # we assume this is a color Palm image with the standard colormap, - # unless the "info" dict has a "custom-colormap" field - - rawmode = "P" - bpp = 8 - version = 1 - - elif im.mode == "L" and im.encoderinfo.has_key("bpp") and im.encoderinfo["bpp"] in (1, 2, 4): - - # this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because - # Palm does greyscale from white (0) to black (1) - bpp = im.encoderinfo["bpp"] - im = im.point(lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift)) - # we ignore the palette here - im.mode = "P" - rawmode = "P;" + str(bpp) - version = 1 - - elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4): - - # here we assume that even though the inherent mode is 8-bit grayscale, only - # the lower bpp bits are significant. We invert them to match the Palm. - bpp = im.info["bpp"] - im = im.point(lambda x, maxval=(1 << bpp)-1: maxval - (x & maxval)) - # we ignore the palette here - im.mode = "P" - rawmode = "P;" + str(bpp) - version = 1 - - elif im.mode == "1": - - # monochrome -- write it inverted, as is the Palm standard - rawmode = "1;I" - bpp = 1 - version = 0 - - else: - - raise IOError, "cannot write mode %s as Palm" % im.mode - - if check: - return check - - # - # make sure image data is available - im.load() - - # write header - - cols = im.size[0] - rows = im.size[1] - - rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2; - transparent_index = 0 - compression_type = _COMPRESSION_TYPES["none"] - - flags = 0; - if im.mode == "P" and im.info.has_key("custom-colormap"): - flags = flags & _FLAGS["custom-colormap"] - colormapsize = 4 * 256 + 2; - colormapmode = im.palette.mode - colormap = im.getdata().getpalette() - else: - colormapsize = 0 - - if im.info.has_key("offset"): - offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4; - else: - offset = 0 - - fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) - fp.write(chr(bpp)) - fp.write(chr(version)) - fp.write(o16b(offset)) - fp.write(chr(transparent_index)) - fp.write(chr(compression_type)) - fp.write(o16b(0)) # reserved by Palm - - # now write colormap if necessary - - if colormapsize > 0: - fp.write(o16b(256)) - for i in range(256): - fp.write(chr(i)) - if colormapmode == 'RGB': - fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2])) - elif colormapmode == 'RGBA': - fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2])) - - # now convert data to raw form - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))]) - - fp.flush() - - -# -# -------------------------------------------------------------------- - -Image.register_save("Palm", _save) - -Image.register_extension("Palm", ".palm") - -Image.register_mime("Palm", "image/palm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py deleted file mode 100755 index 07bd27e9af3..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcdImagePlugin.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PCD file handling -# -# History: -# 96-05-10 fl Created -# 96-05-27 fl Added draft mode (128x192, 256x384) -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.1" - - -import Image, ImageFile - -## -# Image plugin for PhotoCD images. This plugin only reads the 768x512 -# image from the file; higher resolutions are encoded in a proprietary -# encoding. - -class PcdImageFile(ImageFile.ImageFile): - - format = "PCD" - format_description = "Kodak PhotoCD" - - def _open(self): - - # rough - self.fp.seek(2048) - s = self.fp.read(2048) - - if s[:4] != "PCD_": - raise SyntaxError, "not a PCD file" - - orientation = ord(s[1538]) & 3 - if orientation == 1: - self.tile_post_rotate = 90 # hack - elif orientation == 3: - self.tile_post_rotate = -90 - - self.mode = "RGB" - self.size = 768, 512 # FIXME: not correct for rotated images! - self.tile = [("pcd", (0,0)+self.size, 96*2048, None)] - - def draft(self, mode, size): - - if len(self.tile) != 1: - return - - d, e, o, a = self.tile[0] - - if size: - scale = max(self.size[0] / size[0], self.size[1] / size[1]) - for s, o in [(4,0*2048), (2,0*2048), (1,96*2048)]: - if scale >= s: - break - # e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1] - # self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s) - - self.tile = [(d, e, o, a)] - - return self - -# -# registry - -Image.register_open("PCD", PcdImageFile) - -Image.register_extension("PCD", ".pcd") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py deleted file mode 100755 index bec39e3a034..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcfFontFile.py +++ /dev/null @@ -1,256 +0,0 @@ -# -# THIS IS WORK IN PROGRESS -# -# The Python Imaging Library -# $Id$ -# -# portable compiled font file parser -# -# history: -# 1997-08-19 fl created -# 2003-09-13 fl fixed loading of unicode fonts -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1997-2003 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -import Image -import FontFile - -import string - -# -------------------------------------------------------------------- -# declarations - -PCF_MAGIC = 0x70636601 # "\x01fcp" - -PCF_PROPERTIES = (1<<0) -PCF_ACCELERATORS = (1<<1) -PCF_METRICS = (1<<2) -PCF_BITMAPS = (1<<3) -PCF_INK_METRICS = (1<<4) -PCF_BDF_ENCODINGS = (1<<5) -PCF_SWIDTHS = (1<<6) -PCF_GLYPH_NAMES = (1<<7) -PCF_BDF_ACCELERATORS = (1<<8) - -BYTES_PER_ROW = [ - lambda bits: ((bits+7) >> 3), - lambda bits: ((bits+15) >> 3) & ~1, - lambda bits: ((bits+31) >> 3) & ~3, - lambda bits: ((bits+63) >> 3) & ~7, -] - - -def l16(c): - return ord(c[0]) + (ord(c[1])<<8) -def l32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - -def b16(c): - return ord(c[1]) + (ord(c[0])<<8) -def b32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) - -def sz(s, o): - return s[o:string.index(s, "\0", o)] - -## -# Font file plugin for the X11 PCF format. - -class PcfFontFile(FontFile.FontFile): - - name = "name" - - def __init__(self, fp): - - magic = l32(fp.read(4)) - if magic != PCF_MAGIC: - raise SyntaxError, "not a PCF file" - - FontFile.FontFile.__init__(self) - - count = l32(fp.read(4)) - self.toc = {} - for i in range(count): - type = l32(fp.read(4)) - self.toc[type] = l32(fp.read(4)), l32(fp.read(4)), l32(fp.read(4)) - - self.fp = fp - - self.info = self._load_properties() - - metrics = self._load_metrics() - bitmaps = self._load_bitmaps(metrics) - encoding = self._load_encoding() - - # - # create glyph structure - - for ch in range(256): - ix = encoding[ch] - if ix is not None: - x, y, l, r, w, a, d, f = metrics[ix] - glyph = (w, 0), (l, d-y, x+l, d), (0, 0, x, y), bitmaps[ix] - self.glyph[ch] = glyph - - def _getformat(self, tag): - - format, size, offset = self.toc[tag] - - fp = self.fp - fp.seek(offset) - - format = l32(fp.read(4)) - - if format & 4: - i16, i32 = b16, b32 - else: - i16, i32 = l16, l32 - - return fp, format, i16, i32 - - def _load_properties(self): - - # - # font properties - - properties = {} - - fp, format, i16, i32 = self._getformat(PCF_PROPERTIES) - - nprops = i32(fp.read(4)) - - # read property description - p = [] - for i in range(nprops): - p.append((i32(fp.read(4)), ord(fp.read(1)), i32(fp.read(4)))) - if nprops & 3: - fp.seek(4 - (nprops & 3), 1) # pad - - data = fp.read(i32(fp.read(4))) - - for k, s, v in p: - k = sz(data, k) - if s: - v = sz(data, v) - properties[k] = v - - return properties - - def _load_metrics(self): - - # - # font metrics - - metrics = [] - - fp, format, i16, i32 = self._getformat(PCF_METRICS) - - append = metrics.append - - if (format & 0xff00) == 0x100: - - # "compressed" metrics - for i in range(i16(fp.read(2))): - left = ord(fp.read(1)) - 128 - right = ord(fp.read(1)) - 128 - width = ord(fp.read(1)) - 128 - ascent = ord(fp.read(1)) - 128 - descent = ord(fp.read(1)) - 128 - xsize = right - left - ysize = ascent + descent - append( - (xsize, ysize, left, right, width, - ascent, descent, 0) - ) - - else: - - # "jumbo" metrics - for i in range(i32(fp.read(4))): - left = i16(fp.read(2)) - right = i16(fp.read(2)) - width = i16(fp.read(2)) - ascent = i16(fp.read(2)) - descent = i16(fp.read(2)) - attributes = i16(fp.read(2)) - xsize = right - left - ysize = ascent + descent - append( - (xsize, ysize, left, right, width, - ascent, descent, attributes) - ) - - return metrics - - def _load_bitmaps(self, metrics): - - # - # bitmap data - - bitmaps = [] - - fp, format, i16, i32 = self._getformat(PCF_BITMAPS) - - nbitmaps = i32(fp.read(4)) - - if nbitmaps != len(metrics): - raise IOError, "Wrong number of bitmaps" - - offsets = [] - for i in range(nbitmaps): - offsets.append(i32(fp.read(4))) - - bitmapSizes = [] - for i in range(4): - bitmapSizes.append(i32(fp.read(4))) - - byteorder = format & 4 # non-zero => MSB - bitorder = format & 8 # non-zero => MSB - padindex = format & 3 - - bitmapsize = bitmapSizes[padindex] - offsets.append(bitmapsize) - - data = fp.read(bitmapsize) - - pad = BYTES_PER_ROW[padindex] - mode = "1;R" - if bitorder: - mode = "1" - - for i in range(nbitmaps): - x, y, l, r, w, a, d, f = metrics[i] - b, e = offsets[i], offsets[i+1] - bitmaps.append( - Image.fromstring("1", (x, y), data[b:e], "raw", mode, pad(x)) - ) - - return bitmaps - - def _load_encoding(self): - - # map character code to bitmap index - encoding = [None] * 256 - - fp, format, i16, i32 = self._getformat(PCF_BDF_ENCODINGS) - - firstCol, lastCol = i16(fp.read(2)), i16(fp.read(2)) - firstRow, lastRow = i16(fp.read(2)), i16(fp.read(2)) - - default = i16(fp.read(2)) - - nencoding = (lastCol - firstCol + 1) * (lastRow - firstRow + 1) - - for i in range(nencoding): - encodingOffset = i16(fp.read(2)) - if encodingOffset != 0xFFFF: - try: - encoding[i+firstCol] = encodingOffset - except IndexError: - break # only load ISO-8859-1 glyphs - - return encoding diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py deleted file mode 100755 index 15012d51ccd..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PcxImagePlugin.py +++ /dev/null @@ -1,167 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PCX file handling -# -# This format was originally used by ZSoft's popular PaintBrush -# program for the IBM PC. It is also supported by many MS-DOS and -# Windows applications, including the Windows PaintBrush program in -# Windows 3. -# -# history: -# 1995-09-01 fl Created -# 1996-05-20 fl Fixed RGB support -# 1997-01-03 fl Fixed 2-bit and 4-bit support -# 1999-02-03 fl Fixed 8-bit support (broken in 1.0b1) -# 1999-02-07 fl Added write support -# 2002-06-09 fl Made 2-bit and 4-bit support a bit more robust -# 2002-07-30 fl Seek from to current position, not beginning of file -# 2003-06-03 fl Extract DPI settings (info["dpi"]) -# -# Copyright (c) 1997-2003 by Secret Labs AB. -# Copyright (c) 1995-2003 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.6" - -import Image, ImageFile, ImagePalette - -def i16(c,o): - return ord(c[o]) + (ord(c[o+1])<<8) - -def _accept(prefix): - return ord(prefix[0]) == 10 and ord(prefix[1]) in [0, 2, 3, 5] - -## -# Image plugin for Paintbrush images. - -class PcxImageFile(ImageFile.ImageFile): - - format = "PCX" - format_description = "Paintbrush" - - def _open(self): - - # header - s = self.fp.read(128) - if not _accept(s): - raise SyntaxError, "not a PCX file" - - # image - bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1 - if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]: - raise SyntaxError, "bad PCX image size" - - # format - version = ord(s[1]) - bits = ord(s[3]) - planes = ord(s[65]) - stride = i16(s,66) - - self.info["dpi"] = i16(s,12), i16(s,14) - - if bits == 1 and planes == 1: - mode = rawmode = "1" - - elif bits == 1 and planes in (2, 4): - mode = "P" - rawmode = "P;%dL" % planes - self.palette = ImagePalette.raw("RGB", s[16:64]) - - elif version == 5 and bits == 8 and planes == 1: - mode = rawmode = "L" - # FIXME: hey, this doesn't work with the incremental loader !!! - self.fp.seek(-769, 2) - s = self.fp.read(769) - if len(s) == 769 and ord(s[0]) == 12: - # check if the palette is linear greyscale - for i in range(256): - if s[i*3+1:i*3+4] != chr(i)*3: - mode = rawmode = "P" - break - if mode == "P": - self.palette = ImagePalette.raw("RGB", s[1:]) - self.fp.seek(128) - - elif version == 5 and bits == 8 and planes == 3: - mode = "RGB" - rawmode = "RGB;L" - - else: - raise IOError, "unknown PCX mode" - - self.mode = mode - self.size = bbox[2]-bbox[0], bbox[3]-bbox[1] - - bbox = (0, 0) + self.size - - self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))] - -# -------------------------------------------------------------------- -# save PCX files - -SAVE = { - # mode: (version, bits, planes, raw mode) - "1": (2, 1, 1, "1"), - "L": (5, 8, 1, "L"), - "P": (5, 8, 1, "P"), - "RGB": (5, 8, 3, "RGB;L"), -} - -def o16(i): - return chr(i&255) + chr(i>>8&255) - -def _save(im, fp, filename, check=0): - - try: - version, bits, planes, rawmode = SAVE[im.mode] - except KeyError: - raise ValueError, "Cannot save %s images as PCX" % im.mode - - if check: - return check - - # bytes per plane - stride = (im.size[0] * bits + 7) / 8 - - # under windows, we could determine the current screen size with - # "Image.core.display_mode()[1]", but I think that's overkill... - - screen = im.size - - dpi = 100, 100 - - # PCX header - fp.write( - chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) + - o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) + - o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) + - o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) + - chr(0)*54 - ) - - assert fp.tell() == 128 - - ImageFile._save(im, fp, [("pcx", (0,0)+im.size, 0, - (rawmode, bits*planes))]) - - if im.mode == "P": - # colour palette - fp.write(chr(12)) - fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes - elif im.mode == "L": - # greyscale palette - fp.write(chr(12)) - for i in range(256): - fp.write(chr(i)*3) - -# -------------------------------------------------------------------- -# registry - -Image.register_open("PCX", PcxImageFile, _accept) -Image.register_save("PCX", _save) - -Image.register_extension("PCX", ".pcx") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py deleted file mode 100755 index 4f957765ca6..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PdfImagePlugin.py +++ /dev/null @@ -1,211 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PDF (Acrobat) file handling -# -# History: -# 1996-07-16 fl Created -# 1997-01-18 fl Fixed header -# 2004-02-21 fl Fixes for 1/L/CMYK images, etc. -# 2004-02-24 fl Fixes for 1 and P images. -# -# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved. -# Copyright (c) 1996-1997 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -## -# Image plugin for PDF images (output only). -## - -__version__ = "0.4" - -import Image, ImageFile -import StringIO - - -# -# -------------------------------------------------------------------- - -# object ids: -# 1. catalogue -# 2. pages -# 3. image -# 4. page -# 5. page contents - -def _obj(fp, obj, **dict): - fp.write("%d 0 obj\n" % obj) - if dict: - fp.write("<<\n") - for k, v in dict.items(): - if v is not None: - fp.write("/%s %s\n" % (k, v)) - fp.write(">>\n") - -def _endobj(fp): - fp.write("endobj\n") - -## -# (Internal) Image save plugin for the PDF format. - -def _save(im, fp, filename): - resolution = im.encoderinfo.get("resolution", 72.0) - - # - # make sure image data is available - im.load() - - xref = [0]*(5+1) # placeholders - - fp.write("%PDF-1.2\n") - fp.write("% created by PIL PDF driver " + __version__ + "\n") - - # - # Get image characteristics - - width, height = im.size - - # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits) - # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports - # Flatedecode (zip compression). - - bits = 8 - params = None - - if im.mode == "1": - filter = "/ASCIIHexDecode" - colorspace = "/DeviceGray" - procset = "/ImageB" # grayscale - bits = 1 - elif im.mode == "L": - filter = "/DCTDecode" - # params = "<< /Predictor 15 /Columns %d >>" % (width-2) - colorspace = "/DeviceGray" - procset = "/ImageB" # grayscale - elif im.mode == "P": - filter = "/ASCIIHexDecode" - colorspace = "[ /Indexed /DeviceRGB 255 <" - palette = im.im.getpalette("RGB") - for i in range(256): - r = ord(palette[i*3]) - g = ord(palette[i*3+1]) - b = ord(palette[i*3+2]) - colorspace = colorspace + "%02x%02x%02x " % (r, g, b) - colorspace = colorspace + "> ]" - procset = "/ImageI" # indexed color - elif im.mode == "RGB": - filter = "/DCTDecode" - colorspace = "/DeviceRGB" - procset = "/ImageC" # color images - elif im.mode == "CMYK": - filter = "/DCTDecode" - colorspace = "/DeviceCMYK" - procset = "/ImageC" # color images - else: - raise ValueError("cannot save mode %s" % im.mode) - - # - # catalogue - - xref[1] = fp.tell() - _obj(fp, 1, Type = "/Catalog", - Pages = "2 0 R") - _endobj(fp) - - # - # pages - - xref[2] = fp.tell() - _obj(fp, 2, Type = "/Pages", - Count = 1, - Kids = "[4 0 R]") - _endobj(fp) - - # - # image - - op = StringIO.StringIO() - - if filter == "/ASCIIHexDecode": - if bits == 1: - # FIXME: the hex encoder doesn't support packed 1-bit - # images; do things the hard way... - data = im.tostring("raw", "1") - im = Image.new("L", (len(data), 1), None) - im.putdata(data) - ImageFile._save(im, op, [("hex", (0,0)+im.size, 0, im.mode)]) - elif filter == "/DCTDecode": - ImageFile._save(im, op, [("jpeg", (0,0)+im.size, 0, im.mode)]) - elif filter == "/FlateDecode": - ImageFile._save(im, op, [("zip", (0,0)+im.size, 0, im.mode)]) - elif filter == "/RunLengthDecode": - ImageFile._save(im, op, [("packbits", (0,0)+im.size, 0, im.mode)]) - else: - raise ValueError("unsupported PDF filter (%s)" % filter) - - xref[3] = fp.tell() - _obj(fp, 3, Type = "/XObject", - Subtype = "/Image", - Width = width, # * 72.0 / resolution, - Height = height, # * 72.0 / resolution, - Length = len(op.getvalue()), - Filter = filter, - BitsPerComponent = bits, - DecodeParams = params, - ColorSpace = colorspace) - - fp.write("stream\n") - fp.write(op.getvalue()) - fp.write("\nendstream\n") - - _endobj(fp) - - # - # page - - xref[4] = fp.tell() - _obj(fp, 4) - fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\ - "/Resources <<\n/ProcSet [ /PDF %s ]\n"\ - "/XObject << /image 3 0 R >>\n>>\n"\ - "/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\ - (procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution))) - _endobj(fp) - - # - # page contents - - op = StringIO.StringIO() - - op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution))) - - xref[5] = fp.tell() - _obj(fp, 5, Length = len(op.getvalue())) - - fp.write("stream\n") - fp.write(op.getvalue()) - fp.write("\nendstream\n") - - _endobj(fp) - - # - # trailer - startxref = fp.tell() - fp.write("xref\n0 %d\n0000000000 65535 f \n" % len(xref)) - for x in xref[1:]: - fp.write("%010d 00000 n \n" % x) - fp.write("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref)) - fp.write("startxref\n%d\n%%%%EOF\n" % startxref) - fp.flush() - -# -# -------------------------------------------------------------------- - -Image.register_save("PDF", _save) - -Image.register_extension("PDF", ".pdf") - -Image.register_mime("PDF", "application/pdf") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py deleted file mode 100755 index d4c597b6186..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PixarImagePlugin.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PIXAR raster support for PIL -# -# history: -# 97-01-29 fl Created -# -# notes: -# This is incomplete; it is based on a few samples created with -# Photoshop 2.5 and 3.0, and a summary description provided by -# Greg Coats . Hopefully, "L" and -# "RGBA" support will be added in future versions. -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.1" - -import Image, ImageFile - -# -# helpers - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - -## -# Image plugin for PIXAR raster images. - -class PixarImageFile(ImageFile.ImageFile): - - format = "PIXAR" - format_description = "PIXAR raster image" - - def _open(self): - - # assuming a 4-byte magic label (FIXME: add "_accept" hook) - s = self.fp.read(4) - if s != "\200\350\000\000": - raise SyntaxError, "not a PIXAR file" - - # read rest of header - s = s + self.fp.read(508) - - self.size = i16(s[418:420]), i16(s[416:418]) - - # get channel/depth descriptions - mode = i16(s[424:426]), i16(s[426:428]) - - if mode == (14, 2): - self.mode = "RGB" - # FIXME: to be continued... - - # create tile descriptor (assuming "dumped") - self.tile = [("raw", (0,0)+self.size, 1024, (self.mode, 0, 1))] - -# -# -------------------------------------------------------------------- - -Image.register_open("PIXAR", PixarImageFile) - -# -# FIXME: what's the standard extension? diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py deleted file mode 100755 index 0ee8589a536..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PngImagePlugin.py +++ /dev/null @@ -1,620 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PNG support code -# -# See "PNG (Portable Network Graphics) Specification, version 1.0; -# W3C Recommendation", 1996-10-01, Thomas Boutell (ed.). -# -# history: -# 1996-05-06 fl Created (couldn't resist it) -# 1996-12-14 fl Upgraded, added read and verify support (0.2) -# 1996-12-15 fl Separate PNG stream parser -# 1996-12-29 fl Added write support, added getchunks -# 1996-12-30 fl Eliminated circular references in decoder (0.3) -# 1998-07-12 fl Read/write 16-bit images as mode I (0.4) -# 2001-02-08 fl Added transparency support (from Zircon) (0.5) -# 2001-04-16 fl Don't close data source in "open" method (0.6) -# 2004-02-24 fl Don't even pretend to support interlaced files (0.7) -# 2004-08-31 fl Do basic sanity check on chunk identifiers (0.8) -# 2004-09-20 fl Added PngInfo chunk container -# 2004-12-18 fl Added DPI read support (based on code by Niki Spahiev) -# 2008-08-13 fl Added tRNS support for RGB images -# 2009-03-06 fl Support for preserving ICC profiles (by Florian Hoech) -# 2009-03-08 fl Added zTXT support (from Lowell Alleman) -# 2009-03-29 fl Read interlaced PNG files (from Conrado Porto Lopes Gouvua) -# -# Copyright (c) 1997-2009 by Secret Labs AB -# Copyright (c) 1996 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.9" - -import re, string - -import Image, ImageFile, ImagePalette, zlib - - -def i16(c): - return ord(c[1]) + (ord(c[0])<<8) -def i32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) - -is_cid = re.compile("\w\w\w\w").match - - -_MAGIC = "\211PNG\r\n\032\n" - - -_MODES = { - # supported bits/color combinations, and corresponding modes/rawmodes - (1, 0): ("1", "1"), - (2, 0): ("L", "L;2"), - (4, 0): ("L", "L;4"), - (8, 0): ("L", "L"), - (16,0): ("I", "I;16B"), - (8, 2): ("RGB", "RGB"), - (16,2): ("RGB", "RGB;16B"), - (1, 3): ("P", "P;1"), - (2, 3): ("P", "P;2"), - (4, 3): ("P", "P;4"), - (8, 3): ("P", "P"), - (8, 4): ("LA", "LA"), - (16,4): ("RGBA", "LA;16B"), # LA;16B->LA not yet available - (8, 6): ("RGBA", "RGBA"), - (16,6): ("RGBA", "RGBA;16B"), -} - - -# -------------------------------------------------------------------- -# Support classes. Suitable for PNG and related formats like MNG etc. - -class ChunkStream: - - def __init__(self, fp): - - self.fp = fp - self.queue = [] - - if not hasattr(Image.core, "crc32"): - self.crc = self.crc_skip - - def read(self): - "Fetch a new chunk. Returns header information." - - if self.queue: - cid, pos, len = self.queue[-1] - del self.queue[-1] - self.fp.seek(pos) - else: - s = self.fp.read(8) - cid = s[4:] - pos = self.fp.tell() - len = i32(s) - - if not is_cid(cid): - raise SyntaxError, "broken PNG file (chunk %s)" % repr(cid) - - return cid, pos, len - - def close(self): - self.queue = self.crc = self.fp = None - - def push(self, cid, pos, len): - - self.queue.append((cid, pos, len)) - - def call(self, cid, pos, len): - "Call the appropriate chunk handler" - - if Image.DEBUG: - print "STREAM", cid, pos, len - return getattr(self, "chunk_" + cid)(pos, len) - - def crc(self, cid, data): - "Read and verify checksum" - - crc1 = Image.core.crc32(data, Image.core.crc32(cid)) - crc2 = i16(self.fp.read(2)), i16(self.fp.read(2)) - if crc1 != crc2: - raise SyntaxError, "broken PNG file"\ - "(bad header checksum in %s)" % cid - - def crc_skip(self, cid, data): - "Read checksum. Used if the C module is not present" - - self.fp.read(4) - - def verify(self, endchunk = "IEND"): - - # Simple approach; just calculate checksum for all remaining - # blocks. Must be called directly after open. - - cids = [] - - while 1: - cid, pos, len = self.read() - if cid == endchunk: - break - self.crc(cid, ImageFile._safe_read(self.fp, len)) - cids.append(cid) - - return cids - - -# -------------------------------------------------------------------- -# PNG chunk container (for use with save(pnginfo=)) - -class PngInfo: - - def __init__(self): - self.chunks = [] - - def add(self, cid, data): - self.chunks.append((cid, data)) - - def add_text(self, key, value, zip=0): - if zip: - import zlib - self.add("zTXt", key + "\0\0" + zlib.compress(value)) - else: - self.add("tEXt", key + "\0" + value) - -# -------------------------------------------------------------------- -# PNG image stream (IHDR/IEND) - -class PngStream(ChunkStream): - - def __init__(self, fp): - - ChunkStream.__init__(self, fp) - - # local copies of Image attributes - self.im_info = {} - self.im_text = {} - self.im_size = (0,0) - self.im_mode = None - self.im_tile = None - self.im_palette = None - - def chunk_iCCP(self, pos, len): - - # ICC profile - s = ImageFile._safe_read(self.fp, len) - # according to PNG spec, the iCCP chunk contains: - # Profile name 1-79 bytes (character string) - # Null separator 1 byte (null character) - # Compression method 1 byte (0) - # Compressed profile n bytes (zlib with deflate compression) - i = string.find(s, chr(0)) - if Image.DEBUG: - print "iCCP profile name", s[:i] - print "Compression method", ord(s[i]) - comp_method = ord(s[i]) - if comp_method != 0: - raise SyntaxError("Unknown compression method %s in iCCP chunk" % comp_method) - try: - icc_profile = zlib.decompress(s[i+2:]) - except zlib.error: - icc_profile = None # FIXME - self.im_info["icc_profile"] = icc_profile - return s - - def chunk_IHDR(self, pos, len): - - # image header - s = ImageFile._safe_read(self.fp, len) - self.im_size = i32(s), i32(s[4:]) - try: - self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))] - except: - pass - if ord(s[12]): - self.im_info["interlace"] = 1 - if ord(s[11]): - raise SyntaxError, "unknown filter category" - return s - - def chunk_IDAT(self, pos, len): - - # image data - self.im_tile = [("zip", (0,0)+self.im_size, pos, self.im_rawmode)] - self.im_idat = len - raise EOFError - - def chunk_IEND(self, pos, len): - - # end of PNG image - raise EOFError - - def chunk_PLTE(self, pos, len): - - # palette - s = ImageFile._safe_read(self.fp, len) - if self.im_mode == "P": - self.im_palette = "RGB", s - return s - - def chunk_tRNS(self, pos, len): - - # transparency - s = ImageFile._safe_read(self.fp, len) - if self.im_mode == "P": - i = string.find(s, chr(0)) - if i >= 0: - self.im_info["transparency"] = i - elif self.im_mode == "L": - self.im_info["transparency"] = i16(s) - elif self.im_mode == "RGB": - self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:]) - return s - - def chunk_gAMA(self, pos, len): - - # gamma setting - s = ImageFile._safe_read(self.fp, len) - self.im_info["gamma"] = i32(s) / 100000.0 - return s - - def chunk_pHYs(self, pos, len): - - # pixels per unit - s = ImageFile._safe_read(self.fp, len) - px, py = i32(s), i32(s[4:]) - unit = ord(s[8]) - if unit == 1: # meter - dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5) - self.im_info["dpi"] = dpi - elif unit == 0: - self.im_info["aspect"] = px, py - return s - - def chunk_tEXt(self, pos, len): - - # text - s = ImageFile._safe_read(self.fp, len) - try: - k, v = string.split(s, "\0", 1) - except ValueError: - k = s; v = "" # fallback for broken tEXt tags - if k: - self.im_info[k] = self.im_text[k] = v - return s - - def chunk_zTXt(self, pos, len): - - # compressed text - s = ImageFile._safe_read(self.fp, len) - k, v = string.split(s, "\0", 1) - comp_method = ord(v[0]) - if comp_method != 0: - raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method) - import zlib - self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:]) - return s - -# -------------------------------------------------------------------- -# PNG reader - -def _accept(prefix): - return prefix[:8] == _MAGIC - -## -# Image plugin for PNG images. - -class PngImageFile(ImageFile.ImageFile): - - format = "PNG" - format_description = "Portable network graphics" - - def _open(self): - - if self.fp.read(8) != _MAGIC: - raise SyntaxError, "not a PNG file" - - # - # Parse headers up to the first IDAT chunk - - self.png = PngStream(self.fp) - - while 1: - - # - # get next chunk - - cid, pos, len = self.png.read() - - try: - s = self.png.call(cid, pos, len) - except EOFError: - break - except AttributeError: - if Image.DEBUG: - print cid, pos, len, "(unknown)" - s = ImageFile._safe_read(self.fp, len) - - self.png.crc(cid, s) - - # - # Copy relevant attributes from the PngStream. An alternative - # would be to let the PngStream class modify these attributes - # directly, but that introduces circular references which are - # difficult to break if things go wrong in the decoder... - # (believe me, I've tried ;-) - - self.mode = self.png.im_mode - self.size = self.png.im_size - self.info = self.png.im_info - self.text = self.png.im_text # experimental - self.tile = self.png.im_tile - - if self.png.im_palette: - rawmode, data = self.png.im_palette - self.palette = ImagePalette.raw(rawmode, data) - - self.__idat = len # used by load_read() - - - def verify(self): - "Verify PNG file" - - if self.fp is None: - raise RuntimeError("verify must be called directly after open") - - # back up to beginning of IDAT block - self.fp.seek(self.tile[0][2] - 8) - - self.png.verify() - self.png.close() - - self.fp = None - - def load_prepare(self): - "internal: prepare to read PNG file" - - if self.info.get("interlace"): - self.decoderconfig = self.decoderconfig + (1,) - - ImageFile.ImageFile.load_prepare(self) - - def load_read(self, bytes): - "internal: read more image data" - - while self.__idat == 0: - # end of chunk, skip forward to next one - - self.fp.read(4) # CRC - - cid, pos, len = self.png.read() - - if cid not in ["IDAT", "DDAT"]: - self.png.push(cid, pos, len) - return "" - - self.__idat = len # empty chunks are allowed - - # read more data from this chunk - if bytes <= 0: - bytes = self.__idat - else: - bytes = min(bytes, self.__idat) - - self.__idat = self.__idat - bytes - - return self.fp.read(bytes) - - - def load_end(self): - "internal: finished reading image data" - - self.png.close() - self.png = None - - -# -------------------------------------------------------------------- -# PNG writer - -def o16(i): - return chr(i>>8&255) + chr(i&255) - -def o32(i): - return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255) - -_OUTMODES = { - # supported PIL modes, and corresponding rawmodes/bits/color combinations - "1": ("1", chr(1)+chr(0)), - "L;1": ("L;1", chr(1)+chr(0)), - "L;2": ("L;2", chr(2)+chr(0)), - "L;4": ("L;4", chr(4)+chr(0)), - "L": ("L", chr(8)+chr(0)), - "LA": ("LA", chr(8)+chr(4)), - "I": ("I;16B", chr(16)+chr(0)), - "P;1": ("P;1", chr(1)+chr(3)), - "P;2": ("P;2", chr(2)+chr(3)), - "P;4": ("P;4", chr(4)+chr(3)), - "P": ("P", chr(8)+chr(3)), - "RGB": ("RGB", chr(8)+chr(2)), - "RGBA":("RGBA", chr(8)+chr(6)), -} - -def putchunk(fp, cid, *data): - "Write a PNG chunk (including CRC field)" - - data = string.join(data, "") - - fp.write(o32(len(data)) + cid) - fp.write(data) - hi, lo = Image.core.crc32(data, Image.core.crc32(cid)) - fp.write(o16(hi) + o16(lo)) - -class _idat: - # wrap output from the encoder in IDAT chunks - - def __init__(self, fp, chunk): - self.fp = fp - self.chunk = chunk - def write(self, data): - self.chunk(self.fp, "IDAT", data) - -def _save(im, fp, filename, chunk=putchunk, check=0): - # save an image to disk (called by the save method) - - mode = im.mode - - if mode == "P": - - # - # attempt to minimize storage requirements for palette images - - if im.encoderinfo.has_key("bits"): - - # number of bits specified by user - n = 1 << im.encoderinfo["bits"] - - else: - - # check palette contents - n = 256 # FIXME - - if n <= 2: - bits = 1 - elif n <= 4: - bits = 2 - elif n <= 16: - bits = 4 - else: - bits = 8 - - if bits != 8: - mode = "%s;%d" % (mode, bits) - - # encoder options - if im.encoderinfo.has_key("dictionary"): - dictionary = im.encoderinfo["dictionary"] - else: - dictionary = "" - - im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary) - - # get the corresponding PNG mode - try: - rawmode, mode = _OUTMODES[mode] - except KeyError: - raise IOError, "cannot write mode %s as PNG" % mode - - if check: - return check - - # - # write minimal PNG file - - fp.write(_MAGIC) - - chunk(fp, "IHDR", - o32(im.size[0]), o32(im.size[1]), # 0: size - mode, # 8: depth/type - chr(0), # 10: compression - chr(0), # 11: filter category - chr(0)) # 12: interlace flag - - if im.mode == "P": - chunk(fp, "PLTE", im.im.getpalette("RGB")) - - if im.encoderinfo.has_key("transparency"): - if im.mode == "P": - transparency = max(0, min(255, im.encoderinfo["transparency"])) - chunk(fp, "tRNS", chr(255) * transparency + chr(0)) - elif im.mode == "L": - transparency = max(0, min(65535, im.encoderinfo["transparency"])) - chunk(fp, "tRNS", o16(transparency)) - elif im.mode == "RGB": - red, green, blue = im.encoderinfo["transparency"] - chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue)) - else: - raise IOError("cannot use transparency for this mode") - - if 0: - # FIXME: to be supported some day - chunk(fp, "gAMA", o32(int(gamma * 100000.0))) - - dpi = im.encoderinfo.get("dpi") - if dpi: - chunk(fp, "pHYs", - o32(int(dpi[0] / 0.0254 + 0.5)), - o32(int(dpi[1] / 0.0254 + 0.5)), - chr(1)) - - info = im.encoderinfo.get("pnginfo") - if info: - for cid, data in info.chunks: - chunk(fp, cid, data) - - # ICC profile writing support -- 2008-06-06 Florian Hoech - if im.info.has_key("icc_profile"): - # ICC profile - # according to PNG spec, the iCCP chunk contains: - # Profile name 1-79 bytes (character string) - # Null separator 1 byte (null character) - # Compression method 1 byte (0) - # Compressed profile n bytes (zlib with deflate compression) - try: - import ICCProfile - p = ICCProfile.ICCProfile(im.info["icc_profile"]) - name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79] - except ImportError: - name = "ICC Profile" - data = name + "\0\0" + zlib.compress(im.info["icc_profile"]) - chunk(fp, "iCCP", data) - - ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)]) - - chunk(fp, "IEND", "") - - try: - fp.flush() - except: - pass - - -# -------------------------------------------------------------------- -# PNG chunk converter - -def getchunks(im, **params): - """Return a list of PNG chunks representing this image.""" - - class collector: - data = [] - def write(self, data): - pass - def append(self, chunk): - self.data.append(chunk) - - def append(fp, cid, *data): - data = string.join(data, "") - hi, lo = Image.core.crc32(data, Image.core.crc32(cid)) - crc = o16(hi) + o16(lo) - fp.append((cid, data, crc)) - - fp = collector() - - try: - im.encoderinfo = params - _save(im, fp, None, append) - finally: - del im.encoderinfo - - return fp.data - - -# -------------------------------------------------------------------- -# Registry - -Image.register_open("PNG", PngImageFile, _accept) -Image.register_save("PNG", _save) - -Image.register_extension("PNG", ".png") - -Image.register_mime("PNG", "image/png") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py deleted file mode 100755 index e86146c1050..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PpmImagePlugin.py +++ /dev/null @@ -1,131 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# PPM support for PIL -# -# History: -# 96-03-24 fl Created -# 98-03-06 fl Write RGBA images (as RGB, that is) -# -# Copyright (c) Secret Labs AB 1997-98. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.2" - -import string - -import Image, ImageFile - -# -# -------------------------------------------------------------------- - -MODES = { - # standard - "P4": "1", - "P5": "L", - "P6": "RGB", - # extensions - "P0CMYK": "CMYK", - # PIL extensions (for test purposes only) - "PyP": "P", - "PyRGBA": "RGBA", - "PyCMYK": "CMYK" -} - -def _accept(prefix): - return prefix[0] == "P" and prefix[1] in "0456y" - -## -# Image plugin for PBM, PGM, and PPM images. - -class PpmImageFile(ImageFile.ImageFile): - - format = "PPM" - format_description = "Pbmplus image" - - def _token(self, s = ""): - while 1: # read until next whitespace - c = self.fp.read(1) - if not c or c in string.whitespace: - break - s = s + c - return s - - def _open(self): - - # check magic - s = self.fp.read(1) - if s != "P": - raise SyntaxError, "not a PPM file" - mode = MODES[self._token(s)] - - if mode == "1": - self.mode = "1" - rawmode = "1;I" - else: - self.mode = rawmode = mode - - for ix in range(3): - while 1: - while 1: - s = self.fp.read(1) - if s not in string.whitespace: - break - if s != "#": - break - s = self.fp.readline() - s = int(self._token(s)) - if ix == 0: - xsize = s - elif ix == 1: - ysize = s - if mode == "1": - break - - self.size = xsize, ysize - self.tile = [("raw", - (0, 0, xsize, ysize), - self.fp.tell(), - (rawmode, 0, 1))] - - # ALTERNATIVE: load via builtin debug function - # self.im = Image.core.open_ppm(self.filename) - # self.mode = self.im.mode - # self.size = self.im.size - -# -# -------------------------------------------------------------------- - -def _save(im, fp, filename): - if im.mode == "1": - rawmode, head = "1;I", "P4" - elif im.mode == "L": - rawmode, head = "L", "P5" - elif im.mode == "RGB": - rawmode, head = "RGB", "P6" - elif im.mode == "RGBA": - rawmode, head = "RGB", "P6" - else: - raise IOError, "cannot write mode %s as PPM" % im.mode - fp.write(head + "\n%d %d\n" % im.size) - if head != "P4": - fp.write("255\n") - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))]) - - # ALTERNATIVE: save via builtin debug function - # im._dump(filename) - -# -# -------------------------------------------------------------------- - -Image.register_open("PPM", PpmImageFile, _accept) -Image.register_save("PPM", _save) - -Image.register_extension("PPM", ".pbm") -Image.register_extension("PPM", ".pgm") -Image.register_extension("PPM", ".ppm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py deleted file mode 100755 index 9d1b17a3632..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/PsdImagePlugin.py +++ /dev/null @@ -1,291 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# Adobe PSD 2.5/3.0 file handling -# -# History: -# 1995-09-01 fl Created -# 1997-01-03 fl Read most PSD images -# 1997-01-18 fl Fixed P and CMYK support -# 2001-10-21 fl Added seek/tell support (for layers) -# -# Copyright (c) 1997-2001 by Secret Labs AB. -# Copyright (c) 1995-2001 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.4" - -import Image, ImageFile, ImagePalette - -MODES = { - # (photoshop mode, bits) -> (pil mode, required channels) - (0, 1): ("1", 1), - (0, 8): ("L", 1), - (1, 8): ("L", 1), - (2, 8): ("P", 1), - (3, 8): ("RGB", 3), - (4, 8): ("CMYK", 4), - (7, 8): ("L", 1), # FIXME: multilayer - (8, 8): ("L", 1), # duotone - (9, 8): ("LAB", 3) -} - -# -# helpers - -def i16(c): - return ord(c[1]) + (ord(c[0])<<8) - -def i32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) - -# --------------------------------------------------------------------. -# read PSD images - -def _accept(prefix): - return prefix[:4] == "8BPS" - -## -# Image plugin for Photoshop images. - -class PsdImageFile(ImageFile.ImageFile): - - format = "PSD" - format_description = "Adobe Photoshop" - - def _open(self): - - read = self.fp.read - - # - # header - - s = read(26) - if s[:4] != "8BPS" or i16(s[4:]) != 1: - raise SyntaxError, "not a PSD file" - - psd_bits = i16(s[22:]) - psd_channels = i16(s[12:]) - psd_mode = i16(s[24:]) - - mode, channels = MODES[(psd_mode, psd_bits)] - - if channels > psd_channels: - raise IOError, "not enough channels" - - self.mode = mode - self.size = i32(s[18:]), i32(s[14:]) - - # - # color mode data - - size = i32(read(4)) - if size: - data = read(size) - if mode == "P" and size == 768: - self.palette = ImagePalette.raw("RGB;L", data) - - # - # image resources - - self.resources = [] - - size = i32(read(4)) - if size: - # load resources - end = self.fp.tell() + size - while self.fp.tell() < end: - signature = read(4) - id = i16(read(2)) - name = read(ord(read(1))) - if not (len(name) & 1): - read(1) # padding - data = read(i32(read(4))) - if (len(data) & 1): - read(1) # padding - self.resources.append((id, name, data)) - if id == 1039: # ICC profile - self.info["icc_profile"] = data - - # - # layer and mask information - - self.layers = [] - - size = i32(read(4)) - if size: - end = self.fp.tell() + size - size = i32(read(4)) - if size: - self.layers = _layerinfo(self.fp) - self.fp.seek(end) - - # - # image descriptor - - self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels) - - # keep the file open - self._fp = self.fp - self.frame = 0 - - def seek(self, layer): - # seek to given layer (1..max) - if layer == self.frame: - return - try: - if layer <= 0: - raise IndexError - name, mode, bbox, tile = self.layers[layer-1] - self.mode = mode - self.tile = tile - self.frame = layer - self.fp = self._fp - return name, bbox - except IndexError: - raise EOFError, "no such layer" - - def tell(self): - # return layer number (0=image, 1..max=layers) - return self.frame - - def load_prepare(self): - # create image memory if necessary - if not self.im or\ - self.im.mode != self.mode or self.im.size != self.size: - self.im = Image.core.fill(self.mode, self.size, 0) - # create palette (optional) - if self.mode == "P": - Image.Image.load(self) - -def _layerinfo(file): - # read layerinfo block - layers = [] - read = file.read - - for i in range(abs(i16(read(2)))): - - # bounding box - y0 = i32(read(4)); x0 = i32(read(4)) - y1 = i32(read(4)); x1 = i32(read(4)) - - # image info - info = [] - mode = [] - for i in range(i16(read(2))): - type = i16(read(2)) - if type == 65535: - m = "A" - else: - m = "RGB"[type] - mode.append(m) - size = i32(read(4)) - info.append((m, size)) - - # figure out the image mode - mode.sort() - if mode == ["R"]: - mode = "L" - elif mode == ["B", "G", "R"]: - mode = "RGB" - elif mode == ["A", "B", "G", "R"]: - mode = "RGBA" - else: - mode = None # unknown - - # skip over blend flags and extra information - filler = read(12) - name = "" - size = i32(read(4)) - combined = 0 - if size: - length = i32(read(4)) - if length: - mask_y = i32(read(4)); mask_x = i32(read(4)) - mask_h = i32(read(4)) - mask_y; mask_w = i32(read(4)) - mask_x - file.seek(length - 16, 1) - combined += length + 4 - - length = i32(read(4)) - if length: - file.seek(length, 1) - combined += length + 4 - - length = ord(read(1)) - if length: - name = read(length) - combined += length + 1 - - file.seek(size - combined, 1) - layers.append((name, mode, (x0, y0, x1, y1))) - - # get tiles - i = 0 - for name, mode, bbox in layers: - tile = [] - for m in mode: - t = _maketile(file, m, bbox, 1) - if t: - tile.extend(t) - layers[i] = name, mode, bbox, tile - i = i + 1 - - return layers - -def _maketile(file, mode, bbox, channels): - - tile = None - read = file.read - - compression = i16(read(2)) - - xsize = bbox[2] - bbox[0] - ysize = bbox[3] - bbox[1] - - offset = file.tell() - - if compression == 0: - # - # raw compression - tile = [] - for channel in range(channels): - layer = mode[channel] - if mode == "CMYK": - layer = layer + ";I" - tile.append(("raw", bbox, offset, layer)) - offset = offset + xsize*ysize - - elif compression == 1: - # - # packbits compression - i = 0 - tile = [] - bytecount = read(channels * ysize * 2) - offset = file.tell() - for channel in range(channels): - layer = mode[channel] - if mode == "CMYK": - layer = layer + ";I" - tile.append( - ("packbits", bbox, offset, layer) - ) - for y in range(ysize): - offset = offset + i16(bytecount[i:i+2]) - i = i + 2 - - file.seek(offset) - - if offset & 1: - read(1) # padding - - return tile - -# -------------------------------------------------------------------- -# registry - -Image.register_open("PSD", PsdImageFile, _accept) - -Image.register_extension("PSD", ".psd") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py deleted file mode 100755 index c65b91acaf2..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SgiImagePlugin.py +++ /dev/null @@ -1,92 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# SGI image file handling -# -# See "The SGI Image File Format (Draft version 0.97)", Paul Haeberli. -# -# -# History: -# 1995-09-10 fl Created -# -# Copyright (c) 2008 by Karsten Hiddemann. -# Copyright (c) 1997 by Secret Labs AB. -# Copyright (c) 1995 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.2" - - -import Image, ImageFile - - -def i16(c): - return ord(c[1]) + (ord(c[0])<<8) - -def i32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) - - -def _accept(prefix): - return i16(prefix) == 474 - -## -# Image plugin for SGI images. - -class SgiImageFile(ImageFile.ImageFile): - - format = "SGI" - format_description = "SGI Image File Format" - - def _open(self): - - # HEAD - s = self.fp.read(512) - if i16(s) != 474: - raise SyntaxError("not an SGI image file") - - # relevant header entries - compression = ord(s[2]) - - # bytes, dimension, zsize - layout = ord(s[3]), i16(s[4:]), i16(s[10:]) - - # determine mode from bytes/zsize - if layout == (1, 2, 1) or layout == (1, 1, 1): - self.mode = "L" - elif layout == (1, 3, 3): - self.mode = "RGB" - elif layout == (1, 3, 4): - self.mode = "RGBA" - else: - raise SyntaxError("unsupported SGI image mode") - - # size - self.size = i16(s[6:]), i16(s[8:]) - - - # decoder info - if compression == 0: - offset = 512 - pagesize = self.size[0]*self.size[1]*layout[0] - self.tile = [] - for layer in self.mode: - self.tile.append(("raw", (0,0)+self.size, offset, (layer,0,-1))) - offset = offset + pagesize - elif compression == 1: - self.tile = [("sgi_rle", (0,0)+self.size, 512, (self.mode, 0, -1))] - -# -# registry - -Image.register_open("SGI", SgiImageFile, _accept) - -Image.register_extension("SGI", ".bw") -Image.register_extension("SGI", ".rgb") -Image.register_extension("SGI", ".rgba") - -Image.register_extension("SGI", ".sgi") # really? diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py deleted file mode 100755 index e73d55918c8..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SpiderImagePlugin.py +++ /dev/null @@ -1,294 +0,0 @@ -# -# The Python Imaging Library. -# -# SPIDER image file handling -# -# History: -# 2004-08-02 Created BB -# 2006-03-02 added save method -# 2006-03-13 added support for stack images -# -# Copyright (c) 2004 by Health Research Inc. (HRI) RENSSELAER, NY 12144. -# Copyright (c) 2004 by William Baxter. -# Copyright (c) 2004 by Secret Labs AB. -# Copyright (c) 2004 by Fredrik Lundh. -# - -## -# Image plugin for the Spider image format. This format is is used -# by the SPIDER software, in processing image data from electron -# microscopy and tomography. -## - -# -# SpiderImagePlugin.py -# -# The Spider image format is used by SPIDER software, in processing -# image data from electron microscopy and tomography. -# -# Spider home page: -# http://www.wadsworth.org/spider_doc/spider/docs/spider.html -# -# Details about the Spider image format: -# http://www.wadsworth.org/spider_doc/spider/docs/image_doc.html -# - -import Image, ImageFile -import os, struct, sys - -def isInt(f): - try: - i = int(f) - if f-i == 0: return 1 - else: return 0 - except: - return 0 - -iforms = [1,3,-11,-12,-21,-22] - -# There is no magic number to identify Spider files, so just check a -# series of header locations to see if they have reasonable values. -# Returns no.of bytes in the header, if it is a valid Spider header, -# otherwise returns 0 - -def isSpiderHeader(t): - h = (99,) + t # add 1 value so can use spider header index start=1 - # header values 1,2,5,12,13,22,23 should be integers - for i in [1,2,5,12,13,22,23]: - if not isInt(h[i]): return 0 - # check iform - iform = int(h[5]) - if not iform in iforms: return 0 - # check other header values - labrec = int(h[13]) # no. records in file header - labbyt = int(h[22]) # total no. of bytes in header - lenbyt = int(h[23]) # record length in bytes - #print "labrec = %d, labbyt = %d, lenbyt = %d" % (labrec,labbyt,lenbyt) - if labbyt != (labrec * lenbyt): return 0 - # looks like a valid header - return labbyt - -def isSpiderImage(filename): - fp = open(filename,'rb') - f = fp.read(92) # read 23 * 4 bytes - fp.close() - bigendian = 1 - t = struct.unpack('>23f',f) # try big-endian first - hdrlen = isSpiderHeader(t) - if hdrlen == 0: - bigendian = 0 - t = struct.unpack('<23f',f) # little-endian - hdrlen = isSpiderHeader(t) - return hdrlen - - -class SpiderImageFile(ImageFile.ImageFile): - - format = "SPIDER" - format_description = "Spider 2D image" - - def _open(self): - # check header - n = 27 * 4 # read 27 float values - f = self.fp.read(n) - - try: - self.bigendian = 1 - t = struct.unpack('>27f',f) # try big-endian first - hdrlen = isSpiderHeader(t) - if hdrlen == 0: - self.bigendian = 0 - t = struct.unpack('<27f',f) # little-endian - hdrlen = isSpiderHeader(t) - if hdrlen == 0: - raise SyntaxError, "not a valid Spider file" - except struct.error: - raise SyntaxError, "not a valid Spider file" - - h = (99,) + t # add 1 value : spider header index starts at 1 - iform = int(h[5]) - if iform != 1: - raise SyntaxError, "not a Spider 2D image" - - self.size = int(h[12]), int(h[2]) # size in pixels (width, height) - self.istack = int(h[24]) - self.imgnumber = int(h[27]) - - if self.istack == 0 and self.imgnumber == 0: - # stk=0, img=0: a regular 2D image - offset = hdrlen - self.nimages = 1 - elif self.istack > 0 and self.imgnumber == 0: - # stk>0, img=0: Opening the stack for the first time - self.imgbytes = int(h[12]) * int(h[2]) * 4 - self.hdrlen = hdrlen - self.nimages = int(h[26]) - # Point to the first image in the stack - offset = hdrlen * 2 - self.imgnumber = 1 - elif self.istack == 0 and self.imgnumber > 0: - # stk=0, img>0: an image within the stack - offset = hdrlen + self.stkoffset - self.istack = 2 # So Image knows it's still a stack - else: - raise SyntaxError, "inconsistent stack header values" - - if self.bigendian: - self.rawmode = "F;32BF" - else: - self.rawmode = "F;32F" - self.mode = "F" - - self.tile = [("raw", (0, 0) + self.size, offset, - (self.rawmode, 0, 1))] - self.__fp = self.fp # FIXME: hack - - # 1st image index is zero (although SPIDER imgnumber starts at 1) - def tell(self): - if self.imgnumber < 1: - return 0 - else: - return self.imgnumber - 1 - - def seek(self, frame): - if self.istack == 0: - return - if frame >= self.nimages: - raise EOFError, "attempt to seek past end of file" - self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes) - self.fp = self.__fp - self.fp.seek(self.stkoffset) - self._open() - - # returns a byte image after rescaling to 0..255 - def convert2byte(self, depth=255): - (min, max) = self.getextrema() - m = 1 - if max != min: - m = depth / (max-min) - b = -m * min - return self.point(lambda i, m=m, b=b: i * m + b).convert("L") - - # returns a ImageTk.PhotoImage object, after rescaling to 0..255 - def tkPhotoImage(self): - import ImageTk - return ImageTk.PhotoImage(self.convert2byte(), palette=256) - -# -------------------------------------------------------------------- -# Image series - -# given a list of filenames, return a list of images -def loadImageSeries(filelist=None): - " create a list of Image.images for use in montage " - if filelist == None or len(filelist) < 1: - return - - imglist = [] - for img in filelist: - if not os.path.exists(img): - print "unable to find %s" % img - continue - try: - im = Image.open(img).convert2byte() - except: - if not isSpiderImage(img): - print img + " is not a Spider image file" - continue - im.info['filename'] = img - imglist.append(im) - return imglist - -# -------------------------------------------------------------------- -# For saving images in Spider format - -def makeSpiderHeader(im): - nsam,nrow = im.size - lenbyt = nsam * 4 # There are labrec records in the header - labrec = 1024 / lenbyt - if 1024%lenbyt != 0: labrec += 1 - labbyt = labrec * lenbyt - hdr = [] - nvalues = labbyt / 4 - for i in range(nvalues): - hdr.append(0.0) - - if len(hdr) < 23: - return [] - - # NB these are Fortran indices - hdr[1] = 1.0 # nslice (=1 for an image) - hdr[2] = float(nrow) # number of rows per slice - hdr[5] = 1.0 # iform for 2D image - hdr[12] = float(nsam) # number of pixels per line - hdr[13] = float(labrec) # number of records in file header - hdr[22] = float(labbyt) # total number of bytes in header - hdr[23] = float(lenbyt) # record length in bytes - - # adjust for Fortran indexing - hdr = hdr[1:] - hdr.append(0.0) - # pack binary data into a string - hdrstr = [] - for v in hdr: - hdrstr.append(struct.pack('f',v)) - return hdrstr - -def _save(im, fp, filename): - if im.mode[0] != "F": - im = im.convert('F') - - hdr = makeSpiderHeader(im) - if len(hdr) < 256: - raise IOError, "Error creating Spider header" - - # write the SPIDER header - try: - fp = open(filename, 'wb') - except: - raise IOError, "Unable to open %s for writing" % filename - fp.writelines(hdr) - - rawmode = "F;32NF" #32-bit native floating point - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode,0,1))]) - - fp.close() - -def _save_spider(im, fp, filename): - # get the filename extension and register it with Image - fn, ext = os.path.splitext(filename) - Image.register_extension("SPIDER", ext) - _save(im, fp, filename) - -# -------------------------------------------------------------------- - -Image.register_open("SPIDER", SpiderImageFile) -Image.register_save("SPIDER", _save_spider) - -if __name__ == "__main__": - - if not sys.argv[1:]: - print "Syntax: python SpiderImagePlugin.py Spiderimage [outfile]" - sys.exit() - - filename = sys.argv[1] - if not isSpiderImage(filename): - print "input image must be in Spider format" - sys.exit() - - outfile = "" - if len(sys.argv[1:]) > 1: - outfile = sys.argv[2] - - im = Image.open(filename) - print "image: " + str(im) - print "format: " + str(im.format) - print "size: " + str(im.size) - print "mode: " + str(im.mode) - print "max, min: ", - print im.getextrema() - - if outfile != "": - # perform some image operation - im = im.transpose(Image.FLIP_LEFT_RIGHT) - print "saving a flipped version of %s as %s " % (os.path.basename(filename), outfile) - im.save(outfile, "SPIDER") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py deleted file mode 100755 index d189562a483..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/SunImagePlugin.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# Sun image file handling -# -# History: -# 1995-09-10 fl Created -# 1996-05-28 fl Fixed 32-bit alignment -# 1998-12-29 fl Import ImagePalette module -# 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault) -# -# Copyright (c) 1997-2001 by Secret Labs AB -# Copyright (c) 1995-1996 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.3" - - -import Image, ImageFile, ImagePalette - - -def i16(c): - return ord(c[1]) + (ord(c[0])<<8) - -def i32(c): - return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24) - - -def _accept(prefix): - return i32(prefix) == 0x59a66a95 - -## -# Image plugin for Sun raster files. - -class SunImageFile(ImageFile.ImageFile): - - format = "SUN" - format_description = "Sun Raster File" - - def _open(self): - - # HEAD - s = self.fp.read(32) - if i32(s) != 0x59a66a95: - raise SyntaxError, "not an SUN raster file" - - offset = 32 - - self.size = i32(s[4:8]), i32(s[8:12]) - - depth = i32(s[12:16]) - if depth == 1: - self.mode, rawmode = "1", "1;I" - elif depth == 8: - self.mode = rawmode = "L" - elif depth == 24: - self.mode, rawmode = "RGB", "BGR" - else: - raise SyntaxError, "unsupported mode" - - compression = i32(s[20:24]) - - if i32(s[24:28]) != 0: - length = i32(s[28:32]) - offset = offset + length - self.palette = ImagePalette.raw("RGB;L", self.fp.read(length)) - if self.mode == "L": - self.mode = rawmode = "P" - - stride = (((self.size[0] * depth + 7) / 8) + 3) & (~3) - - if compression == 1: - self.tile = [("raw", (0,0)+self.size, offset, (rawmode, stride))] - elif compression == 2: - self.tile = [("sun_rle", (0,0)+self.size, offset, rawmode)] - -# -# registry - -Image.register_open("SUN", SunImageFile, _accept) - -Image.register_extension("SUN", ".ras") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py deleted file mode 100755 index d5de729cd36..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TarIO.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# read files from within a tar file -# -# History: -# 95-06-18 fl Created -# 96-05-28 fl Open files in binary mode -# -# Copyright (c) Secret Labs AB 1997. -# Copyright (c) Fredrik Lundh 1995-96. -# -# See the README file for information on usage and redistribution. -# - -import ContainerIO -import string - -## -# A file object that provides read access to a given member of a TAR -# file. - -class TarIO(ContainerIO.ContainerIO): - - ## - # Create file object. - # - # @param tarfile Name of TAR file. - # @param file Name of member file. - - def __init__(self, tarfile, file): - - fh = open(tarfile, "rb") - - while 1: - - s = fh.read(512) - if len(s) != 512: - raise IOError, "unexpected end of tar file" - - name = s[:100] - i = string.find(name, chr(0)) - if i == 0: - raise IOError, "cannot find subfile" - if i > 0: - name = name[:i] - - size = string.atoi(s[124:136], 8) - - if file == name: - break - - fh.seek((size + 511) & (~511), 1) - - # Open region - ContainerIO.ContainerIO.__init__(self, fh, fh.tell(), size) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py deleted file mode 100755 index 3375991ca9e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TgaImagePlugin.py +++ /dev/null @@ -1,201 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# TGA file handling -# -# History: -# 95-09-01 fl created (reads 24-bit files only) -# 97-01-04 fl support more TGA versions, including compressed images -# 98-07-04 fl fixed orientation and alpha layer bugs -# 98-09-11 fl fixed orientation for runlength decoder -# -# Copyright (c) Secret Labs AB 1997-98. -# Copyright (c) Fredrik Lundh 1995-97. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.3" - -import Image, ImageFile, ImagePalette - - -# -# -------------------------------------------------------------------- -# Read RGA file - -def i16(c): - return ord(c[0]) + (ord(c[1])<<8) - -def i32(c): - return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24) - - -MODES = { - # map imagetype/depth to rawmode - (1, 8): "P", - (3, 1): "1", - (3, 8): "L", - (2, 16): "BGR;5", - (2, 24): "BGR", - (2, 32): "BGRA", -} - - -def _accept(prefix): - return prefix[0] == "\0" - -## -# Image plugin for Targa files. - -class TgaImageFile(ImageFile.ImageFile): - - format = "TGA" - format_description = "Targa" - - def _open(self): - - # process header - s = self.fp.read(18) - - id = ord(s[0]) - - colormaptype = ord(s[1]) - imagetype = ord(s[2]) - - depth = ord(s[16]) - - flags = ord(s[17]) - - self.size = i16(s[12:]), i16(s[14:]) - - # validate header fields - if id != 0 or colormaptype not in (0, 1) or\ - self.size[0] <= 0 or self.size[1] <= 0 or\ - depth not in (1, 8, 16, 24, 32): - raise SyntaxError, "not a TGA file" - - # image mode - if imagetype in (3, 11): - self.mode = "L" - if depth == 1: - self.mode = "1" # ??? - elif imagetype in (1, 9): - self.mode = "P" - elif imagetype in (2, 10): - self.mode = "RGB" - if depth == 32: - self.mode = "RGBA" - else: - raise SyntaxError, "unknown TGA mode" - - # orientation - orientation = flags & 0x30 - if orientation == 0x20: - orientation = 1 - elif not orientation: - orientation = -1 - else: - raise SyntaxError, "unknown TGA orientation" - - self.info["orientation"] = orientation - - if imagetype & 8: - self.info["compression"] = "tga_rle" - - if colormaptype: - # read palette - start, size, mapdepth = i16(s[3:]), i16(s[5:]), i16(s[7:]) - if mapdepth == 16: - self.palette = ImagePalette.raw("BGR;16", - "\0"*2*start + self.fp.read(2*size)) - elif mapdepth == 24: - self.palette = ImagePalette.raw("BGR", - "\0"*3*start + self.fp.read(3*size)) - elif mapdepth == 32: - self.palette = ImagePalette.raw("BGRA", - "\0"*4*start + self.fp.read(4*size)) - - # setup tile descriptor - try: - rawmode = MODES[(imagetype&7, depth)] - if imagetype & 8: - # compressed - self.tile = [("tga_rle", (0, 0)+self.size, - self.fp.tell(), (rawmode, orientation, depth))] - else: - self.tile = [("raw", (0, 0)+self.size, - self.fp.tell(), (rawmode, 0, orientation))] - except KeyError: - pass # cannot decode - -# -# -------------------------------------------------------------------- -# Write TGA file - -def o16(i): - return chr(i&255) + chr(i>>8&255) - -def o32(i): - return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) - -SAVE = { - "1": ("1", 1, 0, 3), - "L": ("L", 8, 0, 3), - "P": ("P", 8, 1, 1), - "RGB": ("BGR", 24, 0, 2), - "RGBA": ("BGRA", 32, 0, 2), -} - -def _save(im, fp, filename, check=0): - - try: - rawmode, bits, colormaptype, imagetype = SAVE[im.mode] - except KeyError: - raise IOError("cannot write mode %s as TGA" % im.mode) - - if check: - return check - - if colormaptype: - colormapfirst, colormaplength, colormapentry = 0, 256, 24 - else: - colormapfirst, colormaplength, colormapentry = 0, 0, 0 - - if im.mode == "RGBA": - flags = 8 - else: - flags = 0 - - orientation = im.info.get("orientation", -1) - if orientation > 0: - flags = flags | 0x20 - - fp.write("\000" + - chr(colormaptype) + - chr(imagetype) + - o16(colormapfirst) + - o16(colormaplength) + - chr(colormapentry) + - o16(0) + - o16(0) + - o16(im.size[0]) + - o16(im.size[1]) + - chr(bits) + - chr(flags)) - - if colormaptype: - fp.write(im.im.getpalette("RGB", "BGR")) - - ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, orientation))]) - -# -# -------------------------------------------------------------------- -# Registry - -Image.register_open("TGA", TgaImageFile, _accept) -Image.register_save("TGA", _save) - -Image.register_extension("TGA", ".tga") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py deleted file mode 100755 index 8a0fde9cd86..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffImagePlugin.py +++ /dev/null @@ -1,860 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# TIFF file handling -# -# TIFF is a flexible, if somewhat aged, image file format originally -# defined by Aldus. Although TIFF supports a wide variety of pixel -# layouts and compression methods, the name doesn't really stand for -# "thousands of incompatible file formats," it just feels that way. -# -# To read TIFF data from a stream, the stream must be seekable. For -# progressive decoding, make sure to use TIFF files where the tag -# directory is placed first in the file. -# -# History: -# 1995-09-01 fl Created -# 1996-05-04 fl Handle JPEGTABLES tag -# 1996-05-18 fl Fixed COLORMAP support -# 1997-01-05 fl Fixed PREDICTOR support -# 1997-08-27 fl Added support for rational tags (from Perry Stoll) -# 1998-01-10 fl Fixed seek/tell (from Jan Blom) -# 1998-07-15 fl Use private names for internal variables -# 1999-06-13 fl Rewritten for PIL 1.0 (1.0) -# 2000-10-11 fl Additional fixes for Python 2.0 (1.1) -# 2001-04-17 fl Fixed rewind support (seek to frame 0) (1.2) -# 2001-05-12 fl Added write support for more tags (from Greg Couch) (1.3) -# 2001-12-18 fl Added workaround for broken Matrox library -# 2002-01-18 fl Don't mess up if photometric tag is missing (D. Alan Stewart) -# 2003-05-19 fl Check FILLORDER tag -# 2003-09-26 fl Added RGBa support -# 2004-02-24 fl Added DPI support; fixed rational write support -# 2005-02-07 fl Added workaround for broken Corel Draw 10 files -# 2006-01-09 fl Added support for float/double tags (from Russell Nelson) -# -# Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved. -# Copyright (c) 1995-1997 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -__version__ = "1.3.5" - -import Image, ImageFile -import ImagePalette - -import array, string, sys - -II = "II" # little-endian (intel-style) -MM = "MM" # big-endian (motorola-style) - -try: - if sys.byteorder == "little": - native_prefix = II - else: - native_prefix = MM -except AttributeError: - if ord(array.array("i",[1]).tostring()[0]): - native_prefix = II - else: - native_prefix = MM - -# -# -------------------------------------------------------------------- -# Read TIFF files - -def il16(c,o=0): - return ord(c[o]) + (ord(c[o+1])<<8) -def il32(c,o=0): - return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24) -def ol16(i): - return chr(i&255) + chr(i>>8&255) -def ol32(i): - return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255) - -def ib16(c,o=0): - return ord(c[o+1]) + (ord(c[o])<<8) -def ib32(c,o=0): - return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24) -def ob16(i): - return chr(i>>8&255) + chr(i&255) -def ob32(i): - return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255) - -# a few tag names, just to make the code below a bit more readable -IMAGEWIDTH = 256 -IMAGELENGTH = 257 -BITSPERSAMPLE = 258 -COMPRESSION = 259 -PHOTOMETRIC_INTERPRETATION = 262 -FILLORDER = 266 -IMAGEDESCRIPTION = 270 -STRIPOFFSETS = 273 -SAMPLESPERPIXEL = 277 -ROWSPERSTRIP = 278 -STRIPBYTECOUNTS = 279 -X_RESOLUTION = 282 -Y_RESOLUTION = 283 -PLANAR_CONFIGURATION = 284 -RESOLUTION_UNIT = 296 -SOFTWARE = 305 -DATE_TIME = 306 -ARTIST = 315 -PREDICTOR = 317 -COLORMAP = 320 -TILEOFFSETS = 324 -EXTRASAMPLES = 338 -SAMPLEFORMAT = 339 -JPEGTABLES = 347 -COPYRIGHT = 33432 -IPTC_NAA_CHUNK = 33723 # newsphoto properties -PHOTOSHOP_CHUNK = 34377 # photoshop properties -ICCPROFILE = 34675 -EXIFIFD = 34665 -XMP = 700 - -COMPRESSION_INFO = { - # Compression => pil compression name - 1: "raw", - 2: "tiff_ccitt", - 3: "group3", - 4: "group4", - 5: "tiff_lzw", - 6: "tiff_jpeg", # obsolete - 7: "jpeg", - 32771: "tiff_raw_16", # 16-bit padding - 32773: "packbits" -} - -OPEN_INFO = { - # (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample, - # ExtraSamples) => mode, rawmode - (II, 0, 1, 1, (1,), ()): ("1", "1;I"), - (II, 0, 1, 2, (1,), ()): ("1", "1;IR"), - (II, 0, 1, 1, (8,), ()): ("L", "L;I"), - (II, 0, 1, 2, (8,), ()): ("L", "L;IR"), - (II, 1, 1, 1, (1,), ()): ("1", "1"), - (II, 1, 1, 2, (1,), ()): ("1", "1;R"), - (II, 1, 1, 1, (8,), ()): ("L", "L"), - (II, 1, 1, 1, (8,8), (2,)): ("LA", "LA"), - (II, 1, 1, 2, (8,), ()): ("L", "L;R"), - (II, 1, 1, 1, (16,), ()): ("I;16", "I;16"), - (II, 1, 2, 1, (16,), ()): ("I;16S", "I;16S"), - (II, 1, 2, 1, (32,), ()): ("I", "I;32S"), - (II, 1, 3, 1, (32,), ()): ("F", "F;32F"), - (II, 2, 1, 1, (8,8,8), ()): ("RGB", "RGB"), - (II, 2, 1, 2, (8,8,8), ()): ("RGB", "RGB;R"), - (II, 2, 1, 1, (8,8,8,8), (0,)): ("RGBX", "RGBX"), - (II, 2, 1, 1, (8,8,8,8), (1,)): ("RGBA", "RGBa"), - (II, 2, 1, 1, (8,8,8,8), (2,)): ("RGBA", "RGBA"), - (II, 2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10 - (II, 3, 1, 1, (1,), ()): ("P", "P;1"), - (II, 3, 1, 2, (1,), ()): ("P", "P;1R"), - (II, 3, 1, 1, (2,), ()): ("P", "P;2"), - (II, 3, 1, 2, (2,), ()): ("P", "P;2R"), - (II, 3, 1, 1, (4,), ()): ("P", "P;4"), - (II, 3, 1, 2, (4,), ()): ("P", "P;4R"), - (II, 3, 1, 1, (8,), ()): ("P", "P"), - (II, 3, 1, 1, (8,8), (2,)): ("PA", "PA"), - (II, 3, 1, 2, (8,), ()): ("P", "P;R"), - (II, 5, 1, 1, (8,8,8,8), ()): ("CMYK", "CMYK"), - (II, 6, 1, 1, (8,8,8), ()): ("YCbCr", "YCbCr"), - (II, 8, 1, 1, (8,8,8), ()): ("LAB", "LAB"), - - (MM, 0, 1, 1, (1,), ()): ("1", "1;I"), - (MM, 0, 1, 2, (1,), ()): ("1", "1;IR"), - (MM, 0, 1, 1, (8,), ()): ("L", "L;I"), - (MM, 0, 1, 2, (8,), ()): ("L", "L;IR"), - (MM, 1, 1, 1, (1,), ()): ("1", "1"), - (MM, 1, 1, 2, (1,), ()): ("1", "1;R"), - (MM, 1, 1, 1, (8,), ()): ("L", "L"), - (MM, 1, 1, 1, (8,8), (2,)): ("LA", "LA"), - (MM, 1, 1, 2, (8,), ()): ("L", "L;R"), - (MM, 1, 1, 1, (16,), ()): ("I;16B", "I;16B"), - (MM, 1, 2, 1, (16,), ()): ("I;16BS", "I;16BS"), - (MM, 1, 2, 1, (32,), ()): ("I;32BS", "I;32BS"), - (MM, 1, 3, 1, (32,), ()): ("F;32BF", "F;32BF"), - (MM, 2, 1, 1, (8,8,8), ()): ("RGB", "RGB"), - (MM, 2, 1, 2, (8,8,8), ()): ("RGB", "RGB;R"), - (MM, 2, 1, 1, (8,8,8,8), (0,)): ("RGBX", "RGBX"), - (MM, 2, 1, 1, (8,8,8,8), (1,)): ("RGBA", "RGBa"), - (MM, 2, 1, 1, (8,8,8,8), (2,)): ("RGBA", "RGBA"), - (MM, 2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10 - (MM, 3, 1, 1, (1,), ()): ("P", "P;1"), - (MM, 3, 1, 2, (1,), ()): ("P", "P;1R"), - (MM, 3, 1, 1, (2,), ()): ("P", "P;2"), - (MM, 3, 1, 2, (2,), ()): ("P", "P;2R"), - (MM, 3, 1, 1, (4,), ()): ("P", "P;4"), - (MM, 3, 1, 2, (4,), ()): ("P", "P;4R"), - (MM, 3, 1, 1, (8,), ()): ("P", "P"), - (MM, 3, 1, 1, (8,8), (2,)): ("PA", "PA"), - (MM, 3, 1, 2, (8,), ()): ("P", "P;R"), - (MM, 5, 1, 1, (8,8,8,8), ()): ("CMYK", "CMYK"), - (MM, 6, 1, 1, (8,8,8), ()): ("YCbCr", "YCbCr"), - (MM, 8, 1, 1, (8,8,8), ()): ("LAB", "LAB"), - -} - -PREFIXES = ["MM\000\052", "II\052\000", "II\xBC\000"] - -def _accept(prefix): - return prefix[:4] in PREFIXES - -## -# Wrapper for TIFF IFDs. - -class ImageFileDirectory: - - # represents a TIFF tag directory. to speed things up, - # we don't decode tags unless they're asked for. - - def __init__(self, prefix): - self.prefix = prefix[:2] - if self.prefix == MM: - self.i16, self.i32 = ib16, ib32 - self.o16, self.o32 = ob16, ob32 - elif self.prefix == II: - self.i16, self.i32 = il16, il32 - self.o16, self.o32 = ol16, ol32 - else: - raise SyntaxError("not a TIFF IFD") - self.reset() - - def reset(self): - self.tags = {} - self.tagdata = {} - self.tagtype = {} # added 2008-06-05 by Florian Hoech - self.next = None - - # dictionary API (sort of) - - def keys(self): - return self.tagdata.keys() + self.tags.keys() - - def items(self): - items = self.tags.items() - for tag in self.tagdata.keys(): - items.append((tag, self[tag])) - return items - - def __len__(self): - return len(self.tagdata) + len(self.tags) - - def __getitem__(self, tag): - try: - return self.tags[tag] - except KeyError: - type, data = self.tagdata[tag] # unpack on the fly - size, handler = self.load_dispatch[type] - self.tags[tag] = data = handler(self, data) - del self.tagdata[tag] - return data - - def get(self, tag, default=None): - try: - return self[tag] - except KeyError: - return default - - def getscalar(self, tag, default=None): - try: - value = self[tag] - if len(value) != 1: - if tag == SAMPLEFORMAT: - # work around broken (?) matrox library - # (from Ted Wright, via Bob Klimek) - raise KeyError # use default - raise ValueError, "not a scalar" - return value[0] - except KeyError: - if default is None: - raise - return default - - def has_key(self, tag): - return self.tags.has_key(tag) or self.tagdata.has_key(tag) - - def __setitem__(self, tag, value): - if type(value) is not type(()): - value = (value,) - self.tags[tag] = value - - # load primitives - - load_dispatch = {} - - def load_byte(self, data): - l = [] - for i in range(len(data)): - l.append(ord(data[i])) - return tuple(l) - load_dispatch[1] = (1, load_byte) - - def load_string(self, data): - if data[-1:] == '\0': - data = data[:-1] - return data - load_dispatch[2] = (1, load_string) - - def load_short(self, data): - l = [] - for i in range(0, len(data), 2): - l.append(self.i16(data, i)) - return tuple(l) - load_dispatch[3] = (2, load_short) - - def load_long(self, data): - l = [] - for i in range(0, len(data), 4): - l.append(self.i32(data, i)) - return tuple(l) - load_dispatch[4] = (4, load_long) - - def load_rational(self, data): - l = [] - for i in range(0, len(data), 8): - l.append((self.i32(data, i), self.i32(data, i+4))) - return tuple(l) - load_dispatch[5] = (8, load_rational) - - def load_float(self, data): - a = array.array("f", data) - if self.prefix != native_prefix: - a.byteswap() - return tuple(a) - load_dispatch[11] = (4, load_float) - - def load_double(self, data): - a = array.array("d", data) - if self.prefix != native_prefix: - a.byteswap() - return tuple(a) - load_dispatch[12] = (8, load_double) - - def load_undefined(self, data): - # Untyped data - return data - load_dispatch[7] = (1, load_undefined) - - def load(self, fp): - # load tag dictionary - - self.reset() - - i16 = self.i16 - i32 = self.i32 - - for i in range(i16(fp.read(2))): - - ifd = fp.read(12) - - tag, typ = i16(ifd), i16(ifd, 2) - - if Image.DEBUG: - import TiffTags - tagname = TiffTags.TAGS.get(tag, "unknown") - typname = TiffTags.TYPES.get(typ, "unknown") - print "tag: %s (%d)" % (tagname, tag), - print "- type: %s (%d)" % (typname, typ), - - try: - dispatch = self.load_dispatch[typ] - except KeyError: - if Image.DEBUG: - print "- unsupported type", typ - continue # ignore unsupported type - - size, handler = dispatch - - size = size * i32(ifd, 4) - - # Get and expand tag value - if size > 4: - here = fp.tell() - fp.seek(i32(ifd, 8)) - data = ImageFile._safe_read(fp, size) - fp.seek(here) - else: - data = ifd[8:8+size] - - if len(data) != size: - raise IOError, "not enough data" - - self.tagdata[tag] = typ, data - self.tagtype[tag] = typ - - if Image.DEBUG: - if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP): - print "- value: " % size - else: - print "- value:", self[tag] - - self.next = i32(fp.read(4)) - - # save primitives - - def save(self, fp): - - o16 = self.o16 - o32 = self.o32 - - fp.write(o16(len(self.tags))) - - # always write in ascending tag order - tags = self.tags.items() - tags.sort() - - directory = [] - append = directory.append - - offset = fp.tell() + len(self.tags) * 12 + 4 - - stripoffsets = None - - # pass 1: convert tags to binary format - for tag, value in tags: - - typ = None - - if self.tagtype.has_key(tag): - typ = self.tagtype[tag] - - if typ == 1: - # byte data - data = value = string.join(map(chr, value), "") - elif typ == 7: - # untyped data - data = value = string.join(value, "") - elif type(value[0]) is type(""): - # string data - typ = 2 - data = value = string.join(value, "\0") + "\0" - else: - # integer data - if tag == STRIPOFFSETS: - stripoffsets = len(directory) - typ = 4 # to avoid catch-22 - elif tag in (X_RESOLUTION, Y_RESOLUTION): - # identify rational data fields - typ = 5 - elif not typ: - typ = 3 - for v in value: - if v >= 65536: - typ = 4 - if typ == 3: - data = string.join(map(o16, value), "") - else: - data = string.join(map(o32, value), "") - - if Image.DEBUG: - import TiffTags - tagname = TiffTags.TAGS.get(tag, "unknown") - typname = TiffTags.TYPES.get(typ, "unknown") - print "save: %s (%d)" % (tagname, tag), - print "- type: %s (%d)" % (typname, typ), - if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP): - size = len(data) - print "- value: " % size - else: - print "- value:", value - - # figure out if data fits into the directory - if len(data) == 4: - append((tag, typ, len(value), data, "")) - elif len(data) < 4: - append((tag, typ, len(value), data + (4-len(data))*"\0", "")) - else: - count = len(value) - if typ == 5: - count = count / 2 # adjust for rational data field - append((tag, typ, count, o32(offset), data)) - offset = offset + len(data) - if offset & 1: - offset = offset + 1 # word padding - - # update strip offset data to point beyond auxiliary data - if stripoffsets is not None: - tag, typ, count, value, data = directory[stripoffsets] - assert not data, "multistrip support not yet implemented" - value = o32(self.i32(value) + offset) - directory[stripoffsets] = tag, typ, count, value, data - - # pass 2: write directory to file - for tag, typ, count, value, data in directory: - if Image.DEBUG > 1: - print tag, typ, count, repr(value), repr(data) - fp.write(o16(tag) + o16(typ) + o32(count) + value) - - # -- overwrite here for multi-page -- - fp.write("\0\0\0\0") # end of directory - - # pass 3: write auxiliary data to file - for tag, typ, count, value, data in directory: - fp.write(data) - if len(data) & 1: - fp.write("\0") - - return offset - -## -# Image plugin for TIFF files. - -class TiffImageFile(ImageFile.ImageFile): - - format = "TIFF" - format_description = "Adobe TIFF" - - def _open(self): - "Open the first image in a TIFF file" - - # Header - ifh = self.fp.read(8) - - if ifh[:4] not in PREFIXES: - raise SyntaxError, "not a TIFF file" - - # image file directory (tag dictionary) - self.tag = self.ifd = ImageFileDirectory(ifh[:2]) - - # setup frame pointers - self.__first = self.__next = self.ifd.i32(ifh, 4) - self.__frame = -1 - self.__fp = self.fp - - # and load the first frame - self._seek(0) - - def seek(self, frame): - "Select a given frame as current image" - - if frame < 0: - frame = 0 - self._seek(frame) - - def tell(self): - "Return the current frame number" - - return self._tell() - - def _seek(self, frame): - - self.fp = self.__fp - if frame < self.__frame: - # rewind file - self.__frame = -1 - self.__next = self.__first - while self.__frame < frame: - if not self.__next: - raise EOFError, "no more images in TIFF file" - self.fp.seek(self.__next) - self.tag.load(self.fp) - self.__next = self.tag.next - self.__frame = self.__frame + 1 - self._setup() - - def _tell(self): - - return self.__frame - - def _decoder(self, rawmode, layer): - "Setup decoder contexts" - - args = None - if rawmode == "RGB" and self._planar_configuration == 2: - rawmode = rawmode[layer] - compression = self._compression - if compression == "raw": - args = (rawmode, 0, 1) - elif compression == "jpeg": - args = rawmode, "" - if self.tag.has_key(JPEGTABLES): - # Hack to handle abbreviated JPEG headers - self.tile_prefix = self.tag[JPEGTABLES] - elif compression == "packbits": - args = rawmode - elif compression == "tiff_lzw": - args = rawmode - if self.tag.has_key(317): - # Section 14: Differencing Predictor - self.decoderconfig = (self.tag[PREDICTOR][0],) - - if self.tag.has_key(ICCPROFILE): - self.info['icc_profile'] = self.tag[ICCPROFILE] - - return args - - def _setup(self): - "Setup this image object based on current tags" - - if self.tag.has_key(0xBC01): - raise IOError, "Windows Media Photo files not yet supported" - - getscalar = self.tag.getscalar - - # extract relevant tags - self._compression = COMPRESSION_INFO[getscalar(COMPRESSION, 1)] - self._planar_configuration = getscalar(PLANAR_CONFIGURATION, 1) - - # photometric is a required tag, but not everyone is reading - # the specification - photo = getscalar(PHOTOMETRIC_INTERPRETATION, 0) - - fillorder = getscalar(FILLORDER, 1) - - if Image.DEBUG: - print "*** Summary ***" - print "- compression:", self._compression - print "- photometric_interpretation:", photo - print "- planar_configuration:", self._planar_configuration - print "- fill_order:", fillorder - - # size - xsize = getscalar(IMAGEWIDTH) - ysize = getscalar(IMAGELENGTH) - self.size = xsize, ysize - - if Image.DEBUG: - print "- size:", self.size - - format = getscalar(SAMPLEFORMAT, 1) - - # mode: check photometric interpretation and bits per pixel - key = ( - self.tag.prefix, photo, format, fillorder, - self.tag.get(BITSPERSAMPLE, (1,)), - self.tag.get(EXTRASAMPLES, ()) - ) - if Image.DEBUG: - print "format key:", key - try: - self.mode, rawmode = OPEN_INFO[key] - except KeyError: - if Image.DEBUG: - print "- unsupported format" - raise SyntaxError, "unknown pixel mode" - - if Image.DEBUG: - print "- raw mode:", rawmode - print "- pil mode:", self.mode - - self.info["compression"] = self._compression - - xres = getscalar(X_RESOLUTION, (1, 1)) - yres = getscalar(Y_RESOLUTION, (1, 1)) - - if xres and yres: - xres = xres[0] / (xres[1] or 1) - yres = yres[0] / (yres[1] or 1) - resunit = getscalar(RESOLUTION_UNIT, 1) - if resunit == 2: # dots per inch - self.info["dpi"] = xres, yres - elif resunit == 3: # dots per centimeter. convert to dpi - self.info["dpi"] = xres * 2.54, yres * 2.54 - else: # No absolute unit of measurement - self.info["resolution"] = xres, yres - - # build tile descriptors - x = y = l = 0 - self.tile = [] - if self.tag.has_key(STRIPOFFSETS): - # striped image - h = getscalar(ROWSPERSTRIP, ysize) - w = self.size[0] - a = None - for o in self.tag[STRIPOFFSETS]: - if not a: - a = self._decoder(rawmode, l) - self.tile.append( - (self._compression, - (0, min(y, ysize), w, min(y+h, ysize)), - o, a)) - y = y + h - if y >= self.size[1]: - x = y = 0 - l = l + 1 - a = None - elif self.tag.has_key(TILEOFFSETS): - # tiled image - w = getscalar(322) - h = getscalar(323) - a = None - for o in self.tag[TILEOFFSETS]: - if not a: - a = self._decoder(rawmode, l) - # FIXME: this doesn't work if the image size - # is not a multiple of the tile size... - self.tile.append( - (self._compression, - (x, y, x+w, y+h), - o, a)) - x = x + w - if x >= self.size[0]: - x, y = 0, y + h - if y >= self.size[1]: - x = y = 0 - l = l + 1 - a = None - else: - if Image.DEBUG: - print "- unsupported data organization" - raise SyntaxError("unknown data organization") - - # fixup palette descriptor - - if self.mode == "P": - palette = map(lambda a: chr(a / 256), self.tag[COLORMAP]) - self.palette = ImagePalette.raw("RGB;L", string.join(palette, "")) -# -# -------------------------------------------------------------------- -# Write TIFF files - -# little endian is default except for image modes with explict big endian byte-order - -SAVE_INFO = { - # mode => rawmode, byteorder, photometrics, sampleformat, bitspersample, extra - "1": ("1", II, 1, 1, (1,), None), - "L": ("L", II, 1, 1, (8,), None), - "LA": ("LA", II, 1, 1, (8,8), 2), - "P": ("P", II, 3, 1, (8,), None), - "PA": ("PA", II, 3, 1, (8,8), 2), - "I": ("I;32S", II, 1, 2, (32,), None), - "I;16": ("I;16", II, 1, 1, (16,), None), - "I;16S": ("I;16S", II, 1, 2, (16,), None), - "F": ("F;32F", II, 1, 3, (32,), None), - "RGB": ("RGB", II, 2, 1, (8,8,8), None), - "RGBX": ("RGBX", II, 2, 1, (8,8,8,8), 0), - "RGBA": ("RGBA", II, 2, 1, (8,8,8,8), 2), - "CMYK": ("CMYK", II, 5, 1, (8,8,8,8), None), - "YCbCr": ("YCbCr", II, 6, 1, (8,8,8), None), - "LAB": ("LAB", II, 8, 1, (8,8,8), None), - - "I;32BS": ("I;32BS", MM, 1, 2, (32,), None), - "I;16B": ("I;16B", MM, 1, 1, (16,), None), - "I;16BS": ("I;16BS", MM, 1, 2, (16,), None), - "F;32BF": ("F;32BF", MM, 1, 3, (32,), None), -} - -def _cvt_res(value): - # convert value to TIFF rational number -- (numerator, denominator) - if type(value) in (type([]), type(())): - assert(len(value) % 2 == 0) - return value - if type(value) == type(1): - return (value, 1) - value = float(value) - return (int(value * 65536), 65536) - -def _save(im, fp, filename): - - try: - rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] - except KeyError: - raise IOError, "cannot write mode %s as TIFF" % im.mode - - ifd = ImageFileDirectory(prefix) - - # -- multi-page -- skip TIFF header on subsequent pages - if fp.tell() == 0: - # tiff header (write via IFD to get everything right) - # PIL always starts the first IFD at offset 8 - fp.write(ifd.prefix + ifd.o16(42) + ifd.o32(8)) - - ifd[IMAGEWIDTH] = im.size[0] - ifd[IMAGELENGTH] = im.size[1] - - # additions written by Greg Couch, gregc@cgl.ucsf.edu - # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com - if hasattr(im, 'tag'): - # preserve tags from original TIFF image file - for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION): - if im.tag.tagdata.has_key(key): - ifd[key] = im.tag.tagdata.get(key) - # preserve some more tags from original TIFF image file - # -- 2008-06-06 Florian Hoech - ifd.tagtype = im.tag.tagtype - for key in (IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, XMP): - if im.tag.has_key(key): - ifd[key] = im.tag[key] - # preserve ICC profile (should also work when saving other formats - # which support profiles as TIFF) -- 2008-06-06 Florian Hoech - if im.info.has_key("icc_profile"): - ifd[ICCPROFILE] = im.info["icc_profile"] - if im.encoderinfo.has_key("description"): - ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"] - if im.encoderinfo.has_key("resolution"): - ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \ - = _cvt_res(im.encoderinfo["resolution"]) - if im.encoderinfo.has_key("x resolution"): - ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"]) - if im.encoderinfo.has_key("y resolution"): - ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"]) - if im.encoderinfo.has_key("resolution unit"): - unit = im.encoderinfo["resolution unit"] - if unit == "inch": - ifd[RESOLUTION_UNIT] = 2 - elif unit == "cm" or unit == "centimeter": - ifd[RESOLUTION_UNIT] = 3 - else: - ifd[RESOLUTION_UNIT] = 1 - if im.encoderinfo.has_key("software"): - ifd[SOFTWARE] = im.encoderinfo["software"] - if im.encoderinfo.has_key("date time"): - ifd[DATE_TIME] = im.encoderinfo["date time"] - if im.encoderinfo.has_key("artist"): - ifd[ARTIST] = im.encoderinfo["artist"] - if im.encoderinfo.has_key("copyright"): - ifd[COPYRIGHT] = im.encoderinfo["copyright"] - - dpi = im.encoderinfo.get("dpi") - if dpi: - ifd[RESOLUTION_UNIT] = 2 - ifd[X_RESOLUTION] = _cvt_res(dpi[0]) - ifd[Y_RESOLUTION] = _cvt_res(dpi[1]) - - if bits != (1,): - ifd[BITSPERSAMPLE] = bits - if len(bits) != 1: - ifd[SAMPLESPERPIXEL] = len(bits) - if extra is not None: - ifd[EXTRASAMPLES] = extra - if format != 1: - ifd[SAMPLEFORMAT] = format - - ifd[PHOTOMETRIC_INTERPRETATION] = photo - - if im.mode == "P": - lut = im.im.getpalette("RGB", "RGB;L") - ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut)) - - # data orientation - stride = len(bits) * ((im.size[0]*bits[0]+7)/8) - ifd[ROWSPERSTRIP] = im.size[1] - ifd[STRIPBYTECOUNTS] = stride * im.size[1] - ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer - ifd[COMPRESSION] = 1 # no compression - - offset = ifd.save(fp) - - ImageFile._save(im, fp, [ - ("raw", (0,0)+im.size, offset, (rawmode, stride, 1)) - ]) - - - # -- helper for multi-page save -- - if im.encoderinfo.has_key("_debug_multipage"): - #just to access o32 and o16 (using correct byte order) - im._debug_multipage = ifd - -# -# -------------------------------------------------------------------- -# Register - -Image.register_open("TIFF", TiffImageFile, _accept) -Image.register_save("TIFF", _save) - -Image.register_extension("TIFF", ".tif") -Image.register_extension("TIFF", ".tiff") - -Image.register_mime("TIFF", "image/tiff") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py deleted file mode 100755 index 33fd209411c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/TiffTags.py +++ /dev/null @@ -1,209 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# TIFF tags -# -# This module provides clear-text names for various well-known -# TIFF tags. the TIFF codec works just fine without it. -# -# Copyright (c) Secret Labs AB 1999. -# -# See the README file for information on usage and redistribution. -# - -## -# This module provides constants and clear-text names for various -# well-known TIFF tags. -## - -## -# Map tag numbers (or tag number, tag value tuples) to tag names. - -TAGS = { - - 254: "NewSubfileType", - 255: "SubfileType", - 256: "ImageWidth", - 257: "ImageLength", - 258: "BitsPerSample", - - 259: "Compression", - (259, 1): "Uncompressed", - (259, 2): "CCITT 1d", - (259, 3): "Group 3 Fax", - (259, 4): "Group 4 Fax", - (259, 5): "LZW", - (259, 6): "JPEG", - (259, 32773): "PackBits", - - 262: "PhotometricInterpretation", - (262, 0): "WhiteIsZero", - (262, 1): "BlackIsZero", - (262, 2): "RGB", - (262, 3): "RGB Palette", - (262, 4): "Transparency Mask", - (262, 5): "CMYK", - (262, 6): "YCbCr", - (262, 8): "CieLAB", - (262, 32803): "CFA", # TIFF/EP, Adobe DNG - (262, 32892): "LinearRaw", # Adobe DNG - - 263: "Thresholding", - 264: "CellWidth", - 265: "CellHeight", - 266: "FillOrder", - 269: "DocumentName", - - 270: "ImageDescription", - 271: "Make", - 272: "Model", - 273: "StripOffsets", - 274: "Orientation", - 277: "SamplesPerPixel", - 278: "RowsPerStrip", - 279: "StripByteCounts", - - 280: "MinSampleValue", - 281: "MaxSampleValue", - 282: "XResolution", - 283: "YResolution", - 284: "PlanarConfiguration", - (284, 1): "Contigous", - (284, 2): "Separate", - - 285: "PageName", - 286: "XPosition", - 287: "YPosition", - 288: "FreeOffsets", - 289: "FreeByteCounts", - - 290: "GrayResponseUnit", - 291: "GrayResponseCurve", - 292: "T4Options", - 293: "T6Options", - 296: "ResolutionUnit", - 297: "PageNumber", - - 301: "TransferFunction", - 305: "Software", - 306: "DateTime", - - 315: "Artist", - 316: "HostComputer", - 317: "Predictor", - 318: "WhitePoint", - 319: "PrimaryChromaticies", - - 320: "ColorMap", - 321: "HalftoneHints", - 322: "TileWidth", - 323: "TileLength", - 324: "TileOffsets", - 325: "TileByteCounts", - - 332: "InkSet", - 333: "InkNames", - 334: "NumberOfInks", - 336: "DotRange", - 337: "TargetPrinter", - 338: "ExtraSamples", - 339: "SampleFormat", - - 340: "SMinSampleValue", - 341: "SMaxSampleValue", - 342: "TransferRange", - - 347: "JPEGTables", - - # obsolete JPEG tags - 512: "JPEGProc", - 513: "JPEGInterchangeFormat", - 514: "JPEGInterchangeFormatLength", - 515: "JPEGRestartInterval", - 517: "JPEGLosslessPredictors", - 518: "JPEGPointTransforms", - 519: "JPEGQTables", - 520: "JPEGDCTables", - 521: "JPEGACTables", - - 529: "YCbCrCoefficients", - 530: "YCbCrSubSampling", - 531: "YCbCrPositioning", - 532: "ReferenceBlackWhite", - - # XMP - 700: "XMP", - - 33432: "Copyright", - - # various extensions (should check specs for "official" names) - 33723: "IptcNaaInfo", - 34377: "PhotoshopInfo", - - # Exif IFD - 34665: "ExifIFD", - - # ICC Profile - 34675: "ICCProfile", - - # Adobe DNG - 50706: "DNGVersion", - 50707: "DNGBackwardVersion", - 50708: "UniqueCameraModel", - 50709: "LocalizedCameraModel", - 50710: "CFAPlaneColor", - 50711: "CFALayout", - 50712: "LinearizationTable", - 50713: "BlackLevelRepeatDim", - 50714: "BlackLevel", - 50715: "BlackLevelDeltaH", - 50716: "BlackLevelDeltaV", - 50717: "WhiteLevel", - 50718: "DefaultScale", - 50741: "BestQualityScale", - 50719: "DefaultCropOrigin", - 50720: "DefaultCropSize", - 50778: "CalibrationIlluminant1", - 50779: "CalibrationIlluminant2", - 50721: "ColorMatrix1", - 50722: "ColorMatrix2", - 50723: "CameraCalibration1", - 50724: "CameraCalibration2", - 50725: "ReductionMatrix1", - 50726: "ReductionMatrix2", - 50727: "AnalogBalance", - 50728: "AsShotNeutral", - 50729: "AsShotWhiteXY", - 50730: "BaselineExposure", - 50731: "BaselineNoise", - 50732: "BaselineSharpness", - 50733: "BayerGreenSplit", - 50734: "LinearResponseLimit", - 50735: "CameraSerialNumber", - 50736: "LensInfo", - 50737: "ChromaBlurRadius", - 50738: "AntiAliasStrength", - 50740: "DNGPrivateData", - 50741: "MakerNoteSafety", -} - -## -# Map type numbers to type names. - -TYPES = { - - 1: "byte", - 2: "ascii", - 3: "short", - 4: "long", - 5: "rational", - 6: "signed byte", - 7: "undefined", - 8: "signed short", - 9: "signed long", - 10: "signed rational", - 11: "float", - 12: "double", - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py deleted file mode 100755 index fb8c38ab4af..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WalImageFile.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# -# The Python Imaging Library. -# $Id$ -# -# WAL file handling -# -# History: -# 2003-04-23 fl created -# -# Copyright (c) 2003 by Fredrik Lundh. -# -# See the README file for information on usage and redistribution. -# - -# NOTE: This format cannot be automatically recognized, so the reader -# is not registered for use with Image.open(). To open a WEL file, use -# the WalImageFile.open() function instead. - -# This reader is based on the specification available from: -# http://www.flipcode.com/tutorials/tut_q2levels.shtml -# and has been tested with a few sample files found using google. - -import Image - -def i32(c, o=0): - return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24) - -## -# Load texture from a Quake2 WAL texture file. -#

-# By default, a Quake2 standard palette is attached to the texture. -# To override the palette, use the putpalette method. -# -# @param filename WAL file name, or an opened file handle. -# @return An image instance. - -def open(filename): - # FIXME: modify to return a WalImageFile instance instead of - # plain Image object ? - - if hasattr(filename, "read"): - fp = filename - else: - import __builtin__ - fp = __builtin__.open(filename, "rb") - - # read header fields - header = fp.read(32+24+32+12) - size = i32(header, 32), i32(header, 36) - offset = i32(header, 40) - - # load pixel data - fp.seek(offset) - - im = Image.fromstring("P", size, fp.read(size[0] * size[1])) - im.putpalette(quake2palette) - - im.format = "WAL" - im.format_description = "Quake2 Texture" - - # strings are null-terminated - im.info["name"] = header[:32].split("\0", 1)[0] - next_name = header[56:56+32].split("\0", 1)[0] - if next_name: - im.info["next_name"] = next_name - - return im - - -quake2palette = ( - # default palette taken from piffo 0.93 by Hans Hggstrm - "\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e" - "\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f" - "\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c" - "\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b" - "\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10" - "\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07" - "\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f" - "\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16" - "\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d" - "\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31" - "\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28" - "\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07" - "\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27" - "\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b" - "\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01" - "\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21" - "\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14" - "\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07" - "\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14" - "\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f" - "\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34" - "\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d" - "\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14" - "\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01" - "\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24" - "\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10" - "\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01" - "\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27" - "\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c" - "\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a" - "\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26" - "\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d" - "\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01" - "\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20" - "\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17" - "\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07" - "\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25" - "\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c" - "\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01" - "\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23" - "\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f" - "\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b" - "\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37" - "\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b" - "\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01" - "\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10" - "\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b" - "\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20" -) - -if __name__ == "__main__": - im = open("../hacks/sample.wal") - print im.info, im.mode, im.size - im.save("../out.png") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py deleted file mode 100755 index 5191f1e51d5..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/WmfImagePlugin.py +++ /dev/null @@ -1,167 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# WMF stub codec -# -# history: -# 1996-12-14 fl Created -# 2004-02-22 fl Turned into a stub driver -# 2004-02-23 fl Added EMF support -# -# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. -# Copyright (c) Fredrik Lundh 1996. -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.2" - -import Image, ImageFile - -_handler = None - -## -# Install application-specific WMF image handler. -# -# @param handler Handler object. - -def register_handler(handler): - global _handler - _handler = handler - -if hasattr(Image.core, "drawwmf"): - # install default handler (windows only) - - class WmfHandler: - - def open(self, im): - im.mode = "RGB" - self.bbox = im.info["wmf_bbox"] - - def load(self, im): - im.fp.seek(0) # rewind - return Image.fromstring( - "RGB", im.size, - Image.core.drawwmf(im.fp.read(), im.size, self.bbox), - "raw", "BGR", (im.size[0]*3 + 3) & -4, -1 - ) - - register_handler(WmfHandler()) - -# -------------------------------------------------------------------- - -def word(c, o=0): - return ord(c[o]) + (ord(c[o+1])<<8) - -def short(c, o=0): - v = ord(c[o]) + (ord(c[o+1])<<8) - if v >= 32768: - v = v - 65536 - return v - -def dword(c, o=0): - return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24) - -def long(c, o=0): - return dword(c, o) - -# -# -------------------------------------------------------------------- -# Read WMF file - -def _accept(prefix): - return ( - prefix[:6] == "\xd7\xcd\xc6\x9a\x00\x00" or - prefix[:4] == "\x01\x00\x00\x00" - ) - -## -# Image plugin for Windows metafiles. - -class WmfStubImageFile(ImageFile.StubImageFile): - - format = "WMF" - format_description = "Windows Metafile" - - def _open(self): - - # check placable header - s = self.fp.read(80) - - if s[:6] == "\xd7\xcd\xc6\x9a\x00\x00": - - # placeable windows metafile - - # get units per inch - inch = word(s, 14) - - # get bounding box - x0 = short(s, 6); y0 = short(s, 8) - x1 = short(s, 10); y1 = short(s, 12) - - # normalize size to 72 dots per inch - size = (x1 - x0) * 72 / inch, (y1 - y0) * 72 / inch - - self.info["wmf_bbox"] = x0, y0, x1, y1 - - self.info["dpi"] = 72 - - # print self.mode, self.size, self.info - - # sanity check (standard metafile header) - if s[22:26] != "\x01\x00\t\x00": - raise SyntaxError("Unsupported WMF file format") - - elif long(s) == 1 and s[40:44] == " EMF": - # enhanced metafile - - # get bounding box - x0 = long(s, 8); y0 = long(s, 12) - x1 = long(s, 16); y1 = long(s, 20) - - # get frame (in 0.01 millimeter units) - frame = long(s, 24), long(s, 28), long(s, 32), long(s, 36) - - # normalize size to 72 dots per inch - size = x1 - x0, y1 - y0 - - # calculate dots per inch from bbox and frame - xdpi = 2540 * (x1 - y0) / (frame[2] - frame[0]) - ydpi = 2540 * (y1 - y0) / (frame[3] - frame[1]) - - self.info["wmf_bbox"] = x0, y0, x1, y1 - - if xdpi == ydpi: - self.info["dpi"] = xdpi - else: - self.info["dpi"] = xdpi, ydpi - - else: - raise SyntaxError("Unsupported file format") - - self.mode = "RGB" - self.size = size - - loader = self._load() - if loader: - loader.open(self) - - def _load(self): - return _handler - - -def _save(im, fp, filename): - if _handler is None or not hasattr("_handler", "save"): - raise IOError("WMF save handler not installed") - _handler.save(im, fp, filename) - -# -# -------------------------------------------------------------------- -# Registry stuff - -Image.register_open(WmfStubImageFile.format, WmfStubImageFile, _accept) -Image.register_save(WmfStubImageFile.format, _save) - -Image.register_extension(WmfStubImageFile.format, ".wmf") -Image.register_extension(WmfStubImageFile.format, ".emf") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py deleted file mode 100755 index ab1fb5d7ac8..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XVThumbImagePlugin.py +++ /dev/null @@ -1,73 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# XV Thumbnail file handler by Charles E. "Gene" Cash -# (gcash@magicnet.net) -# -# see xvcolor.c and xvbrowse.c in the sources to John Bradley's XV, -# available from ftp://ftp.cis.upenn.edu/pub/xv/ -# -# history: -# 98-08-15 cec created (b/w only) -# 98-12-09 cec added color palette -# 98-12-28 fl added to PIL (with only a few very minor modifications) -# -# To do: -# FIXME: make save work (this requires quantization support) -# - -__version__ = "0.1" - -import string -import Image, ImageFile, ImagePalette - -# standard color palette for thumbnails (RGB332) -PALETTE = "" -for r in range(8): - for g in range(8): - for b in range(4): - PALETTE = PALETTE + (chr((r*255)/7)+chr((g*255)/7)+chr((b*255)/3)) - -## -# Image plugin for XV thumbnail images. - -class XVThumbImageFile(ImageFile.ImageFile): - - format = "XVThumb" - format_description = "XV thumbnail image" - - def _open(self): - - # check magic - s = self.fp.read(6) - if s != "P7 332": - raise SyntaxError, "not an XV thumbnail file" - - # Skip to beginning of next line - self.fp.readline() - - # skip info comments - while 1: - s = self.fp.readline() - if not s: - raise SyntaxError, "Unexpected EOF reading XV thumbnail file" - if s[0] != '#': - break - - # parse header line (already read) - s = string.split(s.strip()) - - self.mode = "P" - self.size = int(s[0]), int(s[1]) - - self.palette = ImagePalette.raw("RGB", PALETTE) - - self.tile = [ - ("raw", (0, 0)+self.size, - self.fp.tell(), (self.mode, 0, 1) - )] - -# -------------------------------------------------------------------- - -Image.register_open("XVThumb", XVThumbImageFile) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py deleted file mode 100755 index a8cf1026dce..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XbmImagePlugin.py +++ /dev/null @@ -1,94 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# XBM File handling -# -# History: -# 1995-09-08 fl Created -# 1996-11-01 fl Added save support -# 1997-07-07 fl Made header parser more tolerant -# 1997-07-22 fl Fixed yet another parser bug -# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) -# 2001-05-13 fl Added hotspot handling (based on code from Bernhard Herzog) -# 2004-02-24 fl Allow some whitespace before first #define -# -# Copyright (c) 1997-2004 by Secret Labs AB -# Copyright (c) 1996-1997 by Fredrik Lundh -# -# See the README file for information on usage and redistribution. -# - -__version__ = "0.6" - -import re, string -import Image, ImageFile - -# XBM header -xbm_head = re.compile( - "\s*#define[ \t]+[^_]*_width[ \t]+(?P[0-9]+)[\r\n]+" - "#define[ \t]+[^_]*_height[ \t]+(?P[0-9]+)[\r\n]+" - "(?P" - "#define[ \t]+[^_]*_x_hot[ \t]+(?P[0-9]+)[\r\n]+" - "#define[ \t]+[^_]*_y_hot[ \t]+(?P[0-9]+)[\r\n]+" - ")?" - "[\\000-\\377]*_bits\\[\\]" -) - -def _accept(prefix): - return string.lstrip(prefix)[:7] == "#define" - -## -# Image plugin for X11 bitmaps. - -class XbmImageFile(ImageFile.ImageFile): - - format = "XBM" - format_description = "X11 Bitmap" - - def _open(self): - - m = xbm_head.match(self.fp.read(512)) - - if m: - - xsize = int(m.group("width")) - ysize = int(m.group("height")) - - if m.group("hotspot"): - self.info["hotspot"] = ( - int(m.group("xhot")), int(m.group("yhot")) - ) - - self.mode = "1" - self.size = xsize, ysize - - self.tile = [("xbm", (0, 0)+self.size, m.end(), None)] - - -def _save(im, fp, filename): - - if im.mode != "1": - raise IOError, "cannot write mode %s as XBM" % im.mode - - fp.write("#define im_width %d\n" % im.size[0]) - fp.write("#define im_height %d\n" % im.size[1]) - - hotspot = im.encoderinfo.get("hotspot") - if hotspot: - fp.write("#define im_x_hot %d\n" % hotspot[0]) - fp.write("#define im_y_hot %d\n" % hotspot[1]) - - fp.write("static char im_bits[] = {\n") - - ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)]) - - fp.write("};\n") - - -Image.register_open("XBM", XbmImageFile, _accept) -Image.register_save("XBM", _save) - -Image.register_extension("XBM", ".xbm") - -Image.register_mime("XBM", "image/xbm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py deleted file mode 100755 index a3f40f02c4e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/XpmImagePlugin.py +++ /dev/null @@ -1,129 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# XPM File handling -# -# History: -# 1996-12-29 fl Created -# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) -# -# Copyright (c) Secret Labs AB 1997-2001. -# Copyright (c) Fredrik Lundh 1996-2001. -# -# See the README file for information on usage and redistribution. -# - - -__version__ = "0.2" - - -import re, string -import Image, ImageFile, ImagePalette - -# XPM header -xpm_head = re.compile("\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)") - - -def _accept(prefix): - return prefix[:9] == "/* XPM */" - -## -# Image plugin for X11 pixel maps. - -class XpmImageFile(ImageFile.ImageFile): - - format = "XPM" - format_description = "X11 Pixel Map" - - def _open(self): - - if not _accept(self.fp.read(9)): - raise SyntaxError, "not an XPM file" - - # skip forward to next string - while 1: - s = self.fp.readline() - if not s: - raise SyntaxError, "broken XPM file" - m = xpm_head.match(s) - if m: - break - - self.size = int(m.group(1)), int(m.group(2)) - - pal = int(m.group(3)) - bpp = int(m.group(4)) - - if pal > 256 or bpp != 1: - raise ValueError, "cannot read this XPM file" - - # - # load palette description - - palette = ["\0\0\0"] * 256 - - for i in range(pal): - - s = self.fp.readline() - if s[-2:] == '\r\n': - s = s[:-2] - elif s[-1:] in '\r\n': - s = s[:-1] - - c = ord(s[1]) - s = string.split(s[2:-2]) - - for i in range(0, len(s), 2): - - if s[i] == "c": - - # process colour key - rgb = s[i+1] - if rgb == "None": - self.info["transparency"] = c - elif rgb[0] == "#": - # FIXME: handle colour names (see ImagePalette.py) - rgb = string.atoi(rgb[1:], 16) - palette[c] = chr((rgb >> 16) & 255) +\ - chr((rgb >> 8) & 255) +\ - chr(rgb & 255) - else: - # unknown colour - raise ValueError, "cannot read this XPM file" - break - - else: - - # missing colour key - raise ValueError, "cannot read this XPM file" - - self.mode = "P" - self.palette = ImagePalette.raw("RGB", string.join(palette, "")) - - self.tile = [("raw", (0, 0)+self.size, self.fp.tell(), ("P", 0, 1))] - - def load_read(self, bytes): - - # - # load all image data in one chunk - - xsize, ysize = self.size - - s = [None] * ysize - - for i in range(ysize): - s[i] = string.ljust(self.fp.readline()[1:xsize+1], xsize) - - self.fp = None - - return string.join(s, "") - -# -# Registry - -Image.register_open("XPM", XpmImageFile, _accept) - -Image.register_extension("XPM", ".xpm") - -Image.register_mime("XPM", "image/xpm") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py deleted file mode 100755 index ed54d26f66e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# -# The Python Imaging Library. -# $Id$ -# -# package placeholder -# -# Copyright (c) 1999 by Secret Labs AB. -# -# See the README file for information on usage and redistribution. -# - -# ;-) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imaging.pyd b/tools/HitboxExpander/third_party/Imaging-1.1.7/PIL/_imaging.pyd deleted file mode 100755 index 22ee66c119717b931306da63a289e09754eeefd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193536 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 z%0A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 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/README b/tools/HitboxExpander/third_party/Imaging-1.1.7/README deleted file mode 100755 index 458975b3bac..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/README +++ /dev/null @@ -1,300 +0,0 @@ -The Python Imaging Library -$Id$ - -Release 1.1.7 (November 15, 2009) - -==================================================================== -The Python Imaging Library 1.1.7 -==================================================================== - -Contents --------- - -+ Introduction -+ Support Options - - Commercial support - - Free support -+ Software License -+ Build instructions (all platforms) - - Additional notes for Mac OS X - - Additional notes for Windows - --------------------------------------------------------------------- -Introduction --------------------------------------------------------------------- - -The Python Imaging Library (PIL) adds image processing capabilities -to your Python environment. This library provides extensive file -format support, an efficient internal representation, and powerful -image processing capabilities. - -This source kit has been built and tested with Python 2.0 and newer, -on Windows, Mac OS X, and major Unix platforms. Large parts of the -library also work on 1.5.2 and 1.6. - -The main distribution site for this software is: - - http://www.pythonware.com/products/pil/ - -That site also contains information about free and commercial support -options, PIL add-ons, answers to frequently asked questions, and more. - - -Development versions (alphas, betas) are available here: - - http://effbot.org/downloads/ - - -The PIL handbook is not included in this distribution; to get the -latest version, check: - - http://www.pythonware.com/library/ - http://effbot.org/books/imagingbook/ (drafts) - - -For installation and licensing details, see below. - - --------------------------------------------------------------------- -Support Options --------------------------------------------------------------------- - -+ Commercial Support - -Secret Labs (PythonWare) offers support contracts for companies using -the Python Imaging Library in commercial applications, and in mission- -critical environments. The support contract includes technical support, -bug fixes, extensions to the PIL library, sample applications, and more. - -For the full story, check: - - http://www.pythonware.com/products/pil/support.htm - - -+ Free Support - -For support and general questions on the Python Imaging Library, send -e-mail to the Image SIG mailing list: - - image-sig@python.org - -You can join the Image SIG by sending a mail to: - - image-sig-request@python.org - -Put "subscribe" in the message body to automatically subscribe to the -list, or "help" to get additional information. Alternatively, you can -send your questions to the Python mailing list, python-list@python.org, -or post them to the newsgroup comp.lang.python. DO NOT SEND SUPPORT -QUESTIONS TO PYTHONWARE ADDRESSES. - - --------------------------------------------------------------------- -Software License --------------------------------------------------------------------- - -The Python Imaging Library is - -Copyright (c) 1997-2009 by Secret Labs AB -Copyright (c) 1995-2009 by Fredrik Lundh - -By obtaining, using, and/or copying this software and/or its -associated documentation, you agree that you have read, understood, -and will comply with the following terms and conditions: - -Permission to use, copy, modify, and distribute this software and its -associated documentation for any purpose and without fee is hereby -granted, provided that the above copyright notice appears in all -copies, and that both that copyright notice and this permission notice -appear in supporting documentation, and that the name of Secret Labs -AB or the author not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR -ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - --------------------------------------------------------------------- -Build instructions (all platforms) --------------------------------------------------------------------- - -For a list of changes in this release, see the CHANGES document. - -0. If you're in a hurry, try this: - - $ tar xvfz Imaging-1.1.7.tar.gz - $ cd Imaging-1.1.7 - $ python setup.py install - - If you prefer to know what you're doing, read on. - - -1. Prerequisites. - - If you need any of the features described below, make sure you - have the necessary libraries before building PIL. - - feature library - ----------------------------------------------------------------- - JPEG support libjpeg (6a or 6b) - - http://www.ijg.org - http://www.ijg.org/files/jpegsrc.v6b.tar.gz - ftp://ftp.uu.net/graphics/jpeg/ - - PNG support zlib (1.2.3 or later is recommended) - - http://www.gzip.org/zlib/ - - OpenType/TrueType freetype2 (2.3.9 or later is recommended) - support - http://www.freetype.org - http://freetype.sourceforge.net - - CMS support littleCMS (1.1.5 or later is recommended) - support - http://www.littlecms.com/ - - If you have a recent Linux version, the libraries provided with the - operating system usually work just fine. If some library is - missing, installing a prebuilt version (jpeg-devel, zlib-devel, - etc) is usually easier than building from source. For example, for - Ubuntu 9.10 (karmic), you can install the following libraries: - - sudo apt-get install libjpeg62-dev - sudo apt-get install zlib1g-dev - sudo apt-get install libfreetype6-dev - sudo apt-get install liblcms1-dev - - If you're using Mac OS X, you can use the 'fink' tool to install - missing libraries (also see the Mac OS X section below). - - Similar tools are available for many other platforms. - - -2. To build under Python 1.5.2, you need to install the stand-alone - version of the distutils library: - - http://www.python.org/sigs/distutils-sig/download.html - - You can fetch distutils 1.0.2 from the Python source repository: - - svn export http://svn.python.org/projects/python/tags/Distutils-1_0_2/Lib/distutils/ - - For newer releases, the distutils library is included in the - Python standard library. - - NOTE: Version 1.1.7 is not fully compatible with 1.5.2. Some - more recent additions to the library may not work, but the core - functionality is available. - - -3. If you didn't build Python from sources, make sure you have - Python's build support files on your machine. If you've down- - loaded a prebuilt package (e.g. a Linux RPM), you probably - need additional developer packages. Look for packages named - "python-dev", "python-devel", or similar. For example, for - Ubuntu 9.10 (karmic), use the following command: - - sudo apt-get install python-dev - - -4. When you have everything you need, unpack the PIL distribution - (the file Imaging-1.1.7.tar.gz) in a suitable work directory: - - $ cd MyExtensions # example - $ gunzip Imaging-1.1.7.tar.gz - $ tar xvf Imaging-1.1.7.tar - - -5. Build the library. We recommend that you do an in-place build, - and run the self test before installing. - - $ cd Imaging-1.1.7 - $ python setup.py build_ext -i - $ python selftest.py - - During the build process, the setup.py will display a summary - report that lists what external components it found. The self- - test will display a similar report, with what external components - the tests found in the actual build files: - - ---------------------------------------------------------------- - PIL 1.1.7 SETUP SUMMARY - ---------------------------------------------------------------- - *** TKINTER support not available (Tcl/Tk 8.5 libraries needed) - --- JPEG support available - --- ZLIB (PNG/ZIP) support available - --- FREETYPE support available - ---------------------------------------------------------------- - - Make sure that the optional components you need are included. - - If the build script won't find a given component, you can edit the - setup.py file and set the appropriate ROOT variable. For details, - see instructions in the file. - - If the build script finds the component, but the tests cannot - identify it, try rebuilding *all* modules: - - $ python setup.py clean - $ python setup.py build_ext -i - - -6. If the setup.py and selftest.py commands finish without any - errors, you're ready to install the library: - - $ python setup.py install - - (depending on how Python has been installed on your machine, - you might have to log in as a superuser to run the 'install' - command, or use the 'sudo' command to run 'install'.) - - --------------------------------------------------------------------- -Additional notes for Mac OS X --------------------------------------------------------------------- - -On Mac OS X you will usually install additional software such as -libjpeg or freetype with the "fink" tool, and then it ends up in -"/sw". If you have installed the libraries elsewhere, you may have -to tweak the "setup.py" file before building. - - --------------------------------------------------------------------- -Additional notes for Windows --------------------------------------------------------------------- - -On Windows, you need to tweak the ROOT settings in the "setup.py" -file, to make it find the external libraries. See comments in the -file for details. - -Make sure to build PIL and the external libraries with the same -runtime linking options as was used for the Python interpreter -(usually /MD, under Visual Studio). - - -Note that most Python distributions for Windows include libraries -compiled for Microsoft Visual Studio. You can get the free Express -edition of Visual Studio from: - - http://www.microsoft.com/Express/ - -To build extensions using other tool chains, see the "Using -non-Microsoft compilers on Windows" section in the distutils handbook: - - http://www.python.org/doc/current/inst/non-ms-compilers.html - -For additional information on how to build extensions using the -popular MinGW compiler, see: - - http://mingw.org (compiler) - http://sebsauvage.net/python/mingw.html (build instructions) - http://sourceforge.net/projects/gnuwin32 (prebuilt libraries) - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES deleted file mode 100755 index 95c14697e83..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/CHANGES +++ /dev/null @@ -1,34 +0,0 @@ - -from V1.0 to V2.0 - -_sane.c: - - Values for option constraints are correctly translated to floats - if value type is TYPE_FIXED for SANE_CONSTRAINT_RANGE and - SANE_CONSTRAINT_WORD_LIST - - added constants INFO_INEXACT, INFO_RELOAD_OPTIONS, - INFO_RELOAD_PARAMS (possible return values of set_option()) - to module dictionnary. - - removed additional return variable 'i' from SaneDev_get_option(), - because it is only set when SANE_ACTION_SET_VALUE is used. - - scanDev.get_parameters() now returns the scanner mode as 'format', - no more the typical PIL codes. So 'L' became 'gray', 'RGB' is now - 'color', 'R' is 'red', 'G' is 'green', 'B' is 'red'. This matches - the way scanDev.mode is set. - This should be the only incompatibility vs. version 1.0. - -sane.py - - ScanDev got new method __load_option_dict() called from __init__() - and from __setattr__() if backend reported that the frontend should - reload the options. - - Nice human-readable __repr__() method added for class Option - - if __setattr__ (i.e. set_option) reports that all other options - have to be reloaded due to a change in the backend then they are reloaded. - - due to the change in SaneDev_get_option() only the 'value' is - returned from get_option(). - - in __setattr__ integer values are automatically converted to floats - if SANE backend expects SANE_FIXED (i.e. fix-point float) - - The scanner options can now directly be accessed via scanDev[optionName] - instead scanDev.opt[optionName]. (The old way still works). - -V1.0: - A.M. Kuchling's original pysane package. \ No newline at end of file diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README deleted file mode 100755 index ddff0cf2479..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/README +++ /dev/null @@ -1,22 +0,0 @@ - -Python SANE module V1.1 (30 Sep. 2004) - -The SANE module provides an interface to the SANE scanner and frame -grabber interface for Linux. This module was contributed by Andrew -Kuchling and is extended and currently maintained by Ralph Heinkel -(rheinkel-at-email.de). If you write to me please make sure to have the -word 'SANE' or 'sane' in the subject of your mail, otherwise it might -be classified as spam in the future. - - -To build this module, type (in the Sane directory): - - python setup.py build - -In order to install the module type: - - python setup.py install - - -For some basic documentation please look at the file sanedoc.txt -The two demo_*.py scripts give basic examples on how to use the software. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c deleted file mode 100755 index 21e542fa512..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/_sane.c +++ /dev/null @@ -1,1325 +0,0 @@ -/*********************************************************** -(C) Copyright 2003 A.M. Kuchling. All Rights Reserved -(C) Copyright 2004 A.M. Kuchling, Ralph Heinkel All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of A.M. Kuchling and -Ralph Heinkel not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior permission. - -A.M. KUCHLING, R.H. HEINKEL DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - -******************************************************************/ - -/* SaneDev objects */ - -#include "Python.h" -#include "Imaging.h" -#include - -#include - -static PyObject *ErrorObject; - -typedef struct { - PyObject_HEAD - SANE_Handle h; -} SaneDevObject; - -#ifdef WITH_THREAD -PyThreadState *_save; -#endif - -/* Raise a SANE exception */ -PyObject * -PySane_Error(SANE_Status st) -{ - const char *string; - - if (st==SANE_STATUS_GOOD) {Py_INCREF(Py_None); return (Py_None);} - string=sane_strstatus(st); - PyErr_SetString(ErrorObject, string); - return NULL; -} - -staticforward PyTypeObject SaneDev_Type; - -#define SaneDevObject_Check(v) ((v)->ob_type == &SaneDev_Type) - -static SaneDevObject * -newSaneDevObject(void) -{ - SaneDevObject *self; - self = PyObject_NEW(SaneDevObject, &SaneDev_Type); - if (self == NULL) - return NULL; - self->h=NULL; - return self; -} - -/* SaneDev methods */ - -static void -SaneDev_dealloc(SaneDevObject *self) -{ - if (self->h) sane_close(self->h); - self->h=NULL; - PyObject_DEL(self); -} - -static PyObject * -SaneDev_close(SaneDevObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (self->h) sane_close(self->h); - self->h=NULL; - Py_INCREF(Py_None); - return (Py_None); -} - -static PyObject * -SaneDev_get_parameters(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - SANE_Parameters p; - char *format="unknown format"; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - st=sane_get_parameters(self->h, &p); - Py_END_ALLOW_THREADS - - if (st) return PySane_Error(st); - switch (p.format) - { - case(SANE_FRAME_GRAY): format="gray"; break; - case(SANE_FRAME_RGB): format="color"; break; - case(SANE_FRAME_RED): format="red"; break; - case(SANE_FRAME_GREEN): format="green"; break; - case(SANE_FRAME_BLUE): format="blue"; break; - } - - return Py_BuildValue("si(ii)ii", format, p.last_frame, p.pixels_per_line, - p.lines, p.depth, p.bytes_per_line); -} - - -static PyObject * -SaneDev_fileno(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - SANE_Int fd; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - st=sane_get_select_fd(self->h, &fd); - if (st) return PySane_Error(st); - return PyInt_FromLong(fd); -} - -static PyObject * -SaneDev_start(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - /* sane_start can take several seconds, if the user initiates - a new scan, while the scan head of a flatbed scanner moves - back to the start position after finishing a previous scan. - Hence it is worth to allow threads here. - */ - Py_BEGIN_ALLOW_THREADS - st=sane_start(self->h); - Py_END_ALLOW_THREADS - if (st) return PySane_Error(st); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -SaneDev_cancel(SaneDevObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - sane_cancel(self->h); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -SaneDev_get_options(SaneDevObject *self, PyObject *args) -{ - const SANE_Option_Descriptor *d; - PyObject *list, *value; - int i=1; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - if (!(list = PyList_New(0))) - return NULL; - - do - { - d=sane_get_option_descriptor(self->h, i); - if (d!=NULL) - { - PyObject *constraint=NULL; - int j; - - switch (d->constraint_type) - { - case(SANE_CONSTRAINT_NONE): - Py_INCREF(Py_None); constraint=Py_None; break; - case(SANE_CONSTRAINT_RANGE): - if (d->type == SANE_TYPE_INT) - constraint=Py_BuildValue("iii", d->constraint.range->min, - d->constraint.range->max, - d->constraint.range->quant); - else - constraint=Py_BuildValue("ddd", - SANE_UNFIX(d->constraint.range->min), - SANE_UNFIX(d->constraint.range->max), - SANE_UNFIX(d->constraint.range->quant)); - break; - case(SANE_CONSTRAINT_WORD_LIST): - constraint=PyList_New(d->constraint.word_list[0]); - if (d->type == SANE_TYPE_INT) - for (j=1; j<=d->constraint.word_list[0]; j++) - PyList_SetItem(constraint, j-1, - PyInt_FromLong(d->constraint.word_list[j])); - else - for (j=1; j<=d->constraint.word_list[0]; j++) - PyList_SetItem(constraint, j-1, - PyFloat_FromDouble(SANE_UNFIX(d->constraint.word_list[j]))); - break; - case(SANE_CONSTRAINT_STRING_LIST): - constraint=PyList_New(0); - for(j=0; d->constraint.string_list[j]!=NULL; j++) - PyList_Append(constraint, - PyString_FromString(d->constraint.string_list[j])); - break; - } - value=Py_BuildValue("isssiiiiO", i, d->name, d->title, d->desc, - d->type, d->unit, d->size, d->cap, constraint); - PyList_Append(list, value); - } - i++; - } while (d!=NULL); - return list; -} - -static PyObject * -SaneDev_get_option(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - const SANE_Option_Descriptor *d; - PyObject *value=NULL; - int n; - void *v; - - if (!PyArg_ParseTuple(args, "i", &n)) - { - return NULL; - } - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - d=sane_get_option_descriptor(self->h, n); - v=malloc(d->size+1); - st=sane_control_option(self->h, n, SANE_ACTION_GET_VALUE, - v, NULL); - - if (st) - { - free(v); - return PySane_Error(st); - } - - switch(d->type) - { - case(SANE_TYPE_BOOL): - case(SANE_TYPE_INT): - value=Py_BuildValue("i", *( (SANE_Int*)v) ); - break; - case(SANE_TYPE_FIXED): - value=Py_BuildValue("d", SANE_UNFIX((*((SANE_Fixed*)v))) ); - break; - case(SANE_TYPE_STRING): - value=Py_BuildValue("s", v); - break; - case(SANE_TYPE_BUTTON): - case(SANE_TYPE_GROUP): - value=Py_BuildValue("O", Py_None); - break; - } - - free(v); - return value; -} - -static PyObject * -SaneDev_set_option(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - const SANE_Option_Descriptor *d; - SANE_Int i; - PyObject *value; - int n; - void *v; - - if (!PyArg_ParseTuple(args, "iO", &n, &value)) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - d=sane_get_option_descriptor(self->h, n); - v=malloc(d->size+1); - - switch(d->type) - { - case(SANE_TYPE_BOOL): - if (!PyInt_Check(value)) - { - PyErr_SetString(PyExc_TypeError, "SANE_BOOL requires an integer"); - free(v); - return NULL; - } - /* fall through */ - case(SANE_TYPE_INT): - if (!PyInt_Check(value)) - { - PyErr_SetString(PyExc_TypeError, "SANE_INT requires an integer"); - free(v); - return NULL; - } - *( (SANE_Int*)v) = PyInt_AsLong(value); - break; - case(SANE_TYPE_FIXED): - if (!PyFloat_Check(value)) - { - PyErr_SetString(PyExc_TypeError, "SANE_FIXED requires a floating point number"); - free(v); - return NULL; - } - *( (SANE_Fixed*)v) = SANE_FIX(PyFloat_AsDouble(value)); - break; - case(SANE_TYPE_STRING): - if (!PyString_Check(value)) - { - PyErr_SetString(PyExc_TypeError, "SANE_STRING requires a string"); - free(v); - return NULL; - } - strncpy(v, PyString_AsString(value), d->size-1); - ((char*)v)[d->size-1] = 0; - break; - case(SANE_TYPE_BUTTON): - case(SANE_TYPE_GROUP): - break; - } - - st=sane_control_option(self->h, n, SANE_ACTION_SET_VALUE, - v, &i); - if (st) {free(v); return PySane_Error(st);} - - free(v); - return Py_BuildValue("i", i); -} - -static PyObject * -SaneDev_set_auto_option(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - const SANE_Option_Descriptor *d; - SANE_Int i; - int n; - - if (!PyArg_ParseTuple(args, "i", &n)) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - d=sane_get_option_descriptor(self->h, n); - st=sane_control_option(self->h, n, SANE_ACTION_SET_AUTO, - NULL, &i); - if (st) {return PySane_Error(st);} - - return Py_BuildValue("i", i); - } - -#define READSIZE 32768 - -static PyObject * -SaneDev_snap(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - /* The buffer should be a multiple of 3 in size, so each sane_read - operation will return an integral number of RGB triples. */ - SANE_Byte buffer[READSIZE]; /* XXX how big should the buffer be? */ - SANE_Int len, lastlen; - Imaging im; - SANE_Parameters p; - int px, py, remain, cplen, bufpos, padbytes; - long L; - char errmsg[80]; - union - { char c[2]; - INT16 i16; - } - endian; - PyObject *pyNoCancel = NULL; - int noCancel = 0; - - endian.i16 = 1; - - if (!PyArg_ParseTuple(args, "l|O", &L, &pyNoCancel)) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - im=(Imaging)L; - - if (pyNoCancel) - noCancel = PyObject_IsTrue(pyNoCancel); - - st=SANE_STATUS_GOOD; px=py=0; - /* xxx not yet implemented - - handscanner support (i.e., unknown image length during start) - - generally: move the functionality from method snap in sane.py - down here -- I don't like this cross-dependency. - we need to call sane_get_parameters here, and we can create - the result Image object here. - */ - - Py_UNBLOCK_THREADS - sane_get_parameters(self->h, &p); - if (p.format == SANE_FRAME_GRAY) - { - switch (p.depth) - { - case 1: - remain = p.bytes_per_line * im->ysize; - padbytes = p.bytes_per_line - (im->xsize+7)/8; - bufpos = 0; - lastlen = len = 0; - while (st!=SANE_STATUS_EOF && py < im->ysize) - { - while (len > 0 && py < im->ysize) - { - int i, j, k; - j = buffer[bufpos++]; - k = 0x80; - for (i = 0; i < 8 && px < im->xsize; i++) - { - im->image8[py][px++] = (k&j) ? 0 : 0xFF; - k = k >> 1; - } - len--; - if (px >= im->xsize) - { - bufpos += padbytes; - len -= padbytes; - py++; - px = 0; - } - } - st=sane_read(self->h, buffer, - remainh); - Py_BLOCK_THREADS - return PySane_Error(st); - } - bufpos -= lastlen; - lastlen = len; - remain -= len; - /* skip possible pad bytes at the start of the buffer */ - len -= bufpos; - } - break; - case 8: - remain = p.bytes_per_line * im->ysize; - padbytes = p.bytes_per_line - im->xsize; - bufpos = 0; - len = 0; - while (st!=SANE_STATUS_EOF && py < im->ysize) - { - while (len > 0 && py < im->ysize) - { - cplen = len; - if (px + cplen >= im->xsize) - cplen = im->xsize - px; - memcpy(&im->image8[py][px], &buffer[bufpos], cplen); - len -= cplen; - bufpos += cplen; - px += cplen; - if (px >= im->xsize) - { - px = 0; - py++; - bufpos += padbytes; - len -= padbytes; - } - } - bufpos = -len; - - st=sane_read(self->h, buffer, - remainh); - Py_BLOCK_THREADS - return PySane_Error(st); - } - remain -= len; - len -= bufpos; - } - break; - case 16: - remain = p.bytes_per_line * im->ysize; - padbytes = p.bytes_per_line - 2 * im->xsize; - bufpos = endian.c[0]; - lastlen = len = 0; - while (st!=SANE_STATUS_EOF && py < im->ysize) - { - while (len > 0 && py < im->ysize) - { - im->image8[py][px++] = buffer[bufpos]; - bufpos += 2; - len -= 2; - if (px >= im->xsize) - { - bufpos += padbytes; - len -= padbytes; - py++; - px = 0; - } - } - st=sane_read(self->h, buffer, - remainh); - Py_BLOCK_THREADS - return PySane_Error(st); - } - remain -= len; - bufpos -= lastlen; - lastlen = len; - len -= bufpos; - } - break; - default: - /* other depths are not formally "illegal" according to the - Sane API, but it's agreed by Sane developers that other - depths than 1, 8, 16 should not be used - */ - sane_cancel(self->h); - Py_BLOCK_THREADS - snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth); - PyErr_SetString(ErrorObject, errmsg); - return NULL; - } - } - else if (p.format == SANE_FRAME_RGB) - { - int incr, color, pxs, pxmax, bit, val, mask; - switch (p.depth) - { - case 1: - remain = p.bytes_per_line * im->ysize; - padbytes = p.bytes_per_line - ((im->xsize+7)/8) * 3; - bufpos = 0; - len = 0; - lastlen = 0; - pxmax = 4 * im->xsize; - while (st!=SANE_STATUS_EOF && py < im->ysize) - { - pxs = px; - for (color = 0; color < 3; color++) - { - while (len <= 0 && st == SANE_STATUS_GOOD) - { - st=sane_read(self->h, buffer, - remainh); - Py_BLOCK_THREADS - return PySane_Error(st); - } - bufpos -= lastlen; - remain -= len; - lastlen = len; - /* skip possible pad bytes at the start of the buffer */ - len -= bufpos; - } - if (st == SANE_STATUS_EOF) break; - pxs = px; - val = buffer[bufpos++]; - len--; - mask = 0x80; - for (bit = 0; (bit < 8) && (px < pxmax); bit++) - { - ((UINT8**)(im->image32))[py][px] = (val&mask) ? 0xFF : 0; - mask = mask >> 1; - px += 4; - } - pxs++; - px = pxs; - } - if (st == SANE_STATUS_EOF) - break; - for (bit = 0; bit < 8 && px < pxmax; bit++) - { - ((UINT8**)(im->image32))[py][px] = 0; - px += 4; - } - px -= 3; - if (px >= pxmax) - { - bufpos += padbytes; - len -= padbytes; - py++; - px = 0; - } - } - break; - case 8: - case 16: - if (p.depth == 8) - { - padbytes = p.bytes_per_line - 3 * im->xsize; - bufpos = 0; - incr = 1; - } - else - { - padbytes = p.bytes_per_line - 6 * im->xsize; - bufpos = endian.c[0]; - incr = 2; - } - remain = p.bytes_per_line * im->ysize; - len = 0; - lastlen = 0; - pxmax = 4 * im->xsize; - /* probably not very efficient. But we have to deal with these - possible conditions: - - we may have padding bytes at the end of a scan line - - the number of bytes read with sane_read may be smaller - than the number of pad bytes - - the buffer may become empty after setting any of the - red/green/blue pixel values - - */ - while (st != SANE_STATUS_EOF && py < im->ysize) - { - for (color = 0; color < 3; color++) - { - while (len <= 0 && st == SANE_STATUS_GOOD) - { - bufpos -= lastlen; - if (remain == 0) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - PyErr_SetString(ErrorObject, "internal _sane error: premature end of scan"); - return NULL; - } - st = sane_read(self->h, buffer, - remain<(READSIZE) ? remain : (READSIZE), &len); - if (st && (st!=SANE_STATUS_EOF)) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - return PySane_Error(st); - } - lastlen = len; - remain -= len; - len -= bufpos; - } - if (st == SANE_STATUS_EOF) break; - ((UINT8**)(im->image32))[py][px++] = buffer[bufpos]; - bufpos += incr; - len -= incr; - } - if (st == SANE_STATUS_EOF) break; - - ((UINT8**)(im->image32))[py][px++] = 0; - - if (px >= pxmax) - { - px = 0; - py++; - bufpos += padbytes; - len -= padbytes; - } - } - break; - default: - Py_BLOCK_THREADS - sane_cancel(self->h); - snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth); - PyErr_SetString(ErrorObject, errmsg); - return NULL; - } - - } - else /* should be SANE_FRAME_RED, GREEN or BLUE */ - { - int lastlen, pxa, pxmax, offset, incr, frame_count = 0; - /* at least the Sane test backend behaves a bit weird, if - it returns "premature EOF" for sane_read, i.e., if the - option "return value of sane_read" is set to SANE_STATUS_EOF. - In this case, the test backend does not advance to the next frame, - so p.last_frame will never be set... - So let's count the number of frames we try to acquire - */ - while (!p.last_frame && frame_count < 4) - { - frame_count++; - st = sane_get_parameters(self->h, &p); - if (st) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - return PySane_Error(st); - } - remain = p.bytes_per_line * im->ysize; - bufpos = 0; - len = 0; - lastlen = 0; - py = 0; - switch (p.format) - { - case SANE_FRAME_RED: - offset = 0; - break; - case SANE_FRAME_GREEN: - offset = 1; - break; - case SANE_FRAME_BLUE: - offset = 2; - break; - default: - sane_cancel(self->h); - Py_BLOCK_THREADS - snprintf(errmsg, 80, "unknown/invalid frame format: %i", p.format); - PyErr_SetString(ErrorObject, errmsg); - return NULL; - } - px = offset; - pxa = 3; - pxmax = im->xsize * 4; - switch (p.depth) - { - case 1: - padbytes = p.bytes_per_line - (im->xsize+7)/8; - st = SANE_STATUS_GOOD; - while (st != SANE_STATUS_EOF && py < im->ysize) - { - while (len > 0) - { - int bit, mask, val; - val = buffer[bufpos++]; len--; - mask = 0x80; - for (bit = 0; bit < 8 && px < pxmax; bit++) - { - ((UINT8**)(im->image32))[py][px] - = val&mask ? 0xFF : 0; - ((UINT8**)(im->image32))[py][pxa] = 0; - px += 4; - pxa += 4; - mask = mask >> 1; - } - - if (px >= pxmax) - { - px = offset; - pxa = 3; - py++; - bufpos += padbytes; - len -= padbytes; - } - } - while (len <= 0 && st == SANE_STATUS_GOOD && remain > 0) - { - bufpos -= lastlen; - st = sane_read(self->h, buffer, - remain<(READSIZE) ? remain : (READSIZE), &len); - if (st && (st!=SANE_STATUS_EOF)) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - return PySane_Error(st); - } - remain -= len; - lastlen = len; - len -= bufpos; - } - } - break; - case 8: - case 16: - if (p.depth == 8) - { - padbytes = p.bytes_per_line - im->xsize; - incr = 1; - } - else - { - padbytes = p.bytes_per_line - 2 * im->xsize; - incr = 2; - bufpos = endian.c[0]; - } - st = SANE_STATUS_GOOD; - while (st != SANE_STATUS_EOF && py < im->ysize) - { - while (len <= 0) - { - bufpos -= lastlen; - if (remain == 0) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - PyErr_SetString(ErrorObject, "internal _sane error: premature end of scan"); - return NULL; - } - st = sane_read(self->h, buffer, - remain<(READSIZE) ? remain : (READSIZE), &len); - if (st && (st!=SANE_STATUS_EOF)) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - return PySane_Error(st); - } - if (st == SANE_STATUS_EOF) - break; - lastlen = len; - remain -= len; - if (bufpos >= len) - len = 0; - else - len -= bufpos; - } - if (st == SANE_STATUS_EOF) - break; - ((UINT8**)(im->image32))[py][px] = buffer[bufpos]; - ((UINT8**)(im->image32))[py][pxa] = 0; - bufpos += incr; - len -= incr; - px += 4; - pxa += 4; - - if (px >= pxmax) - { - px = offset; - pxa = 3; - py++; - bufpos += padbytes; - len -= padbytes; - } - } - break; - default: - sane_cancel(self->h); - Py_BLOCK_THREADS - snprintf(errmsg, 80, "unsupported pixel depth: %i", p.depth); - PyErr_SetString(ErrorObject, errmsg); - return NULL; - } - if (!p.last_frame) - { - /* all sane_read calls in the above loop may return - SANE_STATUS_GOOD, but the backend may need another sane_read - call which returns SANE_STATUS_EOF in order to start - a new frame. - */ - do { - st = sane_read(self->h, buffer, READSIZE, &len); - } - while (st == SANE_STATUS_GOOD); - if (st != SANE_STATUS_EOF) - { - Py_BLOCK_THREADS - sane_cancel(self->h); - return PySane_Error(st); - } - - st = sane_start(self->h); - if (st) - { - Py_BLOCK_THREADS - return PySane_Error(st); - } - } - } - } - /* enforce SANE_STATUS_EOF. Can be necessary for ADF scans for some backends */ - do { - st = sane_read(self->h, buffer, READSIZE, &len); - } - while (st == SANE_STATUS_GOOD); - if (st != SANE_STATUS_EOF) - { - sane_cancel(self->h); - Py_BLOCK_THREADS - return PySane_Error(st); - } - - if (!noCancel) - sane_cancel(self->h); - Py_BLOCK_THREADS - Py_INCREF(Py_None); - return Py_None; -} - - -#ifdef WITH_NUMARRAY - -#include "numarray/libnumarray.h" - -/* this global variable is set to 1 in 'init_sane()' after successfully - importing the numarray module. */ -int NUMARRAY_IMPORTED = 0; - -static PyObject * -SaneDev_arr_snap(SaneDevObject *self, PyObject *args) -{ - SANE_Status st; - SANE_Byte buffer[READSIZE]; - SANE_Int len; - SANE_Parameters p; - - PyArrayObject *pyArr = NULL; - NumarrayType arrType; - int line, line_index, buffer_index, remain_bytes_line, num_pad_bytes; - int cp_num_bytes, total_remain, bpp, arr_bytes_per_line; - int pixels_per_line = -1; - char errmsg[80]; - - if (!NUMARRAY_IMPORTED) - { - PyErr_SetString(ErrorObject, "numarray package not available"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "|i", &pixels_per_line)) - return NULL; - if (self->h==NULL) - { - PyErr_SetString(ErrorObject, "SaneDev object is closed"); - return NULL; - } - - sane_get_parameters(self->h, &p); - if (p.format != SANE_FRAME_GRAY) - { - sane_cancel(self->h); - snprintf(errmsg, 80, "numarray only supports gray-scale images"); - PyErr_SetString(ErrorObject, errmsg); - return NULL; - } - - if (p.depth == 8) - { - bpp=1; /* bytes-per-pixel */ - arrType = tUInt8; - } - else if (p.depth == 16) - { - bpp=2; /* bytes-per-pixel */ - arrType = tUInt16; - } - else - { - sane_cancel(self->h); - snprintf(errmsg, 80, "arrsnap: unsupported pixel depth: %i", p.depth); - PyErr_SetString(ErrorObject, errmsg); - return NULL; - } - - if (pixels_per_line < 1) - /* The user can choose a smaller result array than the actual scan */ - pixels_per_line = p.pixels_per_line; - else - if (pixels_per_line > p.pixels_per_line) - { - PyErr_SetString(ErrorObject,"given pixels_per_line too big"); - return NULL; - } - /* important: NumArray have indices like (y, x) !! */ - if (!(pyArr = NA_NewArray(NULL, arrType, 2, p.lines, pixels_per_line))) - { - PyErr_SetString(ErrorObject, "failed to create NumArray object"); - return NULL; - } - - arr_bytes_per_line = pixels_per_line * bpp; - st=SANE_STATUS_GOOD; -#ifdef WRITE_PGM - FILE *fp; - fp = fopen("sane_p5.pgm", "w"); - fprintf(fp, "P5\n%d %d\n%d\n", p.pixels_per_line, - p.lines, (int) pow(2.0, (double) p.depth)-1); -#endif - line_index = line = 0; - remain_bytes_line = arr_bytes_per_line; - total_remain = p.bytes_per_line * p.lines; - num_pad_bytes = p.bytes_per_line - arr_bytes_per_line; - - while (st!=SANE_STATUS_EOF) - { - Py_BEGIN_ALLOW_THREADS - st = sane_read(self->h, buffer, - READSIZE < total_remain ? READSIZE : total_remain, &len); - Py_END_ALLOW_THREADS -#ifdef WRITE_PGM - printf("p5_write: read %d of %d\n", len, READSIZE); - fwrite(buffer, 1, len, fp); -#endif - - buffer_index = 0; - total_remain -= len; - - while (len > 0) - { - /* copy at most the number of bytes that fit into (the rest of) - one line: */ - cp_num_bytes = (len > remain_bytes_line ? remain_bytes_line : len); - remain_bytes_line -= cp_num_bytes; - len -= cp_num_bytes; -#ifdef DEBUG - printf("copying %d bytes from b_idx %d to d_idx %d\n", - cp_num_bytes, buffer_index, - line * arr_bytes_per_line + line_index); - printf("len is now %d\n", len); -#endif - memcpy(pyArr->data + line * arr_bytes_per_line + line_index, - buffer + buffer_index, cp_num_bytes); - - buffer_index += cp_num_bytes; - if (remain_bytes_line ==0) - { - /* The line has been completed, so reinitialize remain_bytes_line - increase the line counter, and reset line_index */ -#ifdef DEBUG - printf("line %d full, skipping %d bytes\n",line,num_pad_bytes); -#endif - remain_bytes_line = arr_bytes_per_line; - line++; - line_index = 0; - /* Skip the number of bytes in the input stream which - are not used: */ - len -= num_pad_bytes; - buffer_index += num_pad_bytes; - } - else - line_index += cp_num_bytes; - } - } -#ifdef WRITE_PGM - fclose(fp); - printf("p5_write finished\n"); -#endif - sane_cancel(self->h); - return (PyObject*) pyArr; -} - - - -#endif /* WITH_NUMARRAY */ - -static PyMethodDef SaneDev_methods[] = { - {"get_parameters", (PyCFunction)SaneDev_get_parameters, 1}, - - {"get_options", (PyCFunction)SaneDev_get_options, 1}, - {"get_option", (PyCFunction)SaneDev_get_option, 1}, - {"set_option", (PyCFunction)SaneDev_set_option, 1}, - {"set_auto_option", (PyCFunction)SaneDev_set_auto_option, 1}, - - {"start", (PyCFunction)SaneDev_start, 1}, - {"cancel", (PyCFunction)SaneDev_cancel, 1}, - {"snap", (PyCFunction)SaneDev_snap, 1}, -#ifdef WITH_NUMARRAY - {"arr_snap", (PyCFunction)SaneDev_arr_snap, 1}, -#endif /* WITH_NUMARRAY */ - {"fileno", (PyCFunction)SaneDev_fileno, 1}, - {"close", (PyCFunction)SaneDev_close, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SaneDev_getattr(SaneDevObject *self, char *name) -{ - return Py_FindMethod(SaneDev_methods, (PyObject *)self, name); -} - -staticforward PyTypeObject SaneDev_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "SaneDev", /*tp_name*/ - sizeof(SaneDevObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)SaneDev_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)SaneDev_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ -}; - -/* --------------------------------------------------------------------- */ - -static PyObject * -PySane_init(PyObject *self, PyObject *args) -{ - SANE_Status st; - SANE_Int version; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - - /* XXX Authorization is not yet supported */ - st=sane_init(&version, NULL); - if (st) return PySane_Error(st); - return Py_BuildValue("iiii", version, SANE_VERSION_MAJOR(version), - SANE_VERSION_MINOR(version), SANE_VERSION_BUILD(version)); -} - -static PyObject * -PySane_exit(PyObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - - sane_exit(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PySane_get_devices(PyObject *self, PyObject *args) -{ - SANE_Device **devlist; - SANE_Device *dev; - SANE_Status st; - PyObject *list; - int local_only, i; - - if (!PyArg_ParseTuple(args, "|i", &local_only)) - { - return NULL; - } - - st=sane_get_devices(&devlist, local_only); - if (st) return PySane_Error(st); - if (!(list = PyList_New(0))) - return NULL; - for(i=0; devlist[i]!=NULL; i++) - { - dev=devlist[i]; - PyList_Append(list, Py_BuildValue("ssss", dev->name, dev->vendor, - dev->model, dev->type)); - } - - return list; -} - -/* Function returning new SaneDev object */ - -static PyObject * -PySane_open(PyObject *self, PyObject *args) -{ - SaneDevObject *rv; - SANE_Status st; - char *name; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - rv = newSaneDevObject(); - if ( rv == NULL ) - return NULL; - st = sane_open(name, &(rv->h)); - if (st) - { - Py_DECREF(rv); - return PySane_Error(st); - } - return (PyObject *)rv; -} - -static PyObject * -PySane_OPTION_IS_ACTIVE(PyObject *self, PyObject *args) -{ - SANE_Int cap; - long lg; - - if (!PyArg_ParseTuple(args, "l", &lg)) - return NULL; - cap=lg; - return PyInt_FromLong( SANE_OPTION_IS_ACTIVE(cap)); -} - -static PyObject * -PySane_OPTION_IS_SETTABLE(PyObject *self, PyObject *args) -{ - SANE_Int cap; - long lg; - - if (!PyArg_ParseTuple(args, "l", &lg)) - return NULL; - cap=lg; - return PyInt_FromLong( SANE_OPTION_IS_SETTABLE(cap)); -} - - -/* List of functions defined in the module */ - -static PyMethodDef PySane_methods[] = { - {"init", PySane_init, 1}, - {"exit", PySane_exit, 1}, - {"get_devices", PySane_get_devices, 1}, - {"_open", PySane_open, 1}, - {"OPTION_IS_ACTIVE", PySane_OPTION_IS_ACTIVE, 1}, - {"OPTION_IS_SETTABLE", PySane_OPTION_IS_SETTABLE, 1}, - {NULL, NULL} /* sentinel */ -}; - - -static void -insint(PyObject *d, char *name, int value) -{ - PyObject *v = PyInt_FromLong((long) value); - if (!v || PyDict_SetItemString(d, name, v)) - Py_FatalError("can't initialize sane module"); - - Py_DECREF(v); -} - -void -init_sane(void) -{ - PyObject *m, *d; - - /* Create the module and add the functions */ - m = Py_InitModule("_sane", PySane_methods); - - /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - ErrorObject = PyString_FromString("_sane.error"); - PyDict_SetItemString(d, "error", ErrorObject); - - insint(d, "INFO_INEXACT", SANE_INFO_INEXACT); - insint(d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS); - insint(d, "RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS); - - insint(d, "FRAME_GRAY", SANE_FRAME_GRAY); - insint(d, "FRAME_RGB", SANE_FRAME_RGB); - insint(d, "FRAME_RED", SANE_FRAME_RED); - insint(d, "FRAME_GREEN", SANE_FRAME_GREEN); - insint(d, "FRAME_BLUE", SANE_FRAME_BLUE); - - insint(d, "CONSTRAINT_NONE", SANE_CONSTRAINT_NONE); - insint(d, "CONSTRAINT_RANGE", SANE_CONSTRAINT_RANGE); - insint(d, "CONSTRAINT_WORD_LIST", SANE_CONSTRAINT_WORD_LIST); - insint(d, "CONSTRAINT_STRING_LIST", SANE_CONSTRAINT_STRING_LIST); - - insint(d, "TYPE_BOOL", SANE_TYPE_BOOL); - insint(d, "TYPE_INT", SANE_TYPE_INT); - insint(d, "TYPE_FIXED", SANE_TYPE_FIXED); - insint(d, "TYPE_STRING", SANE_TYPE_STRING); - insint(d, "TYPE_BUTTON", SANE_TYPE_BUTTON); - insint(d, "TYPE_GROUP", SANE_TYPE_GROUP); - - insint(d, "UNIT_NONE", SANE_UNIT_NONE); - insint(d, "UNIT_PIXEL", SANE_UNIT_PIXEL); - insint(d, "UNIT_BIT", SANE_UNIT_BIT); - insint(d, "UNIT_MM", SANE_UNIT_MM); - insint(d, "UNIT_DPI", SANE_UNIT_DPI); - insint(d, "UNIT_PERCENT", SANE_UNIT_PERCENT); - insint(d, "UNIT_MICROSECOND", SANE_UNIT_MICROSECOND); - - insint(d, "CAP_SOFT_SELECT", SANE_CAP_SOFT_SELECT); - insint(d, "CAP_HARD_SELECT", SANE_CAP_HARD_SELECT); - insint(d, "CAP_SOFT_DETECT", SANE_CAP_SOFT_DETECT); - insint(d, "CAP_EMULATED", SANE_CAP_EMULATED); - insint(d, "CAP_AUTOMATIC", SANE_CAP_AUTOMATIC); - insint(d, "CAP_INACTIVE", SANE_CAP_INACTIVE); - insint(d, "CAP_ADVANCED", SANE_CAP_ADVANCED); - - /* handy for checking array lengths: */ - insint(d, "SANE_WORD_SIZE", sizeof(SANE_Word)); - - /* possible return values of set_option() */ - insint(d, "INFO_INEXACT", SANE_INFO_INEXACT); - insint(d, "INFO_RELOAD_OPTIONS", SANE_INFO_RELOAD_OPTIONS); - insint(d, "INFO_RELOAD_PARAMS", SANE_INFO_RELOAD_PARAMS); - - /* Check for errors */ - if (PyErr_Occurred()) - Py_FatalError("can't initialize module _sane"); - -#ifdef WITH_NUMARRAY - import_libnumarray(); - if (PyErr_Occurred()) - PyErr_Clear(); - else - /* this global variable is declared just in front of the - arr_snap() function and should be set to 1 after - successfully importing the numarray module. */ - NUMARRAY_IMPORTED = 1; - -#endif /* WITH_NUMARRAY */ -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py deleted file mode 100755 index 0104af2d550..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_numarray.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python - -# -# Shows how to scan a 16 bit grayscale image into a numarray object -# - -# Get the path set up to find PIL modules if not installed yet: -import sys ; sys.path.append('../PIL') - -from numarray import * -import sane -import Image - -def toImage(arr): - if arr.type().bytes == 1: - # need to swap coordinates btw array and image (with [::-1]) - im = Image.fromstring('L', arr.shape[::-1], arr.tostring()) - else: - arr_c = arr - arr.min() - arr_c *= (255./arr_c.max()) - arr = arr_c.astype(UInt8) - # need to swap coordinates btw array and image (with [::-1]) - im = Image.fromstring('L', arr.shape[::-1], arr.tostring()) - return im - -print 'SANE version:', sane.init() -print 'Available devices=', sane.get_devices() - -s = sane.open(sane.get_devices()[0][0]) - -# Set scan parameters -s.mode = 'gray' -s.br_x=320. ; s.br_y=240. - -print 'Device parameters:', s.get_parameters() - -s.depth=16 -arr16 = s.arr_scan() -toImage(arr16).show() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py deleted file mode 100755 index 016361f8a82..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/demo_pil.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python - -# -# Shows how to scan a color image into a PIL rgb-image -# - -# Get the path set up to find PIL modules if not installed yet: -import sys ; sys.path.append('../PIL') - -import sane -print 'SANE version:', sane.init() -print 'Available devices=', sane.get_devices() - -s = sane.open(sane.get_devices()[0][0]) - -s.mode = 'color' -s.br_x=320. ; s.br_y=240. - -print 'Device parameters:', s.get_parameters() - -# Initiate the scan -s.start() - -# Get an Image object -# (For my B&W QuickCam, this is a grey-scale image. Other scanning devices -# may return a -im=s.snap() - -# Write the image out as a GIF file -#im.save('foo.gif') - -# The show method() simply saves the image to a temporary file and calls "xv". -im.show() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py deleted file mode 100755 index 27be5a259c4..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sane.py +++ /dev/null @@ -1,289 +0,0 @@ -# sane.py -# -# Python wrapper on top of the _sane module, which is in turn a very -# thin wrapper on top of the SANE library. For a complete understanding -# of SANE, consult the documentation at the SANE home page: -# http://www.mostang.com/sane/ . - -__version__ = '2.0' -__author__ = ['Andrew Kuchling', 'Ralph Heinkel'] - -from PIL import Image - -import _sane -from _sane import * - -TYPE_STR = { TYPE_BOOL: "TYPE_BOOL", TYPE_INT: "TYPE_INT", - TYPE_FIXED: "TYPE_FIXED", TYPE_STRING: "TYPE_STRING", - TYPE_BUTTON: "TYPE_BUTTON", TYPE_GROUP: "TYPE_GROUP" } - -UNIT_STR = { UNIT_NONE: "UNIT_NONE", - UNIT_PIXEL: "UNIT_PIXEL", - UNIT_BIT: "UNIT_BIT", - UNIT_MM: "UNIT_MM", - UNIT_DPI: "UNIT_DPI", - UNIT_PERCENT: "UNIT_PERCENT", - UNIT_MICROSECOND: "UNIT_MICROSECOND" } - - -class Option: - """Class representing a SANE option. - Attributes: - index -- number from 0 to n, giving the option number - name -- a string uniquely identifying the option - title -- single-line string containing a title for the option - desc -- a long string describing the option; useful as a help message - type -- type of this option. Possible values: TYPE_BOOL, - TYPE_INT, TYPE_STRING, and so forth. - unit -- units of this option. Possible values: UNIT_NONE, - UNIT_PIXEL, etc. - size -- size of the value in bytes - cap -- capabilities available; CAP_EMULATED, CAP_SOFT_SELECT, etc. - constraint -- constraint on values. Possible values: - None : No constraint - (min,max,step) Integer values, from min to max, stepping by - list of integers or strings: only the listed values are allowed - """ - - def __init__(self, args, scanDev): - import string - self.scanDev = scanDev # needed to get current value of this option - self.index, self.name = args[0], args[1] - self.title, self.desc = args[2], args[3] - self.type, self.unit = args[4], args[5] - self.size, self.cap = args[6], args[7] - self.constraint = args[8] - def f(x): - if x=='-': return '_' - else: return x - if type(self.name)!=type(''): self.py_name=str(self.name) - else: self.py_name=string.join(map(f, self.name), '') - - def is_active(self): - return _sane.OPTION_IS_ACTIVE(self.cap) - def is_settable(self): - return _sane.OPTION_IS_SETTABLE(self.cap) - def __repr__(self): - if self.is_settable(): - settable = 'yes' - else: - settable = 'no' - if self.is_active(): - active = 'yes' - curValue = repr(getattr(self.scanDev, self.py_name)) - else: - active = 'no' - curValue = '' - s = """\nName: %s -Cur value: %s -Index: %d -Title: %s -Desc: %s -Type: %s -Unit: %s -Constr: %s -active: %s -settable: %s\n""" % (self.py_name, curValue, - self.index, self.title, self.desc, - TYPE_STR[self.type], UNIT_STR[self.unit], - `self.constraint`, active, settable) - return s - - -class _SaneIterator: - """ intended for ADF scans. - """ - - def __init__(self, device): - self.device = device - - def __iter__(self): - return self - - def __del__(self): - self.device.cancel() - - def next(self): - try: - self.device.start() - except error, v: - if v == 'Document feeder out of documents': - raise StopIteration - else: - raise - return self.device.snap(1) - - - -class SaneDev: - """Class representing a SANE device. - Methods: - start() -- initiate a scan, using the current settings - snap() -- snap a picture, returning an Image object - arr_snap() -- snap a picture, returning a numarray object - cancel() -- cancel an in-progress scanning operation - fileno() -- return the file descriptor for the scanner (handy for select) - - Also available, but rather low-level: - get_parameters() -- get the current parameter settings of the device - get_options() -- return a list of tuples describing all the options. - - Attributes: - optlist -- list of option names - - You can also access an option name to retrieve its value, and to - set it. For example, if one option has a .name attribute of - imagemode, and scanner is a SaneDev object, you can do: - print scanner.imagemode - scanner.imagemode = 'Full frame' - scanner.['imagemode'] returns the corresponding Option object. - """ - def __init__(self, devname): - d=self.__dict__ - d['sane_signature'] = self._getSaneSignature(devname) - d['scanner_model'] = d['sane_signature'][1:3] - d['dev'] = _sane._open(devname) - self.__load_option_dict() - - def _getSaneSignature(self, devname): - devices = get_devices() - if not devices: - raise RuntimeError('no scanner available') - for dev in devices: - if devname == dev[0]: - return dev - raise RuntimeError('no such scan device "%s"' % devname) - - def __load_option_dict(self): - d=self.__dict__ - d['opt']={} - optlist=d['dev'].get_options() - for t in optlist: - o=Option(t, self) - if o.type!=TYPE_GROUP: - d['opt'][o.py_name]=o - - def __setattr__(self, key, value): - dev=self.__dict__['dev'] - optdict=self.__dict__['opt'] - if not optdict.has_key(key): - self.__dict__[key]=value ; return - opt=optdict[key] - if opt.type==TYPE_GROUP: - raise AttributeError, "Groups can't be set: "+key - if not _sane.OPTION_IS_ACTIVE(opt.cap): - raise AttributeError, 'Inactive option: '+key - if not _sane.OPTION_IS_SETTABLE(opt.cap): - raise AttributeError, "Option can't be set by software: "+key - if type(value) == int and opt.type == TYPE_FIXED: - # avoid annoying errors of backend if int is given instead float: - value = float(value) - self.last_opt = dev.set_option(opt.index, value) - # do binary AND to find if we have to reload options: - if self.last_opt & INFO_RELOAD_OPTIONS: - self.__load_option_dict() - - def __getattr__(self, key): - dev=self.__dict__['dev'] - optdict=self.__dict__['opt'] - if key=='optlist': - return self.opt.keys() - if key=='area': - return (self.tl_x, self.tl_y),(self.br_x, self.br_y) - if not optdict.has_key(key): - raise AttributeError, 'No such attribute: '+key - opt=optdict[key] - if opt.type==TYPE_BUTTON: - raise AttributeError, "Buttons don't have values: "+key - if opt.type==TYPE_GROUP: - raise AttributeError, "Groups don't have values: "+key - if not _sane.OPTION_IS_ACTIVE(opt.cap): - raise AttributeError, 'Inactive option: '+key - value = dev.get_option(opt.index) - return value - - def __getitem__(self, key): - return self.opt[key] - - def get_parameters(self): - """Return a 5-tuple holding all the current device settings: - (format, last_frame, (pixels_per_line, lines), depth, bytes_per_line) - -- format is one of 'L' (grey), 'RGB', 'R' (red), 'G' (green), 'B' (blue). -- last_frame [bool] indicates if this is the last frame of a multi frame image -- (pixels_per_line, lines) specifies the size of the scanned image (x,y) -- lines denotes the number of scanlines per frame -- depth gives number of pixels per sample -""" - return self.dev.get_parameters() - - def get_options(self): - "Return a list of tuples describing all the available options" - return self.dev.get_options() - - def start(self): - "Initiate a scanning operation" - return self.dev.start() - - def cancel(self): - "Cancel an in-progress scanning operation" - return self.dev.cancel() - - def snap(self, no_cancel=0): - "Snap a picture, returning a PIL image object with the results" - (mode, last_frame, - (xsize, ysize), depth, bytes_per_line) = self.get_parameters() - if mode in ['gray', 'red', 'green', 'blue']: - format = 'L' - elif mode == 'color': - format = 'RGB' - else: - raise ValueError('got unknown "mode" from self.get_parameters()') - im=Image.new(format, (xsize,ysize)) - self.dev.snap( im.im.id, no_cancel ) - return im - - def scan(self): - self.start() - return self.snap() - - def multi_scan(self): - return _SaneIterator(self) - - def arr_snap(self, multipleOf=1): - """Snap a picture, returning a numarray object with the results. - By default the resulting array has the same number of pixels per - line as specified in self.get_parameters()[2][0] - However sometimes it is necessary to obtain arrays where - the number of pixels per line is e.g. a multiple of 4. This can then - be achieved with the option 'multipleOf=4'. So if the scanner - scanned 34 pixels per line, you will obtain an array with 32 pixels - per line. - """ - (mode, last_frame, (xsize, ysize), depth, bpl) = self.get_parameters() - if not mode in ['gray', 'red', 'green', 'blue']: - raise RuntimeError('arr_snap() only works with monochrome images') - if multipleOf < 1: - raise ValueError('option "multipleOf" must be a positive number') - elif multipleOf > 1: - pixels_per_line = xsize - divmod(xsize, 4)[1] - else: - pixels_per_line = xsize - return self.dev.arr_snap(pixels_per_line) - - def arr_scan(self, multipleOf=1): - self.start() - return self.arr_snap(multipleOf=multipleOf) - - def fileno(self): - "Return the file descriptor for the scanning device" - return self.dev.fileno() - - def close(self): - self.dev.close() - - -def open(devname): - "Open a device for scanning" - new=SaneDev(devname) - return new diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt deleted file mode 100755 index db86938e313..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/sanedoc.txt +++ /dev/null @@ -1,294 +0,0 @@ -The _sane_ module is an Python interface to the SANE (Scanning is Now -Easy) library, which provides access to various raster scanning -devices such as flatbed scanners and digital cameras. For more -information about SANE, consult the SANE Web site at -http://www.mostang.com/sane/ . Note that this -documentation doesn't duplicate all the information in the SANE -documentation, which you must also consult to get a complete -understanding. - -This module has been originally developed by A.M. Kuchling (amk1@erols.com), -now development has been taken over by Ralph Heinkel (rheinkel-at-email.de). -If you write to me please make sure to have the word 'SANE' or 'sane' in -the subject of your mail, otherwise it might be classified as spam in the -future. - - -The module exports two object types, a bunch of constants, and two -functions. - -get_devices() - Return a list of 4-tuples containing the available scanning - devices. Each tuple contains 4 strings: the device name, suitable for - passing to _open()_; the device's vendor; the model; and the type of - device, such as 'virtual device' or 'video camera'. - - >>> import sane ; sane.get_devices() - [('epson:libusb:001:004', 'Epson', 'GT-8300', 'flatbed scanner')] - -open(devicename) - Open a device, given a string containing its name. SANE - devices have names like 'epson:libusb:001:004'. If the attempt - to open the device fails, a _sane.error_ exception will be raised. If - there are no problems, a SaneDev object will be returned. - As an easy way to open the scanner (if only one is available) just type - >>> sane.open(sane.get_devices()[0][0]) - - -SaneDev objects -=============== - -The basic process of scanning an image consists of getting a SaneDev -object for the device, setting various parameters, starting the scan, -and then reading the image data. Images are composed of one or more -frames; greyscale and one-pass colour scanners return a single frame -containing all the image data, but 3-pass scanners will usually return -3 frames, one for each of the red, green, blue channels. - -Methods: --------- -fileno() - Returns a file descriptor for the scanning device. This - method's existence means that SaneDev objects can be used by the - select module. - -get_parameters() - Return a tuple containing information about the current settings of - the device and the current frame: (format, last_frame, - pixels_per_line, lines, depth, bytes_per_line). - - mode -- 'gray' for greyscale image, 'color' for RGB image, or - one of 'red', 'green', 'blue' if the image is a single - channel of an RGB image (from PIL's point of view, - this is equivalent to 'L'). - last_frame -- A Boolean value, which is true if this is the - last frame of the image, and false otherwise. - pixels_per_line -- Width of the frame. - lines -- Height of the frame. - depth -- Depth of the image, measured in bits. SANE will only - allow using 8, 16, or 24-bit depths. - bytes_per_line -- Bytes required to store a single line of - data, as computed from pixels_per_line and depth. - -start() - Start a scan. This function must be called before the - _snap()_ method can be used. - -cancel() - Cancel a scan already in progress. - -snap(no_cancel=0) - Snap a single frame of data, returning a PIL Image object - containing the data. If no_cancel is false, the Sane library function - sane_cancel is called after the scan. This is reasonable in most cases, - but may cause backends for duplex ADF scanners to drop the backside image, - when snap() is called for the front side image. If no_cancel is true, - cancel() should be called manually, after all scans are finished. - -scan() - This is just a shortcut for s.start(); s.snap() - Returns a PIL image - -multi_scan() - This method returns an iterator. It is intended to be used for - scanning with an automatic document feeder. The next() method of the - iterator tries to start a scan. If this is successful, it returns a - PIL Image object, like scan(); if the document feeder runs out of - paper, it raises StopIteration, thereby signaling that the sequence - is ran out of items. - -arr_snap(multipleOf=1) - same as snap, but the result is a NumArray object. (Not that - num_array must be installed already at compilation time, otherwise - this feature will not be activated). - By default the resulting array has the same number of pixels per - line as specified in self.get_parameters()[2][0] - However sometimes it is necessary to obtain arrays where - the number of pixels per line is e.g. a multiple of 4. This can then - be achieved with the option 'multipleOf=4'. So if the scanner - scanned 34 pixels per line, you will obtain an array with 32 pixels - per line. - Note that this only works with monochrome images (e.g. gray-scales) - -arr_scan(multipleOf=1) - This is just a shortcut for s.start(); s.arr_snap(multipleOf=1) - Returns a NumArray object - -close() - Closes the object. - - -Attributes: ------------ -SaneDev objects have a few fixed attributes which are always -available, and a larger collection of attributes which vary depending -on the device. An Epson 1660 photo scanner has attributes like -'mode', 'depth', etc. -Another (pseudo scanner), the _pnm:0_ device, takes a PNM file and -simulates a scanner using the image data; a SaneDev object -representing the _pnm:0_ device therefore has a _filename_ attribute -which can be changed to specify the filename, _contrast_ and -_brightness_ attributes to modify the returned image, and so forth. - -The values of the scanner options may be an integer, floating-point -value, or string, depending on the nature of the option. - -sane_signature - The tuple for this scandev that is returned by sane.get_devices() - e.g. ('epson:libusb:001:006', 'Epson', 'GT-8300', 'flatbed scanner') - -scanner_model - same as sane_signature[1:3], i.e. ('Epson', 'GT-8300') for the case above. - -optlist - A list containing the all the options supported by this device. - - >>> import sane ; s=sane.open('epson:libusb:001:004') ; s.optlist - ['focus_position', 'color_correction', 'sharpness', ...., 'br_x'] - -A closer look at all options listed in s.optlist can be obtained -through the SaneOption objects. - -SaneOption objects -================== - -SANE's option handling is its most elaborate subsystem, intended to -allow automatically generating dialog boxes and prompts for user -configuration of the scanning device. The SaneOption object can be -used to get a human-readable name and description for an option, the -units to use, and what the legal values are. No information about the -current value of the option is available; for that, read the -corresponding attribute of a SaneDev object. - -This documentation does not explain all the details of SANE's option -handling; consult the SANE documentation for all the details. - -A scandevice option is accessed via __getitem__. For example -s['mode'] returns the option descriptor for the mode-option which -controls whether the scanner works in color, grayscale, or b/w mode. - ->>> s['mode'] -Name: mode -Cur value: Color -Index: 2 -Title: Scan mode -Desc: Selects the scan mode (e.g., lineart, monochrome, or color). -Type: TYPE_STRING -Unit: UNIT_NONE -Constr: ['Binary', 'Gray', 'Color'] -active: yes -settable: yes - -In order to change 'mode' to 'gray', just type: ->>> s.mode = 'gray' - - -With the attributes and methods of sane-option objects it is possible -to access individual option values: - -is_active() - Returns true if the option is active. - -is_settable() - Returns true if the option can be set under software control. - - -Attributes: - -cap - An integer containing various flags about the object's - capabilities; whether it's active, whether it's settable, etc. Also - available as the _capability_ attribute. - -constraint - The constraint placed on the value of this option. If it's - _None_, there are essentially no constraint of the value. It may also - be a list of integers or strings, in which case the value *must* be - one of the possibilities in the list. Numeric values may have a - 3-tuple as the constraint; this 3-tuple contains _(minimum, maximum, - increment)_, and the value must be in the defined range. - -desc - A lengthy description of what the option does; it may be shown - to the user for clarification. - -index - An integer giving the option's index in the option list. - -name - A short name for the option, as it comes from the sane-backend. - -py_name - The option's name, as a legal Python identifier. The name - attribute may contain the '-' character, so it will be converted to - '_' for the py_name attribute. - -size - For a string-valued option, this is the maximum length allowed. - -title - A single-line string that can be used as a title string. - -type - A constant giving the type of this option: will be one of the following - constants found in the SANE module: - TYPE_BOOL - TYPE_INT - TYPE_FIXED - TYPE_STRING - TYPE_BUTTON - TYPE_GROUP - -unit - For numeric-valued options, this is a constant representing - the unit used for this option. It will be one of the following - constants found in the SANE module: - UNIT_NONE - UNIT_PIXEL - UNIT_BIT - UNIT_MM - UNIT_DPI - UNIT_PERCENT - - - -Example us usage: -================= ->>> import sane ->>> print 'SANE version:', sane.init() ->>> print 'Available devices=', sane.get_devices() -SANE version: (16777230, 1, 0, 14) ->>> s = sane.open(sane.get_devices()[0][0]) ->>> print 'Device parameters:', s.get_parameters() -Device parameters: ('L', 1, (424, 585), 1, 53) ->>> print s.resolution -50 - -## In order to scan a color image into a PIL object: ->>> s.mode = 'color' ->>> s.start() ->>> img = s.snap() ->>> img.show() - - -## In order to obtain a 16-bit grayscale image at 100DPI in a numarray object -## with bottom-right coordinates set to (160, 120) [in millimeter] : ->>> s.mode = 'gray' ->>> s.br_x=160. ; s.br_y=120. ->>> s.resolution = 100 ->>> s.depth=16 ->>> s.start() ->>> s.get_parameters()[2] # just check the size -(624, 472) ->>> arr16 = s.arr_snap() ->>> arr16 -array([[63957, 64721, 65067, ..., 65535, 65535, 65535], - [63892, 64342, 64236, ..., 65535, 65535, 65535], - [64286, 64248, 64705, ..., 65535, 65535, 65535], - ..., - [65518, 65249, 65058, ..., 65535, 65535, 65535], - [64435, 65047, 65081, ..., 65535, 65535, 65535], - [65309, 65438, 65535, ..., 65535, 65535, 65535]], type=UInt16) ->>> arr16.shape # inverse order of coordinates, first y, then x! -(472, 624) - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py deleted file mode 100755 index 3837198ec94..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Sane/setup.py +++ /dev/null @@ -1,24 +0,0 @@ -from distutils.core import setup, Extension - -PIL_BUILD_DIR = '..' -PIL_IMAGING_DIR = PIL_BUILD_DIR+'/libImaging' - -defs = [] -try: - import numarray - defs.append(('WITH_NUMARRAY',None)) -except ImportError: - pass - -sane = Extension('_sane', - include_dirs = [PIL_IMAGING_DIR], - libraries = ['sane'], - library_dirs = [PIL_IMAGING_DIR], - define_macros = defs, - sources = ['_sane.c']) - -setup (name = 'pysane', - version = '2.0', - description = 'This is the pysane package', - py_modules = ['sane'], - ext_modules = [sane]) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README deleted file mode 100755 index a09b0621a1c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/README +++ /dev/null @@ -1,83 +0,0 @@ -------- -Scripts -------- - -This directory contains a number of more or less trivial utilities -and demo programs. - -Comments and contributions are welcome. - - - --------------------------------------------------------------------- -pildriver.py (by Eric S. Raymond) - -A class implementing an image-processing calculator for scripts. -Parses lists of commnds (or, called interactively, command-line -arguments) into image loads, transformations, and saves. - --------------------------------------------------------------------- -viewer.py - -A simple image viewer. Can display all file formats handled by -PIL. Transparent images are properly handled. - --------------------------------------------------------------------- -thresholder.py - -A simple utility that demonstrates how a transparent 1-bit overlay -can be used to show the current thresholding of an 8-bit image. - --------------------------------------------------------------------- -enhancer.py - -Illustrates the ImageEnhance module. Drag the sliders to modify the -images. This might be very slow on some platforms, depending on the -Tk version. - --------------------------------------------------------------------- -painter.py - -Illustrates how a painting program could be based on PIL and Tk. -Press the left mouse button and drag over the image to remove the -colour. Some clever tricks have been used to get decent performance -when updating the screen; see the sources for details. - --------------------------------------------------------------------- -player.py - -A simple image sequence player. You can use either a sequence format -like FLI/FLC, GIF, or ARG, or give a number of images which are -interpreted as frames in a sequence. All frames must have the same -size. - --------------------------------------------------------------------- -gifmaker.py - -Convert a sequence file to a GIF animation. - -Note that the GIF encoder provided with this release of PIL writes -uncompressed GIF files only, so the resulting animations are rather -large compared with these created by other tools. - --------------------------------------------------------------------- -explode.py - -Split a sequence file into individual frames. - --------------------------------------------------------------------- -image2py.py - -Convert an image to a Python module containing an IMAGE variable. -Note that the module using the module must include JPEG and ZIP -decoders, unless the -u option is used. - --------------------------------------------------------------------- -olesummary.py - -Uses the OleFileIO module to dump the summary information from an OLE -structured storage file. This works with most OLE files, including -Word documents, FlashPix images, etc. - -Note that datetime fields currently show the number of seconds since -January 1st, 1601. diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py deleted file mode 100755 index 957b51c8d91..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/enhancer.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# this demo script creates four windows containing an image and a slider. -# drag the slider to modify the image. -# - -from Tkinter import * -from PIL import Image, ImageTk, ImageEnhance -import sys - -# -# enhancer widget - -class Enhance(Frame): - def __init__(self, master, image, name, enhancer, lo, hi): - Frame.__init__(self, master) - - # set up the image - self.tkim = ImageTk.PhotoImage(image.mode, image.size) - self.enhancer = enhancer(image) - self.update("1.0") # normalize - - # image window - Label(self, image=self.tkim).pack() - - # scale - s = Scale(self, label=name, orient=HORIZONTAL, - from_=lo, to=hi, resolution=0.01, - command=self.update) - s.set(self.value) - s.pack() - - def update(self, value): - self.value = eval(value) - self.tkim.paste(self.enhancer.enhance(self.value)) - -# -# main - -root = Tk() - -im = Image.open(sys.argv[1]) - -im.thumbnail((200, 200)) - -Enhance(root, im, "Color", ImageEnhance.Color, 0.0, 4.0).pack() -Enhance(Toplevel(), im, "Sharpness", ImageEnhance.Sharpness, -2.0, 2.0).pack() -Enhance(Toplevel(), im, "Brightness", ImageEnhance.Brightness, -1.0, 3.0).pack() -Enhance(Toplevel(), im, "Contrast", ImageEnhance.Contrast, -1.0, 3.0).pack() - -root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py deleted file mode 100755 index a336f06990c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/explode.py +++ /dev/null @@ -1,107 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# split an animation into a number of frame files -# - -from PIL import Image -import os, string, sys - -class Interval: - - def __init__(self, interval = "0"): - - self.setinterval(interval) - - def setinterval(self, interval): - - self.hilo = [] - - for s in string.split(interval, ","): - if not string.strip(s): - continue - try: - v = string.atoi(s) - if v < 0: - lo, hi = 0, -v - else: - lo = hi = v - except ValueError: - i = string.find(s, "-") - lo, hi = string.atoi(s[:i]), string.atoi(s[i+1:]) - - self.hilo.append((hi, lo)) - - if not self.hilo: - self.hilo = [(sys.maxint, 0)] - - def __getitem__(self, index): - - for hi, lo in self.hilo: - if hi >= index >= lo: - return 1 - return 0 - -# -------------------------------------------------------------------- -# main program - -html = 0 - -if sys.argv[1:2] == ["-h"]: - html = 1 - del sys.argv[1] - -if not sys.argv[2:]: - print - print "Syntax: python explode.py infile template [range]" - print - print "The template argument is used to construct the names of the" - print "individual frame files. The frames are numbered file001.ext," - print "file002.ext, etc. You can insert %d to control the placement" - print "and syntax of the frame number." - print - print "The optional range argument specifies which frames to extract." - print "You can give one or more ranges like 1-10, 5, -15 etc. If" - print "omitted, all frames are extracted." - sys.exit(1) - -infile = sys.argv[1] -outfile = sys.argv[2] - -frames = Interval(string.join(sys.argv[3:], ",")) - -try: - # check if outfile contains a placeholder - outfile % 1 -except TypeError: - file, ext = os.path.splitext(outfile) - outfile = file + "%03d" + ext - -ix = 1 - -im = Image.open(infile) - -if html: - file, ext = os.path.splitext(outfile) - html = open(file+".html", "w") - html.write("\n\n") - -while 1: - - if frames[ix]: - im.save(outfile % ix) - print outfile % ix - - if html: - html.write("
\n" % outfile % ix) - - try: - im.seek(ix) - except EOFError: - break - - ix = ix + 1 - -if html: - html.write("\n\n") diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py deleted file mode 100755 index 95524eacc1c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/gifmaker.py +++ /dev/null @@ -1,135 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# convert sequence format to GIF animation -# -# history: -# 97-01-03 fl created -# -# Copyright (c) Secret Labs AB 1997. All rights reserved. -# Copyright (c) Fredrik Lundh 1997. -# -# See the README file for information on usage and redistribution. -# - -# -# For special purposes, you can import this module and call -# the makedelta or compress functions yourself. For example, -# if you have an application that generates a sequence of -# images, you can convert it to a GIF animation using some- -# thing like the following code: -# -# import Image -# import gifmaker -# -# sequence = [] -# -# # generate sequence -# for i in range(100): -# im = -# sequence.append(im) -# -# # write GIF animation -# fp = open("out.gif", "wb") -# gifmaker.makedelta(fp, sequence) -# fp.close() -# -# Alternatively, use an iterator to generate the sequence, and -# write data directly to a socket. Or something... -# - -from PIL import Image, ImageChops -import string - -from PIL.GifImagePlugin import getheader, getdata - -# -------------------------------------------------------------------- -# sequence iterator - -class image_sequence: - def __init__(self, im): - self.im = im - def __getitem__(self, ix): - try: - if ix: - self.im.seek(ix) - return self.im - except EOFError: - raise IndexError # end of sequence - -# -------------------------------------------------------------------- -# straightforward delta encoding - -def makedelta(fp, sequence): - """Convert list of image frames to a GIF animation file""" - - frames = 0 - - previous = None - - for im in sequence: - - # - # FIXME: write graphics control block before each frame - - if not previous: - - # global header - for s in getheader(im) + getdata(im): - fp.write(s) - - else: - - # delta frame - delta = ImageChops.subtract_modulo(im, previous) - - bbox = delta.getbbox() - - if bbox: - - # compress difference - for s in getdata(im.crop(bbox), offset = bbox[:2]): - fp.write(s) - - else: - # FIXME: what should we do in this case? - pass - - previous = im.copy() - - frames = frames + 1 - - fp.write(";") - - return frames - -# -------------------------------------------------------------------- -# main hack - -def compress(infile, outfile): - - # open input image, and force loading of first frame - im = Image.open(infile) - im.load() - - # open output file - fp = open(outfile, "wb") - - seq = image_sequence(im) - - makedelta(fp, seq) - - fp.close() - - -if __name__ == "__main__": - - import sys - - if len(sys.argv) < 3: - print "GIFMAKER -- create GIF animations" - print "Usage: gifmaker infile outfile" - sys.exit(1) - - compress(sys.argv[1], sys.argv[2]) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py deleted file mode 100755 index efe307386ff..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/painter.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# this demo script illustrates pasting into an already displayed -# photoimage. note that the current version of Tk updates the whole -# image everytime we paste, so to get decent performance, we split -# the image into a set of tiles. -# - -from Tkinter import * -from PIL import Image, ImageTk -import sys - -# -# painter widget - -class PaintCanvas(Canvas): - def __init__(self, master, image): - Canvas.__init__(self, master, width=image.size[0], height=image.size[1]) - - # fill the canvas - self.tile = {} - self.tilesize = tilesize = 32 - xsize, ysize = image.size - for x in range(0, xsize, tilesize): - for y in range(0, ysize, tilesize): - box = x, y, min(xsize, x+tilesize), min(ysize, y+tilesize) - tile = ImageTk.PhotoImage(image.crop(box)) - self.create_image(x, y, image=tile, anchor=NW) - self.tile[(x,y)] = box, tile - - self.image = image - - self.bind("", self.paint) - - def paint(self, event): - xy = event.x - 10, event.y - 10, event.x + 10, event.y + 10 - im = self.image.crop(xy) - - # process the image in some fashion - im = im.convert("L") - - self.image.paste(im, xy) - self.repair(xy) - - def repair(self, box): - # update canvas - dx = box[0] % self.tilesize - dy = box[1] % self.tilesize - for x in range(box[0]-dx, box[2]+1, self.tilesize): - for y in range(box[1]-dy, box[3]+1, self.tilesize): - try: - xy, tile = self.tile[(x, y)] - tile.paste(self.image.crop(xy)) - except KeyError: - pass # outside the image - self.update_idletasks() - -# -# main - -root = Tk() - -im = Image.open(sys.argv[1]) - -if im.mode != "RGB": - im = im.convert("RGB") - -PaintCanvas(root, im).pack() - -root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py deleted file mode 100755 index 1c688f7c9b0..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilconvert.py +++ /dev/null @@ -1,96 +0,0 @@ -#! /usr/local/bin/python -# -# The Python Imaging Library. -# $Id$ -# -# convert image files -# -# History: -# 0.1 96-04-20 fl Created -# 0.2 96-10-04 fl Use draft mode when converting images -# 0.3 96-12-30 fl Optimize output (PNG, JPEG) -# 0.4 97-01-18 fl Made optimize an option (PNG, JPEG) -# 0.5 98-12-30 fl Fixed -f option (from Anthony Baxter) -# - -import site -import getopt, string, sys - -from PIL import Image - -def usage(): - print "PIL Convert 0.5/1998-12-30 -- convert image files" - print "Usage: pilconvert [option] infile outfile" - print - print "Options:" - print - print " -c convert to format (default is given by extension)" - print - print " -g convert to greyscale" - print " -p convert to palette image (using standard palette)" - print " -r convert to rgb" - print - print " -o optimize output (trade speed for size)" - print " -q set compression quality (0-100, JPEG only)" - print - print " -f list supported file formats" - sys.exit(1) - -if len(sys.argv) == 1: - usage() - -try: - opt, argv = getopt.getopt(sys.argv[1:], "c:dfgopq:r") -except getopt.error, v: - print v - sys.exit(1) - -format = None -convert = None - -options = { } - -for o, a in opt: - - if o == "-f": - Image.init() - id = Image.ID[:] - id.sort() - print "Supported formats (* indicates output format):" - for i in id: - if Image.SAVE.has_key(i): - print i+"*", - else: - print i, - sys.exit(1) - - elif o == "-c": - format = a - - if o == "-g": - convert = "L" - elif o == "-p": - convert = "P" - elif o == "-r": - convert = "RGB" - - elif o == "-o": - options["optimize"] = 1 - elif o == "-q": - options["quality"] = string.atoi(a) - -if len(argv) != 2: - usage() - -try: - im = Image.open(argv[0]) - if convert and im.mode != convert: - im.draft(convert, im.size) - im = im.convert(convert) - if format: - apply(im.save, (argv[1], format), options) - else: - apply(im.save, (argv[1],), options) -except: - print "cannot convert image", - print "(%s:%s)" % (sys.exc_type, sys.exc_value) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py deleted file mode 100755 index 5dd575a3fd6..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pildriver.py +++ /dev/null @@ -1,524 +0,0 @@ -#!/usr/bin/env python -"""PILdriver, an image-processing calculator using PIL. - -An instance of class PILDriver is essentially a software stack machine -(Polish-notation interpreter) for sequencing PIL image -transformations. The state of the instance is the interpreter stack. - -The only method one will normally invoke after initialization is the -`execute' method. This takes an argument list of tokens, pushes them -onto the instance's stack, and then tries to clear the stack by -successive evaluation of PILdriver operators. Any part of the stack -not cleaned off persists and is part of the evaluation context for -the next call of the execute method. - -PILDriver doesn't catch any exceptions, on the theory that these -are actually diagnostic information that should be interpreted by -the calling code. - -When called as a script, the command-line arguments are passed to -a PILDriver instance. If there are no command-line arguments, the -module runs an interactive interpreter, each line of which is split into -space-separated tokens and passed to the execute method. - -In the method descriptions below, a first line beginning with the string -`usage:' means this method can be invoked with the token that follows -it. Following <>-enclosed arguments describe how the method interprets -the entries on the stack. Each argument specification begins with a -type specification: either `int', `float', `string', or `image'. - -All operations consume their arguments off the stack (use `dup' to -keep copies around). Use `verbose 1' to see the stack state displayed -before each operation. - -Usage examples: - - `show crop 0 0 200 300 open test.png' loads test.png, crops out a portion -of its upper-left-hand corner and displays the cropped portion. - - `save rotated.png rotate 30 open test.tiff' loads test.tiff, rotates it -30 degrees, and saves the result as rotated.png (in PNG format). -""" -# by Eric S. Raymond -# $Id$ - -# TO DO: -# 1. Add PILFont capabilities, once that's documented. -# 2. Add PILDraw operations. -# 3. Add support for composing and decomposing multiple-image files. -# - -from PIL import Image -import string - -class PILDriver: - - verbose = 0 - - def do_verbose(self): - """usage: verbose - - Set verbosity flag from top of stack. - """ - self.verbose = self.do_pop() - - # The evaluation stack (internal only) - - stack = [] # Stack of pending operations - - def push(self, item): - "Push an argument onto the evaluation stack." - self.stack = [item] + self.stack - - def top(self): - "Return the top-of-stack element." - return self.stack[0] - - # Stack manipulation (callable) - - def do_clear(self): - """usage: clear - - Clear the stack. - """ - self.stack = [] - - def do_pop(self): - """usage: pop - - Discard the top element on the stack. - """ - top = self.stack[0] - self.stack = self.stack[1:] - return top - - def do_dup(self): - """usage: dup - - Duplicate the top-of-stack item. - """ - if hasattr(self, 'format'): # If it's an image, do a real copy - dup = self.stack[0].copy() - else: - dup = self.stack[0] - self.stack = [dup] + self.stack - - def do_swap(self): - """usage: swap - - Swap the top-of-stack item with the next one down. - """ - self.stack = [self.stack[1], self.stack[0]] + self.stack[2:] - - # Image module functions (callable) - - def do_new(self): - """usage: new : - - Create and push a greyscale image of given size and color. - """ - xsize = int(self.do_pop()) - ysize = int(self.do_pop()) - color = int(self.do_pop()) - self.push(Image.new("L", (xsize, ysize), color)) - - def do_open(self): - """usage: open - - Open the indicated image, read it, push the image on the stack. - """ - self.push(Image.open(self.do_pop())) - - def do_blend(self): - """usage: blend - - Replace two images and an alpha with the blended image. - """ - image1 = self.do_pop() - image2 = self.do_pop() - alpha = float(self.do_pop()) - self.push(Image.blend(image1, image2, alpha)) - - def do_composite(self): - """usage: composite - - Replace two images and a mask with their composite. - """ - image1 = self.do_pop() - image2 = self.do_pop() - mask = self.do_pop() - self.push(Image.composite(image1, image2, mask)) - - def do_merge(self): - """usage: merge [ [ []]] - - Merge top-of stack images in a way described by the mode. - """ - mode = self.do_pop() - bandlist = [] - for band in mode: - bandlist.append(self.do_pop()) - self.push(Image.merge(mode, bandlist)) - - # Image class methods - - def do_convert(self): - """usage: convert - - Convert the top image to the given mode. - """ - mode = self.do_pop() - image = self.do_pop() - self.push(image.convert(mode)) - - def do_copy(self): - """usage: copy - - Make and push a true copy of the top image. - """ - self.dup() - - def do_crop(self): - """usage: crop - - Crop and push a rectangular region from the current image. - """ - left = int(self.do_pop()) - upper = int(self.do_pop()) - right = int(self.do_pop()) - lower = int(self.do_pop()) - image = self.do_pop() - self.push(image.crop((left, upper, right, lower))) - - def do_draft(self): - """usage: draft - - Configure the loader for a given mode and size. - """ - mode = self.do_pop() - xsize = int(self.do_pop()) - ysize = int(self.do_pop()) - self.push(self.draft(mode, (xsize, ysize))) - - def do_filter(self): - """usage: filter - - Process the top image with the given filter. - """ - import ImageFilter - filter = eval("ImageFilter." + string.upper(self.do_pop())) - image = self.do_pop() - self.push(image.filter(filter)) - - def do_getbbox(self): - """usage: getbbox - - Push left, upper, right, and lower pixel coordinates of the top image. - """ - bounding_box = self.do_pop().getbbox() - self.push(bounding_box[3]) - self.push(bounding_box[2]) - self.push(bounding_box[1]) - self.push(bounding_box[0]) - - def do_getextrema(self): - """usage: extrema - - Push minimum and maximum pixel values of the top image. - """ - extrema = self.do_pop().extrema() - self.push(extrema[1]) - self.push(extrema[0]) - - def do_offset(self): - """usage: offset - - Offset the pixels in the top image. - """ - xoff = int(self.do_pop()) - yoff = int(self.do_pop()) - image = self.do_pop() - self.push(image.offset(xoff, yoff)) - - def do_paste(self): - """usage: paste - - Paste figure image into ground with upper left at given offsets. - """ - figure = self.do_pop() - xoff = int(self.do_pop()) - yoff = int(self.do_pop()) - ground = self.do_pop() - if figure.mode == "RGBA": - ground.paste(figure, (xoff, yoff), figure) - else: - ground.paste(figure, (xoff, yoff)) - self.push(ground) - - def do_resize(self): - """usage: resize - - Resize the top image. - """ - ysize = int(self.do_pop()) - xsize = int(self.do_pop()) - image = self.do_pop() - self.push(image.resize((xsize, ysize))) - - def do_rotate(self): - """usage: rotate - - Rotate image through a given angle - """ - angle = int(self.do_pop()) - image = self.do_pop() - self.push(image.rotate(angle)) - - def do_save(self): - """usage: save - - Save image with default options. - """ - filename = self.do_pop() - image = self.do_pop() - image.save(filename) - - def do_save2(self): - """usage: save2 - - Save image with specified options. - """ - filename = self.do_pop() - options = self.do_pop() - image = self.do_pop() - image.save(filename, None, options) - - def do_show(self): - """usage: show - - Display and pop the top image. - """ - self.do_pop().show() - - def do_thumbnail(self): - """usage: thumbnail - - Modify the top image in the stack to contain a thumbnail of itself. - """ - ysize = int(self.do_pop()) - xsize = int(self.do_pop()) - self.top().thumbnail((xsize, ysize)) - - def do_transpose(self): - """usage: transpose - - Transpose the top image. - """ - transpose = string.upper(self.do_pop()) - image = self.do_pop() - self.push(image.transpose(transpose)) - - # Image attributes - - def do_format(self): - """usage: format - - Push the format of the top image onto the stack. - """ - self.push(self.pop().format) - - def do_mode(self): - """usage: mode - - Push the mode of the top image onto the stack. - """ - self.push(self.pop().mode) - - def do_size(self): - """usage: size - - Push the image size on the stack as (y, x). - """ - size = self.pop().size - self.push(size[0]) - self.push(size[1]) - - # ImageChops operations - - def do_invert(self): - """usage: invert - - Invert the top image. - """ - import ImageChops - self.push(ImageChops.invert(self.do_pop())) - - def do_lighter(self): - """usage: lighter - - Pop the two top images, push an image of the lighter pixels of both. - """ - import ImageChops - image1 = self.do_pop() - image2 = self.do_pop() - self.push(ImageChops.lighter(image1, image2)) - - def do_darker(self): - """usage: darker - - Pop the two top images, push an image of the darker pixels of both. - """ - import ImageChops - image1 = self.do_pop() - image2 = self.do_pop() - self.push(ImageChops.darker(image1, image2)) - - def do_difference(self): - """usage: difference - - Pop the two top images, push the difference image - """ - import ImageChops - image1 = self.do_pop() - image2 = self.do_pop() - self.push(ImageChops.difference(image1, image2)) - - def do_multiply(self): - """usage: multiply - - Pop the two top images, push the multiplication image. - """ - import ImageChops - image1 = self.do_pop() - image2 = self.do_pop() - self.push(ImageChops.multiply(image1, image2)) - - def do_screen(self): - """usage: screen - - Pop the two top images, superimpose their inverted versions. - """ - import ImageChops - image2 = self.do_pop() - image1 = self.do_pop() - self.push(ImageChops.screen(image1, image2)) - - def do_add(self): - """usage: add - - Pop the two top images, produce the scaled sum with offset. - """ - import ImageChops - image1 = self.do_pop() - image2 = self.do_pop() - scale = float(self.do_pop()) - offset = int(self.do_pop()) - self.push(ImageChops.add(image1, image2, scale, offset)) - - def do_subtract(self): - """usage: subtract - - Pop the two top images, produce the scaled difference with offset. - """ - import ImageChops - image1 = self.do_pop() - image2 = self.do_pop() - scale = float(self.do_pop()) - offset = int(self.do_pop()) - self.push(ImageChops.subtract(image1, image2, scale, offset)) - - # ImageEnhance classes - - def do_color(self): - """usage: color - - Enhance color in the top image. - """ - import ImageEnhance - factor = float(self.do_pop()) - image = self.do_pop() - enhancer = ImageEnhance.Color(image) - self.push(enhancer.enhance(factor)) - - def do_contrast(self): - """usage: contrast - - Enhance contrast in the top image. - """ - import ImageEnhance - factor = float(self.do_pop()) - image = self.do_pop() - enhancer = ImageEnhance.Color(image) - self.push(enhancer.enhance(factor)) - - def do_brightness(self): - """usage: brightness - - Enhance brightness in the top image. - """ - import ImageEnhance - factor = float(self.do_pop()) - image = self.do_pop() - enhancer = ImageEnhance.Color(image) - self.push(enhancer.enhance(factor)) - - def do_sharpness(self): - """usage: sharpness - - Enhance sharpness in the top image. - """ - import ImageEnhance - factor = float(self.do_pop()) - image = self.do_pop() - enhancer = ImageEnhance.Color(image) - self.push(enhancer.enhance(factor)) - - # The interpreter loop - - def execute(self, list): - "Interpret a list of PILDriver commands." - list.reverse() - while len(list) > 0: - self.push(list[0]) - list = list[1:] - if self.verbose: - print "Stack: " + `self.stack` - top = self.top() - if type(top) != type(""): - continue; - funcname = "do_" + top - if not hasattr(self, funcname): - continue - else: - self.do_pop() - func = getattr(self, funcname) - func() - -if __name__ == '__main__': - import sys - try: - import readline - except ImportError: - pass # not available on all platforms - - # If we see command-line arguments, interpret them as a stack state - # and execute. Otherwise go interactive. - - driver = PILDriver() - if len(sys.argv[1:]) > 0: - driver.execute(sys.argv[1:]) - else: - print "PILDriver says hello." - while 1: - try: - line = raw_input('pildriver> '); - except EOFError: - print "\nPILDriver says goodbye." - break - driver.execute(string.split(line)) - print driver.stack - -# The following sets edit modes for GNU EMACS -# Local Variables: -# mode:python -# End: diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py deleted file mode 100755 index 6957257965e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfile.py +++ /dev/null @@ -1,94 +0,0 @@ -#! /usr/local/bin/python -# -# The Python Imaging Library. -# $Id$ -# -# a utility to identify image files -# -# this script identifies image files, extracting size and -# pixel mode information for known file formats. Note that -# you don't need the PIL C extension to use this module. -# -# History: -# 0.0 1995-09-01 fl Created -# 0.1 1996-05-18 fl Modified options, added debugging mode -# 0.2 1996-12-29 fl Added verify mode -# 0.3 1999-06-05 fl Don't mess up on class exceptions (1.5.2 and later) -# 0.4 2003-09-30 fl Expand wildcards on Windows; robustness tweaks -# - -import site -import getopt, glob, sys - -from PIL import Image - -if len(sys.argv) == 1: - print "PIL File 0.4/2003-09-30 -- identify image files" - print "Usage: pilfile [option] files..." - print "Options:" - print " -f list supported file formats" - print " -i show associated info and tile data" - print " -v verify file headers" - print " -q quiet, don't warn for unidentified/missing/broken files" - sys.exit(1) - -try: - opt, args = getopt.getopt(sys.argv[1:], "fqivD") -except getopt.error, v: - print v - sys.exit(1) - -verbose = quiet = verify = 0 - -for o, a in opt: - if o == "-f": - Image.init() - id = Image.ID[:] - id.sort() - print "Supported formats:" - for i in id: - print i, - sys.exit(1) - elif o == "-i": - verbose = 1 - elif o == "-q": - quiet = 1 - elif o == "-v": - verify = 1 - elif o == "-D": - Image.DEBUG = Image.DEBUG + 1 - -def globfix(files): - # expand wildcards where necessary - if sys.platform == "win32": - out = [] - for file in files: - if glob.has_magic(file): - out.extend(glob.glob(file)) - else: - out.append(file) - return out - return files - -for file in globfix(args): - try: - im = Image.open(file) - print "%s:" % file, im.format, "%dx%d" % im.size, im.mode, - if verbose: - print im.info, im.tile, - print - if verify: - try: - im.verify() - except: - if not quiet: - print "failed to verify image", - print "(%s:%s)" % (sys.exc_type, sys.exc_value) - except IOError, v: - if not quiet: - print file, "failed:", v - except: - import traceback - if not quiet: - print file, "failed:", "unexpected error" - traceback.print_exc(file=sys.stdout) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py deleted file mode 100755 index df08d4c083e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilfont.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# PIL raster font compiler -# -# history: -# 1997-08-25 fl created -# 2002-03-10 fl use "from PIL import" -# - -VERSION = "0.4" - -import site -import glob, os, sys - -# drivers -from PIL import BdfFontFile -from PIL import PcfFontFile - -if len(sys.argv) <= 1: - print "PILFONT", VERSION, "-- PIL font compiler." - print - print "Usage: pilfont fontfiles..." - print - print "Convert given font files to the PIL raster font format." - print "This version of pilfont supports X BDF and PCF fonts." - sys.exit(1) - -files = [] -for f in sys.argv[1:]: - files = files + glob.glob(f) - -for f in files: - - print f + "...", - - try: - - fp = open(f, "rb") - - try: - p = PcfFontFile.PcfFontFile(fp) - except SyntaxError: - fp.seek(0) - p = BdfFontFile.BdfFontFile(fp) - - p.save(f) - - except (SyntaxError, IOError): - print "failed" - - else: - print "OK" diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py deleted file mode 100755 index a98b39f7d9b..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/pilprint.py +++ /dev/null @@ -1,93 +0,0 @@ -#! /usr/local/bin/python -# -# The Python Imaging Library. -# $Id$ -# -# print image files to postscript printer -# -# History: -# 0.1 1996-04-20 fl Created -# 0.2 1996-10-04 fl Use draft mode when converting. -# 0.3 2003-05-06 fl Fixed a typo or two. -# - -VERSION = "pilprint 0.3/2003-05-05" - -from PIL import Image -from PIL import PSDraw - -letter = ( 1.0*72, 1.0*72, 7.5*72, 10.0*72 ) - -def description(file, image): - import os - title = os.path.splitext(os.path.split(file)[1])[0] - format = " (%dx%d " - if image.format: - format = " (" + image.format + " %dx%d " - return title + format % image.size + image.mode + ")" - -import getopt, os, sys - -if len(sys.argv) == 1: - print "PIL Print 0.2a1/96-10-04 -- print image files" - print "Usage: pilprint files..." - print "Options:" - print " -c colour printer (default is monochrome)" - print " -p print via lpr (default is stdout)" - print " -P same as -p but use given printer" - sys.exit(1) - -try: - opt, argv = getopt.getopt(sys.argv[1:], "cdpP:") -except getopt.error, v: - print v - sys.exit(1) - -printer = None # print to stdout -monochrome = 1 # reduce file size for most common case - -for o, a in opt: - if o == "-d": - # debug: show available drivers - Image.init() - print Image.ID - sys.exit(1) - elif o == "-c": - # colour printer - monochrome = 0 - elif o == "-p": - # default printer channel - printer = "lpr" - elif o == "-P": - # printer channel - printer = "lpr -P%s" % a - -for file in argv: - try: - - im = Image.open(file) - - title = description(file, im) - - if monochrome and im.mode not in ["1", "L"]: - im.draft("L", im.size) - im = im.convert("L") - - if printer: - fp = os.popen(printer, "w") - else: - fp = sys.stdout - - ps = PSDraw.PSDraw(fp) - - ps.begin_document() - ps.setfont("Helvetica-Narrow-Bold", 18) - ps.text((letter[0], letter[3]+24), title) - ps.setfont("Helvetica-Narrow-Bold", 8) - ps.text((letter[0], letter[1]-30), VERSION) - ps.image(letter, im) - ps.end_document() - - except: - print "cannot print image", - print "(%s:%s)" % (sys.exc_type, sys.exc_value) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py deleted file mode 100755 index 9ca4500bfd4..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/player.py +++ /dev/null @@ -1,121 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# - -from Tkinter import * -from PIL import Image, ImageTk -import sys - - -Image.DEBUG = 0 - - -# -------------------------------------------------------------------- -# experimental: support ARG animation scripts - -import ArgImagePlugin - -def applet_hook(animation, images): - app = animation(animation_display, images) - app.run() - -ArgImagePlugin.APPLET_HOOK = applet_hook - -class AppletDisplay: - def __init__(self, ui): - self.__ui = ui - def paste(self, im, bbox): - self.__ui.image.paste(im, bbox) - def update(self): - self.__ui.update_idletasks() - -# -------------------------------------------------------------------- -# an image animation player - -class UI(Label): - - def __init__(self, master, im): - if type(im) == type([]): - # list of images - self.im = im[1:] - im = self.im[0] - else: - # sequence - self.im = im - - if im.mode == "1": - self.image = ImageTk.BitmapImage(im, foreground="white") - else: - self.image = ImageTk.PhotoImage(im) - - # APPLET SUPPORT (very crude, and not 100% safe) - global animation_display - animation_display = AppletDisplay(self) - - Label.__init__(self, master, image=self.image, bg="black", bd=0) - - self.update() - - try: - duration = im.info["duration"] - except KeyError: - duration = 100 - self.after(duration, self.next) - - def next(self): - - if type(self.im) == type([]): - - try: - im = self.im[0] - del self.im[0] - self.image.paste(im) - except IndexError: - return # end of list - - else: - - try: - im = self.im - im.seek(im.tell() + 1) - self.image.paste(im) - except EOFError: - return # end of file - - try: - duration = im.info["duration"] - except KeyError: - duration = 100 - self.after(duration, self.next) - - self.update_idletasks() - - -# -------------------------------------------------------------------- -# script interface - -if __name__ == "__main__": - - if not sys.argv[1:]: - print "Syntax: python player.py imagefile(s)" - sys.exit(1) - - filename = sys.argv[1] - - root = Tk() - root.title(filename) - - if len(sys.argv) > 2: - # list of images - print "loading..." - im = [] - for filename in sys.argv[1:]: - im.append(Image.open(filename)) - else: - # sequence - im = Image.open(filename) - - UI(root, im).pack() - - root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py deleted file mode 100755 index eb510987267..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/thresholder.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# -# this demo script illustrates how a 1-bit BitmapImage can be used -# as a dynamically updated overlay -# - -from Tkinter import * -from PIL import Image, ImageTk -import sys - -# -# an image viewer - -class UI(Frame): - def __init__(self, master, im, value = 128): - Frame.__init__(self, master) - - self.image = im - self.value = value - - self.canvas = Canvas(self, width=im.size[0], height=im.size[1]) - self.backdrop = ImageTk.PhotoImage(im) - self.canvas.create_image(0, 0, image=self.backdrop, anchor=NW) - self.canvas.pack() - - scale = Scale(self, orient=HORIZONTAL, from_=0, to=255, - resolution=1, command=self.update, length=256) - scale.set(value) - scale.bind("", self.redraw) - scale.pack() - - # uncomment the following line for instant feedback (might - # be too slow on some platforms) - # self.redraw() - - def update(self, value): - self.value = eval(value) - - self.redraw() - - def redraw(self, event = None): - - # create overlay (note the explicit conversion to mode "1") - im = self.image.point(lambda v,t=self.value: v>=t, "1") - self.overlay = ImageTk.BitmapImage(im, foreground="green") - - # update canvas - self.canvas.delete("overlay") - self.canvas.create_image(0, 0, image=self.overlay, anchor=NW, - tags="overlay") - -# -------------------------------------------------------------------- -# main - -root = Tk() - -im = Image.open(sys.argv[1]) - -if im.mode != "L": - im = im.convert("L") - -# im.thumbnail((320,200)) - -UI(root, im).pack() - -root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py deleted file mode 100755 index 6e4dc8b67a1..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Scripts/viewer.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# The Python Imaging Library -# $Id$ -# - -from Tkinter import * -from PIL import Image, ImageTk - -# -# an image viewer - -class UI(Label): - - def __init__(self, master, im): - - if im.mode == "1": - # bitmap image - self.image = ImageTk.BitmapImage(im, foreground="white") - Label.__init__(self, master, image=self.image, bg="black", bd=0) - - else: - # photo image - self.image = ImageTk.PhotoImage(im) - Label.__init__(self, master, image=self.image, bd=0) - -# -# script interface - -if __name__ == "__main__": - - import sys - - if not sys.argv[1:]: - print "Syntax: python viewer.py imagefile" - sys.exit(1) - - filename = sys.argv[1] - - root = Tk() - root.title(filename) - - im = Image.open(filename) - - UI(root, im).pack() - - root.mainloop() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt deleted file mode 100755 index 2d787983b75..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/booster.txt +++ /dev/null @@ -1,108 +0,0 @@ -==================================================================== -The Photoimage Booster Patch (for Windows 95/NT) -==================================================================== - - This patch kit boosts performance for 16/24-bit displays. The -first patch is required on Tk 4.2 (where it fixes the problems for -16-bit displays) and later versions, with the exception for Tk 8.0b1 -where Sun added something similar themselves, only to remove it in -8.0b2. By installing both patches, Tk's PhotoImage handling becomes -much faster on both 16-bit and 24-bit displays. The patch has been -tested with Tk 4.2 and 8.0. - - Here's a benchmark, made with a sample program which loads two -512x512 greyscale PGM's, and two 512x512 colour PPM's, and displays -each of them in a separate toplevel windows. Tcl/Tk was compiled -with Visual C 4.0, and run on a P100 under Win95. Image load times -are not included in the timings: - - 8-bit 16-bit 24-bit --------------------------------------------------------------------- -1. original 4.2 code 5.52 s 8.57 s 3.79 s -2. booster patch 5.49 s 1.87 s 1.82 s - - speedup None 4.6x 2.1x - -==================================================================== - -Here's the patches: - -1. For portability and speed, the best thing under Windows is to -treat 16-bit displays as if they were 24-bit. The Windows device -drivers take care of the rest. - - ---------------------------------------------------------------- - If you have Tk 4.1 or Tk 8.0b1, you don't have to apply this - patch! It only applies to Tk 4.2, Tk 8.0a[12] and Tk 8.0b2. - ---------------------------------------------------------------- - -In win/tkWinImage.c, change the following line in XCreateImage: - - imagePtr->bits_per_pixel = depth; - -to - -/* ==================================================================== */ -/* The tk photo image booster patch -- patch section 1 */ -/* ==================================================================== */ - - if (visual->class == TrueColor) - /* true colour is stored as 3 bytes: (blue, green, red) */ - imagePtr->bits_per_pixel = 24; - else - imagePtr->bits_per_pixel = depth; - -/* ==================================================================== */ - - -2. The DitherInstance implementation is not good. It's especially -bad on highend truecolour displays. IMO, it should be rewritten from -scratch (some other day...). - - Anyway, the following band-aid makes the situation a little bit -better under Windows. This hack trades some marginal quality (no -dithering on 16-bit displays) for a dramatic performance boost. -Requires patch 1, unless you're using Tk 4.1 or Tk 8.0b1. - -In generic/tkImgPhoto.c, add the #ifdef section to the DitherInstance -function: - - for (; height > 0; height -= nLines) { - if (nLines > height) { - nLines = height; - } - dstLinePtr = (unsigned char *) imagePtr->data; - yEnd = yStart + nLines; - -/* ==================================================================== */ -/* The tk photo image booster patch -- patch section 2 */ -/* ==================================================================== */ - -#ifdef __WIN32__ - if (colorPtr->visualInfo.class == TrueColor - && instancePtr->gamma == 1.0) { - /* Windows hicolor/truecolor booster */ - for (y = yStart; y < yEnd; ++y) { - destBytePtr = dstLinePtr; - srcPtr = srcLinePtr; - for (x = xStart; x < xEnd; ++x) { - destBytePtr[0] = srcPtr[2]; - destBytePtr[1] = srcPtr[1]; - destBytePtr[2] = srcPtr[0]; - destBytePtr += 3; srcPtr += 3; - } - srcLinePtr += lineLength; - dstLinePtr += bytesPerLine; - } - } else -#endif - -/* ==================================================================== */ - - for (y = yStart; y < yEnd; ++y) { - srcPtr = srcLinePtr; - errPtr = errLinePtr; - destBytePtr = dstLinePtr; - -==================================================================== -last updated: 97-07-03/fl diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt deleted file mode 100755 index e24d36301c7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/install.txt +++ /dev/null @@ -1,41 +0,0 @@ -==================================================================== -Using PIL With Tkinter -==================================================================== - -Starting with 1.0 final (release candidate 2 and later, to be -precise), PIL can attach itself to Tkinter in flight. As a result, -you no longer need to rebuild the Tkinter extension to be able to -use PIL. - -However, if you cannot get the this to work on your platform, you -can do it in the old way: - -* Adding Tkinter support - -1. Compile Python's _tkinter.c with the WITH_APPINIT and WITH_PIL - flags set, and link it with tkImaging.c and tkappinit.c. To - do this, copy the former to the Modules directory, and edit - the _tkinter line in Setup (or Setup.in) according to the - instructions in that file. - - NOTE: if you have an old Python version, the tkappinit.c - file is not included by default. If this is the case, you - will have to add the following lines to tkappinit.c, after - the MOREBUTTONS stuff: - - { - extern void TkImaging_Init(Tcl_Interp* interp); - TkImaging_Init(interp); - } - - This registers a Tcl command called "PyImagingPhoto", which is - use to communicate between PIL and Tk's PhotoImage handler. - - You must also change the _tkinter line in Setup (or Setup.in) - to something like: - - _tkinter _tkinter.c tkImaging.c tkappinit.c -DWITH_APPINIT - -I/usr/local/include -L/usr/local/lib -ltk8.0 -ltcl8.0 -lX11 - - - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt deleted file mode 100755 index e7c46c65fea..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/pilbitmap.txt +++ /dev/null @@ -1,149 +0,0 @@ -==================================================================== -The PIL Bitmap Booster Patch -==================================================================== - -The pilbitmap booster patch greatly improves performance of the -ImageTk.BitmapImage constructor. Unfortunately, the design of Tk -doesn't allow us to do this from the tkImaging interface module, so -you have to patch the Tk sources. - -Once installed, the ImageTk module will automatically detect this -patch. - -(Note: this patch has been tested with Tk 8.0 on Win32 only, but it -should work just fine on other platforms as well). - -1. To the beginning of TkGetBitmapData (in generic/tkImgBmap.c), add - the following stuff: - ------------------------------------------------------------------------- - int width, height, numBytes, hotX, hotY; - char *p, *end, *expandedFileName; - ParseInfo pi; - char *data = NULL; - Tcl_DString buffer; - -/* ==================================================================== */ -/* The pilbitmap booster patch -- patch section */ -/* ==================================================================== */ - - char *PILGetBitmapData(); - - if (string) { - /* Is this a PIL bitmap reference? */ - data = PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr); - if (data) - return data; - } - -/* ==================================================================== */ - - pi.string = string; - if (string == NULL) { - if (Tcl_IsSafe(interp)) { ------------------------------------------------------------------------- - - -2. Append the following to the same file (you may wish to include -Imaging.h instead of copying the struct declaration...) - ------------------------------------------------------------------------- - -/* ==================================================================== */ -/* The pilbitmap booster patch -- code section */ -/* ==================================================================== */ - -/* Imaging declaration boldly copied from Imaging.h (!) */ - -typedef struct ImagingInstance *Imaging; /* a.k.a. ImagingImage :-) */ - -typedef unsigned char UINT8; -typedef int INT32; - -struct ImagingInstance { - - /* Format */ - char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */ - int type; /* Always 0 in this version */ - int depth; /* Always 8 in this version */ - int bands; /* Number of bands (1, 3, or 4) */ - int xsize; /* Image dimension. */ - int ysize; - - /* Colour palette (for "P" images only) */ - void* palette; - - /* Data pointers */ - UINT8 **image8; /* Set for 8-bit image (pixelsize=1). */ - INT32 **image32; /* Set for 32-bit image (pixelsize=4). */ - - /* Internals */ - char **image; /* Actual raster data. */ - char *block; /* Set if data is allocated in a single block. */ - - int pixelsize; /* Size of a pixel, in bytes (1 or 4) */ - int linesize; /* Size of a line, in bytes (xsize * pixelsize) */ - - /* Virtual methods */ - void (*im_delete)(Imaging *); - -}; - -/* The pilbitmap booster patch allows you to pass PIL images to the - Tk bitmap decoder. Passing images this way is much more efficient - than using the "tobitmap" method. */ - -char * -PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr) - char *string; - int *widthPtr, *heightPtr; - int *hotXPtr, *hotYPtr; -{ - char* data; - char* p; - int y; - Imaging im; - - if (strncmp(string, "PIL:", 4) != 0) - return NULL; - - im = (Imaging) atol(string + 4); - - if (strcmp(im->mode, "1") != 0 && strcmp(im->mode, "L") != 0) - return NULL; - - data = p = (char *) ckalloc((unsigned) ((im->xsize+7)/8) * im->ysize); - - for (y = 0; y < im->ysize; y++) { - char* in = im->image8[y]; - int i, m, b; - b = 0; m = 1; - for (i = 0; i < im->xsize; i++) { - if (in[i] != 0) - b |= m; - m <<= 1; - if (m == 256){ - *p++ = b; - b = 0; m = 1; - } - } - if (m != 1) - *p++ = b; - } - - *widthPtr = im->xsize; - *heightPtr = im->ysize; - *hotXPtr = -1; - *hotYPtr = -1; - - return data; -} - -/* ==================================================================== */ - ------------------------------------------------------------------------- - -3. Recompile Tk and relink the _tkinter module (where necessary). - -==================================================================== -Last updated: 97-05-17/fl diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c deleted file mode 100755 index 5963ee24c7d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/Tk/tkImaging.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * TK interface for Python Imaging objects - * - * Copies (parts of) a named display memory to a photo image object. - * Also contains code to create an display memory. Under Tk, a - * display memory is simply an "L" or "RGB" image memory that is - * allocated in a single block. - * - * To use this module, import the _imagingtk module (ImageTk does - * this for you). - * - * If you're using Python in an embedded context, you can add the - * following lines to your Tcl_AppInit function (in tkappinit.c) - * instead. Put them after the calls to Tcl_Init and Tk_Init: - * - * { - * extern void TkImaging_Init(Tcl_Interp* interp); - * TkImaging_Init(interp); - * } - * - * This registers a Tcl command called "PyImagingPhoto", which is used - * to communicate between PIL and Tk's PhotoImage handler. - * - * Compile and link tkImaging.c with tkappinit.c and _tkinter (see the - * Setup file for details on how to use tkappinit.c). Note that - * _tkinter.c must be compiled with WITH_APPINIT. - * - * History: - * 1995-09-12 fl Created - * 1996-04-08 fl Ready for release - * 1997-05-09 fl Use command instead of image type - * 2001-03-18 fl Initialize alpha layer pointer (struct changed in 8.3) - * 2003-04-23 fl Fixed building for Tk 8.4.1 and later (Jack Jansen) - * 2004-06-24 fl Fixed building for Tk 8.4.6 and later. - * - * Copyright (c) 1997-2004 by Secret Labs AB - * Copyright (c) 1995-2004 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - -#define TK (TK_MAJOR_VERSION*10 + TK_MINOR_VERSION) - -/* This is needed for (at least) Tk 8.4.6 and later, to avoid warnings - for the Tcl_CreateCommand command. */ -#define USE_COMPAT_CONST - -#include "tk.h" - -#include "Imaging.h" - -#include - - -static Imaging -ImagingFind(const char* name) -{ - long id; - - /* FIXME: use CObject instead? */ - id = atol(name); - if (!id) - return NULL; - - return (Imaging) id; -} - - -static int -PyImagingPhotoPut(ClientData clientdata, Tcl_Interp* interp, - int argc, char **argv) -{ - Imaging im; - Tk_PhotoHandle photo; - Tk_PhotoImageBlock block; - - if (argc != 3) { - Tcl_AppendResult(interp, "usage: ", argv[0], - " destPhoto srcImage", (char *) NULL); - return TCL_ERROR; - } - - /* get Tcl PhotoImage handle */ - photo = Tk_FindPhoto(interp, argv[1]); - if (photo == NULL) { - Tcl_AppendResult( - interp, "destination photo must exist", (char *) NULL - ); - return TCL_ERROR; - } - - /* get PIL Image handle */ - im = ImagingFind(argv[2]); - if (!im) { - Tcl_AppendResult(interp, "bad name", (char*) NULL); - return TCL_ERROR; - } - if (!im->block) { - Tcl_AppendResult(interp, "bad display memory", (char*) NULL); - return TCL_ERROR; - } - - /* Active region */ -#if 0 - if (src_xoffset + xsize > im->xsize) - xsize = im->xsize - src_xoffset; - if (src_yoffset + ysize > im->ysize) - ysize = im->ysize - src_yoffset; - if (xsize < 0 || ysize < 0 - || src_xoffset >= im->xsize - || src_yoffset >= im->ysize) - return TCL_OK; -#endif - - /* Mode */ - - if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { - block.pixelSize = 1; - block.offset[0] = block.offset[1] = block.offset[2] = 0; - } else if (strncmp(im->mode, "RGB", 3) == 0) { - block.pixelSize = 4; - block.offset[0] = 0; - block.offset[1] = 1; - block.offset[2] = 2; - if (strcmp(im->mode, "RGBA") == 0) - block.offset[3] = 3; /* alpha (or reserved, under 8.2) */ - else - block.offset[3] = 0; /* no alpha */ - } else { - Tcl_AppendResult(interp, "Bad mode", (char*) NULL); - return TCL_ERROR; - } - - block.width = im->xsize; - block.height = im->ysize; - block.pitch = im->linesize; - block.pixelPtr = (unsigned char*) im->block; -#if 0 - block.pixelPtr = (unsigned char*) im->block + - src_yoffset * im->linesize + - src_xoffset * im->pixelsize; -#endif - -#if TK < 84 /* < 8.4.0 */ - if (strcmp(im->mode, "RGBA") == 0) { - /* Copy non-transparent pixels to photo image */ - int x, y; - Tk_PhotoImageBlock run; - - /* Clear current contents */ - Tk_PhotoBlank(photo); - - /* Setup run descriptor */ - run.height = 1; - run.pitch = block.pitch; - run.pixelSize = block.pixelSize; - run.offset[0] = 0; - run.offset[1] = 1; - run.offset[2] = 2; - run.offset[3] = 0; /* no alpha (or reserved, under 8.2) */ - - /* Copy opaque runs to photo image */ - for (y = 0; y < block.height; y++) { - unsigned char* p = block.pixelPtr + y*block.pitch; - unsigned char* s = p; - int w = 0; - for (x = 0; x < block.width; x++) { - if (p[3]) { - /* opaque: add pixel to current run */ - if (w == 0) - s = p; - w = w + 1; - } else if (s) { - /* copy run to photo image */ - if (w > 0) { - run.width = w; - run.pixelPtr = s; - Tk_PhotoPutBlock(photo, &run, x-w, y, run.width, 1); - } - w = 0; - } - p += block.pixelSize; - } - if (w > 0) { - /* copy final run, if any */ - run.width = w; - run.pixelPtr = s; - Tk_PhotoPutBlock(photo, &run, x-w, y, run.width, 1); - } - } - - } else - - /* Copy opaque block to photo image, and leave the rest to TK */ - Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); - -#else /* Tk 8.4 and newer */ -#if TK < 85 /* Tk 8.4 */ - Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height, - TK_PHOTO_COMPOSITE_SET); - if (strcmp(im->mode, "RGBA") == 0) - /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */ - /* (fixed in Tk 8.5a3) */ - Tk_PhotoSetSize(photo, block.width, block.height); -#else /* Tk 8.5 */ - Tk_PhotoPutBlock(interp, photo, &block, 0, 0, block.width, block.height, - TK_PHOTO_COMPOSITE_SET); -#endif -#endif - - return TCL_OK; -} - - -static int -PyImagingPhotoGet(ClientData clientdata, Tcl_Interp* interp, - int argc, char **argv) -{ - Tk_PhotoHandle photo; - Tk_PhotoImageBlock block; - - if (argc != 2) { - Tcl_AppendResult(interp, "usage: ", argv[0], - " srcPhoto", (char *) NULL); - return TCL_ERROR; - } - - /* get Tcl PhotoImage handle */ - photo = Tk_FindPhoto(interp, argv[1]); - if (photo == NULL) { - Tcl_AppendResult( - interp, "source photo must exist", (char *) NULL - ); - return TCL_ERROR; - } - - Tk_PhotoGetImage(photo, &block); - - printf("pixelPtr = %p\n", block.pixelPtr); - printf("width = %d\n", block.width); - printf("height = %d\n", block.height); - printf("pitch = %d\n", block.pitch); - printf("pixelSize = %d\n", block.pixelSize); - printf("offset = %d %d %d %d\n", block.offset[0], block.offset[1], - block.offset[2], block.offset[3]); - - Tcl_AppendResult( - interp, "this function is not yet supported", (char *) NULL - ); - - return TCL_ERROR; -} - - -void -TkImaging_Init(Tcl_Interp* interp) -{ - Tcl_CreateCommand(interp, "PyImagingPhoto", PyImagingPhotoPut, - (ClientData) 0, (Tcl_CmdDeleteProc*) NULL); - Tcl_CreateCommand(interp, "PyImagingPhotoGet", PyImagingPhotoGet, - (ClientData) 0, (Tcl_CmdDeleteProc*) NULL); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c deleted file mode 100755 index c21897decdc..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imaging.c +++ /dev/null @@ -1,3281 +0,0 @@ -/* - * The Python Imaging Library. - * - * the imaging library bindings - * - * history: - * 1995-09-24 fl Created - * 1996-03-24 fl Ready for first public release (release 0.0) - * 1996-03-25 fl Added fromstring (for Jack's "img" library) - * 1996-03-28 fl Added channel operations - * 1996-03-31 fl Added point operation - * 1996-04-08 fl Added new/new_block/new_array factories - * 1996-04-13 fl Added decoders - * 1996-05-04 fl Added palette hack - * 1996-05-12 fl Compile cleanly as C++ - * 1996-05-19 fl Added matrix conversions, gradient fills - * 1996-05-27 fl Added display_mode - * 1996-07-22 fl Added getbbox, offset - * 1996-07-23 fl Added sequence semantics - * 1996-08-13 fl Added logical operators, point mode - * 1996-08-16 fl Modified paste interface - * 1996-09-06 fl Added putdata methods, use abstract interface - * 1996-11-01 fl Added xbm encoder - * 1996-11-04 fl Added experimental path stuff, draw_lines, etc - * 1996-12-10 fl Added zip decoder, crc32 interface - * 1996-12-14 fl Added modulo arithmetics - * 1996-12-29 fl Added zip encoder - * 1997-01-03 fl Added fli and msp decoders - * 1997-01-04 fl Added experimental sun_rle and tga_rle decoders - * 1997-01-05 fl Added gif encoder, getpalette hack - * 1997-02-23 fl Added histogram mask - * 1997-05-12 fl Minor tweaks to match the IFUNC95 interface - * 1997-05-21 fl Added noise generator, spread effect - * 1997-06-05 fl Added mandelbrot generator - * 1997-08-02 fl Modified putpalette to coerce image mode if necessary - * 1998-01-11 fl Added INT32 support - * 1998-01-22 fl Fixed draw_points to draw the last point too - * 1998-06-28 fl Added getpixel, getink, draw_ink - * 1998-07-12 fl Added getextrema - * 1998-07-17 fl Added point conversion to arbitrary formats - * 1998-09-21 fl Added support for resampling filters - * 1998-09-22 fl Added support for quad transform - * 1998-12-29 fl Added support for arcs, chords, and pieslices - * 1999-01-10 fl Added some experimental arrow graphics stuff - * 1999-02-06 fl Added draw_bitmap, font acceleration stuff - * 2001-04-17 fl Fixed some egcs compiler nits - * 2001-09-17 fl Added screen grab primitives (win32) - * 2002-03-09 fl Added stretch primitive - * 2002-03-10 fl Fixed filter handling in rotate - * 2002-06-06 fl Added I, F, and RGB support to putdata - * 2002-06-08 fl Added rankfilter - * 2002-06-09 fl Added support for user-defined filter kernels - * 2002-11-19 fl Added clipboard grab primitives (win32) - * 2002-12-11 fl Added draw context - * 2003-04-26 fl Tweaks for Python 2.3 beta 1 - * 2003-05-21 fl Added createwindow primitive (win32) - * 2003-09-13 fl Added thread section hooks - * 2003-09-15 fl Added expand helper - * 2003-09-26 fl Added experimental LA support - * 2004-02-21 fl Handle zero-size images in quantize - * 2004-06-05 fl Added ptr attribute (used to access Imaging objects) - * 2004-06-05 fl Don't crash when fetching pixels from zero-wide images - * 2004-09-17 fl Added getcolors - * 2004-10-04 fl Added modefilter - * 2005-10-02 fl Added access proxy - * 2006-06-18 fl Always draw last point in polyline - * - * Copyright (c) 1997-2006 by Secret Labs AB - * Copyright (c) 1995-2006 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - - -#include "Python.h" - -#include "Imaging.h" - - -/* Configuration stuff. Feel free to undef things you don't need. */ -#define WITH_IMAGECHOPS /* ImageChops support */ -#define WITH_IMAGEDRAW /* ImageDraw support */ -#define WITH_MAPPING /* use memory mapping to read some file formats */ -#define WITH_IMAGEPATH /* ImagePath stuff */ -#define WITH_ARROW /* arrow graphics stuff (experimental) */ -#define WITH_EFFECTS /* special effects */ -#define WITH_QUANTIZE /* quantization support */ -#define WITH_RANKFILTER /* rank filter */ -#define WITH_MODEFILTER /* mode filter */ -#define WITH_THREADING /* "friendly" threading support */ -#define WITH_UNSHARPMASK /* Kevin Cazabon's unsharpmask module */ - -#define WITH_DEBUG /* extra debugging interfaces */ - -/* PIL Plus extensions */ -#undef WITH_CRACKCODE /* pil plus */ - -#undef VERBOSE - -#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) - -#define B16(p, i) ((((int)p[(i)]) << 8) + p[(i)+1]) -#define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)]) -#define S16(v) ((v) < 32768 ? (v) : ((v) - 65536)) - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#if PY_VERSION_HEX < 0x02050000 -#define Py_ssize_t int -#define ssizeargfunc intargfunc -#define ssizessizeargfunc intintargfunc -#define ssizeobjargproc intobjargproc -#define ssizessizeobjargproc intintobjargproc -#endif - -/* -------------------------------------------------------------------- */ -/* OBJECT ADMINISTRATION */ -/* -------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - Imaging image; - ImagingAccess access; -} ImagingObject; - -staticforward PyTypeObject Imaging_Type; - -#ifdef WITH_IMAGEDRAW - -typedef struct -{ - /* to write a character, cut out sxy from glyph data, place - at current position plus dxy, and advance by (dx, dy) */ - int dx, dy; - int dx0, dy0, dx1, dy1; - int sx0, sy0, sx1, sy1; -} Glyph; - -typedef struct { - PyObject_HEAD - ImagingObject* ref; - Imaging bitmap; - int ysize; - int baseline; - Glyph glyphs[256]; -} ImagingFontObject; - -staticforward PyTypeObject ImagingFont_Type; - -typedef struct { - PyObject_HEAD - ImagingObject* image; - UINT8 ink[4]; - int blend; -} ImagingDrawObject; - -staticforward PyTypeObject ImagingDraw_Type; - -#endif - -typedef struct { - PyObject_HEAD - ImagingObject* image; - int readonly; -} PixelAccessObject; - -staticforward PyTypeObject PixelAccess_Type; - -PyObject* -PyImagingNew(Imaging imOut) -{ - ImagingObject* imagep; - - if (!imOut) - return NULL; - - imagep = PyObject_New(ImagingObject, &Imaging_Type); - if (imagep == NULL) { - ImagingDelete(imOut); - return NULL; - } - -#ifdef VERBOSE - printf("imaging %p allocated\n", imagep); -#endif - - imagep->image = imOut; - imagep->access = ImagingAccessNew(imOut); - - return (PyObject*) imagep; -} - -static void -_dealloc(ImagingObject* imagep) -{ - -#ifdef VERBOSE - printf("imaging %p deleted\n", imagep); -#endif - - if (imagep->access) - ImagingAccessDelete(imagep->image, imagep->access); - ImagingDelete(imagep->image); - PyObject_Del(imagep); -} - -#define PyImaging_Check(op) ((op)->ob_type == &Imaging_Type) - -Imaging PyImaging_AsImaging(PyObject *op) -{ - if (!PyImaging_Check(op)) { - PyErr_BadInternalCall(); - return NULL; - } - - return ((ImagingObject *)op)->image; -} - - -/* -------------------------------------------------------------------- */ -/* THREAD HANDLING */ -/* -------------------------------------------------------------------- */ - -void ImagingSectionEnter(ImagingSectionCookie* cookie) -{ -#ifdef WITH_THREADING - *cookie = (PyThreadState *) PyEval_SaveThread(); -#endif -} - -void ImagingSectionLeave(ImagingSectionCookie* cookie) -{ -#ifdef WITH_THREADING - PyEval_RestoreThread((PyThreadState*) *cookie); -#endif -} - -/* -------------------------------------------------------------------- */ -/* BUFFER HANDLING */ -/* -------------------------------------------------------------------- */ -/* Python compatibility API */ - -#if PY_VERSION_HEX < 0x02020000 - -int PyImaging_CheckBuffer(PyObject *buffer) -{ - PyBufferProcs *procs = buffer->ob_type->tp_as_buffer; - if (procs && procs->bf_getreadbuffer && procs->bf_getsegcount && - procs->bf_getsegcount(buffer, NULL) == 1) - return 1; - return 0; -} - -int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr) -{ - PyBufferProcs *procs = buffer->ob_type->tp_as_buffer; - return procs->bf_getreadbuffer(buffer, 0, ptr); -} - -#else - -int PyImaging_CheckBuffer(PyObject* buffer) -{ - return PyObject_CheckReadBuffer(buffer); -} - -int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr) -{ - /* must call check_buffer first! */ -#if PY_VERSION_HEX < 0x02050000 - int n = 0; -#else - Py_ssize_t n = 0; -#endif - PyObject_AsReadBuffer(buffer, ptr, &n); - return (int) n; -} - -#endif - -/* -------------------------------------------------------------------- */ -/* EXCEPTION REROUTING */ -/* -------------------------------------------------------------------- */ - -/* error messages */ -static const char* must_be_sequence = "argument must be a sequence"; -static const char* wrong_mode = "unrecognized image mode"; -static const char* wrong_raw_mode = "unrecognized raw mode"; -static const char* outside_image = "image index out of range"; -static const char* outside_palette = "palette index out of range"; -static const char* no_palette = "image has no palette"; -static const char* readonly = "image is readonly"; -/* static const char* no_content = "image has no content"; */ - -void * -ImagingError_IOError(void) -{ - PyErr_SetString(PyExc_IOError, "error when accessing file"); - return NULL; -} - -void * -ImagingError_MemoryError(void) -{ - return PyErr_NoMemory(); -} - -void * -ImagingError_Mismatch(void) -{ - PyErr_SetString(PyExc_ValueError, "images do not match"); - return NULL; -} - -void * -ImagingError_ModeError(void) -{ - PyErr_SetString(PyExc_ValueError, "image has wrong mode"); - return NULL; -} - -void * -ImagingError_ValueError(const char *message) -{ - PyErr_SetString( - PyExc_ValueError, - (message) ? (char*) message : "unrecognized argument value" - ); - return NULL; -} - -void -ImagingError_Clear(void) -{ - PyErr_Clear(); -} - -/* -------------------------------------------------------------------- */ -/* HELPERS */ -/* -------------------------------------------------------------------- */ - -static int -getbands(const char* mode) -{ - Imaging im; - int bands; - - /* FIXME: add primitive to libImaging to avoid extra allocation */ - im = ImagingNew(mode, 0, 0); - if (!im) - return -1; - - bands = im->bands; - - ImagingDelete(im); - - return bands; -} - -#define TYPE_UINT8 (0x100|sizeof(UINT8)) -#define TYPE_INT32 (0x200|sizeof(INT32)) -#define TYPE_FLOAT32 (0x300|sizeof(FLOAT32)) -#define TYPE_DOUBLE (0x400|sizeof(double)) - -static void* -getlist(PyObject* arg, int* length, const char* wrong_length, int type) -{ - int i, n; - void* list; - - if (!PySequence_Check(arg)) { - PyErr_SetString(PyExc_TypeError, must_be_sequence); - return NULL; - } - - n = PyObject_Length(arg); - if (length && wrong_length && n != *length) { - PyErr_SetString(PyExc_ValueError, wrong_length); - return NULL; - } - - list = malloc(n * (type & 0xff)); - if (!list) - return PyErr_NoMemory(); - - switch (type) { - case TYPE_UINT8: - if (PyList_Check(arg)) { - for (i = 0; i < n; i++) { - PyObject *op = PyList_GET_ITEM(arg, i); - int temp = PyInt_AsLong(op); - ((UINT8*)list)[i] = CLIP(temp); - } - } else { - for (i = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(arg, i); - int temp = PyInt_AsLong(op); - Py_XDECREF(op); - ((UINT8*)list)[i] = CLIP(temp); - } - } - break; - case TYPE_INT32: - if (PyList_Check(arg)) { - for (i = 0; i < n; i++) { - PyObject *op = PyList_GET_ITEM(arg, i); - int temp = PyInt_AsLong(op); - ((INT32*)list)[i] = temp; - } - } else { - for (i = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(arg, i); - int temp = PyInt_AsLong(op); - Py_XDECREF(op); - ((INT32*)list)[i] = temp; - } - } - break; - case TYPE_FLOAT32: - if (PyList_Check(arg)) { - for (i = 0; i < n; i++) { - PyObject *op = PyList_GET_ITEM(arg, i); - double temp = PyFloat_AsDouble(op); - ((FLOAT32*)list)[i] = (FLOAT32) temp; - } - } else { - for (i = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(arg, i); - double temp = PyFloat_AsDouble(op); - Py_XDECREF(op); - ((FLOAT32*)list)[i] = (FLOAT32) temp; - } - } - break; - case TYPE_DOUBLE: - if (PyList_Check(arg)) { - for (i = 0; i < n; i++) { - PyObject *op = PyList_GET_ITEM(arg, i); - double temp = PyFloat_AsDouble(op); - ((double*)list)[i] = temp; - } - } else { - for (i = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(arg, i); - double temp = PyFloat_AsDouble(op); - Py_XDECREF(op); - ((double*)list)[i] = temp; - } - } - break; - } - - if (length) - *length = n; - - PyErr_Clear(); - - return list; -} - -static inline PyObject* -getpixel(Imaging im, ImagingAccess access, int x, int y) -{ - union { - UINT8 b[4]; - INT16 h; - INT32 i; - FLOAT32 f; - } pixel; - - if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return NULL; - } - - access->get_pixel(im, x, y, &pixel); - - switch (im->type) { - case IMAGING_TYPE_UINT8: - switch (im->bands) { - case 1: - return PyInt_FromLong(pixel.b[0]); - case 2: - return Py_BuildValue("ii", pixel.b[0], pixel.b[1]); - case 3: - return Py_BuildValue("iii", pixel.b[0], pixel.b[1], pixel.b[2]); - case 4: - return Py_BuildValue("iiii", pixel.b[0], pixel.b[1], pixel.b[2], pixel.b[3]); - } - break; - case IMAGING_TYPE_INT32: - return PyInt_FromLong(pixel.i); - case IMAGING_TYPE_FLOAT32: - return PyFloat_FromDouble(pixel.f); - case IMAGING_TYPE_SPECIAL: - if (strncmp(im->mode, "I;16", 4) == 0) - return PyInt_FromLong(pixel.h); - break; - } - - /* unknown type */ - Py_INCREF(Py_None); - return Py_None; -} - -static char* -getink(PyObject* color, Imaging im, char* ink) -{ - int r, g, b, a; - double f; - - /* fill ink buffer (four bytes) with something that can - be cast to either UINT8 or INT32 */ - - switch (im->type) { - case IMAGING_TYPE_UINT8: - /* unsigned integer */ - if (im->bands == 1) { - /* unsigned integer, single layer */ - r = PyInt_AsLong(color); - if (r == -1 && PyErr_Occurred()) - return NULL; - ink[0] = CLIP(r); - ink[1] = ink[2] = ink[3] = 0; - } else { - a = 255; - if (PyInt_Check(color)) { - r = PyInt_AS_LONG(color); - /* compatibility: ABGR */ - a = (UINT8) (r >> 24); - b = (UINT8) (r >> 16); - g = (UINT8) (r >> 8); - r = (UINT8) r; - } else { - if (im->bands == 2) { - if (!PyArg_ParseTuple(color, "i|i", &r, &a)) - return NULL; - g = b = r; - } else { - if (!PyArg_ParseTuple(color, "iii|i", &r, &g, &b, &a)) - return NULL; - } - } - ink[0] = CLIP(r); - ink[1] = CLIP(g); - ink[2] = CLIP(b); - ink[3] = CLIP(a); - } - return ink; - case IMAGING_TYPE_INT32: - /* signed integer */ - r = PyInt_AsLong(color); - if (r == -1 && PyErr_Occurred()) - return NULL; - *(INT32*) ink = r; - return ink; - case IMAGING_TYPE_FLOAT32: - /* floating point */ - f = PyFloat_AsDouble(color); - if (f == -1.0 && PyErr_Occurred()) - return NULL; - *(FLOAT32*) ink = (FLOAT32) f; - return ink; - case IMAGING_TYPE_SPECIAL: - if (strncmp(im->mode, "I;16", 4) == 0) { - r = PyInt_AsLong(color); - if (r == -1 && PyErr_Occurred()) - return NULL; - ink[0] = (UINT8) r; - ink[1] = (UINT8) (r >> 8); - ink[2] = ink[3] = 0; - return ink; - } - } - - PyErr_SetString(PyExc_ValueError, wrong_mode); - return NULL; -} - -/* -------------------------------------------------------------------- */ -/* FACTORIES */ -/* -------------------------------------------------------------------- */ - -static PyObject* -_fill(PyObject* self, PyObject* args) -{ - char* mode; - int xsize, ysize; - PyObject* color; - char buffer[4]; - Imaging im; - - xsize = ysize = 256; - color = NULL; - - if (!PyArg_ParseTuple(args, "s|(ii)O", &mode, &xsize, &ysize, &color)) - return NULL; - - im = ImagingNew(mode, xsize, ysize); - if (!im) - return NULL; - - if (color) { - if (!getink(color, im, buffer)) { - ImagingDelete(im); - return NULL; - } - } else - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0; - - (void) ImagingFill(im, buffer); - - return PyImagingNew(im); -} - -static PyObject* -_new(PyObject* self, PyObject* args) -{ - char* mode; - int xsize, ysize; - - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; - - return PyImagingNew(ImagingNew(mode, xsize, ysize)); -} - -static PyObject* -_new_array(PyObject* self, PyObject* args) -{ - char* mode; - int xsize, ysize; - - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; - - return PyImagingNew(ImagingNewArray(mode, xsize, ysize)); -} - -static PyObject* -_new_block(PyObject* self, PyObject* args) -{ - char* mode; - int xsize, ysize; - - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; - - return PyImagingNew(ImagingNewBlock(mode, xsize, ysize)); -} - -static PyObject* -_getcount(PyObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":getcount")) - return NULL; - - return PyInt_FromLong(ImagingNewCount); -} - -static PyObject* -_linear_gradient(PyObject* self, PyObject* args) -{ - char* mode; - - if (!PyArg_ParseTuple(args, "s", &mode)) - return NULL; - - return PyImagingNew(ImagingFillLinearGradient(mode)); -} - -static PyObject* -_radial_gradient(PyObject* self, PyObject* args) -{ - char* mode; - - if (!PyArg_ParseTuple(args, "s", &mode)) - return NULL; - - return PyImagingNew(ImagingFillRadialGradient(mode)); -} - -static PyObject* -_open_ppm(PyObject* self, PyObject* args) -{ - char* filename; - - if (!PyArg_ParseTuple(args, "s", &filename)) - return NULL; - - return PyImagingNew(ImagingOpenPPM(filename)); -} - -static PyObject* -_blend(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep1; - ImagingObject* imagep2; - double alpha; - - alpha = 0.5; - if (!PyArg_ParseTuple(args, "O!O!|d", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2, - &alpha)) - return NULL; - - return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image, - (float) alpha)); -} - -/* -------------------------------------------------------------------- */ -/* METHODS */ -/* -------------------------------------------------------------------- */ - -static PyObject* -_convert(ImagingObject* self, PyObject* args) -{ - char* mode; - int dither = 0; - ImagingObject *paletteimage = NULL; - - if (!PyArg_ParseTuple(args, "s|iO", &mode, &dither, &paletteimage)) - return NULL; - if (paletteimage != NULL) { - if (!PyImaging_Check(paletteimage)) { - PyObject_Print((PyObject *)paletteimage, stderr, 0); - PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'"); - return NULL; - } - if (paletteimage->image->palette == NULL) { - PyErr_SetString(PyExc_ValueError, "null palette"); - return NULL; - } - } - - return PyImagingNew(ImagingConvert(self->image, mode, paletteimage ? paletteimage->image->palette : NULL, dither)); -} - -static PyObject* -_convert2(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep1; - ImagingObject* imagep2; - if (!PyArg_ParseTuple(args, "O!O!", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2)) - return NULL; - - if (!ImagingConvert2(imagep1->image, imagep2->image)) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_convert_matrix(ImagingObject* self, PyObject* args) -{ - char* mode; - float m[12]; - if (!PyArg_ParseTuple(args, "s(ffff)", &mode, m+0, m+1, m+2, m+3)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "s(ffffffffffff)", &mode, - m+0, m+1, m+2, m+3, - m+4, m+5, m+6, m+7, - m+8, m+9, m+10, m+11)) - return NULL; - } - - return PyImagingNew(ImagingConvertMatrix(self->image, mode, m)); -} - -static PyObject* -_copy(ImagingObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - - return PyImagingNew(ImagingCopy(self->image)); -} - -static PyObject* -_copy2(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep1; - ImagingObject* imagep2; - if (!PyArg_ParseTuple(args, "O!O!", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2)) - return NULL; - - if (!ImagingCopy2(imagep1->image, imagep2->image)) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_crop(ImagingObject* self, PyObject* args) -{ - int x0, y0, x1, y1; - if (!PyArg_ParseTuple(args, "(iiii)", &x0, &y0, &x1, &y1)) - return NULL; - - return PyImagingNew(ImagingCrop(self->image, x0, y0, x1, y1)); -} - -static PyObject* -_expand(ImagingObject* self, PyObject* args) -{ - int x, y; - int mode = 0; - if (!PyArg_ParseTuple(args, "ii|i", &x, &y, &mode)) - return NULL; - - return PyImagingNew(ImagingExpand(self->image, x, y, mode)); -} - -static PyObject* -_filter(ImagingObject* self, PyObject* args) -{ - PyObject* imOut; - int kernelsize; - FLOAT32* kerneldata; - - int xsize, ysize; - float divisor, offset; - PyObject* kernel = NULL; - if (!PyArg_ParseTuple(args, "(ii)ffO", &xsize, &ysize, - &divisor, &offset, &kernel)) - return NULL; - - /* get user-defined kernel */ - kerneldata = getlist(kernel, &kernelsize, NULL, TYPE_FLOAT32); - if (!kerneldata) - return NULL; - if (kernelsize != xsize * ysize) { - free(kerneldata); - return ImagingError_ValueError("bad kernel size"); - } - - imOut = PyImagingNew( - ImagingFilter(self->image, xsize, ysize, kerneldata, offset, divisor) - ); - - free(kerneldata); - - return imOut; -} - -#ifdef WITH_UNSHARPMASK -static PyObject* -_gaussian_blur(ImagingObject* self, PyObject* args) -{ - Imaging imIn; - Imaging imOut; - - float radius = 0; - if (!PyArg_ParseTuple(args, "f", &radius)) - return NULL; - - imIn = self->image; - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - if (!imOut) - return NULL; - - if (!ImagingGaussianBlur(imIn, imOut, radius)) - return NULL; - - return PyImagingNew(imOut); -} -#endif - -static PyObject* -_getpalette(ImagingObject* self, PyObject* args) -{ - PyObject* palette; - int palettesize = 256; - int bits; - ImagingShuffler pack; - - char* mode = "RGB"; - char* rawmode = "RGB"; - if (!PyArg_ParseTuple(args, "|ss", &mode, &rawmode)) - return NULL; - - if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; - } - - pack = ImagingFindPacker(mode, rawmode, &bits); - if (!pack) { - PyErr_SetString(PyExc_ValueError, wrong_raw_mode); - return NULL; - } - - palette = PyString_FromStringAndSize(NULL, palettesize * bits / 8); - if (!palette) - return NULL; - - pack((UINT8*) PyString_AsString(palette), - self->image->palette->palette, palettesize); - - return palette; -} - -static inline int -_getxy(PyObject* xy, int* x, int *y) -{ - PyObject* value; - - if (!PyTuple_Check(xy) || PyTuple_GET_SIZE(xy) != 2) - goto badarg; - - value = PyTuple_GET_ITEM(xy, 0); - if (PyInt_Check(value)) - *x = PyInt_AS_LONG(value); - else if (PyFloat_Check(value)) - *x = (int) PyFloat_AS_DOUBLE(value); - else - goto badval; - - value = PyTuple_GET_ITEM(xy, 1); - if (PyInt_Check(value)) - *y = PyInt_AS_LONG(value); - else if (PyFloat_Check(value)) - *y = (int) PyFloat_AS_DOUBLE(value); - else - goto badval; - - return 0; - - badarg: - PyErr_SetString( - PyExc_TypeError, - "argument must be sequence of length 2" - ); - return -1; - - badval: - PyErr_SetString( - PyExc_TypeError, - "an integer is required" - ); - return -1; -} - -static PyObject* -_getpixel(ImagingObject* self, PyObject* args) -{ - PyObject* xy; - int x, y; - - if (PyTuple_GET_SIZE(args) != 1) { - PyErr_SetString( - PyExc_TypeError, - "argument 1 must be sequence of length 2" - ); - return NULL; - } - - xy = PyTuple_GET_ITEM(args, 0); - - if (_getxy(xy, &x, &y)) - return NULL; - - if (self->access == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - - return getpixel(self->image, self->access, x, y); -} - -static PyObject* -_histogram(ImagingObject* self, PyObject* args) -{ - ImagingHistogram h; - PyObject* list; - int i; - union { - UINT8 u[2]; - INT32 i[2]; - FLOAT32 f[2]; - } extrema; - void* ep; - int i0, i1; - double f0, f1; - - PyObject* extremap = NULL; - ImagingObject* maskp = NULL; - if (!PyArg_ParseTuple(args, "|OO!", &extremap, &Imaging_Type, &maskp)) - return NULL; - - if (extremap) { - ep = &extrema; - switch (self->image->type) { - case IMAGING_TYPE_UINT8: - if (!PyArg_ParseTuple(extremap, "ii", &i0, &i1)) - return NULL; - /* FIXME: clip */ - extrema.u[0] = i0; - extrema.u[1] = i1; - break; - case IMAGING_TYPE_INT32: - if (!PyArg_ParseTuple(extremap, "ii", &i0, &i1)) - return NULL; - extrema.i[0] = i0; - extrema.i[1] = i1; - break; - case IMAGING_TYPE_FLOAT32: - if (!PyArg_ParseTuple(extremap, "dd", &f0, &f1)) - return NULL; - extrema.f[0] = (FLOAT32) f0; - extrema.f[1] = (FLOAT32) f1; - break; - default: - ep = NULL; - break; - } - } else - ep = NULL; - - h = ImagingGetHistogram(self->image, (maskp) ? maskp->image : NULL, ep); - - if (!h) - return NULL; - - /* Build an integer list containing the histogram */ - list = PyList_New(h->bands * 256); - for (i = 0; i < h->bands * 256; i++) { - PyObject* item; - item = PyInt_FromLong(h->histogram[i]); - if (item == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - PyList_SetItem(list, i, item); - } - - ImagingHistogramDelete(h); - - return list; -} - -#ifdef WITH_MODEFILTER -static PyObject* -_modefilter(ImagingObject* self, PyObject* args) -{ - int size; - if (!PyArg_ParseTuple(args, "i", &size)) - return NULL; - - return PyImagingNew(ImagingModeFilter(self->image, size)); -} -#endif - -static PyObject* -_offset(ImagingObject* self, PyObject* args) -{ - int xoffset, yoffset; - if (!PyArg_ParseTuple(args, "ii", &xoffset, &yoffset)) - return NULL; - - return PyImagingNew(ImagingOffset(self->image, xoffset, yoffset)); -} - -static PyObject* -_paste(ImagingObject* self, PyObject* args) -{ - int status; - char ink[4]; - - PyObject* source; - int x0, y0, x1, y1; - ImagingObject* maskp = NULL; - if (!PyArg_ParseTuple(args, "O(iiii)|O!", - &source, - &x0, &y0, &x1, &y1, - &Imaging_Type, &maskp)) - return NULL; - - if (PyImaging_Check(source)) - status = ImagingPaste( - self->image, PyImaging_AsImaging(source), - (maskp) ? maskp->image : NULL, - x0, y0, x1, y1 - ); - - else { - if (!getink(source, self->image, ink)) - return NULL; - status = ImagingFill2( - self->image, ink, - (maskp) ? maskp->image : NULL, - x0, y0, x1, y1 - ); - } - - if (status < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_point(ImagingObject* self, PyObject* args) -{ - static const char* wrong_number = "wrong number of lut entries"; - - int n, i; - int bands; - Imaging im; - - PyObject* list; - char* mode; - if (!PyArg_ParseTuple(args, "Oz", &list, &mode)) - return NULL; - - if (mode && !strcmp(mode, "F")) { - FLOAT32* data; - - /* map from 8-bit data to floating point */ - n = 256; - data = getlist(list, &n, wrong_number, TYPE_FLOAT32); - if (!data) - return NULL; - im = ImagingPoint(self->image, mode, (void*) data); - free(data); - - } else if (!strcmp(self->image->mode, "I") && mode && !strcmp(mode, "L")) { - UINT8* data; - - /* map from 16-bit subset of 32-bit data to 8-bit */ - /* FIXME: support arbitrary number of entries (requires API change) */ - n = 65536; - data = getlist(list, &n, wrong_number, TYPE_UINT8); - if (!data) - return NULL; - im = ImagingPoint(self->image, mode, (void*) data); - free(data); - - } else { - INT32* data; - UINT8 lut[1024]; - - if (mode) { - bands = getbands(mode); - if (bands < 0) - return NULL; - } else - bands = self->image->bands; - - /* map to integer data */ - n = 256 * bands; - data = getlist(list, &n, wrong_number, TYPE_INT32); - if (!data) - return NULL; - - if (mode && !strcmp(mode, "I")) - im = ImagingPoint(self->image, mode, (void*) data); - else if (mode && bands > 1) { - for (i = 0; i < 256; i++) { - lut[i*4] = CLIP(data[i]); - lut[i*4+1] = CLIP(data[i+256]); - lut[i*4+2] = CLIP(data[i+512]); - if (n > 768) - lut[i*4+3] = CLIP(data[i+768]); - } - im = ImagingPoint(self->image, mode, (void*) lut); - } else { - /* map individual bands */ - for (i = 0; i < n; i++) - lut[i] = CLIP(data[i]); - im = ImagingPoint(self->image, mode, (void*) lut); - } - free(data); - } - - return PyImagingNew(im); -} - -static PyObject* -_point_transform(ImagingObject* self, PyObject* args) -{ - double scale = 1.0; - double offset = 0.0; - if (!PyArg_ParseTuple(args, "|dd", &scale, &offset)) - return NULL; - - return PyImagingNew(ImagingPointTransform(self->image, scale, offset)); -} - -static PyObject* -_putdata(ImagingObject* self, PyObject* args) -{ - Imaging image; - int n, i, x, y; - - PyObject* data; - double scale = 1.0; - double offset = 0.0; - if (!PyArg_ParseTuple(args, "O|dd", &data, &scale, &offset)) - return NULL; - - if (!PySequence_Check(data)) { - PyErr_SetString(PyExc_TypeError, must_be_sequence); - return NULL; - } - - image = self->image; - - n = PyObject_Length(data); - if (n > (int) (image->xsize * image->ysize)) { - PyErr_SetString(PyExc_TypeError, "too many data entries"); - return NULL; - } - - if (image->image8) { - if (PyString_Check(data)) { - unsigned char* p; - p = (unsigned char*) PyString_AS_STRING((PyStringObject*) data); - if (scale == 1.0 && offset == 0.0) - /* Plain string data */ - for (i = y = 0; i < n; i += image->xsize, y++) { - x = n - i; - if (x > (int) image->xsize) - x = image->xsize; - memcpy(image->image8[y], p+i, x); - } - else - /* Scaled and clipped string data */ - for (i = x = y = 0; i < n; i++) { - image->image8[y][x] = CLIP((int) (p[i] * scale + offset)); - if (++x >= (int) image->xsize) - x = 0, y++; - } - } else { - if (scale == 1.0 && offset == 0.0) { - /* Clipped data */ - if (PyList_Check(data)) { - for (i = x = y = 0; i < n; i++) { - PyObject *op = PyList_GET_ITEM(data, i); - image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op)); - if (++x >= (int) image->xsize) - x = 0, y++; - } - } else { - for (i = x = y = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(data, i); - image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op)); - Py_XDECREF(op); - if (++x >= (int) image->xsize) - x = 0, y++; - } - } - } else { - if (PyList_Check(data)) { - /* Scaled and clipped data */ - for (i = x = y = 0; i < n; i++) { - PyObject *op = PyList_GET_ITEM(data, i); - image->image8[y][x] = CLIP( - (int) (PyFloat_AsDouble(op) * scale + offset)); - if (++x >= (int) image->xsize) - x = 0, y++; - } - } else { - for (i = x = y = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(data, i); - image->image8[y][x] = CLIP( - (int) (PyFloat_AsDouble(op) * scale + offset)); - Py_XDECREF(op); - if (++x >= (int) image->xsize) - x = 0, y++; - } - } - } - PyErr_Clear(); /* Avoid weird exceptions */ - } - } else { - /* 32-bit images */ - switch (image->type) { - case IMAGING_TYPE_INT32: - for (i = x = y = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(data, i); - IMAGING_PIXEL_INT32(image, x, y) = - (INT32) (PyFloat_AsDouble(op) * scale + offset); - Py_XDECREF(op); - if (++x >= (int) image->xsize) - x = 0, y++; - } - PyErr_Clear(); /* Avoid weird exceptions */ - break; - case IMAGING_TYPE_FLOAT32: - for (i = x = y = 0; i < n; i++) { - PyObject *op = PySequence_GetItem(data, i); - IMAGING_PIXEL_FLOAT32(image, x, y) = - (FLOAT32) (PyFloat_AsDouble(op) * scale + offset); - Py_XDECREF(op); - if (++x >= (int) image->xsize) - x = 0, y++; - } - PyErr_Clear(); /* Avoid weird exceptions */ - break; - default: - for (i = x = y = 0; i < n; i++) { - char ink[4]; - PyObject *op = PySequence_GetItem(data, i); - if (!op || !getink(op, image, ink)) { - Py_DECREF(op); - return NULL; - } - /* FIXME: what about scale and offset? */ - image->image32[y][x] = *((INT32*) ink); - Py_XDECREF(op); - if (++x >= (int) image->xsize) - x = 0, y++; - } - PyErr_Clear(); /* Avoid weird exceptions */ - break; - } - } - - Py_INCREF(Py_None); - return Py_None; -} - -#ifdef WITH_QUANTIZE - -#include "Quant.h" -static PyObject* -_quantize(ImagingObject* self, PyObject* args) -{ - int colours = 256; - int method = 0; - int kmeans = 0; - if (!PyArg_ParseTuple(args, "|iii", &colours, &method, &kmeans)) - return NULL; - - if (!self->image->xsize || !self->image->ysize) { - /* no content; return an empty image */ - return PyImagingNew( - ImagingNew("P", self->image->xsize, self->image->ysize) - ); - } - - return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans)); -} -#endif - -static PyObject* -_putpalette(ImagingObject* self, PyObject* args) -{ - ImagingShuffler unpack; - int bits; - - char* rawmode; - UINT8* palette; - int palettesize; - if (!PyArg_ParseTuple(args, "ss#", &rawmode, &palette, &palettesize)) - return NULL; - - if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) { - PyErr_SetString(PyExc_ValueError, wrong_mode); - return NULL; - } - - unpack = ImagingFindUnpacker("RGB", rawmode, &bits); - if (!unpack) { - PyErr_SetString(PyExc_ValueError, wrong_raw_mode); - return NULL; - } - - ImagingPaletteDelete(self->image->palette); - - strcpy(self->image->mode, "P"); - - self->image->palette = ImagingPaletteNew("RGB"); - - unpack(self->image->palette->palette, palette, palettesize * 8 / bits); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_putpalettealpha(ImagingObject* self, PyObject* args) -{ - int index; - int alpha = 0; - if (!PyArg_ParseTuple(args, "i|i", &index, &alpha)) - return NULL; - - if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; - } - - if (index < 0 || index >= 256) { - PyErr_SetString(PyExc_ValueError, outside_palette); - return NULL; - } - - strcpy(self->image->palette->mode, "RGBA"); - self->image->palette->palette[index*4+3] = (UINT8) alpha; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_putpixel(ImagingObject* self, PyObject* args) -{ - Imaging im; - char ink[4]; - - int x, y; - PyObject* color; - if (!PyArg_ParseTuple(args, "(ii)O", &x, &y, &color)) - return NULL; - - im = self->image; - - if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return NULL; - } - - if (!getink(color, im, ink)) - return NULL; - - if (self->access) - self->access->put_pixel(im, x, y, ink); - - Py_INCREF(Py_None); - return Py_None; -} - -#ifdef WITH_RANKFILTER -static PyObject* -_rankfilter(ImagingObject* self, PyObject* args) -{ - int size, rank; - if (!PyArg_ParseTuple(args, "ii", &size, &rank)) - return NULL; - - return PyImagingNew(ImagingRankFilter(self->image, size, rank)); -} -#endif - -static PyObject* -_resize(ImagingObject* self, PyObject* args) -{ - Imaging imIn; - Imaging imOut; - - int xsize, ysize; - int filter = IMAGING_TRANSFORM_NEAREST; - if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) - return NULL; - - imIn = self->image; - - imOut = ImagingNew(imIn->mode, xsize, ysize); - if (imOut) - (void) ImagingResize(imOut, imIn, filter); - - return PyImagingNew(imOut); -} - -static PyObject* -_rotate(ImagingObject* self, PyObject* args) -{ - Imaging imOut; - Imaging imIn; - - double theta; - int filter = IMAGING_TRANSFORM_NEAREST; - if (!PyArg_ParseTuple(args, "d|i", &theta, &filter)) - return NULL; - - imIn = self->image; - - theta = fmod(theta, 360.0); - if (theta < 0.0) - theta += 360; - - if (filter && imIn->type != IMAGING_TYPE_SPECIAL) { - /* Rotate with resampling filter */ - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - (void) ImagingRotate(imOut, imIn, theta, filter); - } else if (theta == 90.0 || theta == 270.0) { - /* Use fast version */ - imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize); - if (imOut) { - if (theta == 90.0) - (void) ImagingRotate90(imOut, imIn); - else - (void) ImagingRotate270(imOut, imIn); - } - } else { - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - if (imOut) { - if (theta == 0.0) - /* No rotation: simply copy the input image */ - (void) ImagingCopy2(imOut, imIn); - else if (theta == 180.0) - /* Use fast version */ - (void) ImagingRotate180(imOut, imIn); - else - /* Use ordinary version */ - (void) ImagingRotate(imOut, imIn, theta, 0); - } - } - - return PyImagingNew(imOut); -} - -#define IS_RGB(mode)\ - (!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode, "RGBX")) - -static PyObject* -im_setmode(ImagingObject* self, PyObject* args) -{ - /* attempt to modify the mode of an image in place */ - - Imaging im; - - char* mode; - int modelen; - if (!PyArg_ParseTuple(args, "s#:setmode", &mode, &modelen)) - return NULL; - - im = self->image; - - /* move all logic in here to the libImaging primitive */ - - if (!strcmp(im->mode, mode)) { - ; /* same mode; always succeeds */ - } else if (IS_RGB(im->mode) && IS_RGB(mode)) { - /* color to color */ - strcpy(im->mode, mode); - im->bands = modelen; - if (!strcmp(mode, "RGBA")) - (void) ImagingFillBand(im, 3, 255); - } else { - /* trying doing an in-place conversion */ - if (!ImagingConvertInPlace(im, mode)) - return NULL; - } - - if (self->access) - ImagingAccessDelete(im, self->access); - self->access = ImagingAccessNew(im); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_stretch(ImagingObject* self, PyObject* args) -{ - Imaging imIn; - Imaging imTemp; - Imaging imOut; - - int xsize, ysize; - int filter = IMAGING_TRANSFORM_NEAREST; - if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) - return NULL; - - imIn = self->image; - - /* two-pass resize: minimize size of intermediate image */ - if (imIn->xsize * ysize < xsize * imIn->ysize) - imTemp = ImagingNew(imIn->mode, imIn->xsize, ysize); - else - imTemp = ImagingNew(imIn->mode, xsize, imIn->ysize); - if (!imTemp) - return NULL; - - /* first pass */ - if (!ImagingStretch(imTemp, imIn, filter)) { - ImagingDelete(imTemp); - return NULL; - } - - imOut = ImagingNew(imIn->mode, xsize, ysize); - if (!imOut) { - ImagingDelete(imTemp); - return NULL; - } - - /* second pass */ - if (!ImagingStretch(imOut, imTemp, filter)) { - ImagingDelete(imOut); - ImagingDelete(imTemp); - return NULL; - } - - ImagingDelete(imTemp); - - return PyImagingNew(imOut); -} - -static PyObject* -_transform2(ImagingObject* self, PyObject* args) -{ - static const char* wrong_number = "wrong number of matrix entries"; - - Imaging imIn; - Imaging imOut; - int n; - double *a; - - ImagingObject* imagep; - int x0, y0, x1, y1; - int method; - PyObject* data; - int filter = IMAGING_TRANSFORM_NEAREST; - int fill = 1; - if (!PyArg_ParseTuple(args, "(iiii)O!iO|ii", - &x0, &y0, &x1, &y1, - &Imaging_Type, &imagep, - &method, &data, - &filter, &fill)) - return NULL; - - switch (method) { - case IMAGING_TRANSFORM_AFFINE: - n = 6; - break; - case IMAGING_TRANSFORM_PERSPECTIVE: - n = 8; - break; - case IMAGING_TRANSFORM_QUAD: - n = 8; - break; - default: - n = -1; /* force error */ - } - - a = getlist(data, &n, wrong_number, TYPE_DOUBLE); - if (!a) - return NULL; - - imOut = self->image; - imIn = imagep->image; - - /* FIXME: move transform dispatcher into libImaging */ - - switch (method) { - case IMAGING_TRANSFORM_AFFINE: - imOut = ImagingTransformAffine( - imOut, imIn, x0, y0, x1, y1, a, filter, 1 - ); - break; - case IMAGING_TRANSFORM_PERSPECTIVE: - imOut = ImagingTransformPerspective( - imOut, imIn, x0, y0, x1, y1, a, filter, 1 - ); - break; - case IMAGING_TRANSFORM_QUAD: - imOut = ImagingTransformQuad( - imOut, imIn, x0, y0, x1, y1, a, filter, 1 - ); - break; - default: - (void) ImagingError_ValueError("bad transform method"); - } - - free(a); - - if (!imOut) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_transpose(ImagingObject* self, PyObject* args) -{ - Imaging imIn; - Imaging imOut; - - int op; - if (!PyArg_ParseTuple(args, "i", &op)) - return NULL; - - imIn = self->image; - - switch (op) { - case 0: /* flip left right */ - case 1: /* flip top bottom */ - case 3: /* rotate 180 */ - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - break; - case 2: /* rotate 90 */ - case 4: /* rotate 270 */ - imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize); - break; - default: - PyErr_SetString(PyExc_ValueError, "No such transpose operation"); - return NULL; - } - - if (imOut) - switch (op) { - case 0: - (void) ImagingFlipLeftRight(imOut, imIn); - break; - case 1: - (void) ImagingFlipTopBottom(imOut, imIn); - break; - case 2: - (void) ImagingRotate90(imOut, imIn); - break; - case 3: - (void) ImagingRotate180(imOut, imIn); - break; - case 4: - (void) ImagingRotate270(imOut, imIn); - break; - } - - return PyImagingNew(imOut); -} - -#ifdef WITH_UNSHARPMASK -static PyObject* -_unsharp_mask(ImagingObject* self, PyObject* args) -{ - Imaging imIn; - Imaging imOut; - - float radius; - int percent, threshold; - if (!PyArg_ParseTuple(args, "fii", &radius, &percent, &threshold)) - return NULL; - - - imIn = self->image; - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - if (!imOut) - return NULL; - - if (!ImagingUnsharpMask(imIn, imOut, radius, percent, threshold)) - return NULL; - - return PyImagingNew(imOut); -} -#endif - -/* -------------------------------------------------------------------- */ - -static PyObject* -_isblock(ImagingObject* self, PyObject* args) -{ - return PyInt_FromLong((long) self->image->block); -} - -static PyObject* -_getbbox(ImagingObject* self, PyObject* args) -{ - int bbox[4]; - if (!ImagingGetBBox(self->image, bbox)) { - Py_INCREF(Py_None); - return Py_None; - } - - return Py_BuildValue("iiii", bbox[0], bbox[1], bbox[2], bbox[3]); -} - -static PyObject* -_getcolors(ImagingObject* self, PyObject* args) -{ - ImagingColorItem* items; - int i, colors; - PyObject* out; - - int maxcolors = 256; - if (!PyArg_ParseTuple(args, "i:getcolors", &maxcolors)) - return NULL; - - items = ImagingGetColors(self->image, maxcolors, &colors); - if (!items) - return NULL; - - if (colors > maxcolors) { - out = Py_None; - Py_INCREF(out); - } else { - out = PyList_New(colors); - for (i = 0; i < colors; i++) { - ImagingColorItem* v = &items[i]; - PyObject* item = Py_BuildValue( - "iN", v->count, getpixel(self->image, self->access, v->x, v->y) - ); - PyList_SetItem(out, i, item); - } - } - - free(items); - - return out; -} - -static PyObject* -_getextrema(ImagingObject* self, PyObject* args) -{ - union { - UINT8 u[2]; - INT32 i[2]; - FLOAT32 f[2]; - } extrema; - int status; - - status = ImagingGetExtrema(self->image, &extrema); - if (status < 0) - return NULL; - - if (status) - switch (self->image->type) { - case IMAGING_TYPE_UINT8: - return Py_BuildValue("ii", extrema.u[0], extrema.u[1]); - case IMAGING_TYPE_INT32: - return Py_BuildValue("ii", extrema.i[0], extrema.i[1]); - case IMAGING_TYPE_FLOAT32: - return Py_BuildValue("dd", extrema.f[0], extrema.f[1]); - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_getprojection(ImagingObject* self, PyObject* args) -{ - unsigned char* xprofile; - unsigned char* yprofile; - PyObject* result; - - xprofile = malloc(self->image->xsize); - yprofile = malloc(self->image->ysize); - - if (xprofile == NULL || yprofile == NULL) { - free(xprofile); - free(yprofile); - return PyErr_NoMemory(); - } - - ImagingGetProjection(self->image, (unsigned char *)xprofile, (unsigned char *)yprofile); - - result = Py_BuildValue("s#s#", xprofile, self->image->xsize, - yprofile, self->image->ysize); - - free(xprofile); - free(yprofile); - - return result; -} - -/* -------------------------------------------------------------------- */ - -static PyObject* -_getband(ImagingObject* self, PyObject* args) -{ - int band; - - if (!PyArg_ParseTuple(args, "i", &band)) - return NULL; - - return PyImagingNew(ImagingGetBand(self->image, band)); -} - -static PyObject* -_fillband(ImagingObject* self, PyObject* args) -{ - int band; - int color; - - if (!PyArg_ParseTuple(args, "ii", &band, &color)) - return NULL; - - if (!ImagingFillBand(self->image, band, color)) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_putband(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - int band; - if (!PyArg_ParseTuple(args, "O!i", - &Imaging_Type, &imagep, - &band)) - return NULL; - - if (!ImagingPutBand(self->image, imagep->image, band)) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -/* -------------------------------------------------------------------- */ - -#ifdef WITH_IMAGECHOPS - -static PyObject* -_chop_invert(ImagingObject* self, PyObject* args) -{ - return PyImagingNew(ImagingNegative(self->image)); -} - -static PyObject* -_chop_lighter(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopLighter(self->image, imagep->image)); -} - -static PyObject* -_chop_darker(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopDarker(self->image, imagep->image)); -} - -static PyObject* -_chop_difference(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopDifference(self->image, imagep->image)); -} - -static PyObject* -_chop_multiply(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopMultiply(self->image, imagep->image)); -} - -static PyObject* -_chop_screen(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopScreen(self->image, imagep->image)); -} - -static PyObject* -_chop_add(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - float scale; - int offset; - - scale = 1.0; - offset = 0; - - if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep, - &scale, &offset)) - return NULL; - - return PyImagingNew(ImagingChopAdd(self->image, imagep->image, - scale, offset)); -} - -static PyObject* -_chop_subtract(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - float scale; - int offset; - - scale = 1.0; - offset = 0; - - if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep, - &scale, &offset)) - return NULL; - - return PyImagingNew(ImagingChopSubtract(self->image, imagep->image, - scale, offset)); -} - -static PyObject* -_chop_and(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopAnd(self->image, imagep->image)); -} - -static PyObject* -_chop_or(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopOr(self->image, imagep->image)); -} - -static PyObject* -_chop_xor(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopXor(self->image, imagep->image)); -} - -static PyObject* -_chop_add_modulo(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopAddModulo(self->image, imagep->image)); -} - -static PyObject* -_chop_subtract_modulo(ImagingObject* self, PyObject* args) -{ - ImagingObject* imagep; - - if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; - - return PyImagingNew(ImagingChopSubtractModulo(self->image, imagep->image)); -} - -#endif - - -/* -------------------------------------------------------------------- */ - -#ifdef WITH_IMAGEDRAW - -static PyObject* -_font_new(PyObject* self_, PyObject* args) -{ - ImagingFontObject *self; - int i, y0, y1; - static const char* wrong_length = "descriptor table has wrong size"; - - ImagingObject* imagep; - unsigned char* glyphdata; - int glyphdata_length; - if (!PyArg_ParseTuple(args, "O!s#", - &Imaging_Type, &imagep, - &glyphdata, &glyphdata_length)) - return NULL; - - if (glyphdata_length != 256 * 20) { - PyErr_SetString(PyExc_ValueError, wrong_length); - return NULL; - } - - self = PyObject_New(ImagingFontObject, &ImagingFont_Type); - if (self == NULL) - return NULL; - - /* glyph bitmap */ - self->bitmap = imagep->image; - - y0 = y1 = 0; - - /* glyph glyphs */ - for (i = 0; i < 256; i++) { - self->glyphs[i].dx = S16(B16(glyphdata, 0)); - self->glyphs[i].dy = S16(B16(glyphdata, 2)); - self->glyphs[i].dx0 = S16(B16(glyphdata, 4)); - self->glyphs[i].dy0 = S16(B16(glyphdata, 6)); - self->glyphs[i].dx1 = S16(B16(glyphdata, 8)); - self->glyphs[i].dy1 = S16(B16(glyphdata, 10)); - self->glyphs[i].sx0 = S16(B16(glyphdata, 12)); - self->glyphs[i].sy0 = S16(B16(glyphdata, 14)); - self->glyphs[i].sx1 = S16(B16(glyphdata, 16)); - self->glyphs[i].sy1 = S16(B16(glyphdata, 18)); - if (self->glyphs[i].dy0 < y0) - y0 = self->glyphs[i].dy0; - if (self->glyphs[i].dy1 > y1) - y1 = self->glyphs[i].dy1; - glyphdata += 20; - } - - self->baseline = -y0; - self->ysize = y1 - y0; - - /* keep a reference to the bitmap object */ - Py_INCREF(imagep); - self->ref = imagep; - - return (PyObject*) self; -} - -static void -_font_dealloc(ImagingFontObject* self) -{ - Py_XDECREF(self->ref); - PyObject_Del(self); -} - -static inline int -textwidth(ImagingFontObject* self, const unsigned char* text) -{ - int xsize; - - for (xsize = 0; *text; text++) - xsize += self->glyphs[*text].dx; - - return xsize; -} - -static PyObject* -_font_getmask(ImagingFontObject* self, PyObject* args) -{ - Imaging im; - Imaging bitmap; - int x, b; - int status; - Glyph* glyph; - - unsigned char* text; - char* mode = ""; - if (!PyArg_ParseTuple(args, "s|s:getmask", &text, &mode)) - return NULL; - - im = ImagingNew(self->bitmap->mode, textwidth(self, text), self->ysize); - if (!im) - return NULL; - - b = 0; - (void) ImagingFill(im, &b); - - b = self->baseline; - for (x = 0; *text; text++) { - glyph = &self->glyphs[*text]; - bitmap = ImagingCrop( - self->bitmap, - glyph->sx0, glyph->sy0, glyph->sx1, glyph->sy1 - ); - if (!bitmap) - goto failed; - status = ImagingPaste( - im, bitmap, NULL, - glyph->dx0+x, glyph->dy0+b, glyph->dx1+x, glyph->dy1+b - ); - ImagingDelete(bitmap); - if (status < 0) - goto failed; - x = x + glyph->dx; - b = b + glyph->dy; - } - - return PyImagingNew(im); - - failed: - ImagingDelete(im); - return NULL; -} - -static PyObject* -_font_getsize(ImagingFontObject* self, PyObject* args) -{ - unsigned char* text; - if (!PyArg_ParseTuple(args, "s:getsize", &text)) - return NULL; - - return Py_BuildValue("ii", textwidth(self, text), self->ysize); -} - -static struct PyMethodDef _font_methods[] = { - {"getmask", (PyCFunction)_font_getmask, 1}, - {"getsize", (PyCFunction)_font_getsize, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -_font_getattr(ImagingFontObject* self, char* name) -{ - return Py_FindMethod(_font_methods, (PyObject*) self, name); -} - -/* -------------------------------------------------------------------- */ - -static PyObject* -_draw_new(PyObject* self_, PyObject* args) -{ - ImagingDrawObject *self; - - ImagingObject* imagep; - int blend = 0; - if (!PyArg_ParseTuple(args, "O!|i", &Imaging_Type, &imagep, &blend)) - return NULL; - - self = PyObject_New(ImagingDrawObject, &ImagingDraw_Type); - if (self == NULL) - return NULL; - - /* keep a reference to the image object */ - Py_INCREF(imagep); - self->image = imagep; - - self->ink[0] = self->ink[1] = self->ink[2] = self->ink[3] = 0; - - self->blend = blend; - - return (PyObject*) self; -} - -static void -_draw_dealloc(ImagingDrawObject* self) -{ - Py_XDECREF(self->image); - PyObject_Del(self); -} - -extern int PyPath_Flatten(PyObject* data, double **xy); - -static PyObject* -_draw_ink(ImagingDrawObject* self, PyObject* args) -{ - INT32 ink = 0; - PyObject* color; - char* mode = NULL; /* not used in this release */ - if (!PyArg_ParseTuple(args, "O|s", &color, &mode)) - return NULL; - - if (!getink(color, self->image->image, (char*) &ink)) - return NULL; - - return PyInt_FromLong((int) ink); -} - -static PyObject* -_draw_arc(ImagingDrawObject* self, PyObject* args) -{ - int x0, y0, x1, y1; - int ink; - int start, end; - int op = 0; - if (!PyArg_ParseTuple(args, "(iiii)iii|i", - &x0, &y0, &x1, &y1, - &start, &end, &ink)) - return NULL; - - if (ImagingDrawArc(self->image->image, x0, y0, x1, y1, start, end, - &ink, op) < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_bitmap(ImagingDrawObject* self, PyObject* args) -{ - double *xy; - int n; - - PyObject *data; - ImagingObject* bitmap; - int ink; - if (!PyArg_ParseTuple(args, "OO!i", &data, &Imaging_Type, &bitmap, &ink)) - return NULL; - - n = PyPath_Flatten(data, &xy); - if (n < 0) - return NULL; - if (n != 1) { - PyErr_SetString( - PyExc_TypeError, - "coordinate list must contain exactly 1 coordinate" - ); - return NULL; - } - - n = ImagingDrawBitmap( - self->image->image, (int) xy[0], (int) xy[1], bitmap->image, - &ink, self->blend - ); - - free(xy); - - if (n < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_chord(ImagingDrawObject* self, PyObject* args) -{ - int x0, y0, x1, y1; - int ink, fill; - int start, end; - if (!PyArg_ParseTuple(args, "(iiii)iiii", - &x0, &y0, &x1, &y1, &start, &end, &ink, &fill)) - return NULL; - - if (ImagingDrawChord(self->image->image, x0, y0, x1, y1, - start, end, &ink, fill, self->blend) < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_ellipse(ImagingDrawObject* self, PyObject* args) -{ - double* xy; - int n; - - PyObject* data; - int ink; - int fill = 0; - if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) - return NULL; - - n = PyPath_Flatten(data, &xy); - if (n < 0) - return NULL; - if (n != 2) { - PyErr_SetString( - PyExc_TypeError, - "coordinate list must contain exactly 2 coordinates" - ); - return NULL; - } - - n = ImagingDrawEllipse( - self->image->image, (int) xy[0], (int) xy[1], (int) xy[2], (int) xy[3], - &ink, fill, self->blend - ); - - free(xy); - - if (n < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_line(ImagingDrawObject* self, PyObject* args) -{ - int x0, y0, x1, y1; - int ink; - if (!PyArg_ParseTuple(args, "(ii)(ii)i", &x0, &y0, &x1, &y1, &ink)) - return NULL; - - if (ImagingDrawLine(self->image->image, x0, y0, x1, y1, - &ink, self->blend) < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_lines(ImagingDrawObject* self, PyObject* args) -{ - double *xy; - int i, n; - - PyObject *data; - int ink; - int width = 0; - if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &width)) - return NULL; - - n = PyPath_Flatten(data, &xy); - if (n < 0) - return NULL; - - if (width <= 1) { - double *p = NULL; - for (i = 0; i < n-1; i++) { - p = &xy[i+i]; - if (ImagingDrawLine( - self->image->image, - (int) p[0], (int) p[1], (int) p[2], (int) p[3], - &ink, self->blend) < 0) { - free(xy); - return NULL; - } - } - if (p) /* draw last point */ - ImagingDrawPoint( - self->image->image, - (int) p[2], (int) p[3], - &ink, self->blend - ); - } else { - for (i = 0; i < n-1; i++) { - double *p = &xy[i+i]; - if (ImagingDrawWideLine( - self->image->image, - (int) p[0], (int) p[1], (int) p[2], (int) p[3], - &ink, width, self->blend) < 0) { - free(xy); - return NULL; - } - } - } - - free(xy); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_point(ImagingDrawObject* self, PyObject* args) -{ - int x, y; - int ink; - if (!PyArg_ParseTuple(args, "(ii)i", &x, &y, &ink)) - return NULL; - - if (ImagingDrawPoint(self->image->image, x, y, &ink, self->blend) < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_points(ImagingDrawObject* self, PyObject* args) -{ - double *xy; - int i, n; - - PyObject *data; - int ink; - if (!PyArg_ParseTuple(args, "Oi", &data, &ink)) - return NULL; - - n = PyPath_Flatten(data, &xy); - if (n < 0) - return NULL; - - for (i = 0; i < n; i++) { - double *p = &xy[i+i]; - if (ImagingDrawPoint(self->image->image, (int) p[0], (int) p[1], - &ink, self->blend) < 0) { - free(xy); - return NULL; - } - } - - free(xy); - - Py_INCREF(Py_None); - return Py_None; -} - -#ifdef WITH_ARROW - -/* from outline.c */ -extern ImagingOutline PyOutline_AsOutline(PyObject* outline); - -static PyObject* -_draw_outline(ImagingDrawObject* self, PyObject* args) -{ - ImagingOutline outline; - - PyObject* outline_; - int ink; - int fill = 0; - if (!PyArg_ParseTuple(args, "Oi|i", &outline_, &ink, &fill)) - return NULL; - - outline = PyOutline_AsOutline(outline_); - if (!outline) { - PyErr_SetString(PyExc_TypeError, "expected outline object"); - return NULL; - } - - if (ImagingDrawOutline(self->image->image, outline, - &ink, fill, self->blend) < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -#endif - -static PyObject* -_draw_pieslice(ImagingDrawObject* self, PyObject* args) -{ - int x0, y0, x1, y1; - int ink, fill; - int start, end; - if (!PyArg_ParseTuple(args, "(iiii)iiii", - &x0, &y0, &x1, &y1, &start, &end, &ink, &fill)) - return NULL; - - if (ImagingDrawPieslice(self->image->image, x0, y0, x1, y1, - start, end, &ink, fill, self->blend) < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_polygon(ImagingDrawObject* self, PyObject* args) -{ - double *xy; - int *ixy; - int n, i; - - PyObject* data; - int ink; - int fill = 0; - if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) - return NULL; - - n = PyPath_Flatten(data, &xy); - if (n < 0) - return NULL; - if (n < 2) { - PyErr_SetString( - PyExc_TypeError, - "coordinate list must contain at least 2 coordinates" - ); - return NULL; - } - - /* Copy list of vertices to array */ - ixy = (int*) malloc(n * 2 * sizeof(int)); - - for (i = 0; i < n; i++) { - ixy[i+i] = (int) xy[i+i]; - ixy[i+i+1] = (int) xy[i+i+1]; - } - - free(xy); - - if (ImagingDrawPolygon(self->image->image, n, ixy, - &ink, fill, self->blend) < 0) { - free(ixy); - return NULL; - } - - free(ixy); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw_rectangle(ImagingDrawObject* self, PyObject* args) -{ - double* xy; - int n; - - PyObject* data; - int ink; - int fill = 0; - if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) - return NULL; - - n = PyPath_Flatten(data, &xy); - if (n < 0) - return NULL; - if (n != 2) { - PyErr_SetString( - PyExc_TypeError, - "coordinate list must contain exactly 2 coordinates" - ); - return NULL; - } - - n = ImagingDrawRectangle( - self->image->image, (int) xy[0], (int) xy[1], - (int) xy[2], (int) xy[3], &ink, fill, self->blend - ); - - free(xy); - - if (n < 0) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -static struct PyMethodDef _draw_methods[] = { -#ifdef WITH_IMAGEDRAW - /* Graphics (ImageDraw) */ - {"draw_line", (PyCFunction)_draw_line, 1}, - {"draw_lines", (PyCFunction)_draw_lines, 1}, -#ifdef WITH_ARROW - {"draw_outline", (PyCFunction)_draw_outline, 1}, -#endif - {"draw_polygon", (PyCFunction)_draw_polygon, 1}, - {"draw_rectangle", (PyCFunction)_draw_rectangle, 1}, - {"draw_point", (PyCFunction)_draw_point, 1}, - {"draw_points", (PyCFunction)_draw_points, 1}, - {"draw_arc", (PyCFunction)_draw_arc, 1}, - {"draw_bitmap", (PyCFunction)_draw_bitmap, 1}, - {"draw_chord", (PyCFunction)_draw_chord, 1}, - {"draw_ellipse", (PyCFunction)_draw_ellipse, 1}, - {"draw_pieslice", (PyCFunction)_draw_pieslice, 1}, - {"draw_ink", (PyCFunction)_draw_ink, 1}, -#endif - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -_draw_getattr(ImagingDrawObject* self, char* name) -{ - return Py_FindMethod(_draw_methods, (PyObject*) self, name); -} - -#endif - - -static PyObject* -pixel_access_new(ImagingObject* imagep, PyObject* args) -{ - PixelAccessObject *self; - - int readonly = 0; - if (!PyArg_ParseTuple(args, "|i", &readonly)) - return NULL; - - self = PyObject_New(PixelAccessObject, &PixelAccess_Type); - if (self == NULL) - return NULL; - - /* keep a reference to the image object */ - Py_INCREF(imagep); - self->image = imagep; - - self->readonly = readonly; - - return (PyObject*) self; -} - -static void -pixel_access_dealloc(PixelAccessObject* self) -{ - Py_XDECREF(self->image); - PyObject_Del(self); -} - -static PyObject * -pixel_access_getitem(PixelAccessObject *self, PyObject *xy) -{ - int x, y; - if (_getxy(xy, &x, &y)) - return NULL; - - return getpixel(self->image->image, self->image->access, x, y); -} - -static int -pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) -{ - Imaging im = self->image->image; - char ink[4]; - int x, y; - - if (self->readonly) { - (void) ImagingError_ValueError(readonly); - return -1; - } - - if (_getxy(xy, &x, &y)) - return -1; - - if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return -1; - } - - if (!color) /* FIXME: raise exception? */ - return 0; - - if (!getink(color, im, ink)) - return -1; - - self->image->access->put_pixel(im, x, y, ink); - - return 0; -} - -/* -------------------------------------------------------------------- */ -/* EFFECTS (experimental) */ -/* -------------------------------------------------------------------- */ - -#ifdef WITH_EFFECTS - -static PyObject* -_effect_mandelbrot(ImagingObject* self, PyObject* args) -{ - int xsize = 512; - int ysize = 512; - double extent[4]; - int quality = 100; - - extent[0] = -3; extent[1] = -2.5; - extent[2] = 2; extent[3] = 2.5; - - if (!PyArg_ParseTuple(args, "|(ii)(dddd)i", &xsize, &ysize, - &extent[0], &extent[1], &extent[2], &extent[3], - &quality)) - return NULL; - - return PyImagingNew(ImagingEffectMandelbrot(xsize, ysize, extent, quality)); -} - -static PyObject* -_effect_noise(ImagingObject* self, PyObject* args) -{ - int xsize, ysize; - float sigma = 128; - if (!PyArg_ParseTuple(args, "(ii)|f", &xsize, &ysize, &sigma)) - return NULL; - - return PyImagingNew(ImagingEffectNoise(xsize, ysize, sigma)); -} - -static PyObject* -_effect_spread(ImagingObject* self, PyObject* args) -{ - int dist; - - if (!PyArg_ParseTuple(args, "i", &dist)) - return NULL; - - return PyImagingNew(ImagingEffectSpread(self->image, dist)); -} - -#endif - -/* -------------------------------------------------------------------- */ -/* UTILITIES */ -/* -------------------------------------------------------------------- */ - -static PyObject* -_crc32(PyObject* self, PyObject* args) -{ - unsigned char* buffer; - int bytes; - int hi, lo; - UINT32 crc; - - hi = lo = 0; - - if (!PyArg_ParseTuple(args, "s#|(ii)", &buffer, &bytes, &hi, &lo)) - return NULL; - - crc = ((UINT32) (hi & 0xFFFF) << 16) + (lo & 0xFFFF); - - crc = ImagingCRC32(crc, (unsigned char *)buffer, bytes); - - return Py_BuildValue("ii", (crc >> 16) & 0xFFFF, crc & 0xFFFF); -} - -static PyObject* -_getcodecstatus(PyObject* self, PyObject* args) -{ - int status; - char* msg; - - if (!PyArg_ParseTuple(args, "i", &status)) - return NULL; - - switch (status) { - case IMAGING_CODEC_OVERRUN: - msg = "buffer overrun"; break; - case IMAGING_CODEC_BROKEN: - msg = "broken data stream"; break; - case IMAGING_CODEC_UNKNOWN: - msg = "unrecognized data stream contents"; break; - case IMAGING_CODEC_CONFIG: - msg = "codec configuration error"; break; - case IMAGING_CODEC_MEMORY: - msg = "out of memory"; break; - default: - Py_INCREF(Py_None); - return Py_None; - } - - return PyString_FromString(msg); -} - -/* -------------------------------------------------------------------- */ -/* DEBUGGING HELPERS */ -/* -------------------------------------------------------------------- */ - - -#ifdef WITH_DEBUG - -static PyObject* -_save_ppm(ImagingObject* self, PyObject* args) -{ - char* filename; - - if (!PyArg_ParseTuple(args, "s", &filename)) - return NULL; - - if (!ImagingSavePPM(self->image, filename)) - return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -#endif - -/* -------------------------------------------------------------------- */ - -/* methods */ - -static struct PyMethodDef methods[] = { - - /* Put commonly used methods first */ - {"getpixel", (PyCFunction)_getpixel, 1}, - {"putpixel", (PyCFunction)_putpixel, 1}, - - {"pixel_access", (PyCFunction)pixel_access_new, 1}, - - /* Standard processing methods (Image) */ - {"convert", (PyCFunction)_convert, 1}, - {"convert2", (PyCFunction)_convert2, 1}, - {"convert_matrix", (PyCFunction)_convert_matrix, 1}, - {"copy", (PyCFunction)_copy, 1}, - {"copy2", (PyCFunction)_copy2, 1}, -#ifdef WITH_CRACKCODE - {"crackcode", (PyCFunction)_crackcode, 1}, -#endif - {"crop", (PyCFunction)_crop, 1}, - {"expand", (PyCFunction)_expand, 1}, - {"filter", (PyCFunction)_filter, 1}, - {"histogram", (PyCFunction)_histogram, 1}, -#ifdef WITH_MODEFILTER - {"modefilter", (PyCFunction)_modefilter, 1}, -#endif - {"offset", (PyCFunction)_offset, 1}, - {"paste", (PyCFunction)_paste, 1}, - {"point", (PyCFunction)_point, 1}, - {"point_transform", (PyCFunction)_point_transform, 1}, - {"putdata", (PyCFunction)_putdata, 1}, -#ifdef WITH_QUANTIZE - {"quantize", (PyCFunction)_quantize, 1}, -#endif -#ifdef WITH_RANKFILTER - {"rankfilter", (PyCFunction)_rankfilter, 1}, -#endif - {"resize", (PyCFunction)_resize, 1}, - {"rotate", (PyCFunction)_rotate, 1}, - {"stretch", (PyCFunction)_stretch, 1}, - {"transpose", (PyCFunction)_transpose, 1}, - {"transform2", (PyCFunction)_transform2, 1}, - - {"isblock", (PyCFunction)_isblock, 1}, - - {"getbbox", (PyCFunction)_getbbox, 1}, - {"getcolors", (PyCFunction)_getcolors, 1}, - {"getextrema", (PyCFunction)_getextrema, 1}, - {"getprojection", (PyCFunction)_getprojection, 1}, - - {"getband", (PyCFunction)_getband, 1}, - {"putband", (PyCFunction)_putband, 1}, - {"fillband", (PyCFunction)_fillband, 1}, - - {"setmode", (PyCFunction)im_setmode, 1}, - - {"getpalette", (PyCFunction)_getpalette, 1}, - {"putpalette", (PyCFunction)_putpalette, 1}, - {"putpalettealpha", (PyCFunction)_putpalettealpha, 1}, - -#ifdef WITH_IMAGECHOPS - /* Channel operations (ImageChops) */ - {"chop_invert", (PyCFunction)_chop_invert, 1}, - {"chop_lighter", (PyCFunction)_chop_lighter, 1}, - {"chop_darker", (PyCFunction)_chop_darker, 1}, - {"chop_difference", (PyCFunction)_chop_difference, 1}, - {"chop_multiply", (PyCFunction)_chop_multiply, 1}, - {"chop_screen", (PyCFunction)_chop_screen, 1}, - {"chop_add", (PyCFunction)_chop_add, 1}, - {"chop_subtract", (PyCFunction)_chop_subtract, 1}, - {"chop_add_modulo", (PyCFunction)_chop_add_modulo, 1}, - {"chop_subtract_modulo", (PyCFunction)_chop_subtract_modulo, 1}, - {"chop_and", (PyCFunction)_chop_and, 1}, - {"chop_or", (PyCFunction)_chop_or, 1}, - {"chop_xor", (PyCFunction)_chop_xor, 1}, -#endif - -#ifdef WITH_UNSHARPMASK - /* Kevin Cazabon's unsharpmask extension */ - {"gaussian_blur", (PyCFunction)_gaussian_blur, 1}, - {"unsharp_mask", (PyCFunction)_unsharp_mask, 1}, -#endif - -#ifdef WITH_EFFECTS - /* Special effects */ - {"effect_spread", (PyCFunction)_effect_spread, 1}, -#endif - - /* Misc. */ - {"new_array", (PyCFunction)_new_array, 1}, - {"new_block", (PyCFunction)_new_block, 1}, - -#ifdef WITH_DEBUG - {"save_ppm", (PyCFunction)_save_ppm, 1}, -#endif - - {NULL, NULL} /* sentinel */ -}; - - -/* attributes */ - -static PyObject* -_getattr(ImagingObject* self, char* name) -{ - PyObject* res; - - res = Py_FindMethod(methods, (PyObject*) self, name); - if (res) - return res; - PyErr_Clear(); - if (strcmp(name, "mode") == 0) - return PyString_FromString(self->image->mode); - if (strcmp(name, "size") == 0) - return Py_BuildValue("ii", self->image->xsize, self->image->ysize); - if (strcmp(name, "bands") == 0) - return PyInt_FromLong(self->image->bands); - if (strcmp(name, "id") == 0) - return PyInt_FromLong((long) self->image); - if (strcmp(name, "ptr") == 0) - return PyCObject_FromVoidPtrAndDesc(self->image, IMAGING_MAGIC, NULL); - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - - -/* basic sequence semantics */ - -static Py_ssize_t -image_length(ImagingObject *self) -{ - Imaging im = self->image; - - return im->xsize * im->ysize; -} - -static PyObject * -image_item(ImagingObject *self, Py_ssize_t i) -{ - int x, y; - Imaging im = self->image; - - if (im->xsize > 0) { - x = i % im->xsize; - y = i / im->xsize; - } else - x = y = 0; /* leave it to getpixel to raise an exception */ - - return getpixel(im, self->access, x, y); -} - -static PySequenceMethods image_as_sequence = { - (inquiry) image_length, /*sq_length*/ - (binaryfunc) NULL, /*sq_concat*/ - (ssizeargfunc) NULL, /*sq_repeat*/ - (ssizeargfunc) image_item, /*sq_item*/ - (ssizessizeargfunc) NULL, /*sq_slice*/ - (ssizeobjargproc) NULL, /*sq_ass_item*/ - (ssizessizeobjargproc) NULL, /*sq_ass_slice*/ -}; - - -/* type description */ - -statichere PyTypeObject Imaging_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingCore", /*tp_name*/ - sizeof(ImagingObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number */ - &image_as_sequence, /*tp_as_sequence */ - 0, /*tp_as_mapping */ - 0 /*tp_hash*/ -}; - -#ifdef WITH_IMAGEDRAW - -statichere PyTypeObject ImagingFont_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingFont", /*tp_name*/ - sizeof(ImagingFontObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_font_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_font_getattr, /*tp_getattr*/ -}; - -statichere PyTypeObject ImagingDraw_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingDraw", /*tp_name*/ - sizeof(ImagingDrawObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_draw_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_draw_getattr, /*tp_getattr*/ -}; - -#endif - -static PyMappingMethods pixel_access_as_mapping = { - (inquiry) NULL, /*mp_length*/ - (binaryfunc) pixel_access_getitem, /*mp_subscript*/ - (objobjargproc) pixel_access_setitem, /*mp_ass_subscript*/ -}; - -/* type description */ - -statichere PyTypeObject PixelAccess_Type = { - PyObject_HEAD_INIT(NULL) - 0, "PixelAccess", sizeof(PixelAccessObject), 0, - /* methods */ - (destructor)pixel_access_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number */ - 0, /*tp_as_sequence */ - &pixel_access_as_mapping, /*tp_as_mapping */ - 0 /*tp_hash*/ -}; - -/* -------------------------------------------------------------------- */ - -/* FIXME: this is something of a mess. Should replace this with - pluggable codecs, but not before PIL 1.2 */ - -/* Decoders (in decode.c) */ -extern PyObject* PyImaging_BitDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_FliDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_GifDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_HexDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_JpegDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_MspDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_PcdDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_PcxDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_RawDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_XbmDecoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_ZipDecoderNew(PyObject* self, PyObject* args); - -/* Encoders (in encode.c) */ -extern PyObject* PyImaging_EpsEncoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_GifEncoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_JpegEncoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_PcxEncoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_RawEncoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_XbmEncoderNew(PyObject* self, PyObject* args); -extern PyObject* PyImaging_ZipEncoderNew(PyObject* self, PyObject* args); - -/* Display support etc (in display.c) */ -#ifdef WIN32 -extern PyObject* PyImaging_CreateWindowWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_DisplayWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_DisplayModeWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_GrabScreenWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_ListWindowsWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_EventLoopWin32(PyObject* self, PyObject* args); -extern PyObject* PyImaging_DrawWmf(PyObject* self, PyObject* args); -#endif - -/* Experimental path stuff (in path.c) */ -extern PyObject* PyPath_Create(ImagingObject* self, PyObject* args); - -/* Experimental outline stuff (in outline.c) */ -extern PyObject* PyOutline_Create(ImagingObject* self, PyObject* args); - -extern PyObject* PyImaging_Mapper(PyObject* self, PyObject* args); -extern PyObject* PyImaging_MapBuffer(PyObject* self, PyObject* args); - -static PyMethodDef functions[] = { - - /* Object factories */ - {"blend", (PyCFunction)_blend, 1}, - {"fill", (PyCFunction)_fill, 1}, - {"new", (PyCFunction)_new, 1}, - - {"getcount", (PyCFunction)_getcount, 1}, - - /* Functions */ - {"convert", (PyCFunction)_convert2, 1}, - {"copy", (PyCFunction)_copy2, 1}, - - /* Codecs */ - {"bit_decoder", (PyCFunction)PyImaging_BitDecoderNew, 1}, - {"eps_encoder", (PyCFunction)PyImaging_EpsEncoderNew, 1}, - {"fli_decoder", (PyCFunction)PyImaging_FliDecoderNew, 1}, - {"gif_decoder", (PyCFunction)PyImaging_GifDecoderNew, 1}, - {"gif_encoder", (PyCFunction)PyImaging_GifEncoderNew, 1}, - {"hex_decoder", (PyCFunction)PyImaging_HexDecoderNew, 1}, - {"hex_encoder", (PyCFunction)PyImaging_EpsEncoderNew, 1}, /* EPS=HEX! */ -#ifdef HAVE_LIBJPEG - {"jpeg_decoder", (PyCFunction)PyImaging_JpegDecoderNew, 1}, - {"jpeg_encoder", (PyCFunction)PyImaging_JpegEncoderNew, 1}, -#endif - {"tiff_lzw_decoder", (PyCFunction)PyImaging_TiffLzwDecoderNew, 1}, - {"msp_decoder", (PyCFunction)PyImaging_MspDecoderNew, 1}, - {"packbits_decoder", (PyCFunction)PyImaging_PackbitsDecoderNew, 1}, - {"pcd_decoder", (PyCFunction)PyImaging_PcdDecoderNew, 1}, - {"pcx_decoder", (PyCFunction)PyImaging_PcxDecoderNew, 1}, - {"pcx_encoder", (PyCFunction)PyImaging_PcxEncoderNew, 1}, - {"raw_decoder", (PyCFunction)PyImaging_RawDecoderNew, 1}, - {"raw_encoder", (PyCFunction)PyImaging_RawEncoderNew, 1}, - {"sun_rle_decoder", (PyCFunction)PyImaging_SunRleDecoderNew, 1}, - {"tga_rle_decoder", (PyCFunction)PyImaging_TgaRleDecoderNew, 1}, - {"xbm_decoder", (PyCFunction)PyImaging_XbmDecoderNew, 1}, - {"xbm_encoder", (PyCFunction)PyImaging_XbmEncoderNew, 1}, -#ifdef HAVE_LIBZ - {"zip_decoder", (PyCFunction)PyImaging_ZipDecoderNew, 1}, - {"zip_encoder", (PyCFunction)PyImaging_ZipEncoderNew, 1}, -#endif - - /* Memory mapping */ -#ifdef WITH_MAPPING -#ifdef WIN32 - {"map", (PyCFunction)PyImaging_Mapper, 1}, -#endif - {"map_buffer", (PyCFunction)PyImaging_MapBuffer, 1}, -#endif - - /* Display support */ -#ifdef WIN32 - {"display", (PyCFunction)PyImaging_DisplayWin32, 1}, - {"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, 1}, - {"grabscreen", (PyCFunction)PyImaging_GrabScreenWin32, 1}, - {"grabclipboard", (PyCFunction)PyImaging_GrabClipboardWin32, 1}, - {"createwindow", (PyCFunction)PyImaging_CreateWindowWin32, 1}, - {"eventloop", (PyCFunction)PyImaging_EventLoopWin32, 1}, - {"listwindows", (PyCFunction)PyImaging_ListWindowsWin32, 1}, - {"drawwmf", (PyCFunction)PyImaging_DrawWmf, 1}, -#endif - - /* Utilities */ - {"crc32", (PyCFunction)_crc32, 1}, - {"getcodecstatus", (PyCFunction)_getcodecstatus, 1}, - - /* Debugging stuff */ - {"open_ppm", (PyCFunction)_open_ppm, 1}, - - /* Special effects (experimental) */ -#ifdef WITH_EFFECTS - {"effect_mandelbrot", (PyCFunction)_effect_mandelbrot, 1}, - {"effect_noise", (PyCFunction)_effect_noise, 1}, - {"linear_gradient", (PyCFunction)_linear_gradient, 1}, - {"radial_gradient", (PyCFunction)_radial_gradient, 1}, - {"wedge", (PyCFunction)_linear_gradient, 1}, /* Compatibility */ -#endif - - /* Drawing support stuff */ -#ifdef WITH_IMAGEDRAW - {"font", (PyCFunction)_font_new, 1}, - {"draw", (PyCFunction)_draw_new, 1}, -#endif - - /* Experimental path stuff */ -#ifdef WITH_IMAGEPATH - {"path", (PyCFunction)PyPath_Create, 1}, -#endif - - /* Experimental arrow graphics stuff */ -#ifdef WITH_ARROW - {"outline", (PyCFunction)PyOutline_Create, 1}, -#endif - - {NULL, NULL} /* sentinel */ -}; - -DL_EXPORT(void) -init_imaging(void) -{ - PyObject* m; - PyObject* d; - - /* Patch object type */ - Imaging_Type.ob_type = &PyType_Type; -#ifdef WITH_IMAGEDRAW - ImagingFont_Type.ob_type = &PyType_Type; - ImagingDraw_Type.ob_type = &PyType_Type; -#endif - PixelAccess_Type.ob_type = &PyType_Type; - - ImagingAccessInit(); - - m = Py_InitModule("_imaging", functions); - d = PyModule_GetDict(m); - -#ifdef HAVE_LIBJPEG - { - extern const char* ImagingJpegVersion(void); - PyDict_SetItemString(d, "jpeglib_version", PyString_FromString(ImagingJpegVersion())); - } -#endif - -#ifdef HAVE_LIBZ - { - extern const char* ImagingZipVersion(void); - PyDict_SetItemString(d, "zlib_version", PyString_FromString(ImagingZipVersion())); - } -#endif -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c deleted file mode 100755 index e9a3b00c596..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingcms.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * pyCMS - * a Python / PIL interface to the littleCMS ICC Color Management System - * Copyright (C) 2002-2003 Kevin Cazabon - * kevin@cazabon.com - * http://www.cazabon.com - * Adapted/reworked for PIL by Fredrik Lundh - * Copyright (c) 2009 Fredrik Lundh - * - * pyCMS home page: http://www.cazabon.com/pyCMS - * littleCMS home page: http://www.littlecms.com - * (littleCMS is Copyright (C) 1998-2001 Marti Maria) - * - * Originally released under LGPL. Graciously donated to PIL in - * March 2009, for distribution under the standard PIL license - */ - -#define COPYRIGHTINFO "\ -pyCMS\n\ -a Python / PIL interface to the littleCMS ICC Color Management System\n\ -Copyright (C) 2002-2003 Kevin Cazabon\n\ -kevin@cazabon.com\n\ -http://www.cazabon.com\n\ -" - -#include "Python.h" -#include "lcms.h" -#include "Imaging.h" - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#if LCMS_VERSION < 117 -#define LCMSBOOL BOOL -#endif - -#ifdef WIN32 -#include -#endif - -#define PYCMSVERSION "0.1.0 pil" - -/* version history */ - -/* - 0.1.0 pil integration & refactoring - 0.0.2 alpha: Minor updates, added interfaces to littleCMS features, Jan 6, 2003 - - fixed some memory holes in how transforms/profiles were created and passed back to Python - due to improper destructor setup for PyCObjects - - added buildProofTransformFromOpenProfiles() function - - eliminated some code redundancy, centralizing several common tasks with internal functions - - 0.0.1 alpha: First public release Dec 26, 2002 - -*/ - -/* known to-do list with current version: - - Verify that PILmode->littleCMStype conversion in findLCMStype is correct for all PIL modes (it probably isn't for the more obscure ones) - - Add support for creating custom RGB profiles on the fly - Add support for checking presence of a specific tag in a profile - Add support for other littleCMS features as required - -*/ - -/* - INTENT_PERCEPTUAL 0 - INTENT_RELATIVE_COLORIMETRIC 1 - INTENT_SATURATION 2 - INTENT_ABSOLUTE_COLORIMETRIC 3 -*/ - -/* -------------------------------------------------------------------- */ -/* wrapper classes */ - -/* a profile represents the ICC characteristics for a specific device */ - -typedef struct { - PyObject_HEAD - cmsHPROFILE profile; -} CmsProfileObject; - -staticforward PyTypeObject CmsProfile_Type; - -#define CmsProfile_Check(op) ((op)->ob_type == &CmsProfile_Type) - -static PyObject* -cms_profile_new(cmsHPROFILE profile) -{ - CmsProfileObject* self; - - self = PyObject_New(CmsProfileObject, &CmsProfile_Type); - if (!self) - return NULL; - - self->profile = profile; - - return (PyObject*) self; -} - -static PyObject* -cms_profile_open(PyObject* self, PyObject* args) -{ - cmsHPROFILE hProfile; - - char* sProfile; - if (!PyArg_ParseTuple(args, "s:profile_open", &sProfile)) - return NULL; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - hProfile = cmsOpenProfileFromFile(sProfile, "r"); - if (!hProfile) { - PyErr_SetString(PyExc_IOError, "cannot open profile file"); - return NULL; - } - - return cms_profile_new(hProfile); -} - -static PyObject* -cms_profile_fromstring(PyObject* self, PyObject* args) -{ - cmsHPROFILE hProfile; - - char* pProfile; - int nProfile; - if (!PyArg_ParseTuple(args, "s#:profile_fromstring", &pProfile, &nProfile)) - return NULL; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - hProfile = cmsOpenProfileFromMem(pProfile, nProfile); - if (!hProfile) - PyErr_SetString(PyExc_IOError, "cannot open profile from string"); - - return cms_profile_new(hProfile); -} - -static void -cms_profile_dealloc(CmsProfileObject* self) -{ - (void) cmsCloseProfile(self->profile); - PyObject_Del(self); -} - -/* a transform represents the mapping between two profiles */ - -typedef struct { - PyObject_HEAD - char mode_in[8]; - char mode_out[8]; - cmsHTRANSFORM transform; -} CmsTransformObject; - -staticforward PyTypeObject CmsTransform_Type; - -#define CmsTransform_Check(op) ((op)->ob_type == &CmsTransform_Type) - -static PyObject* -cms_transform_new(cmsHTRANSFORM transform, char* mode_in, char* mode_out) -{ - CmsTransformObject* self; - - self = PyObject_New(CmsTransformObject, &CmsTransform_Type); - if (!self) - return NULL; - - self->transform = transform; - - strcpy(self->mode_in, mode_in); - strcpy(self->mode_out, mode_out); - - return (PyObject*) self; -} - -static void -cms_transform_dealloc(CmsTransformObject* self) -{ - cmsDeleteTransform(self->transform); - PyObject_Del(self); -} - -/* -------------------------------------------------------------------- */ -/* internal functions */ - -static const char* -findICmode(icColorSpaceSignature cs) -{ - switch (cs) { - case icSigXYZData: return "XYZ"; - case icSigLabData: return "LAB"; - case icSigLuvData: return "LUV"; - case icSigYCbCrData: return "YCbCr"; - case icSigYxyData: return "YXY"; - case icSigRgbData: return "RGB"; - case icSigGrayData: return "L"; - case icSigHsvData: return "HSV"; - case icSigHlsData: return "HLS"; - case icSigCmykData: return "CMYK"; - case icSigCmyData: return "CMY"; - default: return ""; /* other TBA */ - } -} - -static DWORD -findLCMStype(char* PILmode) -{ - if (strcmp(PILmode, "RGB") == 0) { - return TYPE_RGBA_8; - } - else if (strcmp(PILmode, "RGBA") == 0) { - return TYPE_RGBA_8; - } - else if (strcmp(PILmode, "RGBX") == 0) { - return TYPE_RGBA_8; - } - else if (strcmp(PILmode, "RGBA;16B") == 0) { - return TYPE_RGBA_16; - } - else if (strcmp(PILmode, "CMYK") == 0) { - return TYPE_CMYK_8; - } - else if (strcmp(PILmode, "L") == 0) { - return TYPE_GRAY_8; - } - else if (strcmp(PILmode, "L;16") == 0) { - return TYPE_GRAY_16; - } - else if (strcmp(PILmode, "L;16B") == 0) { - return TYPE_GRAY_16_SE; - } - else if (strcmp(PILmode, "YCCA") == 0) { - return TYPE_YCbCr_8; - } - else if (strcmp(PILmode, "YCC") == 0) { - return TYPE_YCbCr_8; - } - - else { - /* take a wild guess... but you probably should fail instead. */ - return TYPE_GRAY_8; /* so there's no buffer overrun... */ - } -} - -static int -pyCMSdoTransform(Imaging im, Imaging imOut, cmsHTRANSFORM hTransform) -{ - int i; - - if (im->xsize > imOut->xsize || im->ysize > imOut->ysize) - return -1; - - Py_BEGIN_ALLOW_THREADS - - for (i = 0; i < im->ysize; i++) - cmsDoTransform(hTransform, im->image[i], imOut->image[i], im->xsize); - - Py_END_ALLOW_THREADS - - return 0; -} - -static cmsHTRANSFORM -_buildTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, char *sInMode, char *sOutMode, int iRenderingIntent, DWORD cmsFLAGS) -{ - cmsHTRANSFORM hTransform; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - Py_BEGIN_ALLOW_THREADS - - /* create the transform */ - hTransform = cmsCreateTransform(hInputProfile, - findLCMStype(sInMode), - hOutputProfile, - findLCMStype(sOutMode), - iRenderingIntent, cmsFLAGS); - - Py_END_ALLOW_THREADS - - if (!hTransform) - PyErr_SetString(PyExc_ValueError, "cannot build transform"); - - return hTransform; /* if NULL, an exception is set */ -} - -static cmsHTRANSFORM -_buildProofTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, cmsHPROFILE hProofProfile, char *sInMode, char *sOutMode, int iRenderingIntent, int iProofIntent, DWORD cmsFLAGS) -{ - cmsHTRANSFORM hTransform; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - Py_BEGIN_ALLOW_THREADS - - /* create the transform */ - hTransform = cmsCreateProofingTransform(hInputProfile, - findLCMStype(sInMode), - hOutputProfile, - findLCMStype(sOutMode), - hProofProfile, - iRenderingIntent, - iProofIntent, - cmsFLAGS); - - Py_END_ALLOW_THREADS - - if (!hTransform) - PyErr_SetString(PyExc_ValueError, "cannot build proof transform"); - - return hTransform; /* if NULL, an exception is set */ -} - -/* -------------------------------------------------------------------- */ -/* Python callable functions */ - -static PyObject * -buildTransform(PyObject *self, PyObject *args) { - CmsProfileObject *pInputProfile; - CmsProfileObject *pOutputProfile; - char *sInMode; - char *sOutMode; - int iRenderingIntent = 0; - int cmsFLAGS = 0; - - cmsHTRANSFORM transform = NULL; - - if (!PyArg_ParseTuple(args, "O!O!ss|ii:buildTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &sInMode, &sOutMode, &iRenderingIntent, &cmsFLAGS)) - return NULL; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - transform = _buildTransform(pInputProfile->profile, pOutputProfile->profile, sInMode, sOutMode, iRenderingIntent, cmsFLAGS); - - if (!transform) - return NULL; - - return cms_transform_new(transform, sInMode, sOutMode); -} - -static PyObject * -buildProofTransform(PyObject *self, PyObject *args) -{ - CmsProfileObject *pInputProfile; - CmsProfileObject *pOutputProfile; - CmsProfileObject *pProofProfile; - char *sInMode; - char *sOutMode; - int iRenderingIntent = 0; - int iProofIntent = 0; - int cmsFLAGS = 0; - - cmsHTRANSFORM transform = NULL; - - if (!PyArg_ParseTuple(args, "O!O!O!ss|iii:buildProofTransform", &CmsProfile_Type, &pInputProfile, &CmsProfile_Type, &pOutputProfile, &CmsProfile_Type, &pProofProfile, &sInMode, &sOutMode, &iRenderingIntent, &iProofIntent, &cmsFLAGS)) - return NULL; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - transform = _buildProofTransform(pInputProfile->profile, pOutputProfile->profile, pProofProfile->profile, sInMode, sOutMode, iRenderingIntent, iProofIntent, cmsFLAGS); - - if (!transform) - return NULL; - - return cms_transform_new(transform, sInMode, sOutMode); - -} - -static PyObject * -cms_transform_apply(CmsTransformObject *self, PyObject *args) -{ - long idIn; - long idOut; - Imaging im; - Imaging imOut; - - int result; - - if (!PyArg_ParseTuple(args, "ll:apply", &idIn, &idOut)) - return NULL; - - im = (Imaging) idIn; - imOut = (Imaging) idOut; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - result = pyCMSdoTransform(im, imOut, self->transform); - - return Py_BuildValue("i", result); -} - -/* -------------------------------------------------------------------- */ -/* Python-Callable On-The-Fly profile creation functions */ - -static PyObject * -createProfile(PyObject *self, PyObject *args) -{ - char *sColorSpace; - cmsHPROFILE hProfile; - int iColorTemp = 0; - LPcmsCIExyY whitePoint = NULL; - LCMSBOOL result; - - if (!PyArg_ParseTuple(args, "s|i:createProfile", &sColorSpace, &iColorTemp)) - return NULL; - - cmsErrorAction(LCMS_ERROR_IGNORE); - - if (strcmp(sColorSpace, "LAB") == 0) { - if (iColorTemp > 0) { - result = cmsWhitePointFromTemp(iColorTemp, whitePoint); - if (!result) { - PyErr_SetString(PyExc_ValueError, "ERROR: Could not calculate white point from color temperature provided, must be integer in degrees Kelvin"); - return NULL; - } - hProfile = cmsCreateLabProfile(whitePoint); - } else - hProfile = cmsCreateLabProfile(NULL); - } - else if (strcmp(sColorSpace, "XYZ") == 0) - hProfile = cmsCreateXYZProfile(); - else if (strcmp(sColorSpace, "sRGB") == 0) - hProfile = cmsCreate_sRGBProfile(); - else - hProfile = NULL; - - if (!hProfile) { - PyErr_SetString(PyExc_ValueError, "failed to create requested color space"); - return NULL; - } - - return cms_profile_new(hProfile); -} - -/* -------------------------------------------------------------------- */ -/* profile methods */ - -static PyObject * -cms_profile_is_intent_supported(CmsProfileObject *self, PyObject *args) -{ - LCMSBOOL result; - - int intent; - int direction; - if (!PyArg_ParseTuple(args, "ii:is_intent_supported", &intent, &direction)) - return NULL; - - result = cmsIsIntentSupported(self->profile, intent, direction); - - /* printf("cmsIsIntentSupported(%p, %d, %d) => %d\n", self->profile, intent, direction, result); */ - - return PyInt_FromLong(result != 0); -} - -#ifdef WIN32 -static PyObject * -cms_get_display_profile_win32(PyObject* self, PyObject* args) -{ - char filename[MAX_PATH]; - DWORD filename_size; - BOOL ok; - - int handle = 0; - int is_dc = 0; - if (!PyArg_ParseTuple(args, "|ii:get_display_profile", &handle, &is_dc)) - return NULL; - - filename_size = sizeof(filename); - - if (is_dc) { - ok = GetICMProfile((HDC) handle, &filename_size, filename); - } else { - HDC dc = GetDC((HWND) handle); - ok = GetICMProfile(dc, &filename_size, filename); - ReleaseDC((HWND) handle, dc); - } - - if (ok) - return PyString_FromStringAndSize(filename, filename_size-1); - - Py_INCREF(Py_None); - return Py_None; -} -#endif - -/* -------------------------------------------------------------------- */ -/* Python interface setup */ - -static PyMethodDef pyCMSdll_methods[] = { - - {"profile_open", cms_profile_open, 1}, - {"profile_fromstring", cms_profile_fromstring, 1}, - - /* profile and transform functions */ - {"buildTransform", buildTransform, 1}, - {"buildProofTransform", buildProofTransform, 1}, - {"createProfile", createProfile, 1}, - - /* platform specific tools */ -#ifdef WIN32 - {"get_display_profile_win32", cms_get_display_profile_win32, 1}, -#endif - - {NULL, NULL} -}; - -static struct PyMethodDef cms_profile_methods[] = { - {"is_intent_supported", (PyCFunction) cms_profile_is_intent_supported, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -cms_profile_getattr(CmsProfileObject* self, char* name) -{ - if (!strcmp(name, "product_name")) - return PyString_FromString(cmsTakeProductName(self->profile)); - if (!strcmp(name, "product_desc")) - return PyString_FromString(cmsTakeProductDesc(self->profile)); - if (!strcmp(name, "product_info")) - return PyString_FromString(cmsTakeProductInfo(self->profile)); - if (!strcmp(name, "rendering_intent")) - return PyInt_FromLong(cmsTakeRenderingIntent(self->profile)); - if (!strcmp(name, "pcs")) - return PyString_FromString(findICmode(cmsGetPCS(self->profile))); - if (!strcmp(name, "color_space")) - return PyString_FromString(findICmode(cmsGetColorSpace(self->profile))); - /* FIXME: add more properties (creation_datetime etc) */ - - return Py_FindMethod(cms_profile_methods, (PyObject*) self, name); -} - -statichere PyTypeObject CmsProfile_Type = { - PyObject_HEAD_INIT(NULL) - 0, "CmsProfile", sizeof(CmsProfileObject), 0, - /* methods */ - (destructor) cms_profile_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc) cms_profile_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number */ - 0, /*tp_as_sequence */ - 0, /*tp_as_mapping */ - 0 /*tp_hash*/ -}; - -static struct PyMethodDef cms_transform_methods[] = { - {"apply", (PyCFunction) cms_transform_apply, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -cms_transform_getattr(CmsTransformObject* self, char* name) -{ - if (!strcmp(name, "inputMode")) - return PyString_FromString(self->mode_in); - if (!strcmp(name, "outputMode")) - return PyString_FromString(self->mode_out); - - return Py_FindMethod(cms_transform_methods, (PyObject*) self, name); -} - -statichere PyTypeObject CmsTransform_Type = { - PyObject_HEAD_INIT(NULL) - 0, "CmsTransform", sizeof(CmsTransformObject), 0, - /* methods */ - (destructor) cms_transform_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc) cms_transform_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number */ - 0, /*tp_as_sequence */ - 0, /*tp_as_mapping */ - 0 /*tp_hash*/ -}; - -DL_EXPORT(void) -init_imagingcms(void) -{ - PyObject *m; - PyObject *d; - PyObject *v; - - /* Patch up object types */ - CmsProfile_Type.ob_type = &PyType_Type; - CmsTransform_Type.ob_type = &PyType_Type; - - m = Py_InitModule("_imagingcms", pyCMSdll_methods); - d = PyModule_GetDict(m); - -#if PY_VERSION_HEX >= 0x02020000 - v = PyString_FromFormat("%d.%d", LCMS_VERSION / 100, LCMS_VERSION % 100); -#else - { - char buffer[100]; - sprintf(buffer, "%d.%d", LCMS_VERSION / 100, LCMS_VERSION % 100); - v = PyString_FromString(buffer); - } -#endif - PyDict_SetItemString(d, "littlecms_version", v); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c deleted file mode 100755 index 9358087180d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingft.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * PIL FreeType Driver - * - * a FreeType 2.X driver for PIL - * - * history: - * 2001-02-17 fl Created (based on old experimental freetype 1.0 code) - * 2001-04-18 fl Fixed some egcs compiler nits - * 2002-11-08 fl Added unicode support; more font metrics, etc - * 2003-05-20 fl Fixed compilation under 1.5.2 and newer non-unicode builds - * 2003-09-27 fl Added charmap encoding support - * 2004-05-15 fl Fixed compilation for FreeType 2.1.8 - * 2004-09-10 fl Added support for monochrome bitmaps - * 2006-06-18 fl Fixed glyph bearing calculation - * 2007-12-23 fl Fixed crash in family/style attribute fetch - * 2008-01-02 fl Handle Unicode filenames properly - * - * Copyright (c) 1998-2007 by Secret Labs AB - */ - -#include "Python.h" -#include "Imaging.h" - -#if !defined(USE_FREETYPE_2_0) -/* undef/comment out to use freetype 2.0 */ -#define USE_FREETYPE_2_1 -#endif - -#if defined(USE_FREETYPE_2_1) -/* freetype 2.1 and newer */ -#include -#include FT_FREETYPE_H -#else -/* freetype 2.0 */ -#include -#endif - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#if PY_VERSION_HEX >= 0x01060000 -#if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE) -/* defining this enables unicode support (default under 1.6a1 and later) */ -#define HAVE_UNICODE -#endif -#endif - -#if !defined(Py_RETURN_NONE) -#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None -#endif - -#if !defined(FT_LOAD_TARGET_MONO) -#define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME -#endif - -/* -------------------------------------------------------------------- */ -/* error table */ - -#undef FTERRORS_H -#undef __FTERRORS_H__ - -#define FT_ERRORDEF( e, v, s ) { e, s }, -#define FT_ERROR_START_LIST { -#define FT_ERROR_END_LIST { 0, 0 } }; - -struct { - int code; - const char* message; -} ft_errors[] = - -#include - -/* -------------------------------------------------------------------- */ -/* font objects */ - -static FT_Library library; - -typedef struct { - PyObject_HEAD - FT_Face face; -} FontObject; - -staticforward PyTypeObject Font_Type; - -/* round a 26.6 pixel coordinate to the nearest larger integer */ -#define PIXEL(x) ((((x)+63) & -64)>>6) - -static PyObject* -geterror(int code) -{ - int i; - - for (i = 0; ft_errors[i].message; i++) - if (ft_errors[i].code == code) { - PyErr_SetString(PyExc_IOError, ft_errors[i].message); - return NULL; - } - - PyErr_SetString(PyExc_IOError, "unknown freetype error"); - return NULL; -} - -static PyObject* -getfont(PyObject* self_, PyObject* args, PyObject* kw) -{ - /* create a font object from a file name and a size (in pixels) */ - - FontObject* self; - int error; - - char* filename; - int size; - int index = 0; - unsigned char* encoding = NULL; - static char* kwlist[] = { - "filename", "size", "index", "encoding", NULL - }; - -#if defined(HAVE_UNICODE) && PY_VERSION_HEX >= 0x02020000 - if (!PyArg_ParseTupleAndKeywords(args, kw, "eti|is", kwlist, - Py_FileSystemDefaultEncoding, &filename, - &size, &index, &encoding)) - return NULL; -#else - if (!PyArg_ParseTupleAndKeywords(args, kw, "si|is", kwlist, - &filename, &size, &index, &encoding)) - return NULL; -#endif - - if (!library) { - PyErr_SetString( - PyExc_IOError, - "failed to initialize FreeType library" - ); - return NULL; - } - - self = PyObject_New(FontObject, &Font_Type); - if (!self) - return NULL; - - error = FT_New_Face(library, filename, index, &self->face); - - if (!error) - error = FT_Set_Pixel_Sizes(self->face, 0, size); - - if (!error && encoding && strlen((char*) encoding) == 4) { - FT_Encoding encoding_tag = FT_MAKE_TAG( - encoding[0], encoding[1], encoding[2], encoding[3] - ); - error = FT_Select_Charmap(self->face, encoding_tag); - } - - if (error) { - PyObject_Del(self); - return geterror(error); - } - - return (PyObject*) self; -} - -static int -font_getchar(PyObject* string, int index, FT_ULong* char_out) -{ -#if defined(HAVE_UNICODE) - if (PyUnicode_Check(string)) { - Py_UNICODE* p = PyUnicode_AS_UNICODE(string); - int size = PyUnicode_GET_SIZE(string); - if (index >= size) - return 0; - *char_out = p[index]; - return 1; - } -#endif - if (PyString_Check(string)) { - unsigned char* p = (unsigned char*) PyString_AS_STRING(string); - int size = PyString_GET_SIZE(string); - if (index >= size) - return 0; - *char_out = (unsigned char) p[index]; - return 1; - } - return 0; -} - -static PyObject* -font_getsize(FontObject* self, PyObject* args) -{ - int i, x; - FT_ULong ch; - FT_Face face; - int xoffset; - FT_Bool kerning = FT_HAS_KERNING(self->face); - FT_UInt last_index = 0; - - /* calculate size and bearing for a given string */ - - PyObject* string; - if (!PyArg_ParseTuple(args, "O:getsize", &string)) - return NULL; - -#if defined(HAVE_UNICODE) - if (!PyUnicode_Check(string) && !PyString_Check(string)) { -#else - if (!PyString_Check(string)) { -#endif - PyErr_SetString(PyExc_TypeError, "expected string"); - return NULL; - } - - face = NULL; - xoffset = 0; - - for (x = i = 0; font_getchar(string, i, &ch); i++) { - int index, error; - face = self->face; - index = FT_Get_Char_Index(face, ch); - if (kerning && last_index && index) { - FT_Vector delta; - FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, - &delta); - x += delta.x; - } - error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT); - if (error) - return geterror(error); - if (i == 0) - xoffset = face->glyph->metrics.horiBearingX; - x += face->glyph->metrics.horiAdvance; - last_index = index; - } - - if (face) { - int offset; - /* left bearing */ - if (xoffset < 0) - x -= xoffset; - else - xoffset = 0; - /* right bearing */ - offset = face->glyph->metrics.horiAdvance - - face->glyph->metrics.width - - face->glyph->metrics.horiBearingX; - if (offset < 0) - x -= offset; - } - - return Py_BuildValue( - "(ii)(ii)", - PIXEL(x), PIXEL(self->face->size->metrics.height), - PIXEL(xoffset), 0 - ); -} - -static PyObject* -font_getabc(FontObject* self, PyObject* args) -{ - FT_ULong ch; - FT_Face face; - double a, b, c; - - /* calculate ABC values for a given string */ - - PyObject* string; - if (!PyArg_ParseTuple(args, "O:getabc", &string)) - return NULL; - -#if defined(HAVE_UNICODE) - if (!PyUnicode_Check(string) && !PyString_Check(string)) { -#else - if (!PyString_Check(string)) { -#endif - PyErr_SetString(PyExc_TypeError, "expected string"); - return NULL; - } - - if (font_getchar(string, 0, &ch)) { - int index, error; - face = self->face; - index = FT_Get_Char_Index(face, ch); - error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT); - if (error) - return geterror(error); - a = face->glyph->metrics.horiBearingX / 64.0; - b = face->glyph->metrics.width / 64.0; - c = (face->glyph->metrics.horiAdvance - - face->glyph->metrics.horiBearingX - - face->glyph->metrics.width) / 64.0; - } else - a = b = c = 0.0; - - return Py_BuildValue("ddd", a, b, c); -} - -static PyObject* -font_render(FontObject* self, PyObject* args) -{ - int i, x, y; - Imaging im; - int index, error, ascender; - int load_flags; - unsigned char *source; - FT_ULong ch; - FT_GlyphSlot glyph; - FT_Bool kerning = FT_HAS_KERNING(self->face); - FT_UInt last_index = 0; - - /* render string into given buffer (the buffer *must* have - the right size, or this will crash) */ - PyObject* string; - long id; - int mask = 0; - if (!PyArg_ParseTuple(args, "Ol|i:render", &string, &id, &mask)) - return NULL; - -#if defined(HAVE_UNICODE) - if (!PyUnicode_Check(string) && !PyString_Check(string)) { -#else - if (!PyString_Check(string)) { -#endif - PyErr_SetString(PyExc_TypeError, "expected string"); - return NULL; - } - - im = (Imaging) id; - - load_flags = FT_LOAD_RENDER; - if (mask) - load_flags |= FT_LOAD_TARGET_MONO; - - for (x = i = 0; font_getchar(string, i, &ch); i++) { - if (i == 0 && self->face->glyph->metrics.horiBearingX < 0) - x = -PIXEL(self->face->glyph->metrics.horiBearingX); - index = FT_Get_Char_Index(self->face, ch); - if (kerning && last_index && index) { - FT_Vector delta; - FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, - &delta); - x += delta.x >> 6; - } - error = FT_Load_Glyph(self->face, index, load_flags); - if (error) - return geterror(error); - glyph = self->face->glyph; - if (mask) { - /* use monochrome mask (on palette images, etc) */ - int xx, x0, x1; - source = (unsigned char*) glyph->bitmap.buffer; - ascender = PIXEL(self->face->size->metrics.ascender); - xx = x + glyph->bitmap_left; - x0 = 0; - x1 = glyph->bitmap.width; - if (xx < 0) - x0 = -xx; - if (xx + x1 > im->xsize) - x1 = im->xsize - xx; - for (y = 0; y < glyph->bitmap.rows; y++) { - int yy = y + ascender - glyph->bitmap_top; - if (yy >= 0 && yy < im->ysize) { - /* blend this glyph into the buffer */ - unsigned char *target = im->image8[yy] + xx; - int i, j, m = 128; - for (i = j = 0; j < x1; j++) { - if (j >= x0 && (source[i] & m)) - target[j] = 255; - if (!(m >>= 1)) { - m = 128; - i++; - } - } - } - source += glyph->bitmap.pitch; - } - } else { - /* use antialiased rendering */ - int xx, x0, x1; - source = (unsigned char*) glyph->bitmap.buffer; - ascender = PIXEL(self->face->size->metrics.ascender); - xx = x + glyph->bitmap_left; - x0 = 0; - x1 = glyph->bitmap.width; - if (xx < 0) - x0 = -xx; - if (xx + x1 > im->xsize) - x1 = im->xsize - xx; - for (y = 0; y < glyph->bitmap.rows; y++) { - int yy = y + ascender - glyph->bitmap_top; - if (yy >= 0 && yy < im->ysize) { - /* blend this glyph into the buffer */ - int i; - unsigned char *target = im->image8[yy] + xx; - for (i = x0; i < x1; i++) { - if (target[i] < source[i]) - target[i] = source[i]; - } - } - source += glyph->bitmap.pitch; - } - } - x += PIXEL(glyph->metrics.horiAdvance); - last_index = index; - } - - Py_RETURN_NONE; -} - -static void -font_dealloc(FontObject* self) -{ - FT_Done_Face(self->face); - PyObject_Del(self); -} - -static PyMethodDef font_methods[] = { - {"render", (PyCFunction) font_render, METH_VARARGS}, - {"getsize", (PyCFunction) font_getsize, METH_VARARGS}, - {"getabc", (PyCFunction) font_getabc, METH_VARARGS}, - {NULL, NULL} -}; - -static PyObject* -font_getattr(FontObject* self, char* name) -{ - PyObject* res; - - res = Py_FindMethod(font_methods, (PyObject*) self, name); - - if (res) - return res; - - PyErr_Clear(); - - /* attributes */ - if (!strcmp(name, "family")) { - if (self->face->family_name) - return PyString_FromString(self->face->family_name); - Py_RETURN_NONE; - } - if (!strcmp(name, "style")) { - if (self->face->style_name) - return PyString_FromString(self->face->style_name); - Py_RETURN_NONE; - } - if (!strcmp(name, "ascent")) - return PyInt_FromLong(PIXEL(self->face->size->metrics.ascender)); - if (!strcmp(name, "descent")) - return PyInt_FromLong(-PIXEL(self->face->size->metrics.descender)); - - if (!strcmp(name, "glyphs")) - /* number of glyphs provided by this font */ - return PyInt_FromLong(self->face->num_glyphs); - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -statichere PyTypeObject Font_Type = { - PyObject_HEAD_INIT(NULL) - 0, "Font", sizeof(FontObject), 0, - /* methods */ - (destructor)font_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - (getattrfunc)font_getattr, /* tp_getattr */ -}; - -static PyMethodDef _functions[] = { - {"getfont", (PyCFunction) getfont, METH_VARARGS|METH_KEYWORDS}, - {NULL, NULL} -}; - -DL_EXPORT(void) -init_imagingft(void) -{ - PyObject* m; - PyObject* d; - PyObject* v; - int major, minor, patch; - - /* Patch object type */ - Font_Type.ob_type = &PyType_Type; - - m = Py_InitModule("_imagingft", _functions); - d = PyModule_GetDict(m); - - if (FT_Init_FreeType(&library)) - return; /* leave it uninitalized */ - - FT_Library_Version(library, &major, &minor, &patch); - -#if PY_VERSION_HEX >= 0x02020000 - v = PyString_FromFormat("%d.%d.%d", major, minor, patch); -#else - { - char buffer[100]; - sprintf(buffer, "%d.%d.%d", major, minor, patch); - v = PyString_FromString(buffer); - } -#endif - PyDict_SetItemString(d, "freetype2_version", v); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c deleted file mode 100755 index 928986bb323..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingmath.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * The Python Imaging Library - * - * a simple math add-on for the Python Imaging Library - * - * history: - * 1999-02-15 fl Created - * 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 - * - * Copyright (c) 1999-2005 by Secret Labs AB - * Copyright (c) 2005 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - -#include "Python.h" - -#include "Imaging.h" - -#include "math.h" -#include "float.h" - -#define MAX_INT32 2147483647.0 -#define MIN_INT32 -2147483648.0 - -#if defined(_MSC_VER) && _MSC_VER < 1500 -/* python 2.1/2.2/2.3 = VC98 = VER 1200 */ -/* python 2.4/2.5 = VS.NET 2003 = VER 1310 */ -/* python 2.6 = VS 9.0 = VER 1500 */ -#define powf(a, b) ((float) pow((double) (a), (double) (b))) -#endif - -#define UNOP(name, op, type)\ -void name(Imaging out, Imaging im1)\ -{\ - int x, y;\ - for (y = 0; y < out->ysize; y++) {\ - type* p0 = (type*) out->image[y];\ - type* p1 = (type*) im1->image[y];\ - for (x = 0; x < out->xsize; x++) {\ - *p0 = op(type, *p1);\ - p0++; p1++;\ - }\ - }\ -} - -#define BINOP(name, op, type)\ -void name(Imaging out, Imaging im1, Imaging im2)\ -{\ - int x, y;\ - for (y = 0; y < out->ysize; y++) {\ - type* p0 = (type*) out->image[y];\ - type* p1 = (type*) im1->image[y];\ - type* p2 = (type*) im2->image[y];\ - for (x = 0; x < out->xsize; x++) {\ - *p0 = op(type, *p1, *p2);\ - p0++; p1++; p2++;\ - }\ - }\ -} - -#define NEG(type, v1) -(v1) -#define INVERT(type, v1) ~(v1) - -#define ADD(type, v1, v2) (v1)+(v2) -#define SUB(type, v1, v2) (v1)-(v2) -#define MUL(type, v1, v2) (v1)*(v2) - -#define MIN(type, v1, v2) ((v1)<(v2))?(v1):(v2) -#define MAX(type, v1, v2) ((v1)>(v2))?(v1):(v2) - -#define AND(type, v1, v2) (v1)&(v2) -#define OR(type, v1, v2) (v1)|(v2) -#define XOR(type, v1, v2) (v1)^(v2) -#define LSHIFT(type, v1, v2) (v1)<<(v2) -#define RSHIFT(type, v1, v2) (v1)>>(v2) - -#define ABS_I(type, v1) abs((v1)) -#define ABS_F(type, v1) fabs((v1)) - -/* -------------------------------------------------------------------- - * some day, we should add FPE protection mechanisms. see pyfpe.h for - * details. - * - * PyFPE_START_PROTECT("Error in foobar", return 0) - * PyFPE_END_PROTECT(result) - */ - -#define DIV_I(type, v1, v2) ((v2)!=0)?(v1)/(v2):0 -#define DIV_F(type, v1, v2) ((v2)!=0.0F)?(v1)/(v2):0.0F - -#define MOD_I(type, v1, v2) ((v2)!=0)?(v1)%(v2):0 -#define MOD_F(type, v1, v2) ((v2)!=0.0F)?fmod((v1),(v2)):0.0F - -static int powi(int x, int y) -{ - double v = pow(x, y) + 0.5; - if (errno == EDOM) - return 0; - if (v < MIN_INT32) - v = MIN_INT32; - else if (v > MAX_INT32) - v = MAX_INT32; - return (int) v; -} - -#define POW_I(type, v1, v2) powi(v1, v2) -#define POW_F(type, v1, v2) powf(v1, v2) /* FIXME: EDOM handling */ - -#define DIFF_I(type, v1, v2) abs((v1)-(v2)) -#define DIFF_F(type, v1, v2) fabs((v1)-(v2)) - -#define EQ(type, v1, v2) (v1)==(v2) -#define NE(type, v1, v2) (v1)!=(v2) -#define LT(type, v1, v2) (v1)<(v2) -#define LE(type, v1, v2) (v1)<=(v2) -#define GT(type, v1, v2) (v1)>(v2) -#define GE(type, v1, v2) (v1)>=(v2) - -UNOP(abs_I, ABS_I, INT32) -UNOP(neg_I, NEG, INT32) - -BINOP(add_I, ADD, INT32) -BINOP(sub_I, SUB, INT32) -BINOP(mul_I, MUL, INT32) -BINOP(div_I, DIV_I, INT32) -BINOP(mod_I, MOD_I, INT32) -BINOP(pow_I, POW_I, INT32) -BINOP(diff_I, DIFF_I, INT32) - -UNOP(invert_I, INVERT, INT32) -BINOP(and_I, AND, INT32) -BINOP(or_I, OR, INT32) -BINOP(xor_I, XOR, INT32) -BINOP(lshift_I, LSHIFT, INT32) -BINOP(rshift_I, RSHIFT, INT32) - -BINOP(min_I, MIN, INT32) -BINOP(max_I, MAX, INT32) - -BINOP(eq_I, EQ, INT32) -BINOP(ne_I, NE, INT32) -BINOP(lt_I, LT, INT32) -BINOP(le_I, LE, INT32) -BINOP(gt_I, GT, INT32) -BINOP(ge_I, GE, INT32) - -UNOP(abs_F, ABS_F, FLOAT32) -UNOP(neg_F, NEG, FLOAT32) - -BINOP(add_F, ADD, FLOAT32) -BINOP(sub_F, SUB, FLOAT32) -BINOP(mul_F, MUL, FLOAT32) -BINOP(div_F, DIV_F, FLOAT32) -BINOP(mod_F, MOD_F, FLOAT32) -BINOP(pow_F, POW_F, FLOAT32) -BINOP(diff_F, DIFF_F, FLOAT32) - -BINOP(min_F, MIN, FLOAT32) -BINOP(max_F, MAX, FLOAT32) - -BINOP(eq_F, EQ, FLOAT32) -BINOP(ne_F, NE, FLOAT32) -BINOP(lt_F, LT, FLOAT32) -BINOP(le_F, LE, FLOAT32) -BINOP(gt_F, GT, FLOAT32) -BINOP(ge_F, GE, FLOAT32) - -static PyObject * -_unop(PyObject* self, PyObject* args) -{ - Imaging out; - Imaging im1; - void (*unop)(Imaging, Imaging); - - long op, i0, i1; - if (!PyArg_ParseTuple(args, "lll", &op, &i0, &i1)) - return NULL; - - out = (Imaging) i0; - im1 = (Imaging) i1; - - unop = (void*) op; - - unop(out, im1); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -_binop(PyObject* self, PyObject* args) -{ - Imaging out; - Imaging im1; - Imaging im2; - void (*binop)(Imaging, Imaging, Imaging); - - long op, i0, i1, i2; - if (!PyArg_ParseTuple(args, "llll", &op, &i0, &i1, &i2)) - return NULL; - - out = (Imaging) i0; - im1 = (Imaging) i1; - im2 = (Imaging) i2; - - binop = (void*) op; - - binop(out, im1, im2); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef _functions[] = { - {"unop", _unop, 1}, - {"binop", _binop, 1}, - {NULL, NULL} -}; - -static void -install(PyObject *d, char* name, void* value) -{ - PyObject *v = PyInt_FromLong((long) value); - if (!v || PyDict_SetItemString(d, name, v)) - PyErr_Clear(); - Py_XDECREF(v); -} - -DL_EXPORT(void) -init_imagingmath(void) -{ - PyObject* m; - PyObject* d; - - m = Py_InitModule("_imagingmath", _functions); - d = PyModule_GetDict(m); - - install(d, "abs_I", abs_I); - install(d, "neg_I", neg_I); - install(d, "add_I", add_I); - install(d, "sub_I", sub_I); - install(d, "diff_I", diff_I); - install(d, "mul_I", mul_I); - install(d, "div_I", div_I); - install(d, "mod_I", mod_I); - install(d, "min_I", min_I); - install(d, "max_I", max_I); - install(d, "pow_I", pow_I); - - install(d, "invert_I", invert_I); - install(d, "and_I", and_I); - install(d, "or_I", or_I); - install(d, "xor_I", xor_I); - install(d, "lshift_I", lshift_I); - install(d, "rshift_I", rshift_I); - - install(d, "eq_I", eq_I); - install(d, "ne_I", ne_I); - install(d, "lt_I", lt_I); - install(d, "le_I", le_I); - install(d, "gt_I", gt_I); - install(d, "ge_I", ge_I); - - install(d, "abs_F", abs_F); - install(d, "neg_F", neg_F); - install(d, "add_F", add_F); - install(d, "sub_F", sub_F); - install(d, "diff_F", diff_F); - install(d, "mul_F", mul_F); - install(d, "div_F", div_F); - install(d, "mod_F", mod_F); - install(d, "min_F", min_F); - install(d, "max_F", max_F); - install(d, "pow_F", pow_F); - - install(d, "eq_F", eq_F); - install(d, "ne_F", ne_F); - install(d, "lt_F", lt_F); - install(d, "le_F", le_F); - install(d, "gt_F", gt_F); - install(d, "ge_F", ge_F); - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c deleted file mode 100755 index 6165a2acb93..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/_imagingtk.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * The Python Imaging Library. - * - * tkinter hooks - * - * history: - * 99-07-26 fl created - * 99-08-15 fl moved to its own support module - * - * Copyright (c) Secret Labs AB 1999. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Python.h" -#include "Imaging.h" - -#include "tk.h" - -/* must link with Tk/tkImaging.c */ -extern void TkImaging_Init(Tcl_Interp* interp); - -/* copied from _tkinter.c (this isn't as bad as it may seem: for new - versions, we use _tkinter's interpaddr hook instead, and all older - versions use this structure layout) */ - -typedef struct { - PyObject_HEAD - Tcl_Interp* interp; -} TkappObject; - -static PyObject* -_tkinit(PyObject* self, PyObject* args) -{ - Tcl_Interp* interp; - - long arg; - int is_interp; - if (!PyArg_ParseTuple(args, "li", &arg, &is_interp)) - return NULL; - - if (is_interp) - interp = (Tcl_Interp*) arg; - else { - TkappObject* app; - /* Do it the hard way. This will break if the TkappObject - layout changes */ - app = (TkappObject*) arg; - interp = app->interp; - } - - /* This will bomb if interp is invalid... */ - TkImaging_Init(interp); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef functions[] = { - /* Tkinter interface stuff */ - {"tkinit", (PyCFunction)_tkinit, 1}, - {NULL, NULL} /* sentinel */ -}; - -DL_EXPORT(void) -init_imagingtk(void) -{ - Py_InitModule("_imagingtk", functions); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.exp b/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.exp deleted file mode 100755 index 7247036d7846cba448752fb860a08262cea605b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 670 zcmY*XO;5r=5S@aGF&@Bp^w0wbh_We|h%p+8Uy+DtAmOwLS=hC1EZwGEp!y%YdGk;B z!@PJm(b+adnRMQ~d719)&ThxbL8JE8`?dhqAu)>x&NNFCgB^5^{$UcdHS`vKgp1MC zE%%LPtcYuTrgVWVD4v5Z6llFusSR`oHm54Zi zT{tck@DI~7wG9kvX2Go-hbmGJ+OG7fcBkFFfmb*w!FbN$;)rT@7-^=Z@~KwJi|Dn~ zBNbo90rR;CseY6p9|kPc&$OMMyH+Q4(gYC;I6tEIp>jhuv9F{jBD)eF9#rXH&w-4l z%(MG?%B8aF4sqzz@OC0Da|`1vs>`+xJMJ`d4L zmrZbm24<-ey1@(+FcZ#{w8~66Q|5OeJ{f1Bl)DaE9ZnYtlH^8AG?s%c#N{3S0vo-5 AWB>pF diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.lib b/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imaging.lib deleted file mode 100755 index c6fe61113dae7ec20238a1c100fb1862481fca66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1736 zcmcIl%}(1u5dLfzNG*h-(i@^O5>nwnN{r1^Mm>ZHwlQ#Ge96><}{TjlswC#ES zYT!gvS_;9Z?b2GfvJ@=Qk*MCFVLxh$4m!Cc%hqdJoYVJL2`Eh{VERny%_=d5ctQ3=kJ$pOGo9vPykr)GQa=vr zErzoLB;*U37*Fx>tM#aI5Ff^0o7RLsX?excTC#g<7$lw#@&%v@@hVFrS8agM(Lx)W zAulR%y+Q8A$3Jm(B?kEn6Z@w_qAmc5$9p14;$usONF3H70opq5jfCZ6JSgJZf%l5z zNk>5A)9}e@Hn!cSU7-3Oym|AF z__s{F>uj4M#!2Vxo0r+n?Cf4yIjC3O`h^_88YE^B!I@@hVDKKDqkotHZ56$ZAK_v+ zaY}baGqz;`e5G`bZP++5fvJ&+m+Bdq(S?_6)X~T zu`&^H0K0Hh%;PRoH??(K)YO7&ISN&z9<^QW@7Pz}-X*-kaS=u{4yP@uok66TmddAE zDL0}QQV&&p76;7dBBXjOLp}&tsGn&!ok68WYNP=o7SL(Y+fX?n^Xzl!ipVa<&BGn~ zTk}Ci6Xx1?dcvi$YgJOE4;^~a?NL|yPuRM^TY_fMOn>lirtOi!<4dll@9_O?PPh0H z%$_BPUV6;Kztk~GmCy;M7=W2{rleVB;+ZnL3GoS4=SrzpMXNz)t{_Qn#;nG2u!;D; F%O5MChW`Kn diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.lib b/tools/HitboxExpander/third_party/Imaging-1.1.7/build/temp.win32-2.7/Release/_imagingmath.lib deleted file mode 100755 index 725d4c008867b596b0bb6209e3b04d6e2073a741..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1882 zcmcIl!EVz)5Pfz+TPzM%LG7uMfg<2Q(ztfW0aY#(L{!(U-1LUznxsv9NF9~55-08z zM~-{}AA$M}960a+{f#oS@y2cvnxraYd3WdScz0&@&HCZ1@VMSu(~8DbDXms)%QDNQ zm8-Z^OSY9v>}vq-0ICk;JsO??GZ*{@L3L|q+ph&1Z+GAL)t%b59|Tc5Y(_`TcGztp z2)sSl9k#-ktXa>f_I}UX3^vwl>-1UF?oe|Sb+dLDMy8IcTG@+hv)MsXm>u_yOZp6I@oO<$q&xdE*x4>&Ozx0+o_dEhEJm@mHh z3konNas{Q(IQV$dT;A=ez&jdzl}ge(&|ep#M%WFPO*!>|2EXVfA_>V+>tN+Pu`4Gq z=4p_p{iGe^4vcd;I4t5WtI!9-e2V+}EKTsDEX?5ebbc$UAIG2K!>;kne{Q%{Z&S<; zH1|m74|xIFTa1YMf)}&I!Ia-3qj2hRyF+frr{8gTDL3WsSlCY$GI|FPp0^|-;^f_O z60z8Z0Q7C_6k+@cH;M4-z*?elr{V*(H)rh_E>6iF)3*Ed<|?XS&rjhc`#PFE4KbBA z8TPD7l-ct`DoM}m`G2gKstate, 0, sizeof(decoder->state)); - - /* Allocate decoder context */ - if (contextsize > 0) { - context = (void*) calloc(1, contextsize); - if (!context) { - Py_DECREF(decoder); - (void) PyErr_NoMemory(); - return NULL; - } - } else - context = 0; - - /* Initialize decoder context */ - decoder->state.context = context; - - /* Target image */ - decoder->lock = NULL; - decoder->im = NULL; - - return decoder; -} - -static void -_dealloc(ImagingDecoderObject* decoder) -{ - free(decoder->state.buffer); - free(decoder->state.context); - Py_XDECREF(decoder->lock); - PyObject_Del(decoder); -} - -static PyObject* -_decode(ImagingDecoderObject* decoder, PyObject* args) -{ - UINT8* buffer; - int bufsize, status; - - if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize)) - return NULL; - - status = decoder->decode(decoder->im, &decoder->state, buffer, bufsize); - - return Py_BuildValue("ii", status, decoder->state.errcode); -} - -extern Imaging PyImaging_AsImaging(PyObject *op); - -static PyObject* -_setimage(ImagingDecoderObject* decoder, PyObject* args) -{ - PyObject* op; - Imaging im; - ImagingCodecState state; - int x0, y0, x1, y1; - - x0 = y0 = x1 = y1 = 0; - - /* FIXME: should publish the ImagingType descriptor */ - if (!PyArg_ParseTuple(args, "O|(iiii)", &op, &x0, &y0, &x1, &y1)) - return NULL; - im = PyImaging_AsImaging(op); - if (!im) - return NULL; - - decoder->im = im; - - state = &decoder->state; - - /* Setup decoding tile extent */ - if (x0 == 0 && x1 == 0) { - state->xsize = im->xsize; - state->ysize = im->ysize; - } else { - state->xoff = x0; - state->yoff = y0; - state->xsize = x1 - x0; - state->ysize = y1 - y0; - } - - if (state->xsize <= 0 || - state->xsize + state->xoff > (int) im->xsize || - state->ysize <= 0 || - state->ysize + state->yoff > (int) im->ysize) { - PyErr_SetString(PyExc_ValueError, "tile cannot extend outside image"); - return NULL; - } - - /* Allocate memory buffer (if bits field is set) */ - if (state->bits > 0) { - if (!state->bytes) - state->bytes = (state->bits * state->xsize+7)/8; - state->buffer = (UINT8*) malloc(state->bytes); - if (!state->buffer) - return PyErr_NoMemory(); - } - - /* Keep a reference to the image object, to make sure it doesn't - go away before we do */ - Py_INCREF(op); - Py_XDECREF(decoder->lock); - decoder->lock = op; - - Py_INCREF(Py_None); - return Py_None; -} - -static struct PyMethodDef methods[] = { - {"decode", (PyCFunction)_decode, 1}, - {"setimage", (PyCFunction)_setimage, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -_getattr(ImagingDecoderObject* self, char* name) -{ - return Py_FindMethod(methods, (PyObject*) self, name); -} - -statichere PyTypeObject ImagingDecoderType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingDecoder", /*tp_name*/ - sizeof(ImagingDecoderObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_hash*/ -}; - -/* -------------------------------------------------------------------- */ - -int -get_unpacker(ImagingDecoderObject* decoder, const char* mode, - const char* rawmode) -{ - int bits; - ImagingShuffler unpack; - - unpack = ImagingFindUnpacker(mode, rawmode, &bits); - if (!unpack) { - Py_DECREF(decoder); - PyErr_SetString(PyExc_ValueError, "unknown raw mode"); - return -1; - } - - decoder->state.shuffle = unpack; - decoder->state.bits = bits; - - return 0; -} - - -/* -------------------------------------------------------------------- */ -/* BIT (packed fields) */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_BitDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - int bits = 8; - int pad = 8; - int fill = 0; - int sign = 0; - int ystep = 1; - if (!PyArg_ParseTuple(args, "s|iiiii", &mode, &bits, &pad, &fill, - &sign, &ystep)) - return NULL; - - if (strcmp(mode, "F") != 0) { - PyErr_SetString(PyExc_ValueError, "bad image mode"); - return NULL; - } - - decoder = PyImaging_DecoderNew(sizeof(BITSTATE)); - if (decoder == NULL) - return NULL; - - decoder->decode = ImagingBitDecode; - - decoder->state.ystep = ystep; - - ((BITSTATE*)decoder->state.context)->bits = bits; - ((BITSTATE*)decoder->state.context)->pad = pad; - ((BITSTATE*)decoder->state.context)->fill = fill; - ((BITSTATE*)decoder->state.context)->sign = sign; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* FLI */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_FliDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - decoder->decode = ImagingFliDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* GIF */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_GifDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - int bits = 8; - int interlace = 0; - if (!PyArg_ParseTuple(args, "s|ii", &mode, &bits, &interlace)) - return NULL; - - if (strcmp(mode, "L") != 0 && strcmp(mode, "P") != 0) { - PyErr_SetString(PyExc_ValueError, "bad image mode"); - return NULL; - } - - decoder = PyImaging_DecoderNew(sizeof(GIFDECODERSTATE)); - if (decoder == NULL) - return NULL; - - decoder->decode = ImagingGifDecode; - - ((GIFDECODERSTATE*)decoder->state.context)->bits = bits; - ((GIFDECODERSTATE*)decoder->state.context)->interlace = interlace; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* HEX */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_HexDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) - return NULL; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingHexDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* LZW */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - int filter = 0; - if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &filter)) - return NULL; - - decoder = PyImaging_DecoderNew(sizeof(LZWSTATE)); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingLzwDecode; - - ((LZWSTATE*)decoder->state.context)->filter = filter; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* MSP */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_MspDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, "1", "1") < 0) - return NULL; - - decoder->decode = ImagingMspDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* PackBits */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) - return NULL; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingPackbitsDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* PCD */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_PcdDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - /* Unpack from PhotoYCC to RGB */ - if (get_unpacker(decoder, "RGB", "YCC;P") < 0) - return NULL; - - decoder->decode = ImagingPcdDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* PCX */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_PcxDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - int stride; - if (!PyArg_ParseTuple(args, "ssi", &mode, &rawmode, &stride)) - return NULL; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->state.bytes = stride; - - decoder->decode = ImagingPcxDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* RAW */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_RawDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - int stride = 0; - int ystep = 1; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) - return NULL; - - decoder = PyImaging_DecoderNew(sizeof(RAWSTATE)); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingRawDecode; - - decoder->state.ystep = ystep; - - ((RAWSTATE*)decoder->state.context)->stride = stride; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* SUN RLE */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - if (!PyArg_ParseTuple(args, "ss", &mode, &rawmode)) - return NULL; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingSunRleDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* TGA RLE */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - int ystep = 1; - int depth = 8; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &ystep, &depth)) - return NULL; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingTgaRleDecode; - - decoder->state.ystep = ystep; - decoder->state.count = depth / 8; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* XBM */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_XbmDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - decoder = PyImaging_DecoderNew(0); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, "1", "1;R") < 0) - return NULL; - - decoder->decode = ImagingXbmDecode; - - return (PyObject*) decoder; -} - - -/* -------------------------------------------------------------------- */ -/* ZIP */ -/* -------------------------------------------------------------------- */ - -#ifdef HAVE_LIBZ - -#include "Zip.h" - -PyObject* -PyImaging_ZipDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; - int interlaced = 0; - if (!PyArg_ParseTuple(args, "ss|i", &mode, &rawmode, &interlaced)) - return NULL; - - decoder = PyImaging_DecoderNew(sizeof(ZIPSTATE)); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingZipDecode; - - ((ZIPSTATE*)decoder->state.context)->interlaced = interlaced; - - return (PyObject*) decoder; -} -#endif - - -/* -------------------------------------------------------------------- */ -/* JPEG */ -/* -------------------------------------------------------------------- */ - -#ifdef HAVE_LIBJPEG - -/* We better define this decoder last in this file, so the following - undef's won't mess things up for the Imaging library proper. */ - -#undef HAVE_PROTOTYPES -#undef HAVE_STDDEF_H -#undef HAVE_STDLIB_H -#undef UINT8 -#undef UINT16 -#undef UINT32 -#undef INT8 -#undef INT16 -#undef INT32 - -#include "Jpeg.h" - -PyObject* -PyImaging_JpegDecoderNew(PyObject* self, PyObject* args) -{ - ImagingDecoderObject* decoder; - - char* mode; - char* rawmode; /* what we wan't from the decoder */ - char* jpegmode; /* what's in the file */ - int scale = 1; - int draft = 0; - if (!PyArg_ParseTuple(args, "ssz|ii", &mode, &rawmode, &jpegmode, - &scale, &draft)) - return NULL; - - if (!jpegmode) - jpegmode = ""; - - decoder = PyImaging_DecoderNew(sizeof(JPEGSTATE)); - if (decoder == NULL) - return NULL; - - if (get_unpacker(decoder, mode, rawmode) < 0) - return NULL; - - decoder->decode = ImagingJpegDecode; - - strncpy(((JPEGSTATE*)decoder->state.context)->rawmode, rawmode, 8); - strncpy(((JPEGSTATE*)decoder->state.context)->jpegmode, jpegmode, 8); - - ((JPEGSTATE*)decoder->state.context)->scale = scale; - ((JPEGSTATE*)decoder->state.context)->draft = draft; - - return (PyObject*) decoder; -} -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/display.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/display.c deleted file mode 100755 index 1a08fadd56e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/display.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * The Python Imaging Library. - * - * display support (and other windows-related stuff) - * - * History: - * 1996-05-13 fl Windows DIB support - * 1996-05-21 fl Added palette stuff - * 1996-05-28 fl Added display_mode stuff - * 1997-09-21 fl Added draw primitive - * 2001-09-17 fl Added ImagingGrabScreen (from _grabscreen.c) - * 2002-05-12 fl Added ImagingListWindows - * 2002-11-19 fl Added clipboard support - * 2002-11-25 fl Added GetDC/ReleaseDC helpers - * 2003-05-21 fl Added create window support (including window callback) - * 2003-09-05 fl Added fromstring/tostring methods - * 2009-03-14 fl Added WMF support (from pilwmf) - * - * Copyright (c) 1997-2003 by Secret Labs AB. - * Copyright (c) 1996-1997 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Python.h" - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#include "Imaging.h" - -/* -------------------------------------------------------------------- */ -/* Windows DIB support */ - -#ifdef WIN32 - -#include "ImDib.h" - -typedef struct { - PyObject_HEAD - ImagingDIB dib; -} ImagingDisplayObject; - -staticforward PyTypeObject ImagingDisplayType; - -static ImagingDisplayObject* -_new(const char* mode, int xsize, int ysize) -{ - ImagingDisplayObject *display; - - display = PyObject_New(ImagingDisplayObject, &ImagingDisplayType); - if (display == NULL) - return NULL; - - display->dib = ImagingNewDIB(mode, xsize, ysize); - if (!display->dib) { - Py_DECREF(display); - return NULL; - } - - return display; -} - -static void -_delete(ImagingDisplayObject* display) -{ - if (display->dib) - ImagingDeleteDIB(display->dib); - PyObject_Del(display); -} - -static PyObject* -_expose(ImagingDisplayObject* display, PyObject* args) -{ - int hdc; - if (!PyArg_ParseTuple(args, "i", &hdc)) - return NULL; - - ImagingExposeDIB(display->dib, hdc); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_draw(ImagingDisplayObject* display, PyObject* args) -{ - int hdc; - int dst[4]; - int src[4]; - if (!PyArg_ParseTuple(args, "i(iiii)(iiii)", &hdc, - dst+0, dst+1, dst+2, dst+3, - src+0, src+1, src+2, src+3)) - return NULL; - - ImagingDrawDIB(display->dib, hdc, dst, src); - - Py_INCREF(Py_None); - return Py_None; -} - -extern Imaging PyImaging_AsImaging(PyObject *op); - -static PyObject* -_paste(ImagingDisplayObject* display, PyObject* args) -{ - Imaging im; - - PyObject* op; - int xy[4]; - xy[0] = xy[1] = xy[2] = xy[3] = 0; - if (!PyArg_ParseTuple(args, "O|(iiii)", &op, xy+0, xy+1, xy+2, xy+3)) - return NULL; - im = PyImaging_AsImaging(op); - if (!im) - return NULL; - - if (xy[2] <= xy[0]) - xy[2] = xy[0] + im->xsize; - if (xy[3] <= xy[1]) - xy[3] = xy[1] + im->ysize; - - ImagingPasteDIB(display->dib, im, xy); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_query_palette(ImagingDisplayObject* display, PyObject* args) -{ - int hdc; - int status; - - if (!PyArg_ParseTuple(args, "i", &hdc)) - return NULL; - - status = ImagingQueryPaletteDIB(display->dib, hdc); - - return Py_BuildValue("i", status); -} - -static PyObject* -_getdc(ImagingDisplayObject* display, PyObject* args) -{ - int window; - HDC dc; - - if (!PyArg_ParseTuple(args, "i", &window)) - return NULL; - - dc = GetDC((HWND) window); - if (!dc) { - PyErr_SetString(PyExc_IOError, "cannot create dc"); - return NULL; - } - - return Py_BuildValue("i", (int) dc); -} - -static PyObject* -_releasedc(ImagingDisplayObject* display, PyObject* args) -{ - int window, dc; - - if (!PyArg_ParseTuple(args, "ii", &window, &dc)) - return NULL; - - ReleaseDC((HWND) window, (HDC) dc); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_fromstring(ImagingDisplayObject* display, PyObject* args) -{ - char* ptr; - int bytes; - if (!PyArg_ParseTuple(args, "s#:fromstring", &ptr, &bytes)) - return NULL; - - if (display->dib->ysize * display->dib->linesize != bytes) { - PyErr_SetString(PyExc_ValueError, "wrong size"); - return NULL; - } - - memcpy(display->dib->bits, ptr, bytes); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_tostring(ImagingDisplayObject* display, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":tostring")) - return NULL; - - return PyString_FromStringAndSize( - display->dib->bits, display->dib->ysize * display->dib->linesize - ); -} - -static struct PyMethodDef methods[] = { - {"draw", (PyCFunction)_draw, 1}, - {"expose", (PyCFunction)_expose, 1}, - {"paste", (PyCFunction)_paste, 1}, - {"query_palette", (PyCFunction)_query_palette, 1}, - {"getdc", (PyCFunction)_getdc, 1}, - {"releasedc", (PyCFunction)_releasedc, 1}, - {"fromstring", (PyCFunction)_fromstring, 1}, - {"tostring", (PyCFunction)_tostring, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -_getattr(ImagingDisplayObject* self, char* name) -{ - PyObject* res; - - res = Py_FindMethod(methods, (PyObject*) self, name); - if (res) - return res; - PyErr_Clear(); - if (!strcmp(name, "mode")) - return Py_BuildValue("s", self->dib->mode); - if (!strcmp(name, "size")) - return Py_BuildValue("ii", self->dib->xsize, self->dib->ysize); - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -statichere PyTypeObject ImagingDisplayType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingDisplay", /*tp_name*/ - sizeof(ImagingDisplayObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_delete, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_hash*/ -}; - -PyObject* -PyImaging_DisplayWin32(PyObject* self, PyObject* args) -{ - ImagingDisplayObject* display; - char *mode; - int xsize, ysize; - - if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; - - display = _new(mode, xsize, ysize); - if (display == NULL) - return NULL; - - return (PyObject*) display; -} - -PyObject* -PyImaging_DisplayModeWin32(PyObject* self, PyObject* args) -{ - char *mode; - int size[2]; - - mode = ImagingGetModeDIB(size); - - return Py_BuildValue("s(ii)", mode, size[0], size[1]); -} - -/* -------------------------------------------------------------------- */ -/* Windows screen grabber */ - -PyObject* -PyImaging_GrabScreenWin32(PyObject* self, PyObject* args) -{ - int width, height; - HBITMAP bitmap; - BITMAPCOREHEADER core; - HDC screen, screen_copy; - PyObject* buffer; - - /* step 1: create a memory DC large enough to hold the - entire screen */ - - screen = CreateDC("DISPLAY", NULL, NULL, NULL); - screen_copy = CreateCompatibleDC(screen); - - width = GetDeviceCaps(screen, HORZRES); - height = GetDeviceCaps(screen, VERTRES); - - bitmap = CreateCompatibleBitmap(screen, width, height); - if (!bitmap) - goto error; - - if (!SelectObject(screen_copy, bitmap)) - goto error; - - /* step 2: copy bits into memory DC bitmap */ - - if (!BitBlt(screen_copy, 0, 0, width, height, screen, 0, 0, SRCCOPY)) - goto error; - - /* step 3: extract bits from bitmap */ - - buffer = PyString_FromStringAndSize(NULL, height * ((width*3 + 3) & -4)); - if (!buffer) - return NULL; - - core.bcSize = sizeof(core); - core.bcWidth = width; - core.bcHeight = height; - core.bcPlanes = 1; - core.bcBitCount = 24; - if (!GetDIBits(screen_copy, bitmap, 0, height, PyString_AS_STRING(buffer), - (BITMAPINFO*) &core, DIB_RGB_COLORS)) - goto error; - - DeleteObject(bitmap); - DeleteDC(screen_copy); - DeleteDC(screen); - - return Py_BuildValue("(ii)N", width, height, buffer); - -error: - PyErr_SetString(PyExc_IOError, "screen grab failed"); - - DeleteDC(screen_copy); - DeleteDC(screen); - - return NULL; -} - -static BOOL CALLBACK list_windows_callback(HWND hwnd, LPARAM lParam) -{ - PyObject* window_list = (PyObject*) lParam; - PyObject* item; - PyObject* title; - RECT inner, outer; - int title_size; - int status; - - /* get window title */ - title_size = GetWindowTextLength(hwnd); - if (title_size > 0) { - title = PyString_FromStringAndSize(NULL, title_size); - if (title) - GetWindowText(hwnd, PyString_AS_STRING(title), title_size+1); - } else - title = PyString_FromString(""); - if (!title) - return 0; - - /* get bounding boxes */ - GetClientRect(hwnd, &inner); - GetWindowRect(hwnd, &outer); - - item = Py_BuildValue( - "lN(iiii)(iiii)", (long) hwnd, title, - inner.left, inner.top, inner.right, inner.bottom, - outer.left, outer.top, outer.right, outer.bottom - ); - if (!item) - return 0; - - status = PyList_Append(window_list, item); - - Py_DECREF(item); - - if (status < 0) - return 0; - - return 1; -} - -PyObject* -PyImaging_ListWindowsWin32(PyObject* self, PyObject* args) -{ - PyObject* window_list; - - window_list = PyList_New(0); - if (!window_list) - return NULL; - - EnumWindows(list_windows_callback, (LPARAM) window_list); - - if (PyErr_Occurred()) { - Py_DECREF(window_list); - return NULL; - } - - return window_list; -} - -/* -------------------------------------------------------------------- */ -/* Windows clipboard grabber */ - -PyObject* -PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args) -{ - int clip; - HANDLE handle; - int size; - void* data; - PyObject* result; - - int verbose = 0; /* debugging; will be removed in future versions */ - if (!PyArg_ParseTuple(args, "|i", &verbose)) - return NULL; - - - clip = OpenClipboard(NULL); - /* FIXME: check error status */ - - if (verbose) { - UINT format = EnumClipboardFormats(0); - char buffer[200]; - char* result; - while (format != 0) { - if (GetClipboardFormatName(format, buffer, sizeof buffer) > 0) - result = buffer; - else - switch (format) { - case CF_BITMAP: - result = "CF_BITMAP"; - break; - case CF_DIB: - result = "CF_DIB"; - break; - case CF_DIF: - result = "CF_DIF"; - break; - case CF_ENHMETAFILE: - result = "CF_ENHMETAFILE"; - break; - case CF_HDROP: - result = "CF_HDROP"; - break; - case CF_LOCALE: - result = "CF_LOCALE"; - break; - case CF_METAFILEPICT: - result = "CF_METAFILEPICT"; - break; - case CF_OEMTEXT: - result = "CF_OEMTEXT"; - break; - case CF_OWNERDISPLAY: - result = "CF_OWNERDISPLAY"; - break; - case CF_PALETTE: - result = "CF_PALETTE"; - break; - case CF_PENDATA: - result = "CF_PENDATA"; - break; - case CF_RIFF: - result = "CF_RIFF"; - break; - case CF_SYLK: - result = "CF_SYLK"; - break; - case CF_TEXT: - result = "CF_TEXT"; - break; - case CF_WAVE: - result = "CF_WAVE"; - break; - case CF_TIFF: - result = "CF_TIFF"; - break; - case CF_UNICODETEXT: - result = "CF_UNICODETEXT"; - break; - default: - sprintf(buffer, "[%d]", format); - result = buffer; - break; - } - printf("%s (%d)\n", result, format); - format = EnumClipboardFormats(format); - } - } - - handle = GetClipboardData(CF_DIB); - if (!handle) { - /* FIXME: add CF_HDROP support to allow cut-and-paste from - the explorer */ - CloseClipboard(); - Py_INCREF(Py_None); - return Py_None; - } - - size = GlobalSize(handle); - data = GlobalLock(handle); - -#if 0 - /* calculate proper size for string formats */ - if (format == CF_TEXT || format == CF_OEMTEXT) - size = strlen(data); - else if (format == CF_UNICODETEXT) - size = wcslen(data) * 2; -#endif - - result = PyString_FromStringAndSize(data, size); - - GlobalUnlock(handle); - - CloseClipboard(); - - return result; -} - -/* -------------------------------------------------------------------- */ -/* Windows class */ - -#ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL 522 -#endif - -static int mainloop = 0; - -static void -callback_error(const char* handler) -{ - PyObject* sys_stderr; - - sys_stderr = PySys_GetObject("stderr"); - - if (sys_stderr) { - PyFile_WriteString("*** ImageWin: error in ", sys_stderr); - PyFile_WriteString((char*) handler, sys_stderr); - PyFile_WriteString(":\n", sys_stderr); - } - - PyErr_Print(); - PyErr_Clear(); -} - -static LRESULT CALLBACK -windowCallback(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - PAINTSTRUCT ps; - PyObject* callback = NULL; - PyObject* result; - PyThreadState* threadstate; - PyThreadState* current_threadstate; - HDC dc; - RECT rect; - LRESULT status = 0; - - /* set up threadstate for messages that calls back into python */ - switch (message) { - case WM_CREATE: - mainloop++; - break; - case WM_DESTROY: - mainloop--; - /* fall through... */ - case WM_PAINT: - case WM_SIZE: - callback = (PyObject*) GetWindowLong(wnd, 0); - if (callback) { - threadstate = (PyThreadState*) - GetWindowLong(wnd, sizeof(PyObject*)); - current_threadstate = PyThreadState_Swap(NULL); - PyEval_RestoreThread(threadstate); - } else - return DefWindowProc(wnd, message, wParam, lParam); - } - - /* process message */ - switch (message) { - - case WM_PAINT: - /* redraw (part of) window. this generates a WCK-style - damage/clear/repair cascade */ - BeginPaint(wnd, &ps); - dc = GetDC(wnd); - GetWindowRect(wnd, &rect); /* in screen coordinates */ - - result = PyObject_CallFunction( - callback, "siiii", "damage", - ps.rcPaint.left, ps.rcPaint.top, - ps.rcPaint.right, ps.rcPaint.bottom - ); - if (result) - Py_DECREF(result); - else - callback_error("window damage callback"); - - result = PyObject_CallFunction( - callback, "siiiii", "clear", (int) dc, - 0, 0, rect.right-rect.left, rect.bottom-rect.top - ); - if (result) - Py_DECREF(result); - else - callback_error("window clear callback"); - - result = PyObject_CallFunction( - callback, "siiiii", "repair", (int) dc, - 0, 0, rect.right-rect.left, rect.bottom-rect.top - ); - if (result) - Py_DECREF(result); - else - callback_error("window repair callback"); - - ReleaseDC(wnd, dc); - EndPaint(wnd, &ps); - break; - - case WM_SIZE: - /* resize window */ - result = PyObject_CallFunction( - callback, "sii", "resize", LOWORD(lParam), HIWORD(lParam) - ); - if (result) { - InvalidateRect(wnd, NULL, 1); - Py_DECREF(result); - } else - callback_error("window resize callback"); - break; - - case WM_DESTROY: - /* destroy window */ - result = PyObject_CallFunction(callback, "s", "destroy"); - if (result) - Py_DECREF(result); - else - callback_error("window destroy callback"); - Py_DECREF(callback); - break; - - default: - status = DefWindowProc(wnd, message, wParam, lParam); - } - - if (callback) { - /* restore thread state */ - PyEval_SaveThread(); - PyThreadState_Swap(threadstate); - } - - return status; -} - -PyObject* -PyImaging_CreateWindowWin32(PyObject* self, PyObject* args) -{ - HWND wnd; - WNDCLASS windowClass; - - char* title; - PyObject* callback; - int width = 0, height = 0; - if (!PyArg_ParseTuple(args, "sO|ii", &title, &callback, &width, &height)) - return NULL; - - if (width <= 0) - width = CW_USEDEFAULT; - if (height <= 0) - height = CW_USEDEFAULT; - - /* register toplevel window class */ - windowClass.style = CS_CLASSDC; - windowClass.cbClsExtra = 0; - windowClass.cbWndExtra = sizeof(PyObject*) + sizeof(PyThreadState*); - windowClass.hInstance = GetModuleHandle(NULL); - /* windowClass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); */ - windowClass.hbrBackground = NULL; - windowClass.lpszMenuName = NULL; - windowClass.lpszClassName = "pilWindow"; - windowClass.lpfnWndProc = windowCallback; - windowClass.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(1)); - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); /* CROSS? */ - - RegisterClass(&windowClass); /* FIXME: check return status */ - - wnd = CreateWindowEx( - 0, windowClass.lpszClassName, title, - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, width, height, - HWND_DESKTOP, NULL, NULL, NULL - ); - - if (!wnd) { - PyErr_SetString(PyExc_IOError, "failed to create window"); - return NULL; - } - - /* register window callback */ - Py_INCREF(callback); - SetWindowLong(wnd, 0, (LONG) callback); - SetWindowLong(wnd, sizeof(callback), (LONG) PyThreadState_Get()); - - Py_BEGIN_ALLOW_THREADS - ShowWindow(wnd, SW_SHOWNORMAL); - SetForegroundWindow(wnd); /* to make sure it's visible */ - Py_END_ALLOW_THREADS - - return Py_BuildValue("l", (long) wnd); -} - -PyObject* -PyImaging_EventLoopWin32(PyObject* self, PyObject* args) -{ - MSG msg; - - Py_BEGIN_ALLOW_THREADS - while (mainloop && GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - Py_END_ALLOW_THREADS - - Py_INCREF(Py_None); - return Py_None; -} - -/* -------------------------------------------------------------------- */ -/* windows WMF renderer */ - -#define GET32(p,o) ((DWORD*)(p+o))[0] - -PyObject * -PyImaging_DrawWmf(PyObject* self, PyObject* args) -{ - HBITMAP bitmap; - HENHMETAFILE meta; - BITMAPCOREHEADER core; - HDC dc; - RECT rect; - PyObject* buffer = NULL; - char* ptr; - - char* data; - int datasize; - int width, height; - int x0, y0, x1, y1; - if (!PyArg_ParseTuple(args, "s#(ii)(iiii):_load", &data, &datasize, - &width, &height, &x0, &x1, &y0, &y1)) - return NULL; - - /* step 1: copy metafile contents into METAFILE object */ - - if (datasize > 22 && GET32(data, 0) == 0x9ac6cdd7) { - - /* placeable windows metafile (22-byte aldus header) */ - meta = SetWinMetaFileBits(datasize-22, data+22, NULL, NULL); - - } else if (datasize > 80 && GET32(data, 0) == 1 && - GET32(data, 40) == 0x464d4520) { - - /* enhanced metafile */ - meta = SetEnhMetaFileBits(datasize, data); - - } else { - - /* unknown meta format */ - meta = NULL; - - } - - if (!meta) { - PyErr_SetString(PyExc_IOError, "cannot load metafile"); - return NULL; - } - - /* step 2: create bitmap */ - - core.bcSize = sizeof(core); - core.bcWidth = width; - core.bcHeight = height; - core.bcPlanes = 1; - core.bcBitCount = 24; - - dc = CreateCompatibleDC(NULL); - - bitmap = CreateDIBSection( - dc, (BITMAPINFO*) &core, DIB_RGB_COLORS, &ptr, NULL, 0 - ); - - if (!bitmap) { - PyErr_SetString(PyExc_IOError, "cannot create bitmap"); - goto error; - } - - if (!SelectObject(dc, bitmap)) { - PyErr_SetString(PyExc_IOError, "cannot select bitmap"); - goto error; - } - - /* step 3: render metafile into bitmap */ - - rect.left = rect.top = 0; - rect.right = width; - rect.bottom = height; - - /* FIXME: make background transparent? configurable? */ - FillRect(dc, &rect, GetStockObject(WHITE_BRUSH)); - - if (!PlayEnhMetaFile(dc, meta, &rect)) { - PyErr_SetString(PyExc_IOError, "cannot render metafile"); - goto error; - } - - /* step 4: extract bits from bitmap */ - - GdiFlush(); - - buffer = PyString_FromStringAndSize(ptr, height * ((width*3 + 3) & -4)); - -error: - DeleteEnhMetaFile(meta); - - if (bitmap) - DeleteObject(bitmap); - - DeleteDC(dc); - - return buffer; -} - -#endif /* WIN32 */ diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py deleted file mode 100755 index e8140ecdfdd..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/doctest.py +++ /dev/null @@ -1,1111 +0,0 @@ -# Module doctest version 0.9.6 -# Released to the public domain 16-Jan-2001, -# by Tim Peters (tim.one@home.com). - -# local modifications: -# 2001-02-13 fl: minor tweaks to make it run under both 1.5.2 and 2.0 - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -"""Module doctest -- a framework for running examples in docstrings. - -NORMAL USAGE - -In normal use, end each module M with: - -def _test(): - import doctest, M # replace M with your module's name - return doctest.testmod(M) # ditto - -if __name__ == "__main__": - _test() - -Then running the module as a script will cause the examples in the -docstrings to get executed and verified: - -python M.py - -This won't display anything unless an example fails, in which case the -failing example(s) and the cause(s) of the failure(s) are printed to stdout -(why not stderr? because stderr is a lame hack <0.2 wink>), and the final -line of output is "Test failed.". - -Run it with the -v switch instead: - -python M.py -v - -and a detailed report of all examples tried is printed to stdout, along -with assorted summaries at the end. - -You can force verbose mode by passing "verbose=1" to testmod, or prohibit -it by passing "verbose=0". In either of those cases, sys.argv is not -examined by testmod. - -In any case, testmod returns a 2-tuple of ints (f, t), where f is the -number of docstring examples that failed and t is the total number of -docstring examples attempted. - - -WHICH DOCSTRINGS ARE EXAMINED? - -+ M.__doc__. - -+ f.__doc__ for all functions f in M.__dict__.values(), except those - with private names. - -+ C.__doc__ for all classes C in M.__dict__.values(), except those with - private names. - -+ If M.__test__ exists and "is true", it must be a dict, and - each entry maps a (string) name to a function object, class object, or - string. Function and class object docstrings found from M.__test__ - are searched even if the name is private, and strings are searched - directly as if they were docstrings. In output, a key K in M.__test__ - appears with name - .__test__.K - -Any classes found are recursively searched similarly, to test docstrings in -their contained methods and nested classes. Private names reached from M's -globals are skipped, but all names reached from M.__test__ are searched. - -By default, a name is considered to be private if it begins with an -underscore (like "_my_func") but doesn't both begin and end with (at least) -two underscores (like "__init__"). You can change the default by passing -your own "isprivate" function to testmod. - -If you want to test docstrings in objects with private names too, stuff -them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your -own isprivate function to Tester's constructor, or call the rundoc method -of a Tester instance). - -Warning: imports can cause trouble; e.g., if you do - -from XYZ import XYZclass - -then XYZclass is a name in M.__dict__ too, and doctest has no way to know -that XYZclass wasn't *defined* in M. So it may try to execute the examples -in XYZclass's docstring, and those in turn may require a different set of -globals to work correctly. I prefer to do "import *"- friendly imports, -a la - -import XYY -_XYZclass = XYZ.XYZclass -del XYZ - -or (Python 2.0) - -from XYZ import XYZclass as _XYZclass - -and then the leading underscore stops testmod from going nuts. You may -prefer the method in the next section. - - -WHAT'S THE EXECUTION CONTEXT? - -By default, each time testmod finds a docstring to test, it uses a *copy* -of M's globals (so that running tests on a module doesn't change the -module's real globals, and so that one test in M can't leave behind crumbs -that accidentally allow another test to work). This means examples can -freely use any names defined at top-level in M. It also means that sloppy -imports (see above) can cause examples in external docstrings to use -globals inappropriate for them. - -You can force use of your own dict as the execution context by passing -"globs=your_dict" to testmod instead. Presumably this would be a copy of -M.__dict__ merged with the globals from other imported modules. - - -WHAT IF I WANT TO TEST A WHOLE PACKAGE? - -Piece o' cake, provided the modules do their testing from docstrings. -Here's the test.py I use for the world's most elaborate Rational/ -floating-base-conversion pkg (which I'll distribute some day): - -from Rational import Cvt -from Rational import Format -from Rational import machprec -from Rational import Rat -from Rational import Round -from Rational import utils - -modules = (Cvt, - Format, - machprec, - Rat, - Round, - utils) - -def _test(): - import doctest - import sys - verbose = "-v" in sys.argv - for mod in modules: - doctest.testmod(mod, verbose=verbose, report=0) - doctest.master.summarize() - -if __name__ == "__main__": - _test() - -IOW, it just runs testmod on all the pkg modules. testmod remembers the -names and outcomes (# of failures, # of tries) for each item it's seen, and -passing "report=0" prevents it from printing a summary in verbose mode. -Instead, the summary is delayed until all modules have been tested, and -then "doctest.master.summarize()" forces the summary at the end. - -So this is very nice in practice: each module can be tested individually -with almost no work beyond writing up docstring examples, and collections -of modules can be tested too as a unit with no more work than the above. - - -WHAT ABOUT EXCEPTIONS? - -No problem, as long as the only output generated by the example is the -traceback itself. For example: - - >>> a = [None] - >>> a[1] - Traceback (innermost last): - File "", line 1, in ? - IndexError: list index out of range - >>> - -Note that only the exception type and value are compared (specifically, -only the last line in the traceback). - - -ADVANCED USAGE - -doctest.testmod() captures the testing policy I find most useful most -often. You may want other policies. - -testmod() actually creates a local instance of class doctest.Tester, runs -appropriate methods of that class, and merges the results into global -Tester instance doctest.master. - -You can create your own instances of doctest.Tester, and so build your own -policies, or even run methods of doctest.master directly. See -doctest.Tester.__doc__ for details. - - -SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!? - -Oh ya. It's easy! In most cases a copy-and-paste of an interactive -console session works fine -- just make sure the leading whitespace is -rigidly consistent (you can mix tabs and spaces if you're too lazy to do it -right, but doctest is not in the business of guessing what you think a tab -means). - - >>> # comments are ignored - >>> x = 12 - >>> x - 12 - >>> if x == 13: - ... print "yes" - ... else: - ... print "no" - ... print "NO" - ... print "NO!!!" - ... - no - NO - NO!!! - >>> - -Any expected output must immediately follow the final ">>>" or "..." line -containing the code, and the expected output (if any) extends to the next -">>>" or all-whitespace line. That's it. - -Bummers: - -+ Expected output cannot contain an all-whitespace line, since such a line - is taken to signal the end of expected output. - -+ Output to stdout is captured, but not output to stderr (exception - tracebacks are captured via a different means). - -+ If you continue a line via backslashing in an interactive session, or for - any other reason use a backslash, you need to double the backslash in the - docstring version. This is simply because you're in a string, and so the - backslash must be escaped for it to survive intact. Like: - ->>> if "yes" == \\ -... "y" + \\ -... "es": # in the source code you'll see the doubled backslashes -... print 'yes' -yes - -The starting column doesn't matter: - ->>> assert "Easy!" - >>> import math - >>> math.floor(1.9) - 1.0 - -and as many leading whitespace characters are stripped from the expected -output as appeared in the initial ">>>" line that triggered it. - -If you execute this very file, the examples above will be found and -executed, leading to this output in verbose mode: - -Running doctest.__doc__ -Trying: a = [None] -Expecting: nothing -ok -Trying: a[1] -Expecting: -Traceback (innermost last): - File "", line 1, in ? -IndexError: list index out of range -ok -Trying: x = 12 -Expecting: nothing -ok -Trying: x -Expecting: 12 -ok -Trying: -if x == 13: - print "yes" -else: - print "no" - print "NO" - print "NO!!!" -Expecting: -no -NO -NO!!! -ok -... and a bunch more like that, with this summary at the end: - -5 items had no tests: - doctest.Tester.__init__ - doctest.Tester.run__test__ - doctest.Tester.summarize - doctest.run_docstring_examples - doctest.testmod -12 items passed all tests: - 9 tests in doctest - 6 tests in doctest.Tester - 10 tests in doctest.Tester.merge - 7 tests in doctest.Tester.rundict - 3 tests in doctest.Tester.rundoc - 3 tests in doctest.Tester.runstring - 2 tests in doctest.__test__._TestClass - 2 tests in doctest.__test__._TestClass.__init__ - 2 tests in doctest.__test__._TestClass.get - 1 tests in doctest.__test__._TestClass.square - 2 tests in doctest.__test__.string - 7 tests in doctest.is_private -54 tests in 17 items. -54 passed and 0 failed. -Test passed. -""" - -# 0,0,1 06-Mar-1999 -# initial version posted -# 0,0,2 06-Mar-1999 -# loosened parsing: -# cater to stinkin' tabs -# don't insist on a blank after PS2 prefix -# so trailing "... " line from a compound stmt no longer -# breaks if the file gets whitespace-trimmed -# better error msgs for inconsistent leading whitespace -# 0,9,1 08-Mar-1999 -# exposed the Tester class and added client methods -# plus docstring examples of their use (eww - head-twisting!) -# fixed logic error in reporting total # of tests & failures -# added __test__ support to testmod (a pale reflection of Christian -# Tismer's vision ...) -# removed the "deep" argument; fiddle __test__ instead -# simplified endcase logic for extracting tests, and running them. -# before, if no output was expected but some was produced -# anyway via an eval'ed result, the discrepancy wasn't caught -# made TestClass private and used __test__ to get at it -# many doc updates -# speed _SpoofOut for long expected outputs -# 0,9,2 09-Mar-1999 -# throw out comments from examples, enabling use of the much simpler -# exec compile(... "single") ... -# for simulating the runtime; that barfs on comment-only lines -# used the traceback module to do a much better job of reporting -# exceptions -# run __doc__ values thru str(), "just in case" -# privateness of names now determined by an overridable "isprivate" -# function -# by default a name now considered to be private iff it begins with -# an underscore but doesn't both begin & end with two of 'em; so -# e.g. Class.__init__ etc are searched now -- as they always -# should have been -# 0,9,3 18-Mar-1999 -# added .flush stub to _SpoofOut (JPython buglet diagnosed by -# Hugh Emberson) -# repaired ridiculous docs about backslashes in examples -# minor internal changes -# changed source to Unix line-end conventions -# moved __test__ logic into new Tester.run__test__ method -# 0,9,4 27-Mar-1999 -# report item name and line # in failing examples -# 0,9,5 29-Jun-1999 -# allow straightforward exceptions in examples - thanks to Mark Hammond! -# 0,9,6 16-Jan-2001 -# fiddling for changes in Python 2.0: some of the embedded docstring -# examples no longer worked *exactly* as advertised, due to minor -# language changes, and running doctest on itself pointed that out. -# Hard to think of a better example of why this is useful . - -__version__ = 0, 9, 6 - -import types -_FunctionType = types.FunctionType -_ClassType = types.ClassType -_ModuleType = types.ModuleType -_StringType = types.StringType -del types - -import string -_string_find = string.find -_string_join = string.join -_string_split = string.split -_string_rindex = string.rindex -del string - -import re -PS1 = ">>>" -PS2 = "..." -_isPS1 = re.compile(r"(\s*)" + re.escape(PS1)).match -_isPS2 = re.compile(r"(\s*)" + re.escape(PS2)).match -_isEmpty = re.compile(r"\s*$").match -_isComment = re.compile(r"\s*#").match -del re - -__all__ = [] - -# Extract interactive examples from a string. Return a list of triples, -# (source, outcome, lineno). "source" is the source code, and ends -# with a newline iff the source spans more than one line. "outcome" is -# the expected output if any, else an empty string. When not empty, -# outcome always ends with a newline. "lineno" is the line number, -# 0-based wrt the start of the string, of the first source line. - -def _extract_examples(s): - isPS1, isPS2 = _isPS1, _isPS2 - isEmpty, isComment = _isEmpty, _isComment - examples = [] - lines = _string_split(s, "\n") - i, n = 0, len(lines) - while i < n: - line = lines[i] - i = i + 1 - m = isPS1(line) - if m is None: - continue - j = m.end(0) # beyond the prompt - if isEmpty(line, j) or isComment(line, j): - # a bare prompt or comment -- not interesting - continue - lineno = i - 1 - if line[j] != " ": - raise ValueError("line " + `lineno` + " of docstring lacks " - "blank after " + PS1 + ": " + line) - j = j + 1 - blanks = m.group(1) - nblanks = len(blanks) - # suck up this and following PS2 lines - source = [] - while 1: - source.append(line[j:]) - line = lines[i] - m = isPS2(line) - if m: - if m.group(1) != blanks: - raise ValueError("inconsistent leading whitespace " - "in line " + `i` + " of docstring: " + line) - i = i + 1 - else: - break - if len(source) == 1: - source = source[0] - else: - # get rid of useless null line from trailing empty "..." - if source[-1] == "": - del source[-1] - source = _string_join(source, "\n") + "\n" - # suck up response - if isPS1(line) or isEmpty(line): - expect = "" - else: - expect = [] - while 1: - if line[:nblanks] != blanks: - raise ValueError("inconsistent leading whitespace " - "in line " + `i` + " of docstring: " + line) - expect.append(line[nblanks:]) - i = i + 1 - line = lines[i] - if isPS1(line) or isEmpty(line): - break - expect = _string_join(expect, "\n") + "\n" - examples.append( (source, expect, lineno) ) - return examples - -# Capture stdout when running examples. - -class _SpoofOut: - def __init__(self): - self.clear() - def write(self, s): - self.buf.append(s) - def get(self): - return _string_join(self.buf, "") - def clear(self): - self.buf = [] - def flush(self): - # JPython calls flush - pass - -# Display some tag-and-msg pairs nicely, keeping the tag and its msg -# on the same line when that makes sense. - -def _tag_out(printer, *tag_msg_pairs): - for tag, msg in tag_msg_pairs: - printer(tag + ":") - msg_has_nl = msg[-1:] == "\n" - msg_has_two_nl = msg_has_nl and \ - _string_find(msg, "\n") < len(msg) - 1 - if len(tag) + len(msg) < 76 and not msg_has_two_nl: - printer(" ") - else: - printer("\n") - printer(msg) - if not msg_has_nl: - printer("\n") - -# Run list of examples, in context globs. "out" can be used to display -# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut -# that captures the examples' std output. Return (#failures, #tries). - -def _run_examples_inner(out, fakeout, examples, globs, verbose, name): - import sys, traceback - OK, BOOM, FAIL = range(3) - NADA = "nothing" - stderr = _SpoofOut() - failures = 0 - for source, want, lineno in examples: - if verbose: - _tag_out(out, ("Trying", source), - ("Expecting", want or NADA)) - fakeout.clear() - try: - exec compile(source, "", "single") in globs - got = fakeout.get() - state = OK - except: - # See whether the exception was expected. - if _string_find(want, "Traceback (innermost last):\n") == 0 or\ - _string_find(want, "Traceback (most recent call last):\n") == 0: - # Only compare exception type and value - the rest of - # the traceback isn't necessary. - want = _string_split(want, '\n')[-2] + '\n' - exc_type, exc_val, exc_tb = sys.exc_info() - got = traceback.format_exception_only(exc_type, exc_val)[0] - state = OK - else: - # unexpected exception - stderr.clear() - traceback.print_exc(file=stderr) - state = BOOM - - if state == OK: - if got == want: - if verbose: - out("ok\n") - continue - state = FAIL - - assert state in (FAIL, BOOM) - failures = failures + 1 - out("*" * 65 + "\n") - _tag_out(out, ("Failure in example", source)) - out("from line #" + `lineno` + " of " + name + "\n") - if state == FAIL: - _tag_out(out, ("Expected", want or NADA), ("Got", got)) - else: - assert state == BOOM - _tag_out(out, ("Exception raised", stderr.get())) - - return failures, len(examples) - -# Run list of examples, in context globs. Return (#failures, #tries). - -def _run_examples(examples, globs, verbose, name): - import sys - saveout = sys.stdout - try: - sys.stdout = fakeout = _SpoofOut() - x = _run_examples_inner(saveout.write, fakeout, examples, - globs, verbose, name) - finally: - sys.stdout = saveout - return x - -def run_docstring_examples(f, globs, verbose=0, name="NoName"): - """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. - - Use dict globs as the globals for execution. - Return (#failures, #tries). - - If optional arg verbose is true, print stuff even if there are no - failures. - Use string name in failure msgs. - """ - - try: - doc = f.__doc__ - if not doc: - # docstring empty or None - return 0, 0 - # just in case CT invents a doc object that has to be forced - # to look like a string <0.9 wink> - doc = str(doc) - except: - return 0, 0 - - e = _extract_examples(doc) - if not e: - return 0, 0 - return _run_examples(e, globs, verbose, name) - -def is_private(prefix, base): - """prefix, base -> true iff name prefix + "." + base is "private". - - Prefix may be an empty string, and base does not contain a period. - Prefix is ignored (although functions you write conforming to this - protocol may make use of it). - Return true iff base begins with an (at least one) underscore, but - does not both begin and end with (at least) two underscores. - - >>> is_private("a.b", "my_func") - 0 - >>> is_private("____", "_my_func") - 1 - >>> is_private("someclass", "__init__") - 0 - >>> is_private("sometypo", "__init_") - 1 - >>> is_private("x.y.z", "_") - 1 - >>> is_private("_x.y.z", "__") - 0 - >>> is_private("", "") # senseless but consistent - 0 - """ - - return base[:1] == "_" and not base[:2] == "__" == base[-2:] - -class Tester: - """Class Tester -- runs docstring examples and accumulates stats. - -In normal use, function doctest.testmod() hides all this from you, -so use that if you can. Create your own instances of Tester to do -fancier things. - -Methods: - runstring(s, name) - Search string s for examples to run; use name for logging. - Return (#failures, #tries). - - rundoc(object, name=None) - Search object.__doc__ for examples to run; use name (or - object.__name__) for logging. Return (#failures, #tries). - - rundict(d, name) - Search for examples in docstrings in all of d.values(); use name - for logging. Return (#failures, #tries). - - run__test__(d, name) - Treat dict d like module.__test__. Return (#failures, #tries). - - summarize(verbose=None) - Display summary of testing results, to stdout. Return - (#failures, #tries). - - merge(other) - Merge in the test results from Tester instance "other". - ->>> from doctest import Tester ->>> t = Tester(globs={'x': 42}, verbose=0) ->>> t.runstring(r''' -... >>> x = x * 2 -... >>> print x -... 42 -... ''', 'XYZ') -***************************************************************** -Failure in example: print x -from line #2 of XYZ -Expected: 42 -Got: 84 -(1, 2) ->>> t.runstring(">>> x = x * 2\\n>>> print x\\n84\\n", 'example2') -(0, 2) ->>> t.summarize() -1 items had failures: - 1 of 2 in XYZ -***Test Failed*** 1 failures. -(1, 4) ->>> t.summarize(verbose=1) -1 items passed all tests: - 2 tests in example2 -1 items had failures: - 1 of 2 in XYZ -4 tests in 2 items. -3 passed and 1 failed. -***Test Failed*** 1 failures. -(1, 4) ->>> -""" - - def __init__(self, mod=None, globs=None, verbose=None, - isprivate=None): - """mod=None, globs=None, verbose=None, isprivate=None - -See doctest.__doc__ for an overview. - -Optional keyword arg "mod" is a module, whose globals are used for -executing examples. If not specified, globs must be specified. - -Optional keyword arg "globs" gives a dict to be used as the globals -when executing examples; if not specified, use the globals from -module mod. - -In either case, a copy of the dict is used for each docstring -examined. - -Optional keyword arg "verbose" prints lots of stuff if true, only -failures if false; by default, it's true iff "-v" is in sys.argv. - -Optional keyword arg "isprivate" specifies a function used to determine -whether a name is private. The default function is doctest.is_private; -see its docs for details. -""" - - if mod is None and globs is None: - raise TypeError("Tester.__init__: must specify mod or globs") - if mod is not None and type(mod) is not _ModuleType: - raise TypeError("Tester.__init__: mod must be a module; " + - `mod`) - if globs is None: - globs = mod.__dict__ - self.globs = globs - - if verbose is None: - import sys - verbose = "-v" in sys.argv - self.verbose = verbose - - if isprivate is None: - isprivate = is_private - self.isprivate = isprivate - - self.name2ft = {} # map name to (#failures, #trials) pair - - def runstring(self, s, name): - """ - s, name -> search string s for examples to run, logging as name. - - Use string name as the key for logging the outcome. - Return (#failures, #examples). - - >>> t = Tester(globs={}, verbose=1) - >>> test = r''' - ... # just an example - ... >>> x = 1 + 2 - ... >>> x - ... 3 - ... ''' - >>> t.runstring(test, "Example") - Running string Example - Trying: x = 1 + 2 - Expecting: nothing - ok - Trying: x - Expecting: 3 - ok - 0 of 2 examples failed in string Example - (0, 2) - """ - - if self.verbose: - print "Running string", name - f = t = 0 - e = _extract_examples(s) - if e: - f, t = _run_examples(e, self.globs.copy(), self.verbose, name) - if self.verbose: - print f, "of", t, "examples failed in string", name - self.__record_outcome(name, f, t) - return f, t - - def rundoc(self, object, name=None): - """ - object, name=None -> search object.__doc__ for examples to run. - - Use optional string name as the key for logging the outcome; - by default use object.__name__. - Return (#failures, #examples). - If object is a class object, search recursively for method - docstrings too. - object.__doc__ is examined regardless of name, but if object is - a class, whether private names reached from object are searched - depends on the constructor's "isprivate" argument. - - >>> t = Tester(globs={}, verbose=0) - >>> def _f(): - ... '''Trivial docstring example. - ... >>> assert 2 == 2 - ... ''' - ... return 32 - ... - >>> t.rundoc(_f) # expect 0 failures in 1 example - (0, 1) - """ - - if name is None: - try: - name = object.__name__ - except AttributeError: - raise ValueError("Tester.rundoc: name must be given " - "when object.__name__ doesn't exist; " + `object`) - if self.verbose: - print "Running", name + ".__doc__" - f, t = run_docstring_examples(object, self.globs.copy(), - self.verbose, name) - if self.verbose: - print f, "of", t, "examples failed in", name + ".__doc__" - self.__record_outcome(name, f, t) - if type(object) is _ClassType: - f2, t2 = self.rundict(object.__dict__, name) - f = f + f2 - t = t + t2 - return f, t - - def rundict(self, d, name): - """ - d. name -> search for docstring examples in all of d.values(). - - For k, v in d.items() such that v is a function or class, - do self.rundoc(v, name + "." + k). Whether this includes - objects with private names depends on the constructor's - "isprivate" argument. - Return aggregate (#failures, #examples). - - >>> def _f(): - ... '''>>> assert 1 == 1 - ... ''' - >>> def g(): - ... '''>>> assert 2 != 1 - ... ''' - >>> d = {"_f": _f, "g": g} - >>> t = Tester(globs={}, verbose=0) - >>> t.rundict(d, "rundict_test") # _f is skipped - (0, 1) - >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) - >>> t.rundict(d, "rundict_test_pvt") # both are searched - (0, 2) - """ - - if not hasattr(d, "items"): - raise TypeError("Tester.rundict: d must support .items(); " + - `d`) - f = t = 0 - for thisname, value in d.items(): - if type(value) in (_FunctionType, _ClassType): - f2, t2 = self.__runone(value, name + "." + thisname) - f = f + f2 - t = t + t2 - return f, t - - def run__test__(self, d, name): - """d, name -> Treat dict d like module.__test__. - - Return (#failures, #tries). - See testmod.__doc__ for details. - """ - - failures = tries = 0 - prefix = name + "." - savepvt = self.isprivate - try: - self.isprivate = lambda *args: 0 - for k, v in d.items(): - thisname = prefix + k - if type(v) is _StringType: - f, t = self.runstring(v, thisname) - elif type(v) in (_FunctionType, _ClassType): - f, t = self.rundoc(v, thisname) - else: - raise TypeError("Tester.run__test__: values in " - "dict must be strings, functions " - "or classes; " + `v`) - failures = failures + f - tries = tries + t - finally: - self.isprivate = savepvt - return failures, tries - - def summarize(self, verbose=None): - """ - verbose=None -> summarize results, return (#failures, #tests). - - Print summary of test results to stdout. - Optional arg 'verbose' controls how wordy this is. By - default, use the verbose setting established by the - constructor. - """ - - if verbose is None: - verbose = self.verbose - notests = [] - passed = [] - failed = [] - totalt = totalf = 0 - for x in self.name2ft.items(): - name, (f, t) = x - assert f <= t - totalt = totalt + t - totalf = totalf + f - if t == 0: - notests.append(name) - elif f == 0: - passed.append( (name, t) ) - else: - failed.append(x) - if verbose: - if notests: - print len(notests), "items had no tests:" - notests.sort() - for thing in notests: - print " ", thing - if passed: - print len(passed), "items passed all tests:" - passed.sort() - for thing, count in passed: - print " %3d tests in %s" % (count, thing) - if failed: - print len(failed), "items had failures:" - failed.sort() - for thing, (f, t) in failed: - print " %3d of %3d in %s" % (f, t, thing) - if verbose: - print totalt, "tests in", len(self.name2ft), "items." - print totalt - totalf, "passed and", totalf, "failed." - if totalf: - print "***Test Failed***", totalf, "failures." - elif verbose: - print "Test passed." - return totalf, totalt - - def merge(self, other): - """ - other -> merge in test results from the other Tester instance. - - If self and other both have a test result for something - with the same name, the (#failures, #tests) results are - summed, and a warning is printed to stdout. - - >>> from doctest import Tester - >>> t1 = Tester(globs={}, verbose=0) - >>> t1.runstring(''' - ... >>> x = 12 - ... >>> print x - ... 12 - ... ''', "t1example") - (0, 2) - >>> - >>> t2 = Tester(globs={}, verbose=0) - >>> t2.runstring(''' - ... >>> x = 13 - ... >>> print x - ... 13 - ... ''', "t2example") - (0, 2) - >>> common = ">>> assert 1 + 2 == 3\\n" - >>> t1.runstring(common, "common") - (0, 1) - >>> t2.runstring(common, "common") - (0, 1) - >>> t1.merge(t2) - *** Tester.merge: 'common' in both testers; summing outcomes. - >>> t1.summarize(1) - 3 items passed all tests: - 2 tests in common - 2 tests in t1example - 2 tests in t2example - 6 tests in 3 items. - 6 passed and 0 failed. - Test passed. - (0, 6) - >>> - """ - - d = self.name2ft - for name, (f, t) in other.name2ft.items(): - if d.has_key(name): - print "*** Tester.merge: '" + name + "' in both" \ - " testers; summing outcomes." - f2, t2 = d[name] - f = f + f2 - t = t + t2 - d[name] = f, t - - def __record_outcome(self, name, f, t): - if self.name2ft.has_key(name): - print "*** Warning: '" + name + "' was tested before;", \ - "summing outcomes." - f2, t2 = self.name2ft[name] - f = f + f2 - t = t + t2 - self.name2ft[name] = f, t - - def __runone(self, target, name): - if "." in name: - i = _string_rindex(name, ".") - prefix, base = name[:i], name[i+1:] - else: - prefix, base = "", base - if self.isprivate(prefix, base): - return 0, 0 - return self.rundoc(target, name) - -master = None - -def testmod(m, name=None, globs=None, verbose=None, isprivate=None, - report=1): - """m, name=None, globs=None, verbose=None, isprivate=None, report=1 - - Test examples in docstrings in functions and classes reachable from - module m, starting with m.__doc__. Private names are skipped. - - Also test examples reachable from dict m.__test__ if it exists and is - not None. m.__dict__ maps names to functions, classes and strings; - function and class docstrings are tested even if the name is private; - strings are tested directly, as if they were docstrings. - - Return (#failures, #tests). - - See doctest.__doc__ for an overview. - - Optional keyword arg "name" gives the name of the module; by default - use m.__name__. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use m.__dict__. A copy of this - dict is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "isprivate" specifies a function used to - determine whether a name is private. The default function is - doctest.is_private; see its docs for details. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Advanced tomfoolery: testmod runs methods of a local instance of - class doctest.Tester, then merges the results into (or creates) - global Tester instance doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - - global master - - if type(m) is not _ModuleType: - raise TypeError("testmod: module required; " + `m`) - if name is None: - name = m.__name__ - tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) - failures, tries = tester.rundoc(m, name) - f, t = tester.rundict(m.__dict__, name) - failures = failures + f - tries = tries + t - if hasattr(m, "__test__"): - testdict = m.__test__ - if testdict: - if not hasattr(testdict, "items"): - raise TypeError("testmod: module.__test__ must support " - ".items(); " + `testdict`) - f, t = tester.run__test__(testdict, name + ".__test__") - failures = failures + f - tries = tries + t - if report: - tester.summarize() - if master is None: - master = tester - else: - master.merge(tester) - return failures, tries - -class _TestClass: - """ - A pointless class, for sanity-checking of docstring testing. - - Methods: - square() - get() - - >>> _TestClass(13).get() + _TestClass(-12).get() - 1 - >>> hex(_TestClass(13).square().get()) - '0xa9' - """ - - def __init__(self, val): - """val -> _TestClass object with associated value val. - - >>> t = _TestClass(123) - >>> print t.get() - 123 - """ - - self.val = val - - def square(self): - """square() -> square TestClass's associated value - - >>> _TestClass(13).square().get() - 169 - """ - - self.val = self.val ** 2 - return self - - def get(self): - """get() -> return TestClass's associated value. - - >>> x = _TestClass(-42) - >>> print x.get() - -42 - """ - - return self.val - -__test__ = {"_TestClass": _TestClass, - "string": r""" - Example of a string object, searched as-is. - >>> x = 1; y = 2 - >>> x + y, x * y - (3, 2) - """ - } - -def _test(): - import doctest - return doctest.testmod(doctest) - -if __name__ == "__main__": - _test() diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c deleted file mode 100755 index 2ae13ad7281..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/encode.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * The Python Imaging Library. - * - * standard encoder interfaces for the Imaging library - * - * History: - * 1996-04-19 fl Based on decoders.c - * 1996-05-12 fl Compile cleanly as C++ - * 1996-12-30 fl Plugged potential memory leak for tiled images - * 1997-01-03 fl Added GIF encoder - * 1997-01-05 fl Plugged encoder buffer leaks - * 1997-01-11 fl Added encode_to_file method - * 1998-03-09 fl Added mode/rawmode argument to encoders - * 1998-07-09 fl Added interlace argument to GIF encoder - * 1999-02-07 fl Added PCX encoder - * - * Copyright (c) 1997-2001 by Secret Labs AB - * Copyright (c) 1996-1997 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - -/* FIXME: make these pluggable! */ - -#include "Python.h" - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#include "Imaging.h" -#include "Gif.h" - -#ifdef HAVE_UNISTD_H -#include /* write */ -#endif - -/* -------------------------------------------------------------------- */ -/* Common */ -/* -------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - int (*encode)(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); - struct ImagingCodecStateInstance state; - Imaging im; - PyObject* lock; -} ImagingEncoderObject; - -staticforward PyTypeObject ImagingEncoderType; - -static ImagingEncoderObject* -PyImaging_EncoderNew(int contextsize) -{ - ImagingEncoderObject *encoder; - void *context; - - ImagingEncoderType.ob_type = &PyType_Type; - - encoder = PyObject_New(ImagingEncoderObject, &ImagingEncoderType); - if (encoder == NULL) - return NULL; - - /* Clear the encoder state */ - memset(&encoder->state, 0, sizeof(encoder->state)); - - /* Allocate encoder context */ - if (contextsize > 0) { - context = (void*) calloc(1, contextsize); - if (!context) { - Py_DECREF(encoder); - (void) PyErr_NoMemory(); - return NULL; - } - } else - context = 0; - - /* Initialize encoder context */ - encoder->state.context = context; - - /* Target image */ - encoder->lock = NULL; - encoder->im = NULL; - - return encoder; -} - -static void -_dealloc(ImagingEncoderObject* encoder) -{ - free(encoder->state.buffer); - free(encoder->state.context); - Py_XDECREF(encoder->lock); - PyObject_Del(encoder); -} - -static PyObject* -_encode(ImagingEncoderObject* encoder, PyObject* args) -{ - PyObject* buf; - PyObject* result; - int status; - - /* Encode to a Python string (allocated by this method) */ - - int bufsize = 16384; - - if (!PyArg_ParseTuple(args, "|i", &bufsize)) - return NULL; - - buf = PyString_FromStringAndSize(NULL, bufsize); - if (!buf) - return NULL; - - status = encoder->encode(encoder->im, &encoder->state, - (UINT8*) PyString_AsString(buf), bufsize); - - /* adjust string length to avoid slicing in encoder */ - if (_PyString_Resize(&buf, (status > 0) ? status : 0) < 0) - return NULL; - - result = Py_BuildValue("iiO", status, encoder->state.errcode, buf); - - Py_DECREF(buf); /* must release buffer!!! */ - - return result; -} - -static PyObject* -_encode_to_file(ImagingEncoderObject* encoder, PyObject* args) -{ - UINT8* buf; - int status; - ImagingSectionCookie cookie; - - /* Encode to a file handle */ - - int fh; - int bufsize = 16384; - - if (!PyArg_ParseTuple(args, "i|i", &fh, &bufsize)) - return NULL; - - /* Allocate an encoder buffer */ - buf = (UINT8*) malloc(bufsize); - if (!buf) - return PyErr_NoMemory(); - - ImagingSectionEnter(&cookie); - - do { - - /* This replaces the inner loop in the ImageFile _save - function. */ - - status = encoder->encode(encoder->im, &encoder->state, buf, bufsize); - - if (status > 0) - if (write(fh, buf, status) < 0) { - ImagingSectionLeave(&cookie); - free(buf); - return PyErr_SetFromErrno(PyExc_IOError); - } - - } while (encoder->state.errcode == 0); - - ImagingSectionLeave(&cookie); - - free(buf); - - return Py_BuildValue("i", encoder->state.errcode); -} - -extern Imaging PyImaging_AsImaging(PyObject *op); - -static PyObject* -_setimage(ImagingEncoderObject* encoder, PyObject* args) -{ - PyObject* op; - Imaging im; - ImagingCodecState state; - int x0, y0, x1, y1; - - /* Define where image data should be stored */ - - x0 = y0 = x1 = y1 = 0; - - /* FIXME: should publish the ImagingType descriptor */ - if (!PyArg_ParseTuple(args, "O|(iiii)", &op, &x0, &y0, &x1, &y1)) - return NULL; - im = PyImaging_AsImaging(op); - if (!im) - return NULL; - - encoder->im = im; - - state = &encoder->state; - - if (x0 == 0 && x1 == 0) { - state->xsize = im->xsize; - state->ysize = im->ysize; - } else { - state->xoff = x0; - state->yoff = y0; - state->xsize = x1 - x0; - state->ysize = y1 - y0; - } - - if (state->xsize <= 0 || - state->xsize + state->xoff > im->xsize || - state->ysize <= 0 || - state->ysize + state->yoff > im->ysize) { - PyErr_SetString(PyExc_SystemError, "tile cannot extend outside image"); - return NULL; - } - - /* Allocate memory buffer (if bits field is set) */ - if (state->bits > 0) { - state->bytes = (state->bits * state->xsize+7)/8; - state->buffer = (UINT8*) malloc(state->bytes); - if (!state->buffer) - return PyErr_NoMemory(); - } - - /* Keep a reference to the image object, to make sure it doesn't - go away before we do */ - Py_INCREF(op); - Py_XDECREF(encoder->lock); - encoder->lock = op; - - Py_INCREF(Py_None); - return Py_None; -} - -static struct PyMethodDef methods[] = { - {"encode", (PyCFunction)_encode, 1}, - {"encode_to_file", (PyCFunction)_encode_to_file, 1}, - {"setimage", (PyCFunction)_setimage, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -_getattr(ImagingEncoderObject* self, char* name) -{ - return Py_FindMethod(methods, (PyObject*) self, name); -} - -statichere PyTypeObject ImagingEncoderType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingEncoder", /*tp_name*/ - sizeof(ImagingEncoderObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_hash*/ -}; - -/* -------------------------------------------------------------------- */ - -int -get_packer(ImagingEncoderObject* encoder, const char* mode, - const char* rawmode) -{ - int bits; - ImagingShuffler pack; - - pack = ImagingFindPacker(mode, rawmode, &bits); - if (!pack) { - Py_DECREF(encoder); - PyErr_SetString(PyExc_SystemError, "unknown raw mode"); - return -1; - } - - encoder->state.shuffle = pack; - encoder->state.bits = bits; - - return 0; -} - - -/* -------------------------------------------------------------------- */ -/* EPS */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_EpsEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - encoder = PyImaging_EncoderNew(0); - if (encoder == NULL) - return NULL; - - encoder->encode = ImagingEpsEncode; - - return (PyObject*) encoder; -} - - -/* -------------------------------------------------------------------- */ -/* GIF */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_GifEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - char *mode; - char *rawmode; - int bits = 8; - int interlace = 0; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &bits, &interlace)) - return NULL; - - encoder = PyImaging_EncoderNew(sizeof(GIFENCODERSTATE)); - if (encoder == NULL) - return NULL; - - if (get_packer(encoder, mode, rawmode) < 0) - return NULL; - - encoder->encode = ImagingGifEncode; - - ((GIFENCODERSTATE*)encoder->state.context)->bits = bits; - ((GIFENCODERSTATE*)encoder->state.context)->interlace = interlace; - - return (PyObject*) encoder; -} - - -/* -------------------------------------------------------------------- */ -/* PCX */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_PcxEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - char *mode; - char *rawmode; - int bits = 8; - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &bits)) - return NULL; - - encoder = PyImaging_EncoderNew(0); - if (encoder == NULL) - return NULL; - - if (get_packer(encoder, mode, rawmode) < 0) - return NULL; - - encoder->encode = ImagingPcxEncode; - - return (PyObject*) encoder; -} - - -/* -------------------------------------------------------------------- */ -/* RAW */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_RawEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - char *mode; - char *rawmode; - int stride = 0; - int ystep = 1; - - if (!PyArg_ParseTuple(args, "ss|ii", &mode, &rawmode, &stride, &ystep)) - return NULL; - - encoder = PyImaging_EncoderNew(0); - if (encoder == NULL) - return NULL; - - if (get_packer(encoder, mode, rawmode) < 0) - return NULL; - - encoder->encode = ImagingRawEncode; - - encoder->state.ystep = ystep; - encoder->state.count = stride; - - return (PyObject*) encoder; -} - - -/* -------------------------------------------------------------------- */ -/* XBM */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyImaging_XbmEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - encoder = PyImaging_EncoderNew(0); - if (encoder == NULL) - return NULL; - - if (get_packer(encoder, "1", "1;R") < 0) - return NULL; - - encoder->encode = ImagingXbmEncode; - - return (PyObject*) encoder; -} - - -/* -------------------------------------------------------------------- */ -/* ZIP */ -/* -------------------------------------------------------------------- */ - -#ifdef HAVE_LIBZ - -#include "Zip.h" - -PyObject* -PyImaging_ZipEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - char* mode; - char* rawmode; - int optimize = 0; - char* dictionary = NULL; - int dictionary_size = 0; - if (!PyArg_ParseTuple(args, "ss|is#", &mode, &rawmode, &optimize, - &dictionary, &dictionary_size)) - return NULL; - - encoder = PyImaging_EncoderNew(sizeof(ZIPSTATE)); - if (encoder == NULL) - return NULL; - - if (get_packer(encoder, mode, rawmode) < 0) - return NULL; - - encoder->encode = ImagingZipEncode; - - if (rawmode[0] == 'P') - /* disable filtering */ - ((ZIPSTATE*)encoder->state.context)->mode = ZIP_PNG_PALETTE; - - ((ZIPSTATE*)encoder->state.context)->optimize = optimize; - ((ZIPSTATE*)encoder->state.context)->dictionary = dictionary; - ((ZIPSTATE*)encoder->state.context)->dictionary_size = dictionary_size; - - return (PyObject*) encoder; -} -#endif - - -/* -------------------------------------------------------------------- */ -/* JPEG */ -/* -------------------------------------------------------------------- */ - -#ifdef HAVE_LIBJPEG - -/* We better define this encoder last in this file, so the following - undef's won't mess things up for the Imaging library proper. */ - -#undef HAVE_PROTOTYPES -#undef HAVE_STDDEF_H -#undef HAVE_STDLIB_H -#undef UINT8 -#undef UINT16 -#undef UINT32 -#undef INT8 -#undef INT16 -#undef INT32 - -#include "Jpeg.h" - -PyObject* -PyImaging_JpegEncoderNew(PyObject* self, PyObject* args) -{ - ImagingEncoderObject* encoder; - - char *mode; - char *rawmode; - int quality = 0; - int progressive = 0; - int smooth = 0; - int optimize = 0; - int streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */ - int xdpi = 0, ydpi = 0; - int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */ - char* extra = NULL; int extra_size; - if (!PyArg_ParseTuple(args, "ss|iiiiiiiis#", &mode, &rawmode, &quality, - &progressive, &smooth, &optimize, &streamtype, - &xdpi, &ydpi, &subsampling, &extra, &extra_size)) - return NULL; - - encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE)); - if (encoder == NULL) - return NULL; - - if (get_packer(encoder, mode, rawmode) < 0) - return NULL; - - if (extra && extra_size > 0) { - char* p = malloc(extra_size); - if (!p) - return PyErr_NoMemory(); - memcpy(p, extra, extra_size); - extra = p; - } else - extra = NULL; - - encoder->encode = ImagingJpegEncode; - - ((JPEGENCODERSTATE*)encoder->state.context)->quality = quality; - ((JPEGENCODERSTATE*)encoder->state.context)->subsampling = subsampling; - ((JPEGENCODERSTATE*)encoder->state.context)->progressive = progressive; - ((JPEGENCODERSTATE*)encoder->state.context)->smooth = smooth; - ((JPEGENCODERSTATE*)encoder->state.context)->optimize = optimize; - ((JPEGENCODERSTATE*)encoder->state.context)->streamtype = streamtype; - ((JPEGENCODERSTATE*)encoder->state.context)->xdpi = xdpi; - ((JPEGENCODERSTATE*)encoder->state.context)->ydpi = ydpi; - ((JPEGENCODERSTATE*)encoder->state.context)->extra = extra; - ((JPEGENCODERSTATE*)encoder->state.context)->extra_size = extra_size; - - return (PyObject*) encoder; -} - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c deleted file mode 100755 index 5ebc9b6f36d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Access.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * imaging access objects - * - * Copyright (c) Fredrik Lundh 2009. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -/* use Tests/make_hash.py to calculate these values */ -#define ACCESS_TABLE_SIZE 21 -#define ACCESS_TABLE_HASH 30197 - -static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE]; - -static inline UINT32 -hash(const char* mode) -{ - UINT32 i = ACCESS_TABLE_HASH; - while (*mode) - i = ((i<<5) + i) ^ (UINT8) *mode++; - return i % ACCESS_TABLE_SIZE; -} - -static ImagingAccess -add_item(const char* mode) -{ - UINT32 i = hash(mode); - /* printf("hash %s => %d\n", mode, i); */ - if (access_table[i].mode) { - fprintf(stderr, "AccessInit: hash collision: %d for both %s and %s\n", - i, mode, access_table[i].mode); - exit(1); - } - access_table[i].mode = mode; - return &access_table[i]; -} - -/* fetch pointer to pixel line */ - -static void* -line_8(Imaging im, int x, int y) -{ - return &im->image8[y][x]; -} - -static void* -line_16(Imaging im, int x, int y) -{ - return &im->image8[y][x+x]; -} - -static void* -line_32(Imaging im, int x, int y) -{ - return &im->image32[y][x]; -} - -/* fetch individual pixel */ - -static void -get_pixel(Imaging im, int x, int y, void* color) -{ - char* out = color; - - /* generic pixel access*/ - - if (im->image8) { - out[0] = im->image8[y][x]; - } else { - UINT8* p = (UINT8*) &im->image32[y][x]; - if (im->type == IMAGING_TYPE_UINT8 && im->bands == 2) { - out[0] = p[0]; - out[1] = p[3]; - return; - } - memcpy(out, p, im->pixelsize); - } -} - -static void -get_pixel_8(Imaging im, int x, int y, void* color) -{ - char* out = color; - out[0] = im->image8[y][x]; -} - -static void -get_pixel_16L(Imaging im, int x, int y, void* color) -{ - UINT8* in = (UINT8*) &im->image[y][x+x]; - INT16* out = color; -#ifdef WORDS_BIGENDIAN - out[0] = in[0] + (in[1]<<8); -#else - out[0] = *(INT16*) in; -#endif -} - -static void -get_pixel_16B(Imaging im, int x, int y, void* color) -{ - UINT8* in = (UINT8*) &im->image[y][x+x]; - INT16* out = color; -#ifdef WORDS_BIGENDIAN - out[0] = *(INT16*) in; -#else - out[0] = in[1] + (in[0]<<8); -#endif -} - -static void -get_pixel_32(Imaging im, int x, int y, void* color) -{ - INT32* out = color; - out[0] = im->image32[y][x]; -} - -static void -get_pixel_32L(Imaging im, int x, int y, void* color) -{ - UINT8* in = (UINT8*) &im->image[y][x*4]; - INT32* out = color; -#ifdef WORDS_BIGENDIAN - out[0] = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24); -#else - out[0] = *(INT32*) in; -#endif -} - -static void -get_pixel_32B(Imaging im, int x, int y, void* color) -{ - UINT8* in = (UINT8*) &im->image[y][x*4]; - INT32* out = color; -#ifdef WORDS_BIGENDIAN - out[0] = *(INT32*) in; -#else - out[0] = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24); -#endif -} - -/* store individual pixel */ - -static void -put_pixel(Imaging im, int x, int y, const void* color) -{ - if (im->image8) - im->image8[y][x] = *((UINT8*) color); - else - im->image32[y][x] = *((INT32*) color); -} - -static void -put_pixel_8(Imaging im, int x, int y, const void* color) -{ - im->image8[y][x] = *((UINT8*) color); -} - -static void -put_pixel_16L(Imaging im, int x, int y, const void* color) -{ - const char* in = color; - UINT8* out = (UINT8*) &im->image8[y][x+x]; - out[0] = in[0]; - out[1] = in[1]; -} - -static void -put_pixel_16B(Imaging im, int x, int y, const void* color) -{ - const char* in = color; - UINT8* out = (UINT8*) &im->image8[y][x+x]; - out[0] = in[1]; - out[1] = in[0]; -} - -static void -put_pixel_32L(Imaging im, int x, int y, const void* color) -{ - const char* in = color; - UINT8* out = (UINT8*) &im->image8[y][x*4]; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static void -put_pixel_32B(Imaging im, int x, int y, const void* color) -{ - const char* in = color; - UINT8* out = (UINT8*) &im->image8[y][x*4]; - out[0] = in[3]; - out[1] = in[2]; - out[2] = in[1]; - out[3] = in[0]; -} - -static void -put_pixel_32(Imaging im, int x, int y, const void* color) -{ - im->image32[y][x] = *((INT32*) color); -} - -void -ImagingAccessInit() -{ -#define ADD(mode_, line_, get_pixel_, put_pixel_) \ - { ImagingAccess access = add_item(mode_); \ - access->line = line_; \ - access->get_pixel = get_pixel_; \ - access->put_pixel = put_pixel_; \ - } - - /* populate access table */ - ADD("1", line_8, get_pixel_8, put_pixel_8); - ADD("L", line_8, get_pixel_8, put_pixel_8); - ADD("LA", line_32, get_pixel, put_pixel); - ADD("I", line_32, get_pixel_32, put_pixel_32); - ADD("I;16", line_16, get_pixel_16L, put_pixel_16L); - ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L); - ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B); - ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L); - ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B); - ADD("F", line_32, get_pixel_32, put_pixel_32); - ADD("P", line_8, get_pixel_8, put_pixel_8); - ADD("PA", line_32, get_pixel, put_pixel); - ADD("RGB", line_32, get_pixel_32, put_pixel_32); - ADD("RGBA", line_32, get_pixel_32, put_pixel_32); - ADD("RGBa", line_32, get_pixel_32, put_pixel_32); - ADD("RGBX", line_32, get_pixel_32, put_pixel_32); - ADD("CMYK", line_32, get_pixel_32, put_pixel_32); - ADD("YCbCr", line_32, get_pixel_32, put_pixel_32); -} - -ImagingAccess -ImagingAccessNew(Imaging im) -{ - ImagingAccess access = &access_table[hash(im->mode)]; - if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0) - return NULL; - return access; -} - -void -_ImagingAccessDelete(Imaging im, ImagingAccess access) -{ - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c deleted file mode 100755 index 53dfa352251..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Antialias.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * pilopen antialiasing support - * - * history: - * 2002-03-09 fl Created (for PIL 1.1.3) - * 2002-03-10 fl Added support for mode "F" - * - * Copyright (c) 1997-2002 by Secret Labs AB - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -#include - -/* resampling filters (from antialias.py) */ - -struct filter { - float (*filter)(float x); - float support; -}; - -static inline float sinc_filter(float x) -{ - if (x == 0.0) - return 1.0; - x = x * M_PI; - return sin(x) / x; -} - -static inline float antialias_filter(float x) -{ - /* lanczos (truncated sinc) */ - if (-3.0 <= x && x < 3.0) - return sinc_filter(x) * sinc_filter(x/3); - return 0.0; -} - -static struct filter ANTIALIAS = { antialias_filter, 3.0 }; - -static inline float nearest_filter(float x) -{ - if (-0.5 <= x && x < 0.5) - return 1.0; - return 0.0; -} - -static struct filter NEAREST = { nearest_filter, 0.5 }; - -static inline float bilinear_filter(float x) -{ - if (x < 0.0) - x = -x; - if (x < 1.0) - return 1.0-x; - return 0.0; -} - -static struct filter BILINEAR = { bilinear_filter, 1.0 }; - -static inline float bicubic_filter(float x) -{ - /* FIXME: double-check this algorithm */ - /* FIXME: for best results, "a" should be -0.5 to -1.0, but we'll - set it to zero for now, to match the 1.1 magnifying filter */ -#define a 0.0 - if (x < 0.0) - x = -x; - if (x < 1.0) - return (((a + 2.0) * x) - (a + 3.0)) * x*x + 1; - if (x < 2.0) - return (((a * x) - 5*a) * x + 8) * x - 4*a; - return 0.0; -#undef a -} - -static struct filter BICUBIC = { bicubic_filter, 2.0 }; - -Imaging -ImagingStretch(Imaging imOut, Imaging imIn, int filter) -{ - /* FIXME: this is a quick and straightforward translation from a - python prototype. might need some further C-ification... */ - - ImagingSectionCookie cookie; - struct filter *filterp; - float support, scale, filterscale; - float center, ww, ss, ymin, ymax, xmin, xmax; - int xx, yy, x, y, b; - float *k; - - /* check modes */ - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - - /* check filter */ - switch (filter) { - case IMAGING_TRANSFORM_NEAREST: - filterp = &NEAREST; - break; - case IMAGING_TRANSFORM_ANTIALIAS: - filterp = &ANTIALIAS; - break; - case IMAGING_TRANSFORM_BILINEAR: - filterp = &BILINEAR; - break; - case IMAGING_TRANSFORM_BICUBIC: - filterp = &BICUBIC; - break; - default: - return (Imaging) ImagingError_ValueError( - "unsupported resampling filter" - ); - } - - if (imIn->ysize == imOut->ysize) { - /* prepare for horizontal stretch */ - filterscale = scale = (float) imIn->xsize / imOut->xsize; - } else if (imIn->xsize == imOut->xsize) { - /* prepare for vertical stretch */ - filterscale = scale = (float) imIn->ysize / imOut->ysize; - } else - return (Imaging) ImagingError_Mismatch(); - - /* determine support size (length of resampling filter) */ - support = filterp->support; - - if (filterscale < 1.0) { - filterscale = 1.0; - support = 0.5; - } - - support = support * filterscale; - - /* coefficient buffer (with rounding safety margin) */ - k = malloc(((int) support * 2 + 10) * sizeof(float)); - if (!k) - return (Imaging) ImagingError_MemoryError(); - - ImagingSectionEnter(&cookie); - if (imIn->xsize == imOut->xsize) { - /* vertical stretch */ - for (yy = 0; yy < imOut->ysize; yy++) { - center = (yy + 0.5) * scale; - ww = 0.0; - ss = 1.0 / filterscale; - /* calculate filter weights */ - ymin = floor(center - support); - if (ymin < 0.0) - ymin = 0.0; - ymax = ceil(center + support); - if (ymax > (float) imIn->ysize) - ymax = (float) imIn->ysize; - for (y = (int) ymin; y < (int) ymax; y++) { - float w = filterp->filter((y - center + 0.5) * ss) * ss; - k[y - (int) ymin] = w; - ww = ww + w; - } - if (ww == 0.0) - ww = 1.0; - else - ww = 1.0 / ww; - if (imIn->image8) { - /* 8-bit grayscale */ - for (xx = 0; xx < imOut->xsize; xx++) { - ss = 0.0; - for (y = (int) ymin; y < (int) ymax; y++) - ss = ss + imIn->image8[y][xx] * k[y - (int) ymin]; - ss = ss * ww + 0.5; - if (ss < 0.5) - imOut->image8[yy][xx] = 0; - else if (ss >= 255.0) - imOut->image8[yy][xx] = 255; - else - imOut->image8[yy][xx] = (UINT8) ss; - } - } else - switch(imIn->type) { - case IMAGING_TYPE_UINT8: - /* n-bit grayscale */ - for (xx = 0; xx < imOut->xsize*4; xx++) { - /* FIXME: skip over unused pixels */ - ss = 0.0; - for (y = (int) ymin; y < (int) ymax; y++) - ss = ss + (UINT8) imIn->image[y][xx] * k[y-(int) ymin]; - ss = ss * ww + 0.5; - if (ss < 0.5) - imOut->image[yy][xx] = (UINT8) 0; - else if (ss >= 255.0) - imOut->image[yy][xx] = (UINT8) 255; - else - imOut->image[yy][xx] = (UINT8) ss; - } - break; - case IMAGING_TYPE_INT32: - /* 32-bit integer */ - for (xx = 0; xx < imOut->xsize; xx++) { - ss = 0.0; - for (y = (int) ymin; y < (int) ymax; y++) - ss = ss + IMAGING_PIXEL_I(imIn, xx, y) * k[y - (int) ymin]; - IMAGING_PIXEL_I(imOut, xx, yy) = (int) ss * ww; - } - break; - case IMAGING_TYPE_FLOAT32: - /* 32-bit float */ - for (xx = 0; xx < imOut->xsize; xx++) { - ss = 0.0; - for (y = (int) ymin; y < (int) ymax; y++) - ss = ss + IMAGING_PIXEL_F(imIn, xx, y) * k[y - (int) ymin]; - IMAGING_PIXEL_F(imOut, xx, yy) = ss * ww; - } - break; - default: - ImagingSectionLeave(&cookie); - return (Imaging) ImagingError_ModeError(); - } - } - } else { - /* horizontal stretch */ - for (xx = 0; xx < imOut->xsize; xx++) { - center = (xx + 0.5) * scale; - ww = 0.0; - ss = 1.0 / filterscale; - xmin = floor(center - support); - if (xmin < 0.0) - xmin = 0.0; - xmax = ceil(center + support); - if (xmax > (float) imIn->xsize) - xmax = (float) imIn->xsize; - for (x = (int) xmin; x < (int) xmax; x++) { - float w = filterp->filter((x - center + 0.5) * ss) * ss; - k[x - (int) xmin] = w; - ww = ww + w; - } - if (ww == 0.0) - ww = 1.0; - else - ww = 1.0 / ww; - if (imIn->image8) { - /* 8-bit grayscale */ - for (yy = 0; yy < imOut->ysize; yy++) { - ss = 0.0; - for (x = (int) xmin; x < (int) xmax; x++) - ss = ss + imIn->image8[yy][x] * k[x - (int) xmin]; - ss = ss * ww + 0.5; - if (ss < 0.5) - imOut->image8[yy][xx] = (UINT8) 0; - else if (ss >= 255.0) - imOut->image8[yy][xx] = (UINT8) 255; - else - imOut->image8[yy][xx] = (UINT8) ss; - } - } else - switch(imIn->type) { - case IMAGING_TYPE_UINT8: - /* n-bit grayscale */ - for (yy = 0; yy < imOut->ysize; yy++) { - for (b = 0; b < imIn->bands; b++) { - if (imIn->bands == 2 && b) - b = 3; /* hack to deal with LA images */ - ss = 0.0; - for (x = (int) xmin; x < (int) xmax; x++) - ss = ss + (UINT8) imIn->image[yy][x*4+b] * k[x - (int) xmin]; - ss = ss * ww + 0.5; - if (ss < 0.5) - imOut->image[yy][xx*4+b] = (UINT8) 0; - else if (ss >= 255.0) - imOut->image[yy][xx*4+b] = (UINT8) 255; - else - imOut->image[yy][xx*4+b] = (UINT8) ss; - } - } - break; - case IMAGING_TYPE_INT32: - /* 32-bit integer */ - for (yy = 0; yy < imOut->ysize; yy++) { - ss = 0.0; - for (x = (int) xmin; x < (int) xmax; x++) - ss = ss + IMAGING_PIXEL_I(imIn, x, yy) * k[x - (int) xmin]; - IMAGING_PIXEL_I(imOut, xx, yy) = (int) ss * ww; - } - break; - case IMAGING_TYPE_FLOAT32: - /* 32-bit float */ - for (yy = 0; yy < imOut->ysize; yy++) { - ss = 0.0; - for (x = (int) xmin; x < (int) xmax; x++) - ss = ss + IMAGING_PIXEL_F(imIn, x, yy) * k[x - (int) xmin]; - IMAGING_PIXEL_F(imOut, xx, yy) = ss * ww; - } - break; - default: - ImagingSectionLeave(&cookie); - return (Imaging) ImagingError_ModeError(); - } - } - } - ImagingSectionLeave(&cookie); - - free(k); - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c deleted file mode 100755 index fdfc6ae9581..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bands.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * stuff to extract and paste back individual bands - * - * history: - * 1996-03-20 fl Created - * 1997-08-27 fl Fixed putband for single band targets. - * 2003-09-26 fl Fixed getband/putband for 2-band images (LA, PA). - * - * Copyright (c) 1997-2003 by Secret Labs AB. - * Copyright (c) 1996-1997 by Fredrik Lundh. - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - - -#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) - - -Imaging -ImagingGetBand(Imaging imIn, int band) -{ - Imaging imOut; - int x, y; - - /* Check arguments */ - if (!imIn || imIn->type != IMAGING_TYPE_UINT8) - return (Imaging) ImagingError_ModeError(); - - if (band < 0 || band >= imIn->bands) - return (Imaging) ImagingError_ValueError("band index out of range"); - - /* Shortcuts */ - if (imIn->bands == 1) - return ImagingCopy(imIn); - - /* Special case for LXXA etc */ - if (imIn->bands == 2 && band == 1) - band = 3; - - imOut = ImagingNew("L", imIn->xsize, imIn->ysize); - if (!imOut) - return NULL; - - /* Extract band from image */ - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = (UINT8*) imIn->image[y] + band; - UINT8* out = imOut->image8[y]; - for (x = 0; x < imIn->xsize; x++) { - out[x] = *in; - in += 4; - } - } - - return imOut; -} - -Imaging -ImagingPutBand(Imaging imOut, Imaging imIn, int band) -{ - int x, y; - - /* Check arguments */ - if (!imIn || imIn->bands != 1 || !imOut) - return (Imaging) ImagingError_ModeError(); - - if (band < 0 || band >= imOut->bands) - return (Imaging) ImagingError_ValueError("band index out of range"); - - if (imIn->type != imOut->type || - imIn->xsize != imOut->xsize || - imIn->ysize != imOut->ysize) - return (Imaging) ImagingError_Mismatch(); - - /* Shortcuts */ - if (imOut->bands == 1) - return ImagingCopy2(imOut, imIn); - - /* Special case for LXXA etc */ - if (imOut->bands == 2 && band == 1) - band = 3; - - /* Insert band into image */ - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = imIn->image8[y]; - UINT8* out = (UINT8*) imOut->image[y] + band; - for (x = 0; x < imIn->xsize; x++) { - *out = in[x]; - out += 4; - } - } - - return imOut; -} - -Imaging -ImagingFillBand(Imaging imOut, int band, int color) -{ - int x, y; - - /* Check arguments */ - if (!imOut || imOut->type != IMAGING_TYPE_UINT8) - return (Imaging) ImagingError_ModeError(); - - if (band < 0 || band >= imOut->bands) - return (Imaging) ImagingError_ValueError("band index out of range"); - - /* Special case for LXXA etc */ - if (imOut->bands == 2 && band == 1) - band = 3; - - color = CLIP(color); - - /* Insert color into image */ - for (y = 0; y < imOut->ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y] + band; - for (x = 0; x < imOut->xsize; x++) { - *out = (UINT8) color; - out += 4; - } - } - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h deleted file mode 100755 index 56e3a17d2e7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Bit.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Bit.h */ - -typedef struct { - - /* CONFIGURATION */ - - /* Number of bits per pixel */ - int bits; - - /* Line padding (0 or 8) */ - int pad; - - /* Fill order */ - /* 0=msb/msb, 1=msbfill/lsbshift, 2=lsbfill/msbshift, 3=lsb/lsb */ - int fill; - - /* Signed integers (0=unsigned, 1=signed) */ - int sign; - - /* Lookup table (not implemented) */ - unsigned long lutsize; - FLOAT32* lut; - - /* INTERNAL */ - unsigned long mask; - unsigned long signmask; - unsigned long bitbuffer; - int bitcount; - -} BITSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c deleted file mode 100755 index 572926f0079..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/BitDecode.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for packed bitfields (converts to floating point) - * - * history: - * 97-05-31 fl created (much more than originally intended) - * - * Copyright (c) Fredrik Lundh 1997. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#include "Bit.h" - - -int -ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - BITSTATE* bitstate = state->context; - UINT8* ptr; - - if (state->state == 0) { - - /* Initialize context variables */ - - /* this decoder only works for float32 image buffers */ - if (im->type != IMAGING_TYPE_FLOAT32) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - - /* sanity check */ - if (bitstate->bits < 1 || bitstate->bits >= 32) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - - bitstate->mask = (1<bits)-1; - - if (bitstate->sign) - bitstate->signmask = (1<<(bitstate->bits-1)); - - /* check image orientation */ - if (state->ystep < 0) { - state->y = state->ysize-1; - state->ystep = -1; - } else - state->ystep = 1; - - state->state = 1; - - } - - ptr = buf; - - while (bytes > 0) { - - UINT8 byte = *ptr; - - ptr++; - bytes--; - - /* get a byte from the input stream and insert in the bit buffer */ - if (bitstate->fill&1) - /* fill MSB first */ - bitstate->bitbuffer |= (unsigned long) byte << bitstate->bitcount; - else - /* fill LSB first */ - bitstate->bitbuffer = (bitstate->bitbuffer << 8) | byte; - - bitstate->bitcount += 8; - - while (bitstate->bitcount >= bitstate->bits) { - - /* get a pixel from the bit buffer */ - unsigned long data; - FLOAT32 pixel; - - if (bitstate->fill&2) { - /* store LSB first */ - data = bitstate->bitbuffer & bitstate->mask; - if (bitstate->bitcount > 32) - /* bitbuffer overflow; restore it from last input byte */ - bitstate->bitbuffer = byte >> (8 - (bitstate->bitcount - - bitstate->bits)); - else - bitstate->bitbuffer >>= bitstate->bits; - } else - /* store MSB first */ - data = (bitstate->bitbuffer >> (bitstate->bitcount - - bitstate->bits)) - & bitstate->mask; - - bitstate->bitcount -= bitstate->bits; - - if (bitstate->lutsize > 0) { - /* map through lookup table */ - if (data <= 0) - pixel = bitstate->lut[0]; - else if (data >= bitstate->lutsize) - pixel = bitstate->lut[bitstate->lutsize-1]; - else - pixel = bitstate->lut[data]; - } else { - /* convert */ - if (data & bitstate->signmask) - /* image memory contains signed data */ - pixel = (FLOAT32) (INT32) (data | ~bitstate->mask); - else - pixel = (FLOAT32) data; - } - - *(FLOAT32*)(&im->image32[state->y][state->x]) = pixel; - - /* step forward */ - if (++state->x >= state->xsize) { - /* new line */ - state->y += state->ystep; - if (state->y < 0 || state->y >= state->ysize) { - /* end of file (errcode = 0) */ - return -1; - } - state->x = 0; - /* reset bit buffer */ - if (bitstate->pad > 0) - bitstate->bitcount = 0; - } - } - } - - return ptr - buf; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c deleted file mode 100755 index 0861c8ef4fb..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Blend.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * interpolate between two existing images - * - * history: - * 96-03-20 fl Created - * 96-05-18 fl Simplified blend expression - * 96-10-05 fl Fixed expression bug, special case for interpolation - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - - -Imaging -ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) -{ - Imaging imOut; - int x, y; - - /* Check arguments */ - if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8) - return ImagingError_ModeError(); - if (imIn1->type != imIn2->type || - imIn1->bands != imIn2->bands || - imIn1->xsize != imIn2->xsize || - imIn1->ysize != imIn2->ysize) - return ImagingError_Mismatch(); - - /* Shortcuts */ - if (alpha == 0.0) - return ImagingCopy(imIn1); - else if (alpha == 1.0) - return ImagingCopy(imIn2); - - imOut = ImagingNew(imIn1->mode, imIn1->xsize, imIn1->ysize); - if (!imOut) - return NULL; - - ImagingCopyInfo(imOut, imIn1); - - if (alpha >= 0 && alpha <= 1.0) { - /* Interpolate between bands */ - for (y = 0; y < imIn1->ysize; y++) { - UINT8* in1 = (UINT8*) imIn1->image[y]; - UINT8* in2 = (UINT8*) imIn2->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - for (x = 0; x < imIn1->linesize; x++) - out[x] = (UINT8) - ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); - } - } else { - /* Extrapolation; must make sure to clip resulting values */ - for (y = 0; y < imIn1->ysize; y++) { - UINT8* in1 = (UINT8*) imIn1->image[y]; - UINT8* in2 = (UINT8*) imIn2->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - for (x = 0; x < imIn1->linesize; x++) { - float temp = (float) - ((int) in1[x] + alpha * ((int) in2[x] - (int) in1[x])); - if (temp <= 0.0) - out[x] = 0; - else if (temp >= 255.0) - out[x] = 255; - else - out[x] = (UINT8) temp; - } - } - } - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c deleted file mode 100755 index e5993195a03..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Chops.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * basic channel operations - * - * history: - * 1996-03-28 fl Created - * 1996-08-13 fl Added and/or/xor for "1" images - * 1996-12-14 fl Added add_modulo, sub_modulo - * 2005-09-10 fl Fixed output values from and/or/xor - * - * Copyright (c) 1996 by Fredrik Lundh. - * Copyright (c) 1997 by Secret Labs AB. - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - -#define CHOP(operation, mode)\ - int x, y;\ - Imaging imOut;\ - imOut = create(imIn1, imIn2, mode);\ - if (!imOut)\ - return NULL;\ - for (y = 0; y < imOut->ysize; y++) {\ - UINT8* out = (UINT8*) imOut->image[y];\ - UINT8* in1 = (UINT8*) imIn1->image[y];\ - UINT8* in2 = (UINT8*) imIn2->image[y];\ - for (x = 0; x < imOut->linesize; x++) {\ - int temp = operation;\ - if (temp <= 0)\ - out[x] = 0;\ - else if (temp >= 255)\ - out[x] = 255;\ - else\ - out[x] = temp;\ - }\ - }\ - return imOut; - -#define CHOP2(operation, mode)\ - int x, y;\ - Imaging imOut;\ - imOut = create(imIn1, imIn2, mode);\ - if (!imOut)\ - return NULL;\ - for (y = 0; y < imOut->ysize; y++) {\ - UINT8* out = (UINT8*) imOut->image[y];\ - UINT8* in1 = (UINT8*) imIn1->image[y];\ - UINT8* in2 = (UINT8*) imIn2->image[y];\ - for (x = 0; x < imOut->linesize; x++) {\ - out[x] = operation;\ - }\ - }\ - return imOut; - -static Imaging -create(Imaging im1, Imaging im2, char* mode) -{ - int xsize, ysize; - - if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 || - (mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) - return (Imaging) ImagingError_ModeError(); - if (im1->type != im2->type || - im1->bands != im2->bands) - return (Imaging) ImagingError_Mismatch(); - - xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize; - ysize = (im1->ysize < im2->ysize) ? im1->ysize : im2->ysize; - - return ImagingNew(im1->mode, xsize, ysize); -} - -Imaging -ImagingChopLighter(Imaging imIn1, Imaging imIn2) -{ - CHOP((in1[x] > in2[x]) ? in1[x] : in2[x], NULL); -} - -Imaging -ImagingChopDarker(Imaging imIn1, Imaging imIn2) -{ - CHOP((in1[x] < in2[x]) ? in1[x] : in2[x], NULL); -} - -Imaging -ImagingChopDifference(Imaging imIn1, Imaging imIn2) -{ - CHOP(abs((int) in1[x] - (int) in2[x]), NULL); -} - -Imaging -ImagingChopMultiply(Imaging imIn1, Imaging imIn2) -{ - CHOP((int) in1[x] * (int) in2[x] / 255, NULL); -} - -Imaging -ImagingChopScreen(Imaging imIn1, Imaging imIn2) -{ - CHOP(255 - ((int) (255 - in1[x]) * (int) (255 - in2[x])) / 255, NULL); -} - -Imaging -ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset) -{ - CHOP(((int) in1[x] + (int) in2[x]) / scale + offset, NULL); -} - -Imaging -ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) -{ - CHOP(((int) in1[x] - (int) in2[x]) / scale + offset, NULL); -} - -Imaging -ImagingChopAnd(Imaging imIn1, Imaging imIn2) -{ - CHOP2((in1[x] && in2[x]) ? 255 : 0, "1"); -} - -Imaging -ImagingChopOr(Imaging imIn1, Imaging imIn2) -{ - CHOP2((in1[x] || in2[x]) ? 255 : 0, "1"); -} - -Imaging -ImagingChopXor(Imaging imIn1, Imaging imIn2) -{ - CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1"); -} - -Imaging -ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) -{ - CHOP2(in1[x] + in2[x], NULL); -} - -Imaging -ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) -{ - CHOP2(in1[x] - in2[x], NULL); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c deleted file mode 100755 index 25299aa8280..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Convert.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * convert images - * - * history: - * 1995-06-15 fl created - * 1995-11-28 fl added some "RGBA" and "CMYK" conversions - * 1996-04-22 fl added "1" conversions (same as "L") - * 1996-05-05 fl added palette conversions (hack) - * 1996-07-23 fl fixed "1" conversions to zero/non-zero convention - * 1996-11-01 fl fixed "P" to "L" and "RGB" to "1" conversions - * 1996-12-29 fl set alpha byte in RGB converters - * 1997-05-12 fl added ImagingConvert2 - * 1997-05-30 fl added floating point support - * 1997-08-27 fl added "P" to "1" and "P" to "F" conversions - * 1998-01-11 fl added integer support - * 1998-07-01 fl added "YCbCr" support - * 1998-07-02 fl added "RGBX" conversions (sort of) - * 1998-07-04 fl added floyd-steinberg dithering - * 1998-07-12 fl changed "YCrCb" to "YCbCr" (!) - * 1998-12-29 fl added basic "I;16" and "I;16B" conversions - * 1999-02-03 fl added "RGBa", and "BGR" conversions (experimental) - * 2003-09-26 fl added "LA" and "PA" conversions (experimental) - * 2005-05-05 fl fixed "P" to "1" threshold - * 2005-12-08 fl fixed palette memory leak in topalette - * - * Copyright (c) 1997-2005 by Secret Labs AB. - * Copyright (c) 1995-1997 by Fredrik Lundh. - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - -#define CLIP(v) ((v) <= 0 ? 0 : (v) >= 255 ? 255 : (v)) -#define CLIP16(v) ((v) <= -32768 ? -32768 : (v) >= 32767 ? 32767 : (v)) - -/* like (a * b + 127) / 255), but much faster on most platforms */ -#define MULDIV255(a, b, tmp)\ - (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) - -/* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ -#define L(rgb)\ - ((INT32) (rgb)[0]*299 + (INT32) (rgb)[1]*587 + (INT32) (rgb)[2]*114) - -/* ------------------- */ -/* 1 (bit) conversions */ -/* ------------------- */ - -static void -bit2l(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) - *out++ = (*in++ != 0) ? 255 : 0; -} - -static void -bit2rgb(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - UINT8 v = (*in++ != 0) ? 255 : 0; - *out++ = v; - *out++ = v; - *out++ = v; - *out++ = 255; - } -} - -static void -bit2cmyk(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - *out++ = 0; - *out++ = 0; - *out++ = 0; - *out++ = (*in++ != 0) ? 0 : 255; - } -} - -static void -bit2ycbcr(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - *out++ = (*in++ != 0) ? 255 : 0; - *out++ = 128; - *out++ = 128; - *out++ = 255; - } -} - -/* ----------------- */ -/* RGB/L conversions */ -/* ----------------- */ - -static void -l2bit(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) - *out++ = (*in++ >= 128) ? 255 : 0; -} - -static void -l2la(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - UINT8 v = *in++; - *out++ = v; - *out++ = v; - *out++ = v; - *out++ = 255; - } -} - -static void -l2rgb(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - UINT8 v = *in++; - *out++ = v; - *out++ = v; - *out++ = v; - *out++ = 255; - } -} - -static void -la2l(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) - *out++ = in[0]; -} - -static void -la2rgb(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) { - UINT8 v = in[0]; - *out++ = v; - *out++ = v; - *out++ = v; - *out++ = in[3]; - } -} - -static void -rgb2bit(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) - /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ - *out++ = (L(in) >= 128000) ? 255 : 0; -} - -static void -rgb2l(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) - /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ - *out++ = L(in) / 1000; -} - -static void -rgb2la(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4, out += 4) { - /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ - out[0] = out[1] = out[2] = L(in) / 1000; - out[3] = 255; - } -} - -static void -rgb2i(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = L(in) / 1000; -} - -static void -rgb2f(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = (float) L(in) / 1000.0F; -} - -static void -rgb2bgr15(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - UINT16* out = (UINT16*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = - ((((UINT16)in[0])<<7)&0x7c00) + - ((((UINT16)in[1])<<2)&0x03e0) + - ((((UINT16)in[2])>>3)&0x001f); -} - -static void -rgb2bgr16(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - UINT16* out = (UINT16*) out_; - for (x = 0; x < xsize; x++, in += 4) - *out++ = - ((((UINT16)in[0])<<8)&0xf800) + - ((((UINT16)in[1])<<3)&0x07e0) + - ((((UINT16)in[2])>>3)&0x001f); -} - -static void -rgb2bgr24(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) { - *out++ = in[2]; - *out++ = in[1]; - *out++ = in[0]; - } -} - -/* ---------------- */ -/* RGBA conversions */ -/* ---------------- */ - -static void -rgb2rgba(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - *out++ = *in++; - *out++ = *in++; - *out++ = *in++; - *out++ = 255; in++; - } -} - -static void -rgba2la(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4, out += 4) { - /* ITU-R Recommendation 601-2 (assuming nonlinear RGB) */ - out[0] = out[1] = out[2] = L(in) / 1000; - out[3] = in[3]; - } -} - -static void -rgba2rgb(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - *out++ = *in++; - *out++ = *in++; - *out++ = *in++; - *out++ = 255; in++; - } -} - -static void -rgba2rgba(UINT8* out, const UINT8* in, int xsize) -{ - int x; - unsigned int alpha, tmp; - for (x = 0; x < xsize; x++) { - alpha = in[3]; - *out++ = MULDIV255(*in++, alpha, tmp); - *out++ = MULDIV255(*in++, alpha, tmp); - *out++ = MULDIV255(*in++, alpha, tmp); - *out++ = *in++; - } -} - -/* ---------------- */ -/* CMYK conversions */ -/* ---------------- */ - -static void -l2cmyk(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - *out++ = 0; - *out++ = 0; - *out++ = 0; - *out++ = ~(*in++); - } -} - -static void -rgb2cmyk(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - /* Note: no undercolour removal */ - *out++ = ~(*in++); - *out++ = ~(*in++); - *out++ = ~(*in++); - *out++ = 0; in++; - } -} - -static void -cmyk2rgb(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) { - *out++ = CLIP(255 - (in[0] + in[3])); - *out++ = CLIP(255 - (in[1] + in[3])); - *out++ = CLIP(255 - (in[2] + in[3])); - *out++ = 255; - } -} - -/* ------------- */ -/* I conversions */ -/* ------------- */ - -static void -bit2i(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (*in++ != 0) ? 255 : 0; -} - -static void -l2i(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (INT32) *in++; -} - -static void -i2l(UINT8* out, const UINT8* in_, int xsize) -{ - int x; - INT32* in = (INT32*) in_; - for (x = 0; x < xsize; x++, in++, out++) { - if (*in <= 0) - *out = 0; - else if (*in >= 255) - *out = 255; - else - *out = (UINT8) *in; - } -} - -static void -i2f(UINT8* out_, const UINT8* in_, int xsize) -{ - int x; - INT32* in = (INT32*) in_; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (FLOAT32) *in++; -} - -/* ------------- */ -/* F conversions */ -/* ------------- */ - -static void -bit2f(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (*in++ != 0) ? 255.0F : 0.0F; -} - -static void -l2f(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (FLOAT32) *in++; -} - -static void -f2l(UINT8* out, const UINT8* in_, int xsize) -{ - int x; - FLOAT32* in = (FLOAT32*) in_; - for (x = 0; x < xsize; x++, in++, out++) { - if (*in <= 0.0) - *out = 0; - else if (*in >= 255.0) - *out = 255; - else - *out = (UINT8) *in; - } -} - -static void -f2i(UINT8* out_, const UINT8* in_, int xsize) -{ - int x; - FLOAT32* in = (FLOAT32*) in_; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (INT32) *in++; -} - -/* ----------------- */ -/* YCbCr conversions */ -/* ----------------- */ - -/* See ConvertYCbCr.c for RGB/YCbCr tables */ - -static void -l2ycbcr(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++) { - *out++ = *in++; - *out++ = 128; - *out++ = 128; - *out++ = 255; - } -} - -static void -ycbcr2l(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) - *out++ = in[0]; -} - -/* ------------------------- */ -/* I;16 (16-bit) conversions */ -/* ------------------------- */ - -static void -I_I16L(UINT8* out, const UINT8* in_, int xsize) -{ - int x, v; - INT32* in = (INT32*) in_; - for (x = 0; x < xsize; x++, in++) { - v = CLIP16(*in); - *out++ = (UINT8) v; - *out++ = (UINT8) (v >> 8); - } -} - -static void -I_I16B(UINT8* out, const UINT8* in_, int xsize) -{ - int x, v; - INT32* in = (INT32*) in_; - for (x = 0; x < xsize; x++, in++) { - v = CLIP16(*in); - *out++ = (UINT8) (v >> 8); - *out++ = (UINT8) v; - } -} - - -static void -I16L_I(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++, in += 2) - *out++ = in[0] + ((int) in[1] << 8); -} - - -static void -I16B_I(UINT8* out_, const UINT8* in, int xsize) -{ - int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++, in += 2) - *out++ = in[1] + ((int) in[0] << 8); -} - -static void -L_I16L(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in++) { - *out++ = *in; - *out++ = 0; - } -} - -static void -L_I16B(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in++) { - *out++ = 0; - *out++ = *in; - } -} - -static void -I16L_L(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 2) - if (in[1] != 0) - *out++ = 255; - else - *out++ = in[0]; -} - -static void -I16B_L(UINT8* out, const UINT8* in, int xsize) -{ - int x; - for (x = 0; x < xsize; x++, in += 2) - if (in[0] != 0) - *out++ = 255; - else - *out++ = in[1]; -} - -static struct { - const char* from; - const char* to; - ImagingShuffler convert; -} converters[] = { - - { "1", "L", bit2l }, - { "1", "I", bit2i }, - { "1", "F", bit2f }, - { "1", "RGB", bit2rgb }, - { "1", "RGBA", bit2rgb }, - { "1", "RGBX", bit2rgb }, - { "1", "CMYK", bit2cmyk }, - { "1", "YCbCr", bit2ycbcr }, - - { "L", "1", l2bit }, - { "L", "LA", l2la }, - { "L", "I", l2i }, - { "L", "F", l2f }, - { "L", "RGB", l2rgb }, - { "L", "RGBA", l2rgb }, - { "L", "RGBX", l2rgb }, - { "L", "CMYK", l2cmyk }, - { "L", "YCbCr", l2ycbcr }, - - { "LA", "L", la2l }, - { "LA", "RGB", la2rgb }, - { "LA", "RGBX", la2rgb }, - { "LA", "RGBA", la2rgb }, - - { "I", "L", i2l }, - { "I", "F", i2f }, - - { "F", "L", f2l }, - { "F", "I", f2i }, - - { "RGB", "1", rgb2bit }, - { "RGB", "L", rgb2l }, - { "RGB", "LA", rgb2la }, - { "RGB", "I", rgb2i }, - { "RGB", "F", rgb2f }, - { "RGB", "BGR;15", rgb2bgr15 }, - { "RGB", "BGR;16", rgb2bgr16 }, - { "RGB", "BGR;24", rgb2bgr24 }, - { "RGB", "RGBA", rgb2rgba }, - { "RGB", "RGBX", rgb2rgba }, - { "RGB", "CMYK", rgb2cmyk }, - { "RGB", "YCbCr", ImagingConvertRGB2YCbCr }, - - { "RGBA", "1", rgb2bit }, - { "RGBA", "L", rgb2l }, - { "RGBA", "LA", rgba2la }, - { "RGBA", "I", rgb2i }, - { "RGBA", "F", rgb2f }, - { "RGBA", "RGB", rgba2rgb }, - { "RGBA", "RGBa", rgba2rgba }, - { "RGBA", "RGBX", rgb2rgba }, - { "RGBA", "CMYK", rgb2cmyk }, - { "RGBA", "YCbCr", ImagingConvertRGB2YCbCr }, - - { "RGBX", "1", rgb2bit }, - { "RGBX", "L", rgb2l }, - { "RGBA", "I", rgb2i }, - { "RGBA", "F", rgb2f }, - { "RGBX", "RGB", rgba2rgb }, - { "RGBX", "CMYK", rgb2cmyk }, - { "RGBX", "YCbCr", ImagingConvertRGB2YCbCr }, - - { "CMYK", "RGB", cmyk2rgb }, - { "CMYK", "RGBA", cmyk2rgb }, - { "CMYK", "RGBX", cmyk2rgb }, - - { "YCbCr", "L", ycbcr2l }, - { "YCbCr", "RGB", ImagingConvertYCbCr2RGB }, - - { "I", "I;16", I_I16L }, - { "I;16", "I", I16L_I }, - { "L", "I;16", L_I16L }, - { "I;16", "L", I16L_L }, - - { "I", "I;16L", I_I16L }, - { "I;16L", "I", I16L_I }, - { "I", "I;16B", I_I16B }, - { "I;16B", "I", I16B_I }, - - { "L", "I;16L", L_I16L }, - { "I;16L", "L", I16L_L }, - { "L", "I;16B", L_I16B }, - { "I;16B", "L", I16B_L }, - - { NULL } -}; - -/* FIXME: translate indexed versions to pointer versions below this line */ - -/* ------------------- */ -/* Palette conversions */ -/* ------------------- */ - -static void -p2bit(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - /* FIXME: precalculate greyscale palette? */ - for (x = 0; x < xsize; x++) - *out++ = (L(&palette[in[x]*4]) >= 128000) ? 255 : 0; -} - -static void -p2l(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - /* FIXME: precalculate greyscale palette? */ - for (x = 0; x < xsize; x++) - *out++ = L(&palette[in[x]*4]) / 1000; -} - -static void -pa2la(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - /* FIXME: precalculate greyscale palette? */ - for (x = 0; x < xsize; x++, in += 2) { - *out++ = L(&palette[in[0]*4]) / 1000; - *out++ = in[1]; - } -} - -static void -p2i(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - INT32* out = (INT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = L(&palette[in[x]*4]) / 1000; -} - -static void -p2f(UINT8* out_, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - FLOAT32* out = (FLOAT32*) out_; - for (x = 0; x < xsize; x++) - *out++ = (float) L(&palette[in[x]*4]) / 1000.0F; -} - -static void -p2rgb(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - for (x = 0; x < xsize; x++) { - const UINT8* rgb = &palette[*in++ * 4]; - *out++ = rgb[0]; - *out++ = rgb[1]; - *out++ = rgb[2]; - *out++ = 255; - } -} - -static void -p2rgba(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - for (x = 0; x < xsize; x++) { - const UINT8* rgba = &palette[*in++ * 4]; - *out++ = rgba[0]; - *out++ = rgba[1]; - *out++ = rgba[2]; - *out++ = rgba[3]; - } -} - -static void -pa2rgba(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - int x; - for (x = 0; x < xsize; x++, in += 4) { - const UINT8* rgb = &palette[in[0] * 4]; - *out++ = rgb[0]; - *out++ = rgb[1]; - *out++ = rgb[2]; - *out++ = in[3]; - } -} - -static void -p2cmyk(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - p2rgb(out, in, xsize, palette); - rgb2cmyk(out, out, xsize); -} - -static void -p2ycbcr(UINT8* out, const UINT8* in, int xsize, const UINT8* palette) -{ - p2rgb(out, in, xsize, palette); - ImagingConvertRGB2YCbCr(out, out, xsize); -} - -static Imaging -frompalette(Imaging imOut, Imaging imIn, const char *mode) -{ - ImagingSectionCookie cookie; - int alpha; - int y; - void (*convert)(UINT8*, const UINT8*, int, const UINT8*); - - /* Map palette image to L, RGB, RGBA, or CMYK */ - - if (!imIn->palette) - return (Imaging) ImagingError_ValueError("no palette"); - - alpha = !strcmp(imIn->mode, "PA"); - - if (strcmp(mode, "1") == 0) - convert = p2bit; - else if (strcmp(mode, "L") == 0) - convert = p2l; - else if (strcmp(mode, "LA") == 0) - convert = (alpha) ? pa2la : p2l; - else if (strcmp(mode, "I") == 0) - convert = p2i; - else if (strcmp(mode, "F") == 0) - convert = p2f; - else if (strcmp(mode, "RGB") == 0) - convert = p2rgb; - else if (strcmp(mode, "RGBA") == 0) - convert = (alpha) ? pa2rgba : p2rgba; - else if (strcmp(mode, "RGBX") == 0) - convert = p2rgba; - else if (strcmp(mode, "CMYK") == 0) - convert = p2cmyk; - else if (strcmp(mode, "YCbCr") == 0) - convert = p2ycbcr; - else - return (Imaging) ImagingError_ValueError("conversion not supported"); - - imOut = ImagingNew2(mode, imOut, imIn); - if (!imOut) - return NULL; - - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) - (*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], - imIn->xsize, imIn->palette->palette); - ImagingSectionLeave(&cookie); - - return imOut; -} - -static Imaging -topalette(Imaging imOut, Imaging imIn, ImagingPalette inpalette, int dither) -{ - ImagingSectionCookie cookie; - int x, y; - ImagingPalette palette = inpalette;; - - /* Map L or RGB/RGBX/RGBA to palette image */ - if (strcmp(imIn->mode, "L") != 0 && strncmp(imIn->mode, "RGB", 3) != 0) - return (Imaging) ImagingError_ValueError("conversion not supported"); - - if (palette == NULL) { - /* FIXME: make user configurable */ - if (imIn->bands == 1) - palette = ImagingPaletteNew("RGB"); /* Initialised to grey ramp */ - else - palette = ImagingPaletteNewBrowser(); /* Standard colour cube */ - } - - if (!palette) - return (Imaging) ImagingError_ValueError("no palette"); - - imOut = ImagingNew2("P", imOut, imIn); - if (!imOut) { - if (palette != inpalette) - ImagingPaletteDelete(palette); - return NULL; - } - - ImagingPaletteDelete(imOut->palette); - imOut->palette = ImagingPaletteDuplicate(palette); - - if (imIn->bands == 1) { - /* greyscale image */ - - /* Greyscale palette: copy data as is */ - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) - memcpy(imOut->image[y], imIn->image[y], imIn->linesize); - ImagingSectionLeave(&cookie); - - } else { - /* colour image */ - - /* Create mapping cache */ - if (ImagingPaletteCachePrepare(palette) < 0) { - ImagingDelete(imOut); - if (palette != inpalette) - ImagingPaletteDelete(palette); - return NULL; - } - - if (dither) { - /* floyd-steinberg dither */ - - int* errors; - errors = calloc(imIn->xsize + 1, sizeof(int) * 3); - if (!errors) { - ImagingDelete(imOut); - return ImagingError_MemoryError(); - } - - /* Map each pixel to the nearest palette entry */ - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - int r, r0, r1, r2; - int g, g0, g1, g2; - int b, b0, b1, b2; - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = imOut->image8[y]; - int* e = errors; - - r = r0 = r1 = 0; - g = g0 = g1 = 0; - b = b0 = b1 = b2 = 0; - - for (x = 0; x < imIn->xsize; x++, in += 4) { - int d2; - INT16* cache; - - r = CLIP(in[0] + (r + e[3+0])/16); - g = CLIP(in[1] + (g + e[3+1])/16); - b = CLIP(in[2] + (b + e[3+2])/16); - - /* get closest colour */ - cache = &ImagingPaletteCache(palette, r, g, b); - if (cache[0] == 0x100) - ImagingPaletteCacheUpdate(palette, r, g, b); - out[x] = (UINT8) cache[0]; - - r -= (int) palette->palette[cache[0]*4]; - g -= (int) palette->palette[cache[0]*4+1]; - b -= (int) palette->palette[cache[0]*4+2]; - - /* propagate errors (don't ask ;-) */ - r2 = r; d2 = r + r; r += d2; e[0] = r + r0; - r += d2; r0 = r + r1; r1 = r2; r += d2; - g2 = g; d2 = g + g; g += d2; e[1] = g + g0; - g += d2; g0 = g + g1; g1 = g2; g += d2; - b2 = b; d2 = b + b; b += d2; e[2] = b + b0; - b += d2; b0 = b + b1; b1 = b2; b += d2; - - e += 3; - - } - - e[0] = b0; - e[1] = b1; - e[2] = b2; - - } - ImagingSectionLeave(&cookie); - free(errors); - - } else { - - /* closest colour */ - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - int r, g, b; - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = imOut->image8[y]; - - for (x = 0; x < imIn->xsize; x++, in += 4) { - INT16* cache; - - r = in[0]; g = in[1]; b = in[2]; - - /* get closest colour */ - cache = &ImagingPaletteCache(palette, r, g, b); - if (cache[0] == 0x100) - ImagingPaletteCacheUpdate(palette, r, g, b); - out[x] = (UINT8) cache[0]; - - } - } - ImagingSectionLeave(&cookie); - - } - if (inpalette != palette) - ImagingPaletteCacheDelete(palette); - } - - if (inpalette != palette) - ImagingPaletteDelete(palette); - - return imOut; -} - -static Imaging -tobilevel(Imaging imOut, Imaging imIn, int dither) -{ - ImagingSectionCookie cookie; - int x, y; - int* errors; - - /* Map L or RGB to dithered 1 image */ - if (strcmp(imIn->mode, "L") != 0 && strcmp(imIn->mode, "RGB") != 0) - return (Imaging) ImagingError_ValueError("conversion not supported"); - - imOut = ImagingNew2("1", imOut, imIn); - if (!imOut) - return NULL; - - errors = calloc(imIn->xsize + 1, sizeof(int)); - if (!errors) { - ImagingDelete(imOut); - return ImagingError_MemoryError(); - } - - if (imIn->bands == 1) { - - /* map each pixel to black or white, using error diffusion */ - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - int l, l0, l1, l2, d2; - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = imOut->image8[y]; - - l = l0 = l1 = 0; - - for (x = 0; x < imIn->xsize; x++) { - - /* pick closest colour */ - l = CLIP(in[x] + (l + errors[x+1])/16); - out[x] = (l > 128) ? 255 : 0; - - /* propagate errors */ - l -= (int) out[x]; - l2 = l; d2 = l + l; l += d2; errors[x] = l + l0; - l += d2; l0 = l + l1; l1 = l2; l += d2; - } - - errors[x] = l0; - - } - ImagingSectionLeave(&cookie); - - } else { - - /* map each pixel to black or white, using error diffusion */ - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - int l, l0, l1, l2, d2; - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = imOut->image8[y]; - - l = l0 = l1 = 0; - - for (x = 0; x < imIn->xsize; x++, in += 4) { - - /* pick closest colour */ - l = CLIP(L(in)/1000 + (l + errors[x+1])/16); - out[x] = (l > 128) ? 255 : 0; - - /* propagate errors */ - l -= (int) out[x]; - l2 = l; d2 = l + l; l += d2; errors[x] = l + l0; - l += d2; l0 = l + l1; l1 = l2; l += d2; - - } - - errors[x] = l0; - - } - ImagingSectionLeave(&cookie); - } - - free(errors); - - return imOut; -} - - -static Imaging -convert(Imaging imOut, Imaging imIn, const char *mode, - ImagingPalette palette, int dither) -{ - ImagingSectionCookie cookie; - ImagingShuffler convert; - int y; - - if (!imIn) - return (Imaging) ImagingError_ModeError(); - - if (!mode) { - /* Map palette image to full depth */ - if (!imIn->palette) - return (Imaging) ImagingError_ModeError(); - mode = imIn->palette->mode; - } else - /* Same mode? */ - if (!strcmp(imIn->mode, mode)) - return ImagingCopy2(imOut, imIn); - - - /* test for special conversions */ - - if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "PA") == 0) - return frompalette(imOut, imIn, mode); - - if (strcmp(mode, "P") == 0) - return topalette(imOut, imIn, palette, dither); - - if (dither && strcmp(mode, "1") == 0) - return tobilevel(imOut, imIn, dither); - - - /* standard conversion machinery */ - - convert = NULL; - - for (y = 0; converters[y].from; y++) - if (!strcmp(imIn->mode, converters[y].from) && - !strcmp(mode, converters[y].to)) { - convert = converters[y].convert; - break; - } - - if (!convert) -#ifdef notdef - return (Imaging) ImagingError_ValueError("conversion not supported"); -#else - { - static char buf[256]; - /* FIXME: may overflow if mode is too large */ - sprintf(buf, "conversion from %s to %s not supported", imIn->mode, mode); - return (Imaging) ImagingError_ValueError(buf); - } -#endif - - imOut = ImagingNew2(mode, imOut, imIn); - if (!imOut) - return NULL; - - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) - (*convert)((UINT8*) imOut->image[y], (UINT8*) imIn->image[y], - imIn->xsize); - ImagingSectionLeave(&cookie); - - return imOut; -} - -Imaging -ImagingConvert(Imaging imIn, const char *mode, - ImagingPalette palette, int dither) -{ - return convert(NULL, imIn, mode, palette, dither); -} - -Imaging -ImagingConvert2(Imaging imOut, Imaging imIn) -{ - return convert(imOut, imIn, imOut->mode, NULL, 0); -} - -Imaging -ImagingConvertInPlace(Imaging imIn, const char* mode) -{ - ImagingSectionCookie cookie; - ImagingShuffler convert; - int y; - - /* limited support for inplace conversion */ - if (strcmp(imIn->mode, "L") == 0 && strcmp(mode, "1") == 0) - convert = l2bit; - else if (strcmp(imIn->mode, "1") == 0 && strcmp(mode, "L") == 0) - convert = bit2l; - else - return ImagingError_ModeError(); - - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) - (*convert)((UINT8*) imIn->image[y], (UINT8*) imIn->image[y], - imIn->xsize); - ImagingSectionLeave(&cookie); - - return imIn; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c deleted file mode 100755 index 40cd01780d9..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ConvertYCbCr.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * code to convert YCbCr data - * - * history: - * 98-07-01 hk Created - * - * Copyright (c) Secret Labs AB 1998 - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -/* JPEG/JFIF YCbCr conversions - - Y = R * 0.29900 + G * 0.58700 + B * 0.11400 - Cb = R * -0.16874 + G * -0.33126 + B * 0.50000 + 128 - Cr = R * 0.50000 + G * -0.41869 + B * -0.08131 + 128 - - R = Y + + (Cr - 128) * 1.40200 - G = Y + (Cb - 128) * -0.34414 + (Cr - 128) * -0.71414 - B = Y + (Cb - 128) * 1.77200 - -*/ - -#define SCALE 6 /* bits */ - -static INT16 Y_R[] = { 0, 19, 38, 57, 77, 96, 115, 134, 153, 172, 191, -210, 230, 249, 268, 287, 306, 325, 344, 364, 383, 402, 421, 440, 459, -478, 498, 517, 536, 555, 574, 593, 612, 631, 651, 670, 689, 708, 727, -746, 765, 785, 804, 823, 842, 861, 880, 899, 919, 938, 957, 976, 995, -1014, 1033, 1052, 1072, 1091, 1110, 1129, 1148, 1167, 1186, 1206, -1225, 1244, 1263, 1282, 1301, 1320, 1340, 1359, 1378, 1397, 1416, -1435, 1454, 1473, 1493, 1512, 1531, 1550, 1569, 1588, 1607, 1627, -1646, 1665, 1684, 1703, 1722, 1741, 1761, 1780, 1799, 1818, 1837, -1856, 1875, 1894, 1914, 1933, 1952, 1971, 1990, 2009, 2028, 2048, -2067, 2086, 2105, 2124, 2143, 2162, 2182, 2201, 2220, 2239, 2258, -2277, 2296, 2315, 2335, 2354, 2373, 2392, 2411, 2430, 2449, 2469, -2488, 2507, 2526, 2545, 2564, 2583, 2602, 2622, 2641, 2660, 2679, -2698, 2717, 2736, 2756, 2775, 2794, 2813, 2832, 2851, 2870, 2890, -2909, 2928, 2947, 2966, 2985, 3004, 3023, 3043, 3062, 3081, 3100, -3119, 3138, 3157, 3177, 3196, 3215, 3234, 3253, 3272, 3291, 3311, -3330, 3349, 3368, 3387, 3406, 3425, 3444, 3464, 3483, 3502, 3521, -3540, 3559, 3578, 3598, 3617, 3636, 3655, 3674, 3693, 3712, 3732, -3751, 3770, 3789, 3808, 3827, 3846, 3865, 3885, 3904, 3923, 3942, -3961, 3980, 3999, 4019, 4038, 4057, 4076, 4095, 4114, 4133, 4153, -4172, 4191, 4210, 4229, 4248, 4267, 4286, 4306, 4325, 4344, 4363, -4382, 4401, 4420, 4440, 4459, 4478, 4497, 4516, 4535, 4554, 4574, -4593, 4612, 4631, 4650, 4669, 4688, 4707, 4727, 4746, 4765, 4784, -4803, 4822, 4841, 4861, 4880 }; - -static INT16 Y_G[] = { 0, 38, 75, 113, 150, 188, 225, 263, 301, 338, -376, 413, 451, 488, 526, 564, 601, 639, 676, 714, 751, 789, 826, 864, -902, 939, 977, 1014, 1052, 1089, 1127, 1165, 1202, 1240, 1277, 1315, -1352, 1390, 1428, 1465, 1503, 1540, 1578, 1615, 1653, 1691, 1728, -1766, 1803, 1841, 1878, 1916, 1954, 1991, 2029, 2066, 2104, 2141, -2179, 2217, 2254, 2292, 2329, 2367, 2404, 2442, 2479, 2517, 2555, -2592, 2630, 2667, 2705, 2742, 2780, 2818, 2855, 2893, 2930, 2968, -3005, 3043, 3081, 3118, 3156, 3193, 3231, 3268, 3306, 3344, 3381, -3419, 3456, 3494, 3531, 3569, 3607, 3644, 3682, 3719, 3757, 3794, -3832, 3870, 3907, 3945, 3982, 4020, 4057, 4095, 4132, 4170, 4208, -4245, 4283, 4320, 4358, 4395, 4433, 4471, 4508, 4546, 4583, 4621, -4658, 4696, 4734, 4771, 4809, 4846, 4884, 4921, 4959, 4997, 5034, -5072, 5109, 5147, 5184, 5222, 5260, 5297, 5335, 5372, 5410, 5447, -5485, 5522, 5560, 5598, 5635, 5673, 5710, 5748, 5785, 5823, 5861, -5898, 5936, 5973, 6011, 6048, 6086, 6124, 6161, 6199, 6236, 6274, -6311, 6349, 6387, 6424, 6462, 6499, 6537, 6574, 6612, 6650, 6687, -6725, 6762, 6800, 6837, 6875, 6913, 6950, 6988, 7025, 7063, 7100, -7138, 7175, 7213, 7251, 7288, 7326, 7363, 7401, 7438, 7476, 7514, -7551, 7589, 7626, 7664, 7701, 7739, 7777, 7814, 7852, 7889, 7927, -7964, 8002, 8040, 8077, 8115, 8152, 8190, 8227, 8265, 8303, 8340, -8378, 8415, 8453, 8490, 8528, 8566, 8603, 8641, 8678, 8716, 8753, -8791, 8828, 8866, 8904, 8941, 8979, 9016, 9054, 9091, 9129, 9167, -9204, 9242, 9279, 9317, 9354, 9392, 9430, 9467, 9505, 9542, 9580 }; - -static INT16 Y_B[] = { 0, 7, 15, 22, 29, 36, 44, 51, 58, 66, 73, 80, -88, 95, 102, 109, 117, 124, 131, 139, 146, 153, 161, 168, 175, 182, -190, 197, 204, 212, 219, 226, 233, 241, 248, 255, 263, 270, 277, 285, -292, 299, 306, 314, 321, 328, 336, 343, 350, 358, 365, 372, 379, 387, -394, 401, 409, 416, 423, 430, 438, 445, 452, 460, 467, 474, 482, 489, -496, 503, 511, 518, 525, 533, 540, 547, 554, 562, 569, 576, 584, 591, -598, 606, 613, 620, 627, 635, 642, 649, 657, 664, 671, 679, 686, 693, -700, 708, 715, 722, 730, 737, 744, 751, 759, 766, 773, 781, 788, 795, -803, 810, 817, 824, 832, 839, 846, 854, 861, 868, 876, 883, 890, 897, -905, 912, 919, 927, 934, 941, 948, 956, 963, 970, 978, 985, 992, 1000, -1007, 1014, 1021, 1029, 1036, 1043, 1051, 1058, 1065, 1073, 1080, -1087, 1094, 1102, 1109, 1116, 1124, 1131, 1138, 1145, 1153, 1160, -1167, 1175, 1182, 1189, 1197, 1204, 1211, 1218, 1226, 1233, 1240, -1248, 1255, 1262, 1270, 1277, 1284, 1291, 1299, 1306, 1313, 1321, -1328, 1335, 1342, 1350, 1357, 1364, 1372, 1379, 1386, 1394, 1401, -1408, 1415, 1423, 1430, 1437, 1445, 1452, 1459, 1466, 1474, 1481, -1488, 1496, 1503, 1510, 1518, 1525, 1532, 1539, 1547, 1554, 1561, -1569, 1576, 1583, 1591, 1598, 1605, 1612, 1620, 1627, 1634, 1642, -1649, 1656, 1663, 1671, 1678, 1685, 1693, 1700, 1707, 1715, 1722, -1729, 1736, 1744, 1751, 1758, 1766, 1773, 1780, 1788, 1795, 1802, -1809, 1817, 1824, 1831, 1839, 1846, 1853, 1860 }; - -static INT16 Cb_R[] = { 0, -10, -21, -31, -42, -53, -64, -75, -85, --96, -107, -118, -129, -139, -150, -161, -172, -183, -193, -204, -215, --226, -237, -247, -258, -269, -280, -291, -301, -312, -323, -334, --345, -355, -366, -377, -388, -399, -409, -420, -431, -442, -453, --463, -474, -485, -496, -507, -517, -528, -539, -550, -561, -571, --582, -593, -604, -615, -625, -636, -647, -658, -669, -679, -690, --701, -712, -723, -733, -744, -755, -766, -777, -787, -798, -809, --820, -831, -841, -852, -863, -874, -885, -895, -906, -917, -928, --939, -949, -960, -971, -982, -993, -1003, -1014, -1025, -1036, -1047, --1057, -1068, -1079, -1090, -1101, -1111, -1122, -1133, -1144, -1155, --1165, -1176, -1187, -1198, -1209, -1219, -1230, -1241, -1252, -1263, --1273, -1284, -1295, -1306, -1317, -1327, -1338, -1349, -1360, -1371, --1381, -1392, -1403, -1414, -1425, -1435, -1446, -1457, -1468, -1479, --1489, -1500, -1511, -1522, -1533, -1543, -1554, -1565, -1576, -1587, --1597, -1608, -1619, -1630, -1641, -1651, -1662, -1673, -1684, -1694, --1705, -1716, -1727, -1738, -1748, -1759, -1770, -1781, -1792, -1802, --1813, -1824, -1835, -1846, -1856, -1867, -1878, -1889, -1900, -1910, --1921, -1932, -1943, -1954, -1964, -1975, -1986, -1997, -2008, -2018, --2029, -2040, -2051, -2062, -2072, -2083, -2094, -2105, -2116, -2126, --2137, -2148, -2159, -2170, -2180, -2191, -2202, -2213, -2224, -2234, --2245, -2256, -2267, -2278, -2288, -2299, -2310, -2321, -2332, -2342, --2353, -2364, -2375, -2386, -2396, -2407, -2418, -2429, -2440, -2450, --2461, -2472, -2483, -2494, -2504, -2515, -2526, -2537, -2548, -2558, --2569, -2580, -2591, -2602, -2612, -2623, -2634, -2645, -2656, -2666, --2677, -2688, -2699, -2710, -2720, -2731, -2742, -2753 }; - -static INT16 Cb_G[] = { 0, -20, -41, -63, -84, -105, -126, -147, -169, --190, -211, -232, -253, -275, -296, -317, -338, -359, -381, -402, --423, -444, -465, -487, -508, -529, -550, -571, -593, -614, -635, --656, -677, -699, -720, -741, -762, -783, -805, -826, -847, -868, --889, -911, -932, -953, -974, -995, -1017, -1038, -1059, -1080, -1101, --1123, -1144, -1165, -1186, -1207, -1229, -1250, -1271, -1292, -1313, --1335, -1356, -1377, -1398, -1419, -1441, -1462, -1483, -1504, -1525, --1547, -1568, -1589, -1610, -1631, -1653, -1674, -1695, -1716, -1737, --1759, -1780, -1801, -1822, -1843, -1865, -1886, -1907, -1928, -1949, --1971, -1992, -2013, -2034, -2055, -2077, -2098, -2119, -2140, -2161, --2183, -2204, -2225, -2246, -2267, -2289, -2310, -2331, -2352, -2373, --2395, -2416, -2437, -2458, -2479, -2501, -2522, -2543, -2564, -2585, --2607, -2628, -2649, -2670, -2691, -2713, -2734, -2755, -2776, -2797, --2819, -2840, -2861, -2882, -2903, -2925, -2946, -2967, -2988, -3009, --3031, -3052, -3073, -3094, -3115, -3137, -3158, -3179, -3200, -3221, --3243, -3264, -3285, -3306, -3328, -3349, -3370, -3391, -3412, -3434, --3455, -3476, -3497, -3518, -3540, -3561, -3582, -3603, -3624, -3646, --3667, -3688, -3709, -3730, -3752, -3773, -3794, -3815, -3836, -3858, --3879, -3900, -3921, -3942, -3964, -3985, -4006, -4027, -4048, -4070, --4091, -4112, -4133, -4154, -4176, -4197, -4218, -4239, -4260, -4282, --4303, -4324, -4345, -4366, -4388, -4409, -4430, -4451, -4472, -4494, --4515, -4536, -4557, -4578, -4600, -4621, -4642, -4663, -4684, -4706, --4727, -4748, -4769, -4790, -4812, -4833, -4854, -4875, -4896, -4918, --4939, -4960, -4981, -5002, -5024, -5045, -5066, -5087, -5108, -5130, --5151, -5172, -5193, -5214, -5236, -5257, -5278, -5299, -5320, -5342, --5363, -5384, -5405 }; - -static INT16 Cb_B[] = { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, -320, 352, 384, 416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736, -768, 800, 832, 864, 896, 928, 960, 992, 1024, 1056, 1088, 1120, 1152, -1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504, -1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856, -1888, 1920, 1952, 1984, 2016, 2048, 2080, 2112, 2144, 2176, 2208, -2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464, 2496, 2528, 2560, -2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848, 2880, 2912, -2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232, 3264, -3296, 3328, 3360, 3392, 3424, 3456, 3488, 3520, 3552, 3584, 3616, -3648, 3680, 3712, 3744, 3776, 3808, 3840, 3872, 3904, 3936, 3968, -4000, 4032, 4064, 4096, 4128, 4160, 4192, 4224, 4256, 4288, 4320, -4352, 4384, 4416, 4448, 4480, 4512, 4544, 4576, 4608, 4640, 4672, -4704, 4736, 4768, 4800, 4832, 4864, 4896, 4928, 4960, 4992, 5024, -5056, 5088, 5120, 5152, 5184, 5216, 5248, 5280, 5312, 5344, 5376, -5408, 5440, 5472, 5504, 5536, 5568, 5600, 5632, 5664, 5696, 5728, -5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, -6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, -6464, 6496, 6528, 6560, 6592, 6624, 6656, 6688, 6720, 6752, 6784, -6816, 6848, 6880, 6912, 6944, 6976, 7008, 7040, 7072, 7104, 7136, -7168, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488, -7520, 7552, 7584, 7616, 7648, 7680, 7712, 7744, 7776, 7808, 7840, -7872, 7904, 7936, 7968, 8000, 8032, 8064, 8096, 8128, 8160 }; - -#define Cr_R Cb_B - -static INT16 Cr_G[] = { 0, -26, -53, -79, -106, -133, -160, -187, --213, -240, -267, -294, -321, -347, -374, -401, -428, -455, -481, --508, -535, -562, -589, -615, -642, -669, -696, -722, -749, -776, --803, -830, -856, -883, -910, -937, -964, -990, -1017, -1044, -1071, --1098, -1124, -1151, -1178, -1205, -1232, -1258, -1285, -1312, -1339, --1366, -1392, -1419, -1446, -1473, -1500, -1526, -1553, -1580, -1607, --1634, -1660, -1687, -1714, -1741, -1768, -1794, -1821, -1848, -1875, --1902, -1928, -1955, -1982, -2009, -2036, -2062, -2089, -2116, -2143, --2169, -2196, -2223, -2250, -2277, -2303, -2330, -2357, -2384, -2411, --2437, -2464, -2491, -2518, -2545, -2571, -2598, -2625, -2652, -2679, --2705, -2732, -2759, -2786, -2813, -2839, -2866, -2893, -2920, -2947, --2973, -3000, -3027, -3054, -3081, -3107, -3134, -3161, -3188, -3215, --3241, -3268, -3295, -3322, -3349, -3375, -3402, -3429, -3456, -3483, --3509, -3536, -3563, -3590, -3616, -3643, -3670, -3697, -3724, -3750, --3777, -3804, -3831, -3858, -3884, -3911, -3938, -3965, -3992, -4018, --4045, -4072, -4099, -4126, -4152, -4179, -4206, -4233, -4260, -4286, --4313, -4340, -4367, -4394, -4420, -4447, -4474, -4501, -4528, -4554, --4581, -4608, -4635, -4662, -4688, -4715, -4742, -4769, -4796, -4822, --4849, -4876, -4903, -4929, -4956, -4983, -5010, -5037, -5063, -5090, --5117, -5144, -5171, -5197, -5224, -5251, -5278, -5305, -5331, -5358, --5385, -5412, -5439, -5465, -5492, -5519, -5546, -5573, -5599, -5626, --5653, -5680, -5707, -5733, -5760, -5787, -5814, -5841, -5867, -5894, --5921, -5948, -5975, -6001, -6028, -6055, -6082, -6109, -6135, -6162, --6189, -6216, -6243, -6269, -6296, -6323, -6350, -6376, -6403, -6430, --6457, -6484, -6510, -6537, -6564, -6591, -6618, -6644, -6671, -6698, --6725, -6752, -6778, -6805, -6832 }; - -static INT16 Cr_B[] = { 0, -4, -9, -15, -20, -25, -30, -35, -41, -46, --51, -56, -61, -67, -72, -77, -82, -87, -93, -98, -103, -108, -113, --119, -124, -129, -134, -140, -145, -150, -155, -160, -166, -171, --176, -181, -186, -192, -197, -202, -207, -212, -218, -223, -228, --233, -238, -244, -249, -254, -259, -264, -270, -275, -280, -285, --290, -296, -301, -306, -311, -316, -322, -327, -332, -337, -342, --348, -353, -358, -363, -368, -374, -379, -384, -389, -394, -400, --405, -410, -415, -421, -426, -431, -436, -441, -447, -452, -457, --462, -467, -473, -478, -483, -488, -493, -499, -504, -509, -514, --519, -525, -530, -535, -540, -545, -551, -556, -561, -566, -571, --577, -582, -587, -592, -597, -603, -608, -613, -618, -623, -629, --634, -639, -644, -649, -655, -660, -665, -670, -675, -681, -686, --691, -696, -702, -707, -712, -717, -722, -728, -733, -738, -743, --748, -754, -759, -764, -769, -774, -780, -785, -790, -795, -800, --806, -811, -816, -821, -826, -832, -837, -842, -847, -852, -858, --863, -868, -873, -878, -884, -889, -894, -899, -904, -910, -915, --920, -925, -930, -936, -941, -946, -951, -957, -962, -967, -972, --977, -983, -988, -993, -998, -1003, -1009, -1014, -1019, -1024, --1029, -1035, -1040, -1045, -1050, -1055, -1061, -1066, -1071, -1076, --1081, -1087, -1092, -1097, -1102, -1107, -1113, -1118, -1123, -1128, --1133, -1139, -1144, -1149, -1154, -1159, -1165, -1170, -1175, -1180, --1185, -1191, -1196, -1201, -1206, -1211, -1217, -1222, -1227, -1232, --1238, -1243, -1248, -1253, -1258, -1264, -1269, -1274, -1279, -1284, --1290, -1295, -1300, -1305, -1310, -1316, -1321, -1326 }; - -static INT16 R_Cr[] = { -11484, -11394, -11305, -11215, -11125, --11036, -10946, -10856, -10766, -10677, -10587, -10497, -10407, --10318, -10228, -10138, -10049, -9959, -9869, -9779, -9690, -9600, --9510, -9420, -9331, -9241, -9151, -9062, -8972, -8882, -8792, -8703, --8613, -8523, -8433, -8344, -8254, -8164, -8075, -7985, -7895, -7805, --7716, -7626, -7536, -7446, -7357, -7267, -7177, -7088, -6998, -6908, --6818, -6729, -6639, -6549, -6459, -6370, -6280, -6190, -6101, -6011, --5921, -5831, -5742, -5652, -5562, -5472, -5383, -5293, -5203, -5113, --5024, -4934, -4844, -4755, -4665, -4575, -4485, -4396, -4306, -4216, --4126, -4037, -3947, -3857, -3768, -3678, -3588, -3498, -3409, -3319, --3229, -3139, -3050, -2960, -2870, -2781, -2691, -2601, -2511, -2422, --2332, -2242, -2152, -2063, -1973, -1883, -1794, -1704, -1614, -1524, --1435, -1345, -1255, -1165, -1076, -986, -896, -807, -717, -627, -537, --448, -358, -268, -178, -89, 0, 90, 179, 269, 359, 449, 538, 628, 718, -808, 897, 987, 1077, 1166, 1256, 1346, 1436, 1525, 1615, 1705, 1795, -1884, 1974, 2064, 2153, 2243, 2333, 2423, 2512, 2602, 2692, 2782, -2871, 2961, 3051, 3140, 3230, 3320, 3410, 3499, 3589, 3679, 3769, -3858, 3948, 4038, 4127, 4217, 4307, 4397, 4486, 4576, 4666, 4756, -4845, 4935, 5025, 5114, 5204, 5294, 5384, 5473, 5563, 5653, 5743, -5832, 5922, 6012, 6102, 6191, 6281, 6371, 6460, 6550, 6640, 6730, -6819, 6909, 6999, 7089, 7178, 7268, 7358, 7447, 7537, 7627, 7717, -7806, 7896, 7986, 8076, 8165, 8255, 8345, 8434, 8524, 8614, 8704, -8793, 8883, 8973, 9063, 9152, 9242, 9332, 9421, 9511, 9601, 9691, -9780, 9870, 9960, 10050, 10139, 10229, 10319, 10408, 10498, 10588, -10678, 10767, 10857, 10947, 11037, 11126, 11216, 11306, 11395 }; - -static INT16 G_Cb[] = { 2819, 2797, 2775, 2753, 2731, 2709, 2687, -2665, 2643, 2621, 2599, 2577, 2555, 2533, 2511, 2489, 2467, 2445, -2423, 2401, 2379, 2357, 2335, 2313, 2291, 2269, 2247, 2225, 2202, -2180, 2158, 2136, 2114, 2092, 2070, 2048, 2026, 2004, 1982, 1960, -1938, 1916, 1894, 1872, 1850, 1828, 1806, 1784, 1762, 1740, 1718, -1696, 1674, 1652, 1630, 1608, 1586, 1564, 1542, 1520, 1498, 1476, -1454, 1432, 1410, 1388, 1366, 1344, 1321, 1299, 1277, 1255, 1233, -1211, 1189, 1167, 1145, 1123, 1101, 1079, 1057, 1035, 1013, 991, 969, -947, 925, 903, 881, 859, 837, 815, 793, 771, 749, 727, 705, 683, 661, -639, 617, 595, 573, 551, 529, 507, 485, 463, 440, 418, 396, 374, 352, -330, 308, 286, 264, 242, 220, 198, 176, 154, 132, 110, 88, 66, 44, 22, -0, -21, -43, -65, -87, -109, -131, -153, -175, -197, -219, -241, -263, --285, -307, -329, -351, -373, -395, -417, -439, -462, -484, -506, --528, -550, -572, -594, -616, -638, -660, -682, -704, -726, -748, --770, -792, -814, -836, -858, -880, -902, -924, -946, -968, -990, --1012, -1034, -1056, -1078, -1100, -1122, -1144, -1166, -1188, -1210, --1232, -1254, -1276, -1298, -1320, -1343, -1365, -1387, -1409, -1431, --1453, -1475, -1497, -1519, -1541, -1563, -1585, -1607, -1629, -1651, --1673, -1695, -1717, -1739, -1761, -1783, -1805, -1827, -1849, -1871, --1893, -1915, -1937, -1959, -1981, -2003, -2025, -2047, -2069, -2091, --2113, -2135, -2157, -2179, -2201, -2224, -2246, -2268, -2290, -2312, --2334, -2356, -2378, -2400, -2422, -2444, -2466, -2488, -2510, -2532, --2554, -2576, -2598, -2620, -2642, -2664, -2686, -2708, -2730, -2752, --2774, -2796 }; - -static INT16 G_Cr[] = { 5850, 5805, 5759, 5713, 5667, 5622, 5576, -5530, 5485, 5439, 5393, 5347, 5302, 5256, 5210, 5165, 5119, 5073, -5028, 4982, 4936, 4890, 4845, 4799, 4753, 4708, 4662, 4616, 4570, -4525, 4479, 4433, 4388, 4342, 4296, 4251, 4205, 4159, 4113, 4068, -4022, 3976, 3931, 3885, 3839, 3794, 3748, 3702, 3656, 3611, 3565, -3519, 3474, 3428, 3382, 3336, 3291, 3245, 3199, 3154, 3108, 3062, -3017, 2971, 2925, 2879, 2834, 2788, 2742, 2697, 2651, 2605, 2559, -2514, 2468, 2422, 2377, 2331, 2285, 2240, 2194, 2148, 2102, 2057, -2011, 1965, 1920, 1874, 1828, 1782, 1737, 1691, 1645, 1600, 1554, -1508, 1463, 1417, 1371, 1325, 1280, 1234, 1188, 1143, 1097, 1051, -1006, 960, 914, 868, 823, 777, 731, 686, 640, 594, 548, 503, 457, 411, -366, 320, 274, 229, 183, 137, 91, 46, 0, -45, -90, -136, -182, -228, --273, -319, -365, -410, -456, -502, -547, -593, -639, -685, -730, --776, -822, -867, -913, -959, -1005, -1050, -1096, -1142, -1187, --1233, -1279, -1324, -1370, -1416, -1462, -1507, -1553, -1599, -1644, --1690, -1736, -1781, -1827, -1873, -1919, -1964, -2010, -2056, -2101, --2147, -2193, -2239, -2284, -2330, -2376, -2421, -2467, -2513, -2558, --2604, -2650, -2696, -2741, -2787, -2833, -2878, -2924, -2970, -3016, --3061, -3107, -3153, -3198, -3244, -3290, -3335, -3381, -3427, -3473, --3518, -3564, -3610, -3655, -3701, -3747, -3793, -3838, -3884, -3930, --3975, -4021, -4067, -4112, -4158, -4204, -4250, -4295, -4341, -4387, --4432, -4478, -4524, -4569, -4615, -4661, -4707, -4752, -4798, -4844, --4889, -4935, -4981, -5027, -5072, -5118, -5164, -5209, -5255, -5301, --5346, -5392, -5438, -5484, -5529, -5575, -5621, -5666, -5712, -5758, --5804 }; - -static INT16 B_Cb[] = { -14515, -14402, -14288, -14175, -14062, --13948, -13835, -13721, -13608, -13495, -13381, -13268, -13154, --13041, -12928, -12814, -12701, -12587, -12474, -12360, -12247, --12134, -12020, -11907, -11793, -11680, -11567, -11453, -11340, --11226, -11113, -11000, -10886, -10773, -10659, -10546, -10433, --10319, -10206, -10092, -9979, -9865, -9752, -9639, -9525, -9412, --9298, -9185, -9072, -8958, -8845, -8731, -8618, -8505, -8391, -8278, --8164, -8051, -7938, -7824, -7711, -7597, -7484, -7371, -7257, -7144, --7030, -6917, -6803, -6690, -6577, -6463, -6350, -6236, -6123, -6010, --5896, -5783, -5669, -5556, -5443, -5329, -5216, -5102, -4989, -4876, --4762, -4649, -4535, -4422, -4309, -4195, -4082, -3968, -3855, -3741, --3628, -3515, -3401, -3288, -3174, -3061, -2948, -2834, -2721, -2607, --2494, -2381, -2267, -2154, -2040, -1927, -1814, -1700, -1587, -1473, --1360, -1246, -1133, -1020, -906, -793, -679, -566, -453, -339, -226, --112, 0, 113, 227, 340, 454, 567, 680, 794, 907, 1021, 1134, 1247, -1361, 1474, 1588, 1701, 1815, 1928, 2041, 2155, 2268, 2382, 2495, -2608, 2722, 2835, 2949, 3062, 3175, 3289, 3402, 3516, 3629, 3742, -3856, 3969, 4083, 4196, 4310, 4423, 4536, 4650, 4763, 4877, 4990, -5103, 5217, 5330, 5444, 5557, 5670, 5784, 5897, 6011, 6124, 6237, -6351, 6464, 6578, 6691, 6804, 6918, 7031, 7145, 7258, 7372, 7485, -7598, 7712, 7825, 7939, 8052, 8165, 8279, 8392, 8506, 8619, 8732, -8846, 8959, 9073, 9186, 9299, 9413, 9526, 9640, 9753, 9866, 9980, -10093, 10207, 10320, 10434, 10547, 10660, 10774, 10887, 11001, 11114, -11227, 11341, 11454, 11568, 11681, 11794, 11908, 12021, 12135, 12248, -12361, 12475, 12588, 12702, 12815, 12929, 13042, 13155, 13269, 13382, -13496, 13609, 13722, 13836, 13949, 14063, 14176, 14289, 14403 }; - - -void -ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels) -{ - int x; - UINT8 a; - int r, g, b; - int y, cr, cb; - - for (x = 0; x < pixels; x++, in +=4, out += 4) { - - r = in[0]; - g = in[1]; - b = in[2]; - a = in[3]; - - y = (Y_R[r] + Y_G[g] + Y_B[b]) >> SCALE; - cb = ((Cb_R[r] + Cb_G[g] + Cb_B[b]) >> SCALE) + 128; - cr = ((Cr_R[r] + Cr_G[g] + Cr_B[b]) >> SCALE) + 128; - - out[0] = (UINT8) y; - out[1] = (UINT8) cb; - out[2] = (UINT8) cr; - out[3] = a; - } -} - -void -ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels) -{ - int x; - UINT8 a; - int r, g, b; - int y, cr, cb; - - for (x = 0; x < pixels; x++, in += 4, out += 4) { - - y = in[0]; - cb = in[1]; - cr = in[2]; - a = in[3]; - - r = y + (( R_Cr[cr]) >> SCALE); - g = y + ((G_Cb[cb] + G_Cr[cr]) >> SCALE); - b = y + ((B_Cb[cb] ) >> SCALE); - - out[0] = (r <= 0) ? 0 : (r >= 255) ? 255 : r; - out[1] = (g <= 0) ? 0 : (g >= 255) ? 255 : g; - out[2] = (b <= 0) ? 0 : (b >= 255) ? 255 : b; - out[3] = a; - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c deleted file mode 100755 index 4a1fc248974..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Copy.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * copy image - * - * history: - * 95-11-26 fl Moved from Imaging.c - * 97-05-12 fl Added ImagingCopy2 - * 97-08-28 fl Allow imOut == NULL in ImagingCopy2 - * - * Copyright (c) Fredrik Lundh 1995-97. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - - -static Imaging -_copy(Imaging imOut, Imaging imIn) -{ - ImagingSectionCookie cookie; - int y; - - if (!imIn) - return (Imaging) ImagingError_ValueError(NULL); - - imOut = ImagingNew2(imIn->mode, imOut, imIn); - if (!imOut) - return NULL; - - ImagingCopyInfo(imOut, imIn); - - ImagingSectionEnter(&cookie); - if (imIn->block != NULL && imOut->block != NULL) - memcpy(imOut->block, imIn->block, imIn->ysize * imIn->linesize); - else - for (y = 0; y < imIn->ysize; y++) - memcpy(imOut->image[y], imIn->image[y], imIn->linesize); - ImagingSectionLeave(&cookie); - - return imOut; -} - -Imaging -ImagingCopy(Imaging imIn) -{ - return _copy(NULL, imIn); -} - -Imaging -ImagingCopy2(Imaging imOut, Imaging imIn) -{ - return _copy(imOut, imIn); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c deleted file mode 100755 index d83d0fbacb0..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crc32.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * calculate ISO 3307 checksum - * - * history: - * 96-12-10 fl: Created (based on example in the PNG spec) - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -/* Precalculated CRC values (created by makecrctable.py) */ - -static UINT32 crc32table[] = { 0x0, 0x77073096L, 0xEE0E612CL, -0x990951BAL, 0x76DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, -0xEDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 0x9B64C2BL, -0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, -0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, -0x83D385C7L, 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, -0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L, -0x4C69105EL, 0xD56041E4L, 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, -0xD20D85FDL, 0xA50AB56BL, 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, -0xACBCF940L, 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, -0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, 0x21B4F4B5L, -0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, 0x2802B89EL, 0x5F058808L, -0xC60CD9B2L, 0xB10BE924L, 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, -0xB6662D3DL, 0x76DC4190L, 0x1DB7106L, 0x98D220BCL, 0xEFD5102AL, -0x71B18589L, 0x6B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, 0x7807C9A2L, -0xF00F934L, 0x9609A88EL, 0xE10E9818L, 0x7F6A0DBBL, 0x86D3D2DL, -0x91646C97L, 0xE6635C01L, 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, -0xF262004EL, 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, -0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL, -0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, 0x4DB26158L, 0x3AB551CEL, -0xA3BC0074L, 0xD4BB30E2L, 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, -0xD3D6F4FBL, 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, -0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, 0x5005713CL, -0x270241AAL, 0xBE0B1010L, 0xC90C2086L, 0x5768B525L, 0x206F85B3L, -0xB966D409L, 0xCE61E49FL, 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, -0xC7D7A8B4L, 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, -0xEDB88320L, 0x9ABFB3B6L, 0x3B6E20CL, 0x74B1D29AL, 0xEAD54739L, -0x9DD277AFL, 0x4DB2615L, 0x73DC1683L, 0xE3630B12L, 0x94643B84L, -0xD6D6A3EL, 0x7A6A5AA8L, 0xE40ECF0BL, 0x9309FF9DL, 0xA00AE27L, -0x7D079EB1L, 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, -0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, 0xFED41B76L, -0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, 0xF9B9DF6FL, 0x8EBEEFF9L, -0x17B7BE43L, 0x60B08ED5L, 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, -0x4FDFF252L, 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, -0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, 0xDF60EFC3L, -0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, 0xCB61B38CL, 0xBC66831AL, -0x256FD2A0L, 0x5268E236L, 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, -0x5505262FL, 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, -0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, 0x9B64C2B0L, -0xEC63F226L, 0x756AA39CL, 0x26D930AL, 0x9C0906A9L, 0xEB0E363FL, -0x72076785L, 0x5005713L, 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, -0xCB61B38L, 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0xBDBDF21L, -0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL, -0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, 0x88085AE6L, 0xFF0F6A70L, -0x66063BCAL, 0x11010B5CL, 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, -0x166CCF45L, 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, -0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, 0xAED16A4AL, -0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, 0xA9BCAE53L, 0xDEBB9EC5L, -0x47B2CF7FL, 0x30B5FFE9L, 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, -0x24B4A3A6L, 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, -0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, -0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL }; - - -UINT32 -ImagingCRC32(UINT32 crc, UINT8* buffer, int bytes) -{ - int i; - - crc ^= 0xFFFFFFFFL; - - for (i = 0; i < bytes; i++) - crc = crc32table[(UINT8) crc ^ buffer[i]] ^ (crc >> 8); - - return crc ^ 0xFFFFFFFFL; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c deleted file mode 100755 index 5acacd4c47c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Crop.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * cut region from image - * - * history: - * 95-11-27 fl Created - * 98-07-10 fl Fixed "null result" error - * 99-02-05 fl Rewritten to use Paste primitive - * - * Copyright (c) Secret Labs AB 1997-99. - * Copyright (c) Fredrik Lundh 1995. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -Imaging -ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1) -{ - Imaging imOut; - int xsize, ysize; - int dx0, dy0, dx1, dy1; - INT32 zero = 0; - - if (!imIn) - return (Imaging) ImagingError_ModeError(); - - xsize = sx1 - sx0; - if (xsize < 0) - xsize = 0; - ysize = sy1 - sy0; - if (ysize < 0) - ysize = 0; - - imOut = ImagingNew(imIn->mode, xsize, ysize); - if (!imOut) - return NULL; - - ImagingCopyInfo(imOut, imIn); - - if (sx0 < 0 || sy0 < 0 || sx1 > imIn->xsize || sy1 > imIn->ysize) - (void) ImagingFill(imOut, &zero); - - dx0 = -sx0; - dy0 = -sy0; - dx1 = imIn->xsize - sx0; - dy1 = imIn->ysize - sy0; - - /* paste the source image on top of the output image!!! */ - if (ImagingPaste(imOut, imIn, NULL, dx0, dy0, dx1, dy1) < 0) { - ImagingDelete(imOut); - return NULL; - } - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c deleted file mode 100755 index 36dc24ef3ac..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Dib.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * imaging display object for Windows - * - * history: - * 1996-05-12 fl Created - * 1996-05-17 fl Up and running - * 1996-05-21 fl Added palette stuff - * 1996-05-26 fl Added query palette and mode inquery - * 1997-09-21 fl Added draw primitive - * 1998-01-20 fl Use StretchDIBits instead of StretchBlt - * 1998-12-30 fl Plugged a resource leak in DeleteDIB (from Roger Burnham) - * - * Copyright (c) Secret Labs AB 1997-2001. - * Copyright (c) Fredrik Lundh 1996. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#ifdef WIN32 - -#include "ImDib.h" - - -char* -ImagingGetModeDIB(int size_out[2]) -{ - /* Get device characteristics */ - - HDC dc; - char* mode; - - dc = CreateCompatibleDC(NULL); - - mode = "P"; - if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) { - mode = "RGB"; - if (GetDeviceCaps(dc, BITSPIXEL) == 1) - mode = "1"; - } - - if (size_out) { - size_out[0] = GetDeviceCaps(dc, HORZRES); - size_out[1] = GetDeviceCaps(dc, VERTRES); - } - - DeleteDC(dc); - - return mode; -} - - -ImagingDIB -ImagingNewDIB(const char *mode, int xsize, int ysize) -{ - /* Create a Windows bitmap */ - - ImagingDIB dib; - RGBQUAD *palette; - int i; - - /* Check mode */ - if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 && - strcmp(mode, "RGB") != 0) - return (ImagingDIB) ImagingError_ModeError(); - - /* Create DIB context and info header */ - dib = (ImagingDIB) malloc(sizeof(*dib)); - if (!dib) - return (ImagingDIB) ImagingError_MemoryError(); - dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + - 256 * sizeof(RGBQUAD)); - if (!dib->info) { - free(dib); - return (ImagingDIB) ImagingError_MemoryError(); - } - - memset(dib->info, 0, sizeof(BITMAPINFOHEADER)); - dib->info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - dib->info->bmiHeader.biWidth = xsize; - dib->info->bmiHeader.biHeight = ysize; - dib->info->bmiHeader.biPlanes = 1; - dib->info->bmiHeader.biBitCount = strlen(mode)*8; - dib->info->bmiHeader.biCompression = BI_RGB; - - /* Create DIB */ - dib->dc = CreateCompatibleDC(NULL); - if (!dib->dc) { - free(dib->info); - free(dib); - return (ImagingDIB) ImagingError_MemoryError(); - } - - dib->bitmap = CreateDIBSection(dib->dc, dib->info, DIB_RGB_COLORS, - &dib->bits, NULL, 0); - if (!dib->bitmap) { - free(dib->info); - free(dib); - return (ImagingDIB) ImagingError_MemoryError(); - } - - strcpy(dib->mode, mode); - dib->xsize = xsize; - dib->ysize = ysize; - - dib->pixelsize = strlen(mode); - dib->linesize = (xsize * dib->pixelsize + 3) & -4; - - if (dib->pixelsize == 1) - dib->pack = dib->unpack = (ImagingShuffler) memcpy; - else { - dib->pack = ImagingPackBGR; - dib->unpack = ImagingPackBGR; - } - - /* Bind the DIB to the device context */ - dib->old_bitmap = SelectObject(dib->dc, dib->bitmap); - - palette = dib->info->bmiColors; - - /* Bind a palette to it as well (only required for 8-bit DIBs) */ - if (dib->pixelsize == 1) { - for (i = 0; i < 256; i++) { - palette[i].rgbRed = - palette[i].rgbGreen = - palette[i].rgbBlue = i; - palette[i].rgbReserved = 0; - } - SetDIBColorTable(dib->dc, 0, 256, palette); - } - - /* Create an associated palette (for 8-bit displays only) */ - if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) { - - char palbuf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)]; - LPLOGPALETTE pal = (LPLOGPALETTE) palbuf; - int i, r, g, b; - - /* Load system palette */ - pal->palVersion = 0x300; - pal->palNumEntries = 256; - GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry); - - if (strcmp(mode, "L") == 0) { - - /* Greyscale DIB. Fill all 236 slots with a greyscale ramp - * (this is usually overkill on Windows since VGA only offers - * 6 bits greyscale resolution). Ignore the slots already - * allocated by Windows */ - - i = 10; - for (r = 0; r < 236; r++) { - pal->palPalEntry[i].peRed = - pal->palPalEntry[i].peGreen = - pal->palPalEntry[i].peBlue = i; - i++; - } - - dib->palette = CreatePalette(pal); - - } else if (strcmp(mode, "RGB") == 0) { - -#ifdef CUBE216 - - /* Colour DIB. Create a 6x6x6 colour cube (216 entries) and - * add 20 extra greylevels for best result with greyscale - * images. */ - - i = 10; - for (r = 0; r < 256; r += 51) - for (g = 0; g < 256; g += 51) - for (b = 0; b < 256; b += 51) { - pal->palPalEntry[i].peRed = r; - pal->palPalEntry[i].peGreen = g; - pal->palPalEntry[i].peBlue = b; - i++; - } - for (r = 1; r < 22-1; r++) { - /* Black and white are already provided by the cube. */ - pal->palPalEntry[i].peRed = - pal->palPalEntry[i].peGreen = - pal->palPalEntry[i].peBlue = r * 255 / (22-1); - i++; - } - -#else - - /* Colour DIB. Alternate palette. */ - - i = 10; - for (r = 0; r < 256; r += 37) - for (g = 0; g < 256; g += 32) - for (b = 0; b < 256; b += 64) { - pal->palPalEntry[i].peRed = r; - pal->palPalEntry[i].peGreen = g; - pal->palPalEntry[i].peBlue = b; - i++; - } - -#endif - -#if 0 - { - /* DEBUG: dump palette to file */ - FILE *err = fopen("dib.pal", "w"); - for (i = 0; i < 256; i++) - fprintf(err, "%d: %d/%d/%d\n", i, - pal->palPalEntry[i].peRed, - pal->palPalEntry[i].peGreen, - pal->palPalEntry[i].peBlue); - fclose(err); - } -#endif - - dib->palette = CreatePalette(pal); - - } - - } - - return dib; -} - -void -ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]) -{ - /* Paste image data into a bitmap */ - - /* FIXME: check size! */ - - int y; - for (y = 0; y < im->ysize; y++) - dib->pack(dib->bits + dib->linesize*(dib->ysize-(xy[1]+y)-1) + - xy[0]*dib->pixelsize, im->image[y], im->xsize); - -} - -void -ImagingExposeDIB(ImagingDIB dib, int dc) -{ - /* Copy bitmap to display */ - - if (dib->palette != 0) - SelectPalette((HDC) dc, dib->palette, FALSE); - BitBlt((HDC) dc, 0, 0, dib->xsize, dib->ysize, dib->dc, 0, 0, SRCCOPY); -} - -void -ImagingDrawDIB(ImagingDIB dib, int dc, int dst[4], int src[4]) -{ - /* Copy bitmap to printer/display */ - - if (GetDeviceCaps((HDC) dc, RASTERCAPS) & RC_STRETCHDIB) { - /* stretchdib (printers) */ - StretchDIBits((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1], - src[0], src[1], src[2]-src[0], src[3]-src[1], dib->bits, - dib->info, DIB_RGB_COLORS, SRCCOPY); - } else { - /* stretchblt (displays) */ - if (dib->palette != 0) - SelectPalette((HDC) dc, dib->palette, FALSE); - StretchBlt((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1], - dib->dc, src[0], src[1], src[2]-src[0], src[3]-src[1], - SRCCOPY); - } -} - -int -ImagingQueryPaletteDIB(ImagingDIB dib, int dc) -{ - /* Install bitmap palette */ - - int n; - - if (dib->palette != 0) { - - /* Realize associated palette */ - HPALETTE now = SelectPalette((HDC) dc, dib->palette, FALSE); - n = RealizePalette((HDC) dc); - - /* Restore palette */ - SelectPalette((HDC) dc, now, FALSE); - - } else - n = 0; - - return n; /* number of colours that was changed */ -} - -void -ImagingDeleteDIB(ImagingDIB dib) -{ - /* Clean up */ - - if (dib->palette) - DeleteObject(dib->palette); - if (dib->bitmap) { - SelectObject(dib->dc, dib->old_bitmap); - DeleteObject(dib->bitmap); - } - if (dib->dc) - DeleteDC(dib->dc); - free(dib->info); -} - -#endif /* WIN32 */ diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c deleted file mode 100755 index bdf17e18aa6..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Draw.c +++ /dev/null @@ -1,1167 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * a simple drawing package for the Imaging library - * - * history: - * 1996-04-13 fl Created. - * 1996-04-30 fl Added transforms and polygon support. - * 1996-08-12 fl Added filled polygons. - * 1996-11-05 fl Fixed float/int confusion in polygon filler - * 1997-07-04 fl Support 32-bit images (C++ would have been nice) - * 1998-09-09 fl Eliminated qsort casts; improved rectangle clipping - * 1998-09-10 fl Fixed fill rectangle to include lower edge (!) - * 1998-12-29 fl Added arc, chord, and pieslice primitives - * 1999-01-10 fl Added some level 2 ("arrow") stuff (experimental) - * 1999-02-06 fl Added bitmap primitive - * 1999-07-26 fl Eliminated a compiler warning - * 1999-07-31 fl Pass ink as void* instead of int - * 2002-12-10 fl Added experimental RGBA-on-RGB drawing - * 2004-09-04 fl Support simple wide lines (no joins) - * 2005-05-25 fl Fixed line width calculation - * - * Copyright (c) 1996-2006 by Fredrik Lundh - * Copyright (c) 1997-2006 by Secret Labs AB. - * - * See the README file for information on usage and redistribution. - */ - -/* FIXME: support fill/outline attribute for all filled shapes */ -/* FIXME: support zero-winding fill */ -/* FIXME: add drawing context, support affine transforms */ -/* FIXME: support clip window (and mask?) */ - -#include "Imaging.h" - -#include - -#define CEIL(v) (int) ceil(v) -#define FLOOR(v) ((v) >= 0.0 ? (int) (v) : (int) floor(v)) - -#define INK8(ink) (*(UINT8*)ink) -#define INK32(ink) (*(INT32*)ink) - -/* like (a * b + 127) / 255), but much faster on most platforms */ -#define MULDIV255(a, b, tmp)\ - (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) - -#define BLEND(mask, in1, in2, tmp1, tmp2)\ - (MULDIV255(in1, 255 - mask, tmp1) + MULDIV255(in2, mask, tmp2)) - -/* -------------------------------------------------------------------- */ -/* Primitives */ -/* -------------------------------------------------------------------- */ - -typedef struct { - /* edge descriptor for polygon engine */ - int d; - int x0, y0; - int xmin, ymin, xmax, ymax; - float dx; -} Edge; - -static inline void -point8(Imaging im, int x, int y, int ink) -{ - if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) - im->image8[y][x] = (UINT8) ink; -} - -static inline void -point32(Imaging im, int x, int y, int ink) -{ - if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) - im->image32[y][x] = ink; -} - -static inline void -point32rgba(Imaging im, int x, int y, int ink) -{ - unsigned int tmp1, tmp2; - - if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) { - UINT8* out = (UINT8*) im->image[y]+x*4; - UINT8* in = (UINT8*) &ink; - out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2); - out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2); - out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2); - } -} - -static inline void -hline8(Imaging im, int x0, int y0, int x1, int ink) -{ - int tmp; - - if (y0 >= 0 && y0 < im->ysize) { - if (x0 > x1) - tmp = x0, x0 = x1, x1 = tmp; - if (x0 < 0) - x0 = 0; - else if (x0 >= im->xsize) - return; - if (x1 < 0) - return; - else if (x1 >= im->xsize) - x1 = im->xsize-1; - if (x0 <= x1) - memset(im->image8[y0] + x0, (UINT8) ink, x1 - x0 + 1); - } -} - -static inline void -hline32(Imaging im, int x0, int y0, int x1, int ink) -{ - int tmp; - INT32* p; - - if (y0 >= 0 && y0 < im->ysize) { - if (x0 > x1) - tmp = x0, x0 = x1, x1 = tmp; - if (x0 < 0) - x0 = 0; - else if (x0 >= im->xsize) - return; - if (x1 < 0) - return; - else if (x1 >= im->xsize) - x1 = im->xsize-1; - p = im->image32[y0]; - while (x0 <= x1) - p[x0++] = ink; - } -} - -static inline void -hline32rgba(Imaging im, int x0, int y0, int x1, int ink) -{ - int tmp; - unsigned int tmp1, tmp2; - - if (y0 >= 0 && y0 < im->ysize) { - if (x0 > x1) - tmp = x0, x0 = x1, x1 = tmp; - if (x0 < 0) - x0 = 0; - else if (x0 >= im->xsize) - return; - if (x1 < 0) - return; - else if (x1 >= im->xsize) - x1 = im->xsize-1; - if (x0 <= x1) { - UINT8* out = (UINT8*) im->image[y0]+x0*4; - UINT8* in = (UINT8*) &ink; - while (x0 <= x1) { - out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2); - out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2); - out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2); - x0++; out += 4; - } - } - } -} - -static inline void -line8(Imaging im, int x0, int y0, int x1, int y1, int ink) -{ - int i, n, e; - int dx, dy; - int xs, ys; - - /* normalize coordinates */ - dx = x1-x0; - if (dx < 0) - dx = -dx, xs = -1; - else - xs = 1; - dy = y1-y0; - if (dy < 0) - dy = -dy, ys = -1; - else - ys = 1; - - n = (dx > dy) ? dx : dy; - - if (dx == 0) - - /* vertical */ - for (i = 0; i < dy; i++) { - point8(im, x0, y0, ink); - y0 += ys; - } - - else if (dy == 0) - - /* horizontal */ - for (i = 0; i < dx; i++) { - point8(im, x0, y0, ink); - x0 += xs; - } - - else if (dx > dy) { - - /* bresenham, horizontal slope */ - n = dx; - dy += dy; - e = dy - dx; - dx += dx; - - for (i = 0; i < n; i++) { - point8(im, x0, y0, ink); - if (e >= 0) { - y0 += ys; - e -= dx; - } - e += dy; - x0 += xs; - } - - } else { - - /* bresenham, vertical slope */ - n = dy; - dx += dx; - e = dx - dy; - dy += dy; - - for (i = 0; i < n; i++) { - point8(im, x0, y0, ink); - if (e >= 0) { - x0 += xs; - e -= dy; - } - e += dx; - y0 += ys; - } - - } -} - -static inline void -line32(Imaging im, int x0, int y0, int x1, int y1, int ink) -{ - int i, n, e; - int dx, dy; - int xs, ys; - - /* normalize coordinates */ - dx = x1-x0; - if (dx < 0) - dx = -dx, xs = -1; - else - xs = 1; - dy = y1-y0; - if (dy < 0) - dy = -dy, ys = -1; - else - ys = 1; - - n = (dx > dy) ? dx : dy; - - if (dx == 0) - - /* vertical */ - for (i = 0; i < dy; i++) { - point32(im, x0, y0, ink); - y0 += ys; - } - - else if (dy == 0) - - /* horizontal */ - for (i = 0; i < dx; i++) { - point32(im, x0, y0, ink); - x0 += xs; - } - - else if (dx > dy) { - - /* bresenham, horizontal slope */ - n = dx; - dy += dy; - e = dy - dx; - dx += dx; - - for (i = 0; i < n; i++) { - point32(im, x0, y0, ink); - if (e >= 0) { - y0 += ys; - e -= dx; - } - e += dy; - x0 += xs; - } - - } else { - - /* bresenham, vertical slope */ - n = dy; - dx += dx; - e = dx - dy; - dy += dy; - - for (i = 0; i < n; i++) { - point32(im, x0, y0, ink); - if (e >= 0) { - x0 += xs; - e -= dy; - } - e += dx; - y0 += ys; - } - - } -} - -static inline void -line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) -{ - int i, n, e; - int dx, dy; - int xs, ys; - - /* normalize coordinates */ - dx = x1-x0; - if (dx < 0) - dx = -dx, xs = -1; - else - xs = 1; - dy = y1-y0; - if (dy < 0) - dy = -dy, ys = -1; - else - ys = 1; - - n = (dx > dy) ? dx : dy; - - if (dx == 0) - - /* vertical */ - for (i = 0; i < dy; i++) { - point32rgba(im, x0, y0, ink); - y0 += ys; - } - - else if (dy == 0) - - /* horizontal */ - for (i = 0; i < dx; i++) { - point32rgba(im, x0, y0, ink); - x0 += xs; - } - - else if (dx > dy) { - - /* bresenham, horizontal slope */ - n = dx; - dy += dy; - e = dy - dx; - dx += dx; - - for (i = 0; i < n; i++) { - point32rgba(im, x0, y0, ink); - if (e >= 0) { - y0 += ys; - e -= dx; - } - e += dy; - x0 += xs; - } - - } else { - - /* bresenham, vertical slope */ - n = dy; - dx += dx; - e = dx - dy; - dy += dy; - - for (i = 0; i < n; i++) { - point32rgba(im, x0, y0, ink); - if (e >= 0) { - x0 += xs; - e -= dy; - } - e += dx; - y0 += ys; - } - - } -} - -static int -x_cmp(const void *x0, const void *x1) -{ - float diff = *((float*)x0) - *((float*)x1); - if (diff < 0) - return -1; - else if (diff > 0) - return 1; - else - return 0; -} - -static inline int -polygon8(Imaging im, int n, Edge *e, int ink, int eofill) -{ - int i, j; - float *xx; - int ymin, ymax; - float y; - - if (n <= 0) - return 0; - - /* Find upper and lower polygon boundary (within image) */ - - ymin = e[0].ymin; - ymax = e[0].ymax; - for (i = 1; i < n; i++) { - if (e[i].ymin < ymin) ymin = e[i].ymin; - if (e[i].ymax > ymax) ymax = e[i].ymax; - } - - if (ymin < 0) - ymin = 0; - if (ymax >= im->ysize) - ymax = im->ysize-1; - - /* Process polygon edges */ - - xx = malloc(n * sizeof(float)); - if (!xx) - return -1; - - for (;ymin <= ymax; ymin++) { - y = ymin+0.5F; - for (i = j = 0; i < n; i++) - if (y >= e[i].ymin && y <= e[i].ymax) { - if (e[i].d == 0) - hline8(im, e[i].xmin, ymin, e[i].xmax, ink); - else - xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; - } - if (j == 2) { - if (xx[0] < xx[1]) - hline8(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); - else - hline8(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); - } else { - qsort(xx, j, sizeof(float), x_cmp); - for (i = 0; i < j-1 ; i += 2) - hline8(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); - } - } - - free(xx); - - return 0; -} - -static inline int -polygon32(Imaging im, int n, Edge *e, int ink, int eofill) -{ - int i, j; - float *xx; - int ymin, ymax; - float y; - - if (n <= 0) - return 0; - - /* Find upper and lower polygon boundary (within image) */ - - ymin = e[0].ymin; - ymax = e[0].ymax; - for (i = 1; i < n; i++) { - if (e[i].ymin < ymin) ymin = e[i].ymin; - if (e[i].ymax > ymax) ymax = e[i].ymax; - } - - if (ymin < 0) - ymin = 0; - if (ymax >= im->ysize) - ymax = im->ysize-1; - - /* Process polygon edges */ - - xx = malloc(n * sizeof(float)); - if (!xx) - return -1; - - for (;ymin <= ymax; ymin++) { - y = ymin+0.5F; - for (i = j = 0; i < n; i++) { - if (y >= e[i].ymin && y <= e[i].ymax) { - if (e[i].d == 0) - hline32(im, e[i].xmin, ymin, e[i].xmax, ink); - else - xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; - } - } - if (j == 2) { - if (xx[0] < xx[1]) - hline32(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); - else - hline32(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); - } else { - qsort(xx, j, sizeof(float), x_cmp); - for (i = 0; i < j-1 ; i += 2) - hline32(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); - } - } - - free(xx); - - return 0; -} - -static inline int -polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill) -{ - int i, j; - float *xx; - int ymin, ymax; - float y; - - if (n <= 0) - return 0; - - /* Find upper and lower polygon boundary (within image) */ - - ymin = e[0].ymin; - ymax = e[0].ymax; - for (i = 1; i < n; i++) { - if (e[i].ymin < ymin) ymin = e[i].ymin; - if (e[i].ymax > ymax) ymax = e[i].ymax; - } - - if (ymin < 0) - ymin = 0; - if (ymax >= im->ysize) - ymax = im->ysize-1; - - /* Process polygon edges */ - - xx = malloc(n * sizeof(float)); - if (!xx) - return -1; - - for (;ymin <= ymax; ymin++) { - y = ymin+0.5F; - for (i = j = 0; i < n; i++) { - if (y >= e[i].ymin && y <= e[i].ymax) { - if (e[i].d == 0) - hline32rgba(im, e[i].xmin, ymin, e[i].xmax, ink); - else - xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; - } - } - if (j == 2) { - if (xx[0] < xx[1]) - hline32rgba(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); - else - hline32rgba(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); - } else { - qsort(xx, j, sizeof(float), x_cmp); - for (i = 0; i < j-1 ; i += 2) - hline32rgba(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); - } - } - - free(xx); - - return 0; -} - -static inline void -add_edge(Edge *e, int x0, int y0, int x1, int y1) -{ - /* printf("edge %d %d %d %d\n", x0, y0, x1, y1); */ - - if (x0 <= x1) - e->xmin = x0, e->xmax = x1; - else - e->xmin = x1, e->xmax = x0; - - if (y0 <= y1) - e->ymin = y0, e->ymax = y1; - else - e->ymin = y1, e->ymax = y0; - - if (y0 == y1) { - e->d = 0; - e->dx = 0.0; - } else { - e->dx = ((float)(x1-x0)) / (y1-y0); - if (y0 == e->ymin) - e->d = 1; - else - e->d = -1; - } - - e->x0 = x0; - e->y0 = y0; -} - -typedef struct { - void (*point)(Imaging im, int x, int y, int ink); - void (*hline)(Imaging im, int x0, int y0, int x1, int ink); - void (*line)(Imaging im, int x0, int y0, int x1, int y1, int ink); - int (*polygon)(Imaging im, int n, Edge *e, int ink, int eofill); -} DRAW; - -DRAW draw8 = { point8, hline8, line8, polygon8 }; -DRAW draw32 = { point32, hline32, line32, polygon32 }; -DRAW draw32rgba = { point32rgba, hline32rgba, line32rgba, polygon32rgba }; - -/* -------------------------------------------------------------------- */ -/* Interface */ -/* -------------------------------------------------------------------- */ - -#define DRAWINIT()\ - if (im->image8) {\ - draw = &draw8;\ - ink = INK8(ink_);\ - } else {\ - draw = (op) ? &draw32rgba : &draw32; \ - ink = INK32(ink_);\ - } - -int -ImagingDrawPoint(Imaging im, int x0, int y0, const void* ink_, int op) -{ - DRAW* draw; - INT32 ink; - - DRAWINIT(); - - draw->point(im, x0, y0, ink); - - return 0; -} - -int -ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void* ink_, - int op) -{ - DRAW* draw; - INT32 ink; - - DRAWINIT(); - - draw->line(im, x0, y0, x1, y1, ink); - - return 0; -} - -int -ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1, - const void* ink_, int width, int op) -{ - DRAW* draw; - INT32 ink; - - Edge e[4]; - - int dx, dy; - double d; - - DRAWINIT(); - - if (width <= 1) { - draw->line(im, x0, y0, x1, y1, ink); - return 0; - } - - dx = x1-x0; - dy = y1-y0; - - if (dx == 0 && dy == 0) { - draw->point(im, x0, y0, ink); - return 0; - } - - d = width / sqrt((float) (dx*dx + dy*dy)) / 2.0; - - dx = (int) floor(d * (y1-y0) + 0.5); - dy = (int) floor(d * (x1-x0) + 0.5); - - add_edge(e+0, x0 - dx, y0 + dy, x1 - dx, y1 + dy); - add_edge(e+1, x1 - dx, y1 + dy, x1 + dx, y1 - dy); - add_edge(e+2, x1 + dx, y1 - dy, x0 + dx, y0 - dy); - add_edge(e+3, x0 + dx, y0 - dy, x0 - dx, y0 + dy); - - draw->polygon(im, 4, e, ink, 0); - - return 0; -} - -int -ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1, - const void* ink_, int fill, int op) -{ - int y; - int tmp; - DRAW* draw; - INT32 ink; - - DRAWINIT(); - - if (y0 > y1) - tmp = y0, y0 = y1, y1 = tmp; - - if (fill) { - - if (y0 < 0) - y0 = 0; - else if (y0 >= im->ysize) - return 0; - - if (y1 < 0) - return 0; - else if (y1 > im->ysize) - y1 = im->ysize; - - for (y = y0; y <= y1; y++) - draw->hline(im, x0, y, x1, ink); - - } else { - - /* outline */ - draw->line(im, x0, y0, x1, y0, ink); - draw->line(im, x1, y0, x1, y1, ink); - draw->line(im, x1, y1, x0, y1, ink); - draw->line(im, x0, y1, x0, y0, ink); - - } - - return 0; -} - -int -ImagingDrawPolygon(Imaging im, int count, int* xy, const void* ink_, - int fill, int op) -{ - int i, n; - DRAW* draw; - INT32 ink; - - if (count <= 0) - return 0; - - DRAWINIT(); - - if (fill) { - - /* Build edge list */ - Edge* e = malloc(count * sizeof(Edge)); - if (!e) { - (void) ImagingError_MemoryError(); - return -1; - } - for (i = n = 0; i < count-1; i++) - add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3]); - if (xy[i+i] != xy[0] || xy[i+i+1] != xy[1]) - add_edge(&e[n++], xy[i+i], xy[i+i+1], xy[0], xy[1]); - draw->polygon(im, n, e, ink, 0); - free(e); - - } else { - - /* Outline */ - for (i = 0; i < count-1; i++) - draw->line(im, xy[i+i], xy[i+i+1], xy[i+i+2], xy[i+i+3], ink); - draw->line(im, xy[i+i], xy[i+i+1], xy[0], xy[1], ink); - - } - - return 0; -} - -int -ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void* ink, - int op) -{ - return ImagingFill2( - im, ink, bitmap, - x0, y0, x0 + bitmap->xsize, y0 + bitmap->ysize - ); -} - -/* -------------------------------------------------------------------- */ -/* standard shapes */ - -#define ARC 0 -#define CHORD 1 -#define PIESLICE 2 - -static int -ellipse(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink_, int fill, - int mode, int op) -{ - int i, n; - int cx, cy; - int w, h; - int x = 0, y = 0; - int lx = 0, ly = 0; - int sx = 0, sy = 0; - DRAW* draw; - INT32 ink; - - w = x1 - x0; - h = y1 - y0; - if (w < 0 || h < 0) - return 0; - - DRAWINIT(); - - cx = (x0 + x1) / 2; - cy = (y0 + y1) / 2; - - while (end < start) - end += 360; - - if (mode != ARC && fill) { - - /* Build edge list */ - Edge* e = malloc((end - start + 3) * sizeof(Edge)); - if (!e) { - ImagingError_MemoryError(); - return -1; - } - - n = 0; - - for (i = start; i <= end; i++) { - x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5); - y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5); - if (i != start) - add_edge(&e[n++], lx, ly, x, y); - else - sx = x, sy = y; - lx = x, ly = y; - } - - if (n > 0) { - /* close and draw polygon */ - if (mode == PIESLICE) { - if (x != cx || y != cy) { - add_edge(&e[n++], x, y, cx, cy); - add_edge(&e[n++], cx, cy, sx, sy); - } - } else { - if (x != sx || y != sy) - add_edge(&e[n++], x, y, sx, sy); - } - draw->polygon(im, n, e, ink, 0); - } - - free(e); - - } else { - - for (i = start; i <= end; i++) { - x = FLOOR((cos(i*M_PI/180) * w/2) + cx + 0.5); - y = FLOOR((sin(i*M_PI/180) * h/2) + cy + 0.5); - if (i != start) - draw->line(im, lx, ly, x, y, ink); - else - sx = x, sy = y; - lx = x, ly = y; - } - - if (i != start) { - if (mode == PIESLICE) { - if (x != cx || y != cy) { - draw->line(im, x, y, cx, cy, ink); - draw->line(im, cx, cy, sx, sy, ink); - } - } else if (mode == CHORD) { - if (x != sx || y != sy) - draw->line(im, x, y, sx, sy, ink); - } - } - } - - return 0; -} - -int -ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink, int op) -{ - return ellipse(im, x0, y0, x1, y1, start, end, ink, 0, ARC, op); -} - -int -ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink, int fill, int op) -{ - return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, CHORD, op); -} - -int -ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1, - const void* ink, int fill, int op) -{ - return ellipse(im, x0, y0, x1, y1, 0, 360, ink, fill, CHORD, op); -} - -int -ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink, int fill, int op) -{ - return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, PIESLICE, op); -} - -/* -------------------------------------------------------------------- */ - -/* experimental level 2 ("arrow") graphics stuff. this implements - portions of the arrow api on top of the Edge structure. the - semantics are ok, except that "curve" flattens the bezier curves by - itself */ - -#if 1 /* ARROW_GRAPHICS */ - -struct ImagingOutlineInstance { - - float x0, y0; - - float x, y; - - int count; - Edge *edges; - - int size; - -}; - - -ImagingOutline -ImagingOutlineNew(void) -{ - ImagingOutline outline; - - outline = calloc(1, sizeof(struct ImagingOutlineInstance)); - if (!outline) - return (ImagingOutline) ImagingError_MemoryError(); - - outline->edges = NULL; - outline->count = outline->size = 0; - - ImagingOutlineMove(outline, 0, 0); - - return outline; -} - -void -ImagingOutlineDelete(ImagingOutline outline) -{ - if (!outline) - return; - - if (outline->edges) - free(outline->edges); - - free(outline); -} - - -static Edge* -allocate(ImagingOutline outline, int extra) -{ - Edge* e; - - if (outline->count + extra > outline->size) { - /* expand outline buffer */ - outline->size += extra + 25; - if (!outline->edges) - e = malloc(outline->size * sizeof(Edge)); - else - e = realloc(outline->edges, outline->size * sizeof(Edge)); - if (!e) - return NULL; - outline->edges = e; - } - - e = outline->edges + outline->count; - - outline->count += extra; - - return e; -} - -int -ImagingOutlineMove(ImagingOutline outline, float x0, float y0) -{ - outline->x = outline->x0 = x0; - outline->y = outline->y0 = y0; - - return 0; -} - -int -ImagingOutlineLine(ImagingOutline outline, float x1, float y1) -{ - Edge* e; - - e = allocate(outline, 1); - if (!e) - return -1; /* out of memory */ - - add_edge(e, (int) outline->x, (int) outline->y, (int) x1, (int) y1); - - outline->x = x1; - outline->y = y1; - - return 0; -} - -int -ImagingOutlineCurve(ImagingOutline outline, float x1, float y1, - float x2, float y2, float x3, float y3) -{ - Edge* e; - int i; - float xo, yo; - -#define STEPS 32 - - e = allocate(outline, STEPS); - if (!e) - return -1; /* out of memory */ - - xo = outline->x; - yo = outline->y; - - /* flatten the bezier segment */ - - for (i = 1; i <= STEPS; i++) { - - float t = ((float) i) / STEPS; - float t2 = t*t; - float t3 = t2*t; - - float u = 1.0F - t; - float u2 = u*u; - float u3 = u2*u; - - float x = outline->x*u3 + 3*(x1*t*u2 + x2*t2*u) + x3*t3 + 0.5; - float y = outline->y*u3 + 3*(y1*t*u2 + y2*t2*u) + y3*t3 + 0.5; - - add_edge(e++, xo, yo, (int) x, (int) y); - - xo = x, yo = y; - - } - - outline->x = xo; - outline->y = yo; - - return 0; -} - -int -ImagingOutlineCurve2(ImagingOutline outline, float cx, float cy, - float x3, float y3) -{ - /* add bezier curve based on three control points (as - in the Flash file format) */ - - return ImagingOutlineCurve( - outline, - (outline->x + cx + cx)/3, (outline->y + cy + cy)/3, - (cx + cx + x3)/3, (cy + cy + y3)/3, - x3, y3); -} - -int -ImagingOutlineClose(ImagingOutline outline) -{ - if (outline->x == outline->x0 && outline->y == outline->y0) - return 0; - return ImagingOutlineLine(outline, outline->x0, outline->y0); -} - -int -ImagingOutlineTransform(ImagingOutline outline, double a[6]) -{ - Edge *eIn; - Edge *eOut; - int i, n; - int x0, y0, x1, y1; - int X0, Y0, X1, Y1; - - double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; - double a3 = a[3]; double a4 = a[4]; double a5 = a[5]; - - eIn = outline->edges; - n = outline->count; - - /* FIXME: ugly! */ - outline->edges = NULL; - outline->count = outline->size = 0; - - eOut = allocate(outline, n); - if (!eOut) { - outline->edges = eIn; - outline->count = outline->size = n; - ImagingError_MemoryError(); - return -1; - } - - for (i = 0; i < n; i++) { - - x0 = eIn->x0; - y0 = eIn->y0; - - /* FIXME: ouch! */ - if (eIn->x0 == eIn->xmin) - x1 = eIn->xmax; - else - x1 = eIn->xmin; - if (eIn->y0 == eIn->ymin) - y1 = eIn->ymax; - else - y1 = eIn->ymin; - - /* full moon tonight! if this doesn't work, you may need to - upgrade your compiler (make sure you have the right service - pack) */ - - X0 = (int) (a0*x0 + a1*y0 + a2); - Y0 = (int) (a3*x0 + a4*y0 + a5); - X1 = (int) (a0*x1 + a1*y1 + a2); - Y1 = (int) (a3*x1 + a4*y1 + a5); - - add_edge(eOut, X0, Y0, X1, Y1); - - eIn++; - eOut++; - - } - - free(eIn); - - return 0; -} - -int -ImagingDrawOutline(Imaging im, ImagingOutline outline, const void* ink_, - int fill, int op) -{ - DRAW* draw; - INT32 ink; - - DRAWINIT(); - - draw->polygon(im, outline->count, outline->edges, ink, 0); - - return 0; -} - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c deleted file mode 100755 index 1b964ac408f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Effects.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * various special effects and image generators - * - * history: - * 1997-05-21 fl Just for fun - * 1997-06-05 fl Added mandelbrot generator - * 2003-05-24 fl Added perlin_turbulence generator (in progress) - * - * Copyright (c) 1997-2003 by Fredrik Lundh. - * Copyright (c) 1997 by Secret Labs AB. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#include - -Imaging -ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) -{ - /* Generate a Mandelbrot set covering the given extent */ - - Imaging im; - int x, y, k; - double width, height; - double x1, y1, xi2, yi2, cr, ci, radius; - double dr, di; - - /* Check arguments */ - width = extent[2] - extent[0]; - height = extent[3] - extent[1]; - if (width < 0.0 || height < 0.0 || quality < 2) - return (Imaging) ImagingError_ValueError(NULL); - - im = ImagingNew("L", xsize, ysize); - if (!im) - return NULL; - - dr = width/(xsize-1); - di = height/(ysize-1); - - radius = 100.0; - - for (y = 0; y < ysize; y++) { - UINT8* buf = im->image8[y]; - for (x = 0; x < xsize; x++) { - x1 = y1 = xi2 = yi2 = 0.0; - cr = x*dr + extent[0]; - ci = y*di + extent[1]; - for (k = 1;; k++) { - y1 = 2*x1*y1 + ci; - x1 = xi2 - yi2 + cr; - xi2 = x1*x1; - yi2 = y1*y1; - if ((xi2 + yi2) > radius) { - buf[x] = k*255/quality; - break; - } - if (k > quality) { - buf[x] = 0; - break; - } - } - } - } - return im; -} - -Imaging -ImagingEffectNoise(int xsize, int ysize, float sigma) -{ - /* Generate gaussian noise centered around 128 */ - - Imaging imOut; - int x, y; - int nextok; - double this, next; - - imOut = ImagingNew("L", xsize, ysize); - if (!imOut) - return NULL; - - next = 0.0; - nextok = 0; - - for (y = 0; y < imOut->ysize; y++) { - UINT8* out = imOut->image8[y]; - for (x = 0; x < imOut->xsize; x++) { - if (nextok) { - this = next; - nextok = 0; - } else { - /* after numerical recepies */ - double v1, v2, radius, factor; - do { - v1 = rand()*(2.0/32767.0) - 1.0; - v2 = rand()*(2.0/32767.0) - 1.0; - radius= v1*v1 + v2*v2; - } while (radius >= 1.0); - factor = sqrt(-2.0*log(radius)/radius); - this = factor * v1; - next = factor * v2; - } - out[x] = (unsigned char) (128 + sigma * this); - } - } - - return imOut; -} - -Imaging -ImagingEffectPerlinTurbulence(int xsize, int ysize) -{ - /* Perlin turbulence (In progress) */ - - return NULL; -} - -Imaging -ImagingEffectSpread(Imaging imIn, int distance) -{ - /* Randomly spread pixels in an image */ - - Imaging imOut; - int x, y; - - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - - if (!imOut) - return NULL; - -#define SPREAD(type, image)\ - for (y = 0; y < imIn->ysize; y++)\ - for (x = 0; x < imIn->xsize; x++) {\ - int xx = x + (rand() % distance) - distance/2;\ - int yy = y + (rand() % distance) - distance/2;\ - if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) {\ - imOut->image[yy][xx] = imIn->image[y][x];\ - imOut->image[y][x] = imIn->image[yy][xx];\ - } else\ - imOut->image[y][x] = imIn->image[y][x];\ - } - - if (imIn->image8) { - SPREAD(UINT8, image8); - } else { - SPREAD(INT32, image32); - } - - ImagingCopyInfo(imOut, imIn); - - return imOut; -} - -/* -------------------------------------------------------------------- */ -/* Taken from the "C" code in the W3C SVG specification. Translated - to C89 by Fredrik Lundh */ - -#if 0 - -/* Produces results in the range [1, 2**31 - 2]. -Algorithm is: r = (a * r) mod m -where a = 16807 and m = 2**31 - 1 = 2147483647 -See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988 -To test: the algorithm should produce the result 1043618065 -as the 10,000th generated number if the original seed is 1. -*/ -#define RAND_m 2147483647 /* 2**31 - 1 */ -#define RAND_a 16807 /* 7**5; primitive root of m */ -#define RAND_q 127773 /* m / a */ -#define RAND_r 2836 /* m % a */ - -static long -perlin_setup_seed(long lSeed) -{ - if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1; - if (lSeed > RAND_m - 1) lSeed = RAND_m - 1; - return lSeed; -} - -static long -perlin_random(long lSeed) -{ - long result; - result = RAND_a * (lSeed % RAND_q) - RAND_r * (lSeed / RAND_q); - if (result <= 0) result += RAND_m; - return result; -} - -#define BSize 0x100 -#define BM 0xff -#define PerlinN 0x1000 -#define NP 12 /* 2^PerlinN */ -#define NM 0xfff -static int perlin_uLatticeSelector[BSize + BSize + 2]; -static double perlin_fGradient[4][BSize + BSize + 2][2]; -typedef struct -{ - int nWidth; /* How much to subtract to wrap for stitching. */ - int nHeight; - int nWrapX; /* Minimum value to wrap. */ - int nWrapY; -} StitchInfo; - -static void -perlin_init(long lSeed) -{ - double s; - int i, j, k; - lSeed = perlin_setup_seed(lSeed); - for(k = 0; k < 4; k++) - { - for(i = 0; i < BSize; i++) - { - perlin_uLatticeSelector[i] = i; - for (j = 0; j < 2; j++) - perlin_fGradient[k][i][j] = (double)(((lSeed = perlin_random(lSeed)) % (BSize + BSize)) - BSize) / BSize; - s = (double) (sqrt(perlin_fGradient[k][i][0] * perlin_fGradient[k][i][0] + perlin_fGradient[k][i][1] * perlin_fGradient[k][i][1])); - perlin_fGradient[k][i][0] /= s; - perlin_fGradient[k][i][1] /= s; - } - } - while(--i) - { - k = perlin_uLatticeSelector[i]; - perlin_uLatticeSelector[i] = perlin_uLatticeSelector[j = (lSeed = perlin_random(lSeed)) % BSize]; - perlin_uLatticeSelector[j] = k; - } - for(i = 0; i < BSize + 2; i++) - { - perlin_uLatticeSelector[BSize + i] = perlin_uLatticeSelector[i]; - for(k = 0; k < 4; k++) - for(j = 0; j < 2; j++) - perlin_fGradient[k][BSize + i][j] = perlin_fGradient[k][i][j]; - } -} - -#define s_curve(t) ( t * t * (3. - 2. * t) ) -#define lerp(t, a, b) ( a + t * (b - a) ) -static double -perlin_noise2(int nColorChannel, double vec[2], StitchInfo *pStitchInfo) -{ - int bx0, bx1, by0, by1, b00, b10, b01, b11; - double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v; - register int i, j; - - t = vec[0] + (double) PerlinN; - bx0 = (int)t; - bx1 = bx0+1; - rx0 = t - (int)t; - rx1 = rx0 - 1.0f; - t = vec[1] + (double) PerlinN; - by0 = (int)t; - by1 = by0+1; - ry0 = t - (int)t; - ry1 = ry0 - 1.0f; - - /* If stitching, adjust lattice points accordingly. */ - if(pStitchInfo != NULL) - { - if(bx0 >= pStitchInfo->nWrapX) - bx0 -= pStitchInfo->nWidth; - if(bx1 >= pStitchInfo->nWrapX) - bx1 -= pStitchInfo->nWidth; - if(by0 >= pStitchInfo->nWrapY) - by0 -= pStitchInfo->nHeight; - if(by1 >= pStitchInfo->nWrapY) - by1 -= pStitchInfo->nHeight; - } - - bx0 &= BM; - bx1 &= BM; - by0 &= BM; - by1 &= BM; - - i = perlin_uLatticeSelector[bx0]; - j = perlin_uLatticeSelector[bx1]; - b00 = perlin_uLatticeSelector[i + by0]; - b10 = perlin_uLatticeSelector[j + by0]; - b01 = perlin_uLatticeSelector[i + by1]; - b11 = perlin_uLatticeSelector[j + by1]; - sx = (double) (s_curve(rx0)); - sy = (double) (s_curve(ry0)); - q = perlin_fGradient[nColorChannel][b00]; u = rx0 * q[0] + ry0 * q[1]; - q = perlin_fGradient[nColorChannel][b10]; v = rx1 * q[0] + ry0 * q[1]; - a = lerp(sx, u, v); - q = perlin_fGradient[nColorChannel][b01]; u = rx0 * q[0] + ry1 * q[1]; - q = perlin_fGradient[nColorChannel][b11]; v = rx1 * q[0] + ry1 * q[1]; - b = lerp(sx, u, v); - return lerp(sy, a, b); -} - -double -perlin_turbulence( - int nColorChannel, double *point, double fBaseFreqX, double fBaseFreqY, - int nNumOctaves, int bFractalSum, int bDoStitching, - double fTileX, double fTileY, double fTileWidth, double fTileHeight) -{ - StitchInfo stitch; - StitchInfo *pStitchInfo = NULL; /* Not stitching when NULL. */ - - double fSum = 0.0f; - double vec[2]; - double ratio = 1; - - int nOctave; - - vec[0] = point[0] * fBaseFreqX; - vec[1] = point[1] * fBaseFreqY; - - /* Adjust the base frequencies if necessary for stitching. */ - if(bDoStitching) - { - /* When stitching tiled turbulence, the frequencies must be adjusted */ - /* so that the tile borders will be continuous. */ - if(fBaseFreqX != 0.0) - { - double fLoFreq = (double) (floor(fTileWidth * fBaseFreqX)) / fTileWidth; - double fHiFreq = (double) (ceil(fTileWidth * fBaseFreqX)) / fTileWidth; - if(fBaseFreqX / fLoFreq < fHiFreq / fBaseFreqX) - fBaseFreqX = fLoFreq; - else - fBaseFreqX = fHiFreq; - } - - if(fBaseFreqY != 0.0) - { - double fLoFreq = (double) (floor(fTileHeight * fBaseFreqY)) / fTileHeight; - double fHiFreq = (double) (ceil(fTileHeight * fBaseFreqY)) / fTileHeight; - if(fBaseFreqY / fLoFreq < fHiFreq / fBaseFreqY) - fBaseFreqY = fLoFreq; - else - fBaseFreqY = fHiFreq; - } - - /* Set up initial stitch values. */ - pStitchInfo = &stitch; - stitch.nWidth = (int) (fTileWidth * fBaseFreqX + 0.5f); - stitch.nWrapX = (int) (fTileX * fBaseFreqX + PerlinN + stitch.nWidth); - stitch.nHeight = (int) (fTileHeight * fBaseFreqY + 0.5f); - stitch.nWrapY = (int) (fTileY * fBaseFreqY + PerlinN + stitch.nHeight); - } - - for(nOctave = 0; nOctave < nNumOctaves; nOctave++) - { - if(bFractalSum) - fSum += (double) (perlin_noise2(nColorChannel, vec, pStitchInfo) / ratio); - else - fSum += (double) (fabs(perlin_noise2(nColorChannel, vec, pStitchInfo)) / ratio); - - vec[0] *= 2; - vec[1] *= 2; - ratio *= 2; - - if(pStitchInfo != NULL) - { - /* Update stitch values. Subtracting PerlinN before the multiplication and */ - /* adding it afterward simplifies to subtracting it once. */ - stitch.nWidth *= 2; - stitch.nWrapX = 2 * stitch.nWrapX - PerlinN; - stitch.nHeight *= 2; - stitch.nWrapY = 2 * stitch.nWrapY - PerlinN; - } - } - return fSum; -} - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c deleted file mode 100755 index 704d5a6567d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/EpsEncode.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * encoder for EPS hex data - * - * history: - * 96-04-19 fl created - * 96-06-27 fl don't drop last block of encoded data - * - * notes: - * FIXME: rename to HexEncode.c ?? - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - enum { HEXBYTE=1, NEWLINE }; - const char *hex = "0123456789abcdef"; - - UINT8* ptr = buf; - UINT8* in, i; - - if (!state->state) { - state->state = HEXBYTE; - state->xsize *= im->pixelsize; /* Hack! */ - } - - in = (UINT8*) im->image[state->y]; - - for (;;) { - - if (state->state == NEWLINE) { - if (bytes < 1) - break; - *ptr++ = '\n'; - bytes--; - state->state = HEXBYTE; - } - - if (bytes < 2) - break; - - i = in[state->x++]; - *ptr++ = hex[(i>>4)&15]; - *ptr++ = hex[i&15]; - bytes -= 2; - - /* Skip junk bytes */ - if (im->bands == 3 && (state->x & 3) == 3) - state->x++; - - if (++state->count >= 79/2) { - state->state = NEWLINE; - state->count = 0; - } - - if (state->x >= state->xsize) { - state->x = 0; - if (++state->y >= state->ysize) { - state->errcode = IMAGING_CODEC_END; - break; - } - in = (UINT8*) im->image[state->y]; - } - - } - - return ptr - buf; - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c deleted file mode 100755 index 635435d576c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Except.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * default exception handling - * - * This module is usually overridden by application code (e.g. - * _imaging.c for PIL's standard Python bindings). If you get - * linking errors, remove this file from your project/library. - * - * history: - * 1995-06-15 fl Created - * 1998-12-29 fl Minor tweaks - * 2003-09-13 fl Added ImagingEnter/LeaveSection() - * - * Copyright (c) 1997-2003 by Secret Labs AB. - * Copyright (c) 1995-2003 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -/* exception state */ - -void * -ImagingError_IOError(void) -{ - fprintf(stderr, "*** exception: file access error\n"); - return NULL; -} - -void * -ImagingError_MemoryError(void) -{ - fprintf(stderr, "*** exception: out of memory\n"); - return NULL; -} - -void * -ImagingError_ModeError(void) -{ - return ImagingError_ValueError("bad image mode"); - return NULL; -} - -void * -ImagingError_Mismatch(void) -{ - return ImagingError_ValueError("images don't match"); - return NULL; -} - -void * -ImagingError_ValueError(const char *message) -{ - if (!message) - message = "exception: bad argument to function"; - fprintf(stderr, "*** %s\n", message); - return NULL; -} - -void -ImagingError_Clear(void) -{ - /* nop */; -} - -/* thread state */ - -void -ImagingSectionEnter(ImagingSectionCookie* cookie) -{ - /* pass */ -} - -void -ImagingSectionLeave(ImagingSectionCookie* cookie) -{ - /* pass */ -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c deleted file mode 100755 index 6f454d1ca5d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/File.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * built-in image file handling - * - * history: - * 1995-11-26 fl Created, supports PGM/PPM - * 1996-08-07 fl Write "1" images as PGM - * 1999-02-21 fl Don't write non-standard modes - * - * Copyright (c) 1997-99 by Secret Labs AB. - * Copyright (c) 1995-96 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#include - -Imaging -ImagingOpenPPM(const char* infile) -{ - FILE* fp; - int i, c, v; - char* mode; - int x, y, max; - Imaging im; - - if (!infile) - return ImagingError_ValueError(NULL); - - fp = fopen(infile, "rb"); - if (!fp) - return ImagingError_IOError(); - - /* PPM magic */ - if (fgetc(fp) != 'P') - goto error; - switch (fgetc(fp)) { - case '4': /* FIXME: 1-bit images are not yet supported */ - goto error; - case '5': - mode = "L"; - break; - case '6': - mode = "RGB"; - break; - default: - goto error; - } - - i = 0; - c = fgetc(fp); - - x = y = max = 0; - - while (i < 3) { - - /* Ignore optional comment fields */ - while (c == '\n') { - c = fgetc(fp); - if (c == '#') { - do { - c = fgetc(fp); - if (c == EOF) - goto error; - } while (c != '\n'); - c = fgetc(fp); - } - } - - /* Skip forward to next value */ - while (isspace(c)) - c = fgetc(fp); - - /* And parse it */ - v = 0; - while (isdigit(c)) { - v = v * 10 + (c - '0'); - c = fgetc(fp); - } - - if (c == EOF) - goto error; - - switch (i++) { - case 0: - x = v; - break; - case 1: - y = v; - break; - case 2: - max = v; - break; - } - } - - im = ImagingNew(mode, x, y); - if (!im) - return NULL; - - /* if (max != 255) ... FIXME: does anyone ever use this feature? */ - - if (strcmp(im->mode, "L") == 0) { - - /* PPM "L" */ - for (y = 0; y < im->ysize; y++) - if (fread(im->image[y], im->xsize, 1, fp) != 1) - goto error; - - } else { - - /* PPM "RGB" or PyPPM mode */ - for (y = 0; y < im->ysize; y++) - for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) - if (fread(im->image[y]+i, im->bands, 1, fp) != 1) - goto error; - } - - fclose(fp); - - return im; - -error: - fclose(fp); - return ImagingError_IOError(); -} - - -int -ImagingSaveRaw(Imaging im, FILE* fp) -{ - int x, y, i; - - if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { - - /* @PIL227: FIXME: for mode "1", map != 0 to 255 */ - - /* PGM "L" */ - for (y = 0; y < im->ysize; y++) - fwrite(im->image[y], 1, im->xsize, fp); - - } else { - - /* PPM "RGB" or other internal format */ - for (y = 0; y < im->ysize; y++) - for (x = i = 0; x < im->xsize; x++, i += im->pixelsize) - fwrite(im->image[y]+i, 1, im->bands, fp); - - } - - return 1; -} - - -int -ImagingSavePPM(Imaging im, const char* outfile) -{ - FILE* fp; - - if (!im) { - (void) ImagingError_ValueError(NULL); - return 0; - } - - fp = fopen(outfile, "wb"); - if (!fp) { - (void) ImagingError_IOError(); - return 0; - } - - if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) { - /* Write "PGM" */ - fprintf(fp, "P5\n%d %d\n255\n", im->xsize, im->ysize); - } else if (strcmp(im->mode, "RGB") == 0) { - /* Write "PPM" */ - fprintf(fp, "P6\n%d %d\n255\n", im->xsize, im->ysize); - } else { - (void) ImagingError_ModeError(); - return 0; - } - - ImagingSaveRaw(im, fp); - - fclose(fp); - - return 1; -} - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c deleted file mode 100755 index ce00e6c157c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Fill.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * fill image with constant pixel value - * - * history: - * 95-11-26 fl moved from Imaging.c - * 96-05-17 fl added radial fill, renamed wedge to linear - * 98-06-23 fl changed ImageFill signature - * - * Copyright (c) Secret Labs AB 1997-98. All rights reserved. - * Copyright (c) Fredrik Lundh 1995-96. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#include "math.h" - -Imaging -ImagingFill(Imaging im, const void* colour) -{ - int x, y; - - if (im->type == IMAGING_TYPE_SPECIAL) { - /* use generic API */ - ImagingAccess access = ImagingAccessNew(im); - if (access) { - for (y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++) - access->put_pixel(im, x, y, colour); - ImagingAccessDelete(im, access); - } else { - /* wipe the image */ - for (y = 0; y < im->ysize; y++) - memset(im->image[y], 0, im->linesize); - } - } else { - INT32 c = 0L; - memcpy(&c, colour, im->pixelsize); - if (im->image32 && c != 0L) { - for (y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++) - im->image32[y][x] = c; - } else { - unsigned char cc = (unsigned char) *(UINT8*) colour; - for (y = 0; y < im->ysize; y++) - memset(im->image[y], cc, im->linesize); - } - } - - return im; -} - -Imaging -ImagingFillLinearGradient(const char *mode) -{ - Imaging im; - int y; - - if (strlen(mode) != 1) - return (Imaging) ImagingError_ModeError(); - - im = ImagingNew(mode, 256, 256); - if (!im) - return NULL; - - for (y = 0; y < 256; y++) - memset(im->image8[y], (unsigned char) y, 256); - - return im; -} - -Imaging -ImagingFillRadialGradient(const char *mode) -{ - Imaging im; - int x, y; - int d; - - if (strlen(mode) != 1) - return (Imaging) ImagingError_ModeError(); - - im = ImagingNew(mode, 256, 256); - if (!im) - return NULL; - - for (y = 0; y < 256; y++) - for (x = 0; x < 256; x++) { - d = (int) sqrt((double) ((x-128)*(x-128) + (y-128)*(y-128)) * 2.0); - if (d >= 255) - im->image8[y][x] = 255; - else - im->image8[y][x] = d; - } - - return im; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c deleted file mode 100755 index 45c9bf0606f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Filter.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * apply convolution kernel to image - * - * history: - * 1995-11-26 fl Created, supports 3x3 kernels - * 1995-11-27 fl Added 5x5 kernels, copy border - * 1999-07-26 fl Eliminated a few compiler warnings - * 2002-06-09 fl Moved kernel definitions to Python - * 2002-06-11 fl Support floating point kernels - * 2003-09-15 fl Added ImagingExpand helper - * - * Copyright (c) Secret Labs AB 1997-2002. All rights reserved. - * Copyright (c) Fredrik Lundh 1995. - * - * See the README file for information on usage and redistribution. - */ - -/* - * FIXME: Support RGB and RGBA/CMYK modes as well - * FIXME: Expand image border (current version leaves border as is) - * FIXME: Implement image processing gradient filters - */ - -#include "Imaging.h" - -Imaging -ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode) -{ - Imaging imOut; - int x, y; - - if (xmargin < 0 && ymargin < 0) - return (Imaging) ImagingError_ValueError("bad kernel size"); - - imOut = ImagingNew( - imIn->mode, imIn->xsize+2*xmargin, imIn->ysize+2*ymargin - ); - if (!imOut) - return NULL; - -#define EXPAND_LINE(type, image, yin, yout) {\ - for (x = 0; x < xmargin; x++)\ - imOut->image[yout][x] = imIn->image[yin][0];\ - for (x = 0; x < imIn->xsize; x++)\ - imOut->image[yout][x+xmargin] = imIn->image[yin][x];\ - for (x = 0; x < xmargin; x++)\ - imOut->image[yout][xmargin+imIn->xsize+x] =\ - imIn->image[yin][imIn->xsize-1];\ - } - -#define EXPAND(type, image) {\ - for (y = 0; y < ymargin; y++)\ - EXPAND_LINE(type, image, 0, y);\ - for (y = 0; y < imIn->ysize; y++)\ - EXPAND_LINE(type, image, y, y+ymargin);\ - for (y = 0; y < ymargin; y++)\ - EXPAND_LINE(type, image, imIn->ysize-1, ymargin+imIn->ysize+y);\ - } - - if (imIn->image8) { - EXPAND(UINT8, image8); - } else { - EXPAND(INT32, image32); - } - - ImagingCopyInfo(imOut, imIn); - - return imOut; -} - -Imaging -ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32* kernel, - FLOAT32 offset, FLOAT32 divisor) -{ - Imaging imOut; - int x, y; - FLOAT32 sum; - - if (!im || strcmp(im->mode, "L") != 0) - return (Imaging) ImagingError_ModeError(); - - if (im->xsize < xsize || im->ysize < ysize) - return ImagingCopy(im); - - if ((xsize != 3 && xsize != 5) || xsize != ysize) - return (Imaging) ImagingError_ValueError("bad kernel size"); - - imOut = ImagingNew(im->mode, im->xsize, im->ysize); - if (!imOut) - return NULL; - - /* brute force kernel implementations */ -#define KERNEL3x3(image, kernel, d) ( \ - (int) image[y+1][x-d] * kernel[0] + \ - (int) image[y+1][x] * kernel[1] + \ - (int) image[y+1][x+d] * kernel[2] + \ - (int) image[y][x-d] * kernel[3] + \ - (int) image[y][x] * kernel[4] + \ - (int) image[y][x+d] * kernel[5] + \ - (int) image[y-1][x-d] * kernel[6] + \ - (int) image[y-1][x] * kernel[7] + \ - (int) image[y-1][x+d] * kernel[8]) - -#define KERNEL5x5(image, kernel, d) ( \ - (int) image[y+2][x-d-d] * kernel[0] + \ - (int) image[y+2][x-d] * kernel[1] + \ - (int) image[y+2][x] * kernel[2] + \ - (int) image[y+2][x+d] * kernel[3] + \ - (int) image[y+2][x+d+d] * kernel[4] + \ - (int) image[y+1][x-d-d] * kernel[5] + \ - (int) image[y+1][x-d] * kernel[6] + \ - (int) image[y+1][x] * kernel[7] + \ - (int) image[y+1][x+d] * kernel[8] + \ - (int) image[y+1][x+d+d] * kernel[9] + \ - (int) image[y][x-d-d] * kernel[10] + \ - (int) image[y][x-d] * kernel[11] + \ - (int) image[y][x] * kernel[12] + \ - (int) image[y][x+d] * kernel[13] + \ - (int) image[y][x+d+d] * kernel[14] + \ - (int) image[y-1][x-d-d] * kernel[15] + \ - (int) image[y-1][x-d] * kernel[16] + \ - (int) image[y-1][x] * kernel[17] + \ - (int) image[y-1][x+d] * kernel[18] + \ - (int) image[y-1][x+d+d] * kernel[19] + \ - (int) image[y-2][x-d-d] * kernel[20] + \ - (int) image[y-2][x-d] * kernel[21] + \ - (int) image[y-2][x] * kernel[22] + \ - (int) image[y-2][x+d] * kernel[23] + \ - (int) image[y-2][x+d+d] * kernel[24]) - - if (xsize == 3) { - /* 3x3 kernel. */ - for (x = 0; x < im->xsize; x++) - imOut->image[0][x] = im->image8[0][x]; - for (y = 1; y < im->ysize-1; y++) { - imOut->image[y][0] = im->image8[y][0]; - for (x = 1; x < im->xsize-1; x++) { - sum = KERNEL3x3(im->image8, kernel, 1) / divisor + offset; - if (sum <= 0) - imOut->image8[y][x] = 0; - else if (sum >= 255) - imOut->image8[y][x] = 255; - else - imOut->image8[y][x] = (UINT8) sum; - } - imOut->image8[y][x] = im->image8[y][x]; - } - for (x = 0; x < im->xsize; x++) - imOut->image8[y][x] = im->image8[y][x]; - } else { - /* 5x5 kernel. */ - for (y = 0; y < 2; y++) - for (x = 0; x < im->xsize; x++) - imOut->image8[y][x] = im->image8[y][x]; - for (; y < im->ysize-2; y++) { - for (x = 0; x < 2; x++) - imOut->image8[y][x] = im->image8[y][x]; - for (; x < im->xsize-2; x++) { - sum = KERNEL5x5(im->image8, kernel, 1) / divisor + offset; - if (sum <= 0) - imOut->image8[y][x] = 0; - else if (sum >= 255) - imOut->image8[y][x] = 255; - else - imOut->image8[y][x] = (UINT8) sum; - } - for (; x < im->xsize; x++) - imOut->image8[y][x] = im->image8[y][x]; - } - for (; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++) - imOut->image8[y][x] = im->image8[y][x]; - } - return imOut; -} - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c deleted file mode 100755 index 75eebe86c90..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/FliDecode.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for Autodesk Animator FLI/FLC animations - * - * history: - * 97-01-03 fl Created - * 97-01-17 fl Added SS2 support (FLC) - * - * Copyright (c) Fredrik Lundh 1997. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -#define I16(ptr)\ - ((ptr)[0] + ((ptr)[1] << 8)) - -#define I32(ptr)\ - ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) - - -int -ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8* ptr; - int framesize; - int c, chunks; - int l, lines; - int i, j, x = 0, y, ymax; - - /* If not even the chunk size is present, we'd better leave */ - - if (bytes < 4) - return 0; - - /* We don't decode anything unless we have a full chunk in the - input buffer (on the other hand, the Python part of the driver - makes sure this is always the case) */ - - ptr = buf; - - framesize = I32(ptr); - if (framesize < I32(ptr)) - return 0; - - /* Make sure this is a frame chunk. The Python driver takes - case of other chunk types. */ - - if (I16(ptr+4) != 0xF1FA) { - state->errcode = IMAGING_CODEC_UNKNOWN; - return -1; - } - - chunks = I16(ptr+6); - ptr += 16; - - /* Process subchunks */ - for (c = 0; c < chunks; c++) { - UINT8 *data = ptr + 6; - switch (I16(ptr+4)) { - case 4: case 11: - /* FLI COLOR chunk */ - break; /* ignored; handled by Python code */ - case 7: - /* FLI SS2 chunk (word delta) */ - lines = I16(data); data += 2; - for (l = y = 0; l < lines && y < state->ysize; l++, y++) { - UINT8* buf = (UINT8*) im->image[y]; - int p, packets; - packets = I16(data); data += 2; - while (packets & 0x8000) { - /* flag word */ - if (packets & 0x4000) { - y += 65536 - packets; /* skip lines */ - if (y >= state->ysize) { - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - buf = (UINT8*) im->image[y]; - } else { - /* store last byte (used if line width is odd) */ - buf[state->xsize-1] = (UINT8) packets; - } - packets = I16(data); data += 2; - } - for (p = x = 0; p < packets; p++) { - x += data[0]; /* pixel skip */ - if (data[1] >= 128) { - i = 256-data[1]; /* run */ - if (x + i + i > state->xsize) - break; - for (j = 0; j < i; j++) { - buf[x++] = data[2]; - buf[x++] = data[3]; - } - data += 2 + 2; - } else { - i = 2 * (int) data[1]; /* chunk */ - if (x + i > state->xsize) - break; - memcpy(buf + x, data + 2, i); - data += 2 + i; - x += i; - } - } - if (p < packets) - break; /* didn't process all packets */ - } - if (l < lines) { - /* didn't process all lines */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - break; - case 12: - /* FLI LC chunk (byte delta) */ - y = I16(data); ymax = y + I16(data+2); data += 4; - for (; y < ymax && y < state->ysize; y++) { - UINT8* out = (UINT8*) im->image[y]; - int p, packets = *data++; - for (p = x = 0; p < packets; p++, x += i) { - x += data[0]; /* skip pixels */ - if (data[1] & 0x80) { - i = 256-data[1]; /* run */ - if (x + i > state->xsize) - break; - memset(out + x, data[2], i); - data += 3; - } else { - i = data[1]; /* chunk */ - if (x + i > state->xsize) - break; - memcpy(out + x, data + 2, i); - data += i + 2; - } - } - if (p < packets) - break; /* didn't process all packets */ - } - if (y < ymax) { - /* didn't process all lines */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - break; - case 13: - /* FLI BLACK chunk */ - for (y = 0; y < state->ysize; y++) - memset(im->image[y], 0, state->xsize); - break; - case 15: - /* FLI BRUN chunk */ - for (y = 0; y < state->ysize; y++) { - UINT8* out = (UINT8*) im->image[y]; - data += 1; /* ignore packetcount byte */ - for (x = 0; x < state->xsize; x += i) { - if (data[0] & 0x80) { - i = 256 - data[0]; - if (x + i > state->xsize) - break; /* safety first */ - memcpy(out + x, data + 1, i); - data += i + 1; - } else { - i = data[0]; - if (x + i > state->xsize) - break; /* safety first */ - memset(out + x, data[1], i); - data += 2; - } - } - if (x != state->xsize) { - /* didn't unpack whole line */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - } - break; - case 16: - /* COPY chunk */ - for (y = 0; y < state->ysize; y++) { - UINT8* buf = (UINT8*) im->image[y]; - memcpy(buf+x, data, state->xsize); - data += state->xsize; - } - break; - case 18: - /* PSTAMP chunk */ - break; /* ignored */ - default: - /* unknown chunk */ - /* printf("unknown FLI/FLC chunk: %d\n", I16(ptr+4)); */ - state->errcode = IMAGING_CODEC_UNKNOWN; - return -1; - } - ptr += I32(ptr); - } - - return -1; /* end of frame */ -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c deleted file mode 100755 index 41f535b562d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Geometry.c +++ /dev/null @@ -1,959 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * the imaging geometry methods - * - * history: - * 1995-06-15 fl Created - * 1996-04-15 fl Changed origin - * 1996-05-18 fl Fixed rotate90/270 for rectangular images - * 1996-05-27 fl Added general purpose transform - * 1996-11-22 fl Don't crash when resizing from outside source image - * 1997-08-09 fl Fixed rounding error in resize - * 1998-09-21 fl Incorporated transformation patches (from Zircon #2) - * 1998-09-22 fl Added bounding box to transform engines - * 1999-02-03 fl Fixed bicubic filtering for RGB images - * 1999-02-16 fl Added fixed-point version of affine transform - * 2001-03-28 fl Fixed transform(EXTENT) for xoffset < 0 - * 2003-03-10 fl Compiler tweaks - * 2004-09-19 fl Fixed bilinear/bicubic filtering of LA images - * - * Copyright (c) 1997-2003 by Secret Labs AB - * Copyright (c) 1995-1997 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -/* Undef if you don't need resampling filters */ -#define WITH_FILTERS - -#define COORD(v) ((v) < 0.0 ? -1 : ((int)(v))) -#define FLOOR(v) ((v) < 0.0 ? ((int)floor(v)) : ((int)(v))) - -/* -------------------------------------------------------------------- */ -/* Transpose operations */ - -Imaging -ImagingFlipLeftRight(Imaging imOut, Imaging imIn) -{ - ImagingSectionCookie cookie; - int x, y, xr; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) - return (Imaging) ImagingError_Mismatch(); - - ImagingCopyInfo(imOut, imIn); - -#define FLIP_HORIZ(image)\ - for (y = 0; y < imIn->ysize; y++) {\ - xr = imIn->xsize-1;\ - for (x = 0; x < imIn->xsize; x++, xr--)\ - imOut->image[y][x] = imIn->image[y][xr];\ - } - - ImagingSectionEnter(&cookie); - - if (imIn->image8) - FLIP_HORIZ(image8) - else - FLIP_HORIZ(image32) - - ImagingSectionLeave(&cookie); - - return imOut; -} - - -Imaging -ImagingFlipTopBottom(Imaging imOut, Imaging imIn) -{ - ImagingSectionCookie cookie; - int y, yr; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) - return (Imaging) ImagingError_Mismatch(); - - ImagingCopyInfo(imOut, imIn); - - ImagingSectionEnter(&cookie); - - yr = imIn->ysize-1; - for (y = 0; y < imIn->ysize; y++, yr--) - memcpy(imOut->image[yr], imIn->image[y], imIn->linesize); - - ImagingSectionLeave(&cookie); - - return imOut; -} - - -Imaging -ImagingRotate90(Imaging imOut, Imaging imIn) -{ - ImagingSectionCookie cookie; - int x, y, xr; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) - return (Imaging) ImagingError_Mismatch(); - - ImagingCopyInfo(imOut, imIn); - -#define ROTATE_90(image)\ - for (y = 0; y < imIn->ysize; y++) {\ - xr = imIn->xsize-1;\ - for (x = 0; x < imIn->xsize; x++, xr--)\ - imOut->image[xr][y] = imIn->image[y][x];\ - } - - ImagingSectionEnter(&cookie); - - if (imIn->image8) - ROTATE_90(image8) - else - ROTATE_90(image32) - - ImagingSectionLeave(&cookie); - - return imOut; -} - - -Imaging -ImagingRotate180(Imaging imOut, Imaging imIn) -{ - ImagingSectionCookie cookie; - int x, y, xr, yr; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize) - return (Imaging) ImagingError_Mismatch(); - - ImagingCopyInfo(imOut, imIn); - - yr = imIn->ysize-1; - -#define ROTATE_180(image)\ - for (y = 0; y < imIn->ysize; y++, yr--) {\ - xr = imIn->xsize-1;\ - for (x = 0; x < imIn->xsize; x++, xr--)\ - imOut->image[y][x] = imIn->image[yr][xr];\ - } - - ImagingSectionEnter(&cookie); - - if (imIn->image8) - ROTATE_180(image8) - else - ROTATE_180(image32) - - ImagingSectionLeave(&cookie); - - return imOut; -} - - -Imaging -ImagingRotate270(Imaging imOut, Imaging imIn) -{ - ImagingSectionCookie cookie; - int x, y, yr; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize) - return (Imaging) ImagingError_Mismatch(); - - ImagingCopyInfo(imOut, imIn); - - yr = imIn->ysize - 1; - -#define ROTATE_270(image)\ - for (y = 0; y < imIn->ysize; y++, yr--)\ - for (x = 0; x < imIn->xsize; x++)\ - imOut->image[x][y] = imIn->image[yr][x]; - - ImagingSectionEnter(&cookie); - - if (imIn->image8) - ROTATE_270(image8) - else - ROTATE_270(image32) - - ImagingSectionLeave(&cookie); - - return imOut; -} - - -/* -------------------------------------------------------------------- */ -/* Transforms */ - -/* transform primitives (ImagingTransformMap) */ - -static int -affine_transform(double* xin, double* yin, int x, int y, void* data) -{ - /* full moon tonight. your compiler will generate bogus code - for simple expressions, unless you reorganize the code, or - install Service Pack 3 */ - - double* a = (double*) data; - double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; - double a3 = a[3]; double a4 = a[4]; double a5 = a[5]; - - xin[0] = a0 + a1*x + a2*y; - yin[0] = a3 + a4*x + a5*y; - - return 1; -} - -static int -perspective_transform(double* xin, double* yin, int x, int y, void* data) -{ - double* a = (double*) data; - double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; - double a3 = a[3]; double a4 = a[4]; double a5 = a[5]; - double a6 = a[6]; double a7 = a[7]; - - xin[0] = (a0 + a1*x + a2*y) / (a6*x + a7*y + 1); - yin[0] = (a3 + a4*x + a5*y) / (a6*x + a7*y + 1); - - return 1; -} - -#if 0 -static int -quadratic_transform(double* xin, double* yin, int x, int y, void* data) -{ - double* a = (double*) data; - - double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3]; - double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7]; - double a8 = a[8]; double a9 = a[9]; double a10 = a[10]; double a11 = a[11]; - - xin[0] = a0 + a1*x + a2*y + a3*x*x + a4*x*y + a5*y*y; - yin[0] = a6 + a7*x + a8*y + a9*x*x + a10*x*y + a11*y*y; - - return 1; -} -#endif - -static int -quad_transform(double* xin, double* yin, int x, int y, void* data) -{ - /* quad warp: map quadrilateral to rectangle */ - - double* a = (double*) data; - double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3]; - double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7]; - - xin[0] = a0 + a1*x + a2*y + a3*x*y; - yin[0] = a4 + a5*x + a6*y + a7*x*y; - - return 1; -} - -/* transform filters (ImagingTransformFilter) */ - -#ifdef WITH_FILTERS - -static int -nearest_filter8(void* out, Imaging im, double xin, double yin, void* data) -{ - int x = COORD(xin); - int y = COORD(yin); - if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) - return 0; - ((UINT8*)out)[0] = im->image8[y][x]; - return 1; -} - -static int -nearest_filter16(void* out, Imaging im, double xin, double yin, void* data) -{ - int x = COORD(xin); - int y = COORD(yin); - if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) - return 0; - ((INT16*)out)[0] = ((INT16*)(im->image8[y]))[x]; - return 1; -} - -static int -nearest_filter32(void* out, Imaging im, double xin, double yin, void* data) -{ - int x = COORD(xin); - int y = COORD(yin); - if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) - return 0; - ((INT32*)out)[0] = im->image32[y][x]; - return 1; -} - -#define XCLIP(im, x) ( ((x) < 0) ? 0 : ((x) < im->xsize) ? (x) : im->xsize-1 ) -#define YCLIP(im, y) ( ((y) < 0) ? 0 : ((y) < im->ysize) ? (y) : im->ysize-1 ) - -#define BILINEAR(v, a, b, d)\ - (v = (a) + ( (b) - (a) ) * (d)) - -#define BILINEAR_HEAD(type)\ - int x, y;\ - int x0, x1;\ - double v1, v2;\ - double dx, dy;\ - type* in;\ - if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize)\ - return 0;\ - xin -= 0.5;\ - yin -= 0.5;\ - x = FLOOR(xin);\ - y = FLOOR(yin);\ - dx = xin - x;\ - dy = yin - y; - -#define BILINEAR_BODY(type, image, step, offset) {\ - in = (type*) ((image)[YCLIP(im, y)] + offset);\ - x0 = XCLIP(im, x+0)*step;\ - x1 = XCLIP(im, x+1)*step;\ - BILINEAR(v1, in[x0], in[x1], dx);\ - if (y+1 >= 0 && y+1 < im->ysize) {\ - in = (type*) ((image)[y+1] + offset);\ - BILINEAR(v2, in[x0], in[x1], dx);\ - } else\ - v2 = v1;\ - BILINEAR(v1, v1, v2, dy);\ -} - -static int -bilinear_filter8(void* out, Imaging im, double xin, double yin, void* data) -{ - BILINEAR_HEAD(UINT8); - BILINEAR_BODY(UINT8, im->image8, 1, 0); - ((UINT8*)out)[0] = (UINT8) v1; - return 1; -} - -static int -bilinear_filter32I(void* out, Imaging im, double xin, double yin, void* data) -{ - BILINEAR_HEAD(INT32); - BILINEAR_BODY(INT32, im->image32, 1, 0); - ((INT32*)out)[0] = (INT32) v1; - return 1; -} - -static int -bilinear_filter32F(void* out, Imaging im, double xin, double yin, void* data) -{ - BILINEAR_HEAD(FLOAT32); - BILINEAR_BODY(FLOAT32, im->image32, 1, 0); - ((FLOAT32*)out)[0] = (FLOAT32) v1; - return 1; -} - -static int -bilinear_filter32LA(void* out, Imaging im, double xin, double yin, void* data) -{ - BILINEAR_HEAD(UINT8); - BILINEAR_BODY(UINT8, im->image, 4, 0); - ((UINT8*)out)[0] = (UINT8) v1; - ((UINT8*)out)[1] = (UINT8) v1; - ((UINT8*)out)[2] = (UINT8) v1; - BILINEAR_BODY(UINT8, im->image, 4, 3); - ((UINT8*)out)[3] = (UINT8) v1; - return 1; -} - -static int -bilinear_filter32RGB(void* out, Imaging im, double xin, double yin, void* data) -{ - int b; - BILINEAR_HEAD(UINT8); - for (b = 0; b < im->bands; b++) { - BILINEAR_BODY(UINT8, im->image, 4, b); - ((UINT8*)out)[b] = (UINT8) v1; - } - return 1; -} - -#define BICUBIC(v, v1, v2, v3, v4, d) {\ - double p1 = v2;\ - double p2 = -v1 + v3;\ - double p3 = 2*(v1 - v2) + v3 - v4;\ - double p4 = -v1 + v2 - v3 + v4;\ - v = p1 + (d)*(p2 + (d)*(p3 + (d)*p4));\ -} - -#define BICUBIC_HEAD(type)\ - int x = FLOOR(xin);\ - int y = FLOOR(yin);\ - int x0, x1, x2, x3;\ - double v1, v2, v3, v4;\ - double dx, dy;\ - type* in;\ - if (xin < 0.0 || xin >= im->xsize || yin < 0.0 || yin >= im->ysize)\ - return 0;\ - xin -= 0.5;\ - yin -= 0.5;\ - x = FLOOR(xin);\ - y = FLOOR(yin);\ - dx = xin - x;\ - dy = yin - y;\ - x--; y--; - -#define BICUBIC_BODY(type, image, step, offset) {\ - in = (type*) ((image)[YCLIP(im, y)] + offset);\ - x0 = XCLIP(im, x+0)*step;\ - x1 = XCLIP(im, x+1)*step;\ - x2 = XCLIP(im, x+2)*step;\ - x3 = XCLIP(im, x+3)*step;\ - BICUBIC(v1, in[x0], in[x1], in[x2], in[x3], dx);\ - if (y+1 >= 0 && y+1 < im->ysize) {\ - in = (type*) ((image)[y+1] + offset);\ - BICUBIC(v2, in[x0], in[x1], in[x2], in[x3], dx);\ - } else\ - v2 = v1;\ - if (y+2 >= 0 && y+2 < im->ysize) {\ - in = (type*) ((image)[y+2] + offset);\ - BICUBIC(v3, in[x0], in[x1], in[x2], in[x3], dx);\ - } else\ - v3 = v2;\ - if (y+3 >= 0 && y+3 < im->ysize) {\ - in = (type*) ((image)[y+3] + offset);\ - BICUBIC(v4, in[x0], in[x1], in[x2], in[x3], dx);\ - } else\ - v4 = v3;\ - BICUBIC(v1, v1, v2, v3, v4, dy);\ -} - - -static int -bicubic_filter8(void* out, Imaging im, double xin, double yin, void* data) -{ - BICUBIC_HEAD(UINT8); - BICUBIC_BODY(UINT8, im->image8, 1, 0); - if (v1 <= 0.0) - ((UINT8*)out)[0] = 0; - else if (v1 >= 255.0) - ((UINT8*)out)[0] = 255; - else - ((UINT8*)out)[0] = (UINT8) v1; - return 1; -} - -static int -bicubic_filter32I(void* out, Imaging im, double xin, double yin, void* data) -{ - BICUBIC_HEAD(INT32); - BICUBIC_BODY(INT32, im->image32, 1, 0); - ((INT32*)out)[0] = (INT32) v1; - return 1; -} - -static int -bicubic_filter32F(void* out, Imaging im, double xin, double yin, void* data) -{ - BICUBIC_HEAD(FLOAT32); - BICUBIC_BODY(FLOAT32, im->image32, 1, 0); - ((FLOAT32*)out)[0] = (FLOAT32) v1; - return 1; -} - -static int -bicubic_filter32LA(void* out, Imaging im, double xin, double yin, void* data) -{ - BICUBIC_HEAD(UINT8); - BICUBIC_BODY(UINT8, im->image, 4, 0); - if (v1 <= 0.0) { - ((UINT8*)out)[0] = 0; - ((UINT8*)out)[1] = 0; - ((UINT8*)out)[2] = 0; - } else if (v1 >= 255.0) { - ((UINT8*)out)[0] = 255; - ((UINT8*)out)[1] = 255; - ((UINT8*)out)[2] = 255; - } else { - ((UINT8*)out)[0] = (UINT8) v1; - ((UINT8*)out)[1] = (UINT8) v1; - ((UINT8*)out)[2] = (UINT8) v1; - } - BICUBIC_BODY(UINT8, im->image, 4, 3); - if (v1 <= 0.0) - ((UINT8*)out)[3] = 0; - else if (v1 >= 255.0) - ((UINT8*)out)[3] = 255; - else - ((UINT8*)out)[3] = (UINT8) v1; - return 1; -} - -static int -bicubic_filter32RGB(void* out, Imaging im, double xin, double yin, void* data) -{ - int b; - BICUBIC_HEAD(UINT8); - for (b = 0; b < im->bands; b++) { - BICUBIC_BODY(UINT8, im->image, 4, b); - if (v1 <= 0.0) - ((UINT8*)out)[b] = 0; - else if (v1 >= 255.0) - ((UINT8*)out)[b] = 255; - else - ((UINT8*)out)[b] = (UINT8) v1; - } - return 1; -} - -static ImagingTransformFilter -getfilter(Imaging im, int filterid) -{ - switch (filterid) { - case IMAGING_TRANSFORM_NEAREST: - if (im->image8) - switch (im->type) { - case IMAGING_TYPE_UINT8: - return (ImagingTransformFilter) nearest_filter8; - case IMAGING_TYPE_SPECIAL: - switch (im->pixelsize) { - case 1: - return (ImagingTransformFilter) nearest_filter8; - case 2: - return (ImagingTransformFilter) nearest_filter16; - case 4: - return (ImagingTransformFilter) nearest_filter32; - } - } - else - return (ImagingTransformFilter) nearest_filter32; - break; - case IMAGING_TRANSFORM_BILINEAR: - if (im->image8) - return (ImagingTransformFilter) bilinear_filter8; - else if (im->image32) { - switch (im->type) { - case IMAGING_TYPE_UINT8: - if (im->bands == 2) - return (ImagingTransformFilter) bilinear_filter32LA; - else - return (ImagingTransformFilter) bilinear_filter32RGB; - case IMAGING_TYPE_INT32: - return (ImagingTransformFilter) bilinear_filter32I; - case IMAGING_TYPE_FLOAT32: - return (ImagingTransformFilter) bilinear_filter32F; - } - } - break; - case IMAGING_TRANSFORM_BICUBIC: - if (im->image8) - return (ImagingTransformFilter) bicubic_filter8; - else if (im->image32) { - switch (im->type) { - case IMAGING_TYPE_UINT8: - if (im->bands == 2) - return (ImagingTransformFilter) bicubic_filter32LA; - else - return (ImagingTransformFilter) bicubic_filter32RGB; - case IMAGING_TYPE_INT32: - return (ImagingTransformFilter) bicubic_filter32I; - case IMAGING_TYPE_FLOAT32: - return (ImagingTransformFilter) bicubic_filter32F; - } - } - break; - } - /* no such filter */ - return NULL; -} - -#else -#define getfilter(im, id) NULL -#endif - -/* transformation engines */ - -Imaging -ImagingTransform( - Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, - ImagingTransformMap transform, void* transform_data, - ImagingTransformFilter filter, void* filter_data, - int fill) -{ - /* slow generic transformation. use ImagingTransformAffine or - ImagingScaleAffine where possible. */ - - ImagingSectionCookie cookie; - int x, y; - char *out; - double xx, yy; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - - ImagingCopyInfo(imOut, imIn); - - ImagingSectionEnter(&cookie); - - if (x0 < 0) - x0 = 0; - if (y0 < 0) - y0 = 0; - if (x1 > imOut->xsize) - x1 = imOut->xsize; - if (y1 > imOut->ysize) - y1 = imOut->ysize; - - for (y = y0; y < y1; y++) { - out = imOut->image[y] + x0*imOut->pixelsize; - for (x = x0; x < x1; x++) { - if (!transform(&xx, &yy, x-x0, y-y0, transform_data) || - !filter(out, imIn, xx, yy, filter_data)) { - if (fill) - memset(out, 0, imOut->pixelsize); - } - out += imOut->pixelsize; - } - } - - ImagingSectionLeave(&cookie); - - return imOut; -} - -static Imaging -ImagingScaleAffine(Imaging imOut, Imaging imIn, - int x0, int y0, int x1, int y1, - double a[6], int fill) -{ - /* scale, nearest neighbour resampling */ - - ImagingSectionCookie cookie; - int x, y; - int xin; - double xo, yo; - int xmin, xmax; - int *xintab; - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - - ImagingCopyInfo(imOut, imIn); - - if (x0 < 0) - x0 = 0; - if (y0 < 0) - y0 = 0; - if (x1 > imOut->xsize) - x1 = imOut->xsize; - if (y1 > imOut->ysize) - y1 = imOut->ysize; - - xintab = (int*) malloc(imOut->xsize * sizeof(int)); - if (!xintab) { - ImagingDelete(imOut); - return (Imaging) ImagingError_MemoryError(); - } - - xo = a[0]; - yo = a[3]; - - xmin = x1; - xmax = x0; - - /* Pretabulate horizontal pixel positions */ - for (x = x0; x < x1; x++) { - xin = COORD(xo); - if (xin >= 0 && xin < (int) imIn->xsize) { - xmax = x+1; - if (x < xmin) - xmin = x; - xintab[x] = xin; - } - xo += a[1]; - } - -#define AFFINE_SCALE(pixel, image)\ - for (y = y0; y < y1; y++) {\ - int yi = COORD(yo);\ - pixel *in, *out;\ - out = imOut->image[y];\ - if (fill && x1 > x0)\ - memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ - if (yi >= 0 && yi < imIn->ysize) {\ - in = imIn->image[yi];\ - for (x = xmin; x < xmax; x++)\ - out[x] = in[xintab[x]];\ - }\ - yo += a[5];\ - } - - ImagingSectionEnter(&cookie); - - if (imIn->image8) { - AFFINE_SCALE(UINT8, image8); - } else { - AFFINE_SCALE(INT32, image32); - } - - ImagingSectionLeave(&cookie); - - free(xintab); - - return imOut; -} - -static inline int -check_fixed(double a[6], int x, int y) -{ - return (fabs(a[0] + x*a[1] + y*a[2]) < 32768.0 && - fabs(a[3] + x*a[4] + y*a[5]) < 32768.0); -} - -static inline Imaging -affine_fixed(Imaging imOut, Imaging imIn, - int x0, int y0, int x1, int y1, - double a[6], int filterid, int fill) -{ - /* affine transform, nearest neighbour resampling, fixed point - arithmetics */ - - int x, y; - int xin, yin; - int xsize, ysize; - int xx, yy; - int a0, a1, a2, a3, a4, a5; - - ImagingCopyInfo(imOut, imIn); - - xsize = (int) imIn->xsize; - ysize = (int) imIn->ysize; - -/* use 16.16 fixed point arithmetics */ -#define FIX(v) FLOOR((v)*65536.0 + 0.5) - - a0 = FIX(a[0]); a1 = FIX(a[1]); a2 = FIX(a[2]); - a3 = FIX(a[3]); a4 = FIX(a[4]); a5 = FIX(a[5]); - -#define AFFINE_TRANSFORM_FIXED(pixel, image)\ - for (y = y0; y < y1; y++) {\ - pixel *out;\ - xx = a0;\ - yy = a3;\ - out = imOut->image[y];\ - if (fill && x1 > x0)\ - memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ - for (x = x0; x < x1; x++, out++) {\ - xin = xx >> 16;\ - if (xin >= 0 && xin < xsize) {\ - yin = yy >> 16;\ - if (yin >= 0 && yin < ysize)\ - *out = imIn->image[yin][xin];\ - }\ - xx += a1;\ - yy += a4;\ - }\ - a0 += a2;\ - a3 += a5;\ - } - - if (imIn->image8) - AFFINE_TRANSFORM_FIXED(UINT8, image8) - else - AFFINE_TRANSFORM_FIXED(INT32, image32) - - return imOut; -} - -Imaging -ImagingTransformAffine(Imaging imOut, Imaging imIn, - int x0, int y0, int x1, int y1, - double a[6], int filterid, int fill) -{ - /* affine transform, nearest neighbour resampling, floating point - arithmetics*/ - - ImagingSectionCookie cookie; - int x, y; - int xin, yin; - int xsize, ysize; - double xx, yy; - double xo, yo; - - if (filterid || imIn->type == IMAGING_TYPE_SPECIAL) { - /* Filtered transform */ - ImagingTransformFilter filter = getfilter(imIn, filterid); - if (!filter) - return (Imaging) ImagingError_ValueError("unknown filter"); - return ImagingTransform( - imOut, imIn, - x0, y0, x1, y1, - affine_transform, a, - filter, NULL, fill); - } - - if (a[2] == 0 && a[4] == 0) - /* Scaling */ - return ImagingScaleAffine(imOut, imIn, x0, y0, x1, y1, a, fill); - - if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0) - return (Imaging) ImagingError_ModeError(); - - if (x0 < 0) - x0 = 0; - if (y0 < 0) - y0 = 0; - if (x1 > imOut->xsize) - x1 = imOut->xsize; - if (y1 > imOut->ysize) - y1 = imOut->ysize; - - ImagingCopyInfo(imOut, imIn); - - /* translate all four corners to check if they are within the - range that can be represented by the fixed point arithmetics */ - - if (check_fixed(a, 0, 0) && check_fixed(a, x1-x0, y1-y0) && - check_fixed(a, 0, y1-y0) && check_fixed(a, x1-x0, 0)) - return affine_fixed(imOut, imIn, x0, y0, x1, y1, a, filterid, fill); - - /* FIXME: cannot really think of any reasonable case when the - following code is used. maybe we should fall back on the slow - generic transform engine in this case? */ - - xsize = (int) imIn->xsize; - ysize = (int) imIn->ysize; - - xo = a[0]; - yo = a[3]; - -#define AFFINE_TRANSFORM(pixel, image)\ - for (y = y0; y < y1; y++) {\ - pixel *out;\ - xx = xo;\ - yy = yo;\ - out = imOut->image[y];\ - if (fill && x1 > x0)\ - memset(out+x0, 0, (x1-x0)*sizeof(pixel));\ - for (x = x0; x < x1; x++, out++) {\ - xin = COORD(xx);\ - if (xin >= 0 && xin < xsize) {\ - yin = COORD(yy);\ - if (yin >= 0 && yin < ysize)\ - *out = imIn->image[yin][xin];\ - }\ - xx += a[1];\ - yy += a[4];\ - }\ - xo += a[2];\ - yo += a[5];\ - } - - ImagingSectionEnter(&cookie); - - if (imIn->image8) - AFFINE_TRANSFORM(UINT8, image8) - else - AFFINE_TRANSFORM(INT32, image32) - - ImagingSectionLeave(&cookie); - - return imOut; -} - -Imaging -ImagingTransformPerspective(Imaging imOut, Imaging imIn, - int x0, int y0, int x1, int y1, - double a[8], int filterid, int fill) -{ - ImagingTransformFilter filter = getfilter(imIn, filterid); - if (!filter) - return (Imaging) ImagingError_ValueError("bad filter number"); - - return ImagingTransform( - imOut, imIn, - x0, y0, x1, y1, - perspective_transform, a, - filter, NULL, - fill); -} - -Imaging -ImagingTransformQuad(Imaging imOut, Imaging imIn, - int x0, int y0, int x1, int y1, - double a[8], int filterid, int fill) -{ - ImagingTransformFilter filter = getfilter(imIn, filterid); - if (!filter) - return (Imaging) ImagingError_ValueError("bad filter number"); - - return ImagingTransform( - imOut, imIn, - x0, y0, x1, y1, - quad_transform, a, - filter, NULL, - fill); -} - -/* -------------------------------------------------------------------- */ -/* Convenience functions */ - -Imaging -ImagingResize(Imaging imOut, Imaging imIn, int filterid) -{ - double a[6]; - - if (imOut->xsize == imIn->xsize && imOut->ysize == imIn->ysize) - return ImagingCopy2(imOut, imIn); - - memset(a, 0, sizeof a); - a[1] = (double) imIn->xsize / imOut->xsize; - a[5] = (double) imIn->ysize / imOut->ysize; - - if (!filterid && imIn->type != IMAGING_TYPE_SPECIAL) - return ImagingScaleAffine( - imOut, imIn, - 0, 0, imOut->xsize, imOut->ysize, - a, 1); - - return ImagingTransformAffine( - imOut, imIn, - 0, 0, imOut->xsize, imOut->ysize, - a, filterid, 1); -} - -Imaging -ImagingRotate(Imaging imOut, Imaging imIn, double theta, int filterid) -{ - int xsize, ysize; - double sintheta, costheta; - double a[6]; - - /* Setup an affine transform to rotate around the image center */ - theta = -theta * M_PI / 180.0; - sintheta = sin(theta); - costheta = cos(theta); - - xsize = imOut->xsize; - ysize = imOut->ysize; - - a[0] = -costheta * xsize/2 - sintheta * ysize/2 + xsize/2; - a[1] = costheta; - a[2] = sintheta; - a[3] = sintheta * xsize/2 - costheta * ysize/2 + ysize/2; - a[4] = -sintheta; - a[5] = costheta; - - return ImagingTransformAffine( - imOut, imIn, - 0, 0, imOut->xsize, imOut->ysize, - a, filterid, 1); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c deleted file mode 100755 index d1722fe1488..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GetBBox.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * helpers to bounding boxes, min/max values, number of colors, etc. - * - * history: - * 1996-07-22 fl Created - * 1996-12-30 fl Added projection stuff - * 1998-07-12 fl Added extrema stuff - * 2004-09-17 fl Added colors stuff - * - * Copyright (c) 1997-2004 by Secret Labs AB. - * Copyright (c) 1996-2004 by Fredrik Lundh. - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingGetBBox(Imaging im, int bbox[4]) -{ - /* Get the bounding box for any non-zero data in the image.*/ - - int x, y; - int has_data; - - /* Initialize bounding box to max values */ - bbox[0] = im->xsize; - bbox[1] = -1; - bbox[2] = bbox[3] = 0; - -#define GETBBOX(image, mask)\ - for (y = 0; y < im->ysize; y++) {\ - has_data = 0;\ - for (x = 0; x < im->xsize; x++)\ - if (im->image[y][x] & mask) {\ - has_data = 1;\ - if (x < bbox[0])\ - bbox[0] = x;\ - if (x >= bbox[2])\ - bbox[2] = x+1;\ - }\ - if (has_data) {\ - if (bbox[1] < 0)\ - bbox[1] = y;\ - bbox[3] = y+1;\ - }\ - } - - if (im->image8) { - GETBBOX(image8, 0xff); - } else { - INT32 mask = 0xffffffff; - if (im->bands == 3) - ((UINT8*) &mask)[3] = 0; - GETBBOX(image32, mask); - } - - /* Check that we got a box */ - if (bbox[1] < 0) - return 0; /* no data */ - - return 1; /* ok */ -} - - -int -ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj) -{ - /* Get projection arrays for non-zero data in the image.*/ - - int x, y; - int has_data; - - /* Initialize projection arrays */ - memset(xproj, 0, im->xsize); - memset(yproj, 0, im->ysize); - -#define GETPROJ(image, mask)\ - for (y = 0; y < im->ysize; y++) {\ - has_data = 0;\ - for (x = 0; x < im->xsize; x++)\ - if (im->image[y][x] & mask) {\ - has_data = 1;\ - xproj[x] = 1;\ - }\ - if (has_data)\ - yproj[y] = 1;\ - } - - if (im->image8) { - GETPROJ(image8, 0xff); - } else { - INT32 mask = 0xffffffff; - if (im->bands == 3) - ((UINT8*) &mask)[3] = 0; - GETPROJ(image32, mask); - } - - return 1; /* ok */ -} - - -int -ImagingGetExtrema(Imaging im, void *extrema) -{ - int x, y; - INT32 imin, imax; - FLOAT32 fmin, fmax; - - if (im->bands != 1) { - (void) ImagingError_ModeError(); - return -1; /* mismatch */ - } - - if (!im->xsize || !im->ysize) - return 0; /* zero size */ - - switch (im->type) { - case IMAGING_TYPE_UINT8: - imin = imax = im->image8[0][0]; - for (y = 0; y < im->ysize; y++) { - UINT8* in = im->image8[y]; - for (x = 0; x < im->xsize; x++) { - if (imin > in[x]) - imin = in[x]; - else if (imax < in[x]) - imax = in[x]; - } - } - ((UINT8*) extrema)[0] = (UINT8) imin; - ((UINT8*) extrema)[1] = (UINT8) imax; - break; - case IMAGING_TYPE_INT32: - imin = imax = im->image32[0][0]; - for (y = 0; y < im->ysize; y++) { - INT32* in = im->image32[y]; - for (x = 0; x < im->xsize; x++) { - if (imin > in[x]) - imin = in[x]; - else if (imax < in[x]) - imax = in[x]; - } - } - ((INT32*) extrema)[0] = imin; - ((INT32*) extrema)[1] = imax; - break; - case IMAGING_TYPE_FLOAT32: - fmin = fmax = ((FLOAT32*) im->image32[0])[0]; - for (y = 0; y < im->ysize; y++) { - FLOAT32* in = (FLOAT32*) im->image32[y]; - for (x = 0; x < im->xsize; x++) { - if (fmin > in[x]) - fmin = in[x]; - else if (fmax < in[x]) - fmax = in[x]; - } - } - ((FLOAT32*) extrema)[0] = fmin; - ((FLOAT32*) extrema)[1] = fmax; - break; - case IMAGING_TYPE_SPECIAL: - if (strcmp(im->mode, "I;16") == 0) { - imin = imax = ((UINT16*) im->image8[0])[0]; - for (y = 0; y < im->ysize; y++) { - UINT16* in = (UINT16 *) im->image[y]; - for (x = 0; x < im->xsize; x++) { - if (imin > in[x]) - imin = in[x]; - else if (imax < in[x]) - imax = in[x]; - } - } - ((UINT16*) extrema)[0] = (UINT16) imin; - ((UINT16*) extrema)[1] = (UINT16) imax; - break; - } - /* FALL THROUGH */ - default: - (void) ImagingError_ModeError(); - return -1; - } - return 1; /* ok */ -} - - -/* static ImagingColorItem* getcolors8(Imaging im, int maxcolors, int* size);*/ -static ImagingColorItem* getcolors32(Imaging im, int maxcolors, int* size); - -ImagingColorItem* -ImagingGetColors(Imaging im, int maxcolors, int* size) -{ - /* FIXME: add support for 8-bit images */ - return getcolors32(im, maxcolors, size); -} - -static ImagingColorItem* -getcolors32(Imaging im, int maxcolors, int* size) -{ - unsigned int h; - unsigned int i, incr; - int colors; - INT32 pixel_mask; - int x, y; - ImagingColorItem* table; - ImagingColorItem* v; - - unsigned int code_size; - unsigned int code_poly; - unsigned int code_mask; - - /* note: the hash algorithm used here is based on the dictionary - code in Python 2.1.3; the exact implementation is borrowed from - Python's Unicode property database (written by yours truly) /F */ - - static int SIZES[] = { - 4,3, 8,3, 16,3, 32,5, 64,3, 128,3, 256,29, 512,17, 1024,9, 2048,5, - 4096,83, 8192,27, 16384,43, 32768,3, 65536,45, 131072,9, 262144,39, - 524288,39, 1048576,9, 2097152,5, 4194304,3, 8388608,33, 16777216,27, - 33554432,9, 67108864,71, 134217728,39, 268435456,9, 536870912,5, - 1073741824,83, 0 - }; - - code_size = code_poly = code_mask = 0; - - for (i = 0; SIZES[i]; i += 2) { - if (SIZES[i] > maxcolors) { - code_size = SIZES[i]; - code_poly = SIZES[i+1]; - code_mask = code_size - 1; - break; - } - } - - /* printf("code_size=%d\n", code_size); */ - /* printf("code_poly=%d\n", code_poly); */ - - if (!code_size) - return ImagingError_MemoryError(); /* just give up */ - - if (!im->image32) - return ImagingError_ModeError(); - - table = calloc(code_size + 1, sizeof(ImagingColorItem)); - if (!table) - return ImagingError_MemoryError(); - - pixel_mask = 0xffffffff; - if (im->bands == 3) - ((UINT8*) &pixel_mask)[3] = 0; - - colors = 0; - - for (y = 0; y < im->ysize; y++) { - INT32* p = im->image32[y]; - for (x = 0; x < im->xsize; x++) { - INT32 pixel = p[x] & pixel_mask; - h = (pixel); /* null hashing */ - i = (~h) & code_mask; - v = &table[i]; - if (!v->count) { - /* add to table */ - if (colors++ == maxcolors) - goto overflow; - v->x = x; v->y = y; - v->pixel = pixel; - v->count = 1; - continue; - } else if (v->pixel == pixel) { - v->count++; - continue; - } - incr = (h ^ (h >> 3)) & code_mask; - if (!incr) - incr = code_mask; - for (;;) { - i = (i + incr) & code_mask; - v = &table[i]; - if (!v->count) { - /* add to table */ - if (colors++ == maxcolors) - goto overflow; - v->x = x; v->y = y; - v->pixel = pixel; - v->count = 1; - break; - } else if (v->pixel == pixel) { - v->count++; - break; - } - incr = incr << 1; - if (incr > code_mask) - incr = incr ^ code_poly; - } - } - } - -overflow: - - /* pack the table */ - for (x = y = 0; x < (int) code_size; x++) - if (table[x].count) { - if (x != y) - table[y] = table[x]; - y++; - } - table[y].count = 0; /* mark end of table */ - - *size = colors; - - return table; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h deleted file mode 100755 index 85d428b0d2d..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Gif.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * Declarations for a fast, suspendable GIF decoder. - * - * Copyright (c) Fredrik Lundh 1995-96. - */ - - -/* Max size for a LZW code word. */ - -#define GIFBITS 12 - -#define GIFTABLE (1< -#include /* memcpy() */ - -#include "Gif.h" - - -#define NEWLINE(state, context) {\ - state->x = 0;\ - state->y += context->step;\ - while (state->y >= state->ysize)\ - switch (context->interlace) {\ - case 1:\ - context->repeat = state->y = 4;\ - context->interlace = 2;\ - break;\ - case 2:\ - context->step = 4;\ - context->repeat = state->y = 2;\ - context->interlace = 3;\ - break;\ - case 3:\ - context->step = 2;\ - context->repeat = state->y = 1;\ - context->interlace = 0;\ - break;\ - default:\ - return -1;\ - }\ - if (state->y < state->ysize)\ - out = im->image8[state->y + state->yoff] + state->xoff;\ -} - - -int -ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes) -{ - UINT8* p; - UINT8* out; - int c, i; - int thiscode; - GIFDECODERSTATE *context = (GIFDECODERSTATE*) state->context; - - UINT8 *ptr = buffer; - - if (!state->state) { - - /* Initialise state */ - if (context->bits < 0 || context->bits > 8) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - - /* Clear code */ - context->clear = 1 << context->bits; - - /* End code */ - context->end = context->clear + 1; - - /* Interlace */ - if (context->interlace) { - context->interlace = 1; - context->step = context->repeat = 8; - } else - context->step = 1; - - state->state = 1; - } - - out = im->image8[state->y + state->yoff] + state->xoff + state->x; - - for (;;) { - - if (state->state == 1) { - - /* First free entry in table */ - context->next = context->clear + 2; - - /* Initial code size */ - context->codesize = context->bits + 1; - context->codemask = (1 << context->codesize) - 1; - - /* Buffer pointer. We fill the buffer from right, which - allows us to return all of it in one operation. */ - context->bufferindex = GIFBUFFER; - - state->state = 2; - } - - if (context->bufferindex < GIFBUFFER) { - - /* Return whole buffer in one chunk */ - i = GIFBUFFER - context->bufferindex; - p = &context->buffer[context->bufferindex]; - - context->bufferindex = GIFBUFFER; - - } else { - - /* Get current symbol */ - - while (context->bitcount < context->codesize) { - - if (context->blocksize > 0) { - - /* Read next byte */ - c = *ptr++; bytes--; - - context->blocksize--; - - /* New bits are shifted in from from the left. */ - context->bitbuffer |= (INT32) c << context->bitcount; - context->bitcount += 8; - - } else { - - /* New GIF block */ - - /* We don't start decoding unless we have a full block */ - if (bytes < 1) - return ptr - buffer; - c = *ptr; - if (bytes < c+1) - return ptr - buffer; - - context->blocksize = c; - - ptr++; bytes--; - - } - } - - /* Extract current symbol from bit buffer. */ - c = (int) context->bitbuffer & context->codemask; - - /* Adjust buffer */ - context->bitbuffer >>= context->codesize; - context->bitcount -= context->codesize; - - /* If c is less than "clear", it's a data byte. Otherwise, - it's either clear/end or a code symbol which should be - expanded. */ - - if (c == context->clear) { - if (state->state != 2) - state->state = 1; - continue; - } - - if (c == context->end) - break; - - i = 1; - p = &context->lastdata; - - if (state->state == 2) { - - /* First valid symbol after clear; use as is */ - if (c > context->clear) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - context->lastdata = context->lastcode = c; - state->state = 3; - - } else { - - thiscode = c; - - if (c > context->next) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - if (c == context->next) { - - /* c == next is allowed. not sure why. */ - - if (context->bufferindex <= 0) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - context->buffer[--context->bufferindex] = - context->lastdata; - - c = context->lastcode; - - } - - while (c >= context->clear) { - - /* Copy data string to buffer (beginning from right) */ - - if (context->bufferindex <= 0 || c >= GIFTABLE) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - context->buffer[--context->bufferindex] = - context->data[c]; - - c = context->link[c]; - } - - context->lastdata = c; - - if (context->next < GIFTABLE) { - - /* We'll only add this symbol if we have room - for it (take advise, Netscape!) */ - context->data[context->next] = c; - context->link[context->next] = context->lastcode; - - if (context->next == context->codemask && - context->codesize < GIFBITS) { - - /* Expand code size */ - context->codesize++; - context->codemask = (1 << context->codesize) - 1; - } - - context->next++; - - } - - context->lastcode = thiscode; - - } - } - - /* Copy the bytes into the image */ - if (state->y >= state->ysize) { - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - /* To squeeze some extra pixels out of this loop, we test for - some common cases and handle them separately. */ - - /* FIXME: should we handle the transparency index in here??? */ - - if (i == 1) { - if (state->x < state->xsize-1) { - /* Single pixel, not at the end of the line. */ - *out++ = p[0]; - state->x++; - continue; - } - } else if (state->x + i <= state->xsize) { - /* This string fits into current line. */ - memcpy(out, p, i); - out += i; - state->x += i; - if (state->x == state->xsize) { - NEWLINE(state, context); - } - continue; - } - - /* No shortcut, copy pixel by pixel */ - for (c = 0; c < i; c++) { - *out++ = p[c]; - if (++state->x >= state->xsize) { - NEWLINE(state, context); - } - } - } - - return ptr - buffer; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c deleted file mode 100755 index f4d07598fce..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/GifEncode.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * encoder for uncompressed GIF data - * - * history: - * 97-01-05 fl created (writes uncompressed data) - * 97-08-27 fl fixed off-by-one error in buffer size test - * 98-07-09 fl added interlace write support - * 99-02-07 fl rewritten, now uses a run-length encoding strategy - * 99-02-08 fl improved run-length encoding for long runs - * - * Copyright (c) Secret Labs AB 1997-99. - * Copyright (c) Fredrik Lundh 1997. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -#include "Gif.h" - -/* codes from 0 to 255 are literals */ -#define CLEAR_CODE 256 -#define EOF_CODE 257 -#define FIRST_CODE 258 -#define LAST_CODE 511 - -enum { INIT, ENCODE, ENCODE_EOF, FLUSH, EXIT }; - -/* to make things a little less complicated, we use a simple output - queue to hold completed blocks. the following inlined function - adds a byte to the current block. it allocates a new block if - necessary. */ - -static inline int -emit(GIFENCODERSTATE *context, int byte) -{ - /* write a byte to the output buffer */ - - if (!context->block || context->block->size == 255) { - GIFENCODERBLOCK* block; - - /* no room in the current block (or no current block); - allocate a new one */ - - /* add current block to end of flush queue */ - if (context->block) { - block = context->flush; - while (block && block->next) - block = block->next; - if (block) - block->next = context->block; - else - context->flush = context->block; - } - - /* get a new block */ - if (context->free) { - block = context->free; - context->free = NULL; - } else { - block = malloc(sizeof(GIFENCODERBLOCK)); - if (!block) - return 0; - } - - block->size = 0; - block->next = NULL; - - context->block = block; - - } - - /* write new byte to block */ - context->block->data[context->block->size++] = byte; - - return 1; -} - -/* write a code word to the current block. this is a macro to make - sure it's inlined on all platforms */ - -#define EMIT(code) {\ - context->bitbuffer |= ((INT32) (code)) << context->bitcount;\ - context->bitcount += 9;\ - while (context->bitcount >= 8) {\ - if (!emit(context, (UINT8) context->bitbuffer)) {\ - state->errcode = IMAGING_CODEC_MEMORY;\ - return 0;\ - }\ - context->bitbuffer >>= 8;\ - context->bitcount -= 8;\ - }\ -} - -/* write a run. we use a combination of literals and combinations of - literals. this can give quite decent compression for images with - long stretches of identical pixels. but remember: if you want - really good compression, use another file format. */ - -#define EMIT_RUN(label) {\ -label:\ - while (context->count > 0) {\ - int run = 2;\ - EMIT(context->last);\ - context->count--;\ - if (state->count++ == LAST_CODE) {\ - EMIT(CLEAR_CODE);\ - state->count = FIRST_CODE;\ - goto label;\ - }\ - while (context->count >= run) {\ - EMIT(state->count - 1);\ - context->count -= run;\ - run++;\ - if (state->count++ == LAST_CODE) {\ - EMIT(CLEAR_CODE);\ - state->count = FIRST_CODE;\ - goto label;\ - }\ - }\ - if (context->count > 1) {\ - EMIT(state->count - 1 - (run - context->count));\ - context->count = 0;\ - if (state->count++ == LAST_CODE) {\ - EMIT(CLEAR_CODE);\ - state->count = FIRST_CODE;\ - }\ - break;\ - }\ - }\ -} - -int -ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8* ptr; - int this; - - GIFENCODERBLOCK* block; - GIFENCODERSTATE *context = (GIFENCODERSTATE*) state->context; - - if (!state->state) { - - /* place a clear code in the output buffer */ - context->bitbuffer = CLEAR_CODE; - context->bitcount = 9; - - state->count = FIRST_CODE; - - if (context->interlace) { - context->interlace = 1; - context->step = 8; - } else - context->step = 1; - - context->last = -1; - - /* sanity check */ - if (state->xsize <= 0 || state->ysize <= 0) - state->state = ENCODE_EOF; - - } - - ptr = buf; - - for (;;) - - switch (state->state) { - - case INIT: - case ENCODE: - - /* identify and store a run of pixels */ - - if (state->x == 0 || state->x >= state->xsize) { - - if (!context->interlace && state->y >= state->ysize) { - state->state = ENCODE_EOF; - break; - } - - if (context->flush) { - state->state = FLUSH; - break; - } - - /* get another line of data */ - state->shuffle( - state->buffer, - (UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->xsize - ); - - state->x = 0; - - if (state->state == INIT) { - /* preload the run-length buffer and get going */ - context->last = state->buffer[0]; - context->count = state->x = 1; - state->state = ENCODE; - } - - /* step forward, according to the interlace settings */ - state->y += context->step; - while (context->interlace && state->y >= state->ysize) - switch (context->interlace) { - case 1: - state->y = 4; - context->interlace = 2; - break; - case 2: - context->step = 4; - state->y = 2; - context->interlace = 3; - break; - case 3: - context->step = 2; - state->y = 1; - context->interlace = 0; - break; - default: - /* just make sure we don't loop forever */ - context->interlace = 0; - } - - } - - this = state->buffer[state->x++]; - - if (this == context->last) - context->count++; - else { - EMIT_RUN(label1); - context->last = this; - context->count = 1; - } - break; - - - case ENCODE_EOF: - - /* write the final run */ - EMIT_RUN(label2); - - /* write an end of image marker */ - EMIT(EOF_CODE); - - /* empty the bit buffer */ - while (context->bitcount > 0) { - if (!emit(context, (UINT8) context->bitbuffer)) { - state->errcode = IMAGING_CODEC_MEMORY; - return 0; - } - context->bitbuffer >>= 8; - context->bitcount -= 8; - } - - /* flush the last block, and exit */ - if (context->block) { - GIFENCODERBLOCK* block; - block = context->flush; - while (block && block->next) - block = block->next; - if (block) - block->next = context->block; - else - context->flush = context->block; - context->block = NULL; - } - - state->state = EXIT; - - /* fall through... */ - - case EXIT: - case FLUSH: - - while (context->flush) { - - /* get a block from the flush queue */ - block = context->flush; - - if (block->size > 0) { - - /* make sure it fits into the output buffer */ - if (bytes < block->size+1) - return ptr - buf; - - ptr[0] = block->size; - memcpy(ptr+1, block->data, block->size); - - ptr += block->size+1; - bytes -= block->size+1; - - } - - context->flush = block->next; - - if (context->free) - free(context->free); - context->free = block; - - } - - if (state->state == EXIT) { - /* this was the last block! */ - if (context->free) - free(context->free); - state->errcode = IMAGING_CODEC_END; - return ptr - buf; - } - - state->state = ENCODE; - break; - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c deleted file mode 100755 index 14f5241dc5e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/HexDecode.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for hex encoded image data - * - * history: - * 96-05-16 fl Created - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#define HEX(v) ((v >= '0' && v <= '9') ? v - '0' :\ - (v >= 'a' && v <= 'f') ? v - 'a' + 10 :\ - (v >= 'A' && v <= 'F') ? v - 'A' + 10 : -1) - -int -ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8* ptr; - int a, b; - - ptr = buf; - - for (;;) { - - if (bytes < 2) - return ptr - buf; - - a = HEX(ptr[0]); - b = HEX(ptr[1]); - - if (a < 0 || b < 0) { - - ptr++; - bytes--; - - } else { - - ptr += 2; - bytes -= 2; - - state->buffer[state->x] = (a<<4) + b; - - if (++state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y], state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } - - } - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c deleted file mode 100755 index 513c844756e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Histo.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * histogram support - * - * history: - * 1995-06-15 fl Created. - * 1996-04-05 fl Fixed histogram for multiband images. - * 1997-02-23 fl Added mask support - * 1998-07-01 fl Added basic 32-bit float/integer support - * - * Copyright (c) 1997-2003 by Secret Labs AB. - * Copyright (c) 1995-2003 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -/* HISTOGRAM */ -/* -------------------------------------------------------------------- - * Take a histogram of an image. Returns a histogram object containing - * 256 slots per band in the input image. - */ - -void -ImagingHistogramDelete(ImagingHistogram h) -{ - if (h->histogram) - free(h->histogram); - free(h); -} - -ImagingHistogram -ImagingHistogramNew(Imaging im) -{ - ImagingHistogram h; - - /* Create histogram descriptor */ - h = calloc(1, sizeof(struct ImagingHistogramInstance)); - strcpy(h->mode, im->mode); - h->bands = im->bands; - h->histogram = calloc(im->pixelsize, 256 * sizeof(long)); - - return h; -} - -ImagingHistogram -ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax) -{ - ImagingSectionCookie cookie; - int x, y, i; - ImagingHistogram h; - INT32 imin, imax; - FLOAT32 fmin, fmax, scale; - - if (!im) - return ImagingError_ModeError(); - - if (imMask) { - /* Validate mask */ - if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) - return ImagingError_Mismatch(); - if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) - return ImagingError_ValueError("bad transparency mask"); - } - - h = ImagingHistogramNew(im); - - if (imMask) { - /* mask */ - if (im->image8) { - ImagingSectionEnter(&cookie); - for (y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++) - if (imMask->image8[y][x] != 0) - h->histogram[im->image8[y][x]]++; - ImagingSectionLeave(&cookie); - } else { /* yes, we need the braces. C isn't Python! */ - if (im->type != IMAGING_TYPE_UINT8) - return ImagingError_ModeError(); - ImagingSectionEnter(&cookie); - for (y = 0; y < im->ysize; y++) { - UINT8* in = (UINT8*) im->image32[y]; - for (x = 0; x < im->xsize; x++) - if (imMask->image8[y][x] != 0) { - h->histogram[(*in++)]++; - h->histogram[(*in++)+256]++; - h->histogram[(*in++)+512]++; - h->histogram[(*in++)+768]++; - } else - in += 4; - } - ImagingSectionLeave(&cookie); - } - } else { - /* mask not given; process pixels in image */ - if (im->image8) { - ImagingSectionEnter(&cookie); - for (y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++) - h->histogram[im->image8[y][x]]++; - ImagingSectionLeave(&cookie); - } else { - switch (im->type) { - case IMAGING_TYPE_UINT8: - ImagingSectionEnter(&cookie); - for (y = 0; y < im->ysize; y++) { - UINT8* in = (UINT8*) im->image[y]; - for (x = 0; x < im->xsize; x++) { - h->histogram[(*in++)]++; - h->histogram[(*in++)+256]++; - h->histogram[(*in++)+512]++; - h->histogram[(*in++)+768]++; - } - } - ImagingSectionLeave(&cookie); - break; - case IMAGING_TYPE_INT32: - if (!minmax) - return ImagingError_ValueError("min/max not given"); - if (!im->xsize || !im->ysize) - break; - imin = ((INT32*) minmax)[0]; - imax = ((INT32*) minmax)[1]; - if (imin >= imax) - break; - ImagingSectionEnter(&cookie); - scale = 255.0F / (imax - imin); - for (y = 0; y < im->ysize; y++) { - INT32* in = im->image32[y]; - for (x = 0; x < im->xsize; x++) { - i = (int) (((*in++)-imin)*scale); - if (i >= 0 && i < 256) - h->histogram[i]++; - } - } - ImagingSectionLeave(&cookie); - break; - case IMAGING_TYPE_FLOAT32: - if (!minmax) - return ImagingError_ValueError("min/max not given"); - if (!im->xsize || !im->ysize) - break; - fmin = ((FLOAT32*) minmax)[0]; - fmax = ((FLOAT32*) minmax)[1]; - if (fmin >= fmax) - break; - ImagingSectionEnter(&cookie); - scale = 255.0F / (fmax - fmin); - for (y = 0; y < im->ysize; y++) { - FLOAT32* in = (FLOAT32*) im->image32[y]; - for (x = 0; x < im->xsize; x++) { - i = (int) (((*in++)-fmin)*scale); - if (i >= 0 && i < 256) - h->histogram[i]++; - } - } - ImagingSectionLeave(&cookie); - break; - } - } - } - - return h; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h deleted file mode 100755 index 2effd387044..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImDib.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * Windows DIB specifics - * - * Copyright (c) Secret Labs AB 1997-98. - * Copyright (c) Fredrik Lundh 1996. - * - * See the README file for information on usage and redistribution. - */ - -#ifdef WIN32 - -#if (defined(_MSC_VER) && _MSC_VER >= 1200) || (defined __GNUC__) -/* already defined in basetsd.h */ -#undef INT32 -#undef INT64 -#undef UINT32 -#endif - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -struct ImagingDIBInstance { - /* Windows interface */ - HDC dc; - HBITMAP bitmap; - HGDIOBJ old_bitmap; - BITMAPINFO *info; - UINT8 *bits; - HPALETTE palette; - /* Used by cut and paste */ - char mode[4]; - int xsize, ysize; - int pixelsize; - int linesize; - ImagingShuffler pack; - ImagingShuffler unpack; -}; - -typedef struct ImagingDIBInstance* ImagingDIB; - -extern char* ImagingGetModeDIB(int size_out[2]); - -extern ImagingDIB ImagingNewDIB(const char *mode, int xsize, int ysize); - -extern void ImagingDeleteDIB(ImagingDIB im); - -extern void ImagingDrawDIB(ImagingDIB dib, int dc, int dst[4], int src[4]); -extern void ImagingExposeDIB(ImagingDIB dib, int dc); - -extern int ImagingQueryPaletteDIB(ImagingDIB dib, int dc); - -extern void ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4]); - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h deleted file mode 100755 index 4ffd6fdef9e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ImPlatform.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * platform declarations for the imaging core library - * - * Copyright (c) Fredrik Lundh 1995-2003. - */ - -#include "Python.h" - -/* Check that we have an ANSI compliant compiler */ -#ifndef HAVE_PROTOTYPES -#error Sorry, this library requires support for ANSI prototypes. -#endif -#ifndef STDC_HEADERS -#error Sorry, this library requires ANSI header files. -#endif - -#if defined(_MSC_VER) -#ifndef WIN32 -#define WIN32 -#endif -/* VC++ 4.0 is a bit annoying when it comes to precision issues (like - claiming that "float a = 0.0;" would lead to loss of precision). I - don't like to see warnings from my code, but since I still want to - keep it readable, I simply switch off a few warnings instead of adding - the tons of casts that VC++ seem to require. This code is compiled - with numerous other compilers as well, so any real errors are likely - to be catched anyway. */ -#pragma warning(disable: 4244) /* conversion from 'float' to 'int' */ -#endif - -#if defined(_MSC_VER) -#define inline __inline -#elif !defined(USE_INLINE) -#define inline -#endif - -#if SIZEOF_SHORT == 2 -#define INT16 short -#elif SIZEOF_INT == 2 -#define INT16 int -#else -#define INT16 short /* most things works just fine anyway... */ -#endif - -#if SIZEOF_SHORT == 4 -#define INT32 short -#elif SIZEOF_INT == 4 -#define INT32 int -#elif SIZEOF_LONG == 4 -#define INT32 long -#else -#error Cannot find required 32-bit integer type -#endif - -#if SIZEOF_LONG == 8 -#define INT64 long -#elif SIZEOF_LONG_LONG == 8 -#define INT64 long -#endif - -/* assume IEEE; tweak if necessary (patches are welcome) */ -#define FLOAT32 float -#define FLOAT64 double - -#define INT8 signed char -#define UINT8 unsigned char - -#define UINT16 unsigned INT16 -#define UINT32 unsigned INT32 diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h deleted file mode 100755 index 4609376adda..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Imaging.h +++ /dev/null @@ -1,497 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * declarations for the imaging core library - * - * Copyright (c) 1997-2005 by Secret Labs AB - * Copyright (c) 1995-2005 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - - -#include "ImPlatform.h" - - -#if defined(__cplusplus) -extern "C" { -#endif - - -#ifndef M_PI -#define M_PI 3.14159265359 -#endif - - -/* -------------------------------------------------------------------- */ - -/* - * Image data organization: - * - * mode bytes byte order - * ------------------------------- - * 1 1 1 - * L 1 L - * P 1 P - * I 4 I (32-bit integer, native byte order) - * F 4 F (32-bit IEEE float, native byte order) - * RGB 4 R, G, B, - - * RGBA 4 R, G, B, A - * CMYK 4 C, M, Y, K - * YCbCr 4 Y, Cb, Cr, - - * - * experimental modes (incomplete): - * LA 4 L, -, -, A - * PA 4 P, -, -, A - * I;16 2 I (16-bit integer, native byte order) - * - * "P" is an 8-bit palette mode, which should be mapped through the - * palette member to get an output image. Check palette->mode to - * find the corresponding "real" mode. - * - * For information on how to access Imaging objects from your own C - * extensions, see http://www.effbot.org/zone/pil-extending.htm - */ - -/* Handles */ - -typedef struct ImagingMemoryInstance* Imaging; - -typedef struct ImagingAccessInstance* ImagingAccess; -typedef struct ImagingHistogramInstance* ImagingHistogram; -typedef struct ImagingOutlineInstance* ImagingOutline; -typedef struct ImagingPaletteInstance* ImagingPalette; - -/* handle magics (used with PyCObject). */ -#define IMAGING_MAGIC "PIL Imaging" - -/* pixel types */ -#define IMAGING_TYPE_UINT8 0 -#define IMAGING_TYPE_INT32 1 -#define IMAGING_TYPE_FLOAT32 2 -#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */ - -struct ImagingMemoryInstance { - - /* Format */ - char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */ - int type; /* Data type (IMAGING_TYPE_*) */ - int depth; /* Depth (ignored in this version) */ - int bands; /* Number of bands (1, 2, 3, or 4) */ - int xsize; /* Image dimension. */ - int ysize; - - /* Colour palette (for "P" images only) */ - ImagingPalette palette; - - /* Data pointers */ - UINT8 **image8; /* Set for 8-bit images (pixelsize=1). */ - INT32 **image32; /* Set for 32-bit images (pixelsize=4). */ - - /* Internals */ - char **image; /* Actual raster data. */ - char *block; /* Set if data is allocated in a single block. */ - - int pixelsize; /* Size of a pixel, in bytes (1, 2 or 4) */ - int linesize; /* Size of a line, in bytes (xsize * pixelsize) */ - - /* Virtual methods */ - void (*destroy)(Imaging im); -}; - - -#define IMAGING_PIXEL_1(im,x,y) ((im)->image8[(y)][(x)]) -#define IMAGING_PIXEL_L(im,x,y) ((im)->image8[(y)][(x)]) -#define IMAGING_PIXEL_LA(im,x,y) ((im)->image[(y)][(x)*4]) -#define IMAGING_PIXEL_P(im,x,y) ((im)->image8[(y)][(x)]) -#define IMAGING_PIXEL_PA(im,x,y) ((im)->image[(y)][(x)*4]) -#define IMAGING_PIXEL_I(im,x,y) ((im)->image32[(y)][(x)]) -#define IMAGING_PIXEL_F(im,x,y) (((FLOAT32*)(im)->image32[y])[x]) -#define IMAGING_PIXEL_RGB(im,x,y) ((im)->image[(y)][(x)*4]) -#define IMAGING_PIXEL_RGBA(im,x,y) ((im)->image[(y)][(x)*4]) -#define IMAGING_PIXEL_CMYK(im,x,y) ((im)->image[(y)][(x)*4]) -#define IMAGING_PIXEL_YCbCr(im,x,y) ((im)->image[(y)][(x)*4]) - -#define IMAGING_PIXEL_UINT8(im,x,y) ((im)->image8[(y)][(x)]) -#define IMAGING_PIXEL_INT32(im,x,y) ((im)->image32[(y)][(x)]) -#define IMAGING_PIXEL_FLOAT32(im,x,y) (((FLOAT32*)(im)->image32[y])[x]) - -struct ImagingAccessInstance { - const char* mode; - void* (*line)(Imaging im, int x, int y); - void (*get_pixel)(Imaging im, int x, int y, void* pixel); - void (*put_pixel)(Imaging im, int x, int y, const void* pixel); -}; - -struct ImagingHistogramInstance { - - /* Format */ - char mode[4+1]; /* Band names (of corresponding source image) */ - int bands; /* Number of bands (1, 3, or 4) */ - - /* Data */ - long *histogram; /* Histogram (bands*256 longs) */ - -}; - - -struct ImagingPaletteInstance { - - /* Format */ - char mode[4+1]; /* Band names */ - - /* Data */ - UINT8 palette[1024];/* Palette data (same format as image data) */ - - INT16* cache; /* Palette cache (used for predefined palettes) */ - int keep_cache; /* This palette will be reused; keep cache */ - -}; - - -/* Objects */ -/* ------- */ - -extern int ImagingNewCount; - -extern Imaging ImagingNew(const char* mode, int xsize, int ysize); -extern Imaging ImagingNew2(const char* mode, Imaging imOut, Imaging imIn); -extern void ImagingDelete(Imaging im); - -extern Imaging ImagingNewBlock(const char* mode, int xsize, int ysize); -extern Imaging ImagingNewArray(const char* mode, int xsize, int ysize); -extern Imaging ImagingNewMap(const char* filename, int readonly, - const char* mode, int xsize, int ysize); - -extern Imaging ImagingNewPrologue(const char *mode, - unsigned xsize, unsigned ysize); -extern Imaging ImagingNewPrologueSubtype(const char *mode, - unsigned xsize, unsigned ysize, - int structure_size); -extern Imaging ImagingNewEpilogue(Imaging im); - -extern void ImagingCopyInfo(Imaging destination, Imaging source); - -extern void ImagingHistogramDelete(ImagingHistogram histogram); - -extern void ImagingAccessInit(void); -extern ImagingAccess ImagingAccessNew(Imaging im); -extern void _ImagingAccessDelete(Imaging im, ImagingAccess access); -#define ImagingAccessDelete(im, access) /* nop, for now */ -/*#define ImagingAccessDelete(im, access) \ - ((access)->dynamic ? _ImagingAccessDelete((im), (access)), 0 : 0)) */ - -extern ImagingPalette ImagingPaletteNew(const char *mode); -extern ImagingPalette ImagingPaletteNewBrowser(void); -extern ImagingPalette ImagingPaletteDuplicate(ImagingPalette palette); -extern void ImagingPaletteDelete(ImagingPalette palette); - -extern int ImagingPaletteCachePrepare(ImagingPalette palette); -extern void ImagingPaletteCacheUpdate(ImagingPalette palette, - int r, int g, int b); -extern void ImagingPaletteCacheDelete(ImagingPalette palette); - -#define ImagingPaletteCache(p, r, g, b)\ - p->cache[(r>>2) + (g>>2)*64 + (b>>2)*64*64] - -extern Imaging ImagingQuantize(Imaging im, int colours, int mode, int kmeans); - -/* Threading */ -/* --------- */ - -typedef void* ImagingSectionCookie; - -extern void ImagingSectionEnter(ImagingSectionCookie* cookie); -extern void ImagingSectionLeave(ImagingSectionCookie* cookie); - -/* Exceptions */ -/* ---------- */ - -extern void* ImagingError_IOError(void); -extern void* ImagingError_MemoryError(void); -extern void* ImagingError_ModeError(void); /* maps to ValueError by default */ -extern void* ImagingError_Mismatch(void); /* maps to ValueError by default */ -extern void* ImagingError_ValueError(const char* message); -extern void ImagingError_Clear(void); - -/* Transform callbacks */ -/* ------------------- */ - -/* standard transforms */ -#define IMAGING_TRANSFORM_AFFINE 0 -#define IMAGING_TRANSFORM_PERSPECTIVE 2 -#define IMAGING_TRANSFORM_QUAD 3 - - -/* standard filters */ -#define IMAGING_TRANSFORM_NEAREST 0 -#define IMAGING_TRANSFORM_ANTIALIAS 1 -#define IMAGING_TRANSFORM_BILINEAR 2 -#define IMAGING_TRANSFORM_BICUBIC 3 - -typedef int (*ImagingTransformMap)(double* X, double* Y, - int x, int y, void* data); -typedef int (*ImagingTransformFilter)(void* out, Imaging im, - double x, double y, - void* data); - -/* Image Manipulation Methods */ -/* -------------------------- */ - -extern Imaging ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha); -extern Imaging ImagingCopy(Imaging im); -extern Imaging ImagingConvert(Imaging im, const char* mode, ImagingPalette palette, int dither); -extern Imaging ImagingConvertInPlace(Imaging im, const char* mode); -extern Imaging ImagingConvertMatrix(Imaging im, const char *mode, float m[]); -extern Imaging ImagingCrop(Imaging im, int x0, int y0, int x1, int y1); -extern Imaging ImagingExpand(Imaging im, int x, int y, int mode); -extern Imaging ImagingFill(Imaging im, const void* ink); -extern int ImagingFill2( - Imaging into, const void* ink, Imaging mask, - int x0, int y0, int x1, int y1); -extern Imaging ImagingFillBand(Imaging im, int band, int color); -extern Imaging ImagingFillLinearGradient(const char* mode); -extern Imaging ImagingFillRadialGradient(const char* mode); -extern Imaging ImagingFilter( - Imaging im, int xsize, int ysize, const FLOAT32* kernel, - FLOAT32 offset, FLOAT32 divisor); -extern Imaging ImagingFlipLeftRight(Imaging imOut, Imaging imIn); -extern Imaging ImagingFlipTopBottom(Imaging imOut, Imaging imIn); -extern Imaging ImagingGaussianBlur(Imaging im, Imaging imOut, float radius); -extern Imaging ImagingGetBand(Imaging im, int band); -extern int ImagingGetBBox(Imaging im, int bbox[4]); -typedef struct { int x, y; INT32 count; INT32 pixel; } ImagingColorItem; -extern ImagingColorItem* ImagingGetColors(Imaging im, int maxcolors, - int *colors); -extern int ImagingGetExtrema(Imaging im, void *extrema); -extern int ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj); -extern ImagingHistogram ImagingGetHistogram( - Imaging im, Imaging mask, void *extrema); -extern Imaging ImagingModeFilter(Imaging im, int size); -extern Imaging ImagingNegative(Imaging im); -extern Imaging ImagingOffset(Imaging im, int xoffset, int yoffset); -extern int ImagingPaste( - Imaging into, Imaging im, Imaging mask, - int x0, int y0, int x1, int y1); -extern Imaging ImagingPoint( - Imaging im, const char* tablemode, const void* table); -extern Imaging ImagingPointTransform( - Imaging imIn, double scale, double offset); -extern Imaging ImagingPutBand(Imaging im, Imaging imIn, int band); -extern Imaging ImagingRankFilter(Imaging im, int size, int rank); -extern Imaging ImagingResize(Imaging imOut, Imaging imIn, int filter); -extern Imaging ImagingRotate( - Imaging imOut, Imaging imIn, double theta, int filter); -extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn); -extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn); -extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn); -extern Imaging ImagingStretch(Imaging imOut, Imaging imIn, int filter); -extern Imaging ImagingTransformPerspective( - Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, - double a[8], int filter, int fill); -extern Imaging ImagingTransformAffine( - Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, - double a[6], int filter, int fill); -extern Imaging ImagingTransformQuad( - Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, - double a[8], int filter, int fill); -extern Imaging ImagingTransform( - Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, - ImagingTransformMap transform, void* transform_data, - ImagingTransformFilter filter, void* filter_data, - int fill); -extern Imaging ImagingUnsharpMask( - Imaging im, Imaging imOut, float radius, int percent, int threshold); - -extern Imaging ImagingCopy2(Imaging imOut, Imaging imIn); -extern Imaging ImagingConvert2(Imaging imOut, Imaging imIn); - -/* Channel operations */ -/* any mode, except "F" */ -extern Imaging ImagingChopLighter(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopDarker(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopDifference(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopMultiply(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopScreen(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopAdd( - Imaging imIn1, Imaging imIn2, float scale, int offset); -extern Imaging ImagingChopSubtract( - Imaging imIn1, Imaging imIn2, float scale, int offset); -extern Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2); - -/* "1" images only */ -extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2); -extern Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2); - -/* Image measurement */ -extern void ImagingCrack(Imaging im, int x0, int y0); - -/* Graphics */ -struct ImagingAffineMatrixInstance { - float a[9]; -}; - -typedef struct ImagingAffineMatrixInstance *ImagingAffineMatrix; - -extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink, int op); -extern int ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, - const void* ink, int op); -extern int ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink, int fill, - int op); -extern int ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1, - const void* ink, int fill, int op); -extern int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, - const void* ink, int op); -extern int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1, - const void* ink, int width, int op); -extern int ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1, - int start, int end, const void* ink, int fill, - int op); -extern int ImagingDrawPoint(Imaging im, int x, int y, const void* ink, int op); -extern int ImagingDrawPolygon(Imaging im, int points, int *xy, - const void* ink, int fill, int op); -extern int ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1, - const void* ink, int fill, int op); - -/* Level 2 graphics (WORK IN PROGRESS) */ -extern ImagingOutline ImagingOutlineNew(void); -extern void ImagingOutlineDelete(ImagingOutline outline); - -extern int ImagingDrawOutline(Imaging im, ImagingOutline outline, - const void* ink, int fill, int op); - -extern int ImagingOutlineMove(ImagingOutline outline, float x, float y); -extern int ImagingOutlineLine(ImagingOutline outline, float x, float y); -extern int ImagingOutlineCurve(ImagingOutline outline, float x1, float y1, - float x2, float y2, float x3, float y3); -extern int ImagingOutlineTransform(ImagingOutline outline, double a[6]); - -extern int ImagingOutlineClose(ImagingOutline outline); - -/* Special effects */ -extern Imaging ImagingEffectSpread(Imaging imIn, int distance); -extern Imaging ImagingEffectNoise(int xsize, int ysize, float sigma); -extern Imaging ImagingEffectMandelbrot(int xsize, int ysize, - double extent[4], int quality); - -/* Obsolete */ -extern int ImagingToString(Imaging im, int orientation, char *buffer); -extern int ImagingFromString(Imaging im, int orientation, char *buffer); - - -/* File I/O */ -/* -------- */ - -/* Built-in drivers */ -extern Imaging ImagingOpenPPM(const char* filename); -extern int ImagingSavePPM(Imaging im, const char* filename); - -/* Utility functions */ -extern UINT32 ImagingCRC32(UINT32 crc, UINT8* buffer, int bytes); - -/* Codecs */ -typedef struct ImagingCodecStateInstance *ImagingCodecState; -typedef int (*ImagingCodec)(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); - -extern int ImagingBitDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingEpsEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingFliDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingGifDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingGifEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingHexDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -#ifdef HAVE_LIBJPEG -extern int ImagingJpegDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingJpegEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -#endif -extern int ImagingLzwDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -#ifdef HAVE_LIBMPEG -extern int ImagingMpegDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -#endif -extern int ImagingMspDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingPackbitsDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingPcdDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingPcxDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingPcxEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingRawDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingRawEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingSunRleDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingTgaRleDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingXbmDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingXbmEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -#ifdef HAVE_LIBZ -extern int ImagingZipDecode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -extern int ImagingZipEncode(Imaging im, ImagingCodecState state, - UINT8* buffer, int bytes); -#endif - -typedef void (*ImagingShuffler)(UINT8* out, const UINT8* in, int pixels); - -/* Public shufflers */ -extern void ImagingPackRGB(UINT8* out, const UINT8* in, int pixels); -extern void ImagingPackBGR(UINT8* out, const UINT8* in, int pixels); -extern void ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels); -extern void ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels); -extern void ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels); -extern void ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels); -extern void ImagingUnpackYCbCr(UINT8* out, const UINT8* in, int pixels); - -extern void ImagingConvertRGB2YCbCr(UINT8* out, const UINT8* in, int pixels); -extern void ImagingConvertYCbCr2RGB(UINT8* out, const UINT8* in, int pixels); - -extern ImagingShuffler ImagingFindUnpacker(const char* mode, - const char* rawmode, int* bits_out); -extern ImagingShuffler ImagingFindPacker(const char* mode, - const char* rawmode, int* bits_out); - -struct ImagingCodecStateInstance { - int count; - int state; - int errcode; - int x, y; - int ystep; - int xsize, ysize, xoff, yoff; - ImagingShuffler shuffle; - int bits, bytes; - UINT8 *buffer; - void *context; -}; - -/* Errcodes */ -#define IMAGING_CODEC_END 1 -#define IMAGING_CODEC_OVERRUN -1 -#define IMAGING_CODEC_BROKEN -2 -#define IMAGING_CODEC_UNKNOWN -3 -#define IMAGING_CODEC_CONFIG -8 -#define IMAGING_CODEC_MEMORY -9 - -#if defined(__cplusplus) -} -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h deleted file mode 100755 index d39165f3cfd..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Jpeg.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * declarations for the IJG JPEG codec interface. - * - * Copyright (c) 1995-2001 by Secret Labs AB - * Copyright (c) 1995-1996 by Fredrik Lundh - */ - -#include "jpeglib.h" - -#include - - -typedef struct { - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ -} JPEGERROR; - - -/* -------------------------------------------------------------------- */ -/* Decoder */ - -typedef struct { - struct jpeg_source_mgr pub; - int skip; -} JPEGSOURCE; - -typedef struct { - - /* CONFIGURATION */ - - /* Jpeg file mode (empty if not known) */ - char jpegmode[8+1]; - - /* Converter output mode (input to the shuffler). If empty, - convert conversions are disabled */ - char rawmode[8+1]; - - /* If set, trade quality for speed */ - int draft; - - /* Scale factor (1, 2, 4, 8) */ - int scale; - - /* PRIVATE CONTEXT (set by decoder) */ - - struct jpeg_decompress_struct cinfo; - - JPEGERROR error; - - JPEGSOURCE source; - -} JPEGSTATE; - - -/* -------------------------------------------------------------------- */ -/* Encoder */ - -typedef struct { - struct jpeg_destination_mgr pub; - /* might add something some other day */ -} JPEGDESTINATION; - -typedef struct { - - /* CONFIGURATION */ - - /* Quality (1-100, 0 means default) */ - int quality; - - /* Progressive mode */ - int progressive; - - /* Smoothing factor (1-100, 0 means none) */ - int smooth; - - /* Optimize Huffman tables (slow) */ - int optimize; - - /* Stream type (0=full, 1=tables only, 2=image only) */ - int streamtype; - - /* DPI setting (0=square pixels, otherwide DPI) */ - int xdpi, ydpi; - - /* Chroma Subsampling (-1=default, 0=none, 1=medium, 2=high) */ - int subsampling; - - /* Extra data (to be injected after header) */ - char* extra; int extra_size; - - /* PRIVATE CONTEXT (set by encoder) */ - - struct jpeg_compress_struct cinfo; - - JPEGERROR error; - - JPEGDESTINATION destination; - - int extra_offset; - -} JPEGENCODERSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c deleted file mode 100755 index 11b2767ba2f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegDecode.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for JPEG image data. - * - * history: - * 1996-05-02 fl Created - * 1996-05-05 fl Handle small JPEG files correctly - * 1996-05-28 fl Added "draft mode" support - * 1997-01-25 fl Added colour conversion override - * 1998-01-31 fl Adapted to libjpeg 6a - * 1998-07-12 fl Extended YCbCr support - * 1998-12-29 fl Added new state to handle suspension in multipass modes - * 2000-10-12 fl Suppress warnings - * 2000-12-04 fl Suppress errors beyond end of image data - * - * Copyright (c) 1998-2000 Secret Labs AB - * Copyright (c) 1996-2000 Fredrik Lundh - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - -#ifdef HAVE_LIBJPEG - -#undef HAVE_PROTOTYPES -#undef HAVE_STDLIB_H -#undef HAVE_STDDEF_H -#undef UINT8 -#undef UINT16 -#undef UINT32 -#undef INT16 -#undef INT32 - -#include "Jpeg.h" - - -/* -------------------------------------------------------------------- */ -/* Suspending input handler */ -/* -------------------------------------------------------------------- */ - -METHODDEF(void) -stub(j_decompress_ptr cinfo) -{ - /* empty */ -} - -METHODDEF(boolean) -fill_input_buffer(j_decompress_ptr cinfo) -{ - /* Suspension */ - return FALSE; -} - -METHODDEF(void) -skip_input_data(j_decompress_ptr cinfo, long num_bytes) -{ - JPEGSOURCE* source = (JPEGSOURCE*) cinfo->src; - - if (num_bytes > (long) source->pub.bytes_in_buffer) { - /* We need to skip more data than we have in the buffer. - This will force the JPEG library to suspend decoding. */ - source->skip = num_bytes - source->pub.bytes_in_buffer; - source->pub.next_input_byte += source->pub.bytes_in_buffer; - source->pub.bytes_in_buffer = 0; - } else { - /* Skip portion of the buffer */ - source->pub.bytes_in_buffer -= num_bytes; - source->pub.next_input_byte += num_bytes; - source->skip = 0; - } -} - - -GLOBAL(void) -jpeg_buffer_src(j_decompress_ptr cinfo, JPEGSOURCE* source) -{ - cinfo->src = (void*) source; - - /* Prepare for suspending reader */ - source->pub.init_source = stub; - source->pub.fill_input_buffer = fill_input_buffer; - source->pub.skip_input_data = skip_input_data; - source->pub.resync_to_restart = jpeg_resync_to_restart; - source->pub.term_source = stub; - source->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - - source->skip = 0; -} - - -/* -------------------------------------------------------------------- */ -/* Error handler */ -/* -------------------------------------------------------------------- */ - -METHODDEF(void) -error(j_common_ptr cinfo) -{ - JPEGERROR* error; - error = (JPEGERROR*) cinfo->err; - longjmp(error->setjmp_buffer, 1); -} - -METHODDEF(void) -output(j_common_ptr cinfo) -{ - /* nothing */ -} - -/* -------------------------------------------------------------------- */ -/* Decoder */ -/* -------------------------------------------------------------------- */ - -int -ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - JPEGSTATE* context = (JPEGSTATE*) state->context; - int ok; - - if (setjmp(context->error.setjmp_buffer)) { - /* JPEG error handler */ - jpeg_destroy_decompress(&context->cinfo); - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - if (!state->state) { - - /* Setup decompression context */ - context->cinfo.err = jpeg_std_error(&context->error.pub); - context->error.pub.error_exit = error; - context->error.pub.output_message = output; - jpeg_create_decompress(&context->cinfo); - jpeg_buffer_src(&context->cinfo, &context->source); - - /* Ready to decode */ - state->state = 1; - - } - - /* Load the source buffer */ - context->source.pub.next_input_byte = buf; - context->source.pub.bytes_in_buffer = bytes; - - if (context->source.skip > 0) { - skip_input_data(&context->cinfo, context->source.skip); - if (context->source.skip > 0) - return context->source.pub.next_input_byte - buf; - } - - switch (state->state) { - - case 1: - - /* Read JPEG header, until we find an image body. */ - do { - - /* Note that we cannot return unless we have decoded - as much data as possible. */ - ok = jpeg_read_header(&context->cinfo, FALSE); - - } while (ok == JPEG_HEADER_TABLES_ONLY); - - if (ok == JPEG_SUSPENDED) - break; - - /* Decoder settings */ - - /* jpegmode indicates whats in the file; if not set, we'll - trust the decoder */ - if (strcmp(context->jpegmode, "L") == 0) - context->cinfo.jpeg_color_space = JCS_GRAYSCALE; - else if (strcmp(context->jpegmode, "RGB") == 0) - context->cinfo.jpeg_color_space = JCS_RGB; - else if (strcmp(context->jpegmode, "CMYK") == 0) - context->cinfo.jpeg_color_space = JCS_CMYK; - else if (strcmp(context->jpegmode, "YCbCr") == 0) - context->cinfo.jpeg_color_space = JCS_YCbCr; - else if (strcmp(context->jpegmode, "YCbCrK") == 0) { - context->cinfo.jpeg_color_space = JCS_YCCK; - } - - /* rawmode indicates what we want from the decoder. if not - set, conversions are disabled */ - if (strcmp(context->rawmode, "L") == 0) - context->cinfo.out_color_space = JCS_GRAYSCALE; - else if (strcmp(context->rawmode, "RGB") == 0) - context->cinfo.out_color_space = JCS_RGB; - else if (strcmp(context->rawmode, "CMYK") == 0 || - strcmp(context->rawmode, "CMYK;I") == 0) - context->cinfo.out_color_space = JCS_CMYK; - else if (strcmp(context->rawmode, "YCbCr") == 0) - context->cinfo.out_color_space = JCS_YCbCr; - else if (strcmp(context->rawmode, "YCbCrK") == 0) - context->cinfo.out_color_space = JCS_YCCK; - else { - /* Disable decoder conversions */ - context->cinfo.jpeg_color_space = JCS_UNKNOWN; - context->cinfo.out_color_space = JCS_UNKNOWN; - } - - if (context->scale > 1) { - context->cinfo.scale_num = 1; - context->cinfo.scale_denom = context->scale; - } - if (context->draft) { - context->cinfo.do_fancy_upsampling = FALSE; - context->cinfo.dct_method = JDCT_FASTEST; - } - - state->state++; - /* fall through */ - - case 2: - - /* Set things up for decompression (this processes the entire - file if necessary to return data line by line) */ - if (!jpeg_start_decompress(&context->cinfo)) - break; - - state->state++; - /* fall through */ - - case 3: - - /* Decompress a single line of data */ - ok = 1; - while (state->y < state->ysize) { - ok = jpeg_read_scanlines(&context->cinfo, &state->buffer, 1); - if (ok != 1) - break; - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - state->y++; - } - if (ok != 1) - break; - state->state++; - /* fall through */ - - case 4: - - /* Finish decompression */ - if (!jpeg_finish_decompress(&context->cinfo)) { - /* FIXME: add strictness mode test */ - if (state->y < state->ysize) - break; - } - - /* Clean up */ - jpeg_destroy_decompress(&context->cinfo); - /* if (jerr.pub.num_warnings) return BROKEN; */ - return -1; - - } - - /* Return number of bytes consumed */ - return context->source.pub.next_input_byte - buf; - -} - -#endif - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c deleted file mode 100755 index 1e2191a69b0..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/JpegEncode.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * coder for JPEG data - * - * history: - * 1996-05-06 fl created - * 1996-07-16 fl don't drop last block of encoded data - * 1996-12-30 fl added quality and progressive settings - * 1997-01-08 fl added streamtype settings - * 1998-01-31 fl adapted to libjpeg 6a - * 1998-07-12 fl added YCbCr support - * 2001-04-16 fl added DPI write support - * - * Copyright (c) 1997-2001 by Secret Labs AB - * Copyright (c) 1995-1997 by Fredrik Lundh - * - * See the README file for details on usage and redistribution. - */ - - -#include "Imaging.h" - -#ifdef HAVE_LIBJPEG - -#undef HAVE_PROTOTYPES -#undef HAVE_STDLIB_H -#undef HAVE_STDDEF_H -#undef UINT8 -#undef UINT16 -#undef UINT32 -#undef INT16 -#undef INT32 - -#include "Jpeg.h" - -/* -------------------------------------------------------------------- */ -/* Suspending output handler */ -/* -------------------------------------------------------------------- */ - -METHODDEF(void) -stub(j_compress_ptr cinfo) -{ - /* empty */ -} - -METHODDEF(boolean) -empty_output_buffer (j_compress_ptr cinfo) -{ - /* Suspension */ - return FALSE; -} - -GLOBAL(void) -jpeg_buffer_dest(j_compress_ptr cinfo, JPEGDESTINATION* destination) -{ - cinfo->dest = (void*) destination; - - destination->pub.init_destination = stub; - destination->pub.empty_output_buffer = empty_output_buffer; - destination->pub.term_destination = stub; -} - - -/* -------------------------------------------------------------------- */ -/* Error handler */ -/* -------------------------------------------------------------------- */ - -METHODDEF(void) -error(j_common_ptr cinfo) -{ - JPEGERROR* error; - error = (JPEGERROR*) cinfo->err; - (*cinfo->err->output_message) (cinfo); - longjmp(error->setjmp_buffer, 1); -} - - -/* -------------------------------------------------------------------- */ -/* Encoder */ -/* -------------------------------------------------------------------- */ - -int -ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - JPEGENCODERSTATE* context = (JPEGENCODERSTATE*) state->context; - int ok; - - if (setjmp(context->error.setjmp_buffer)) { - /* JPEG error handler */ - jpeg_destroy_compress(&context->cinfo); - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - if (!state->state) { - - /* Setup compression context (very similar to the decoder) */ - context->cinfo.err = jpeg_std_error(&context->error.pub); - context->error.pub.error_exit = error; - jpeg_create_compress(&context->cinfo); - jpeg_buffer_dest(&context->cinfo, &context->destination); - - context->extra_offset = 0; - - /* Ready to encode */ - state->state = 1; - - } - - /* Load the destination buffer */ - context->destination.pub.next_output_byte = buf; - context->destination.pub.free_in_buffer = bytes; - - switch (state->state) { - - case 1: - - context->cinfo.image_width = state->xsize; - context->cinfo.image_height = state->ysize; - - switch (state->bits) { - case 8: - context->cinfo.input_components = 1; - context->cinfo.in_color_space = JCS_GRAYSCALE; - break; - case 24: - context->cinfo.input_components = 3; - if (strcmp(im->mode, "YCbCr") == 0) - context->cinfo.in_color_space = JCS_YCbCr; - else - context->cinfo.in_color_space = JCS_RGB; - break; - case 32: - context->cinfo.input_components = 4; - context->cinfo.in_color_space = JCS_CMYK; - break; - default: - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - - /* Compressor configuration */ - jpeg_set_defaults(&context->cinfo); - if (context->quality > 0) - jpeg_set_quality(&context->cinfo, context->quality, 1); - - /* Set subsampling options */ - switch (context->subsampling) - { - case 0: /* 1x1 1x1 1x1 (4:4:4) : None */ - { - context->cinfo.comp_info[0].h_samp_factor = 1; - context->cinfo.comp_info[0].v_samp_factor = 1; - context->cinfo.comp_info[1].h_samp_factor = 1; - context->cinfo.comp_info[1].v_samp_factor = 1; - context->cinfo.comp_info[2].h_samp_factor = 1; - context->cinfo.comp_info[2].v_samp_factor = 1; - break; - } - case 1: /* 2x1, 1x1, 1x1 (4:2:2) : Medium */ - { - context->cinfo.comp_info[0].h_samp_factor = 2; - context->cinfo.comp_info[0].v_samp_factor = 1; - context->cinfo.comp_info[1].h_samp_factor = 1; - context->cinfo.comp_info[1].v_samp_factor = 1; - context->cinfo.comp_info[2].h_samp_factor = 1; - context->cinfo.comp_info[2].v_samp_factor = 1; - break; - } - case 2: /* 2x2, 1x1, 1x1 (4:1:1) : High */ - { - context->cinfo.comp_info[0].h_samp_factor = 2; - context->cinfo.comp_info[0].v_samp_factor = 2; - context->cinfo.comp_info[1].h_samp_factor = 1; - context->cinfo.comp_info[1].v_samp_factor = 1; - context->cinfo.comp_info[2].h_samp_factor = 1; - context->cinfo.comp_info[2].v_samp_factor = 1; - break; - } - default: - { - /* Use the lib's default */ - break; - } - } - if (context->progressive) - jpeg_simple_progression(&context->cinfo); - context->cinfo.smoothing_factor = context->smooth; - context->cinfo.optimize_coding = (boolean) context->optimize; - if (context->xdpi > 0 && context->ydpi > 0) { - context->cinfo.density_unit = 1; /* dots per inch */ - context->cinfo.X_density = context->xdpi; - context->cinfo.Y_density = context->ydpi; - } - switch (context->streamtype) { - case 1: - /* tables only -- not yet implemented */ - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - case 2: - /* image only */ - jpeg_suppress_tables(&context->cinfo, TRUE); - jpeg_start_compress(&context->cinfo, FALSE); - /* suppress extra section */ - context->extra_offset = context->extra_size; - break; - default: - /* interchange stream */ - jpeg_start_compress(&context->cinfo, TRUE); - break; - } - state->state++; - /* fall through */ - - case 2: - - if (context->extra) { - /* copy extra buffer to output buffer */ - unsigned int n = context->extra_size - context->extra_offset; - if (n > context->destination.pub.free_in_buffer) - n = context->destination.pub.free_in_buffer; - memcpy(context->destination.pub.next_output_byte, - context->extra + context->extra_offset, n); - context->destination.pub.next_output_byte += n; - context->destination.pub.free_in_buffer -= n; - context->extra_offset += n; - if (context->extra_offset >= context->extra_size) - state->state++; - else - break; - } else - state->state++; - - case 3: - - ok = 1; - while (state->y < state->ysize) { - state->shuffle(state->buffer, - (UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->xsize); - ok = jpeg_write_scanlines(&context->cinfo, &state->buffer, 1); - if (ok != 1) - break; - state->y++; - } - - if (ok != 1) - break; - state->state++; - /* fall through */ - - case 4: - - /* Finish compression */ - if (context->destination.pub.free_in_buffer < 100) - break; - jpeg_finish_compress(&context->cinfo); - - /* Clean up */ - if (context->extra) - free(context->extra); - jpeg_destroy_compress(&context->cinfo); - /* if (jerr.pub.num_warnings) return BROKEN; */ - state->errcode = IMAGING_CODEC_END; - break; - - } - - /* Return number of bytes in output buffer */ - return context->destination.pub.next_output_byte - buf; - -} - -const char* -ImagingJpegVersion(void) -{ - static char version[20]; - sprintf(version, "%d.%d", JPEG_LIB_VERSION / 10, JPEG_LIB_VERSION % 10); - return version; -} - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h deleted file mode 100755 index 7d087ac4779..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Lzw.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * declarations for the TIFF LZW decoder. - * - * Copyright (c) Fredrik Lundh 1995-96. - */ - - -/* Max size for LZW code words */ - -#define LZWBITS 12 - -#define LZWTABLE (1< -#include /* memcpy() */ - -#include "Lzw.h" - - -int -ImagingLzwDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8* p; - int c, i; - int thiscode; - LZWSTATE* context = (LZWSTATE*) state->context; - - unsigned char *ptr = buf; - - if (!state->state) { - - /* Clear code */ - context->clear = 1 << 8; - - /* End code */ - context->end = context->clear + 1; - - state->state = 1; - } - - for (;;) { - - if (state->state == 1) { - - /* First free entry in table */ - context->next = context->clear + 2; - - /* Initial code size */ - context->codesize = 8 + 1; - context->codemask = (1 << context->codesize) - 1; - - /* Buffer pointer. We fill the buffer from right, which - allows us to return all of it in one operation. */ - context->bufferindex = LZWBUFFER; - - state->state = 2; - } - - if (context->bufferindex < LZWBUFFER) { - - /* Return whole buffer in one chunk */ - i = LZWBUFFER - context->bufferindex; - p = &context->buffer[context->bufferindex]; - - context->bufferindex = LZWBUFFER; - - } else { - - /* Get current symbol */ - while (context->bitcount < context->codesize) { - - if (bytes < 1) - return ptr - buf;; - - /* Read next byte */ - c = *ptr++; bytes--; - - /* New bits are shifted in from from the right. */ - context->bitbuffer = (context->bitbuffer << 8) | c; - context->bitcount += 8; - - } - - /* Extract current symbol from bit buffer. */ - c = (context->bitbuffer >> (context->bitcount - - context->codesize)) - & context->codemask; - - /* Adjust buffer */ - context->bitcount -= context->codesize; - - /* If c is less than clear, it's a data byte. Otherwise, - it's either clear/end or a code symbol which should be - expanded. */ - - if (c == context->clear) { - if (state->state != 2) - state->state = 1; - continue; - } - - if (c == context->end) - break; - - i = 1; - p = &context->lastdata; - - if (state->state == 2) { - - /* First valid symbol after clear; use as is */ - if (c > context->clear) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - context->lastdata = context->lastcode = c; - state->state = 3; - - } else { - - thiscode = c; - - if (c > context->next) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - if (c == context->next) { - - /* c == next is allowed, by some strange reason */ - if (context->bufferindex <= 0) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - context->buffer[--context->bufferindex] = context->lastdata; - c = context->lastcode; - } - - while (c >= context->clear) { - - /* Copy data string to buffer (beginning from right) */ - - if (context->bufferindex <= 0 || c >= LZWTABLE) { - state->errcode = IMAGING_CODEC_BROKEN; - return -1; - } - - context->buffer[--context->bufferindex] = - context->data[c]; - c = context->link[c]; - } - - context->lastdata = c; - - if (context->next < LZWTABLE) { - - /* While we still have room for it, add this - symbol to the table. */ - context->data[context->next] = c; - context->link[context->next] = context->lastcode; - - context->next++; - - if (context->next == context->codemask && - context->codesize < LZWBITS) { - - /* Expand code size */ - context->codesize++; - context->codemask = (1 << context->codesize) - 1; - - } - } - context->lastcode = thiscode; - } - } - - /* Update the output image */ - for (c = 0; c < i; c++) { - - state->buffer[state->x] = p[c]; - - if (++state->x >= state->bytes) { - - int x, bpp; - - /* Apply filter */ - switch (context->filter) { - case 2: - /* Horizontal differing ("prior") */ - bpp = (state->bits + 7) / 8; - for (x = bpp; x < state->bytes; x++) - state->buffer[x] += state->buffer[x-bpp]; - } - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) - /* End of file (errcode = 0) */ - return -1; - } - } - } - - return ptr - buf; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c deleted file mode 100755 index 5d2f031cf3c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Matrix.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * colour and luminance matrix transforms - * - * history: - * 1996-05-18 fl: created (brute force implementation) - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -#define CLIPF(v) ((v <= 0.0) ? 0 : (v >= 255.0F) ? 255 : (UINT8) v) - - -Imaging -ImagingConvertMatrix(Imaging im, const char *mode, float m[]) -{ - Imaging imOut; - int x, y; - - /* Assume there's enough data in the buffer */ - if (!im) - return (Imaging) ImagingError_ModeError(); - - if (strcmp(mode, "L") == 0 && im->bands == 3) { - - imOut = ImagingNew("L", im->xsize, im->ysize); - if (!imOut) - return NULL; - - for (y = 0; y < im->ysize; y++) { - UINT8* in = (UINT8*) im->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - - for (x = 0; x < im->xsize; x++) { - float v = m[0]*in[0] + m[1]*in[1] + m[2]*in[2] + m[3] + 0.5; - out[x] = CLIPF(v); - in += 4; - } - } - - } else if (strlen(mode) == 3 && im->bands == 3) { - - imOut = ImagingNew(mode, im->xsize, im->ysize); - if (!imOut) - return NULL; - - for (y = 0; y < im->ysize; y++) { - UINT8* in = (UINT8*) im->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - - for (x = 0; x < im->xsize; x++) { - float v0 = m[0]*in[0] + m[1]*in[1] + m[2]*in[2] + m[3] + 0.5; - float v1 = m[4]*in[0] + m[5]*in[1] + m[6]*in[2] + m[7] + 0.5; - float v2 = m[8]*in[0] + m[9]*in[1] + m[10]*in[2] + m[11] + 0.5; - out[0] = CLIPF(v0); - out[1] = CLIPF(v1); - out[2] = CLIPF(v2); - in += 4; out += 4; - } - } - } else - return (Imaging) ImagingError_ModeError(); - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c deleted file mode 100755 index ad11d87d4a3..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ModeFilter.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * mode filter - * - * history: - * 2002-06-08 fl Created (based on code from IFUNC95) - * 2004-10-05 fl Rewritten; use a simpler brute-force algorithm - * - * Copyright (c) Secret Labs AB 2002-2004. All rights reserved. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -Imaging -ImagingModeFilter(Imaging im, int size) -{ - Imaging imOut; - int x, y, i; - int xx, yy; - int maxcount; - UINT8 maxpixel; - int histogram[256]; - - if (!im || im->bands != 1 || im->type != IMAGING_TYPE_UINT8) - return (Imaging) ImagingError_ModeError(); - - imOut = ImagingNew(im->mode, im->xsize, im->ysize); - if (!imOut) - return NULL; - - size = size / 2; - - for (y = 0; y < imOut->ysize; y++) { - UINT8* out = &IMAGING_PIXEL_L(imOut, 0, y); - for (x = 0; x < imOut->xsize; x++) { - - /* calculate histogram over current area */ - - /* FIXME: brute force! to improve, update the histogram - incrementally. may also add a "frequent list", like in - the old implementation, but I'm not sure that's worth - the added complexity... */ - - memset(histogram, 0, sizeof(histogram)); - for (yy = y - size; yy <= y + size; yy++) - if (yy >= 0 && yy < imOut->ysize) { - UINT8* in = &IMAGING_PIXEL_L(im, 0, yy); - for (xx = x - size; xx <= x + size; xx++) - if (xx >= 0 && xx < imOut->xsize) - histogram[in[xx]]++; - } - - /* find most frequent pixel value in this region */ - maxpixel = 0; - maxcount = histogram[maxpixel]; - for (i = 1; i < 256; i++) - if (histogram[i] > maxcount) { - maxcount = histogram[i]; - maxpixel = (UINT8) i; - } - - if (maxcount > 2) - out[x] = maxpixel; - else - out[x] = IMAGING_PIXEL_L(im, x, y); - - } - - } - - ImagingCopyInfo(imOut, im); - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c deleted file mode 100755 index b611098d874..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/MspDecode.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for MSP version 2 data. - * - * history: - * 97-01-03 fl Created - * - * Copyright (c) Fredrik Lundh 1997. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - int n; - UINT8* ptr; - - ptr = buf; - - for (;;) { - - if (bytes < 1) - return ptr - buf; - - if (ptr[0] == 0) { - - /* Run (3 bytes block) */ - if (bytes < 3) - break; - - n = ptr[1]; - - if (state->x + n > state->bytes) { - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - memset(state->buffer + state->x, ptr[2], n); - - ptr += 3; - bytes -= 3; - - } else { - - /* Literal (1+n bytes block) */ - n = ptr[0]; - - if (bytes < 1 + n) - break; - - if (state->x + n > state->bytes) { - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - memcpy(state->buffer + state->x, ptr + 1, n); - - ptr += 1 + n; - bytes -= 1 + n; - - } - - state->x += n; - - if (state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } - - } - - return ptr - buf; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c deleted file mode 100755 index eaa790768f0..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Negative.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * negate image - * - * to do: - * FIXME: Maybe this should be implemented using ImagingPoint() - * - * history: - * 95-11-27 fl: Created - * - * Copyright (c) Fredrik Lundh 1995. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -Imaging -ImagingNegative(Imaging im) -{ - Imaging imOut; - int x, y; - - if (!im) - return (Imaging) ImagingError_ModeError(); - - imOut = ImagingNew(im->mode, im->xsize, im->ysize); - if (!imOut) - return NULL; - - for (y = 0; y < im->ysize; y++) - for (x = 0; x < im->linesize; x++) - imOut->image[y][x] = ~im->image[y][x]; - - return imOut; -} - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c deleted file mode 100755 index f6d6e510e5c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Offset.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * offset an image in x and y directions - * - * history: - * 96-07-22 fl: Created - * 98-11-01 cgw@pgt.com: Fixed negative-array index bug - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -Imaging -ImagingOffset(Imaging im, int xoffset, int yoffset) -{ - int x, y; - Imaging imOut; - - if (!im) - return (Imaging) ImagingError_ModeError(); - - imOut = ImagingNew(im->mode, im->xsize, im->ysize); - if (!imOut) - return NULL; - - ImagingCopyInfo(imOut, im); - - /* make offsets positive to avoid negative coordinates */ - xoffset %= im->xsize; - xoffset = im->xsize - xoffset; - if (xoffset < 0) - xoffset += im->xsize; - - yoffset %= im->ysize; - yoffset = im->ysize - yoffset; - if (yoffset < 0) - yoffset += im->ysize; - -#define OFFSET(image)\ - for (y = 0; y < im->ysize; y++)\ - for (x = 0; x < im->xsize; x++) {\ - int yi = (y + yoffset) % im->ysize;\ - int xi = (x + xoffset) % im->xsize;\ - imOut->image[y][x] = im->image[yi][xi];\ - } - - if (im->image8) - OFFSET(image8) - else - OFFSET(image32) - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c deleted file mode 100755 index 478de74996c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Pack.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * code to pack raw data - * - * history: - * 1996-04-30 fl Created - * 1996-05-12 fl Published a few RGB packers - * 1996-11-01 fl More RGB packers (Tk booster stuff) - * 1996-12-30 fl Added P;1, P;2 and P;4 packers - * 1997-06-02 fl Added F (F;32NF) packer - * 1997-08-28 fl Added 1 as L packer - * 1998-02-08 fl Added I packer - * 1998-03-09 fl Added mode field, RGBA/RGBX as RGB packers - * 1998-07-01 fl Added YCbCr support - * 1998-07-12 fl Added I 16 packer - * 1999-02-03 fl Added BGR packers - * 2003-09-26 fl Added LA/PA packers - * 2006-06-22 fl Added CMYK;I packer - * - * Copyright (c) 1997-2006 by Secret Labs AB. - * Copyright (c) 1996-1997 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#define R 0 -#define G 1 -#define B 2 -#define X 3 -#define A 3 - -#define C 0 -#define M 1 -#define Y 2 -#define K 3 - -/* byte swapping macros */ - -#define C16N\ - (out[0]=tmp[0], out[1]=tmp[1]); -#define C16S\ - (out[1]=tmp[0], out[0]=tmp[1]); -#define C32N\ - (out[0]=tmp[0], out[1]=tmp[1], out[2]=tmp[2], out[3]=tmp[3]); -#define C32S\ - (out[3]=tmp[0], out[2]=tmp[1], out[1]=tmp[2], out[0]=tmp[3]); -#define C64N\ - (out[0]=tmp[0], out[1]=tmp[1], out[2]=tmp[2], out[3]=tmp[3],\ - out[4]=tmp[4], out[5]=tmp[5], out[6]=tmp[6], out[7]=tmp[7]); -#define C64S\ - (out[7]=tmp[0], out[6]=tmp[1], out[5]=tmp[2], out[4]=tmp[3],\ - out[3]=tmp[4], out[2]=tmp[5], out[1]=tmp[6], out[0]=tmp[7]); - -#ifdef WORDS_BIGENDIAN -#define C16B C16N -#define C16L C16S -#define C32B C32N -#define C32L C32S -#define C64B C64N -#define C64L C64S -#else -#define C16B C16S -#define C16L C16N -#define C32B C32S -#define C32L C32N -#define C64B C64S -#define C64L C64N -#endif - -static void -pack1(UINT8* out, const UINT8* in, int pixels) -{ - int i, m, b; - /* bilevel (black is 0) */ - b = 0; m = 128; - for (i = 0; i < pixels; i++) { - if (in[i] != 0) - b |= m; - m >>= 1; - if (m == 0) { - *out++ = b; - b = 0; m = 128; - } - } - if (m != 128) - *out++ = b; -} - -static void -pack1I(UINT8* out, const UINT8* in, int pixels) -{ - int i, m, b; - /* bilevel (black is 1) */ - b = 0; m = 128; - for (i = 0; i < pixels; i++) { - if (in[i] == 0) - b |= m; - m >>= 1; - if (m == 0) { - *out++ = b; - b = 0; m = 128; - } - } - if (m != 128) - *out++ = b; -} - -static void -pack1R(UINT8* out, const UINT8* in, int pixels) -{ - int i, m, b; - /* bilevel, lsb first (black is 0) */ - b = 0; m = 1; - for (i = 0; i < pixels; i++) { - if (in[i] != 0) - b |= m; - m <<= 1; - if (m == 256){ - *out++ = b; - b = 0; m = 1; - } - } - if (m != 1) - *out++ = b; -} - -static void -pack1IR(UINT8* out, const UINT8* in, int pixels) -{ - int i, m, b; - /* bilevel, lsb first (black is 1) */ - b = 0; m = 1; - for (i = 0; i < pixels; i++) { - if (in[i] == 0) - b |= m; - m <<= 1; - if (m == 256){ - *out++ = b; - b = 0; m = 1; - } - } - if (m != 1) - *out++ = b; -} - -static void -pack1L(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* bilevel, stored as bytes */ - for (i = 0; i < pixels; i++) - out[i] = (in[i] != 0) ? 255 : 0; -} - -static void -packP4(UINT8* out, const UINT8* in, int pixels) -{ - while (pixels >= 2) { - *out++ = (in[0] << 4) | - (in[1] & 15); - in += 2; pixels -= 2; - } - - if (pixels) - out[0] = (in[0] << 4); -} - -static void -packP2(UINT8* out, const UINT8* in, int pixels) -{ - while (pixels >= 4) { - *out++ = (in[0] << 6) | - ((in[1] & 3) << 4) | - ((in[2] & 3) << 2) | - (in[3] & 3); - in += 4; pixels -= 4; - } - - switch (pixels) { - case 3: - out[0] = (in[0] << 6) | - ((in[1] & 3) << 4) | - ((in[2] & 3) << 2); - break; - case 2: - out[0] = (in[0] << 6) | - ((in[1] & 3) << 4); - case 1: - out[0] = (in[0] << 6); - } -} - -static void -packLA(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* LA, pixel interleaved */ - for (i = 0; i < pixels; i++) { - out[0] = in[R]; - out[1] = in[A]; - out += 2; in += 4; - } -} - -static void -packLAL(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* LA, line interleaved */ - for (i = 0; i < pixels; i++) { - out[i] = in[R]; - out[i+pixels] = in[A]; - in += 4; - } -} - -void -ImagingPackRGB(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB triplets */ - for (i = 0; i < pixels; i++) { - out[0] = in[R]; - out[1] = in[G]; - out[2] = in[B]; - out += 3; in += 4; - } -} - -void -ImagingPackXRGB(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* XRGB, triplets with left padding */ - for (i = 0; i < pixels; i++) { - out[0] = 0; - out[1] = in[R]; - out[2] = in[G]; - out[3] = in[B]; - out += 4; in += 4; - } -} - -void -ImagingPackBGR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, reversed bytes */ - for (i = 0; i < pixels; i++) { - out[0] = in[B]; - out[1] = in[G]; - out[2] = in[R]; - out += 3; in += 4; - } -} - -void -ImagingPackBGRX(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* BGRX, reversed bytes with right padding */ - for (i = 0; i < pixels; i++) { - out[0] = in[B]; - out[1] = in[G]; - out[2] = in[R]; - out[3] = 0; - out += 4; in += 4; - } -} - -void -ImagingPackXBGR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* XBGR, reversed bytes with left padding */ - for (i = 0; i < pixels; i++) { - out[0] = 0; - out[1] = in[B]; - out[2] = in[G]; - out[3] = in[R]; - out += 4; in += 4; - } -} - -void -ImagingPackBGRA(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* BGRX, reversed bytes with right padding */ - for (i = 0; i < pixels; i++) { - out[0] = in[B]; - out[1] = in[G]; - out[2] = in[R]; - out[3] = in[A]; - out += 4; in += 4; - } -} - -void -ImagingPackABGR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* XBGR, reversed bytes with left padding */ - for (i = 0; i < pixels; i++) { - out[0] = in[A]; - out[1] = in[B]; - out[2] = in[G]; - out[3] = in[R]; - out += 4; in += 4; - } -} - -static void -packRGBL(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, line interleaved */ - for (i = 0; i < pixels; i++) { - out[i] = in[R]; - out[i+pixels] = in[G]; - out[i+pixels+pixels] = in[B]; - in += 4; - } -} - -static void -packRGBXL(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGBX, line interleaved */ - for (i = 0; i < pixels; i++) { - out[i] = in[R]; - out[i+pixels] = in[G]; - out[i+pixels+pixels] = in[B]; - out[i+pixels+pixels+pixels] = in[X]; - in += 4; - } -} - -static void -packI16B(UINT8* out, const UINT8* in_, int pixels) -{ - int i; - INT32* in = (INT32*) in_; - UINT16 tmp_; - UINT8* tmp = (UINT8*) &tmp_; - for (i = 0; i < pixels; i++) { - if (in[0] <= 0) - tmp_ = 0; - else if (in[0] > 65535) - tmp_ = 65535; - else - tmp_ = in[0]; - C16B; - out += 2; in++; - } -} - -static void -packI32S(UINT8* out, const UINT8* in, int pixels) -{ - int i; - UINT8* tmp = (UINT8*) in; - for (i = 0; i < pixels; i++) { - C32L; - out += 4; tmp += 4; - } -} - -static void -copy1(UINT8* out, const UINT8* in, int pixels) -{ - /* L, P */ - memcpy(out, in, pixels); -} - -static void -copy2(UINT8* out, const UINT8* in, int pixels) -{ - /* I;16, etc */ - memcpy(out, in, pixels*2); -} - -static void -copy3(UINT8* out, const UINT8* in, int pixels) -{ - /* BGR;24, etc */ - memcpy(out, in, pixels*3); -} - -static void -copy4(UINT8* out, const UINT8* in, int pixels) -{ - /* RGBA, CMYK quadruples */ - memcpy(out, in, 4*pixels); -} - -static void -copy4I(UINT8* out, const UINT8* in, int pixels) -{ - /* RGBA, CMYK quadruples, inverted */ - int i; - for (i = 0; i < pixels*4; i++) - out[i] = ~in[i]; -} - -static void -band0(UINT8* out, const UINT8* in, int pixels) -{ - int i; - for (i = 0; i < pixels; i++, in += 4) - out[i] = in[0]; -} - -static void -band1(UINT8* out, const UINT8* in, int pixels) -{ - int i; - for (i = 0; i < pixels; i++, in += 4) - out[i] = in[1]; -} - -static void -band2(UINT8* out, const UINT8* in, int pixels) -{ - int i; - for (i = 0; i < pixels; i++, in += 4) - out[i] = in[2]; -} - -static void -band3(UINT8* out, const UINT8* in, int pixels) -{ - int i; - for (i = 0; i < pixels; i++, in += 4) - out[i] = in[3]; -} - -static struct { - const char* mode; - const char* rawmode; - int bits; - ImagingShuffler pack; -} packers[] = { - - /* bilevel */ - {"1", "1", 1, pack1}, - {"1", "1;I", 1, pack1I}, - {"1", "1;R", 1, pack1R}, - {"1", "1;IR", 1, pack1IR}, - {"1", "L", 8, pack1L}, - - /* greyscale */ - {"L", "L", 8, copy1}, - - /* greyscale w. alpha */ - {"LA", "LA", 16, packLA}, - {"LA", "LA;L", 16, packLAL}, - - /* palette */ - {"P", "P;1", 1, pack1}, - {"P", "P;2", 2, packP2}, - {"P", "P;4", 4, packP4}, - {"P", "P", 8, copy1}, - - /* palette w. alpha */ - {"PA", "PA", 16, packLA}, - {"PA", "PA;L", 16, packLAL}, - - /* true colour */ - {"RGB", "RGB", 24, ImagingPackRGB}, - {"RGB", "RGBX", 32, copy4}, - {"RGB", "XRGB", 32, ImagingPackXRGB}, - {"RGB", "BGR", 24, ImagingPackBGR}, - {"RGB", "BGRX", 32, ImagingPackBGRX}, - {"RGB", "XBGR", 32, ImagingPackXBGR}, - {"RGB", "RGB;L", 24, packRGBL}, - {"RGB", "R", 8, band0}, - {"RGB", "G", 8, band1}, - {"RGB", "B", 8, band2}, - - /* true colour w. alpha */ - {"RGBA", "RGBA", 32, copy4}, - {"RGBA", "RGBA;L", 32, packRGBXL}, - {"RGBA", "RGB", 24, ImagingPackRGB}, - {"RGBA", "BGR", 24, ImagingPackBGR}, - {"RGBA", "BGRA", 32, ImagingPackBGRA}, - {"RGBA", "ABGR", 32, ImagingPackABGR}, - {"RGBA", "R", 8, band0}, - {"RGBA", "G", 8, band1}, - {"RGBA", "B", 8, band2}, - {"RGBA", "A", 8, band3}, - - /* true colour w. padding */ - {"RGBX", "RGBX", 32, copy4}, - {"RGBX", "RGBX;L", 32, packRGBXL}, - {"RGBX", "RGB", 32, ImagingPackRGB}, - {"RGBX", "BGR", 32, ImagingPackBGR}, - {"RGBX", "BGRX", 32, ImagingPackBGRX}, - {"RGBX", "XBGR", 32, ImagingPackXBGR}, - {"RGBX", "R", 8, band0}, - {"RGBX", "G", 8, band1}, - {"RGBX", "B", 8, band2}, - {"RGBX", "X", 8, band3}, - - /* colour separation */ - {"CMYK", "CMYK", 32, copy4}, - {"CMYK", "CMYK;I", 32, copy4I}, - {"CMYK", "CMYK;L", 32, packRGBXL}, - {"CMYK", "C", 8, band0}, - {"CMYK", "M", 8, band1}, - {"CMYK", "Y", 8, band2}, - {"CMYK", "K", 8, band3}, - - /* video (YCbCr) */ - {"YCbCr", "YCbCr", 24, ImagingPackRGB}, - {"YCbCr", "YCbCr;L", 24, packRGBL}, - {"YCbCr", "YCbCrX", 32, copy4}, - {"YCbCr", "YCbCrK", 32, copy4}, - {"YCbCr", "Y", 8, band0}, - {"YCbCr", "Cb", 8, band1}, - {"YCbCr", "Cr", 8, band2}, - - /* integer */ - {"I", "I", 32, copy4}, - {"I", "I;16B", 16, packI16B}, - {"I", "I;32S", 32, packI32S}, - {"I", "I;32NS", 32, copy4}, - - /* floating point */ - {"F", "F", 32, copy4}, - {"F", "F;32F", 32, packI32S}, - {"F", "F;32NF", 32, copy4}, - - /* storage modes */ - {"I;16", "I;16", 16, copy2}, - {"I;16B", "I;16B", 16, copy2}, - {"I;16L", "I;16L", 16, copy2}, - {"BGR;15", "BGR;15", 16, copy2}, - {"BGR;16", "BGR;16", 16, copy2}, - {"BGR;24", "BGR;24", 24, copy3}, - - {NULL} /* sentinel */ -}; - - -ImagingShuffler -ImagingFindPacker(const char* mode, const char* rawmode, int* bits_out) -{ - int i; - - /* find a suitable pixel packer */ - for (i = 0; packers[i].rawmode; i++) - if (strcmp(packers[i].mode, mode) == 0 && - strcmp(packers[i].rawmode, rawmode) == 0) { - if (bits_out) - *bits_out = packers[i].bits; - return packers[i].pack; - } - return NULL; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c deleted file mode 100755 index aea8f04e301..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PackDecode.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for PackBits image data. - * - * history: - * 96-04-19 fl Created - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -int -ImagingPackbitsDecode(Imaging im, ImagingCodecState state, - UINT8* buf, int bytes) -{ - UINT8 n; - UINT8* ptr; - int i; - - ptr = buf; - - for (;;) { - - if (bytes < 1) - return ptr - buf; - - if (ptr[0] & 0x80) { - - if (ptr[0] == 0x80) { - /* Nop */ - ptr++; bytes--; - continue; - } - - /* Run */ - if (bytes < 2) - return ptr - buf; - - for (n = 257 - ptr[0]; n > 0; n--) { - if (state->x >= state->bytes) { - /* state->errcode = IMAGING_CODEC_OVERRUN; */ - break; - } - state->buffer[state->x++] = ptr[1]; - } - - ptr += 2; bytes -= 2; - - } else { - - /* Literal */ - n = ptr[0]+2; - - if (bytes < n) - return ptr - buf; - - for (i = 1; i < n; i++) { - if (state->x >= state->bytes) { - /* state->errcode = IMAGING_CODEC_OVERRUN; */ - break; - } - state->buffer[state->x++] = ptr[i]; - } - - ptr += n; bytes -= n; - - } - - if (state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } - - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c deleted file mode 100755 index bd4f4f1d637..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Palette.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * imaging palette object - * - * history: - * 1996-05-05 fl Added to library - * 1996-05-27 fl Added colour mapping stuff - * 1997-05-12 fl Support RGBA palettes - * 2005-02-09 fl Removed grayscale entries from web palette - * - * Copyright (c) Secret Labs AB 1997-2005. All rights reserved. - * Copyright (c) Fredrik Lundh 1995-1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#include - - -ImagingPalette -ImagingPaletteNew(const char* mode) -{ - /* Create a palette object */ - - int i; - ImagingPalette palette; - - if (strcmp(mode, "RGB") && strcmp(mode, "RGBA")) - return (ImagingPalette) ImagingError_ModeError(); - - palette = calloc(1, sizeof(struct ImagingPaletteInstance)); - if (!palette) - return (ImagingPalette) ImagingError_MemoryError(); - - strcpy(palette->mode, mode); - - /* Initialize to ramp */ - for (i = 0; i < 256; i++) { - palette->palette[i*4+0] = - palette->palette[i*4+1] = - palette->palette[i*4+2] = (UINT8) i; - palette->palette[i*4+3] = 255; /* opaque */ - } - - return palette; -} - -ImagingPalette -ImagingPaletteNewBrowser(void) -{ - /* Create a standard "browser" palette object */ - - int i, r, g, b; - ImagingPalette palette; - - palette = ImagingPaletteNew("RGB"); - if (!palette) - return NULL; - - /* Blank out unused entries */ - /* FIXME: Add 10-level windows palette here? */ - - for (i = 0; i < 10; i++) { - palette->palette[i*4+0] = - palette->palette[i*4+1] = - palette->palette[i*4+2] = 0; - } - - /* Simple 6x6x6 colour cube */ - - for (b = 0; b < 256; b += 51) - for (g = 0; g < 256; g += 51) - for (r = 0; r < 256; r += 51) { - palette->palette[i*4+0] = r; - palette->palette[i*4+1] = g; - palette->palette[i*4+2] = b; - i++; - } - - /* Blank out unused entries */ - /* FIXME: add 30-level greyscale wedge here? */ - - for (; i < 256; i++) { - palette->palette[i*4+0] = - palette->palette[i*4+1] = - palette->palette[i*4+2] = 0; - } - - return palette; -} - -ImagingPalette -ImagingPaletteDuplicate(ImagingPalette palette) -{ - /* Duplicate palette descriptor */ - - ImagingPalette new_palette; - - if (!palette) - return NULL; - - new_palette = malloc(sizeof(struct ImagingPaletteInstance)); - if (!new_palette) - return (ImagingPalette) ImagingError_MemoryError(); - - memcpy(new_palette, palette, sizeof(struct ImagingPaletteInstance)); - - /* Don't share the cache */ - new_palette->cache = NULL; - - return new_palette; -} - -void -ImagingPaletteDelete(ImagingPalette palette) -{ - /* Destroy palette object */ - - if (palette) { - if (palette->cache) - free(palette->cache); - free(palette); - } -} - - -/* -------------------------------------------------------------------- */ -/* Colour mapping */ -/* -------------------------------------------------------------------- */ - -/* This code is used to map RGB triplets to palette indices, using - a palette index cache. */ - -/* - * This implementation is loosely based on the corresponding code in - * the IJG JPEG library by Thomas G. Lane. Original algorithms by - * Paul Heckbert and Spencer W. Thomas. - * - * The IJG JPEG library is copyright (C) 1991-1995, Thomas G. Lane. */ - -#define DIST(a, b, s) (a - b) * (a - b) * s - -/* Colour weights (no scaling, for now) */ -#define RSCALE 1 -#define GSCALE 1 -#define BSCALE 1 - -/* Calculated scaled distances */ -#define RDIST(a, b) DIST(a, b, RSCALE*RSCALE) -#define GDIST(a, b) DIST(a, b, GSCALE*GSCALE) -#define BDIST(a, b) DIST(a, b, BSCALE*BSCALE) - -/* Incremental steps */ -#define RSTEP (4 * RSCALE) -#define GSTEP (4 * GSCALE) -#define BSTEP (4 * BSCALE) - -#define BOX 8 - -#define BOXVOLUME BOX*BOX*BOX - -void -ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b) -{ - int i, j; - unsigned int dmin[256], dmax; - int r0, g0, b0; - int r1, g1, b1; - int rc, gc, bc; - unsigned int d[BOXVOLUME]; - UINT8 c[BOXVOLUME]; - - /* Get box boundaries for the given (r,g,b)-triplet. Each box - covers eight cache slots (32 colour values, that is). */ - - r0 = r & 0xe0; r1 = r0 + 0x1f; rc = (r0 + r1) / 2; - g0 = g & 0xe0; g1 = g0 + 0x1f; gc = (g0 + g1) / 2; - b0 = b & 0xe0; b1 = b0 + 0x1f; bc = (b0 + b1) / 2; - - /* Step 1 -- Select relevant palette entries (after Heckbert) */ - - /* For each palette entry, calculate the min and max distances to - * any position in the box given by the colour we're looking for. */ - - dmax = (unsigned int) ~0; - - for (i = 0; i < 256; i++) { - - int r, g, b; - unsigned int tmin, tmax; - - /* Find min and max distances to any point in the box */ - r = palette->palette[i*4+0]; - tmin = (r < r0) ? RDIST(r, r1) : (r > r1) ? RDIST(r, r0) : 0; - tmax = (r <= rc) ? RDIST(r, r1) : RDIST(r, r0); - - g = palette->palette[i*4+1]; - tmin += (g < g0) ? GDIST(g, g1) : (g > g1) ? GDIST(g, g0) : 0; - tmax += (g <= gc) ? GDIST(g, g1) : GDIST(g, g0); - - b = palette->palette[i*4+2]; - tmin += (b < b0) ? BDIST(b, b1) : (b > b1) ? BDIST(b, b0) : 0; - tmax += (b <= bc) ? BDIST(b, b1) : BDIST(b, b0); - - dmin[i] = tmin; - if (tmax < dmax) - dmax = tmax; /* keep the smallest max distance only */ - - } - - /* Step 2 -- Incrementally update cache slot (after Thomas) */ - - /* Find the box containing the nearest palette entry, and update - * all slots in that box. We only check boxes for which the min - * distance is less than or equal the smallest max distance */ - - for (i = 0; i < BOXVOLUME; i++) - d[i] = (unsigned int) ~0; - - for (i = 0; i < 256; i++) - - if (dmin[i] <= dmax) { - - int rd, gd, bd; - int ri, gi, bi; - int rx, gx, bx; - - ri = (r0 - palette->palette[i*4+0]) * RSCALE; - gi = (g0 - palette->palette[i*4+1]) * GSCALE; - bi = (b0 - palette->palette[i*4+2]) * BSCALE; - - rd = ri*ri + gi*gi + bi*bi; - - ri = ri * (2 * RSTEP) + RSTEP * RSTEP; - gi = gi * (2 * GSTEP) + GSTEP * GSTEP; - bi = bi * (2 * BSTEP) + BSTEP * BSTEP; - - rx = ri; - for (r = j = 0; r < BOX; r++) { - gd = rd; gx = gi; - for (g = 0; g < BOX; g++) { - bd = gd; bx = bi; - for (b = 0; b < BOX; b++) { - if ((unsigned int) bd < d[j]) { - d[j] = bd; - c[j] = (UINT8) i; - } - bd += bx; - bx += 2 * BSTEP * BSTEP; - j++; - } - gd += gx; - gx += 2 * GSTEP * GSTEP; - } - rd += rx; - rx += 2 * RSTEP * RSTEP; - } - } - - /* Step 3 -- Update cache */ - - /* The c array now contains the closest match for each - * cache slot in the box. Update the cache. */ - - j = 0; - for (r = r0; r < r1; r+=4) - for (g = g0; g < g1; g+=4) - for (b = b0; b < b1; b+=4) - ImagingPaletteCache(palette, r, g, b) = c[j++]; -} - - -int -ImagingPaletteCachePrepare(ImagingPalette palette) -{ - /* Add a colour cache to a palette */ - - int i; - int entries = 64*64*64; - - if (palette->cache == NULL) { - - /* The cache is 512k. It might be a good idea to break it - up into a pointer array (e.g. an 8-bit image?) */ - - palette->cache = (INT16*) malloc(entries * sizeof(INT16)); - if (!palette->cache) { - (void) ImagingError_MemoryError(); - return -1; - } - - /* Mark all entries as empty */ - for (i = 0; i < entries; i++) - palette->cache[i] = 0x100; - - } - - return 0; -} - - -void -ImagingPaletteCacheDelete(ImagingPalette palette) -{ - /* Release the colour cache, if any */ - - if (palette && palette->cache) { - free(palette->cache); - palette->cache = NULL; - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c deleted file mode 100755 index b89dd640453..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Paste.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * paste image on another image - * - * history: - * 96-03-27 fl Created - * 96-07-16 fl Support "1", "L" and "RGBA" masks - * 96-08-16 fl Merged with opaque paste - * 97-01-17 fl Faster blending, added support for RGBa images - * 97-08-27 fl Faster masking for 32-bit images - * 98-02-02 fl Fixed MULDIV255 macro for gcc - * 99-02-02 fl Added "RGBa" mask support - * 99-02-06 fl Rewritten. Added support for masked fill operations. - * 99-12-08 fl Fixed matte fill. - * - * Copyright (c) Fredrik Lundh 1996-97. - * Copyright (c) Secret Labs AB 1997-99. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -/* like (a * b + 127) / 255), but much faster on most platforms */ -#define MULDIV255NEW(a, b, tmp)\ - (tmp = (a) * (b) + 128, ((((tmp) >> 8) + (tmp)) >> 8)) - -#define MULDIV255OLD(a, b, tmp)\ - (((a) * (b) + 127) / 255) - -#define MULDIV255 MULDIV255NEW - -#define BLEND(mask, in1, in2, tmp1, tmp2)\ - (MULDIV255(in1, 255 - mask, tmp1) + MULDIV255(in2, mask, tmp2)) - -#define PREBLEND(mask, in1, in2, tmp1)\ - (MULDIV255(in1, 255 - mask, tmp1) + in2) - -static inline void -paste(Imaging imOut, Imaging imIn, int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* paste opaque region */ - - int y; - - dx *= pixelsize; - sx *= pixelsize; - - xsize *= pixelsize; - - for (y = 0; y < ysize; y++) - memcpy(imOut->image[y+dy]+dx, imIn->image[y+sy]+sx, xsize); -} - -static inline void -paste_mask_1(Imaging imOut, Imaging imIn, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* paste with mode "1" mask */ - - int x, y; - - if (imOut->image8) { - - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* in = imIn->image8[y+sy]+sx; - UINT8* mask = imMask->image8[y+sy]+sx; - for (x = 0; x < xsize; x++) { - if (*mask++) - *out = *in; - out++, in++; - } - } - - } else { - - for (y = 0; y < ysize; y++) { - INT32* out = imOut->image32[y+dy]+dx; - INT32* in = imIn->image32[y+sy]+sx; - UINT8* mask = imMask->image8[y+sy]+sx; - for (x = 0; x < xsize; x++) { - if (*mask++) - *out = *in; - out++, in++; - } - } - } -} - -static inline void -paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* paste with mode "L" matte */ - - int x, y, i; - unsigned int tmp1, tmp2; - - if (imOut->image8) { - - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* in = imIn->image8[y+sy]+sx; - UINT8* mask = imMask->image8[y+sy]+sx; - for (x = 0; x < xsize; x++) { - *out = BLEND(*mask, *out, *in, tmp1, tmp2); - out++, in++, mask++; - } - } - - } else { - - for (y = 0; y < ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; - UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; - for (x = 0; x < xsize; x++) { - for (i = 0; i < pixelsize; i++) { - *out = BLEND(*mask, *out, *in, tmp1, tmp2); - out++, in++; - } - mask++; - } - } - } -} - -static inline void -paste_mask_RGBA(Imaging imOut, Imaging imIn, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* paste with mode "RGBA" matte */ - - int x, y, i; - unsigned int tmp1, tmp2; - - if (imOut->image8) { - - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* in = imIn->image8[y+sy]+sx; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; - for (x = 0; x < xsize; x++) { - *out = BLEND(*mask, *out, *in, tmp1, tmp2); - out++, in++, mask += 4; - } - } - - } else { - - for (y = 0; y < ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; - UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; - for (x = 0; x < xsize; x++) { - for (i = 0; i < pixelsize; i++) { - *out = BLEND(*mask, *out, *in, tmp1, tmp2); - out++, in++; - } - mask += 4; - } - } - } -} - - -static inline void -paste_mask_RGBa(Imaging imOut, Imaging imIn, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* paste with mode "RGBa" matte */ - - int x, y, i; - unsigned int tmp1; - - if (imOut->image8) { - - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* in = imIn->image8[y+sy]+sx; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; - for (x = 0; x < xsize; x++) { - *out = PREBLEND(*mask, *out, *in, tmp1); - out++, in++, mask += 4; - } - } - - } else { - - for (y = 0; y < ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; - UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx*4+3; - for (x = 0; x < xsize; x++) { - for (i = 0; i < pixelsize; i++) { - *out = PREBLEND(*mask, *out, *in, tmp1); - out++, in++; - } - mask += 4; - } - } - } -} - -int -ImagingPaste(Imaging imOut, Imaging imIn, Imaging imMask, - int dx0, int dy0, int dx1, int dy1) -{ - int xsize, ysize; - int pixelsize; - int sx0, sy0; - ImagingSectionCookie cookie; - - if (!imOut || !imIn) { - (void) ImagingError_ModeError(); - return -1; - } - - pixelsize = imOut->pixelsize; - - xsize = dx1 - dx0; - ysize = dy1 - dy0; - - if (xsize != imIn->xsize || ysize != imIn->ysize || - pixelsize != imIn->pixelsize) { - (void) ImagingError_Mismatch(); - return -1; - } - - if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { - (void) ImagingError_Mismatch(); - return -1; - } - - /* Determine which region to copy */ - sx0 = sy0 = 0; - if (dx0 < 0) - xsize += dx0, sx0 = -dx0, dx0 = 0; - if (dx0 + xsize > imOut->xsize) - xsize = imOut->xsize - dx0; - if (dy0 < 0) - ysize += dy0, sy0 = -dy0, dy0 = 0; - if (dy0 + ysize > imOut->ysize) - ysize = imOut->ysize - dy0; - - if (xsize <= 0 || ysize <= 0) - return 0; - - if (!imMask) { - ImagingSectionEnter(&cookie); - paste(imOut, imIn, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "1") == 0) { - ImagingSectionEnter(&cookie); - paste_mask_1(imOut, imIn, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "L") == 0) { - ImagingSectionEnter(&cookie); - paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBA") == 0) { - ImagingSectionEnter(&cookie); - paste_mask_RGBA(imOut, imIn, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBa") == 0) { - ImagingSectionEnter(&cookie); - paste_mask_RGBa(imOut, imIn, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else { - (void) ImagingError_ValueError("bad transparency mask"); - return -1; - } - - return 0; -} - -static inline void -fill(Imaging imOut, const void* ink_, int dx, int dy, - int xsize, int ysize, int pixelsize) -{ - /* fill opaque region */ - - int x, y; - UINT8 ink8 = 0; - INT32 ink32 = 0L; - - memcpy(&ink32, ink_, pixelsize); - memcpy(&ink8, ink_, sizeof(ink8)); - - if (imOut->image8 || ink32 == 0L) { - - dx *= pixelsize; - xsize *= pixelsize; - for (y = 0; y < ysize; y++) - memset(imOut->image[y+dy]+dx, ink8, xsize); - - } else { - - for (y = 0; y < ysize; y++) { - INT32* out = imOut->image32[y+dy]+dx; - for (x = 0; x < xsize; x++) - out[x] = ink32; - } - - } -} - -static inline void -fill_mask_1(Imaging imOut, const void* ink_, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* fill with mode "1" mask */ - - int x, y; - UINT8 ink8 = 0; - INT32 ink32 = 0L; - - memcpy(&ink32, ink_, pixelsize); - memcpy(&ink8, ink_, sizeof(ink8)); - - if (imOut->image8) { - - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* mask = imMask->image8[y+sy]+sx; - for (x = 0; x < xsize; x++) { - if (*mask++) - *out = ink8; - out++; - } - } - - } else { - - for (y = 0; y < ysize; y++) { - INT32* out = imOut->image32[y+dy]+dx; - UINT8* mask = imMask->image8[y+sy]+sx; - for (x = 0; x < xsize; x++) { - if (*mask++) - *out = ink32; - out++; - } - } - } -} - -static inline void -fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* fill with mode "L" matte */ - - int x, y, i; - unsigned int tmp1, tmp2; - - if (imOut->image8) { - - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* mask = imMask->image8[y+sy]+sx; - for (x = 0; x < xsize; x++) { - *out = BLEND(*mask, *out, ink[0], tmp1, tmp2); - out++, mask++; - } - } - - } else { - - for (y = 0; y < ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; - for (x = 0; x < xsize; x++) { - for (i = 0; i < pixelsize; i++) { - *out = BLEND(*mask, *out, ink[i], tmp1, tmp2); - out++; - } - mask++; - } - } - } -} - -static inline void -fill_mask_RGBA(Imaging imOut, const UINT8* ink, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* fill with mode "RGBA" matte */ - - int x, y, i; - unsigned int tmp1, tmp2; - - if (imOut->image8) { - - sx = sx*4+3; - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; - for (x = 0; x < xsize; x++) { - *out = BLEND(*mask, *out, ink[0], tmp1, tmp2); - out++, mask += 4; - } - } - - } else { - - dx *= pixelsize; - sx = sx*4 + 3; - for (y = 0; y < ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y+dy]+dx; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; - for (x = 0; x < xsize; x++) { - for (i = 0; i < pixelsize; i++) { - *out = BLEND(*mask, *out, ink[i], tmp1, tmp2); - out++; - } - mask += 4; - } - } - } -} - -static inline void -fill_mask_RGBa(Imaging imOut, const UINT8* ink, Imaging imMask, - int dx, int dy, int sx, int sy, - int xsize, int ysize, int pixelsize) -{ - /* fill with mode "RGBa" matte */ - - int x, y, i; - unsigned int tmp1; - - if (imOut->image8) { - - sx = sx*4 + 3; - for (y = 0; y < ysize; y++) { - UINT8* out = imOut->image8[y+dy]+dx; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; - for (x = 0; x < xsize; x++) { - *out = PREBLEND(*mask, *out, ink[0], tmp1); - out++, mask += 4; - } - } - - } else { - - dx *= pixelsize; - sx = sx*4 + 3; - for (y = 0; y < ysize; y++) { - UINT8* out = (UINT8*) imOut->image[y+dy]+dx; - UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; - for (x = 0; x < xsize; x++) { - for (i = 0; i < pixelsize; i++) { - *out = PREBLEND(*mask, *out, ink[i], tmp1); - out++; - } - mask += 4; - } - } - } -} - -int -ImagingFill2(Imaging imOut, const void* ink, Imaging imMask, - int dx0, int dy0, int dx1, int dy1) -{ - ImagingSectionCookie cookie; - int xsize, ysize; - int pixelsize; - int sx0, sy0; - - if (!imOut || !ink) { - (void) ImagingError_ModeError(); - return -1; - } - - pixelsize = imOut->pixelsize; - - xsize = dx1 - dx0; - ysize = dy1 - dy0; - - if (imMask && (xsize != imMask->xsize || ysize != imMask->ysize)) { - (void) ImagingError_Mismatch(); - return -1; - } - - /* Determine which region to fill */ - sx0 = sy0 = 0; - if (dx0 < 0) - xsize += dx0, sx0 = -dx0, dx0 = 0; - if (dx0 + xsize > imOut->xsize) - xsize = imOut->xsize - dx0; - if (dy0 < 0) - ysize += dy0, sy0 = -dy0, dy0 = 0; - if (dy0 + ysize > imOut->ysize) - ysize = imOut->ysize - dy0; - - if (xsize <= 0 || ysize <= 0) - return 0; - - if (!imMask) { - ImagingSectionEnter(&cookie); - fill(imOut, ink, dx0, dy0, xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "1") == 0) { - ImagingSectionEnter(&cookie); - fill_mask_1(imOut, ink, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "L") == 0) { - ImagingSectionEnter(&cookie); - fill_mask_L(imOut, ink, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBA") == 0) { - ImagingSectionEnter(&cookie); - fill_mask_RGBA(imOut, ink, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else if (strcmp(imMask->mode, "RGBa") == 0) { - ImagingSectionEnter(&cookie); - fill_mask_RGBa(imOut, ink, imMask, dx0, dy0, sx0, sy0, - xsize, ysize, pixelsize); - ImagingSectionLeave(&cookie); - - } else { - (void) ImagingError_ValueError("bad transparency mask"); - return -1; - } - - return 0; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c deleted file mode 100755 index b6898e301d1..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcdDecode.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for uncompressed PCD image data. - * - * history: - * 96-05-10 fl Created - * 96-05-18 fl New tables - * 97-01-25 fl Use PhotoYCC unpacker - * - * notes: - * This driver supports uncompressed PCD modes only - * (resolutions up to 768x512). - * - * Copyright (c) Fredrik Lundh 1996-97. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - int x; - int chunk; - UINT8* out; - UINT8* ptr; - - ptr = buf; - - chunk = 3 * state->xsize; - - for (;;) { - - /* We need data for two full lines before we can do anything */ - if (bytes < chunk) - return ptr - buf; - - /* Unpack first line */ - out = state->buffer; - for (x = 0; x < state->xsize; x++) { - out[0] = ptr[x]; - out[1] = ptr[(x+4*state->xsize)/2]; - out[2] = ptr[(x+5*state->xsize)/2]; - out += 4; - } - - state->shuffle((UINT8*) im->image[state->y], - state->buffer, state->xsize); - - if (++state->y >= state->ysize) - return -1; /* This can hardly happen */ - - /* Unpack second line */ - out = state->buffer; - for (x = 0; x < state->xsize; x++) { - out[0] = ptr[x+state->xsize]; - out[1] = ptr[(x+4*state->xsize)/2]; - out[2] = ptr[(x+5*state->xsize)/2]; - out += 4; - } - - state->shuffle((UINT8*) im->image[state->y], - state->buffer, state->xsize); - - if (++state->y >= state->ysize) - return -1; - - ptr += chunk; - bytes -= chunk; - - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c deleted file mode 100755 index ab82b23adcc..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxDecode.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for PCX image data. - * - * history: - * 95-09-14 fl Created - * - * Copyright (c) Fredrik Lundh 1995. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -int -ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8 n; - UINT8* ptr; - - ptr = buf; - - for (;;) { - - if (bytes < 1) - return ptr - buf; - - if ((*ptr & 0xC0) == 0xC0) { - - /* Run */ - if (bytes < 2) - return ptr - buf; - - n = ptr[0] & 0x3F; - - while (n > 0) { - if (state->x >= state->bytes) { - state->errcode = IMAGING_CODEC_OVERRUN; - break; - } - state->buffer[state->x++] = ptr[1]; - n--; - } - - ptr += 2; bytes -= 2; - - } else { - - /* Literal */ - state->buffer[state->x++] = ptr[0]; - ptr++; bytes--; - - } - - if (state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } - - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c deleted file mode 100755 index 87d59946388..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/PcxEncode.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * encoder for PCX data - * - * history: - * 99-02-07 fl created - * - * Copyright (c) Fredrik Lundh 1999. - * Copyright (c) Secret Labs AB 1999. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -enum { INIT, FETCH, ENCODE }; - -/* we're reusing "ystep" to store the last value */ -#define LAST ystep - -int -ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8* ptr; - int this; - - ptr = buf; - - if (!state->state) { - - /* sanity check */ - if (state->xsize <= 0 || state->ysize <= 0) { - state->errcode = IMAGING_CODEC_END; - return 0; - } - - state->bytes = (state->xsize*state->bits + 7) / 8; - state->state = FETCH; - - } - - for (;;) - - switch (state->state) { - case FETCH: - - /* get a line of data */ - if (state->y >= state->ysize) { - state->errcode = IMAGING_CODEC_END; - return ptr - buf; - } - - state->shuffle(state->buffer, - (UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->xsize); - - state->y++; - - state->count = 1; - state->LAST = state->buffer[0]; - - state->x = 1; - - state->state = ENCODE; - /* fall through */ - - case ENCODE: - - /* compress this line */ - - /* when we arrive here, "count" contains the number of - bytes having the value of "LAST" that we've already - seen */ - - while (state->x < state->bytes) { - - if (state->count == 63) { - - /* this run is full; flush it */ - if (bytes < 2) - return ptr - buf; - *ptr++ = 0xff; - *ptr++ = state->LAST; - bytes -= 2; - - state->count = 0; - - } - - this = state->buffer[state->x]; - - if (this == state->LAST) { - - /* extend the current run */ - state->x++; - state->count++; - - } else { - - /* start a new run */ - if (state->count == 1 && (state->LAST < 0xc0)) { - if (bytes < 1) - return ptr - buf; - *ptr++ = state->LAST; - bytes--; - } else { - if (state->count > 0) { - if (bytes < 2) - return ptr - buf; - *ptr++ = 0xc0 | state->count; - *ptr++ = state->LAST; - bytes -= 2; - } - } - - state->LAST = this; - state->count = 1; - - state->x++; - - } - } - - /* end of line; flush the current run */ - if (state->count == 1 && (state->LAST < 0xc0)) { - if (bytes < 1) - return ptr - buf; - *ptr++ = state->LAST; - bytes--; - } else { - if (state->count > 0) { - if (bytes < 2) - return ptr - buf; - *ptr++ = 0xc0 | state->count; - *ptr++ = state->LAST; - bytes -= 2; - } - } - - /* read next line */ - state->state = FETCH; - break; - - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c deleted file mode 100755 index 2593dca57ec..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Point.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * point (pixel) translation - * - * history: - * 1995-11-27 fl Created - * 1996-03-31 fl Fixed colour support - * 1996-08-13 fl Support 8-bit to "1" thresholding - * 1997-05-31 fl Added floating point transform - * 1998-07-02 fl Added integer point transform - * 1998-07-17 fl Support L to anything lookup - * 2004-12-18 fl Refactored; added I to L lookup - * - * Copyright (c) 1997-2004 by Secret Labs AB. - * Copyright (c) 1995-2004 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -typedef struct { - const void* table; -} im_point_context; - -static void -im_point_8_8(Imaging imOut, Imaging imIn, im_point_context* context) -{ - int x, y; - /* 8-bit source, 8-bit destination */ - UINT8* table = (UINT8*) context->table; - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = imIn->image8[y]; - UINT8* out = imOut->image8[y]; - for (x = 0; x < imIn->xsize; x++) - out[x] = table[in[x]]; - } -} - -static void -im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context* context) -{ - int x, y; - /* 2x8-bit source, 2x8-bit destination */ - UINT8* table = (UINT8*) context->table; - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - for (x = 0; x < imIn->xsize; x++) { - out[0] = table[in[0]]; - out[3] = table[in[3]+256]; - in += 4; out += 4; - } - } -} - -static void -im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context* context) -{ - int x, y; - /* 3x8-bit source, 3x8-bit destination */ - UINT8* table = (UINT8*) context->table; - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - for (x = 0; x < imIn->xsize; x++) { - out[0] = table[in[0]]; - out[1] = table[in[1]+256]; - out[2] = table[in[2]+512]; - in += 4; out += 4; - } - } -} - -static void -im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context* context) -{ - int x, y; - /* 4x8-bit source, 4x8-bit destination */ - UINT8* table = (UINT8*) context->table; - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = (UINT8*) imIn->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; - for (x = 0; x < imIn->xsize; x++) { - out[0] = table[in[0]]; - out[1] = table[in[1]+256]; - out[2] = table[in[2]+512]; - out[3] = table[in[3]+768]; - in += 4; out += 4; - } - } -} - -static void -im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context) -{ - int x, y; - /* 8-bit source, 32-bit destination */ - INT32* table = (INT32*) context->table; - for (y = 0; y < imIn->ysize; y++) { - UINT8* in = imIn->image8[y]; - INT32* out = imOut->image32[y]; - for (x = 0; x < imIn->xsize; x++) - out[x] = table[in[x]]; - } -} - -static void -im_point_32_8(Imaging imOut, Imaging imIn, im_point_context* context) -{ - int x, y; - /* 32-bit source, 8-bit destination */ - UINT8* table = (UINT8*) context->table; - for (y = 0; y < imIn->ysize; y++) { - INT32* in = imIn->image32[y]; - UINT8* out = imOut->image8[y]; - for (x = 0; x < imIn->xsize; x++) { - int v = in[x]; - if (v < 0) - v = 0; - else if (v > 65535) - v = 65535; - out[x] = table[v]; - } - } -} - -Imaging -ImagingPoint(Imaging imIn, const char* mode, const void* table) -{ - /* lookup table transform */ - - ImagingSectionCookie cookie; - Imaging imOut; - im_point_context context; - void (*point)(Imaging imIn, Imaging imOut, im_point_context* context); - - if (!imIn) - return (Imaging) ImagingError_ModeError(); - - if (!mode) - mode = imIn->mode; - - if (imIn->type != IMAGING_TYPE_UINT8) { - if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0) - goto mode_mismatch; - } else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0) - goto mode_mismatch; - - imOut = ImagingNew(mode, imIn->xsize, imIn->ysize); - if (!imOut) - return NULL; - - /* find appropriate handler */ - if (imIn->type == IMAGING_TYPE_UINT8) { - if (imIn->bands == imOut->bands && imIn->type == imOut->type) { - switch (imIn->bands) { - case 1: - point = im_point_8_8; - break; - case 2: - point = im_point_2x8_2x8; - break; - case 3: - point = im_point_3x8_3x8; - break; - case 4: - point = im_point_4x8_4x8; - break; - default: - /* this cannot really happen */ - point = im_point_8_8; - break; - } - } else - point = im_point_8_32; - } else - point = im_point_32_8; - - ImagingCopyInfo(imOut, imIn); - - ImagingSectionEnter(&cookie); - - context.table = table; - point(imOut, imIn, &context); - - ImagingSectionLeave(&cookie); - - return imOut; - - mode_mismatch: - return (Imaging) ImagingError_ValueError( - "point operation not supported for this mode" - ); -} - - -Imaging -ImagingPointTransform(Imaging imIn, double scale, double offset) -{ - /* scale/offset transform */ - - ImagingSectionCookie cookie; - Imaging imOut; - int x, y; - - if (!imIn || (strcmp(imIn->mode, "I") != 0 && - strcmp(imIn->mode, "I;16") != 0 && - strcmp(imIn->mode, "F") != 0)) - return (Imaging) ImagingError_ModeError(); - - imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - if (!imOut) - return NULL; - - ImagingCopyInfo(imOut, imIn); - - switch (imIn->type) { - case IMAGING_TYPE_INT32: - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - INT32* in = imIn->image32[y]; - INT32* out = imOut->image32[y]; - /* FIXME: add clipping? */ - for (x = 0; x < imIn->xsize; x++) - out[x] = in[x] * scale + offset; - } - ImagingSectionLeave(&cookie); - break; - case IMAGING_TYPE_FLOAT32: - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - FLOAT32* in = (FLOAT32*) imIn->image32[y]; - FLOAT32* out = (FLOAT32*) imOut->image32[y]; - for (x = 0; x < imIn->xsize; x++) - out[x] = in[x] * scale + offset; - } - ImagingSectionLeave(&cookie); - break; - case IMAGING_TYPE_SPECIAL: - if (strcmp(imIn->mode,"I;16") == 0) { - ImagingSectionEnter(&cookie); - for (y = 0; y < imIn->ysize; y++) { - UINT16* in = (UINT16 *)imIn->image[y]; - UINT16* out = (UINT16 *)imOut->image[y]; - /* FIXME: add clipping? */ - for (x = 0; x < imIn->xsize; x++) - out[x] = in[x] * scale + offset; - } - ImagingSectionLeave(&cookie); - break; - } - /* FALL THROUGH */ - default: - ImagingDelete(imOut); - return (Imaging) ImagingError_ValueError("internal error"); - } - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c deleted file mode 100755 index 1b76a6a0fab..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.c +++ /dev/null @@ -1,1610 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * history: - * 1998-09-10 tjs Contributed - * 1998-12-29 fl Added to PIL 1.0b1 - * 2004-02-21 fl Fixed bogus free() on quantization error - * 2005-02-07 fl Limit number of colors to 256 - * - * Written by Toby J Sargeant . - * - * Copyright (c) 1998 by Toby J Sargeant - * Copyright (c) 1998-2004 by Secret Labs AB. All rights reserved. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -#include -#include -#include -#include - -#include "Quant.h" - -#include "QuantDefines.h" -#include "QuantHash.h" -#include "QuantHeap.h" - -#define NO_OUTPUT - -typedef struct { - unsigned long scale; -} PixelHashData; - -typedef struct _PixelList { - struct _PixelList *next[3],*prev[3]; - Pixel p; - unsigned int flag:1; - int count; -} PixelList; - -typedef struct _BoxNode { - struct _BoxNode *l,*r; - PixelList *head[3],*tail[3]; - int axis; - int volume; - unsigned long pixelCount; -} BoxNode; - -#define _SQR(x) ((x)*(x)) -#define _DISTSQR(p1,p2) \ - _SQR((int)((p1)->c.r)-(int)((p2)->c.r))+ \ - _SQR((int)((p1)->c.g)-(int)((p2)->c.g))+ \ - _SQR((int)((p1)->c.b)-(int)((p2)->c.b)) - -#define MAX_HASH_ENTRIES 65536 - -#define PIXEL_HASH(r,g,b) \ - (((unsigned int)(r) )*463 ^ \ - ((unsigned int)(g)<< 8)*10069 ^ \ - ((unsigned int)(b)<<16)*64997) - -#define PIXEL_UNSCALE(p,q,s) \ - ((q)->c.r=(p)->c.r<<(s)), \ - ((q)->c.g=(p)->c.g<<(s)), \ - ((q)->c.b=(p)->c.b<<(s)) - -#define PIXEL_SCALE(p,q,s)\ - ((q)->c.r=(p)->c.r>>(s)), \ - ((q)->c.g=(p)->c.g>>(s)), \ - ((q)->c.b=(p)->c.b>>(s)) - -static unsigned long -unshifted_pixel_hash(const HashTable h, const void *p) -{ - Pixel *pixel=(Pixel *)&p; - unsigned long hash=PIXEL_HASH(pixel->c.r, - pixel->c.g, - pixel->c.b); - return hash; -} - -static int -unshifted_pixel_cmp(const HashTable h, const void *a, const void *b) -{ - Pixel *pixel1=(Pixel *)&a; - Pixel *pixel2=(Pixel *)&b; - if (pixel1->c.r==pixel2->c.r) { - if (pixel1->c.g==pixel2->c.g) { - if (pixel1->c.b==pixel2->c.b) { - return 0; - } else { - return (int)(pixel1->c.b)-(int)(pixel2->c.b); - } - } else { - return (int)(pixel1->c.g)-(int)(pixel2->c.g); - } - } else { - return (int)(pixel1->c.r)-(int)(pixel2->c.r); - } -} - -static unsigned long -pixel_hash(const HashTable h,const void *p) -{ - PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); - Pixel *pixel=(Pixel *)&p; - unsigned long hash=PIXEL_HASH(pixel->c.r>>d->scale, - pixel->c.g>>d->scale, - pixel->c.b>>d->scale); - return hash; -} - -static int -pixel_cmp(const HashTable h,const void *a,const void *b) -{ - PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); - Pixel *pixel1=(Pixel *)&a; - Pixel *pixel2=(Pixel *)&b; - unsigned long A,B; - A=PIXEL_HASH(pixel1->c.r>>d->scale, - pixel1->c.g>>d->scale, - pixel1->c.b>>d->scale); - B=PIXEL_HASH(pixel2->c.r>>d->scale, - pixel2->c.g>>d->scale, - pixel2->c.b>>d->scale); - return (A==B)?0:((Ascale=0; - timer=timer3=clock(); - for (i=0;iMAX_HASH_ENTRIES) { - d->scale++; -#ifndef NO_OUTPUT - printf ("rehashing - new scale: %d\n",(int)d->scale); -#endif - timer2=clock(); - hashtable_rehash_compute(hash,rehash_collide); - timer2=clock()-timer2; -#ifndef NO_OUTPUT - printf ("rehash took %f sec\n",timer2/(double)CLOCKS_PER_SEC); -#endif - timer+=timer2; - } - } -#ifndef NO_OUTPUT - printf ("inserts took %f sec\n",(clock()-timer)/(double)CLOCKS_PER_SEC); -#endif -#ifndef NO_OUTPUT - printf ("total %f sec\n",(clock()-timer3)/(double)CLOCKS_PER_SEC); -#endif - return hash; -} - -static void -destroy_pixel_hash(HashTable hash) -{ - PixelHashData *d=(PixelHashData *)hashtable_get_user_data(hash); - if (d) free(d); - hashtable_free(hash); -} - - -/* 1. hash quantized pixels. */ -/* 2. create R,G,B lists of sorted quantized pixels. */ -/* 3. median cut. */ -/* 4. build hash table from median cut boxes. */ -/* 5. for each pixel, compute entry in hash table, and hence median cut box. */ -/* 6. compute median cut box pixel averages. */ -/* 7. map each pixel to nearest average. */ - -static int -compute_box_volume(BoxNode *b) -{ - unsigned char rl,rh,gl,gh,bl,bh; - if (b->volume>=0) return b->volume; - if (!b->head[0]) { - b->volume=0; - } else { - rh=b->head[0]->p.c.r; - rl=b->tail[0]->p.c.r; - gh=b->head[1]->p.c.g; - gl=b->tail[1]->p.c.g; - bh=b->head[2]->p.c.b; - bl=b->tail[2]->p.c.b; - b->volume=(rh-rl+1)*(gh-gl+1)*(bh-bl+1); - } - return b->volume; -} - -static void -hash_to_list(HashTable h, const void *key, const void *val, void *u) -{ - PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); - PixelList **pl=(PixelList **)u; - PixelList *p; - Pixel *pixel=(Pixel *)&key; - int i; - Pixel q; - int count=*(int *)&val; - - PIXEL_SCALE(pixel,&q,d->scale); - - p=malloc(sizeof(PixelList)); - if (!p) return; - - p->flag=0; - p->p=q; - p->count=count; - for (i=0;i<3;i++) { - p->next[i]=pl[i]; - p->prev[i]=NULL; - if (pl[i]) pl[i]->prev[i]=p; - pl[i]=p; - } -} - -static PixelList * -mergesort_pixels(PixelList *head, int i) -{ - PixelList *c,*t,*a,*b,*p; - if (!head||!head->next[i]) { - if (head) { - head->next[i]=NULL; - head->prev[i]=NULL; - } - return head; - } - for (c=t=head;c&&t;c=c->next[i],t=(t->next[i])?t->next[i]->next[i]:NULL); - if (c) { - if (c->prev[i]) c->prev[i]->next[i]=NULL; - c->prev[i]=NULL; - } - a=mergesort_pixels(head,i); - b=mergesort_pixels(c,i); - head=NULL; - p=NULL; - while (a&&b) { - if (a->p.a.v[i]>b->p.a.v[i]) { - c=a; - a=a->next[i]; - } else { - c=b; - b=b->next[i]; - } - c->prev[i]=p; - c->next[i]=NULL; - if (p) p->next[i]=c; - p=c; - if (!head) head=c; - } - if (a) { - c->next[i]=a; - a->prev[i]=c; - } else if (b) { - c->next[i]=b; - b->prev[i]=c; - } - return head; -} - -#if defined(TEST_MERGESORT) || defined(TEST_SORTED) -static int -test_sorted(PixelList *pl[3]) -{ - int i,n,l; - PixelList *t; - - for(i=0;i<3;i++) { - n=0; - l=256; - for (t=pl[i];t;t=t->next[i]) { - if (lp.a.v[i]) return 0; - l=t->p.a.v[i]; - } - } - return 1; -} -#endif - -static int -box_heap_cmp(const Heap h, const void *A, const void *B) -{ - BoxNode *a=(BoxNode *)A; - BoxNode *b=(BoxNode *)B; - return (int)a->pixelCount-(int)b->pixelCount; -} - -#define LUMINANCE(p) (77*(p)->c.r+150*(p)->c.g+29*(p)->c.b) - -static int -splitlists(PixelList *h[3], - PixelList *t[3], - PixelList *nh[2][3], - PixelList *nt[2][3], - unsigned long nCount[2], - int axis, - unsigned long pixelCount) -{ - unsigned long left; - - PixelList *l,*r,*c,*n; - int i; - int nRight,nLeft; - int splitColourVal; - -#ifdef TEST_SPLIT - { - PixelList *_prevTest,*_nextTest; - int _i,_nextCount[3],_prevCount[3]; - for (_i=0;_i<3;_i++) { - for (_nextCount[_i]=0,_nextTest=h[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++); - for (_prevCount[_i]=0,_prevTest=t[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++); - if (_nextTest!=t[_i]) { - printf ("next-list of axis %d does not end at tail\n",_i); - exit(1); - } - if (_prevTest!=h[_i]) { - printf ("prev-list of axis %d does not end at head\n",_i); - exit(1); - } - for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]); - for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]); - if (_nextTest!=h[_i]) { - printf ("next-list of axis %d does not loop back to head\n",_i); - exit(1); - } - if (_prevTest!=t[_i]) { - printf ("prev-list of axis %d does not loop back to tail\n",_i); - exit(1); - } - } - for (_i=1;_i<3;_i++) { - if (_prevCount[_i]!=_prevCount[_i-1] || - _nextCount[_i]!=_nextCount[_i-1] || - _prevCount[_i]!=_nextCount[_i]) { - printf ("{%d %d %d} {%d %d %d}\n", - _prevCount[0], - _prevCount[1], - _prevCount[2], - _nextCount[0], - _nextCount[1], - _nextCount[2]); - exit(1); - } - } - } -#endif - nCount[0]=nCount[1]=0; - nLeft=nRight=0; - for (left=0,c=h[axis];c;) { - left=left+c->count; - nCount[0]+=c->count; - c->flag=0; - nLeft++; - c=c->next[axis]; - if (left*2>pixelCount) { - break; - } - } - if (c) { - splitColourVal=c->prev[axis]->p.a.v[axis]; - for (;c;c=c->next[axis]) { - if (splitColourVal!=c->p.a.v[axis]) { - break; - } - c->flag=0; - nLeft++; - nCount[0]+=c->count; - } - } - for (;c;c=c->next[axis]) { - c->flag=1; - nRight++; - nCount[1]+=c->count; - } - if (!nRight) { - for (c=t[axis],splitColourVal=t[axis]->p.a.v[axis];c;c=c->prev[axis]) { - if (splitColourVal!=c->p.a.v[axis]) { - break; - } - c->flag=1; - nRight++; - nLeft--; - nCount[0]-=c->count; - nCount[1]+=c->count; - } - } -#ifndef NO_OUTPUT - if (!nLeft) { - for (c=h[axis];c;c=c->next[axis]) { - printf ("[%d %d %d]\n",c->p.c.r,c->p.c.g,c->p.c.b); - } - printf ("warning... trivial split\n"); - } -#endif - - for (i=0;i<3;i++) { - l=r=NULL; - nh[0][i]=nt[0][i]=NULL; - nh[1][i]=nt[1][i]=NULL; - for (c=h[i];c;c=n) { - n=c->next[i]; - if (c->flag) { /* move pixel to right list*/ - if (r) r->next[i]=c; else nh[1][i]=c; - c->prev[i]=r; - r=c; - } else { /* move pixel to left list */ - if (l) l->next[i]=c; else nh[0][i]=c; - c->prev[i]=l; - l=c; - } - } - if (l) l->next[i]=NULL; - if (r) r->next[i]=NULL; - nt[0][i]=l; - nt[1][i]=r; - } - return 1; -} - -static int -split(BoxNode *node) -{ - unsigned char rl,rh,gl,gh,bl,bh; - int f[3]; - int best,axis; - int i; - PixelList *heads[2][3]; - PixelList *tails[2][3]; - unsigned long newCounts[2]; - BoxNode *left,*right; - - rh=node->head[0]->p.c.r; - rl=node->tail[0]->p.c.r; - gh=node->head[1]->p.c.g; - gl=node->tail[1]->p.c.g; - bh=node->head[2]->p.c.b; - bl=node->tail[2]->p.c.b; -#ifdef TEST_SPLIT - printf ("splitting node [%d %d %d] [%d %d %d] ",rl,gl,bl,rh,gh,bh); -#endif - f[0]=(rh-rl)*77; - f[1]=(gh-gl)*150; - f[2]=(bh-bl)*29; - - best=f[0]; - axis=0; - for (i=1;i<3;i++) { - if (besttail[_i]->next[_i]) { - printf ("tail is not tail\n"); - printf ("node->tail[%d]->next[%d]=%p\n",_i,_i,node->tail[_i]->next[_i]); - } - if (node->head[_i]->prev[_i]) { - printf ("head is not head\n"); - printf ("node->head[%d]->prev[%d]=%p\n",_i,_i,node->head[_i]->prev[_i]); - } - } - - for (_i=0;_i<3;_i++) { - for (_nextCount[_i]=0,_nextTest=node->head[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++); - for (_prevCount[_i]=0,_prevTest=node->tail[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++); - if (_nextTest!=node->tail[_i]) { - printf ("next-list of axis %d does not end at tail\n",_i); - } - if (_prevTest!=node->head[_i]) { - printf ("prev-list of axis %d does not end at head\n",_i); - } - for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]); - for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]); - if (_nextTest!=node->head[_i]) { - printf ("next-list of axis %d does not loop back to head\n",_i); - } - if (_prevTest!=node->tail[_i]) { - printf ("prev-list of axis %d does not loop back to tail\n",_i); - } - } - for (_i=1;_i<3;_i++) { - if (_prevCount[_i]!=_prevCount[_i-1] || - _nextCount[_i]!=_nextCount[_i-1] || - _prevCount[_i]!=_nextCount[_i]) { - printf ("{%d %d %d} {%d %d %d}\n", - _prevCount[0], - _prevCount[1], - _prevCount[2], - _nextCount[0], - _nextCount[1], - _nextCount[2]); - } - } - } -#endif - node->axis=axis; - if (!splitlists(node->head, - node->tail, - heads, - tails, - newCounts, - axis, - node->pixelCount)) { -#ifndef NO_OUTPUT - printf ("list split failed.\n"); -#endif - return 0; - } -#ifdef TEST_SPLIT - if (!test_sorted(heads[0])) { - printf ("bug in split"); - exit(1); - } - if (!test_sorted(heads[1])) { - printf ("bug in split"); - exit(1); - } -#endif - left=malloc(sizeof(BoxNode)); - right=malloc(sizeof(BoxNode)); - if (!left||!right) { - return 0; - } - for(i=0;i<3;i++) { - left->head[i]=heads[0][i]; - left->tail[i]=tails[0][i]; - right->head[i]=heads[1][i]; - right->tail[i]=tails[1][i]; - node->head[i]=NULL; - node->tail[i]=NULL; - } -#ifdef TEST_SPLIT - if (left->head[0]) { - rh=left->head[0]->p.c.r; - rl=left->tail[0]->p.c.r; - gh=left->head[1]->p.c.g; - gl=left->tail[1]->p.c.g; - bh=left->head[2]->p.c.b; - bl=left->tail[2]->p.c.b; - printf (" left node [%3d %3d %3d] [%3d %3d %3d]\n",rl,gl,bl,rh,gh,bh); - } - if (right->head[0]) { - rh=right->head[0]->p.c.r; - rl=right->tail[0]->p.c.r; - gh=right->head[1]->p.c.g; - gl=right->tail[1]->p.c.g; - bh=right->head[2]->p.c.b; - bl=right->tail[2]->p.c.b; - printf (" right node [%3d %3d %3d] [%3d %3d %3d]\n",rl,gl,bl,rh,gh,bh); - } -#endif - left->l=left->r=NULL; - right->l=right->r=NULL; - left->axis=right->axis=-1; - left->volume=right->volume=-1; - left->pixelCount=newCounts[0]; - right->pixelCount=newCounts[1]; - node->l=left; - node->r=right; - return 1; -} - -static BoxNode * -median_cut(PixelList *hl[3], - unsigned long imPixelCount, - int nPixels) -{ - PixelList *tl[3]; - int i; - BoxNode *root; - Heap h; - BoxNode *thisNode; - - h=ImagingQuantHeapNew(box_heap_cmp); - root=malloc(sizeof(BoxNode)); - if (!root) { ImagingQuantHeapFree(h); return NULL; } - for(i=0;i<3;i++) { - for (tl[i]=hl[i];tl[i]&&tl[i]->next[i];tl[i]=tl[i]->next[i]); - root->head[i]=hl[i]; - root->tail[i]=tl[i]; - } - root->l=root->r=NULL; - root->axis=-1; - root->volume=-1; - root->pixelCount=imPixelCount; - - ImagingQuantHeapAdd(h,(void *)root); - while (--nPixels) { - do { - if (!ImagingQuantHeapRemove(h,(void **)&thisNode)) { - goto done; - } - } while (compute_box_volume(thisNode)==1); - if (!split(thisNode)) { -#ifndef NO_OUTPUT - printf ("Oops, split failed...\n"); -#endif - exit (1); - } - ImagingQuantHeapAdd(h,(void *)(thisNode->l)); - ImagingQuantHeapAdd(h,(void *)(thisNode->r)); - } -done: - ImagingQuantHeapFree(h); - return root; -} - -static void -free_box_tree(BoxNode *n) -{ - PixelList *p,*pp; - if (n->l) free_box_tree(n->l); - if (n->r) free_box_tree(n->r); - for (p=n->head[0];p;p=pp) { - pp=p->next[0]; - free(p); - } - free(n); -} - -#ifdef TEST_SPLIT_INTEGRITY -static int -checkContained(BoxNode *n,Pixel *pp) -{ - if (n->l&&n->r) { - return checkContained(n->l,pp)+checkContained(n->r,pp); - } - if (n->l||n->r) { -#ifndef NO_OUTPUT - printf ("box tree is dead\n"); -#endif - return 0; - } - if ( - pp->c.r<=n->head[0]->p.c.r && - pp->c.r>=n->tail[0]->p.c.r && - pp->c.g<=n->head[1]->p.c.g && - pp->c.g>=n->tail[1]->p.c.g && - pp->c.b<=n->head[2]->p.c.b && - pp->c.b>=n->tail[2]->p.c.b) { - return 1; - } - return 0; -} -#endif - -static int -annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box) -{ - PixelList *p; - PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); - Pixel q; - if (n->l&&n->r) { - return annotate_hash_table(n->l,h,box) && annotate_hash_table(n->r,h,box); - } - if (n->l||n->r) { -#ifndef NO_OUTPUT - printf ("box tree is dead\n"); -#endif - return 0; - } - for (p=n->head[0];p;p=p->next[0]) { - PIXEL_UNSCALE(&(p->p),&q,d->scale); - if (!hashtable_insert(h,(void *)q.v,(void *)*box)) { -#ifndef NO_OUTPUT - printf ("hashtable insert failed\n"); -#endif - return 0; - } - } - if (n->head[0]) (*box)++; - return 1; -} - -static int -_sort_ulong_ptr_keys(const void *a, const void *b) -{ - unsigned long A=**(unsigned long **)a; - unsigned long B=**(unsigned long **)b; - return (A==B)?0:((A*(skRow[k]));k--) { - skRow[k]=skRow[k-1]; - } - if (k!=j) skRow[k]=skElt; - } - } - return 1; -} - -static int -build_distance_tables(unsigned long *avgDist, - unsigned long **avgDistSortKey, - Pixel *p, - unsigned long nEntries) -{ - unsigned long i,j; - - for (i=0;i1) { - printf ("pixel in two boxes\n"); - for(i=0;i<3;i++) free (avg[i]); - free(count); - return 0; - } -#endif - if (!hashtable_lookup(medianBoxHash,(void *)pixelData[i].v,(void **)&paletteEntry)) { -#ifndef NO_OUTPUT - printf ("pixel lookup failed\n"); -#endif - for(i=0;i<3;i++) free (avg[i]); - free(count); - return 0; - } - if (paletteEntry>=nPaletteEntries) { -#ifndef NO_OUTPUT - printf ("panic - paletteEntry>=nPaletteEntries (%d>=%d)\n",(int)paletteEntry,(int)nPaletteEntries); -#endif - for(i=0;i<3;i++) free (avg[i]); - free(count); - return 0; - } - avg[0][paletteEntry]+=pixelData[i].c.r; - avg[1][paletteEntry]+=pixelData[i].c.g; - avg[2][paletteEntry]+=pixelData[i].c.b; - count[paletteEntry]++; - } - p=malloc(sizeof(Pixel)*nPaletteEntries); - if (!p) { - for(i=0;i<3;i++) free (avg[i]); - free(count); - return 0; - } - for (i=0;i=nPaletteEntries) { -#ifndef NO_OUTPUT - printf ("scream\n"); -#endif - return 0; - } - avg[0][qp[i]]+=pixelData[i].c.r; - avg[1][qp[i]]+=pixelData[i].c.g; - avg[2][qp[i]]+=pixelData[i].c.b; - count[qp[i]]++; - } - for (i=0;i - { - unsigned long bestmatch,bestdist,dist; - HashTable h2; - printf ("nearest neighbour search (full search)..."); fflush(stdout); timer=clock(); - h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); - for (i=0;inew),pixel); - if (data->secondPixel || newDistdata->furthestDistance) { - data->furthestDistance=oldDist; - data->furthest.v=pixel->v; - } -} - -int -quantize2(Pixel *pixelData, - unsigned long nPixels, - unsigned long nQuantPixels, - Pixel **palette, - unsigned long *paletteLength, - unsigned long **quantizedPixels, - int kmeans) -{ - HashTable h; - unsigned long i; - unsigned long mean[3]; - Pixel *p; - DistanceData data; - - unsigned long *qp; - unsigned long *avgDist; - unsigned long **avgDistSortKey; - - p=malloc(sizeof(Pixel)*nQuantPixels); - if (!p) return 0; - mean[0]=mean[1]=mean[2]=0; - h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); - for (i=0;i 256) - /* FIXME: for colors > 256, consider returning an RGB image - instead (see @PIL205) */ - return (Imaging) ImagingError_ValueError("bad number of colors"); - - if (strcmp(im->mode, "L") != 0 && strcmp(im->mode, "P") != 0 && - strcmp(im->mode, "RGB")) - return ImagingError_ModeError(); - - p = malloc(sizeof(Pixel) * im->xsize * im->ysize); - if (!p) - return ImagingError_MemoryError(); - - /* collect statistics */ - - /* FIXME: maybe we could load the hash tables directly from the - image data? */ - - if (!strcmp(im->mode, "L")) { - /* greyscale */ - - /* FIXME: converting a "L" image to "P" with 256 colors - should be done by a simple copy... */ - - for (i = y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++, i++) - p[i].c.r = p[i].c.g = p[i].c.b = im->image8[y][x]; - - } else if (!strcmp(im->mode, "P")) { - /* palette */ - - pp = im->palette->palette; - - for (i = y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++, i++) { - v = im->image8[y][x]; - p[i].c.r = pp[v*4+0]; - p[i].c.g = pp[v*4+1]; - p[i].c.b = pp[v*4+2]; - } - - } else if (!strcmp(im->mode, "RGB")) { - /* true colour */ - - for (i = y = 0; y < im->ysize; y++) - for (x = 0; x < im->xsize; x++, i++) - p[i].v = im->image32[y][x]; - - } else { - free(p); - return (Imaging) ImagingError_ValueError("internal error"); - } - - switch (mode) { - case 0: - /* median cut */ - result = quantize( - p, - im->xsize*im->ysize, - colors, - &palette, - &paletteLength, - &newData, - kmeans - ); - break; - case 1: - /* maximum coverage */ - result = quantize2( - p, - im->xsize*im->ysize, - colors, - &palette, - &paletteLength, - &newData, - kmeans - ); - break; - default: - result = 0; - break; - } - - free(p); - - if (result) { - - imOut = ImagingNew("P", im->xsize, im->ysize); - - for (i = y = 0; y < im->ysize; y++) - for (x=0; x < im->xsize; x++) - imOut->image8[y][x] = (unsigned char) newData[i++]; - - free(newData); - - pp = imOut->palette->palette; - - for (i = j = 0; i < (int) paletteLength; i++) { - *pp++ = palette[i].c.r; - *pp++ = palette[i].c.g; - *pp++ = palette[i].c.b; - *pp++ = 255; - } - for (; i < 256; i++) { - *pp++ = 0; - *pp++ = 0; - *pp++ = 0; - *pp++ = 255; - } - - free(palette); - - return imOut; - - } else { - - return (Imaging) ImagingError_ValueError("quantization error"); - - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h deleted file mode 100755 index 0de485a1a1a..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Quant.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * Written by Toby J Sargeant . - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __QUANT_H__ -#define __QUANT_H__ - -typedef union { - struct { - unsigned char r,g,b,a; - } c; - struct { - unsigned char v[4]; - } a; - unsigned long v; -} Pixel; - -int quantize(Pixel *, - unsigned long, - unsigned long, - Pixel **, - unsigned long *, - unsigned long **, - int); - -int quantize2(Pixel *, - unsigned long, - unsigned long, - Pixel **, - unsigned long *, - unsigned long **, - int); -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h deleted file mode 100755 index 5b080104e1a..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantDefines.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * Written by Toby J Sargeant . - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __DEFINES_H__ -#define __DEFINES_H__ - -#if 0 - -void *newMalloc(size_t,const char *,const char *,int); -void newFree(void *,const char *,const char *,int); -void print_malloc_stats(); -#define malloc(x) newMalloc(x,__FILE__,__FUNCTION__,__LINE__) -#define free(x) newFree(x,__FILE__,__FUNCTION__,__LINE__) - -#endif - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c deleted file mode 100755 index e6438402dd7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * hash tables used by the image quantizer - * - * history: - * 98-09-10 tjs Contributed - * 98-12-29 fl Added to PIL 1.0b1 - * - * Written by Toby J Sargeant . - * - * Copyright (c) 1998 by Toby J Sargeant - * Copyright (c) 1998 by Secret Labs AB - * - * See the README file for information on usage and redistribution. - */ - -#include -#include -#include -#include - -#include "QuantHash.h" -#include "QuantDefines.h" - -typedef struct _IntHashNode { - struct _IntHashNode *next; - void *key,*value; -} IntHashNode; - -typedef struct _IntHashTable { - IntHashNode **table; - unsigned long length; - unsigned long count; - HashFunc hashFunc; - HashCmpFunc cmpFunc; - DestroyFunc keyDestroyFunc; - DestroyFunc valDestroyFunc; - void *userData; -} IntHashTable; - -#define MIN_LENGTH 11 -#define RESIZE_FACTOR 3 - -static int _hashtable_insert_node(IntHashTable *,IntHashNode *,int,int,CollisionFunc); -#if 0 -static int _hashtable_test(IntHashTable *); -#endif - -HashTable hashtable_new(HashFunc hf,HashCmpFunc cf) { - IntHashTable *h; - h=malloc(sizeof(IntHashTable)); - if (!h) { return NULL; } - h->hashFunc=hf; - h->cmpFunc=cf; - h->keyDestroyFunc=NULL; - h->valDestroyFunc=NULL; - h->length=MIN_LENGTH; - h->count=0; - h->userData=NULL; - h->table=malloc(sizeof(IntHashNode *)*h->length); - if (!h->table) { free(h); return NULL; } - memset (h->table,0,sizeof(IntHashNode *)*h->length); - return (HashTable)h; -} - -static void _hashtable_destroy(HashTable H,const void *key,const void *val,void *u) { - IntHashTable *h=(IntHashTable *)H; - if (h->keyDestroyFunc&&key) { - h->keyDestroyFunc((HashTable)h,(void *)key); - } - if (h->valDestroyFunc&&val) { - h->valDestroyFunc((HashTable)h,(void *)val); - } -} - -static unsigned long _findPrime(unsigned long start,int dir) { - static int unit[]={0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0}; - unsigned long t; - while (start>1) { - if (!unit[start&0x0f]) { - start+=dir; - continue; - } - for (t=2;t=sqrt((double)start)) { - break; - } - start+=dir; - } - return start; -} - -static void _hashtable_rehash(IntHashTable *h, - CollisionFunc cf, - unsigned long newSize) { - IntHashNode **oldTable=h->table; - unsigned long i; - IntHashNode *n,*nn; - unsigned long oldSize; - oldSize=h->length; - h->table=malloc(sizeof(IntHashNode *)*newSize); - if (!h->table) { - h->table=oldTable; - return; - } - h->length=newSize; - h->count=0; - memset (h->table,0,sizeof(IntHashNode *)*h->length); - for (i=0;inext; - _hashtable_insert_node(h,n,0,0,cf); - } - } - free(oldTable); -} - -static void _hashtable_resize(IntHashTable *h) { - unsigned long newSize; - unsigned long oldSize; - oldSize=h->length; - newSize=oldSize; - if (h->count*RESIZE_FACTORlength) { - newSize=_findPrime(h->length/2-1,-1); - } else if (h->length*RESIZE_FACTORcount) { - newSize=_findPrime(h->length*2+1,+1); - } - if (newSizelength;i++) { - for (n=h->table[i];n&&n->next;n=n->next) { - j=h->cmpFunc((HashTable)h,n->key,n->next->key); - printf ("%c",j?(j<0?'-':'+'):'='); - } - printf ("\n"); - } - return 0; -} -#endif - -static int _hashtable_insert_node(IntHashTable *h,IntHashNode *node,int resize,int update,CollisionFunc cf) { - unsigned long hash=h->hashFunc((HashTable)h,node->key)%h->length; - IntHashNode **n,*nv; - int i; - - for (n=&(h->table[hash]);*n;n=&((*n)->next)) { - nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,node->key); - if (!i) { - if (cf) { - nv->key=node->key; - cf((HashTable)h,&(nv->key),&(nv->value),node->key,node->value); - free(node); - return 1; - } else { - if (h->valDestroyFunc) { - h->valDestroyFunc((HashTable)h,nv->value); - } - if (h->keyDestroyFunc) { - h->keyDestroyFunc((HashTable)h,nv->key); - } - nv->key=node->key; - nv->value=node->value; - free(node); - return 1; - } - } else if (i>0) { - break; - } - } - if (!update) { - node->next=*n; - *n=node; - h->count++; - if (resize) _hashtable_resize(h); - return 1; - } else { - return 0; - } -} - -static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int update) { - IntHashNode **n,*nv; - IntHashNode *t; - int i; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - - for (n=&(h->table[hash]);*n;n=&((*n)->next)) { - nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,key); - if (!i) { - if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,nv->value); } - nv->value=val; - return 1; - } else if (i>0) { - break; - } - } - if (!update) { - t=malloc(sizeof(IntHashNode)); - if (!t) return 0; - t->next=*n; - *n=t; - t->key=key; - t->value=val; - h->count++; - if (resize) _hashtable_resize(h); - return 1; - } else { - return 0; - } -} - -static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,void *newVal,int resize) { - IntHashNode **n,*nv; - IntHashNode *t; - int i; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - - for (n=&(h->table[hash]);*n;n=&((*n)->next)) { - nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,key); - if (!i) { - *retVal=nv->value; - return 1; - } else if (i>0) { - break; - } - } - t=malloc(sizeof(IntHashNode)); - if (!t) return 0; - t->next=*n; - *n=t; - t->key=key; - t->value=newVal; - *retVal=newVal; - h->count++; - if (resize) _hashtable_resize(h); - return 1; -} - -int hashtable_insert_or_update_computed(HashTable H, - void *key, - ComputeFunc newFunc, - ComputeFunc existsFunc) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode **n,*nv; - IntHashNode *t; - int i; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - - for (n=&(h->table[hash]);*n;n=&((*n)->next)) { - nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,key); - if (!i) { - void *old=nv->value; - if (existsFunc) { - existsFunc(H,nv->key,&(nv->value)); - if (nv->value!=old) { - if (h->valDestroyFunc) { - h->valDestroyFunc((HashTable)h,old); - } - } - } else { - return 0; - } - return 1; - } else if (i>0) { - break; - } - } - t=malloc(sizeof(IntHashNode)); - if (!t) return 0; - t->key=key; - t->next=*n; - *n=t; - if (newFunc) { - newFunc(H,t->key,&(t->value)); - } else { - free(t); - return 0; - } - h->count++; - _hashtable_resize(h); - return 1; -} - -int hashtable_update(HashTable H,void *key,void *val) { - IntHashTable *h=(IntHashTable *)H; - return _hashtable_insert(h,key,val,1,0); -} - -int hashtable_insert(HashTable H,void *key,void *val) { - IntHashTable *h=(IntHashTable *)H; - return _hashtable_insert(h,key,val,1,0); -} - -void hashtable_foreach_update(HashTable H,IteratorUpdateFunc i,void *u) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode *n; - unsigned long x; - - if (h->table) { - for (x=0;xlength;x++) { - for (n=h->table[x];n;n=n->next) { - i((HashTable)h,n->key,(void **)&(n->value),u); - } - } - } -} - -void hashtable_foreach(HashTable H,IteratorFunc i,void *u) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode *n; - unsigned long x; - - if (h->table) { - for (x=0;xlength;x++) { - for (n=h->table[x];n;n=n->next) { - i((HashTable)h,n->key,n->value,u); - } - } - } -} - -void hashtable_free(HashTable H) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode *n,*nn; - unsigned long i; - - if (h->table) { - if (h->keyDestroyFunc || h->keyDestroyFunc) { - hashtable_foreach(H,_hashtable_destroy,NULL); - } - for (i=0;ilength;i++) { - for (n=h->table[i];n;n=nn) { - nn=n->next; - free(n); - } - } - free(h->table); - } - free(h); -} - -DestroyFunc hashtable_set_value_destroy_func(HashTable H,DestroyFunc d) { - IntHashTable *h=(IntHashTable *)H; - DestroyFunc r=h->valDestroyFunc; - h->valDestroyFunc=d; - return r; -} - -DestroyFunc hashtable_set_key_destroy_func(HashTable H,DestroyFunc d) { - IntHashTable *h=(IntHashTable *)H; - DestroyFunc r=h->keyDestroyFunc; - h->keyDestroyFunc=d; - return r; -} - -static int _hashtable_remove(IntHashTable *h, - const void *key, - void **keyRet, - void **valRet, - int resize) { - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - IntHashNode *n,*p; - int i; - - for (p=NULL,n=h->table[hash];n;p=n,n=n->next) { - i=h->cmpFunc((HashTable)h,n->key,key); - if (!i) { - if (p) p=n->next; else h->table[hash]=n->next; - *keyRet=n->key; - *valRet=n->value; - free(n); - h->count++; - return 1; - } else if (i>0) { - break; - } - } - return 0; -} - -static int _hashtable_delete(IntHashTable *h,const void *key,int resize) { - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - IntHashNode *n,*p; - int i; - - for (p=NULL,n=h->table[hash];n;p=n,n=n->next) { - i=h->cmpFunc((HashTable)h,n->key,key); - if (!i) { - if (p) p=n->next; else h->table[hash]=n->next; - if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,n->value); } - if (h->keyDestroyFunc) { h->keyDestroyFunc((HashTable)h,n->key); } - free(n); - h->count++; - return 1; - } else if (i>0) { - break; - } - } - return 0; -} - -int hashtable_remove(HashTable H,const void *key,void **keyRet,void **valRet) { - IntHashTable *h=(IntHashTable *)H; - return _hashtable_remove(h,key,keyRet,valRet,1); -} - -int hashtable_delete(HashTable H,const void *key) { - IntHashTable *h=(IntHashTable *)H; - return _hashtable_delete(h,key,1); -} - -void hashtable_rehash_compute(HashTable H,CollisionFunc cf) { - IntHashTable *h=(IntHashTable *)H; - _hashtable_rehash(h,cf,h->length); -} - -void hashtable_rehash(HashTable H) { - IntHashTable *h=(IntHashTable *)H; - _hashtable_rehash(h,NULL,h->length); -} - -int hashtable_lookup_or_insert(HashTable H,void *key,void **valp,void *val) { - IntHashTable *h=(IntHashTable *)H; - return _hashtable_lookup_or_insert(h,key,valp,val,1); -} - -int hashtable_lookup(const HashTable H,const void *key,void **valp) { - IntHashTable *h=(IntHashTable *)H; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - IntHashNode *n; - int i; - - for (n=h->table[hash];n;n=n->next) { - i=h->cmpFunc((HashTable)h,n->key,key); - if (!i) { - *valp=n->value; - return 1; - } else if (i>0) { - break; - } - } - return 0; -} - -unsigned long hashtable_get_count(const HashTable H) { - IntHashTable *h=(IntHashTable *)H; - return h->count; -} - -void *hashtable_get_user_data(const HashTable H) { - IntHashTable *h=(IntHashTable *)H; - return h->userData; -} - -void *hashtable_set_user_data(HashTable H,void *data) { - IntHashTable *h=(IntHashTable *)H; - void *r=h->userData; - h->userData=data; - return r; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h deleted file mode 100755 index b98b56eaa4c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHash.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * Written by Toby J Sargeant . - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __HASH_H__ -#define __HASH_H__ - -#include "QuantTypes.h" - -HashTable hashtable_new(HashFunc,HashCmpFunc); -void hashtable_free(HashTable); -void hashtable_foreach(HashTable,IteratorFunc,void *); -void hashtable_foreach_update(HashTable,IteratorUpdateFunc,void *); -int hashtable_insert(HashTable,void *,void *); -int hashtable_update(HashTable,void *,void *); -int hashtable_lookup(const HashTable,const void *,void **); -int hashtable_lookup_or_insert(HashTable,void *,void **,void *); -int hashtable_insert_or_update_computed(HashTable,void *,ComputeFunc,ComputeFunc); -int hashtable_delete(HashTable,const void *); -int hashtable_remove(HashTable,const void *,void **,void **); -void *hashtable_set_user_data(HashTable,void *); -void *hashtable_get_user_data(const HashTable); -DestroyFunc hashtable_set_key_destroy_func(HashTable,DestroyFunc); -DestroyFunc hashtable_set_value_destroy_func(HashTable,DestroyFunc); -unsigned long hashtable_get_count(const HashTable); -void hashtable_rehash(HashTable); -void hashtable_rehash_compute(HashTable,CollisionFunc); - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c deleted file mode 100755 index 9332a5cd71f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * heap data type used by the image quantizer - * - * history: - * 98-09-10 tjs Contributed - * 98-12-29 fl Added to PIL 1.0b1 - * - * Written by Toby J Sargeant . - * - * Copyright (c) 1998 by Toby J Sargeant - * Copyright (c) 1998 by Secret Labs AB - * - * See the README file for information on usage and redistribution. - */ - -#include -#include -#include -#include - -#include "QuantHash.h" -#include "QuantDefines.h" - -typedef struct { - void **heap; - int heapsize; - int heapcount; - HeapCmpFunc cf; -} IntHeap; - -#define INITIAL_SIZE 256 - -#define DEBUG - -#ifdef DEBUG -static int _heap_test(Heap); -#endif - -void ImagingQuantHeapFree(Heap H) { - IntHeap *h=(IntHeap *)H; - free(h->heap); - free(h); -} - -static int _heap_grow(IntHeap *h,int newsize) { - void *newheap; - if (!newsize) newsize=h->heapsize<<1; - if (newsizeheapsize) return 0; - newheap=malloc(sizeof(void *)*newsize); - if (!newheap) return 0; - memcpy(newheap,h->heap,sizeof(void *)*h->heapsize); - free(h->heap); - h->heap=newheap; - h->heapsize=newsize; - return 1; -} - -#ifdef DEBUG -static int _heap_test(Heap H) { - IntHeap *h=(IntHeap *)H; - int k; - for (k=1;k*2<=h->heapcount;k++) { - if (h->cf(H,h->heap[k],h->heap[k*2])<0) { - printf ("heap is bad\n"); - return 0; - } - if (k*2+1<=h->heapcount && h->cf(H,h->heap[k],h->heap[k*2+1])<0) { - printf ("heap is bad\n"); - return 0; - } - } - return 1; -} -#endif - -int ImagingQuantHeapRemove(Heap H,void **r) { - IntHeap *h=(IntHeap *)H; - int k,l; - void *v; - - if (!h->heapcount) { - return 0; - } - *r=h->heap[1]; - v=h->heap[h->heapcount--]; - for (k=1;k*2<=h->heapcount;k=l) { - l=k*2; - if (lheapcount) { - if (h->cf(H,h->heap[l],h->heap[l+1])<0) { - l++; - } - } - if (h->cf(H,v,h->heap[l])>0) { - break; - } - h->heap[k]=h->heap[l]; - } - h->heap[k]=v; -#ifdef DEBUG - if (!_heap_test(H)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); } -#endif - return 1; -} - -int ImagingQuantHeapAdd(Heap H,void *val) { - IntHeap *h=(IntHeap *)H; - int k; - if (h->heapcount==h->heapsize-1) { - _heap_grow(h,0); - } - k=++h->heapcount; - while (k!=1) { - if (h->cf(H,val,h->heap[k/2])<=0) { - break; - } - h->heap[k]=h->heap[k/2]; - k>>=1; - } - h->heap[k]=val; -#ifdef DEBUG - if (!_heap_test(H)) { printf ("oops - heap_add messed up the heap\n"); exit(1); } -#endif - return 1; -} - -int ImagingQuantHeapTop(Heap H,void **r) { - IntHeap *h=(IntHeap *)H; - if (!h->heapcount) { - return 0; - } - *r=h->heap[1]; - return 1; -} - -Heap *ImagingQuantHeapNew(HeapCmpFunc cf) { - IntHeap *h; - - h=malloc(sizeof(IntHeap)); - if (!h) return NULL; - h->heapsize=INITIAL_SIZE; - h->heap=malloc(sizeof(void *)*h->heapsize); - if (!h->heap) { free(h); return NULL; } - h->heapcount=0; - h->cf=cf; - return (Heap)h; -} - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h deleted file mode 100755 index 5a213c42ab8..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantHeap.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * Written by Toby J Sargeant . - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __HEAP_H__ -#define __HEAP_H__ - -#include "QuantTypes.h" - -void ImagingQuantHeapFree(Heap); -int ImagingQuantHeapRemove(Heap,void **); -int ImagingQuantHeapAdd(Heap,void *); -int ImagingQuantHeapTop(Heap,void **); -Heap *ImagingQuantHeapNew(HeapCmpFunc); - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h deleted file mode 100755 index 308b51c1324..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/QuantTypes.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * Written by Toby J Sargeant . - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __TYPES_H__ -#define __TYPES_H__ - -typedef void *HashTable; -typedef void *Heap; - -typedef unsigned long (*HashFunc)(const HashTable,const void *); -typedef int (*HashCmpFunc)(const HashTable,const void *,const void *); -typedef void (*IteratorFunc)(const HashTable,const void *,const void *,void *); -typedef void (*IteratorUpdateFunc)(const HashTable,const void *,void **,void *); -typedef void (*DestroyFunc)(const HashTable,void *); -typedef void (*ComputeFunc)(const HashTable,const void *,void **); -typedef void (*CollisionFunc)(const HashTable,void **,void **,void *,void *); - -typedef int (*HeapCmpFunc)(const Heap,const void *,const void *); - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c deleted file mode 100755 index 84090f7510e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RankFilter.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * min, max, median filters - * - * history: - * 2002-06-08 fl Created - * - * Copyright (c) Secret Labs AB 2002. All rights reserved. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - -/* Fast rank algorithm (due to Wirth), based on public domain code - by Nicolas Devillard, available at http://ndevilla.free.fr */ - -#define SWAP(type,a,b) { register type t=(a);(a)=(b);(b)=t; } - -#define MakeRankFunction(type)\ -static type Rank##type(type a[], int n, int k)\ -{\ - register int i, j, l, m;\ - register type x;\ - l = 0; m = n-1;\ - while (l < m) {\ - x = a[k];\ - i = l;\ - j = m;\ - do {\ - while (a[i] < x) i++;\ - while (x < a[j]) j--;\ - if (i <= j) {\ - SWAP(type, a[i], a[j]);\ - i++; j--;\ - }\ - } while (i <= j);\ - if (j < k) l = i;\ - if (k < i) m = j;\ - }\ - return a[k];\ -} - -MakeRankFunction(UINT8) -MakeRankFunction(INT32) -MakeRankFunction(FLOAT32) - -Imaging -ImagingRankFilter(Imaging im, int size, int rank) -{ - Imaging imOut = NULL; - int x, y; - int i, margin, size2; - - if (!im || im->bands != 1 || im->type == IMAGING_TYPE_SPECIAL) - return (Imaging) ImagingError_ModeError(); - - if (!(size & 1)) - return (Imaging) ImagingError_ValueError("bad filter size"); - - size2 = size * size; - margin = (size-1) / 2; - - if (rank < 0 || rank >= size2) - return (Imaging) ImagingError_ValueError("bad rank value"); - - imOut = ImagingNew(im->mode, im->xsize - 2*margin, im->ysize - 2*margin); - if (!imOut) - return NULL; - -#define RANK_BODY(type) do {\ - type* buf = malloc(size2 * sizeof(type));\ - if (!buf)\ - goto nomemory;\ - for (y = 0; y < imOut->ysize; y++)\ - for (x = 0; x < imOut->xsize; x++) {\ - for (i = 0; i < size; i++)\ - memcpy(buf + i*size, &IMAGING_PIXEL_##type(im, x, y+i),\ - size * sizeof(type));\ - IMAGING_PIXEL_##type(imOut, x, y) = Rank##type(buf, size2, rank);\ - }\ -} while (0) - - if (im->image8) - RANK_BODY(UINT8); - else if (im->type == IMAGING_TYPE_INT32) - RANK_BODY(INT32); - else if (im->type == IMAGING_TYPE_FLOAT32) - RANK_BODY(FLOAT32); - else { - /* safety net (we shouldn't end up here) */ - ImagingDelete(imOut); - return (Imaging) ImagingError_ModeError(); - } - - ImagingCopyInfo(imOut, im); - - return imOut; - -nomemory: - ImagingDelete(imOut); - return (Imaging) ImagingError_MemoryError(); -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h deleted file mode 100755 index 4d28fa54665..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Raw.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Raw.h */ - -typedef struct { - - /* CONFIGURATION */ - - /* Distance between lines (0=no padding) */ - int stride; - - /* PRIVATE (initialized by decoder) */ - - /* Padding between lines */ - int skip; - -} RAWSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c deleted file mode 100755 index 5aadb2b44d7..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawDecode.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for raw (uncompressed) image data - * - * history: - * 96-03-07 fl rewritten - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#include "Raw.h" - - -int -ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - enum { LINE = 1, SKIP }; - RAWSTATE* rawstate = state->context; - - UINT8* ptr; - - if (state->state == 0) { - - /* Initialize context variables */ - - /* get size of image data and padding */ - state->bytes = (state->xsize * state->bits + 7) / 8; - rawstate->skip = (rawstate->stride) ? - rawstate->stride - state->bytes : 0; - - /* check image orientation */ - if (state->ystep < 0) { - state->y = state->ysize-1; - state->ystep = -1; - } else - state->ystep = 1; - - state->state = LINE; - - } - - ptr = buf; - - for (;;) { - - if (state->state == SKIP) { - - /* Skip padding between lines */ - - if (bytes < rawstate->skip) - return ptr - buf; - - ptr += rawstate->skip; - bytes -= rawstate->skip; - - state->state = LINE; - - } - - if (bytes < state->bytes) - return ptr - buf; - - /* Unpack data */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, ptr, state->xsize); - - ptr += state->bytes; - bytes -= state->bytes; - - state->y += state->ystep; - - if (state->y < 0 || state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - - state->state = SKIP; - - } - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c deleted file mode 100755 index a3b74b8cffc..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/RawEncode.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * coder for raw data - * - * FIXME: This encoder will fail if the buffer is not large enough to - * hold one full line of data. There's a workaround for this problem - * in ImageFile.py, but it should be solved here instead. - * - * history: - * 96-04-30 fl created - * 97-01-03 fl fixed padding - * - * Copyright (c) Fredrik Lundh 1996-97. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. */ - - -#include "Imaging.h" - -int -ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - UINT8* ptr; - - if (!state->state) { - - /* The "count" field holds the stride, if specified. Fix - things up so "bytes" is the full size, and "count" the - packed size */ - - if (state->count > 0) { - int bytes = state->count; - - /* stride must not be less than real size */ - if (state->count < state->bytes) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - state->count = state->bytes; - state->bytes = bytes; - } else - state->count = state->bytes; - - /* The "ystep" field specifies the orientation */ - - if (state->ystep < 0) { - state->y = state->ysize-1; - state->ystep = -1; - } else - state->ystep = 1; - - state->state = 1; - - } - - if (bytes < state->bytes) { - state->errcode = IMAGING_CODEC_CONFIG; - return 0; - } - - ptr = buf; - - while (bytes >= state->bytes) { - - state->shuffle(ptr, (UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->xsize); - - if (state->bytes > state->count) - /* zero-pad the buffer, if necessary */ - memset(ptr + state->count, 0, state->bytes - state->count); - - ptr += state->bytes; - bytes -= state->bytes; - - state->y += state->ystep; - - if (state->y < 0 || state->y >= state->ysize) { - state->errcode = IMAGING_CODEC_END; - break; - } - - } - - return ptr - buf; - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c deleted file mode 100755 index 76a66c2a5b1..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Storage.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * imaging storage object - * - * This baseline implementation is designed to efficiently handle - * large images, provided they fit into the available memory. - * - * history: - * 1995-06-15 fl Created - * 1995-09-12 fl Updated API, compiles silently under ANSI C++ - * 1995-11-26 fl Compiles silently under Borland 4.5 as well - * 1996-05-05 fl Correctly test status from Prologue - * 1997-05-12 fl Increased THRESHOLD (to speed up Tk interface) - * 1997-05-30 fl Added support for floating point images - * 1997-11-17 fl Added support for "RGBX" images - * 1998-01-11 fl Added support for integer images - * 1998-03-05 fl Exported Prologue/Epilogue functions - * 1998-07-01 fl Added basic "YCrCb" support - * 1998-07-03 fl Attach palette in prologue for "P" images - * 1998-07-09 hk Don't report MemoryError on zero-size images - * 1998-07-12 fl Change "YCrCb" to "YCbCr" (!) - * 1998-10-26 fl Added "I;16" and "I;16B" storage modes (experimental) - * 1998-12-29 fl Fixed allocation bug caused by previous fix - * 1999-02-03 fl Added "RGBa" and "BGR" modes (experimental) - * 2001-04-22 fl Fixed potential memory leak in ImagingCopyInfo - * 2003-09-26 fl Added "LA" and "PA" modes (experimental) - * 2005-10-02 fl Added image counter - * - * Copyright (c) 1998-2005 by Secret Labs AB - * Copyright (c) 1995-2005 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int ImagingNewCount = 0; - -/* -------------------------------------------------------------------- - * Standard image object. - */ - -Imaging -ImagingNewPrologueSubtype(const char *mode, unsigned xsize, unsigned ysize, - int size) -{ - Imaging im; - ImagingSectionCookie cookie; - - im = (Imaging) calloc(1, size); - if (!im) - return (Imaging) ImagingError_MemoryError(); - - /* Setup image descriptor */ - im->xsize = xsize; - im->ysize = ysize; - - im->type = IMAGING_TYPE_UINT8; - - if (strcmp(mode, "1") == 0) { - /* 1-bit images */ - im->bands = im->pixelsize = 1; - im->linesize = xsize; - - } else if (strcmp(mode, "P") == 0) { - /* 8-bit palette mapped images */ - im->bands = im->pixelsize = 1; - im->linesize = xsize; - im->palette = ImagingPaletteNew("RGB"); - - } else if (strcmp(mode, "PA") == 0) { - /* 8-bit palette with alpha */ - im->bands = 2; - im->pixelsize = 4; /* store in image32 memory */ - im->linesize = xsize * 4; - im->palette = ImagingPaletteNew("RGB"); - - } else if (strcmp(mode, "L") == 0) { - /* 8-bit greyscale (luminance) images */ - im->bands = im->pixelsize = 1; - im->linesize = xsize; - - } else if (strcmp(mode, "LA") == 0) { - /* 8-bit greyscale (luminance) with alpha */ - im->bands = 2; - im->pixelsize = 4; /* store in image32 memory */ - im->linesize = xsize * 4; - - } else if (strcmp(mode, "F") == 0) { - /* 32-bit floating point images */ - im->bands = 1; - im->pixelsize = 4; - im->linesize = xsize * 4; - im->type = IMAGING_TYPE_FLOAT32; - - } else if (strcmp(mode, "I") == 0) { - /* 32-bit integer images */ - im->bands = 1; - im->pixelsize = 4; - im->linesize = xsize * 4; - im->type = IMAGING_TYPE_INT32; - - } else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 || strcmp(mode, "I;16B") == 0) { - /* EXPERIMENTAL */ - /* 16-bit raw integer images */ - im->bands = 1; - im->pixelsize = 2; - im->linesize = xsize * 2; - im->type = IMAGING_TYPE_SPECIAL; - - } else if (strcmp(mode, "RGB") == 0) { - /* 24-bit true colour images */ - im->bands = 3; - im->pixelsize = 4; - im->linesize = xsize * 4; - - } else if (strcmp(mode, "BGR;15") == 0) { - /* EXPERIMENTAL */ - /* 15-bit true colour */ - im->bands = 1; - im->pixelsize = 2; - im->linesize = (xsize*2 + 3) & -4; - im->type = IMAGING_TYPE_SPECIAL; - - } else if (strcmp(mode, "BGR;16") == 0) { - /* EXPERIMENTAL */ - /* 16-bit reversed true colour */ - im->bands = 1; - im->pixelsize = 2; - im->linesize = (xsize*2 + 3) & -4; - im->type = IMAGING_TYPE_SPECIAL; - - } else if (strcmp(mode, "BGR;24") == 0) { - /* EXPERIMENTAL */ - /* 24-bit reversed true colour */ - im->bands = 1; - im->pixelsize = 3; - im->linesize = (xsize*3 + 3) & -4; - im->type = IMAGING_TYPE_SPECIAL; - - } else if (strcmp(mode, "BGR;32") == 0) { - /* EXPERIMENTAL */ - /* 32-bit reversed true colour */ - im->bands = 1; - im->pixelsize = 4; - im->linesize = (xsize*4 + 3) & -4; - im->type = IMAGING_TYPE_SPECIAL; - - } else if (strcmp(mode, "RGBX") == 0) { - /* 32-bit true colour images with padding */ - im->bands = im->pixelsize = 4; - im->linesize = xsize * 4; - - } else if (strcmp(mode, "RGBA") == 0) { - /* 32-bit true colour images with alpha */ - im->bands = im->pixelsize = 4; - im->linesize = xsize * 4; - - } else if (strcmp(mode, "RGBa") == 0) { - /* EXPERIMENTAL */ - /* 32-bit true colour images with premultiplied alpha */ - im->bands = im->pixelsize = 4; - im->linesize = xsize * 4; - - } else if (strcmp(mode, "CMYK") == 0) { - /* 32-bit colour separation */ - im->bands = im->pixelsize = 4; - im->linesize = xsize * 4; - - } else if (strcmp(mode, "YCbCr") == 0) { - /* 24-bit video format */ - im->bands = 3; - im->pixelsize = 4; - im->linesize = xsize * 4; - - } else { - free(im); - return (Imaging) ImagingError_ValueError("unrecognized mode"); - } - - /* Setup image descriptor */ - strcpy(im->mode, mode); - - ImagingSectionEnter(&cookie); - - /* Pointer array (allocate at least one line, to avoid MemoryError - exceptions on platforms where calloc(0, x) returns NULL) */ - im->image = (char **) calloc((ysize > 0) ? ysize : 1, sizeof(void *)); - - ImagingSectionLeave(&cookie); - - if (!im->image) { - free(im); - return (Imaging) ImagingError_MemoryError(); - } - - ImagingNewCount++; - - return im; -} - -Imaging -ImagingNewPrologue(const char *mode, unsigned xsize, unsigned ysize) -{ - return ImagingNewPrologueSubtype( - mode, xsize, ysize, sizeof(struct ImagingMemoryInstance) - ); -} - -Imaging -ImagingNewEpilogue(Imaging im) -{ - /* If the raster data allocator didn't setup a destructor, - assume that it couldn't allocate the required amount of - memory. */ - if (!im->destroy) - return (Imaging) ImagingError_MemoryError(); - - /* Initialize alias pointers to pixel data. */ - switch (im->pixelsize) { - case 1: case 2: case 3: - im->image8 = (UINT8 **) im->image; - break; - case 4: - im->image32 = (INT32 **) im->image; - break; - } - - return im; -} - -void -ImagingDelete(Imaging im) -{ - if (!im) - return; - - if (im->palette) - ImagingPaletteDelete(im->palette); - - if (im->destroy) - im->destroy(im); - - if (im->image) - free(im->image); - - free(im); -} - - -/* Array Storage Type */ -/* ------------------ */ -/* Allocate image as an array of line buffers. */ - -static void -ImagingDestroyArray(Imaging im) -{ - int y; - - if (im->image) - for (y = 0; y < im->ysize; y++) - if (im->image[y]) - free(im->image[y]); -} - -Imaging -ImagingNewArray(const char *mode, int xsize, int ysize) -{ - Imaging im; - ImagingSectionCookie cookie; - - int y; - char* p; - - im = ImagingNewPrologue(mode, xsize, ysize); - if (!im) - return NULL; - - ImagingSectionEnter(&cookie); - - /* Allocate image as an array of lines */ - for (y = 0; y < im->ysize; y++) { - p = (char *) malloc(im->linesize); - if (!p) { - ImagingDestroyArray(im); - break; - } - im->image[y] = p; - } - - ImagingSectionLeave(&cookie); - - if (y == im->ysize) - im->destroy = ImagingDestroyArray; - - return ImagingNewEpilogue(im); -} - - -/* Block Storage Type */ -/* ------------------ */ -/* Allocate image as a single block. */ - -static void -ImagingDestroyBlock(Imaging im) -{ - if (im->block) - free(im->block); -} - -Imaging -ImagingNewBlock(const char *mode, int xsize, int ysize) -{ - Imaging im; - int y, i; - int bytes; - - im = ImagingNewPrologue(mode, xsize, ysize); - if (!im) - return NULL; - - /* Use a single block */ - bytes = im->ysize * im->linesize; - if (bytes <= 0) - /* some platforms return NULL for malloc(0); this fix - prevents MemoryError on zero-sized images on such - platforms */ - bytes = 1; - im->block = (char *) malloc(bytes); - - if (im->block) { - - for (y = i = 0; y < im->ysize; y++) { - im->image[y] = im->block + i; - i += im->linesize; - } - - im->destroy = ImagingDestroyBlock; - - } - - return ImagingNewEpilogue(im); -} - -/* -------------------------------------------------------------------- - * Create a new, internally allocated, image. - */ -#if defined(IMAGING_SMALL_MODEL) -#define THRESHOLD 16384L -#else -#define THRESHOLD (2048*2048*4L) -#endif - -Imaging -ImagingNew(const char* mode, int xsize, int ysize) -{ - int bytes; - Imaging im; - - if (strlen(mode) == 1) { - if (mode[0] == 'F' || mode[0] == 'I') - bytes = 4; - else - bytes = 1; - } else - bytes = strlen(mode); /* close enough */ - - if ((long) xsize * ysize * bytes <= THRESHOLD) { - im = ImagingNewBlock(mode, xsize, ysize); - if (im) - return im; - /* assume memory error; try allocating in array mode instead */ - ImagingError_Clear(); - } - - return ImagingNewArray(mode, xsize, ysize); -} - -Imaging -ImagingNew2(const char* mode, Imaging imOut, Imaging imIn) -{ - /* allocate or validate output image */ - - if (imOut) { - /* make sure images match */ - if (strcmp(imOut->mode, mode) != 0 - || imOut->xsize != imIn->xsize - || imOut->ysize != imIn->ysize) { - return ImagingError_Mismatch(); - } - } else { - /* create new image */ - imOut = ImagingNew(mode, imIn->xsize, imIn->ysize); - if (!imOut) - return NULL; - } - - return imOut; -} - -void -ImagingCopyInfo(Imaging destination, Imaging source) -{ - if (source->palette) { - if (destination->palette) - ImagingPaletteDelete(destination->palette); - destination->palette = ImagingPaletteDuplicate(source->palette); - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c deleted file mode 100755 index bf34d93821f..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/SunRleDecode.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * THIS IS WORK IN PROGRESS - * - * The Python Imaging Library. - * $Id$ - * - * decoder for SUN RLE data. - * - * history: - * 97-01-04 fl Created - * - * Copyright (c) Fredrik Lundh 1997. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - int n; - UINT8* ptr; - - ptr = buf; - - for (;;) { - - if (bytes < 1) - return ptr - buf; - - if (ptr[0] == 0x80) { - - if (bytes < 2) - break; - - n = ptr[1]; - - if (n == 0) { - - /* Literal 0x80 (2 bytes) */ - n = 1; - - state->buffer[state->x] = 0x80; - - ptr += 2; - bytes -= 2; - - } else { - - /* Run (3 bytes) */ - if (bytes < 3) - break; - - if (state->x + n > state->bytes) { - /* FIXME: is this correct? */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - memset(state->buffer + state->x, ptr[2], n); - - ptr += 3; - bytes -= 3; - - } - - } else { - - /* Literal (1+n bytes block) */ - n = ptr[0]; - - if (bytes < 1 + n) - break; - - if (state->x + n > state->bytes) { - /* FIXME: is this correct? */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - memcpy(state->buffer + state->x, ptr + 1, n); - - ptr += 1 + n; - bytes -= 1 + n; - - } - - state->x += n; - - if (state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } - - } - - return ptr - buf; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c deleted file mode 100755 index cad6bc3bcfe..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/TgaRleDecode.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for Targa RLE data. - * - * history: - * 97-01-04 fl created - * 98-09-11 fl don't one byte per pixel; take orientation into account - * - * Copyright (c) Fredrik Lundh 1997. - * Copyright (c) Secret Labs AB 1997-98. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingTgaRleDecode(Imaging im, ImagingCodecState state, - UINT8* buf, int bytes) -{ - int n, depth; - UINT8* ptr; - - ptr = buf; - - if (state->state == 0) { - - /* check image orientation */ - if (state->ystep < 0) { - state->y = state->ysize-1; - state->ystep = -1; - } else - state->ystep = 1; - - state->state = 1; - - } - - depth = state->count; - - for (;;) { - - if (bytes < 1) - return ptr - buf; - - if (ptr[0] & 0x80) { - - /* Run (1 + pixelsize bytes) */ - - if (bytes < 1 + depth) - break; - - n = depth * ((ptr[0] & 0x7f) + 1); - - if (state->x + n > state->bytes) { - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - if (depth == 1) - memset(state->buffer + state->x, ptr[1], n); - else { - int i; - for (i = 0; i < n; i += depth) - memcpy(state->buffer + state->x + i, ptr+1, depth); - } - - ptr += 1 + depth; - bytes -= 1 + depth; - - } else { - - /* Literal (1+n+1 bytes block) */ - n = depth * (ptr[0] + 1); - - if (bytes < 1 + n) - break; - - if (state->x + n > state->bytes) { - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } - - memcpy(state->buffer + state->x, ptr + 1, n); - - ptr += 1 + n; - bytes -= 1 + n; - - } - - state->x += n; - - if (state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); - - state->x = 0; - - state->y += state->ystep; - - if (state->y < 0 || state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - - } - - } - - return ptr - buf; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c deleted file mode 100755 index 90a76feb341..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Unpack.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * code to unpack raw data from various file formats - * - * history: - * 1996-03-07 fl Created (from various decoders) - * 1996-04-19 fl Added band unpackers - * 1996-05-12 fl Published RGB unpackers - * 1996-05-27 fl Added nibble unpacker - * 1996-12-10 fl Added complete set of PNG unpackers - * 1996-12-29 fl Set alpha byte in RGB unpackers - * 1997-01-05 fl Added remaining TGA unpackers - * 1997-01-18 fl Added inverting band unpackers - * 1997-01-25 fl Added FlashPix unpackers - * 1997-05-31 fl Added floating point unpackers - * 1998-02-08 fl Added I unpacker - * 1998-07-01 fl Added YCbCr unpacker - * 1998-07-02 fl Added full set of integer unpackers - * 1998-12-29 fl Added mode field, I;16 unpackers - * 1998-12-30 fl Added RGBX modes - * 1999-02-04 fl Fixed I;16 unpackers - * 2003-05-13 fl Added L/RGB reversed unpackers - * 2003-09-26 fl Added LA/PA and RGBa->RGB unpackers - * - * Copyright (c) 1997-2003 by Secret Labs AB. - * Copyright (c) 1996-1997 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - -#include "Imaging.h" - - -#define R 0 -#define G 1 -#define B 2 -#define X 3 - -#define A 3 - -#define C 0 -#define M 1 -#define Y 2 -#define K 3 - -#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) - -/* byte-swapping macros */ - -#define C16N\ - (tmp[0]=in[0], tmp[1]=in[1]); -#define C16S\ - (tmp[1]=in[0], tmp[0]=in[1]); -#define C32N\ - (tmp[0]=in[0], tmp[1]=in[1], tmp[2]=in[2], tmp[3]=in[3]); -#define C32S\ - (tmp[3]=in[0], tmp[2]=in[1], tmp[1]=in[2], tmp[0]=in[3]); -#define C64N\ - (tmp[0]=in[0], tmp[1]=in[1], tmp[2]=in[2], tmp[3]=in[3],\ - tmp[4]=in[4], tmp[5]=in[5], tmp[6]=in[6], tmp[7]=in[7]); -#define C64S\ - (tmp[7]=in[0], tmp[6]=in[1], tmp[5]=in[2], tmp[4]=in[3],\ - tmp[3]=in[4], tmp[2]=in[5], tmp[1]=in[6], tmp[0]=in[7]); - -#ifdef WORDS_BIGENDIAN -#define C16B C16N -#define C16L C16S -#define C32B C32N -#define C32L C32S -#define C64B C64N -#define C64L C64S -#else -#define C16B C16S -#define C16L C16N -#define C32B C32S -#define C32L C32N -#define C64B C64S -#define C64L C64N -#endif - -/* bit-swapping */ - -static UINT8 BITFLIP[] = { - 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, - 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, - 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, - 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, - 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, - 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, - 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, - 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, - 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, - 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, - 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, - 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, - 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, - 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, - 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7, - 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, - 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, - 255 -}; - -/* Unpack to "1" image */ - -static void -unpack1(UINT8* out, const UINT8* in, int pixels) -{ - /* bits (msb first, white is non-zero) */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 7: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 6: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 5: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 4: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 3: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 2: *out++ = (byte & 128) ? 255 : 0; byte <<= 1; - case 1: *out++ = (byte & 128) ? 255 : 0; - } - pixels -= 8; - } -} - -static void -unpack1I(UINT8* out, const UINT8* in, int pixels) -{ - /* bits (msb first, white is zero) */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 7: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 6: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 5: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 4: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 3: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 2: *out++ = (byte & 128) ? 0 : 255; byte <<= 1; - case 1: *out++ = (byte & 128) ? 0 : 255; - } - pixels -= 8; - } -} - -static void -unpack1R(UINT8* out, const UINT8* in, int pixels) -{ - /* bits (lsb first, white is non-zero) */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 7: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 6: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 5: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 4: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 3: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 2: *out++ = (byte & 1) ? 255 : 0; byte >>= 1; - case 1: *out++ = (byte & 1) ? 255 : 0; - } - pixels -= 8; - } -} - -static void -unpack1IR(UINT8* out, const UINT8* in, int pixels) -{ - /* bits (lsb first, white is zero) */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 7: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 6: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 5: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 4: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 3: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 2: *out++ = (byte & 1) ? 0 : 255; byte >>= 1; - case 1: *out++ = (byte & 1) ? 0 : 255; - } - pixels -= 8; - } -} - - -/* Unpack to "L" image */ - -static void -unpackL2(UINT8* out, const UINT8* in, int pixels) -{ - /* nibbles */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2; - case 3: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2; - case 2: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2; - case 1: *out++ = ((byte >> 6) & 3) * 255 / 3; - } - pixels -= 4; - } -} - -static void -unpackL4(UINT8* out, const UINT8* in, int pixels) -{ - /* nibbles */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = ((byte >> 4) & 15) * 255 / 15; byte <<= 4; - case 1: *out++ = ((byte >> 4) & 15) * 255 / 15; - } - pixels -= 2; - } -} - -static void -unpackLA(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* LA, pixel interleaved */ - for (i = 0; i < pixels; i++) { - out[R] = out[G] = out[B] = in[0]; - out[A] = in[1]; - in += 2; out += 4; - } -} - -static void -unpackLAL(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* LA, line interleaved */ - for (i = 0; i < pixels; i++) { - out[R] = out[G] = out[B] = in[i]; - out[A] = in[i+pixels]; - out += 4; - } -} - -static void -unpackLI(UINT8* out, const UINT8* in, int pixels) -{ - /* negative */ - int i; - for (i = 0; i < pixels; i++) - out[i] = ~in[i]; -} - -static void -unpackLR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, bit reversed */ - for (i = 0; i < pixels; i++) { - out[i] = BITFLIP[in[i]]; - } -} - -static void -unpackL16(UINT8* out, const UINT8* in, int pixels) -{ - /* int16 (upper byte, little endian) */ - int i; - for (i = 0; i < pixels; i++) { - out[i] = in[1]; - in += 2; - } -} - -static void -unpackL16B(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* int16 (upper byte, big endian) */ - for (i = 0; i < pixels; i++) { - out[i] = in[0]; - in += 2; - } -} - - -/* Unpack to "P" image */ - -static void -unpackP1(UINT8* out, const UINT8* in, int pixels) -{ - /* bits */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte >> 7) & 1; byte <<= 1; - case 7: *out++ = (byte >> 7) & 1; byte <<= 1; - case 6: *out++ = (byte >> 7) & 1; byte <<= 1; - case 5: *out++ = (byte >> 7) & 1; byte <<= 1; - case 4: *out++ = (byte >> 7) & 1; byte <<= 1; - case 3: *out++ = (byte >> 7) & 1; byte <<= 1; - case 2: *out++ = (byte >> 7) & 1; byte <<= 1; - case 1: *out++ = (byte >> 7) & 1; - } - pixels -= 8; - } -} - -static void -unpackP2(UINT8* out, const UINT8* in, int pixels) -{ - /* bit pairs */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte >> 6) & 3; byte <<= 2; - case 3: *out++ = (byte >> 6) & 3; byte <<= 2; - case 2: *out++ = (byte >> 6) & 3; byte <<= 2; - case 1: *out++ = (byte >> 6) & 3; - } - pixels -= 4; - } -} - -static void -unpackP4(UINT8* out, const UINT8* in, int pixels) -{ - /* nibbles */ - while (pixels > 0) { - UINT8 byte = *in++; - switch (pixels) { - default: *out++ = (byte >> 4) & 15; byte <<= 4; - case 1: *out++ = (byte >> 4) & 15; - } - pixels -= 2; - } -} - -static void -unpackP2L(UINT8* out, const UINT8* in, int pixels) -{ - int i, j, m, s; - /* bit layers */ - m = 128; - s = (pixels+7)/8; - for (i = j = 0; i < pixels; i++) { - out[i] = ((in[j] & m) ? 1 : 0) + ((in[j + s] & m) ? 2 : 0); - if ((m >>= 1) == 0) { - m = 128; - j++; - } - } -} - -static void -unpackP4L(UINT8* out, const UINT8* in, int pixels) -{ - int i, j, m, s; - /* bit layers (trust the optimizer ;-) */ - m = 128; - s = (pixels+7)/8; - for (i = j = 0; i < pixels; i++) { - out[i] = ((in[j] & m) ? 1 : 0) + ((in[j + s] & m) ? 2 : 0) + - ((in[j + 2*s] & m) ? 4 : 0) + ((in[j + 3*s] & m) ? 8 : 0); - if ((m >>= 1) == 0) { - m = 128; - j++; - } - } -} - -/* Unpack to "RGB" image */ - -void -ImagingUnpackRGB(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB triplets */ - for (i = 0; i < pixels; i++) { - out[R] = in[0]; - out[G] = in[1]; - out[B] = in[2]; - out[A] = 255; - out += 4; in += 3; - } -} - -void -unpackRGB16B(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* 16-bit RGB triplets, big-endian order */ - for (i = 0; i < pixels; i++) { - out[R] = in[0]; - out[G] = in[2]; - out[B] = in[4]; - out[A] = 255; - out += 4; in += 6; - } -} - -static void -unpackRGBL(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, line interleaved */ - for (i = 0; i < pixels; i++) { - out[R] = in[i]; - out[G] = in[i+pixels]; - out[B] = in[i+pixels+pixels]; - out[A] = 255; - out += 4; - } -} - -static void -unpackRGBR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, bit reversed */ - for (i = 0; i < pixels; i++) { - out[R] = BITFLIP[in[0]]; - out[G] = BITFLIP[in[1]]; - out[B] = BITFLIP[in[2]]; - out[A] = 255; - out += 4; in += 3; - } -} - -void -ImagingUnpackBGR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, reversed bytes */ - for (i = 0; i < pixels; i++) { - out[R] = in[2]; - out[G] = in[1]; - out[B] = in[0]; - out[A] = 255; - out += 4; in += 3; - } -} - -void -ImagingUnpackBGR15(UINT8* out, const UINT8* in, int pixels) -{ - int i, pixel; - /* RGB, reversed bytes, 5 bits per pixel */ - for (i = 0; i < pixels; i++) { - pixel = in[0] + (in[1] << 8); - out[B] = (pixel & 31) * 255 / 31; - out[G] = ((pixel>>5) & 31) * 255 / 31; - out[R] = ((pixel>>10) & 31) * 255 / 31; - out[A] = 255; - out += 4; in += 2; - } -} - -void -ImagingUnpackBGR16(UINT8* out, const UINT8* in, int pixels) -{ - int i, pixel; - /* RGB, reversed bytes, 5/6/5 bits per pixel */ - for (i = 0; i < pixels; i++) { - pixel = in[0] + (in[1] << 8); - out[B] = (pixel & 31) * 255 / 31; - out[G] = ((pixel>>5) & 63) * 255 / 63; - out[R] = ((pixel>>11) & 31) * 255 / 31; - out[A] = 255; - out += 4; in += 2; - } -} - -static void -ImagingUnpackBGRX(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, reversed bytes with padding */ - for (i = 0; i < pixels; i++) { - out[R] = in[2]; - out[G] = in[1]; - out[B] = in[0]; - out[A] = 255; - out += 4; in += 4; - } -} - -static void -ImagingUnpackXRGB(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, leading pad */ - for (i = 0; i < pixels; i++) { - out[R] = in[1]; - out[G] = in[2]; - out[B] = in[3]; - out[A] = 255; - out += 4; in += 4; - } -} - -static void -ImagingUnpackXBGR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGB, reversed bytes, leading pad */ - for (i = 0; i < pixels; i++) { - out[R] = in[3]; - out[G] = in[2]; - out[B] = in[1]; - out[A] = 255; - out += 4; in += 4; - } -} - -/* Unpack to "RGBA" image */ - -static void -unpackRGBALA(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* greyscale with alpha */ - for (i = 0; i < pixels; i++) { - out[R] = out[G] = out[B] = in[0]; - out[A] = in[1]; - out += 4; in += 2; - } -} - -static void -unpackRGBALA16B(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* 16-bit greyscale with alpha, big-endian */ - for (i = 0; i < pixels; i++) { - out[R] = out[G] = out[B] = in[0]; - out[A] = in[2]; - out += 4; in += 4; - } -} - -static void -unpackRGBa(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* premultiplied RGBA */ - for (i = 0; i < pixels; i++) { - int a = in[3]; - if (!a) - out[R] = out[G] = out[B] = out[A] = 0; - else { - out[R] = CLIP(in[0] * 255 / a); - out[G] = CLIP(in[1] * 255 / a); - out[B] = CLIP(in[2] * 255 / a); - out[A] = a; - } - out += 4; in += 4; - } -} - -static void -unpackRGBAI(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGBA, inverted RGB bytes (FlashPix) */ - for (i = 0; i < pixels; i++) { - out[R] = ~in[0]; - out[G] = ~in[1]; - out[B] = ~in[2]; - out[A] = in[3]; - out += 4; in += 4; - } -} - -static void -unpackRGBAL(UINT8* out, const UINT8* in, int pixels) -{ - int i; - - /* RGBA, line interleaved */ - for (i = 0; i < pixels; i++) { - out[R] = in[i]; - out[G] = in[i+pixels]; - out[B] = in[i+pixels+pixels]; - out[A] = in[i+pixels+pixels+pixels]; - out += 4; - } -} - -void -unpackRGBA16B(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* 16-bit RGBA, big-endian order */ - for (i = 0; i < pixels; i++) { - out[R] = in[0]; - out[G] = in[2]; - out[B] = in[4]; - out[A] = in[6]; - out += 4; in += 8; - } -} - -static void -unpackARGB(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGBA, leading pad */ - for (i = 0; i < pixels; i++) { - out[R] = in[1]; - out[G] = in[2]; - out[B] = in[3]; - out[A] = in[0]; - out += 4; in += 4; - } -} - -static void -unpackABGR(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGBA, reversed bytes */ - for (i = 0; i < pixels; i++) { - out[R] = in[3]; - out[G] = in[2]; - out[B] = in[1]; - out[A] = in[0]; - out += 4; in += 4; - } -} - -static void -unpackBGRA(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* RGBA, reversed bytes */ - for (i = 0; i < pixels; i++) { - out[R] = in[2]; - out[G] = in[1]; - out[B] = in[0]; - out[A] = in[3]; - out += 4; in += 4; - } -} - - -/* Unpack to "CMYK" image */ - -static void -unpackCMYKI(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* CMYK, inverted bytes (Photoshop 2.5) */ - for (i = 0; i < pixels; i++) { - out[C] = ~in[0]; - out[M] = ~in[1]; - out[Y] = ~in[2]; - out[K] = ~in[3]; - out += 4; in += 4; - } -} - -static void -copy1(UINT8* out, const UINT8* in, int pixels) -{ - /* L, P */ - memcpy(out, in, pixels); -} - -static void -copy2(UINT8* out, const UINT8* in, int pixels) -{ - /* I;16 */ - memcpy(out, in, pixels*2); -} - -static void -copy4(UINT8* out, const UINT8* in, int pixels) -{ - /* RGBA, CMYK quadruples */ - memcpy(out, in, 4 * pixels); -} - - -/* Unpack to "I" and "F" images */ - -#define UNPACK_RAW(NAME, GET, INTYPE, OUTTYPE)\ -static void NAME(UINT8* out_, const UINT8* in, int pixels)\ -{\ - int i;\ - OUTTYPE* out = (OUTTYPE*) out_;\ - for (i = 0; i < pixels; i++, in += sizeof(INTYPE))\ - out[i] = (OUTTYPE) ((INTYPE) GET);\ -} - -#define UNPACK(NAME, COPY, INTYPE, OUTTYPE)\ -static void NAME(UINT8* out_, const UINT8* in, int pixels)\ -{\ - int i;\ - OUTTYPE* out = (OUTTYPE*) out_;\ - INTYPE tmp_;\ - UINT8* tmp = (UINT8*) &tmp_;\ - for (i = 0; i < pixels; i++, in += sizeof(INTYPE)) {\ - COPY;\ - out[i] = (OUTTYPE) tmp_;\ - }\ -} - -UNPACK_RAW(unpackI8, in[0], UINT8, INT32) -UNPACK_RAW(unpackI8S, in[0], INT8, INT32) -UNPACK(unpackI16, C16L, UINT16, INT32) -UNPACK(unpackI16S, C16L, INT16, INT32) -UNPACK(unpackI16B, C16B, UINT16, INT32) -UNPACK(unpackI16BS, C16B, INT16, INT32) -UNPACK(unpackI16N, C16N, UINT16, INT32) -UNPACK(unpackI16NS, C16N, INT16, INT32) -UNPACK(unpackI32, C32L, UINT32, INT32) -UNPACK(unpackI32S, C32L, INT32, INT32) -UNPACK(unpackI32B, C32B, UINT32, INT32) -UNPACK(unpackI32BS, C32B, INT32, INT32) -UNPACK(unpackI32N, C32N, UINT32, INT32) -UNPACK(unpackI32NS, C32N, INT32, INT32) - -UNPACK_RAW(unpackF8, in[0], UINT8, FLOAT32) -UNPACK_RAW(unpackF8S, in[0], INT8, FLOAT32) -UNPACK(unpackF16, C16L, UINT16, FLOAT32) -UNPACK(unpackF16S, C16L, INT16, FLOAT32) -UNPACK(unpackF16B, C16B, UINT16, FLOAT32) -UNPACK(unpackF16BS, C16B, INT16, FLOAT32) -UNPACK(unpackF16N, C16N, UINT16, FLOAT32) -UNPACK(unpackF16NS, C16N, INT16, FLOAT32) -UNPACK(unpackF32, C32L, UINT32, FLOAT32) -UNPACK(unpackF32S, C32L, INT32, FLOAT32) -UNPACK(unpackF32B, C32B, UINT32, FLOAT32) -UNPACK(unpackF32BS, C32B, INT32, FLOAT32) -UNPACK(unpackF32N, C32N, UINT32, FLOAT32) -UNPACK(unpackF32NS, C32N, INT32, FLOAT32) -UNPACK(unpackF32F, C32L, FLOAT32, FLOAT32) -UNPACK(unpackF32BF, C32B, FLOAT32, FLOAT32) -UNPACK(unpackF32NF, C32N, FLOAT32, FLOAT32) -#ifdef FLOAT64 -UNPACK(unpackF64F, C64L, FLOAT64, FLOAT32) -UNPACK(unpackF64BF, C64B, FLOAT64, FLOAT32) -UNPACK(unpackF64NF, C64N, FLOAT64, FLOAT32) -#endif - - -/* Misc. unpackers */ - -static void -band0(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* band 0 only */ - for (i = 0; i < pixels; i++) { - out[0] = in[i]; - out += 4; - } -} - -static void -band1(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* band 1 only */ - for (i = 0; i < pixels; i++) { - out[1] = in[i]; - out += 4; - } -} - -static void -band2(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* band 2 only */ - for (i = 0; i < pixels; i++) { - out[2] = in[i]; - out += 4; - } -} - -static void -band3(UINT8* out, const UINT8* in, int pixels) -{ - /* band 3 only */ - int i; - for (i = 0; i < pixels; i++) { - out[3] = in[i]; - out += 4; - } -} - -static void -band0I(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* band 0 only */ - for (i = 0; i < pixels; i++) { - out[0] = ~in[i]; - out += 4; - } -} - -static void -band1I(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* band 1 only */ - for (i = 0; i < pixels; i++) { - out[1] = ~in[i]; - out += 4; - } -} - -static void -band2I(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* band 2 only */ - for (i = 0; i < pixels; i++) { - out[2] = ~in[i]; - out += 4; - } -} - -static void -band3I(UINT8* out, const UINT8* in, int pixels) -{ - /* band 3 only */ - int i; - for (i = 0; i < pixels; i++) { - out[3] = ~in[i]; - out += 4; - } -} - -static struct { - const char* mode; - const char* rawmode; - int bits; - ImagingShuffler unpack; -} unpackers[] = { - - /* raw mode syntax is ";" where "bits" defaults - depending on mode (1 for "1", 8 for "P" and "L", etc), and - "flags" should be given in alphabetical order. if both bits - and flags have their default values, the ; should be left out */ - - /* flags: "I" inverted data; "R" reversed bit order; "B" big - endian byte order (default is little endian); "L" line - interleave, "S" signed, "F" floating point */ - - /* bilevel */ - {"1", "1", 1, unpack1}, - {"1", "1;I", 1, unpack1I}, - {"1", "1;R", 1, unpack1R}, - {"1", "1;IR", 1, unpack1IR}, - - /* greyscale */ - {"L", "L;2", 2, unpackL2}, - {"L", "L;4", 4, unpackL4}, - {"L", "L", 8, copy1}, - {"L", "L;I", 8, unpackLI}, - {"L", "L;R", 8, unpackLR}, - {"L", "L;16", 16, unpackL16}, - {"L", "L;16B", 16, unpackL16B}, - - /* greyscale w. alpha */ - {"LA", "LA", 16, unpackLA}, - {"LA", "LA;L", 16, unpackLAL}, - - /* palette */ - {"P", "P;1", 1, unpackP1}, - {"P", "P;2", 2, unpackP2}, - {"P", "P;2L", 2, unpackP2L}, - {"P", "P;4", 4, unpackP4}, - {"P", "P;4L", 4, unpackP4L}, - {"P", "P", 8, copy1}, - {"P", "P;R", 8, unpackLR}, - - /* palette w. alpha */ - {"PA", "PA", 16, unpackLA}, - {"PA", "PA;L", 16, unpackLAL}, - - /* true colour */ - {"RGB", "RGB", 24, ImagingUnpackRGB}, - {"RGB", "RGB;L", 24, unpackRGBL}, - {"RGB", "RGB;R", 24, unpackRGBR}, - {"RGB", "RGB;16B", 48, unpackRGB16B}, - {"RGB", "BGR", 24, ImagingUnpackBGR}, - {"RGB", "BGR;15", 16, ImagingUnpackBGR15}, - {"RGB", "BGR;16", 16, ImagingUnpackBGR16}, - {"RGB", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */ - {"RGB", "RGBX", 32, copy4}, - {"RGB", "RGBX;L", 32, unpackRGBAL}, - {"RGB", "BGRX", 32, ImagingUnpackBGRX}, - {"RGB", "XRGB", 24, ImagingUnpackXRGB}, - {"RGB", "XBGR", 32, ImagingUnpackXBGR}, - {"RGB", "YCC;P", 24, ImagingUnpackYCC}, - {"RGB", "R", 8, band0}, - {"RGB", "G", 8, band1}, - {"RGB", "B", 8, band2}, - - /* true colour w. alpha */ - {"RGBA", "LA", 16, unpackRGBALA}, - {"RGBA", "LA;16B", 32, unpackRGBALA16B}, - {"RGBA", "RGBA", 32, copy4}, - {"RGBA", "RGBa", 32, unpackRGBa}, - {"RGBA", "RGBA;I", 32, unpackRGBAI}, - {"RGBA", "RGBA;L", 32, unpackRGBAL}, - {"RGBA", "RGBA;16B", 64, unpackRGBA16B}, - {"RGBA", "BGRA", 32, unpackBGRA}, - {"RGBA", "ARGB", 32, unpackARGB}, - {"RGBA", "ABGR", 32, unpackABGR}, - {"RGBA", "YCCA;P", 32, ImagingUnpackYCCA}, - {"RGBA", "R", 8, band0}, - {"RGBA", "G", 8, band1}, - {"RGBA", "B", 8, band2}, - {"RGBA", "A", 8, band3}, - - /* true colour w. padding */ - {"RGBX", "RGB", 24, ImagingUnpackRGB}, - {"RGBX", "RGB;L", 24, unpackRGBL}, - {"RGBX", "RGB;16B", 48, unpackRGB16B}, - {"RGBX", "BGR", 24, ImagingUnpackBGR}, - {"RGBX", "BGR;15", 16, ImagingUnpackBGR15}, - {"RGB", "BGR;16", 16, ImagingUnpackBGR16}, - {"RGBX", "BGR;5", 16, ImagingUnpackBGR15}, /* compat */ - {"RGBX", "RGBX", 32, copy4}, - {"RGBX", "RGBX;L", 32, unpackRGBAL}, - {"RGBX", "BGRX", 32, ImagingUnpackBGRX}, - {"RGBX", "XRGB", 24, ImagingUnpackXRGB}, - {"RGBX", "XBGR", 32, ImagingUnpackXBGR}, - {"RGBX", "YCC;P", 24, ImagingUnpackYCC}, - {"RGBX", "R", 8, band0}, - {"RGBX", "G", 8, band1}, - {"RGBX", "B", 8, band2}, - {"RGBX", "X", 8, band3}, - - /* colour separation */ - {"CMYK", "CMYK", 32, copy4}, - {"CMYK", "CMYK;I", 32, unpackCMYKI}, - {"CMYK", "CMYK;L", 32, unpackRGBAL}, - {"CMYK", "C", 8, band0}, - {"CMYK", "M", 8, band1}, - {"CMYK", "Y", 8, band2}, - {"CMYK", "K", 8, band3}, - {"CMYK", "C;I", 8, band0I}, - {"CMYK", "M;I", 8, band1I}, - {"CMYK", "Y;I", 8, band2I}, - {"CMYK", "K;I", 8, band3I}, - - /* video (YCbCr) */ - {"YCbCr", "YCbCr", 24, ImagingUnpackRGB}, - {"YCbCr", "YCbCr;L", 24, unpackRGBL}, - {"YCbCr", "YCbCrX", 32, copy4}, - {"YCbCr", "YCbCrK", 32, copy4}, - - /* integer variations */ - {"I", "I", 32, copy4}, - {"I", "I;8", 8, unpackI8}, - {"I", "I;8S", 8, unpackI8S}, - {"I", "I;16", 16, unpackI16}, - {"I", "I;16S", 16, unpackI16S}, - {"I", "I;16B", 16, unpackI16B}, - {"I", "I;16BS", 16, unpackI16BS}, - {"I", "I;16N", 16, unpackI16N}, - {"I", "I;16NS", 16, unpackI16NS}, - {"I", "I;32", 32, unpackI32}, - {"I", "I;32S", 32, unpackI32S}, - {"I", "I;32B", 32, unpackI32B}, - {"I", "I;32BS", 32, unpackI32BS}, - {"I", "I;32N", 32, unpackI32N}, - {"I", "I;32NS", 32, unpackI32NS}, - - /* floating point variations */ - {"F", "F", 32, copy4}, - {"F", "F;8", 8, unpackF8}, - {"F", "F;8S", 8, unpackF8S}, - {"F", "F;16", 16, unpackF16}, - {"F", "F;16S", 16, unpackF16S}, - {"F", "F;16B", 16, unpackF16B}, - {"F", "F;16BS", 16, unpackF16BS}, - {"F", "F;16N", 16, unpackF16N}, - {"F", "F;16NS", 16, unpackF16NS}, - {"F", "F;32", 32, unpackF32}, - {"F", "F;32S", 32, unpackF32S}, - {"F", "F;32B", 32, unpackF32B}, - {"F", "F;32BS", 32, unpackF32BS}, - {"F", "F;32N", 32, unpackF32N}, - {"F", "F;32NS", 32, unpackF32NS}, - {"F", "F;32F", 32, unpackF32F}, - {"F", "F;32BF", 32, unpackF32BF}, - {"F", "F;32NF", 32, unpackF32NF}, -#ifdef FLOAT64 - {"F", "F;64F", 64, unpackF64F}, - {"F", "F;64BF", 64, unpackF64BF}, - {"F", "F;64NF", 64, unpackF64NF}, -#endif - - /* storage modes */ - {"I;16", "I;16", 16, copy2}, - {"I;16B", "I;16B", 16, copy2}, - {"I;16L", "I;16L", 16, copy2}, - - {NULL} /* sentinel */ -}; - - -ImagingShuffler -ImagingFindUnpacker(const char* mode, const char* rawmode, int* bits_out) -{ - int i; - - /* find a suitable pixel unpacker */ - for (i = 0; unpackers[i].rawmode; i++) - if (strcmp(unpackers[i].mode, mode) == 0 && - strcmp(unpackers[i].rawmode, rawmode) == 0) { - if (bits_out) - *bits_out = unpackers[i].bits; - return unpackers[i].unpack; - } - - /* FIXME: configure a general unpacker based on the type codes... */ - - return NULL; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c deleted file mode 100755 index 19da1f65443..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnpackYCC.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * code to convert and unpack PhotoYCC data - * - * history: - * 97-01-25 fl Moved from PcdDecode.c - * - * Copyright (c) Fredrik Lundh 1996-97. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -/* Tables generated by pcdtables.py, based on transforms taken from - the "Colour Space Conversions FAQ" by Roberts/Ford. */ - -static INT16 L[] = { 0, 1, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 18, -19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, -42, 43, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 60, 61, 62, 64, -65, 67, 68, 69, 71, 72, 73, 75, 76, 77, 79, 80, 82, 83, 84, 86, 87, -88, 90, 91, 92, 94, 95, 96, 98, 99, 101, 102, 103, 105, 106, 107, 109, -110, 111, 113, 114, 115, 117, 118, 120, 121, 122, 124, 125, 126, 128, -129, 130, 132, 133, 134, 136, 137, 139, 140, 141, 143, 144, 145, 147, -148, 149, 151, 152, 153, 155, 156, 158, 159, 160, 162, 163, 164, 166, -167, 168, 170, 171, 173, 174, 175, 177, 178, 179, 181, 182, 183, 185, -186, 187, 189, 190, 192, 193, 194, 196, 197, 198, 200, 201, 202, 204, -205, 206, 208, 209, 211, 212, 213, 215, 216, 217, 219, 220, 221, 223, -224, 225, 227, 228, 230, 231, 232, 234, 235, 236, 238, 239, 240, 242, -243, 245, 246, 247, 249, 250, 251, 253, 254, 255, 257, 258, 259, 261, -262, 264, 265, 266, 268, 269, 270, 272, 273, 274, 276, 277, 278, 280, -281, 283, 284, 285, 287, 288, 289, 291, 292, 293, 295, 296, 297, 299, -300, 302, 303, 304, 306, 307, 308, 310, 311, 312, 314, 315, 317, 318, -319, 321, 322, 323, 325, 326, 327, 329, 330, 331, 333, 334, 336, 337, -338, 340, 341, 342, 344, 345, 346 }; - -static INT16 CB[] = { -345, -343, -341, -338, -336, -334, -332, -329, --327, -325, -323, -321, -318, -316, -314, -312, -310, -307, -305, --303, -301, -298, -296, -294, -292, -290, -287, -285, -283, -281, --278, -276, -274, -272, -270, -267, -265, -263, -261, -258, -256, --254, -252, -250, -247, -245, -243, -241, -239, -236, -234, -232, --230, -227, -225, -223, -221, -219, -216, -214, -212, -210, -207, --205, -203, -201, -199, -196, -194, -192, -190, -188, -185, -183, --181, -179, -176, -174, -172, -170, -168, -165, -163, -161, -159, --156, -154, -152, -150, -148, -145, -143, -141, -139, -137, -134, --132, -130, -128, -125, -123, -121, -119, -117, -114, -112, -110, --108, -105, -103, -101, -99, -97, -94, -92, -90, -88, -85, -83, -81, --79, -77, -74, -72, -70, -68, -66, -63, -61, -59, -57, -54, -52, -50, --48, -46, -43, -41, -39, -37, -34, -32, -30, -28, -26, -23, -21, -19, --17, -15, -12, -10, -8, -6, -3, -1, 0, 2, 4, 7, 9, 11, 13, 16, 18, 20, -22, 24, 27, 29, 31, 33, 35, 38, 40, 42, 44, 47, 49, 51, 53, 55, 58, -60, 62, 64, 67, 69, 71, 73, 75, 78, 80, 82, 84, 86, 89, 91, 93, 95, -98, 100, 102, 104, 106, 109, 111, 113, 115, 118, 120, 122, 124, 126, -129, 131, 133, 135, 138, 140, 142, 144, 146, 149, 151, 153, 155, 157, -160, 162, 164, 166, 169, 171, 173, 175, 177, 180, 182, 184, 186, 189, -191, 193, 195, 197, 200, 202, 204, 206, 208, 211, 213, 215, 217, 220 }; - -static INT16 GB[] = { 67, 67, 66, 66, 65, 65, 65, 64, 64, 63, 63, 62, -62, 62, 61, 61, 60, 60, 59, 59, 59, 58, 58, 57, 57, 56, 56, 56, 55, -55, 54, 54, 53, 53, 52, 52, 52, 51, 51, 50, 50, 49, 49, 49, 48, 48, -47, 47, 46, 46, 46, 45, 45, 44, 44, 43, 43, 43, 42, 42, 41, 41, 40, -40, 40, 39, 39, 38, 38, 37, 37, 37, 36, 36, 35, 35, 34, 34, 34, 33, -33, 32, 32, 31, 31, 31, 30, 30, 29, 29, 28, 28, 28, 27, 27, 26, 26, -25, 25, 25, 24, 24, 23, 23, 22, 22, 22, 21, 21, 20, 20, 19, 19, 19, -18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 13, 13, 12, 12, 12, 11, -11, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, -1, 1, 0, 0, 0, 0, 0, -1, -1, -2, -2, -2, -3, -3, -4, -4, -5, -5, -5, --6, -6, -7, -7, -8, -8, -8, -9, -9, -10, -10, -11, -11, -11, -12, -12, --13, -13, -14, -14, -14, -15, -15, -16, -16, -17, -17, -18, -18, -18, --19, -19, -20, -20, -21, -21, -21, -22, -22, -23, -23, -24, -24, -24, --25, -25, -26, -26, -27, -27, -27, -28, -28, -29, -29, -30, -30, -30, --31, -31, -32, -32, -33, -33, -33, -34, -34, -35, -35, -36, -36, -36, --37, -37, -38, -38, -39, -39, -39, -40, -40, -41, -41, -42 }; - -static INT16 CR[] = { -249, -247, -245, -243, -241, -239, -238, -236, --234, -232, -230, -229, -227, -225, -223, -221, -219, -218, -216, --214, -212, -210, -208, -207, -205, -203, -201, -199, -198, -196, --194, -192, -190, -188, -187, -185, -183, -181, -179, -178, -176, --174, -172, -170, -168, -167, -165, -163, -161, -159, -157, -156, --154, -152, -150, -148, -147, -145, -143, -141, -139, -137, -136, --134, -132, -130, -128, -127, -125, -123, -121, -119, -117, -116, --114, -112, -110, -108, -106, -105, -103, -101, -99, -97, -96, -94, --92, -90, -88, -86, -85, -83, -81, -79, -77, -76, -74, -72, -70, -68, --66, -65, -63, -61, -59, -57, -55, -54, -52, -50, -48, -46, -45, -43, --41, -39, -37, -35, -34, -32, -30, -28, -26, -25, -23, -21, -19, -17, --15, -14, -12, -10, -8, -6, -4, -3, -1, 0, 2, 4, 5, 7, 9, 11, 13, 15, -16, 18, 20, 22, 24, 26, 27, 29, 31, 33, 35, 36, 38, 40, 42, 44, 46, -47, 49, 51, 53, 55, 56, 58, 60, 62, 64, 66, 67, 69, 71, 73, 75, 77, -78, 80, 82, 84, 86, 87, 89, 91, 93, 95, 97, 98, 100, 102, 104, 106, -107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 129, 131, -133, 135, 137, 138, 140, 142, 144, 146, 148, 149, 151, 153, 155, 157, -158, 160, 162, 164, 166, 168, 169, 171, 173, 175, 177, 179, 180, 182, -184, 186, 188, 189, 191, 193, 195, 197, 199, 200, 202, 204, 206, 208, -209, 211, 213, 215 }; - -static INT16 GR[] = { 127, 126, 125, 124, 123, 122, 121, 121, 120, 119, -118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 108, 107, 106, -105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 95, 94, 93, 92, 91, -90, 89, 88, 87, 86, 85, 84, 83, 83, 82, 81, 80, 79, 78, 77, 76, 75, -74, 73, 72, 71, 70, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, -58, 57, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 45, 44, -43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28, -27, 26, 25, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, -11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5, -5, --6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -18, -19, --20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -31, -32, --33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -44, -45, --46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -56, -57, -58, --59, -60, -61, -62, -63, -64, -65, -66, -67, -68, -69, -69, -70, -71, --72, -73, -74, -75, -76, -77, -78, -79, -80, -81, -82, -82, -83, -84, --85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -94, -95, -96, -97, --98, -99, -100, -101, -102, -103, -104, -105, -106, -107, -107, -108 }; - -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -#define YCC2RGB(rgb, y, cb, cr) {\ - int l = L[y];\ - int r = l + CR[cr];\ - int g = l + GR[cr] + GB[cb];\ - int b = l + CB[cb];\ - rgb[0] = (r <= 0) ? 0 : (r >= 255) ? 255 : r;\ - rgb[1] = (g <= 0) ? 0 : (g >= 255) ? 255 : g;\ - rgb[2] = (b <= 0) ? 0 : (b >= 255) ? 255 : b;\ -} - -void -ImagingUnpackYCC(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* PhotoYCC triplets */ - for (i = 0; i < pixels; i++) { - YCC2RGB(out, in[0], in[1], in[2]); - out[A] = 255; - out += 4; in += 3; - } -} - -void -ImagingUnpackYCCA(UINT8* out, const UINT8* in, int pixels) -{ - int i; - /* PhotoYCC triplets plus premultiplied alpha */ - for (i = 0; i < pixels; i++) { - /* Divide by alpha */ - UINT8 rgb[3]; - rgb[0] = (in[3] == 0) ? 0 : (((int) in[0] * 255) / in[3]); - rgb[1] = (in[3] == 0) ? 0 : (((int) in[1] * 255) / in[3]); - rgb[2] = (in[3] == 0) ? 0 : (((int) in[2] * 255) / in[3]); - /* Convert non-multiplied data to RGB */ - YCC2RGB(out, rgb[0], rgb[1], rgb[2]); - out[A] = in[3]; - out += 4; in += 4; - } -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c deleted file mode 100755 index 2318262450e..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/UnsharpMask.c +++ /dev/null @@ -1,398 +0,0 @@ -/* PILusm, a gaussian blur and unsharp masking library for PIL - By Kevin Cazabon, copyright 2003 - kevin_cazabon@hotmail.com - kevin@cazabon.com */ - -/* Originally released under LGPL. Graciously donated to PIL - for distribution under the standard PIL license in 2009." */ - -#include "Python.h" -#include "Imaging.h" - -#define PILUSMVERSION "0.6.1" - -/* version history - -0.6.1 converted to C and added to PIL 1.1.7 - -0.6.0 fixed/improved float radius support (oops!) - now that radius can be a float (properly), changed radius value to - be an actual radius (instead of diameter). So, you should get - similar results from PIL_usm as from other paint programs when - using the SAME values (no doubling of radius required any more). - Be careful, this may "break" software if you had it set for 2x - or 5x the radius as was recommended with earlier versions. - made PILusm thread-friendly (release GIL before lengthly operations, - and re-acquire it before returning to Python). This makes a huge - difference with multi-threaded applications on dual-processor - or "Hyperthreading"-enabled systems (Pentium4, Xeon, etc.) - -0.5.0 added support for float radius values! - -0.4.0 tweaked gaussian curve calculation to be closer to consistent shape - across a wide range of radius values - -0.3.0 changed deviation calculation in gausian algorithm to be dynamic - _gblur now adds 1 to the user-supplied radius before using it so - that a value of "0" returns the original image instead of a - black one. - fixed handling of alpha channel in RGBX, RGBA images - improved speed of gblur by reducing unnecessary checks and assignments - -0.2.0 fixed L-mode image support - -0.1.0 initial release - -*/ - -static inline UINT8 clip(double in) -{ - if (in >= 255.0) - return (UINT8) 255; - if (in <= 0.0) - return (UINT8) 0; - return (UINT8) in; -} - -static Imaging -gblur(Imaging im, Imaging imOut, float floatRadius, int channels, int padding) -{ - ImagingSectionCookie cookie; - - float *maskData = NULL; - int y = 0; - int x = 0; - float z = 0; - float sum = 0.0; - float dev = 0.0; - - float *buffer = NULL; - - int *line = NULL; - UINT8 *line8 = NULL; - - int pix = 0; - float newPixel[4]; - int channel = 0; - int offset = 0; - INT32 newPixelFinals; - - int radius = 0; - float remainder = 0.0; - - int i; - - /* Do the gaussian blur */ - - /* For a symmetrical gaussian blur, instead of doing a radius*radius - matrix lookup, you get the EXACT same results by doing a radius*1 - transform, followed by a 1*radius transform. This reduces the - number of lookups exponentially (10 lookups per pixel for a - radius of 5 instead of 25 lookups). So, we blur the lines first, - then we blur the resulting columns. */ - - /* first, round radius off to the next higher integer and hold the - remainder this is used so we can support float radius values - properly. */ - - remainder = floatRadius - ((int) floatRadius); - floatRadius = ceil(floatRadius); - - /* Next, double the radius and offset by 2.0... that way "0" returns - the original image instead of a black one. We multiply it by 2.0 - so that it is a true "radius", not a diameter (the results match - other paint programs closer that way too). */ - radius = (int) ((floatRadius * 2.0) + 2.0); - - /* create the maskData for the gaussian curve */ - maskData = malloc(radius * sizeof(float)); - /* FIXME: error checking */ - for (x = 0; x < radius; x++) { - z = ((float) (x + 2) / ((float) radius)); - dev = 0.5 + (((float) (radius * radius)) * 0.001); - /* you can adjust this factor to change the shape/center-weighting - of the gaussian */ - maskData[x] = (float) pow((1.0 / sqrt(2.0 * 3.14159265359 * dev)), - ((-(z - 1.0) * -(x - 1.0)) / - (2.0 * dev))); - } - - /* if there's any remainder, multiply the first/last values in - MaskData it. this allows us to support float radius values. */ - if (remainder > 0.0) { - maskData[0] *= remainder; - maskData[radius - 1] *= remainder; - } - - for (x = 0; x < radius; x++) { - /* this is done separately now due to the correction for float - radius values above */ - sum += maskData[x]; - } - - for (i = 0; i < radius; i++) { - maskData[i] *= (1.0 / sum); - /* printf("%f\n", maskData[i]); */ - } - - /* create a temporary memory buffer for the data for the first pass - memset the buffer to 0 so we can use it directly with += */ - - /* don't bother about alpha/padding */ - buffer = calloc((size_t) (im->xsize * im->ysize * channels), - sizeof(float)); - if (buffer == NULL) - return ImagingError_MemoryError(); - - /* be nice to other threads while you go off to lala land */ - ImagingSectionEnter(&cookie); - - /* memset(buffer, 0, sizeof(buffer)); */ - - newPixel[0] = newPixel[1] = newPixel[2] = newPixel[3] = 0; - - /* perform a blur on each line, and place in the temporary storage buffer */ - for (y = 0; y < im->ysize; y++) { - if (channels == 1 && im->image8 != NULL) { - line8 = (UINT8 *) im->image8[y]; - } else { - line = im->image32[y]; - } - for (x = 0; x < im->xsize; x++) { - newPixel[0] = newPixel[1] = newPixel[2] = newPixel[3] = 0; - /* for each neighbor pixel, factor in its value/weighting to the - current pixel */ - for (pix = 0; pix < radius; pix++) { - /* figure the offset of this neighbor pixel */ - offset = - (int) ((-((float) radius / 2.0) + (float) pix) + 0.5); - if (x + offset < 0) - offset = -x; - else if (x + offset >= im->xsize) - offset = im->xsize - x - 1; - - /* add (neighbor pixel value * maskData[pix]) to the current - pixel value */ - if (channels == 1) { - buffer[(y * im->xsize) + x] += - ((float) ((UINT8 *) & line8[x + offset])[0]) * - (maskData[pix]); - } else { - for (channel = 0; channel < channels; channel++) { - buffer[(y * im->xsize * channels) + - (x * channels) + channel] += - ((float) ((UINT8 *) & line[x + offset]) - [channel]) * (maskData[pix]); - } - } - } - } - } - - /* perform a blur on each column in the buffer, and place in the - output image */ - for (x = 0; x < im->xsize; x++) { - for (y = 0; y < im->ysize; y++) { - newPixel[0] = newPixel[1] = newPixel[2] = newPixel[3] = 0; - /* for each neighbor pixel, factor in its value/weighting to the - current pixel */ - for (pix = 0; pix < radius; pix++) { - /* figure the offset of this neighbor pixel */ - offset = - (int) (-((float) radius / 2.0) + (float) pix + 0.5); - if (y + offset < 0) - offset = -y; - else if (y + offset >= im->ysize) - offset = im->ysize - y - 1; - /* add (neighbor pixel value * maskData[pix]) to the current - pixel value */ - for (channel = 0; channel < channels; channel++) { - newPixel[channel] += - (buffer - [((y + offset) * im->xsize * channels) + - (x * channels) + channel]) * (maskData[pix]); - } - } - /* if the image is RGBX or RGBA, copy the 4th channel data to - newPixel, so it gets put in imOut */ - if (strcmp(im->mode, "RGBX") == 0 - || strcmp(im->mode, "RGBA") == 0) { - newPixel[3] = (float) ((UINT8 *) & line[x + offset])[3]; - } - - /* pack the channels into an INT32 so we can put them back in - the PIL image */ - newPixelFinals = 0; - if (channels == 1) { - newPixelFinals = clip(newPixel[0]); - } else { - /* for RGB, the fourth channel isn't used anyways, so just - pack a 0 in there, this saves checking the mode for each - pixel. */ - /* this doesn't work on little-endian machines... fix it! */ - newPixelFinals = - clip(newPixel[0]) | clip(newPixel[1]) << 8 | - clip(newPixel[2]) << 16 | clip(newPixel[3]) << 24; - } - /* set the resulting pixel in imOut */ - if (channels == 1) { - imOut->image8[y][x] = (UINT8) newPixelFinals; - } else { - imOut->image32[y][x] = newPixelFinals; - } - } - } - - /* free the buffer */ - free(buffer); - - /* get the GIL back so Python knows who you are */ - ImagingSectionLeave(&cookie); - - return imOut; -} - -Imaging ImagingGaussianBlur(Imaging im, Imaging imOut, float radius) -{ - int channels = 0; - int padding = 0; - - if (strcmp(im->mode, "RGB") == 0) { - channels = 3; - padding = 1; - } else if (strcmp(im->mode, "RGBA") == 0) { - channels = 3; - padding = 1; - } else if (strcmp(im->mode, "RGBX") == 0) { - channels = 3; - padding = 1; - } else if (strcmp(im->mode, "CMYK") == 0) { - channels = 4; - padding = 0; - } else if (strcmp(im->mode, "L") == 0) { - channels = 1; - padding = 0; - } else - return ImagingError_ModeError(); - - return gblur(im, imOut, radius, channels, padding); -} - -Imaging -ImagingUnsharpMask(Imaging im, Imaging imOut, float radius, int percent, - int threshold) -{ - ImagingSectionCookie cookie; - - Imaging result; - int channel = 0; - int channels = 0; - int padding = 0; - - int x = 0; - int y = 0; - - int *lineIn = NULL; - int *lineOut = NULL; - UINT8 *lineIn8 = NULL; - UINT8 *lineOut8 = NULL; - - int diff = 0; - - INT32 newPixel = 0; - - if (strcmp(im->mode, "RGB") == 0) { - channels = 3; - padding = 1; - } else if (strcmp(im->mode, "RGBA") == 0) { - channels = 3; - padding = 1; - } else if (strcmp(im->mode, "RGBX") == 0) { - channels = 3; - padding = 1; - } else if (strcmp(im->mode, "CMYK") == 0) { - channels = 4; - padding = 0; - } else if (strcmp(im->mode, "L") == 0) { - channels = 1; - padding = 0; - } else - return ImagingError_ModeError(); - - /* first, do a gaussian blur on the image, putting results in imOut - temporarily */ - result = gblur(im, imOut, radius, channels, padding); - if (!result) - return NULL; - - /* now, go through each pixel, compare "normal" pixel to blurred - pixel. if the difference is more than threshold values, apply - the OPPOSITE correction to the amount of blur, multiplied by - percent. */ - - ImagingSectionEnter(&cookie); - - for (y = 0; y < im->ysize; y++) { - if (channels == 1) { - lineIn8 = im->image8[y]; - lineOut8 = imOut->image8[y]; - } else { - lineIn = im->image32[y]; - lineOut = imOut->image32[y]; - } - for (x = 0; x < im->xsize; x++) { - newPixel = 0; - /* compare in/out pixels, apply sharpening */ - if (channels == 1) { - diff = - ((UINT8 *) & lineIn8[x])[0] - - ((UINT8 *) & lineOut8[x])[0]; - if (abs(diff) > threshold) { - /* add the diff*percent to the original pixel */ - imOut->image8[y][x] = - clip((((UINT8 *) & lineIn8[x])[0]) + - (diff * ((float) percent) / 100.0)); - } else { - /* newPixel is the same as imIn */ - imOut->image8[y][x] = ((UINT8 *) & lineIn8[x])[0]; - } - } - - else { - for (channel = 0; channel < channels; channel++) { - diff = (int) ((((UINT8 *) & lineIn[x])[channel]) - - (((UINT8 *) & lineOut[x])[channel])); - if (abs(diff) > threshold) { - /* add the diff*percent to the original pixel - this may not work for little-endian systems, fix it! */ - newPixel = - newPixel | - clip((float) (((UINT8 *) & lineIn[x])[channel]) - + - (diff * - (((float) percent / - 100.0)))) << (channel * 8); - } else { - /* newPixel is the same as imIn - this may not work for little-endian systems, fix it! */ - newPixel = - newPixel | ((UINT8 *) & lineIn[x])[channel] << - (channel * 8); - } - } - if (strcmp(im->mode, "RGBX") == 0 - || strcmp(im->mode, "RGBA") == 0) { - /* preserve the alpha channel - this may not work for little-endian systems, fix it! */ - newPixel = - newPixel | ((UINT8 *) & lineIn[x])[channel] << 24; - } - imOut->image32[y][x] = newPixel; - } - } - } - - ImagingSectionLeave(&cookie); - - return imOut; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c deleted file mode 100755 index 8a203841bef..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmDecode.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for XBM hex image data - * - * history: - * 96-04-13 fl Created - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#define HEX(v) ((v >= '0' && v <= '9') ? v - '0' :\ - (v >= 'a' && v <= 'f') ? v - 'a' + 10 :\ - (v >= 'A' && v <= 'F') ? v - 'A' + 10 : 0) - -int -ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - enum { BYTE = 1, SKIP }; - - UINT8* ptr; - - if (!state->state) - state->state = SKIP; - - ptr = buf; - - for (;;) { - - if (state->state == SKIP) { - - /* Skip forward until next 'x' */ - - while (bytes > 0) { - if (*ptr == 'x') - break; - ptr++; - bytes--; - } - - if (bytes == 0) - return ptr - buf; - - state->state = BYTE; - - } - - if (bytes < 3) - return ptr - buf; - - state->buffer[state->x] = (HEX(ptr[1])<<4) + HEX(ptr[2]); - - if (++state->x >= state->bytes) { - - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y], state->buffer, - state->xsize); - - state->x = 0; - - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } - - ptr += 3; - bytes -= 3; - - state->state = SKIP; - - } - -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c deleted file mode 100755 index e066fd6b583..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/XbmEncode.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * encoder for Xbm data - * - * history: - * 96-11-01 fl created - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - - -int -ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - const char *hex = "0123456789abcdef"; - - UINT8* ptr = buf; - int i, n; - - if (!state->state) { - - /* 8 pixels are stored in no more than 6 bytes */ - state->bytes = 6*(state->xsize+7)/8; - - state->state = 1; - - } - - if (bytes < state->bytes) { - state->errcode = IMAGING_CODEC_MEMORY; - return 0; - } - - ptr = buf; - - while (bytes >= state->bytes) { - - state->shuffle(state->buffer, - (UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->xsize); - - if (state->y < state->ysize-1) { - - /* any line but the last */ - for (n = 0; n < state->xsize; n += 8) { - - i = state->buffer[n/8]; - - *ptr++ = '0'; - *ptr++ = 'x'; - *ptr++ = hex[(i>>4)&15]; - *ptr++ = hex[i&15]; - *ptr++ = ','; - bytes -= 5; - - if (++state->count >= 79/5) { - *ptr++ = '\n'; - bytes--; - state->count = 0; - } - - } - - state->y++; - - } else { - - /* last line */ - for (n = 0; n < state->xsize; n += 8) { - - i = state->buffer[n/8]; - - *ptr++ = '0'; - *ptr++ = 'x'; - *ptr++ = hex[(i>>4)&15]; - *ptr++ = hex[i&15]; - - if (n < state->xsize-8) { - *ptr++ = ','; - if (++state->count >= 79/5) { - *ptr++ = '\n'; - bytes--; - state->count = 0; - } - } else - *ptr++ = '\n'; - - bytes -= 5; - - } - - state->errcode = IMAGING_CODEC_END; - break; - } - } - - return ptr - buf; -} diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h deleted file mode 100755 index d961407e31b..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/Zip.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * declarations for the ZIP codecs - * - * Copyright (c) Fredrik Lundh 1996. - */ - - -#include "zlib.h" - - -/* modes */ -#define ZIP_PNG 0 /* continuous, filtered image data */ -#define ZIP_PNG_PALETTE 1 /* non-continuous data, disable filtering */ -#define ZIP_TIFF_PREDICTOR 2 /* TIFF, with predictor */ -#define ZIP_TIFF 3 /* TIFF, without predictor */ - - -typedef struct { - - /* CONFIGURATION */ - - /* Codec mode */ - int mode; - - /* Optimize (max compression) SLOW!!! */ - int optimize; - - /* Predefined dictionary (experimental) */ - char* dictionary; - int dictionary_size; - - /* PRIVATE CONTEXT (set by decoder/encoder) */ - - z_stream z_stream; /* (de)compression stream */ - - UINT8* previous; /* previous line (allocated) */ - - int last_output; /* # bytes last output by inflate */ - - /* Compressor specific stuff */ - UINT8* prior; /* filter storage (allocated) */ - UINT8* up; - UINT8* average; - UINT8* paeth; - - UINT8* output; /* output data */ - - int prefix; /* size of filter prefix (0 for TIFF data) */ - - int interlaced; /* is the image interlaced? (PNG) */ - - int pass; /* current pass of the interlaced image (PNG) */ - -} ZIPSTATE; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c deleted file mode 100755 index 08cdc718964..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipDecode.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * decoder for ZIP (deflated) image data. - * - * history: - * 1996-12-14 fl Created (for PNG) - * 1997-01-15 fl Prepared to read TIFF/ZIP - * 2001-11-19 fl PNG incomplete read patch (from Bernhard Herzog) - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997-2001. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#ifdef HAVE_LIBZ - -#include "Zip.h" - -static const int OFFSET[] = { 7, 3, 3, 1, 1, 0, 0 }; -static const int STARTING_COL[] = { 0, 4, 0, 2, 0, 1, 0 }; -static const int STARTING_ROW[] = { 0, 0, 4, 0, 2, 0, 1 }; -static const int COL_INCREMENT[] = { 8, 8, 4, 4, 2, 2, 1 }; -static const int ROW_INCREMENT[] = { 8, 8, 8, 4, 4, 2, 2 }; - -/* Get the length in bytes of a scanline in the pass specified, - * for interlaced images */ -static int get_row_len(ImagingCodecState state, int pass) -{ - int row_len = (state->xsize + OFFSET[pass]) / COL_INCREMENT[pass]; - return ((row_len * state->bits) + 7) / 8; -} - -/* -------------------------------------------------------------------- */ -/* Decoder */ -/* -------------------------------------------------------------------- */ - -int -ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - ZIPSTATE* context = (ZIPSTATE*) state->context; - int err; - int n; - UINT8* ptr; - int i, bpp; - int row_len; - - if (!state->state) { - - /* Initialization */ - if (context->mode == ZIP_PNG || context->mode == ZIP_PNG_PALETTE) - context->prefix = 1; /* PNG */ - - /* Expand standard buffer to make room for the (optional) filter - prefix, and allocate a buffer to hold the previous line */ - free(state->buffer); - state->buffer = (UINT8*) malloc(state->bytes+1); - context->previous = (UINT8*) malloc(state->bytes+1); - if (!state->buffer || !context->previous) { - state->errcode = IMAGING_CODEC_MEMORY; - return -1; - } - - context->last_output = 0; - - /* Initialize to black */ - memset(context->previous, 0, state->bytes+1); - - /* Setup decompression context */ - context->z_stream.zalloc = (alloc_func) NULL; - context->z_stream.zfree = (free_func) NULL; - context->z_stream.opaque = (voidpf) NULL; - - err = inflateInit(&context->z_stream); - if (err < 0) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - - if (context->interlaced) { - context->pass = 0; - state->y = STARTING_ROW[context->pass]; - } - - /* Ready to decode */ - state->state = 1; - - } - - if (context->interlaced) { - row_len = get_row_len(state, context->pass); - } else { - row_len = state->bytes; - } - - /* Setup the source buffer */ - context->z_stream.next_in = buf; - context->z_stream.avail_in = bytes; - - /* Decompress what we've got this far */ - while (context->z_stream.avail_in > 0) { - - context->z_stream.next_out = state->buffer + context->last_output; - context->z_stream.avail_out = - row_len + context->prefix - context->last_output; - - err = inflate(&context->z_stream, Z_NO_FLUSH); - - if (err < 0) { - /* Something went wrong inside the compression library */ - if (err == Z_DATA_ERROR) - state->errcode = IMAGING_CODEC_BROKEN; - else if (err == Z_MEM_ERROR) - state->errcode = IMAGING_CODEC_MEMORY; - else - state->errcode = IMAGING_CODEC_CONFIG; - free(context->previous); - inflateEnd(&context->z_stream); - return -1; - } - - n = row_len + context->prefix - context->z_stream.avail_out; - - if (n < row_len + context->prefix) { - context->last_output = n; - break; /* need more input data */ - } - - /* Apply predictor */ - switch (context->mode) { - case ZIP_PNG: - switch (state->buffer[0]) { - case 0: - break; - case 1: - /* prior */ - bpp = (state->bits + 7) / 8; - for (i = bpp+1; i <= row_len; i++) - state->buffer[i] += state->buffer[i-bpp]; - break; - case 2: - /* up */ - for (i = 1; i <= row_len; i++) - state->buffer[i] += context->previous[i]; - break; - case 3: - /* average */ - bpp = (state->bits + 7) / 8; - for (i = 1; i <= bpp; i++) - state->buffer[i] += context->previous[i]/2; - for (; i <= row_len; i++) - state->buffer[i] += - (state->buffer[i-bpp] + context->previous[i])/2; - break; - case 4: - /* paeth filtering */ - bpp = (state->bits + 7) / 8; - for (i = 1; i <= bpp; i++) - state->buffer[i] += context->previous[i]; - for (; i <= row_len; i++) { - int a, b, c; - int pa, pb, pc; - - /* fetch pixels */ - a = state->buffer[i-bpp]; - b = context->previous[i]; - c = context->previous[i-bpp]; - - /* distances to surrounding pixels */ - pa = abs(b - c); - pb = abs(a - c); - pc = abs(a + b - 2*c); - - /* pick predictor with the shortest distance */ - state->buffer[i] += - (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; - - } - break; - default: - state->errcode = IMAGING_CODEC_UNKNOWN; - free(context->previous); - inflateEnd(&context->z_stream); - return -1; - } - break; - case ZIP_TIFF_PREDICTOR: - bpp = (state->bits + 7) / 8; - for (i = bpp+1; i <= row_len; i++) - state->buffer[i] += state->buffer[i-bpp]; - break; - } - - /* Stuff data into the image */ - if (context->interlaced) { - int col = STARTING_COL[context->pass]; - if (state->bits >= 8) { - /* Stuff pixels in their correct location, one by one */ - for (i = 0; i < row_len; i += ((state->bits + 7) / 8)) { - state->shuffle((UINT8*) im->image[state->y] + - col * im->pixelsize, - state->buffer + context->prefix + i, 1); - col += COL_INCREMENT[context->pass]; - } - } else { - /* Handle case with more than a pixel in each byte */ - int row_bits = ((state->xsize + OFFSET[context->pass]) - / COL_INCREMENT[context->pass]) * state->bits; - for (i = 0; i < row_bits; i += state->bits) { - UINT8 byte = *(state->buffer + context->prefix + (i / 8)); - byte <<= (i % 8); - state->shuffle((UINT8*) im->image[state->y] + - col * im->pixelsize, &byte, 1); - col += COL_INCREMENT[context->pass]; - } - } - /* Find next valid scanline */ - state->y += ROW_INCREMENT[context->pass]; - while (state->y >= state->ysize || row_len <= 0) { - context->pass++; - if (context->pass == 7) { - /* Force exit below */ - state->y = state->ysize; - break; - } - state->y = STARTING_ROW[context->pass]; - row_len = get_row_len(state, context->pass); - /* Since we're moving to the "first" line, the previous line - * should be black to make filters work corectly */ - memset(state->buffer, 0, state->bytes+1); - } - } else { - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, - state->buffer + context->prefix, - state->xsize); - state->y++; - } - - /* all inflate output has been consumed */ - context->last_output = 0; - - if (state->y >= state->ysize || err == Z_STREAM_END) { - - /* The image and the data should end simultaneously */ - /* if (state->y < state->ysize || err != Z_STREAM_END) - state->errcode = IMAGING_CODEC_BROKEN; */ - - free(context->previous); - inflateEnd(&context->z_stream); - return -1; /* end of file (errcode=0) */ - - } - - /* Swap buffer pointers */ - ptr = state->buffer; - state->buffer = context->previous; - context->previous = ptr; - - } - - return bytes; /* consumed all of it */ - -} - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c deleted file mode 100755 index 19b2b778783..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/libImaging/ZipEncode.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * The Python Imaging Library. - * $Id$ - * - * coder for ZIP (deflated) image data - * - * History: - * 96-12-29 fl created - * 96-12-30 fl adaptive filter selection, encoder tuning - * - * Copyright (c) Fredrik Lundh 1996. - * Copyright (c) Secret Labs AB 1997. - * - * See the README file for information on usage and redistribution. - */ - - -#include "Imaging.h" - -#ifdef HAVE_LIBZ - -#include "Zip.h" - -int -ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) -{ - ZIPSTATE* context = (ZIPSTATE*) state->context; - int err; - UINT8* ptr; - int i, bpp, s, sum; - ImagingSectionCookie cookie; - - if (!state->state) { - - /* Initialization */ - - /* Valid modes are ZIP_PNG, ZIP_PNG_PALETTE, and ZIP_TIFF */ - - /* Expand standard buffer to make room for the filter selector, - and allocate filter buffers */ - free(state->buffer); - state->buffer = (UINT8*) malloc(state->bytes+1); - context->previous = (UINT8*) malloc(state->bytes+1); - context->prior = (UINT8*) malloc(state->bytes+1); - context->up = (UINT8*) malloc(state->bytes+1); - context->average = (UINT8*) malloc(state->bytes+1); - context->paeth = (UINT8*) malloc(state->bytes+1); - if (!state->buffer || !context->previous || !context->prior || - !context->up || !context->average || !context->paeth) { - free(context->paeth); - free(context->average); - free(context->up); - free(context->prior); - free(context->previous); - state->errcode = IMAGING_CODEC_MEMORY; - return -1; - } - - /* Initalise filter buffers */ - state->buffer[0] = 0; - context->prior[0] = 1; - context->up[0] = 2; - context->average[0] = 3; - context->paeth[0] = 4; - - /* Initialise previous buffer to black */ - memset(context->previous, 0, state->bytes+1); - - /* Setup compression context */ - context->z_stream.zalloc = (alloc_func)0; - context->z_stream.zfree = (free_func)0; - context->z_stream.opaque = (voidpf)0; - context->z_stream.next_in = 0; - context->z_stream.avail_in = 0; - - err = deflateInit2(&context->z_stream, - /* compression level */ - (context->optimize) ? Z_BEST_COMPRESSION - : Z_DEFAULT_COMPRESSION, - /* compression method */ - Z_DEFLATED, - /* compression memory resources */ - 15, 9, - /* compression strategy (image data are filtered)*/ - (context->mode == ZIP_PNG) ? Z_FILTERED - : Z_DEFAULT_STRATEGY); - if (err < 0) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - - if (context->dictionary && context->dictionary_size > 0) { - err = deflateSetDictionary(&context->z_stream, (unsigned char *)context->dictionary, - context->dictionary_size); - if (err < 0) { - state->errcode = IMAGING_CODEC_CONFIG; - return -1; - } - } - - /* Ready to decode */ - state->state = 1; - - } - - /* Setup the destination buffer */ - context->z_stream.next_out = buf; - context->z_stream.avail_out = bytes; - if (context->z_stream.next_in && context->z_stream.avail_in > 0) { - /* We have some data from previous round, deflate it first */ - err = deflate(&context->z_stream, Z_NO_FLUSH); - - if (err < 0) { - /* Something went wrong inside the compression library */ - if (err == Z_DATA_ERROR) - state->errcode = IMAGING_CODEC_BROKEN; - else if (err == Z_MEM_ERROR) - state->errcode = IMAGING_CODEC_MEMORY; - else - state->errcode = IMAGING_CODEC_CONFIG; - free(context->paeth); - free(context->average); - free(context->up); - free(context->prior); - free(context->previous); - deflateEnd(&context->z_stream); - return -1; - } - } - - ImagingSectionEnter(&cookie); - for (;;) { - - switch (state->state) { - - case 1: - - /* Compress image data */ - while (context->z_stream.avail_out > 0) { - - if (state->y >= state->ysize) { - /* End of image; now flush compressor buffers */ - state->state = 2; - break; - - } - - /* Stuff image data into the compressor */ - state->shuffle(state->buffer+1, - (UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, - state->xsize); - - state->y++; - - context->output = state->buffer; - - if (context->mode == ZIP_PNG) { - - /* Filter the image data. For each line, select - the filter that gives the least total distance - from zero for the filtered data (taken from - LIBPNG) */ - - bpp = (state->bits + 7) / 8; - - /* 0. No filter */ - for (i = 1, sum = 0; i <= state->bytes; i++) { - UINT8 v = state->buffer[i]; - sum += (v < 128) ? v : 256 - v; - } - - /* 2. Up. We'll test this first to save time when - an image line is identical to the one above. */ - if (sum > 0) { - for (i = 1, s = 0; i <= state->bytes; i++) { - UINT8 v = state->buffer[i] - context->previous[i]; - context->up[i] = v; - s += (v < 128) ? v : 256 - v; - } - if (s < sum) { - context->output = context->up; - sum = s; /* 0 if line was duplicated */ - } - } - - /* 1. Prior */ - if (sum > 0) { - for (i = 1, s = 0; i <= bpp; i++) { - UINT8 v = state->buffer[i]; - context->prior[i] = v; - s += (v < 128) ? v : 256 - v; - } - for (; i <= state->bytes; i++) { - UINT8 v = state->buffer[i] - state->buffer[i-bpp]; - context->prior[i] = v; - s += (v < 128) ? v : 256 - v; - } - if (s < sum) { - context->output = context->prior; - sum = s; /* 0 if line is solid */ - } - } - - /* 3. Average (not very common in real-life images, - so its only used with the optimize option) */ - if (context->optimize && sum > 0) { - for (i = 1, s = 0; i <= bpp; i++) { - UINT8 v = state->buffer[i] - context->previous[i]/2; - context->average[i] = v; - s += (v < 128) ? v : 256 - v; - } - for (; i <= state->bytes; i++) { - UINT8 v = state->buffer[i] - - (state->buffer[i-bpp] + context->previous[i])/2; - context->average[i] = v; - s += (v < 128) ? v : 256 - v; - } - if (s < sum) { - context->output = context->average; - sum = s; - } - } - - /* 4. Paeth */ - if (sum > 0) { - for (i = 1, s = 0; i <= bpp; i++) { - UINT8 v = state->buffer[i] - context->previous[i]; - context->paeth[i] = v; - s += (v < 128) ? v : 256 - v; - } - for (; i <= state->bytes; i++) { - UINT8 v; - int a, b, c; - int pa, pb, pc; - - /* fetch pixels */ - a = state->buffer[i-bpp]; - b = context->previous[i]; - c = context->previous[i-bpp]; - - /* distances to surrounding pixels */ - pa = abs(b - c); - pb = abs(a - c); - pc = abs(a + b - 2*c); - - /* pick predictor with the shortest distance */ - v = state->buffer[i] - - ((pa <= pb && pa <= pc) ? a : - (pb <= pc) ? b : c); - context->paeth[i] = v; - s += (v < 128) ? v : 256 - v; - } - if (s < sum) { - context->output = context->paeth; - sum = s; - } - } - } - - /* Compress this line */ - context->z_stream.next_in = context->output; - context->z_stream.avail_in = state->bytes+1; - - err = deflate(&context->z_stream, Z_NO_FLUSH); - - if (err < 0) { - /* Something went wrong inside the compression library */ - if (err == Z_DATA_ERROR) - state->errcode = IMAGING_CODEC_BROKEN; - else if (err == Z_MEM_ERROR) - state->errcode = IMAGING_CODEC_MEMORY; - else - state->errcode = IMAGING_CODEC_CONFIG; - free(context->paeth); - free(context->average); - free(context->up); - free(context->prior); - free(context->previous); - deflateEnd(&context->z_stream); - ImagingSectionLeave(&cookie); - return -1; - } - - /* Swap buffer pointers */ - ptr = state->buffer; - state->buffer = context->previous; - context->previous = ptr; - - } - - if (context->z_stream.avail_out == 0) - break; /* Buffer full */ - - case 2: - - /* End of image data; flush compressor buffers */ - - while (context->z_stream.avail_out > 0) { - - err = deflate(&context->z_stream, Z_FINISH); - - if (err == Z_STREAM_END) { - - free(context->paeth); - free(context->average); - free(context->up); - free(context->prior); - free(context->previous); - - deflateEnd(&context->z_stream); - - state->errcode = IMAGING_CODEC_END; - - break; - } - - if (context->z_stream.avail_out == 0) - break; /* Buffer full */ - - } - - } - ImagingSectionLeave(&cookie); - return bytes - context->z_stream.avail_out; - - } - - /* Should never ever arrive here... */ - state->errcode = IMAGING_CODEC_CONFIG; - ImagingSectionLeave(&cookie); - return -1; -} - -const char* -ImagingZipVersion(void) -{ - return ZLIB_VERSION; -} - -#endif diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/map.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/map.c deleted file mode 100755 index f15b8200f8a..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/map.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * The Python Imaging Library. - * - * standard memory mapping interface for the Imaging library - * - * history: - * 1998-03-05 fl added Win32 read mapping - * 1999-02-06 fl added "I;16" support - * 2003-04-21 fl added PyImaging_MapBuffer primitive - * - * Copyright (c) 1998-2003 by Secret Labs AB. - * Copyright (c) 2003 by Fredrik Lundh. - * - * See the README file for information on usage and redistribution. - */ - -/* - * FIXME: should move the memory mapping primitives into libImaging! - */ - -#include "Python.h" - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#include "Imaging.h" - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#undef INT32 -#undef INT64 -#undef UINT32 -#include "windows.h" -#endif - -/* compatibility wrappers (defined in _imaging.c) */ -extern int PyImaging_CheckBuffer(PyObject* buffer); -extern int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr); - -/* -------------------------------------------------------------------- */ -/* Standard mapper */ - -typedef struct { - PyObject_HEAD - char* base; - int size; - int offset; -#ifdef WIN32 - HANDLE hFile; - HANDLE hMap; -#endif -} ImagingMapperObject; - -staticforward PyTypeObject ImagingMapperType; - -ImagingMapperObject* -PyImaging_MapperNew(const char* filename, int readonly) -{ - ImagingMapperObject *mapper; - - ImagingMapperType.ob_type = &PyType_Type; - - mapper = PyObject_New(ImagingMapperObject, &ImagingMapperType); - if (mapper == NULL) - return NULL; - - mapper->base = NULL; - mapper->size = mapper->offset = 0; - -#ifdef WIN32 - mapper->hFile = (HANDLE)-1; - mapper->hMap = (HANDLE)-1; - - /* FIXME: currently supports readonly mappings only */ - mapper->hFile = CreateFile( - filename, - GENERIC_READ, - FILE_SHARE_READ, - NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (mapper->hFile == (HANDLE)-1) { - PyErr_SetString(PyExc_IOError, "cannot open file"); - PyObject_Del(mapper); - return NULL; - } - - mapper->hMap = CreateFileMapping( - mapper->hFile, NULL, - PAGE_READONLY, - 0, 0, NULL); - if (mapper->hMap == (HANDLE)-1) { - CloseHandle(mapper->hFile); - PyErr_SetString(PyExc_IOError, "cannot map file"); - PyObject_Del(mapper); - return NULL; - } - - mapper->base = (char*) MapViewOfFile( - mapper->hMap, - FILE_MAP_READ, - 0, 0, 0); - - mapper->size = GetFileSize(mapper->hFile, 0); -#endif - - return mapper; -} - -static void -mapping_dealloc(ImagingMapperObject* mapper) -{ -#ifdef WIN32 - if (mapper->base != 0) - UnmapViewOfFile(mapper->base); - if (mapper->hMap != (HANDLE)-1) - CloseHandle(mapper->hMap); - if (mapper->hFile != (HANDLE)-1) - CloseHandle(mapper->hFile); - mapper->base = 0; - mapper->hMap = mapper->hFile = (HANDLE)-1; -#endif - PyObject_Del(mapper); -} - -/* -------------------------------------------------------------------- */ -/* standard file operations */ - -static PyObject* -mapping_read(ImagingMapperObject* mapper, PyObject* args) -{ - PyObject* buf; - - int size = -1; - if (!PyArg_ParseTuple(args, "|i", &size)) - return NULL; - - /* check size */ - if (size < 0 || mapper->offset + size > mapper->size) - size = mapper->size - mapper->offset; - if (size < 0) - size = 0; - - buf = PyString_FromStringAndSize(NULL, size); - if (!buf) - return NULL; - - if (size > 0) { - memcpy(PyString_AsString(buf), mapper->base + mapper->offset, size); - mapper->offset += size; - } - - return buf; -} - -static PyObject* -mapping_seek(ImagingMapperObject* mapper, PyObject* args) -{ - int offset; - int whence = 0; - if (!PyArg_ParseTuple(args, "i|i", &offset, &whence)) - return NULL; - - switch (whence) { - case 0: /* SEEK_SET */ - mapper->offset = offset; - break; - case 1: /* SEEK_CUR */ - mapper->offset += offset; - break; - case 2: /* SEEK_END */ - mapper->offset = mapper->size + offset; - break; - default: - /* FIXME: raise ValueError? */ - break; - } - - Py_INCREF(Py_None); - return Py_None; -} - -/* -------------------------------------------------------------------- */ -/* map entire image */ - -extern PyObject*PyImagingNew(Imaging im); - -static void -ImagingDestroyMap(Imaging im) -{ - return; /* nothing to do! */ -} - -static PyObject* -mapping_readimage(ImagingMapperObject* mapper, PyObject* args) -{ - int y, size; - Imaging im; - - char* mode; - int xsize; - int ysize; - int stride; - int orientation; - if (!PyArg_ParseTuple(args, "s(ii)ii", &mode, &xsize, &ysize, - &stride, &orientation)) - return NULL; - - if (stride <= 0) { - /* FIXME: maybe we should call ImagingNewPrologue instead */ - if (!strcmp(mode, "L") || !strcmp(mode, "P")) - stride = xsize; - else if (!strcmp(mode, "I;16") || !strcmp(mode, "I;16B")) - stride = xsize * 2; - else - stride = xsize * 4; - } - - size = ysize * stride; - - if (mapper->offset + size > mapper->size) { - PyErr_SetString(PyExc_IOError, "image file truncated"); - return NULL; - } - - im = ImagingNewPrologue(mode, xsize, ysize); - if (!im) - return NULL; - - /* setup file pointers */ - if (orientation > 0) - for (y = 0; y < ysize; y++) - im->image[y] = mapper->base + mapper->offset + y * stride; - else - for (y = 0; y < ysize; y++) - im->image[ysize-y-1] = mapper->base + mapper->offset + y * stride; - - im->destroy = ImagingDestroyMap; - - if (!ImagingNewEpilogue(im)) - return NULL; - - mapper->offset += size; - - return PyImagingNew(im); -} - -static struct PyMethodDef methods[] = { - /* standard file interface */ - {"read", (PyCFunction)mapping_read, 1}, - {"seek", (PyCFunction)mapping_seek, 1}, - /* extensions */ - {"readimage", (PyCFunction)mapping_readimage, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -mapping_getattr(ImagingMapperObject* self, char* name) -{ - return Py_FindMethod(methods, (PyObject*) self, name); -} - -statichere PyTypeObject ImagingMapperType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ImagingMapper", /*tp_name*/ - sizeof(ImagingMapperObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)mapping_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)mapping_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_hash*/ -}; - -PyObject* -PyImaging_Mapper(PyObject* self, PyObject* args) -{ - char* filename; - if (!PyArg_ParseTuple(args, "s", &filename)) - return NULL; - - return (PyObject*) PyImaging_MapperNew(filename, 1); -} - -/* -------------------------------------------------------------------- */ -/* Buffer mapper */ - -typedef struct ImagingBufferInstance { - struct ImagingMemoryInstance im; - PyObject* target; -} ImagingBufferInstance; - -static void -mapping_destroy_buffer(Imaging im) -{ - ImagingBufferInstance* buffer = (ImagingBufferInstance*) im; - - Py_XDECREF(buffer->target); -} - -PyObject* -PyImaging_MapBuffer(PyObject* self, PyObject* args) -{ - int y, size; - Imaging im; - char* ptr; - int bytes; - - PyObject* target; - char* mode; - char* codec; - PyObject* bbox; - int offset; - int xsize, ysize; - int stride; - int ystep; - - if (!PyArg_ParseTuple(args, "O(ii)sOi(sii)", &target, &xsize, &ysize, - &codec, &bbox, &offset, &mode, &stride, &ystep)) - return NULL; - - if (!PyImaging_CheckBuffer(target)) { - PyErr_SetString(PyExc_TypeError, "expected string or buffer"); - return NULL; - } - - if (stride <= 0) { - if (!strcmp(mode, "L") || !strcmp(mode, "P")) - stride = xsize; - else if (!strncmp(mode, "I;16", 4)) - stride = xsize * 2; - else - stride = xsize * 4; - } - - size = ysize * stride; - - /* check buffer size */ - bytes = PyImaging_ReadBuffer(target, (const void**) &ptr); - if (bytes < 0) { - PyErr_SetString(PyExc_ValueError, "buffer has negative size"); - return NULL; - } - if (offset + size > bytes) { - PyErr_SetString(PyExc_ValueError, "buffer is not large enough"); - return NULL; - } - - im = ImagingNewPrologueSubtype( - mode, xsize, ysize, sizeof(ImagingBufferInstance) - ); - if (!im) - return NULL; - - /* setup file pointers */ - if (ystep > 0) - for (y = 0; y < ysize; y++) - im->image[y] = ptr + offset + y * stride; - else - for (y = 0; y < ysize; y++) - im->image[ysize-y-1] = ptr + offset + y * stride; - - im->destroy = mapping_destroy_buffer; - - Py_INCREF(target); - ((ImagingBufferInstance*) im)->target = target; - - if (!ImagingNewEpilogue(im)) - return NULL; - - return PyImagingNew(im); -} - diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c deleted file mode 100755 index 6bb2ebb547c..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/outline.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * THIS IS WORK IN PROGRESS. - * - * The Python Imaging Library. - * - * "arrow" outline stuff. the contents of this module - * will be merged with the path module and the rest of - * the arrow graphics package, but not before PIL 1.1. - * use at your own risk. - * - * history: - * 99-01-10 fl Added to PIL (experimental) - * - * Copyright (c) Secret Labs AB 1999. - * Copyright (c) Fredrik Lundh 1999. - * - * See the README file for information on usage and redistribution. - */ - -#include "Python.h" - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#include "Imaging.h" - - -/* -------------------------------------------------------------------- */ -/* Class */ - -typedef struct { - PyObject_HEAD - ImagingOutline outline; -} OutlineObject; - -staticforward PyTypeObject OutlineType; - -#define PyOutline_Check(op) ((op)->ob_type == &OutlineType) - -static OutlineObject* -_outline_new(void) -{ - OutlineObject *self; - - self = PyObject_New(OutlineObject, &OutlineType); - if (self == NULL) - return NULL; - - self->outline = ImagingOutlineNew(); - - return self; -} - -static void -_outline_dealloc(OutlineObject* self) -{ - ImagingOutlineDelete(self->outline); - PyObject_Del(self); -} - -ImagingOutline -PyOutline_AsOutline(PyObject* outline) -{ - if (PyOutline_Check(outline)) - return ((OutlineObject*) outline)->outline; - - return NULL; -} - - -/* -------------------------------------------------------------------- */ -/* Factories */ - -PyObject* -PyOutline_Create(PyObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":outline")) - return NULL; - - return (PyObject*) _outline_new(); -} - - -/* -------------------------------------------------------------------- */ -/* Methods */ - -static PyObject* -_outline_move(OutlineObject* self, PyObject* args) -{ - float x0, y0; - if (!PyArg_ParseTuple(args, "ff", &x0, &y0)) - return NULL; - - ImagingOutlineMove(self->outline, x0, y0); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_outline_line(OutlineObject* self, PyObject* args) -{ - float x1, y1; - if (!PyArg_ParseTuple(args, "ff", &x1, &y1)) - return NULL; - - ImagingOutlineLine(self->outline, x1, y1); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_outline_curve(OutlineObject* self, PyObject* args) -{ - float x1, y1, x2, y2, x3, y3; - if (!PyArg_ParseTuple(args, "ffffff", &x1, &y1, &x2, &y2, &x3, &y3)) - return NULL; - - ImagingOutlineCurve(self->outline, x1, y1, x2, y2, x3, y3); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_outline_close(OutlineObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":close")) - return NULL; - - ImagingOutlineClose(self->outline); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject* -_outline_transform(OutlineObject* self, PyObject* args) -{ - double a[6]; - if (!PyArg_ParseTuple(args, "(dddddd)", a+0, a+1, a+2, a+3, a+4, a+5)) - return NULL; - - ImagingOutlineTransform(self->outline, a); - - Py_INCREF(Py_None); - return Py_None; -} - -static struct PyMethodDef _outline_methods[] = { - {"line", (PyCFunction)_outline_line, 1}, - {"curve", (PyCFunction)_outline_curve, 1}, - {"move", (PyCFunction)_outline_move, 1}, - {"close", (PyCFunction)_outline_close, 1}, - {"transform", (PyCFunction)_outline_transform, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -_outline_getattr(OutlineObject* self, char* name) -{ - return Py_FindMethod(_outline_methods, (PyObject*) self, name); -} - -statichere PyTypeObject OutlineType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "Outline", /*tp_name*/ - sizeof(OutlineObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)_outline_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)_outline_getattr, /*tp_getattr*/ - 0 /*tp_setattr*/ -}; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/path.c b/tools/HitboxExpander/third_party/Imaging-1.1.7/path.c deleted file mode 100755 index f083b971d04..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/path.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * The Python Imaging Library. - * - * 2D path utilities - * - * history: - * 1996-11-04 fl Added to PIL (incomplete) - * 1996-11-05 fl Added sequence semantics - * 1997-02-28 fl Fixed getbbox - * 1997-06-12 fl Added id attribute - * 1997-06-14 fl Added slicing and setitem - * 1998-12-29 fl Improved sequence handling (from Richard Jones) - * 1999-01-10 fl Fixed IndexError test for 1.5 (from Fred Drake) - * 2000-10-12 fl Added special cases for tuples and lists - * 2002-10-27 fl Added clipping boilerplate - * 2004-09-19 fl Added tolist(flat) variant - * 2005-05-06 fl Added buffer interface support to path constructor - * - * notes: - * FIXME: fill in remaining slots in the sequence api - * - * Copyright (c) 1997-2005 by Secret Labs AB - * Copyright (c) 1997-2005 by Fredrik Lundh - * - * See the README file for information on usage and redistribution. - */ - - -#include "Python.h" - -#include - -#if PY_VERSION_HEX < 0x01060000 -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL -#endif - -#if PY_VERSION_HEX < 0x02050000 -#define Py_ssize_t int -#define lenfunc inquiry -#define ssizeargfunc intargfunc -#define ssizessizeargfunc intintargfunc -#define ssizeobjargproc intobjargproc -#define ssizessizeobjargproc intintobjargproc -#endif - -/* compatibility wrappers (defined in _imaging.c) */ -extern int PyImaging_CheckBuffer(PyObject* buffer); -extern int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr); - -/* -------------------------------------------------------------------- */ -/* Class */ -/* -------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - Py_ssize_t count; - double *xy; - int index; /* temporary use, e.g. in decimate */ -} PyPathObject; - -staticforward PyTypeObject PyPathType; - -static double* -alloc_array(int count) -{ - double* xy; - if (count < 0) { - PyErr_NoMemory(); - return NULL; - } - xy = malloc(2 * count * sizeof(double) + 1); - if (!xy) - PyErr_NoMemory(); - return xy; -} - -static PyPathObject* -path_new(Py_ssize_t count, double* xy, int duplicate) -{ - PyPathObject *path; - - if (duplicate) { - /* duplicate path */ - double* p = alloc_array(count); - if (!p) - return NULL; - memcpy(p, xy, count * 2 * sizeof(double)); - xy = p; - } - - path = PyObject_New(PyPathObject, &PyPathType); - if (path == NULL) - return NULL; - - path->count = count; - path->xy = xy; - - return path; -} - -static void -path_dealloc(PyPathObject* path) -{ - free(path->xy); - PyObject_Del(path); -} - -/* -------------------------------------------------------------------- */ -/* Helpers */ -/* -------------------------------------------------------------------- */ - -#define PyPath_Check(op) ((op)->ob_type == &PyPathType) - -int -PyPath_Flatten(PyObject* data, double **pxy) -{ - int i, j, n; - double *xy; - - if (PyPath_Check(data)) { - /* This was another path object. */ - PyPathObject *path = (PyPathObject*) data; - xy = alloc_array(path->count); - if (!xy) - return -1; - memcpy(xy, path->xy, 2 * path->count * sizeof(double)); - *pxy = xy; - return path->count; - } - - if (PyImaging_CheckBuffer(data)) { - /* Assume the buffer contains floats */ - float* ptr; - int n = PyImaging_ReadBuffer(data, (const void**) &ptr); - n /= 2 * sizeof(float); - xy = alloc_array(n); - if (!xy) - return -1; - for (i = 0; i < n+n; i++) - xy[i] = ptr[i]; - *pxy = xy; - return n; - } - - if (!PySequence_Check(data)) { - PyErr_SetString(PyExc_TypeError, "argument must be sequence"); - return -1; - } - - j = 0; - n = PyObject_Length(data); - /* Just in case __len__ breaks (or doesn't exist) */ - if (PyErr_Occurred()) - return -1; - - /* Allocate for worst case */ - xy = alloc_array(n); - if (!xy) - return -1; - - /* Copy table to path array */ - if (PyList_Check(data)) { - for (i = 0; i < n; i++) { - double x, y; - PyObject *op = PyList_GET_ITEM(data, i); - if (PyFloat_Check(op)) - xy[j++] = PyFloat_AS_DOUBLE(op); - else if (PyInt_Check(op)) - xy[j++] = (float) PyInt_AS_LONG(op); - else if (PyNumber_Check(op)) - xy[j++] = PyFloat_AsDouble(op); - else if (PyArg_ParseTuple(op, "dd", &x, &y)) { - xy[j++] = x; - xy[j++] = y; - } else { - free(xy); - return -1; - } - } - } else if (PyTuple_Check(data)) { - for (i = 0; i < n; i++) { - double x, y; - PyObject *op = PyTuple_GET_ITEM(data, i); - if (PyFloat_Check(op)) - xy[j++] = PyFloat_AS_DOUBLE(op); - else if (PyInt_Check(op)) - xy[j++] = (float) PyInt_AS_LONG(op); - else if (PyNumber_Check(op)) - xy[j++] = PyFloat_AsDouble(op); - else if (PyArg_ParseTuple(op, "dd", &x, &y)) { - xy[j++] = x; - xy[j++] = y; - } else { - free(xy); - return -1; - } - } - } else { - for (i = 0; i < n; i++) { - double x, y; - PyObject *op = PySequence_GetItem(data, i); - if (!op) { - /* treat IndexError as end of sequence */ - if (PyErr_Occurred() && - PyErr_ExceptionMatches(PyExc_IndexError)) { - PyErr_Clear(); - break; - } else { - free(xy); - return -1; - } - } - if (PyFloat_Check(op)) - xy[j++] = PyFloat_AS_DOUBLE(op); - else if (PyInt_Check(op)) - xy[j++] = (float) PyInt_AS_LONG(op); - else if (PyNumber_Check(op)) - xy[j++] = PyFloat_AsDouble(op); - else if (PyArg_ParseTuple(op, "dd", &x, &y)) { - xy[j++] = x; - xy[j++] = y; - } else { - Py_DECREF(op); - free(xy); - return -1; - } - Py_DECREF(op); - } - } - - if (j & 1) { - PyErr_SetString(PyExc_ValueError, "wrong number of coordinates"); - free(xy); - return -1; - } - - *pxy = xy; - return j/2; -} - - -/* -------------------------------------------------------------------- */ -/* Factories */ -/* -------------------------------------------------------------------- */ - -PyObject* -PyPath_Create(PyObject* self, PyObject* args) -{ - PyObject* data; - Py_ssize_t count; - double *xy; - - if (PyArg_ParseTuple(args, "i:Path", &count)) { - - /* number of vertices */ - xy = alloc_array(count); - if (!xy) - return NULL; - - } else { - - /* sequence or other path */ - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O", &data)) - return NULL; - - count = PyPath_Flatten(data, &xy); - if (count < 0) - return NULL; - } - - return (PyObject*) path_new(count, xy, 0); -} - - -/* -------------------------------------------------------------------- */ -/* Methods */ -/* -------------------------------------------------------------------- */ - -static PyObject* -path_compact(PyPathObject* self, PyObject* args) -{ - /* Simple-minded method to shorten path. A point is removed if - the city block distance to the previous point is less than the - given distance */ - int i, j; - double *xy; - - double cityblock = 2.0; - - if (!PyArg_ParseTuple(args, "|d:compact", &cityblock)) - return NULL; - - xy = self->xy; - - /* remove bogus vertices */ - for (i = j = 1; i < self->count; i++) { - if (fabs(xy[j+j-2]-xy[i+i]) + fabs(xy[j+j-1]-xy[i+i+1]) >= cityblock) { - xy[j+j] = xy[i+i]; - xy[j+j+1] = xy[i+i+1]; - j++; - } - } - - i = self->count - j; - self->count = j; - - /* shrink coordinate array */ - self->xy = realloc(self->xy, 2 * self->count * sizeof(double)); - - return Py_BuildValue("i", i); /* number of removed vertices */ -} - -static PyObject* -path_clip_polygon(PyPathObject* self, PyObject* args) -{ - /* Clip path representing a single polygon */ - PyErr_SetString(PyExc_RuntimeError, "not yet implemented"); - return NULL; -} - -static PyObject* -path_clip_polyline(PyPathObject* self, PyObject* args) -{ - /* Clip path representing a single polyline (outline) */ - PyErr_SetString(PyExc_RuntimeError, "not yet implemented"); - return NULL; -} - -static PyObject* -path_getbbox(PyPathObject* self, PyObject* args) -{ - /* Find bounding box */ - int i; - double *xy; - double x0, y0, x1, y1; - - if (!PyArg_ParseTuple(args, ":getbbox")) - return NULL; - - xy = self->xy; - - x0 = x1 = xy[0]; - y0 = y1 = xy[1]; - - for (i = 1; i < self->count; i++) { - if (xy[i+i] < x0) - x0 = xy[i+i]; - if (xy[i+i] > x1) - x1 = xy[i+i]; - if (xy[i+i+1] < y0) - y0 = xy[i+i+1]; - if (xy[i+i+1] > y1) - y1 = xy[i+i+1]; - } - - return Py_BuildValue("dddd", x0, y0, x1, y1); -} - -static PyObject* -path_getitem(PyPathObject* self, int i) -{ - if (i < 0 || i >= self->count) { - PyErr_SetString(PyExc_IndexError, "path index out of range"); - return NULL; - } - - return Py_BuildValue("dd", self->xy[i+i], self->xy[i+i+1]); -} - -static PyObject* -path_getslice(PyPathObject* self, Py_ssize_t ilow, Py_ssize_t ihigh) -{ - /* adjust arguments */ - if (ilow < 0) - ilow = 0; - else if (ilow >= self->count) - ilow = self->count; - if (ihigh < 0) - ihigh = 0; - if (ihigh < ilow) - ihigh = ilow; - else if (ihigh > self->count) - ihigh = self->count; - - return (PyObject*) path_new(ihigh - ilow, self->xy + ilow * 2, 1); -} - -static Py_ssize_t -path_len(PyPathObject* self) -{ - return self->count; -} - -static PyObject* -path_map(PyPathObject* self, PyObject* args) -{ - /* Map coordinate set through function */ - int i; - double *xy; - PyObject* function; - - if (!PyArg_ParseTuple(args, "O:map", &function)) - return NULL; - - xy = self->xy; - - /* apply function to coordinate set */ - for (i = 0; i < self->count; i++) { - double x = xy[i+i]; - double y = xy[i+i+1]; - PyObject* item = PyObject_CallFunction(function, "dd", x, y); - if (!item || !PyArg_ParseTuple(item, "dd", &x, &y)) { - Py_XDECREF(item); - return NULL; - } - xy[i+i] = x; - xy[i+i+1] = y; - Py_DECREF(item); - } - - Py_INCREF(Py_None); - return Py_None; -} - -static int -path_setitem(PyPathObject* self, int i, PyObject* op) -{ - double* xy; - - if (i < 0 || i >= self->count) { - PyErr_SetString(PyExc_IndexError, - "path assignment index out of range"); - return -1; - } - - if (op == NULL) { - PyErr_SetString(PyExc_TypeError, - "cannot delete from path"); - return -1; - } - - xy = &self->xy[i+i]; - - if (!PyArg_ParseTuple(op, "dd", &xy[0], &xy[1])) - return -1; - - return 0; -} - -static PyObject* -path_tolist(PyPathObject* self, PyObject* args) -{ - PyObject *list; - int i; - - int flat = 0; - if (!PyArg_ParseTuple(args, "|i:tolist", &flat)) - return NULL; - - if (flat) { - list = PyList_New(self->count*2); - for (i = 0; i < self->count*2; i++) { - PyObject* item; - item = PyFloat_FromDouble(self->xy[i]); - if (!item) - goto error; - PyList_SetItem(list, i, item); - } - } else { - list = PyList_New(self->count); - for (i = 0; i < self->count; i++) { - PyObject* item; - item = Py_BuildValue("dd", self->xy[i+i], self->xy[i+i+1]); - if (!item) - goto error; - PyList_SetItem(list, i, item); - } - } - - return list; - -error: - Py_DECREF(list); - return NULL; -} - -static PyObject* -path_transform(PyPathObject* self, PyObject* args) -{ - /* Apply affine transform to coordinate set */ - int i; - double *xy; - double a, b, c, d, e, f; - - double wrap = 0.0; - - if (!PyArg_ParseTuple(args, "(dddddd)|d:transform", - &a, &b, &c, &d, &e, &f, - &wrap)) - return NULL; - - xy = self->xy; - - /* transform the coordinate set */ - if (b == 0.0 && d == 0.0) - /* scaling */ - for (i = 0; i < self->count; i++) { - xy[i+i] = a*xy[i+i]+c; - xy[i+i+1] = e*xy[i+i+1]+f; - } - else - /* affine transform */ - for (i = 0; i < self->count; i++) { - double x = xy[i+i]; - double y = xy[i+i+1]; - xy[i+i] = a*x+b*y+c; - xy[i+i+1] = d*x+e*y+f; - } - - /* special treatment of geographical map data */ - if (wrap != 0.0) - for (i = 0; i < self->count; i++) - xy[i+i] = fmod(xy[i+i], wrap); - - Py_INCREF(Py_None); - return Py_None; -} - -static struct PyMethodDef methods[] = { - {"getbbox", (PyCFunction)path_getbbox, 1}, - {"tolist", (PyCFunction)path_tolist, 1}, - {"clip_polygon", (PyCFunction)path_clip_polygon, 1}, - {"clip_polyline", (PyCFunction)path_clip_polyline, 1}, - {"compact", (PyCFunction)path_compact, 1}, - {"map", (PyCFunction)path_map, 1}, - {"transform", (PyCFunction)path_transform, 1}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject* -path_getattr(PyPathObject* self, char* name) -{ - PyObject* res; - - res = Py_FindMethod(methods, (PyObject*) self, name); - if (res) - return res; - - PyErr_Clear(); - - if (strcmp(name, "id") == 0) - return Py_BuildValue("l", (long) self->xy); - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -static PySequenceMethods path_as_sequence = { - (lenfunc)path_len, /*sq_length*/ - (binaryfunc)0, /*sq_concat*/ - (ssizeargfunc)0, /*sq_repeat*/ - (ssizeargfunc)path_getitem, /*sq_item*/ - (ssizessizeargfunc)path_getslice, /*sq_slice*/ - (ssizeobjargproc)path_setitem, /*sq_ass_item*/ - (ssizessizeobjargproc)0, /*sq_ass_slice*/ -}; - -statichere PyTypeObject PyPathType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "Path", /*tp_name*/ - sizeof(PyPathObject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)path_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)path_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number */ - &path_as_sequence, /*tp_as_sequence */ - 0, /*tp_as_mapping */ - 0, /*tp_hash*/ -}; diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py deleted file mode 100755 index 22bbe433bf6..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/selftest.py +++ /dev/null @@ -1,202 +0,0 @@ -# minimal sanity check - -ROOT = "." - -import os, sys -sys.path.insert(0, ROOT) - -from PIL import Image -from PIL import ImageDraw -from PIL import ImageFilter -from PIL import ImageMath - -try: - Image.core.ping -except ImportError, v: - print "***", v - sys.exit() -except AttributeError: - pass - -def _info(im): - im.load() - return im.format, im.mode, im.size - -def testimage(): - """ - PIL lets you create in-memory images with various pixel types: - - >>> im = Image.new("1", (128, 128)) # monochrome - >>> _info(im) - (None, '1', (128, 128)) - >>> _info(Image.new("L", (128, 128))) # grayscale (luminance) - (None, 'L', (128, 128)) - >>> _info(Image.new("P", (128, 128))) # palette - (None, 'P', (128, 128)) - >>> _info(Image.new("RGB", (128, 128))) # truecolor - (None, 'RGB', (128, 128)) - >>> _info(Image.new("I", (128, 128))) # 32-bit integer - (None, 'I', (128, 128)) - >>> _info(Image.new("F", (128, 128))) # 32-bit floating point - (None, 'F', (128, 128)) - - Or open existing files: - - >>> im = Image.open(os.path.join(ROOT, "Images/lena.gif")) - >>> _info(im) - ('GIF', 'P', (128, 128)) - >>> _info(Image.open(os.path.join(ROOT, "Images/lena.ppm"))) - ('PPM', 'RGB', (128, 128)) - >>> try: - ... _info(Image.open(os.path.join(ROOT, "Images/lena.jpg"))) - ... except IOError, v: - ... print v - ('JPEG', 'RGB', (128, 128)) - - PIL doesn't actually load the image data until it's needed, - or you call the "load" method: - - >>> im = Image.open(os.path.join(ROOT, "Images/lena.ppm")) - >>> print im.im # internal image attribute - None - >>> a = im.load() - >>> type(im.im) - - - You can apply many different operations on images. Most - operations return a new image: - - >>> im = Image.open(os.path.join(ROOT, "Images/lena.ppm")) - >>> _info(im.convert("L")) - (None, 'L', (128, 128)) - >>> _info(im.copy()) - (None, 'RGB', (128, 128)) - >>> _info(im.crop((32, 32, 96, 96))) - (None, 'RGB', (64, 64)) - >>> _info(im.filter(ImageFilter.BLUR)) - (None, 'RGB', (128, 128)) - >>> im.getbands() - ('R', 'G', 'B') - >>> im.getbbox() - (0, 0, 128, 128) - >>> len(im.getdata()) - 16384 - >>> im.getextrema() - ((61, 255), (26, 234), (44, 223)) - >>> im.getpixel((0, 0)) - (223, 162, 133) - >>> len(im.getprojection()) - 2 - >>> len(im.histogram()) - 768 - >>> _info(im.point(range(256)*3)) - (None, 'RGB', (128, 128)) - >>> _info(im.resize((64, 64))) - (None, 'RGB', (64, 64)) - >>> _info(im.rotate(45)) - (None, 'RGB', (128, 128)) - >>> map(_info, im.split()) - [(None, 'L', (128, 128)), (None, 'L', (128, 128)), (None, 'L', (128, 128))] - >>> len(im.convert("1").tobitmap()) - 10456 - >>> len(im.tostring()) - 49152 - >>> _info(im.transform((512, 512), Image.AFFINE, (1,0,0,0,1,0))) - (None, 'RGB', (512, 512)) - >>> _info(im.transform((512, 512), Image.EXTENT, (32,32,96,96))) - (None, 'RGB', (512, 512)) - - The ImageDraw module lets you draw stuff in raster images: - - >>> im = Image.new("L", (128, 128), 64) - >>> d = ImageDraw.ImageDraw(im) - >>> d.line((0, 0, 128, 128), fill=128) - >>> d.line((0, 128, 128, 0), fill=128) - >>> im.getextrema() - (64, 128) - - In 1.1.4, you can specify colors in a number of ways: - - >>> xy = 0, 0, 128, 128 - >>> im = Image.new("RGB", (128, 128), 0) - >>> d = ImageDraw.ImageDraw(im) - >>> d.rectangle(xy, "#f00") - >>> im.getpixel((0, 0)) - (255, 0, 0) - >>> d.rectangle(xy, "#ff0000") - >>> im.getpixel((0, 0)) - (255, 0, 0) - >>> d.rectangle(xy, "rgb(255,0,0)") - >>> im.getpixel((0, 0)) - (255, 0, 0) - >>> d.rectangle(xy, "rgb(100%,0%,0%)") - >>> im.getpixel((0, 0)) - (255, 0, 0) - >>> d.rectangle(xy, "hsl(0, 100%, 50%)") - >>> im.getpixel((0, 0)) - (255, 0, 0) - >>> d.rectangle(xy, "red") - >>> im.getpixel((0, 0)) - (255, 0, 0) - - In 1.1.6, you can use the ImageMath module to do image - calculations. - - >>> im = ImageMath.eval("float(im + 20)", im=im.convert("L")) - >>> im.mode, im.size - ('F', (128, 128)) - - PIL can do many other things, but I'll leave that for another - day. If you're curious, check the handbook, available from: - - http://www.pythonware.com - - Cheers /F - """ - - -def check_module(feature, module): - try: - __import__("PIL." + module) - except ImportError: - print "***", feature, "support not installed" - else: - print "---", feature, "support ok" - -def check_codec(feature, codec): - if codec + "_encoder" not in dir(Image.core): - print "***", feature, "support not installed" - else: - print "---", feature, "support ok" - - -if __name__ == "__main__": - # check build sanity - - exit_status = 0 - - print "-"*68 - print "PIL", Image.VERSION, "TEST SUMMARY " - print "-"*68 - print "Python modules loaded from", os.path.dirname(Image.__file__) - print "Binary modules loaded from", os.path.dirname(Image.core.__file__) - print "-"*68 - check_module("PIL CORE", "_imaging") - check_module("TKINTER", "_imagingtk") - check_codec("JPEG", "jpeg") - check_codec("ZLIB (PNG/ZIP)", "zip") - check_module("FREETYPE2", "_imagingft") - check_module("LITTLECMS", "_imagingcms") - print "-"*68 - - # use doctest to make sure the test program behaves as documented! - import doctest, selftest - print "Running selftest:" - status = doctest.testmod(selftest) - if status[0]: - print "*** %s tests of %d failed." % status - exit_status = 1 - else: - print "--- %s tests passed." % status[1] - - sys.exit(exit_status) diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py b/tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py deleted file mode 100755 index a76954e0313..00000000000 --- a/tools/HitboxExpander/third_party/Imaging-1.1.7/setup.py +++ /dev/null @@ -1,487 +0,0 @@ -#!/usr/bin/env python -# -# Setup script for PIL 1.1.5 and later -# -# Usage: python setup.py install -# - -import glob, os, re, struct, string, sys - -# make it possible to run the setup script from another directory -try: - os.chdir(os.path.dirname(sys.argv[0])) -except OSError: - pass - -def libinclude(root): - # map root to (root/lib, root/include) - return os.path.join(root, "lib"), os.path.join(root, "include") - -# -------------------------------------------------------------------- -# Library pointers. -# -# Use None to look for the libraries in well-known library locations. -# Use a string to specify a single directory, for both the library and -# the include files. Use a tuple to specify separate directories: -# (libpath, includepath). Examples: -# -# JPEG_ROOT = "/home/libraries/jpeg-6b" -# TIFF_ROOT = "/opt/tiff/lib", "/opt/tiff/include" -# -# If you have "lib" and "include" directories under a common parent, -# you can use the "libinclude" helper: -# -# TIFF_ROOT = libinclude("/opt/tiff") - -TCL_ROOT = None -JPEG_ROOT = None -ZLIB_ROOT = libinclude(os.path.abspath("../zlib")) -TIFF_ROOT = None -FREETYPE_ROOT = None -LCMS_ROOT = None - -# FIXME: add mechanism to explicitly *disable* the use of a library - -# -------------------------------------------------------------------- -# Identification - -NAME = "PIL" -DESCRIPTION = "Python Imaging Library" -AUTHOR = "Secret Labs AB (PythonWare)", "info@pythonware.com" -HOMEPAGE = "http://www.pythonware.com/products/pil" -DOWNLOAD_URL = "http://effbot.org/downloads/%s-%s.tar.gz" # name, version - -# -------------------------------------------------------------------- -# Core library - -IMAGING = [ - "decode", "encode", "map", "display", "outline", "path", - ] - -LIBIMAGING = [ - "Access", "Antialias", "Bands", "BitDecode", "Blend", "Chops", - "Convert", "ConvertYCbCr", "Copy", "Crc32", "Crop", "Dib", "Draw", - "Effects", "EpsEncode", "File", "Fill", "Filter", "FliDecode", - "Geometry", "GetBBox", "GifDecode", "GifEncode", "HexDecode", - "Histo", "JpegDecode", "JpegEncode", "LzwDecode", "Matrix", - "ModeFilter", "MspDecode", "Negative", "Offset", "Pack", - "PackDecode", "Palette", "Paste", "Quant", "QuantHash", - "QuantHeap", "PcdDecode", "PcxDecode", "PcxEncode", "Point", - "RankFilter", "RawDecode", "RawEncode", "Storage", "SunRleDecode", - "TgaRleDecode", "Unpack", "UnpackYCC", "UnsharpMask", "XbmDecode", - "XbmEncode", "ZipDecode", "ZipEncode" - ] - -# -------------------------------------------------------------------- -# Override settings - -try: - from setup_site import * -except ImportError: - pass - -# -------------------------------------------------------------------- - -from distutils import sysconfig -from distutils.core import Extension, setup -from distutils.command.build_ext import build_ext - -try: - import _tkinter -except ImportError: - _tkinter = None - -def add_directory(path, dir, where=None): - if dir and os.path.isdir(dir) and dir not in path: - if where is None: - path.append(dir) - else: - path.insert(where, dir) - -def find_include_file(self, include): - for directory in self.compiler.include_dirs: - if os.path.isfile(os.path.join(directory, include)): - return 1 - return 0 - -def find_library_file(self, library): - return self.compiler.find_library_file(self.compiler.library_dirs, library) - -def find_version(filename): - for line in open(filename).readlines(): - m = re.search("VERSION\s*=\s*\"([^\"]+)\"", line) - if m: - return m.group(1) - return None - -VERSION = find_version("PIL/Image.py") - -class pil_build_ext(build_ext): - - def build_extensions(self): - - global TCL_ROOT - - library_dirs = [] - include_dirs = [] - - add_directory(include_dirs, "libImaging") - - # - # add platform directories - - if sys.platform == "cygwin": - # pythonX.Y.dll.a is in the /usr/lib/pythonX.Y/config directory - add_directory(library_dirs, os.path.join( - "/usr/lib", "python%s" % sys.version[:3], "config" - )) - - elif sys.platform == "darwin": - # attempt to make sure we pick freetype2 over other versions - add_directory(include_dirs, "/sw/include/freetype2") - add_directory(include_dirs, "/sw/lib/freetype2/include") - # fink installation directories - add_directory(library_dirs, "/sw/lib") - add_directory(include_dirs, "/sw/include") - # darwin ports installation directories - add_directory(library_dirs, "/opt/local/lib") - add_directory(include_dirs, "/opt/local/include") - - add_directory(library_dirs, "/usr/local/lib") - # FIXME: check /opt/stuff directories here? - - prefix = sysconfig.get_config_var("prefix") - if prefix: - add_directory(library_dirs, os.path.join(prefix, "lib")) - add_directory(include_dirs, os.path.join(prefix, "include")) - - # - # locate tkinter libraries - - if _tkinter: - TCL_VERSION = _tkinter.TCL_VERSION[:3] - - if _tkinter and not TCL_ROOT: - # we have Tkinter but the TCL_ROOT variable was not set; - # try to locate appropriate Tcl/Tk libraries - PYVERSION = sys.version[0] + sys.version[2] - TCLVERSION = TCL_VERSION[0] + TCL_VERSION[2] - roots = [ - # common installation directories, mostly for Windows - # (for Unix-style platforms, we'll check in well-known - # locations later) - os.path.join("/py" + PYVERSION, "Tcl"), - os.path.join("/python" + PYVERSION, "Tcl"), - "/Tcl", "/Tcl" + TCLVERSION, "/Tcl" + TCL_VERSION, - os.path.join(os.environ.get("ProgramFiles", ""), "Tcl"), - ] - for TCL_ROOT in roots: - TCL_ROOT = os.path.abspath(TCL_ROOT) - if os.path.isfile(os.path.join(TCL_ROOT, "include", "tk.h")): - # FIXME: use distutils logging (?) - print "--- using Tcl/Tk libraries at", TCL_ROOT - print "--- using Tcl/Tk version", TCL_VERSION - TCL_ROOT = libinclude(TCL_ROOT) - break - else: - TCL_ROOT = None - - # - # add configured kits - - for root in (TCL_ROOT, JPEG_ROOT, TCL_ROOT, TIFF_ROOT, ZLIB_ROOT, - FREETYPE_ROOT, LCMS_ROOT): - if isinstance(root, type(())): - lib_root, include_root = root - else: - lib_root = include_root = root - add_directory(library_dirs, lib_root) - add_directory(include_dirs, include_root) - - # - # add standard directories - - # look for tcl specific subdirectory (e.g debian) - if _tkinter: - tcl_dir = "/usr/include/tcl" + TCL_VERSION - if os.path.isfile(os.path.join(tcl_dir, "tk.h")): - add_directory(include_dirs, tcl_dir) - - # standard locations - add_directory(library_dirs, "/usr/local/lib") - add_directory(include_dirs, "/usr/local/include") - - add_directory(library_dirs, "/usr/lib") - add_directory(include_dirs, "/usr/include") - - # - # insert new dirs *before* default libs, to avoid conflicts - # between Python PYD stub libs and real libraries - - self.compiler.library_dirs = library_dirs + self.compiler.library_dirs - self.compiler.include_dirs = include_dirs + self.compiler.include_dirs - - # - # look for available libraries - - class feature: - zlib = jpeg = tiff = freetype = tcl = tk = lcms = None - feature = feature() - - if find_include_file(self, "zlib.h"): - if find_library_file(self, "z"): - feature.zlib = "z" - elif sys.platform == "win32" and find_library_file(self, "zdll"): - feature.zlib = "zdll" # alternative name - - if find_include_file(self, "jpeglib.h"): - if find_library_file(self, "jpeg"): - feature.jpeg = "jpeg" - elif sys.platform == "win32" and find_library_file(self, "libjpeg"): - feature.jpeg = "libjpeg" # alternative name - - if find_library_file(self, "tiff"): - feature.tiff = "tiff" - - if find_library_file(self, "freetype"): - # look for freetype2 include files - freetype_version = 0 - for dir in self.compiler.include_dirs: - if os.path.isfile(os.path.join(dir, "ft2build.h")): - freetype_version = 21 - dir = os.path.join(dir, "freetype2") - break - dir = os.path.join(dir, "freetype2") - if os.path.isfile(os.path.join(dir, "ft2build.h")): - freetype_version = 21 - break - if os.path.isdir(os.path.join(dir, "freetype")): - freetype_version = 20 - break - if freetype_version: - feature.freetype = "freetype" - feature.freetype_version = freetype_version - if dir: - add_directory(self.compiler.include_dirs, dir, 0) - - if find_include_file(self, "lcms.h"): - if find_library_file(self, "lcms"): - feature.lcms = "lcms" - - if _tkinter and find_include_file(self, "tk.h"): - # the library names may vary somewhat (e.g. tcl84 or tcl8.4) - version = TCL_VERSION[0] + TCL_VERSION[2] - if find_library_file(self, "tcl" + version): - feature.tcl = "tcl" + version - elif find_library_file(self, "tcl" + TCL_VERSION): - feature.tcl = "tcl" + TCL_VERSION - if find_library_file(self, "tk" + version): - feature.tk = "tk" + version - elif find_library_file(self, "tk" + TCL_VERSION): - feature.tk = "tk" + TCL_VERSION - - # - # core library - - files = ["_imaging.c"] - for file in IMAGING: - files.append(file + ".c") - for file in LIBIMAGING: - files.append(os.path.join("libImaging", file + ".c")) - - libs = [] - defs = [] - if feature.jpeg: - libs.append(feature.jpeg) - defs.append(("HAVE_LIBJPEG", None)) - if feature.zlib: - libs.append(feature.zlib) - defs.append(("HAVE_LIBZ", None)) - if sys.platform == "win32": - libs.extend(["kernel32", "user32", "gdi32"]) - if struct.unpack("h", "\0\1")[0] == 1: - defs.append(("WORDS_BIGENDIAN", None)) - - exts = [(Extension( - "_imaging", files, libraries=libs, define_macros=defs - ))] - - # - # additional libraries - - if feature.freetype: - defs = [] - if feature.freetype_version == 20: - defs.append(("USE_FREETYPE_2_0", None)) - exts.append(Extension( - "_imagingft", ["_imagingft.c"], libraries=["freetype"], - define_macros=defs - )) - - if os.path.isfile("_imagingtiff.c") and feature.tiff: - exts.append(Extension( - "_imagingtiff", ["_imagingtiff.c"], libraries=["tiff"] - )) - - if os.path.isfile("_imagingcms.c") and feature.lcms: - extra = [] - if sys.platform == "win32": - extra.extend(["user32", "gdi32"]) - exts.append(Extension( - "_imagingcms", ["_imagingcms.c"], libraries=["lcms"] + extra - )) - - if sys.platform == "darwin": - # locate Tcl/Tk frameworks - frameworks = [] - framework_roots = [ - "/Library/Frameworks", - "/System/Library/Frameworks" - ] - for root in framework_roots: - if (os.path.exists(os.path.join(root, "Tcl.framework")) and - os.path.exists(os.path.join(root, "Tk.framework"))): - print "--- using frameworks at", root - frameworks = ["-framework", "Tcl", "-framework", "Tk"] - dir = os.path.join(root, "Tcl.framework", "Headers") - add_directory(self.compiler.include_dirs, dir, 0) - dir = os.path.join(root, "Tk.framework", "Headers") - add_directory(self.compiler.include_dirs, dir, 1) - break - if frameworks: - exts.append(Extension( - "_imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"], - extra_compile_args=frameworks, extra_link_args=frameworks - )) - feature.tcl = feature.tk = 1 # mark as present - elif feature.tcl and feature.tk: - exts.append(Extension( - "_imagingtk", ["_imagingtk.c", "Tk/tkImaging.c"], - libraries=[feature.tcl, feature.tk] - )) - - if os.path.isfile("_imagingmath.c"): - exts.append(Extension("_imagingmath", ["_imagingmath.c"])) - - self.extensions[:] = exts - - build_ext.build_extensions(self) - - # - # sanity and security checks - - unsafe_zlib = None - - if feature.zlib: - unsafe_zlib = self.check_zlib_version(self.compiler.include_dirs) - - self.summary_report(feature, unsafe_zlib) - - def summary_report(self, feature, unsafe_zlib): - - print "-" * 68 - print "PIL", VERSION, "SETUP SUMMARY" - print "-" * 68 - print "version ", VERSION - v = string.split(sys.version, "[") - print "platform ", sys.platform, string.strip(v[0]) - for v in v[1:]: - print " ", string.strip("[" + v) - print "-" * 68 - - options = [ - (feature.tcl and feature.tk, "TKINTER"), - (feature.jpeg, "JPEG"), - (feature.zlib, "ZLIB (PNG/ZIP)"), - # (feature.tiff, "experimental TIFF G3/G4 read"), - (feature.freetype, "FREETYPE2"), - (feature.lcms, "LITTLECMS"), - ] - - all = 1 - for option in options: - if option[0]: - print "---", option[1], "support available" - else: - print "***", option[1], "support not available", - if option[1] == "TKINTER" and _tkinter: - version = _tkinter.TCL_VERSION - print "(Tcl/Tk %s libraries needed)" % version, - print - all = 0 - - if feature.zlib and unsafe_zlib: - print - print "*** Warning: zlib", unsafe_zlib, - print "may contain a security vulnerability." - print "*** Consider upgrading to zlib 1.2.3 or newer." - print "*** See: http://www.kb.cert.org/vuls/id/238678" - print " http://www.kb.cert.org/vuls/id/680620" - print " http://www.gzip.org/zlib/advisory-2002-03-11.txt" - print - - print "-" * 68 - - if not all: - print "To add a missing option, make sure you have the required" - print "library, and set the corresponding ROOT variable in the" - print "setup.py script." - print - - print "To check the build, run the selftest.py script." - - def check_zlib_version(self, include_dirs): - # look for unsafe versions of zlib - for dir in include_dirs: - zlibfile = os.path.join(dir, "zlib.h") - if os.path.isfile(zlibfile): - break - else: - return - for line in open(zlibfile).readlines(): - m = re.match('#define\s+ZLIB_VERSION\s+"([^"]*)"', line) - if not m: - continue - if m.group(1) < "1.2.3": - return m.group(1) - -# -# build! - -if __name__ == "__main__": - - try: - # add necessary to distutils (for backwards compatibility) - from distutils.dist import DistributionMetadata - DistributionMetadata.classifiers = None - DistributionMetadata.download_url = None - DistributionMetadata.platforms = None - except: - pass - - setup( - author=AUTHOR[0], author_email=AUTHOR[1], - classifiers=[ - "Development Status :: 6 - Mature", - "Topic :: Multimedia :: Graphics", - "Topic :: Multimedia :: Graphics :: Capture :: Digital Camera", - "Topic :: Multimedia :: Graphics :: Capture :: Scanners", - "Topic :: Multimedia :: Graphics :: Capture :: Screen Capture", - "Topic :: Multimedia :: Graphics :: Graphics Conversion", - "Topic :: Multimedia :: Graphics :: Viewers", - ], - cmdclass = {"build_ext": pil_build_ext}, - description=DESCRIPTION, - download_url=DOWNLOAD_URL % (NAME, VERSION), - ext_modules = [Extension("_imaging", ["_imaging.c"])], # dummy - extra_path = "PIL", - license="Python (MIT style)", - long_description=DESCRIPTION, - name=NAME, - package_dir={"": "PIL"}, - packages=[""], - platforms="Python 1.5.2 and later.", - scripts = glob.glob("Scripts/pil*.py"), - url=HOMEPAGE, - version=VERSION, - ) diff --git a/tools/HitboxExpander/third_party/zlib.zip b/tools/HitboxExpander/third_party/zlib.zip new file mode 100755 index 0000000000000000000000000000000000000000..af4a2fd4c5c572708cd852aec5e6b1bcef08169a GIT binary patch literal 141415 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⁢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

n9g-L+3>ccXOmG` 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 literal 0 HcmV?d00001 diff --git a/tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt b/tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt deleted file mode 100755 index 12c009018c3..00000000000 --- a/tools/HitboxExpander/third_party/zlib/DLL_FAQ.txt +++ /dev/null @@ -1,397 +0,0 @@ - - Frequently Asked Questions about ZLIB1.DLL - - -This document describes the design, the rationale, and the usage -of the official DLL build of zlib, named ZLIB1.DLL. If you have -general questions about zlib, you should see the file "FAQ" found -in the zlib distribution, or at the following location: - http://www.gzip.org/zlib/zlib_faq.html - - - 1. What is ZLIB1.DLL, and how can I get it? - - - ZLIB1.DLL is the official build of zlib as a DLL. - (Please remark the character '1' in the name.) - - Pointers to a precompiled ZLIB1.DLL can be found in the zlib - web site at: - http://www.zlib.net/ - - Applications that link to ZLIB1.DLL can rely on the following - specification: - - * The exported symbols are exclusively defined in the source - files "zlib.h" and "zlib.def", found in an official zlib - source distribution. - * The symbols are exported by name, not by ordinal. - * The exported names are undecorated. - * The calling convention of functions is "C" (CDECL). - * The ZLIB1.DLL binary is linked to MSVCRT.DLL. - - The archive in which ZLIB1.DLL is bundled contains compiled - test programs that must run with a valid build of ZLIB1.DLL. - It is recommended to download the prebuilt DLL from the zlib - web site, instead of building it yourself, to avoid potential - incompatibilities that could be introduced by your compiler - and build settings. If you do build the DLL yourself, please - make sure that it complies with all the above requirements, - and it runs with the precompiled test programs, bundled with - the original ZLIB1.DLL distribution. - - If, for any reason, you need to build an incompatible DLL, - please use a different file name. - - - 2. Why did you change the name of the DLL to ZLIB1.DLL? - What happened to the old ZLIB.DLL? - - - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required - compilation settings that were incompatible to those used by - a static build. The DLL settings were supposed to be enabled - by defining the macro ZLIB_DLL, before including "zlib.h". - Incorrect handling of this macro was silently accepted at - build time, resulting in two major problems: - - * ZLIB_DLL was missing from the old makefile. When building - the DLL, not all people added it to the build options. In - consequence, incompatible incarnations of ZLIB.DLL started - to circulate around the net. - - * When switching from using the static library to using the - DLL, applications had to define the ZLIB_DLL macro and - to recompile all the sources that contained calls to zlib - functions. Failure to do so resulted in creating binaries - that were unable to run with the official ZLIB.DLL build. - - The only possible solution that we could foresee was to make - a binary-incompatible change in the DLL interface, in order to - remove the dependency on the ZLIB_DLL macro, and to release - the new DLL under a different name. - - We chose the name ZLIB1.DLL, where '1' indicates the major - zlib version number. We hope that we will not have to break - the binary compatibility again, at least not as long as the - zlib-1.x series will last. - - There is still a ZLIB_DLL macro, that can trigger a more - efficient build and use of the DLL, but compatibility no - longer dependents on it. - - - 3. Can I build ZLIB.DLL from the new zlib sources, and replace - an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? - - - In principle, you can do it by assigning calling convention - keywords to the macros ZEXPORT and ZEXPORTVA. In practice, - it depends on what you mean by "an old ZLIB.DLL", because the - old DLL exists in several mutually-incompatible versions. - You have to find out first what kind of calling convention is - being used in your particular ZLIB.DLL build, and to use the - same one in the new build. If you don't know what this is all - about, you might be better off if you would just leave the old - DLL intact. - - - 4. Can I compile my application using the new zlib interface, and - link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or - earlier? - - - The official answer is "no"; the real answer depends again on - what kind of ZLIB.DLL you have. Even if you are lucky, this - course of action is unreliable. - - If you rebuild your application and you intend to use a newer - version of zlib (post- 1.1.4), it is strongly recommended to - link it to the new ZLIB1.DLL. - - - 5. Why are the zlib symbols exported by name, and not by ordinal? - - - Although exporting symbols by ordinal is a little faster, it - is risky. Any single glitch in the maintenance or use of the - DEF file that contains the ordinals can result in incompatible - builds and frustrating crashes. Simply put, the benefits of - exporting symbols by ordinal do not justify the risks. - - Technically, it should be possible to maintain ordinals in - the DEF file, and still export the symbols by name. Ordinals - exist in every DLL, and even if the dynamic linking performed - at the DLL startup is searching for names, ordinals serve as - hints, for a faster name lookup. However, if the DEF file - contains ordinals, the Microsoft linker automatically builds - an implib that will cause the executables linked to it to use - those ordinals, and not the names. It is interesting to - notice that the GNU linker for Win32 does not suffer from this - problem. - - It is possible to avoid the DEF file if the exported symbols - are accompanied by a "__declspec(dllexport)" attribute in the - source files. You can do this in zlib by predefining the - ZLIB_DLL macro. - - - 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling - convention. Why not use the STDCALL convention? - STDCALL is the standard convention in Win32, and I need it in - my Visual Basic project! - - (For readability, we use CDECL to refer to the convention - triggered by the "__cdecl" keyword, STDCALL to refer to - the convention triggered by "__stdcall", and FASTCALL to - refer to the convention triggered by "__fastcall".) - - - Most of the native Windows API functions (without varargs) use - indeed the WINAPI convention (which translates to STDCALL in - Win32), but the standard C functions use CDECL. If a user - application is intrinsically tied to the Windows API (e.g. - it calls native Windows API functions such as CreateFile()), - sometimes it makes sense to decorate its own functions with - WINAPI. But if ANSI C or POSIX portability is a goal (e.g. - it calls standard C functions such as fopen()), it is not a - sound decision to request the inclusion of , or to - use non-ANSI constructs, for the sole purpose to make the user - functions STDCALL-able. - - The functionality offered by zlib is not in the category of - "Windows functionality", but is more like "C functionality". - - Technically, STDCALL is not bad; in fact, it is slightly - faster than CDECL, and it works with variable-argument - functions, just like CDECL. It is unfortunate that, in spite - of using STDCALL in the Windows API, it is not the default - convention used by the C compilers that run under Windows. - The roots of the problem reside deep inside the unsafety of - the K&R-style function prototypes, where the argument types - are not specified; but that is another story for another day. - - The remaining fact is that CDECL is the default convention. - Even if an explicit convention is hard-coded into the function - prototypes inside C headers, problems may appear. The - necessity to expose the convention in users' callbacks is one - of these problems. - - The calling convention issues are also important when using - zlib in other programming languages. Some of them, like Ada - (GNAT) and Fortran (GNU G77), have C bindings implemented - initially on Unix, and relying on the C calling convention. - On the other hand, the pre- .NET versions of Microsoft Visual - Basic require STDCALL, while Borland Delphi prefers, although - it does not require, FASTCALL. - - In fairness to all possible uses of zlib outside the C - programming language, we choose the default "C" convention. - Anyone interested in different bindings or conventions is - encouraged to maintain specialized projects. The "contrib/" - directory from the zlib distribution already holds a couple - of foreign bindings, such as Ada, C++, and Delphi. - - - 7. I need a DLL for my Visual Basic project. What can I do? - - - Define the ZLIB_WINAPI macro before including "zlib.h", when - building both the DLL and the user application (except that - you don't need to define anything when using the DLL in Visual - Basic). The ZLIB_WINAPI macro will switch on the WINAPI - (STDCALL) convention. The name of this DLL must be different - than the official ZLIB1.DLL. - - Gilles Vollant has contributed a build named ZLIBWAPI.DLL, - with the ZLIB_WINAPI macro turned on, and with the minizip - functionality built in. For more information, please read - the notes inside "contrib/vstudio/readme.txt", found in the - zlib distribution. - - - 8. I need to use zlib in my Microsoft .NET project. What can I - do? - - - Henrik Ravn has contributed a .NET wrapper around zlib. Look - into contrib/dotzlib/, inside the zlib distribution. - - - 9. If my application uses ZLIB1.DLL, should I link it to - MSVCRT.DLL? Why? - - - It is not required, but it is recommended to link your - application to MSVCRT.DLL, if it uses ZLIB1.DLL. - - The executables (.EXE, .DLL, etc.) that are involved in the - same process and are using the C run-time library (i.e. they - are calling standard C functions), must link to the same - library. There are several libraries in the Win32 system: - CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. - Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that - depend on it should also be linked to MSVCRT.DLL. - - -10. Why are you saying that ZLIB1.DLL and my application should - be linked to the same C run-time (CRT) library? I linked my - application and my DLLs to different C libraries (e.g. my - application to a static library, and my DLLs to MSVCRT.DLL), - and everything works fine. - - - If a user library invokes only pure Win32 API (accessible via - and the related headers), its DLL build will work - in any context. But if this library invokes standard C API, - things get more complicated. - - There is a single Win32 library in a Win32 system. Every - function in this library resides in a single DLL module, that - is safe to call from anywhere. On the other hand, there are - multiple versions of the C library, and each of them has its - own separate internal state. Standalone executables and user - DLLs that call standard C functions must link to a C run-time - (CRT) library, be it static or shared (DLL). Intermixing - occurs when an executable (not necessarily standalone) and a - DLL are linked to different CRTs, and both are running in the - same process. - - Intermixing multiple CRTs is possible, as long as their - internal states are kept intact. The Microsoft Knowledge Base - articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 - "HOWTO: Link with the Correct C Run-Time (CRT) Library" - mention the potential problems raised by intermixing. - - If intermixing works for you, it's because your application - and DLLs are avoiding the corruption of each of the CRTs' - internal states, maybe by careful design, or maybe by fortune. - - Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such - as those provided by Borland, raises similar problems. - - -11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? - - - MSVCRT.DLL exists on every Windows 95 with a new service pack - installed, or with Microsoft Internet Explorer 4 or later, and - on all other Windows 4.x or later (Windows 98, Windows NT 4, - or later). It is freely distributable; if not present in the - system, it can be downloaded from Microsoft or from other - software provider for free. - - The fact that MSVCRT.DLL does not exist on a virgin Windows 95 - is not so problematic. Windows 95 is scarcely found nowadays, - Microsoft ended its support a long time ago, and many recent - applications from various vendors, including Microsoft, do not - even run on it. Furthermore, no serious user should run - Windows 95 without a proper update installed. - - -12. Why are you not linking ZLIB1.DLL to - <> ? - - - We considered and abandoned the following alternatives: - - * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or - LIBCMT.LIB) is not a good option. People are using the DLL - mainly to save disk space. If you are linking your program - to a static C library, you may as well consider linking zlib - in statically, too. - - * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because - CRTDLL.DLL is present on every Win32 installation. - Unfortunately, it has a series of problems: it does not - work properly with Microsoft's C++ libraries, it does not - provide support for 64-bit file offsets, (and so on...), - and Microsoft discontinued its support a long time ago. - - * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied - with the Microsoft .NET platform, and Visual C++ 7.0/7.1, - raises problems related to the status of ZLIB1.DLL as a - system component. According to the Microsoft Knowledge Base - article KB326922 "INFO: Redistribution of the Shared C - Runtime Component in Visual C++ .NET", MSVCR70.DLL and - MSVCR71.DLL are not supposed to function as system DLLs, - because they may clash with MSVCRT.DLL. Instead, the - application's installer is supposed to put these DLLs - (if needed) in the application's private directory. - If ZLIB1.DLL depends on a non-system runtime, it cannot - function as a redistributable system component. - - * Linking ZLIB1.DLL to non-Microsoft runtimes, such as - Borland's, or Cygwin's, raises problems related to the - reliable presence of these runtimes on Win32 systems. - It's easier to let the DLL build of zlib up to the people - who distribute these runtimes, and who may proceed as - explained in the answer to Question 14. - - -13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, - how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 - (Visual Studio .NET) or newer? - - - Due to the problems explained in the Microsoft Knowledge Base - article KB326922 (see the previous answer), the C runtime that - comes with the VC7 environment is no longer considered a - system component. That is, it should not be assumed that this - runtime exists, or may be installed in a system directory. - Since ZLIB1.DLL is supposed to be a system component, it may - not depend on a non-system component. - - In order to link ZLIB1.DLL and your application to MSVCRT.DLL - in VC7, you need the library of Visual C++ 6.0 or older. If - you don't have this library at hand, it's probably best not to - use ZLIB1.DLL. - - We are hoping that, in the future, Microsoft will provide a - way to build applications linked to a proper system runtime, - from the Visual C++ environment. Until then, you have a - couple of alternatives, such as linking zlib in statically. - If your application requires dynamic linking, you may proceed - as explained in the answer to Question 14. - - -14. I need to link my own DLL build to a CRT different than - MSVCRT.DLL. What can I do? - - - Feel free to rebuild the DLL from the zlib sources, and link - it the way you want. You should, however, clearly state that - your build is unofficial. You should give it a different file - name, and/or install it in a private directory that can be - accessed by your application only, and is not visible to the - others (i.e. it's neither in the PATH, nor in the SYSTEM or - SYSTEM32 directories). Otherwise, your build may clash with - applications that link to the official build. - - For example, in Cygwin, zlib is linked to the Cygwin runtime - CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. - - -15. May I include additional pieces of code that I find useful, - link them in ZLIB1.DLL, and export them? - - - No. A legitimate build of ZLIB1.DLL must not include code - that does not originate from the official zlib source code. - But you can make your own private DLL build, under a different - file name, as suggested in the previous answer. - - For example, zlib is a part of the VCL library, distributed - with Borland Delphi and C++ Builder. The DLL build of VCL - is a redistributable file, named VCLxx.DLL. - - -16. May I remove some functionality out of ZLIB1.DLL, by enabling - macros like NO_GZCOMPRESS or NO_GZIP at compile time? - - - No. A legitimate build of ZLIB1.DLL must provide the complete - zlib functionality, as implemented in the official zlib source - code. But you can make your own private DLL build, under a - different file name, as suggested in the previous answer. - - -17. I made my own ZLIB1.DLL build. Can I test it for compliance? - - - We prefer that you download the official DLL from the zlib - web site. If you need something peculiar from this DLL, you - can send your suggestion to the zlib mailing list. - - However, in case you do rebuild the DLL yourself, you can run - it with the test programs found in the DLL distribution. - Running these test programs is not a guarantee of compliance, - but a failure can imply a detected problem. - -** - -This document is written and maintained by -Cosmin Truta diff --git a/tools/HitboxExpander/third_party/zlib/README.txt b/tools/HitboxExpander/third_party/zlib/README.txt deleted file mode 100755 index 34a13b344e7..00000000000 --- a/tools/HitboxExpander/third_party/zlib/README.txt +++ /dev/null @@ -1,60 +0,0 @@ - -What's here -=========== - The official ZLIB1.DLL - - -Source -====== - zlib version 1.2.8 - available at http://www.gzip.org/zlib/ - - -Specification and rationale -=========================== - See the accompanying DLL_FAQ.txt - - -Usage -===== - See the accompanying USAGE.txt - - -Build info -========== - Contributed by Jan Nijtmans. - - Compiler: - i686-w64-mingw32-gcc (GCC) 4.5.3 - Library: - mingw64-i686-runtime/headers: 3.0b_svn5747-1 - Build commands: - i686-w64-mingw32-gcc -c -DASMV contrib/asm686/match.S - i686-w64-mingw32-gcc -c -DASMINF -I. -O3 contrib/inflate86/inffas86.c - make -f win32/Makefile.gcc PREFIX=i686-w64-mingw32- LOC="-mms-bitfields -DASMV -DASMINF" OBJA="inffas86.o match.o" - Finally, from VS commandline (VS2005 or higher): - lib -machine:X86 -name:zlib1.dll -def:zlib.def -out:zdll.lib - -Copyright notice -================ - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - diff --git a/tools/HitboxExpander/third_party/zlib/USAGE.txt b/tools/HitboxExpander/third_party/zlib/USAGE.txt deleted file mode 100755 index 48e594ee572..00000000000 --- a/tools/HitboxExpander/third_party/zlib/USAGE.txt +++ /dev/null @@ -1,89 +0,0 @@ - -Installing ZLIB1.DLL -==================== - Copy ZLIB1.DLL to the SYSTEM or the SYSTEM32 directory. - - -Using ZLIB1.DLL with Microsoft Visual C++ -========================================= - 1. Install the supplied header files "zlib.h" and "zconf.h" - into a directory found in the INCLUDE path list. - - 2. Install the supplied library file "zdll.lib" into a - directory found in the LIB path list. - - 3. Add "zdll.lib" to your project. - - -Using ZLIB1.DLL with gcc/MinGW -============================== - 1. Install the supplied header files "zlib.h" and "zconf.h" - into the INCLUDE directory. - - 2. Copy the supplied library file "zdll.lib" to "libzdll.a": - cp lib/zdll.lib lib/libzdll.a - - OR - - 2' Build the import library from the supplied "zlib.def": - dlltool -D zlib1.dll -d lib/zlib.def -l lib/libzdll.a - - 3. Install "libzdll.a" into the LIB directory. - - 4. Add "libzdll.a" to your project, or use the -lzdll option. - - -Using ZLIB1.DLL with gcc/Cygwin -=============================== - ZLIB1.DLL is not designed to work with Cygwin. The Cygwin - system has its own DLL build of zlib, named CYGZ.DLL. - - -Using ZLIB1.DLL with Borland C++ -================================ - 1. Install the supplied header files "zlib.h" and "zconf.h" - into a directory found in the INCLUDE path list. - - 2. Build the import library using the IMPLIB tool: - implib -a -c -f lib\zdllbor.lib zlib1.dll - - OR - - 2' Convert the supplied library file "zdll.lib" to OMF format, - using the COFF2OMF tool: - coff2omf lib\zdll.lib lib\zdllbor.lib - - 3. Install "zdllbor.lib" into a directory found in the LIB path - list. - - 4. Add "zdllbor.lib" to your project. - - Notes: - - The modules that are linked with "zdllbor.lib" must be compiled - using a 4-byte alignment (option -a): - bcc32 -a -c myprog.c - bcc32 myprog.obj zdllbor.lib - - If you wish, you may use "zlib1.lib" instead of "zdllbor.lib". - - -Rebuilding ZLIB1.DLL -==================== - Depending on your build environment, use the appropriate - makefile from the win32/ directory, found in the zlib source - distribution. - - Your custom build has to comply with the requirements stated - in DLL_FAQ.txt, including (but not limited to) the following: - - It must be built from an unaltered zlib source distribution. - - It must be linked to MSVCRT.DLL. - - The macros that compile out certain portions of the zlib - code (such as NO_GZCOMPRESS, NO_GZIP) must not be enabled. - - The ZLIB_WINAPI macro must not be enabled. - - Furthermore, it has to run successfully with the test suite - found in this package. - - It is recommended, however, to use the supplied ZLIB1.DLL, - instead of rebuilding it yourself. You should rebuild it - only if you have a special reason. - diff --git a/tools/HitboxExpander/third_party/zlib/include/zconf.h b/tools/HitboxExpander/third_party/zlib/include/zconf.h deleted file mode 100755 index 9987a775530..00000000000 --- a/tools/HitboxExpander/third_party/zlib/include/zconf.h +++ /dev/null @@ -1,511 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzvprintf z_gzvprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateGetDictionary z_inflateGetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/tools/HitboxExpander/third_party/zlib/include/zlib.h b/tools/HitboxExpander/third_party/zlib/include/zlib.h deleted file mode 100755 index 3e0c7672ac5..00000000000 --- a/tools/HitboxExpander/third_party/zlib/include/zlib.h +++ /dev/null @@ -1,1768 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.8, April 28th, 2013 - - Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.8" -#define ZLIB_VERNUM 0x1280 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 8 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). Then deflate is guaranteed to - return Z_STREAM_END. If not enough output space is provided, deflate will - not return Z_STREAM_END, and it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - producted so far. The CRC-32 is checked against the gzip trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/tools/HitboxExpander/third_party/zlib/lib/zdll.lib b/tools/HitboxExpander/third_party/zlib/lib/zdll.lib deleted file mode 100755 index 669b186cc5a5cfb531800a670b7abb32bfffae3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15256 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 diff --git a/tools/HitboxExpander/third_party/zlib/lib/zlib.def b/tools/HitboxExpander/third_party/zlib/lib/zlib.def deleted file mode 100755 index face655183a..00000000000 --- a/tools/HitboxExpander/third_party/zlib/lib/zlib.def +++ /dev/null @@ -1,86 +0,0 @@ -; zlib data compression library -EXPORTS -; basic functions - zlibVersion - deflate - deflateEnd - inflate - inflateEnd -; advanced functions - deflateSetDictionary - deflateCopy - deflateReset - deflateParams - deflateTune - deflateBound - deflatePending - deflatePrime - deflateSetHeader - inflateSetDictionary - inflateGetDictionary - inflateSync - inflateCopy - inflateReset - inflateReset2 - inflatePrime - inflateMark - inflateGetHeader - inflateBack - inflateBackEnd - zlibCompileFlags -; utility functions - compress - compress2 - compressBound - uncompress - gzopen - gzdopen - gzbuffer - gzsetparams - gzread - gzwrite - gzprintf - gzvprintf - gzputs - gzgets - gzputc - gzgetc - gzungetc - gzflush - gzseek - gzrewind - gztell - gzoffset - gzeof - gzdirect - gzclose - gzclose_r - gzclose_w - gzerror - gzclearerr -; large file functions - gzopen64 - gzseek64 - gztell64 - gzoffset64 - adler32_combine64 - crc32_combine64 -; checksum functions - adler32 - crc32 - adler32_combine - crc32_combine -; various hacks, don't look :) - deflateInit_ - deflateInit2_ - inflateInit_ - inflateInit2_ - inflateBackInit_ - gzgetc_ - zError - inflateSyncPoint - get_crc_table - inflateUndermine - inflateResetKeep - deflateResetKeep - gzopen_w diff --git a/tools/HitboxExpander/third_party/zlib/test/example_d.exe b/tools/HitboxExpander/third_party/zlib/test/example_d.exe deleted file mode 100755 index 1061952b844918126d263ef1c730546bb4a50107..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38912 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 VBe!Cl8y)|Dbm~97__rzWzXAHFG=%^F diff --git a/tools/HitboxExpander/third_party/zlib/test/minigzip_d.exe b/tools/HitboxExpander/third_party/zlib/test/minigzip_d.exe deleted file mode 100755 index e829976d93fec59cc5cc38d4f7af40a6f6b87637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35840 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 PuYUfY(X0RWTk*dDdX5d7 diff --git a/tools/HitboxExpander/third_party/zlib/zlib1.dll b/tools/HitboxExpander/third_party/zlib/zlib1.dll deleted file mode 100755 index 9ea38d5cf3e0ddbeaccc0122ce3cdb6c3741a3e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107520 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

|MhCkB4mr`;oB! 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

-# You can also use any pixel decoder supported by PIL. For more -# information on available decoders, see the section Writing Your Own File Decoder. -#

+# You can also use any pixel decoder supported by PIL. For more +# information on available decoders, see the section Writing Your Own File Decoder. +#