@ai-ecoverse/py-pillow 12.3.0-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +30 -0
- package/README.md +4 -0
- package/lib/python3.14/site-packages/PIL/AvifImagePlugin.py +295 -0
- package/lib/python3.14/site-packages/PIL/BdfFontFile.py +124 -0
- package/lib/python3.14/site-packages/PIL/BlpImagePlugin.py +498 -0
- package/lib/python3.14/site-packages/PIL/BmpImagePlugin.py +514 -0
- package/lib/python3.14/site-packages/PIL/BufrStubImagePlugin.py +72 -0
- package/lib/python3.14/site-packages/PIL/ContainerIO.py +173 -0
- package/lib/python3.14/site-packages/PIL/CurImagePlugin.py +103 -0
- package/lib/python3.14/site-packages/PIL/DcxImagePlugin.py +84 -0
- package/lib/python3.14/site-packages/PIL/DdsImagePlugin.py +632 -0
- package/lib/python3.14/site-packages/PIL/EpsImagePlugin.py +484 -0
- package/lib/python3.14/site-packages/PIL/ExifTags.py +384 -0
- package/lib/python3.14/site-packages/PIL/FitsImagePlugin.py +153 -0
- package/lib/python3.14/site-packages/PIL/FliImagePlugin.py +184 -0
- package/lib/python3.14/site-packages/PIL/FontFile.py +160 -0
- package/lib/python3.14/site-packages/PIL/FpxImagePlugin.py +262 -0
- package/lib/python3.14/site-packages/PIL/FtexImagePlugin.py +115 -0
- package/lib/python3.14/site-packages/PIL/GbrImagePlugin.py +103 -0
- package/lib/python3.14/site-packages/PIL/GdImageFile.py +104 -0
- package/lib/python3.14/site-packages/PIL/GifImagePlugin.py +1223 -0
- package/lib/python3.14/site-packages/PIL/GimpGradientFile.py +154 -0
- package/lib/python3.14/site-packages/PIL/GimpPaletteFile.py +75 -0
- package/lib/python3.14/site-packages/PIL/GribStubImagePlugin.py +72 -0
- package/lib/python3.14/site-packages/PIL/Hdf5StubImagePlugin.py +72 -0
- package/lib/python3.14/site-packages/PIL/IcnsImagePlugin.py +401 -0
- package/lib/python3.14/site-packages/PIL/IcoImagePlugin.py +396 -0
- package/lib/python3.14/site-packages/PIL/ImImagePlugin.py +390 -0
- package/lib/python3.14/site-packages/PIL/Image.py +4385 -0
- package/lib/python3.14/site-packages/PIL/ImageChops.py +311 -0
- package/lib/python3.14/site-packages/PIL/ImageCms.py +1078 -0
- package/lib/python3.14/site-packages/PIL/ImageColor.py +320 -0
- package/lib/python3.14/site-packages/PIL/ImageDraw.py +1002 -0
- package/lib/python3.14/site-packages/PIL/ImageDraw2.py +244 -0
- package/lib/python3.14/site-packages/PIL/ImageEnhance.py +113 -0
- package/lib/python3.14/site-packages/PIL/ImageFile.py +938 -0
- package/lib/python3.14/site-packages/PIL/ImageFilter.py +617 -0
- package/lib/python3.14/site-packages/PIL/ImageFont.py +1330 -0
- package/lib/python3.14/site-packages/PIL/ImageGrab.py +234 -0
- package/lib/python3.14/site-packages/PIL/ImageMath.py +314 -0
- package/lib/python3.14/site-packages/PIL/ImageMode.py +85 -0
- package/lib/python3.14/site-packages/PIL/ImageMorph.py +317 -0
- package/lib/python3.14/site-packages/PIL/ImageOps.py +749 -0
- package/lib/python3.14/site-packages/PIL/ImagePalette.py +290 -0
- package/lib/python3.14/site-packages/PIL/ImagePath.py +20 -0
- package/lib/python3.14/site-packages/PIL/ImageQt.py +219 -0
- package/lib/python3.14/site-packages/PIL/ImageSequence.py +88 -0
- package/lib/python3.14/site-packages/PIL/ImageShow.py +367 -0
- package/lib/python3.14/site-packages/PIL/ImageStat.py +167 -0
- package/lib/python3.14/site-packages/PIL/ImageText.py +509 -0
- package/lib/python3.14/site-packages/PIL/ImageTk.py +266 -0
- package/lib/python3.14/site-packages/PIL/ImageTransform.py +136 -0
- package/lib/python3.14/site-packages/PIL/ImageWin.py +247 -0
- package/lib/python3.14/site-packages/PIL/ImtImagePlugin.py +103 -0
- package/lib/python3.14/site-packages/PIL/IptcImagePlugin.py +226 -0
- package/lib/python3.14/site-packages/PIL/Jpeg2KImagePlugin.py +466 -0
- package/lib/python3.14/site-packages/PIL/JpegImagePlugin.py +889 -0
- package/lib/python3.14/site-packages/PIL/JpegPresets.py +242 -0
- package/lib/python3.14/site-packages/PIL/McIdasImagePlugin.py +78 -0
- package/lib/python3.14/site-packages/PIL/MicImagePlugin.py +103 -0
- package/lib/python3.14/site-packages/PIL/MpegImagePlugin.py +84 -0
- package/lib/python3.14/site-packages/PIL/MpoImagePlugin.py +203 -0
- package/lib/python3.14/site-packages/PIL/MspImagePlugin.py +200 -0
- package/lib/python3.14/site-packages/PIL/PSDraw.py +238 -0
- package/lib/python3.14/site-packages/PIL/PaletteFile.py +54 -0
- package/lib/python3.14/site-packages/PIL/PalmImagePlugin.py +217 -0
- package/lib/python3.14/site-packages/PIL/PcdImagePlugin.py +68 -0
- package/lib/python3.14/site-packages/PIL/PcfFontFile.py +256 -0
- package/lib/python3.14/site-packages/PIL/PcxImagePlugin.py +232 -0
- package/lib/python3.14/site-packages/PIL/PdfImagePlugin.py +315 -0
- package/lib/python3.14/site-packages/PIL/PdfParser.py +1092 -0
- package/lib/python3.14/site-packages/PIL/PixarImagePlugin.py +72 -0
- package/lib/python3.14/site-packages/PIL/PngImagePlugin.py +1578 -0
- package/lib/python3.14/site-packages/PIL/PpmImagePlugin.py +375 -0
- package/lib/python3.14/site-packages/PIL/PsdImagePlugin.py +339 -0
- package/lib/python3.14/site-packages/PIL/QoiImagePlugin.py +235 -0
- package/lib/python3.14/site-packages/PIL/SgiImagePlugin.py +231 -0
- package/lib/python3.14/site-packages/PIL/SpiderImagePlugin.py +332 -0
- package/lib/python3.14/site-packages/PIL/SunImagePlugin.py +145 -0
- package/lib/python3.14/site-packages/PIL/TarIO.py +61 -0
- package/lib/python3.14/site-packages/PIL/TgaImagePlugin.py +284 -0
- package/lib/python3.14/site-packages/PIL/TiffImagePlugin.py +2354 -0
- package/lib/python3.14/site-packages/PIL/TiffTags.py +566 -0
- package/lib/python3.14/site-packages/PIL/WalImageFile.py +129 -0
- package/lib/python3.14/site-packages/PIL/WebPImagePlugin.py +322 -0
- package/lib/python3.14/site-packages/PIL/WmfImagePlugin.py +183 -0
- package/lib/python3.14/site-packages/PIL/XVThumbImagePlugin.py +83 -0
- package/lib/python3.14/site-packages/PIL/XbmImagePlugin.py +98 -0
- package/lib/python3.14/site-packages/PIL/XpmImagePlugin.py +157 -0
- package/lib/python3.14/site-packages/PIL/__init__.py +87 -0
- package/lib/python3.14/site-packages/PIL/__main__.py +7 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/AvifImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/BdfFontFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/BlpImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/BmpImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/BufrStubImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ContainerIO.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/CurImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/DcxImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/DdsImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/EpsImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ExifTags.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/FitsImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/FliImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/FontFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/FpxImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/FtexImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/GbrImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/GdImageFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/GifImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/GimpGradientFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/GimpPaletteFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/GribStubImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/Hdf5StubImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/IcnsImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/IcoImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/Image.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageChops.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageCms.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageColor.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageDraw.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageDraw2.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageEnhance.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageFilter.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageFont.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageGrab.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageMath.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageMode.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageMorph.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageOps.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImagePalette.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImagePath.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageQt.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageSequence.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageShow.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageStat.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageText.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageTk.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageTransform.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImageWin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/ImtImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/IptcImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/Jpeg2KImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/JpegImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/JpegPresets.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/McIdasImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/MicImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/MpegImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/MpoImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/MspImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PSDraw.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PaletteFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PalmImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PcdImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PcfFontFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PcxImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PdfImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PdfParser.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PixarImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PngImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PpmImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/PsdImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/QoiImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/SgiImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/SpiderImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/SunImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/TarIO.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/TgaImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/TiffImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/TiffTags.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/WalImageFile.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/WebPImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/WmfImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/XVThumbImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/XbmImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/XpmImagePlugin.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/__init__.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/__main__.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/_binary.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/_deprecate.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/_tkinter_finder.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/_typing.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/_util.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/_version.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/features.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/__pycache__/report.cpython-314.pyc +0 -0
- package/lib/python3.14/site-packages/PIL/_avif.pyi +3 -0
- package/lib/python3.14/site-packages/PIL/_binary.py +113 -0
- package/lib/python3.14/site-packages/PIL/_deprecate.py +72 -0
- package/lib/python3.14/site-packages/PIL/_imaging.cpython-314-wasm32-wasix.so +0 -0
- package/lib/python3.14/site-packages/PIL/_imaging.pyi +31 -0
- package/lib/python3.14/site-packages/PIL/_imagingcms.pyi +143 -0
- package/lib/python3.14/site-packages/PIL/_imagingft.cpython-314-wasm32-wasix.so +0 -0
- package/lib/python3.14/site-packages/PIL/_imagingft.pyi +70 -0
- package/lib/python3.14/site-packages/PIL/_imagingmath.cpython-314-wasm32-wasix.so +0 -0
- package/lib/python3.14/site-packages/PIL/_imagingmath.pyi +3 -0
- package/lib/python3.14/site-packages/PIL/_imagingmorph.cpython-314-wasm32-wasix.so +0 -0
- package/lib/python3.14/site-packages/PIL/_imagingmorph.pyi +3 -0
- package/lib/python3.14/site-packages/PIL/_imagingtk.cpython-314-wasm32-wasix.so +0 -0
- package/lib/python3.14/site-packages/PIL/_imagingtk.pyi +3 -0
- package/lib/python3.14/site-packages/PIL/_tkinter_finder.py +20 -0
- package/lib/python3.14/site-packages/PIL/_typing.py +45 -0
- package/lib/python3.14/site-packages/PIL/_util.py +29 -0
- package/lib/python3.14/site-packages/PIL/_version.py +4 -0
- package/lib/python3.14/site-packages/PIL/_webp.pyi +3 -0
- package/lib/python3.14/site-packages/PIL/features.py +343 -0
- package/lib/python3.14/site-packages/PIL/py.typed +0 -0
- package/lib/python3.14/site-packages/PIL/report.py +5 -0
- package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/METADATA +180 -0
- package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/RECORD +117 -0
- package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/WHEEL +5 -0
- package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/licenses/LICENSE +30 -0
- package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/top_level.txt +1 -0
- package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/zip-safe +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#
|
|
2
|
+
# The Python Imaging Library.
|
|
3
|
+
# $Id$
|
|
4
|
+
#
|
|
5
|
+
# PCX file handling
|
|
6
|
+
#
|
|
7
|
+
# This format was originally used by ZSoft's popular PaintBrush
|
|
8
|
+
# program for the IBM PC. It is also supported by many MS-DOS and
|
|
9
|
+
# Windows applications, including the Windows PaintBrush program in
|
|
10
|
+
# Windows 3.
|
|
11
|
+
#
|
|
12
|
+
# history:
|
|
13
|
+
# 1995-09-01 fl Created
|
|
14
|
+
# 1996-05-20 fl Fixed RGB support
|
|
15
|
+
# 1997-01-03 fl Fixed 2-bit and 4-bit support
|
|
16
|
+
# 1999-02-03 fl Fixed 8-bit support (broken in 1.0b1)
|
|
17
|
+
# 1999-02-07 fl Added write support
|
|
18
|
+
# 2002-06-09 fl Made 2-bit and 4-bit support a bit more robust
|
|
19
|
+
# 2002-07-30 fl Seek from to current position, not beginning of file
|
|
20
|
+
# 2003-06-03 fl Extract DPI settings (info["dpi"])
|
|
21
|
+
#
|
|
22
|
+
# Copyright (c) 1997-2003 by Secret Labs AB.
|
|
23
|
+
# Copyright (c) 1995-2003 by Fredrik Lundh.
|
|
24
|
+
#
|
|
25
|
+
# See the README file for information on usage and redistribution.
|
|
26
|
+
#
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import io
|
|
30
|
+
import logging
|
|
31
|
+
from typing import IO
|
|
32
|
+
|
|
33
|
+
from . import Image, ImageFile, ImagePalette
|
|
34
|
+
from ._binary import i16le as i16
|
|
35
|
+
from ._binary import o8
|
|
36
|
+
from ._binary import o16le as o16
|
|
37
|
+
|
|
38
|
+
logger = logging.getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _accept(prefix: bytes) -> bool:
|
|
42
|
+
return len(prefix) >= 2 and prefix[0] == 10 and prefix[1] in [0, 2, 3, 5]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Image plugin for Paintbrush images.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class PcxImageFile(ImageFile.ImageFile):
|
|
50
|
+
format = "PCX"
|
|
51
|
+
format_description = "Paintbrush"
|
|
52
|
+
|
|
53
|
+
def _open(self) -> None:
|
|
54
|
+
# header
|
|
55
|
+
assert self.fp is not None
|
|
56
|
+
|
|
57
|
+
s = self.fp.read(68)
|
|
58
|
+
if not _accept(s):
|
|
59
|
+
msg = "not a PCX file"
|
|
60
|
+
raise SyntaxError(msg)
|
|
61
|
+
|
|
62
|
+
# image
|
|
63
|
+
bbox = i16(s, 4), i16(s, 6), i16(s, 8) + 1, i16(s, 10) + 1
|
|
64
|
+
if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:
|
|
65
|
+
msg = "bad PCX image size"
|
|
66
|
+
raise SyntaxError(msg)
|
|
67
|
+
logger.debug("BBox: %s %s %s %s", *bbox)
|
|
68
|
+
|
|
69
|
+
offset = self.fp.tell() + 60
|
|
70
|
+
|
|
71
|
+
# format
|
|
72
|
+
version = s[1]
|
|
73
|
+
bits = s[3]
|
|
74
|
+
planes = s[65]
|
|
75
|
+
provided_stride = i16(s, 66)
|
|
76
|
+
logger.debug(
|
|
77
|
+
"PCX version %s, bits %s, planes %s, stride %s",
|
|
78
|
+
version,
|
|
79
|
+
bits,
|
|
80
|
+
planes,
|
|
81
|
+
provided_stride,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
self.info["dpi"] = i16(s, 12), i16(s, 14)
|
|
85
|
+
|
|
86
|
+
if bits == 1 and planes == 1:
|
|
87
|
+
mode = rawmode = "1"
|
|
88
|
+
|
|
89
|
+
elif bits == 1 and planes in (2, 4):
|
|
90
|
+
mode = "P"
|
|
91
|
+
rawmode = f"P;{planes}L"
|
|
92
|
+
self.palette = ImagePalette.raw("RGB", s[16:64])
|
|
93
|
+
|
|
94
|
+
elif version == 5 and bits == 8 and planes == 1:
|
|
95
|
+
mode = rawmode = "L"
|
|
96
|
+
# FIXME: hey, this doesn't work with the incremental loader !!!
|
|
97
|
+
self.fp.seek(-769, io.SEEK_END)
|
|
98
|
+
s = self.fp.read(769)
|
|
99
|
+
if len(s) == 769 and s[0] == 12:
|
|
100
|
+
# check if the palette is linear grayscale
|
|
101
|
+
for i in range(256):
|
|
102
|
+
if s[i * 3 + 1 : i * 3 + 4] != o8(i) * 3:
|
|
103
|
+
mode = rawmode = "P"
|
|
104
|
+
break
|
|
105
|
+
if mode == "P":
|
|
106
|
+
self.palette = ImagePalette.raw("RGB", s[1:])
|
|
107
|
+
|
|
108
|
+
elif version == 5 and bits == 8 and planes == 3:
|
|
109
|
+
mode = "RGB"
|
|
110
|
+
rawmode = "RGB;L"
|
|
111
|
+
|
|
112
|
+
else:
|
|
113
|
+
msg = "unknown PCX mode"
|
|
114
|
+
raise OSError(msg)
|
|
115
|
+
|
|
116
|
+
self._mode = mode
|
|
117
|
+
self._size = bbox[2] - bbox[0], bbox[3] - bbox[1]
|
|
118
|
+
|
|
119
|
+
# Don't trust the passed in stride.
|
|
120
|
+
# Calculate the approximate position for ourselves.
|
|
121
|
+
# CVE-2020-35653
|
|
122
|
+
stride = (self._size[0] * bits + 7) // 8
|
|
123
|
+
|
|
124
|
+
# While the specification states that this must be even,
|
|
125
|
+
# not all images follow this
|
|
126
|
+
if provided_stride != stride:
|
|
127
|
+
stride += stride % 2
|
|
128
|
+
|
|
129
|
+
bbox = (0, 0) + self.size
|
|
130
|
+
logger.debug("size: %sx%s", *self.size)
|
|
131
|
+
|
|
132
|
+
self.tile = [ImageFile._Tile("pcx", bbox, offset, (rawmode, planes * stride))]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# --------------------------------------------------------------------
|
|
136
|
+
# save PCX files
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
SAVE = {
|
|
140
|
+
# mode: (version, bits, planes, raw mode)
|
|
141
|
+
"1": (2, 1, 1, "1"),
|
|
142
|
+
"L": (5, 8, 1, "L"),
|
|
143
|
+
"P": (5, 8, 1, "P"),
|
|
144
|
+
"RGB": (5, 8, 3, "RGB;L"),
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
|
149
|
+
if im.width == 0 or im.height == 0:
|
|
150
|
+
msg = "Cannot write empty image as PCX"
|
|
151
|
+
raise ValueError(msg)
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
version, bits, planes, rawmode = SAVE[im.mode]
|
|
155
|
+
except KeyError as e:
|
|
156
|
+
msg = f"Cannot save {im.mode} images as PCX"
|
|
157
|
+
raise ValueError(msg) from e
|
|
158
|
+
|
|
159
|
+
# bytes per plane
|
|
160
|
+
stride = (im.size[0] * bits + 7) // 8
|
|
161
|
+
# stride should be even
|
|
162
|
+
stride += stride % 2
|
|
163
|
+
# Stride needs to be kept in sync with the PcxEncode.c version.
|
|
164
|
+
# Ideally it should be passed in in the state, but the bytes value
|
|
165
|
+
# gets overwritten.
|
|
166
|
+
|
|
167
|
+
logger.debug(
|
|
168
|
+
"PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d",
|
|
169
|
+
im.size[0],
|
|
170
|
+
bits,
|
|
171
|
+
stride,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# under windows, we could determine the current screen size with
|
|
175
|
+
# "Image.core.display_mode()[1]", but I think that's overkill...
|
|
176
|
+
|
|
177
|
+
screen = im.size
|
|
178
|
+
|
|
179
|
+
dpi = 100, 100
|
|
180
|
+
|
|
181
|
+
# PCX header
|
|
182
|
+
fp.write(
|
|
183
|
+
o8(10)
|
|
184
|
+
+ o8(version)
|
|
185
|
+
+ o8(1)
|
|
186
|
+
+ o8(bits)
|
|
187
|
+
+ o16(0)
|
|
188
|
+
+ o16(0)
|
|
189
|
+
+ o16(im.size[0] - 1)
|
|
190
|
+
+ o16(im.size[1] - 1)
|
|
191
|
+
+ o16(dpi[0])
|
|
192
|
+
+ o16(dpi[1])
|
|
193
|
+
+ b"\0" * 24
|
|
194
|
+
+ b"\xff" * 24
|
|
195
|
+
+ b"\0"
|
|
196
|
+
+ o8(planes)
|
|
197
|
+
+ o16(stride)
|
|
198
|
+
+ o16(1)
|
|
199
|
+
+ o16(screen[0])
|
|
200
|
+
+ o16(screen[1])
|
|
201
|
+
+ b"\0" * 54
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
assert fp.tell() == 128
|
|
205
|
+
|
|
206
|
+
ImageFile._save(
|
|
207
|
+
im, fp, [ImageFile._Tile("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))]
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
if im.mode == "P":
|
|
211
|
+
# colour palette
|
|
212
|
+
fp.write(o8(12))
|
|
213
|
+
palette = im.im.getpalette("RGB", "RGB")
|
|
214
|
+
palette += b"\x00" * (768 - len(palette))
|
|
215
|
+
fp.write(palette) # 768 bytes
|
|
216
|
+
elif im.mode == "L":
|
|
217
|
+
# grayscale palette
|
|
218
|
+
fp.write(o8(12))
|
|
219
|
+
for i in range(256):
|
|
220
|
+
fp.write(o8(i) * 3)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# --------------------------------------------------------------------
|
|
224
|
+
# registry
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
Image.register_open(PcxImageFile.format, PcxImageFile, _accept)
|
|
228
|
+
Image.register_save(PcxImageFile.format, _save)
|
|
229
|
+
|
|
230
|
+
Image.register_extension(PcxImageFile.format, ".pcx")
|
|
231
|
+
|
|
232
|
+
Image.register_mime(PcxImageFile.format, "image/x-pcx")
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
#
|
|
2
|
+
# The Python Imaging Library.
|
|
3
|
+
# $Id$
|
|
4
|
+
#
|
|
5
|
+
# PDF (Acrobat) file handling
|
|
6
|
+
#
|
|
7
|
+
# History:
|
|
8
|
+
# 1996-07-16 fl Created
|
|
9
|
+
# 1997-01-18 fl Fixed header
|
|
10
|
+
# 2004-02-21 fl Fixes for 1/L/CMYK images, etc.
|
|
11
|
+
# 2004-02-24 fl Fixes for 1 and P images.
|
|
12
|
+
#
|
|
13
|
+
# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved.
|
|
14
|
+
# Copyright (c) 1996-1997 by Fredrik Lundh.
|
|
15
|
+
#
|
|
16
|
+
# See the README file for information on usage and redistribution.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Image plugin for PDF images (output only).
|
|
21
|
+
##
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import io
|
|
25
|
+
import math
|
|
26
|
+
import os
|
|
27
|
+
import time
|
|
28
|
+
from typing import IO, Any
|
|
29
|
+
|
|
30
|
+
from . import Image, ImageFile, ImageSequence, PdfParser, features
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# --------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
# object ids:
|
|
36
|
+
# 1. catalogue
|
|
37
|
+
# 2. pages
|
|
38
|
+
# 3. image
|
|
39
|
+
# 4. page
|
|
40
|
+
# 5. page contents
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
|
44
|
+
_save(im, fp, filename, save_all=True)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# (Internal) Image save plugin for the PDF format.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _write_image(
|
|
52
|
+
im: Image.Image,
|
|
53
|
+
filename: str | bytes,
|
|
54
|
+
existing_pdf: PdfParser.PdfParser,
|
|
55
|
+
image_refs: list[PdfParser.IndirectReference],
|
|
56
|
+
) -> tuple[PdfParser.IndirectReference, str]:
|
|
57
|
+
# FIXME: Should replace ASCIIHexDecode with RunLengthDecode
|
|
58
|
+
# (packbits) or LZWDecode (tiff/lzw compression). Note that
|
|
59
|
+
# PDF 1.2 also supports Flatedecode (zip compression).
|
|
60
|
+
|
|
61
|
+
params = None
|
|
62
|
+
decode = None
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Get image characteristics
|
|
66
|
+
|
|
67
|
+
width, height = im.size
|
|
68
|
+
|
|
69
|
+
dict_obj: dict[str, Any] = {"BitsPerComponent": 8}
|
|
70
|
+
if im.mode == "1":
|
|
71
|
+
if features.check("libtiff"):
|
|
72
|
+
decode_filter = "CCITTFaxDecode"
|
|
73
|
+
dict_obj["BitsPerComponent"] = 1
|
|
74
|
+
params = PdfParser.PdfArray(
|
|
75
|
+
[
|
|
76
|
+
PdfParser.PdfDict(
|
|
77
|
+
{
|
|
78
|
+
"K": -1,
|
|
79
|
+
"BlackIs1": True,
|
|
80
|
+
"Columns": width,
|
|
81
|
+
"Rows": height,
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
]
|
|
85
|
+
)
|
|
86
|
+
else:
|
|
87
|
+
decode_filter = "DCTDecode"
|
|
88
|
+
dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray")
|
|
89
|
+
procset = "ImageB" # grayscale
|
|
90
|
+
elif im.mode == "L":
|
|
91
|
+
decode_filter = "DCTDecode"
|
|
92
|
+
# params = f"<< /Predictor 15 /Columns {width-2} >>"
|
|
93
|
+
dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray")
|
|
94
|
+
procset = "ImageB" # grayscale
|
|
95
|
+
elif im.mode == "LA":
|
|
96
|
+
decode_filter = "JPXDecode"
|
|
97
|
+
# params = f"<< /Predictor 15 /Columns {width-2} >>"
|
|
98
|
+
procset = "ImageB" # grayscale
|
|
99
|
+
dict_obj["SMaskInData"] = 1
|
|
100
|
+
elif im.mode == "P":
|
|
101
|
+
decode_filter = "ASCIIHexDecode"
|
|
102
|
+
palette = im.getpalette()
|
|
103
|
+
assert palette is not None
|
|
104
|
+
dict_obj["ColorSpace"] = [
|
|
105
|
+
PdfParser.PdfName("Indexed"),
|
|
106
|
+
PdfParser.PdfName("DeviceRGB"),
|
|
107
|
+
len(palette) // 3 - 1,
|
|
108
|
+
PdfParser.PdfBinary(palette),
|
|
109
|
+
]
|
|
110
|
+
procset = "ImageI" # indexed color
|
|
111
|
+
|
|
112
|
+
if "transparency" in im.info:
|
|
113
|
+
smask = im.convert("LA").getchannel("A")
|
|
114
|
+
smask.encoderinfo = {}
|
|
115
|
+
|
|
116
|
+
image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0]
|
|
117
|
+
dict_obj["SMask"] = image_ref
|
|
118
|
+
elif im.mode == "RGB":
|
|
119
|
+
decode_filter = "DCTDecode"
|
|
120
|
+
dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceRGB")
|
|
121
|
+
procset = "ImageC" # color images
|
|
122
|
+
elif im.mode == "RGBA":
|
|
123
|
+
decode_filter = "JPXDecode"
|
|
124
|
+
procset = "ImageC" # color images
|
|
125
|
+
dict_obj["SMaskInData"] = 1
|
|
126
|
+
elif im.mode == "CMYK":
|
|
127
|
+
decode_filter = "DCTDecode"
|
|
128
|
+
dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceCMYK")
|
|
129
|
+
procset = "ImageC" # color images
|
|
130
|
+
decode = [1, 0, 1, 0, 1, 0, 1, 0]
|
|
131
|
+
else:
|
|
132
|
+
msg = f"cannot save mode {im.mode}"
|
|
133
|
+
raise ValueError(msg)
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# image
|
|
137
|
+
|
|
138
|
+
op = io.BytesIO()
|
|
139
|
+
|
|
140
|
+
if decode_filter == "ASCIIHexDecode":
|
|
141
|
+
ImageFile._save(im, op, [ImageFile._Tile("hex", (0, 0) + im.size, 0, im.mode)])
|
|
142
|
+
elif decode_filter == "CCITTFaxDecode":
|
|
143
|
+
im.save(
|
|
144
|
+
op,
|
|
145
|
+
"TIFF",
|
|
146
|
+
compression="group4",
|
|
147
|
+
# use a single strip
|
|
148
|
+
strip_size=math.ceil(width / 8) * height,
|
|
149
|
+
)
|
|
150
|
+
elif decode_filter == "DCTDecode":
|
|
151
|
+
from . import JpegImagePlugin
|
|
152
|
+
|
|
153
|
+
JpegImagePlugin._save(im, op, filename)
|
|
154
|
+
elif decode_filter == "JPXDecode":
|
|
155
|
+
from . import Jpeg2KImagePlugin
|
|
156
|
+
|
|
157
|
+
del dict_obj["BitsPerComponent"]
|
|
158
|
+
Jpeg2KImagePlugin._save(im, op, filename)
|
|
159
|
+
else:
|
|
160
|
+
msg = f"unsupported PDF filter ({decode_filter})"
|
|
161
|
+
raise ValueError(msg)
|
|
162
|
+
|
|
163
|
+
stream = op.getvalue()
|
|
164
|
+
filter: PdfParser.PdfArray | PdfParser.PdfName
|
|
165
|
+
if decode_filter == "CCITTFaxDecode":
|
|
166
|
+
stream = stream[8:]
|
|
167
|
+
filter = PdfParser.PdfArray([PdfParser.PdfName(decode_filter)])
|
|
168
|
+
else:
|
|
169
|
+
filter = PdfParser.PdfName(decode_filter)
|
|
170
|
+
|
|
171
|
+
image_ref = image_refs.pop(0)
|
|
172
|
+
existing_pdf.write_obj(
|
|
173
|
+
image_ref,
|
|
174
|
+
stream=stream,
|
|
175
|
+
Type=PdfParser.PdfName("XObject"),
|
|
176
|
+
Subtype=PdfParser.PdfName("Image"),
|
|
177
|
+
Width=width, # * 72.0 / x_resolution,
|
|
178
|
+
Height=height, # * 72.0 / y_resolution,
|
|
179
|
+
Filter=filter,
|
|
180
|
+
Decode=decode,
|
|
181
|
+
DecodeParms=params,
|
|
182
|
+
**dict_obj,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return image_ref, procset
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _save(
|
|
189
|
+
im: Image.Image, fp: IO[bytes], filename: str | bytes, save_all: bool = False
|
|
190
|
+
) -> None:
|
|
191
|
+
is_appending = im.encoderinfo.get("append", False)
|
|
192
|
+
filename_str = filename.decode() if isinstance(filename, bytes) else filename
|
|
193
|
+
if is_appending:
|
|
194
|
+
existing_pdf = PdfParser.PdfParser(f=fp, filename=filename_str, mode="r+b")
|
|
195
|
+
else:
|
|
196
|
+
existing_pdf = PdfParser.PdfParser(f=fp, filename=filename_str, mode="w+b")
|
|
197
|
+
|
|
198
|
+
dpi = im.encoderinfo.get("dpi")
|
|
199
|
+
if dpi:
|
|
200
|
+
x_resolution = dpi[0]
|
|
201
|
+
y_resolution = dpi[1]
|
|
202
|
+
else:
|
|
203
|
+
x_resolution = y_resolution = im.encoderinfo.get("resolution", 72.0)
|
|
204
|
+
|
|
205
|
+
info = {
|
|
206
|
+
"title": (
|
|
207
|
+
None if is_appending else os.path.splitext(os.path.basename(filename))[0]
|
|
208
|
+
),
|
|
209
|
+
"author": None,
|
|
210
|
+
"subject": None,
|
|
211
|
+
"keywords": None,
|
|
212
|
+
"creator": None,
|
|
213
|
+
"producer": None,
|
|
214
|
+
"creationDate": None if is_appending else time.gmtime(),
|
|
215
|
+
"modDate": None if is_appending else time.gmtime(),
|
|
216
|
+
}
|
|
217
|
+
for k, default in info.items():
|
|
218
|
+
v = im.encoderinfo.get(k) if k in im.encoderinfo else default
|
|
219
|
+
if v:
|
|
220
|
+
existing_pdf.info[k[0].upper() + k[1:]] = v
|
|
221
|
+
|
|
222
|
+
#
|
|
223
|
+
# make sure image data is available
|
|
224
|
+
im.load()
|
|
225
|
+
|
|
226
|
+
existing_pdf.start_writing()
|
|
227
|
+
existing_pdf.write_header()
|
|
228
|
+
existing_pdf.write_comment("created by Pillow PDF driver")
|
|
229
|
+
|
|
230
|
+
#
|
|
231
|
+
# pages
|
|
232
|
+
ims = [im]
|
|
233
|
+
if save_all:
|
|
234
|
+
append_images = im.encoderinfo.get("append_images", [])
|
|
235
|
+
for append_im in append_images:
|
|
236
|
+
append_im.encoderinfo = im.encoderinfo.copy()
|
|
237
|
+
ims.append(append_im)
|
|
238
|
+
number_of_pages = 0
|
|
239
|
+
image_refs = []
|
|
240
|
+
page_refs = []
|
|
241
|
+
contents_refs = []
|
|
242
|
+
for im in ims:
|
|
243
|
+
im_number_of_pages = 1
|
|
244
|
+
if save_all:
|
|
245
|
+
im_number_of_pages = getattr(im, "n_frames", 1)
|
|
246
|
+
number_of_pages += im_number_of_pages
|
|
247
|
+
for i in range(im_number_of_pages):
|
|
248
|
+
image_refs.append(existing_pdf.next_object_id(0))
|
|
249
|
+
if im.mode == "P" and "transparency" in im.info:
|
|
250
|
+
image_refs.append(existing_pdf.next_object_id(0))
|
|
251
|
+
|
|
252
|
+
page_refs.append(existing_pdf.next_object_id(0))
|
|
253
|
+
contents_refs.append(existing_pdf.next_object_id(0))
|
|
254
|
+
existing_pdf.pages.append(page_refs[-1])
|
|
255
|
+
|
|
256
|
+
#
|
|
257
|
+
# catalog and list of pages
|
|
258
|
+
existing_pdf.write_catalog()
|
|
259
|
+
|
|
260
|
+
page_number = 0
|
|
261
|
+
for im_sequence in ims:
|
|
262
|
+
im_pages: ImageSequence.Iterator | list[Image.Image] = (
|
|
263
|
+
ImageSequence.Iterator(im_sequence) if save_all else [im_sequence]
|
|
264
|
+
)
|
|
265
|
+
for im in im_pages:
|
|
266
|
+
image_ref, procset = _write_image(im, filename, existing_pdf, image_refs)
|
|
267
|
+
|
|
268
|
+
#
|
|
269
|
+
# page
|
|
270
|
+
|
|
271
|
+
existing_pdf.write_page(
|
|
272
|
+
page_refs[page_number],
|
|
273
|
+
Resources=PdfParser.PdfDict(
|
|
274
|
+
ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)],
|
|
275
|
+
XObject=PdfParser.PdfDict(image=image_ref),
|
|
276
|
+
),
|
|
277
|
+
MediaBox=[
|
|
278
|
+
0,
|
|
279
|
+
0,
|
|
280
|
+
im.width * 72.0 / x_resolution,
|
|
281
|
+
im.height * 72.0 / y_resolution,
|
|
282
|
+
],
|
|
283
|
+
Contents=contents_refs[page_number],
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
#
|
|
287
|
+
# page contents
|
|
288
|
+
|
|
289
|
+
page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % (
|
|
290
|
+
im.width * 72.0 / x_resolution,
|
|
291
|
+
im.height * 72.0 / y_resolution,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
existing_pdf.write_obj(contents_refs[page_number], stream=page_contents)
|
|
295
|
+
|
|
296
|
+
page_number += 1
|
|
297
|
+
|
|
298
|
+
#
|
|
299
|
+
# trailer
|
|
300
|
+
existing_pdf.write_xref_and_trailer()
|
|
301
|
+
if hasattr(fp, "flush"):
|
|
302
|
+
fp.flush()
|
|
303
|
+
existing_pdf.close()
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
#
|
|
307
|
+
# --------------------------------------------------------------------
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
Image.register_save("PDF", _save)
|
|
311
|
+
Image.register_save_all("PDF", _save_all)
|
|
312
|
+
|
|
313
|
+
Image.register_extension("PDF", ".pdf")
|
|
314
|
+
|
|
315
|
+
Image.register_mime("PDF", "application/pdf")
|