@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.
Files changed (217) hide show
  1. package/LICENSE +30 -0
  2. package/README.md +4 -0
  3. package/lib/python3.14/site-packages/PIL/AvifImagePlugin.py +295 -0
  4. package/lib/python3.14/site-packages/PIL/BdfFontFile.py +124 -0
  5. package/lib/python3.14/site-packages/PIL/BlpImagePlugin.py +498 -0
  6. package/lib/python3.14/site-packages/PIL/BmpImagePlugin.py +514 -0
  7. package/lib/python3.14/site-packages/PIL/BufrStubImagePlugin.py +72 -0
  8. package/lib/python3.14/site-packages/PIL/ContainerIO.py +173 -0
  9. package/lib/python3.14/site-packages/PIL/CurImagePlugin.py +103 -0
  10. package/lib/python3.14/site-packages/PIL/DcxImagePlugin.py +84 -0
  11. package/lib/python3.14/site-packages/PIL/DdsImagePlugin.py +632 -0
  12. package/lib/python3.14/site-packages/PIL/EpsImagePlugin.py +484 -0
  13. package/lib/python3.14/site-packages/PIL/ExifTags.py +384 -0
  14. package/lib/python3.14/site-packages/PIL/FitsImagePlugin.py +153 -0
  15. package/lib/python3.14/site-packages/PIL/FliImagePlugin.py +184 -0
  16. package/lib/python3.14/site-packages/PIL/FontFile.py +160 -0
  17. package/lib/python3.14/site-packages/PIL/FpxImagePlugin.py +262 -0
  18. package/lib/python3.14/site-packages/PIL/FtexImagePlugin.py +115 -0
  19. package/lib/python3.14/site-packages/PIL/GbrImagePlugin.py +103 -0
  20. package/lib/python3.14/site-packages/PIL/GdImageFile.py +104 -0
  21. package/lib/python3.14/site-packages/PIL/GifImagePlugin.py +1223 -0
  22. package/lib/python3.14/site-packages/PIL/GimpGradientFile.py +154 -0
  23. package/lib/python3.14/site-packages/PIL/GimpPaletteFile.py +75 -0
  24. package/lib/python3.14/site-packages/PIL/GribStubImagePlugin.py +72 -0
  25. package/lib/python3.14/site-packages/PIL/Hdf5StubImagePlugin.py +72 -0
  26. package/lib/python3.14/site-packages/PIL/IcnsImagePlugin.py +401 -0
  27. package/lib/python3.14/site-packages/PIL/IcoImagePlugin.py +396 -0
  28. package/lib/python3.14/site-packages/PIL/ImImagePlugin.py +390 -0
  29. package/lib/python3.14/site-packages/PIL/Image.py +4385 -0
  30. package/lib/python3.14/site-packages/PIL/ImageChops.py +311 -0
  31. package/lib/python3.14/site-packages/PIL/ImageCms.py +1078 -0
  32. package/lib/python3.14/site-packages/PIL/ImageColor.py +320 -0
  33. package/lib/python3.14/site-packages/PIL/ImageDraw.py +1002 -0
  34. package/lib/python3.14/site-packages/PIL/ImageDraw2.py +244 -0
  35. package/lib/python3.14/site-packages/PIL/ImageEnhance.py +113 -0
  36. package/lib/python3.14/site-packages/PIL/ImageFile.py +938 -0
  37. package/lib/python3.14/site-packages/PIL/ImageFilter.py +617 -0
  38. package/lib/python3.14/site-packages/PIL/ImageFont.py +1330 -0
  39. package/lib/python3.14/site-packages/PIL/ImageGrab.py +234 -0
  40. package/lib/python3.14/site-packages/PIL/ImageMath.py +314 -0
  41. package/lib/python3.14/site-packages/PIL/ImageMode.py +85 -0
  42. package/lib/python3.14/site-packages/PIL/ImageMorph.py +317 -0
  43. package/lib/python3.14/site-packages/PIL/ImageOps.py +749 -0
  44. package/lib/python3.14/site-packages/PIL/ImagePalette.py +290 -0
  45. package/lib/python3.14/site-packages/PIL/ImagePath.py +20 -0
  46. package/lib/python3.14/site-packages/PIL/ImageQt.py +219 -0
  47. package/lib/python3.14/site-packages/PIL/ImageSequence.py +88 -0
  48. package/lib/python3.14/site-packages/PIL/ImageShow.py +367 -0
  49. package/lib/python3.14/site-packages/PIL/ImageStat.py +167 -0
  50. package/lib/python3.14/site-packages/PIL/ImageText.py +509 -0
  51. package/lib/python3.14/site-packages/PIL/ImageTk.py +266 -0
  52. package/lib/python3.14/site-packages/PIL/ImageTransform.py +136 -0
  53. package/lib/python3.14/site-packages/PIL/ImageWin.py +247 -0
  54. package/lib/python3.14/site-packages/PIL/ImtImagePlugin.py +103 -0
  55. package/lib/python3.14/site-packages/PIL/IptcImagePlugin.py +226 -0
  56. package/lib/python3.14/site-packages/PIL/Jpeg2KImagePlugin.py +466 -0
  57. package/lib/python3.14/site-packages/PIL/JpegImagePlugin.py +889 -0
  58. package/lib/python3.14/site-packages/PIL/JpegPresets.py +242 -0
  59. package/lib/python3.14/site-packages/PIL/McIdasImagePlugin.py +78 -0
  60. package/lib/python3.14/site-packages/PIL/MicImagePlugin.py +103 -0
  61. package/lib/python3.14/site-packages/PIL/MpegImagePlugin.py +84 -0
  62. package/lib/python3.14/site-packages/PIL/MpoImagePlugin.py +203 -0
  63. package/lib/python3.14/site-packages/PIL/MspImagePlugin.py +200 -0
  64. package/lib/python3.14/site-packages/PIL/PSDraw.py +238 -0
  65. package/lib/python3.14/site-packages/PIL/PaletteFile.py +54 -0
  66. package/lib/python3.14/site-packages/PIL/PalmImagePlugin.py +217 -0
  67. package/lib/python3.14/site-packages/PIL/PcdImagePlugin.py +68 -0
  68. package/lib/python3.14/site-packages/PIL/PcfFontFile.py +256 -0
  69. package/lib/python3.14/site-packages/PIL/PcxImagePlugin.py +232 -0
  70. package/lib/python3.14/site-packages/PIL/PdfImagePlugin.py +315 -0
  71. package/lib/python3.14/site-packages/PIL/PdfParser.py +1092 -0
  72. package/lib/python3.14/site-packages/PIL/PixarImagePlugin.py +72 -0
  73. package/lib/python3.14/site-packages/PIL/PngImagePlugin.py +1578 -0
  74. package/lib/python3.14/site-packages/PIL/PpmImagePlugin.py +375 -0
  75. package/lib/python3.14/site-packages/PIL/PsdImagePlugin.py +339 -0
  76. package/lib/python3.14/site-packages/PIL/QoiImagePlugin.py +235 -0
  77. package/lib/python3.14/site-packages/PIL/SgiImagePlugin.py +231 -0
  78. package/lib/python3.14/site-packages/PIL/SpiderImagePlugin.py +332 -0
  79. package/lib/python3.14/site-packages/PIL/SunImagePlugin.py +145 -0
  80. package/lib/python3.14/site-packages/PIL/TarIO.py +61 -0
  81. package/lib/python3.14/site-packages/PIL/TgaImagePlugin.py +284 -0
  82. package/lib/python3.14/site-packages/PIL/TiffImagePlugin.py +2354 -0
  83. package/lib/python3.14/site-packages/PIL/TiffTags.py +566 -0
  84. package/lib/python3.14/site-packages/PIL/WalImageFile.py +129 -0
  85. package/lib/python3.14/site-packages/PIL/WebPImagePlugin.py +322 -0
  86. package/lib/python3.14/site-packages/PIL/WmfImagePlugin.py +183 -0
  87. package/lib/python3.14/site-packages/PIL/XVThumbImagePlugin.py +83 -0
  88. package/lib/python3.14/site-packages/PIL/XbmImagePlugin.py +98 -0
  89. package/lib/python3.14/site-packages/PIL/XpmImagePlugin.py +157 -0
  90. package/lib/python3.14/site-packages/PIL/__init__.py +87 -0
  91. package/lib/python3.14/site-packages/PIL/__main__.py +7 -0
  92. package/lib/python3.14/site-packages/PIL/__pycache__/AvifImagePlugin.cpython-314.pyc +0 -0
  93. package/lib/python3.14/site-packages/PIL/__pycache__/BdfFontFile.cpython-314.pyc +0 -0
  94. package/lib/python3.14/site-packages/PIL/__pycache__/BlpImagePlugin.cpython-314.pyc +0 -0
  95. package/lib/python3.14/site-packages/PIL/__pycache__/BmpImagePlugin.cpython-314.pyc +0 -0
  96. package/lib/python3.14/site-packages/PIL/__pycache__/BufrStubImagePlugin.cpython-314.pyc +0 -0
  97. package/lib/python3.14/site-packages/PIL/__pycache__/ContainerIO.cpython-314.pyc +0 -0
  98. package/lib/python3.14/site-packages/PIL/__pycache__/CurImagePlugin.cpython-314.pyc +0 -0
  99. package/lib/python3.14/site-packages/PIL/__pycache__/DcxImagePlugin.cpython-314.pyc +0 -0
  100. package/lib/python3.14/site-packages/PIL/__pycache__/DdsImagePlugin.cpython-314.pyc +0 -0
  101. package/lib/python3.14/site-packages/PIL/__pycache__/EpsImagePlugin.cpython-314.pyc +0 -0
  102. package/lib/python3.14/site-packages/PIL/__pycache__/ExifTags.cpython-314.pyc +0 -0
  103. package/lib/python3.14/site-packages/PIL/__pycache__/FitsImagePlugin.cpython-314.pyc +0 -0
  104. package/lib/python3.14/site-packages/PIL/__pycache__/FliImagePlugin.cpython-314.pyc +0 -0
  105. package/lib/python3.14/site-packages/PIL/__pycache__/FontFile.cpython-314.pyc +0 -0
  106. package/lib/python3.14/site-packages/PIL/__pycache__/FpxImagePlugin.cpython-314.pyc +0 -0
  107. package/lib/python3.14/site-packages/PIL/__pycache__/FtexImagePlugin.cpython-314.pyc +0 -0
  108. package/lib/python3.14/site-packages/PIL/__pycache__/GbrImagePlugin.cpython-314.pyc +0 -0
  109. package/lib/python3.14/site-packages/PIL/__pycache__/GdImageFile.cpython-314.pyc +0 -0
  110. package/lib/python3.14/site-packages/PIL/__pycache__/GifImagePlugin.cpython-314.pyc +0 -0
  111. package/lib/python3.14/site-packages/PIL/__pycache__/GimpGradientFile.cpython-314.pyc +0 -0
  112. package/lib/python3.14/site-packages/PIL/__pycache__/GimpPaletteFile.cpython-314.pyc +0 -0
  113. package/lib/python3.14/site-packages/PIL/__pycache__/GribStubImagePlugin.cpython-314.pyc +0 -0
  114. package/lib/python3.14/site-packages/PIL/__pycache__/Hdf5StubImagePlugin.cpython-314.pyc +0 -0
  115. package/lib/python3.14/site-packages/PIL/__pycache__/IcnsImagePlugin.cpython-314.pyc +0 -0
  116. package/lib/python3.14/site-packages/PIL/__pycache__/IcoImagePlugin.cpython-314.pyc +0 -0
  117. package/lib/python3.14/site-packages/PIL/__pycache__/ImImagePlugin.cpython-314.pyc +0 -0
  118. package/lib/python3.14/site-packages/PIL/__pycache__/Image.cpython-314.pyc +0 -0
  119. package/lib/python3.14/site-packages/PIL/__pycache__/ImageChops.cpython-314.pyc +0 -0
  120. package/lib/python3.14/site-packages/PIL/__pycache__/ImageCms.cpython-314.pyc +0 -0
  121. package/lib/python3.14/site-packages/PIL/__pycache__/ImageColor.cpython-314.pyc +0 -0
  122. package/lib/python3.14/site-packages/PIL/__pycache__/ImageDraw.cpython-314.pyc +0 -0
  123. package/lib/python3.14/site-packages/PIL/__pycache__/ImageDraw2.cpython-314.pyc +0 -0
  124. package/lib/python3.14/site-packages/PIL/__pycache__/ImageEnhance.cpython-314.pyc +0 -0
  125. package/lib/python3.14/site-packages/PIL/__pycache__/ImageFile.cpython-314.pyc +0 -0
  126. package/lib/python3.14/site-packages/PIL/__pycache__/ImageFilter.cpython-314.pyc +0 -0
  127. package/lib/python3.14/site-packages/PIL/__pycache__/ImageFont.cpython-314.pyc +0 -0
  128. package/lib/python3.14/site-packages/PIL/__pycache__/ImageGrab.cpython-314.pyc +0 -0
  129. package/lib/python3.14/site-packages/PIL/__pycache__/ImageMath.cpython-314.pyc +0 -0
  130. package/lib/python3.14/site-packages/PIL/__pycache__/ImageMode.cpython-314.pyc +0 -0
  131. package/lib/python3.14/site-packages/PIL/__pycache__/ImageMorph.cpython-314.pyc +0 -0
  132. package/lib/python3.14/site-packages/PIL/__pycache__/ImageOps.cpython-314.pyc +0 -0
  133. package/lib/python3.14/site-packages/PIL/__pycache__/ImagePalette.cpython-314.pyc +0 -0
  134. package/lib/python3.14/site-packages/PIL/__pycache__/ImagePath.cpython-314.pyc +0 -0
  135. package/lib/python3.14/site-packages/PIL/__pycache__/ImageQt.cpython-314.pyc +0 -0
  136. package/lib/python3.14/site-packages/PIL/__pycache__/ImageSequence.cpython-314.pyc +0 -0
  137. package/lib/python3.14/site-packages/PIL/__pycache__/ImageShow.cpython-314.pyc +0 -0
  138. package/lib/python3.14/site-packages/PIL/__pycache__/ImageStat.cpython-314.pyc +0 -0
  139. package/lib/python3.14/site-packages/PIL/__pycache__/ImageText.cpython-314.pyc +0 -0
  140. package/lib/python3.14/site-packages/PIL/__pycache__/ImageTk.cpython-314.pyc +0 -0
  141. package/lib/python3.14/site-packages/PIL/__pycache__/ImageTransform.cpython-314.pyc +0 -0
  142. package/lib/python3.14/site-packages/PIL/__pycache__/ImageWin.cpython-314.pyc +0 -0
  143. package/lib/python3.14/site-packages/PIL/__pycache__/ImtImagePlugin.cpython-314.pyc +0 -0
  144. package/lib/python3.14/site-packages/PIL/__pycache__/IptcImagePlugin.cpython-314.pyc +0 -0
  145. package/lib/python3.14/site-packages/PIL/__pycache__/Jpeg2KImagePlugin.cpython-314.pyc +0 -0
  146. package/lib/python3.14/site-packages/PIL/__pycache__/JpegImagePlugin.cpython-314.pyc +0 -0
  147. package/lib/python3.14/site-packages/PIL/__pycache__/JpegPresets.cpython-314.pyc +0 -0
  148. package/lib/python3.14/site-packages/PIL/__pycache__/McIdasImagePlugin.cpython-314.pyc +0 -0
  149. package/lib/python3.14/site-packages/PIL/__pycache__/MicImagePlugin.cpython-314.pyc +0 -0
  150. package/lib/python3.14/site-packages/PIL/__pycache__/MpegImagePlugin.cpython-314.pyc +0 -0
  151. package/lib/python3.14/site-packages/PIL/__pycache__/MpoImagePlugin.cpython-314.pyc +0 -0
  152. package/lib/python3.14/site-packages/PIL/__pycache__/MspImagePlugin.cpython-314.pyc +0 -0
  153. package/lib/python3.14/site-packages/PIL/__pycache__/PSDraw.cpython-314.pyc +0 -0
  154. package/lib/python3.14/site-packages/PIL/__pycache__/PaletteFile.cpython-314.pyc +0 -0
  155. package/lib/python3.14/site-packages/PIL/__pycache__/PalmImagePlugin.cpython-314.pyc +0 -0
  156. package/lib/python3.14/site-packages/PIL/__pycache__/PcdImagePlugin.cpython-314.pyc +0 -0
  157. package/lib/python3.14/site-packages/PIL/__pycache__/PcfFontFile.cpython-314.pyc +0 -0
  158. package/lib/python3.14/site-packages/PIL/__pycache__/PcxImagePlugin.cpython-314.pyc +0 -0
  159. package/lib/python3.14/site-packages/PIL/__pycache__/PdfImagePlugin.cpython-314.pyc +0 -0
  160. package/lib/python3.14/site-packages/PIL/__pycache__/PdfParser.cpython-314.pyc +0 -0
  161. package/lib/python3.14/site-packages/PIL/__pycache__/PixarImagePlugin.cpython-314.pyc +0 -0
  162. package/lib/python3.14/site-packages/PIL/__pycache__/PngImagePlugin.cpython-314.pyc +0 -0
  163. package/lib/python3.14/site-packages/PIL/__pycache__/PpmImagePlugin.cpython-314.pyc +0 -0
  164. package/lib/python3.14/site-packages/PIL/__pycache__/PsdImagePlugin.cpython-314.pyc +0 -0
  165. package/lib/python3.14/site-packages/PIL/__pycache__/QoiImagePlugin.cpython-314.pyc +0 -0
  166. package/lib/python3.14/site-packages/PIL/__pycache__/SgiImagePlugin.cpython-314.pyc +0 -0
  167. package/lib/python3.14/site-packages/PIL/__pycache__/SpiderImagePlugin.cpython-314.pyc +0 -0
  168. package/lib/python3.14/site-packages/PIL/__pycache__/SunImagePlugin.cpython-314.pyc +0 -0
  169. package/lib/python3.14/site-packages/PIL/__pycache__/TarIO.cpython-314.pyc +0 -0
  170. package/lib/python3.14/site-packages/PIL/__pycache__/TgaImagePlugin.cpython-314.pyc +0 -0
  171. package/lib/python3.14/site-packages/PIL/__pycache__/TiffImagePlugin.cpython-314.pyc +0 -0
  172. package/lib/python3.14/site-packages/PIL/__pycache__/TiffTags.cpython-314.pyc +0 -0
  173. package/lib/python3.14/site-packages/PIL/__pycache__/WalImageFile.cpython-314.pyc +0 -0
  174. package/lib/python3.14/site-packages/PIL/__pycache__/WebPImagePlugin.cpython-314.pyc +0 -0
  175. package/lib/python3.14/site-packages/PIL/__pycache__/WmfImagePlugin.cpython-314.pyc +0 -0
  176. package/lib/python3.14/site-packages/PIL/__pycache__/XVThumbImagePlugin.cpython-314.pyc +0 -0
  177. package/lib/python3.14/site-packages/PIL/__pycache__/XbmImagePlugin.cpython-314.pyc +0 -0
  178. package/lib/python3.14/site-packages/PIL/__pycache__/XpmImagePlugin.cpython-314.pyc +0 -0
  179. package/lib/python3.14/site-packages/PIL/__pycache__/__init__.cpython-314.pyc +0 -0
  180. package/lib/python3.14/site-packages/PIL/__pycache__/__main__.cpython-314.pyc +0 -0
  181. package/lib/python3.14/site-packages/PIL/__pycache__/_binary.cpython-314.pyc +0 -0
  182. package/lib/python3.14/site-packages/PIL/__pycache__/_deprecate.cpython-314.pyc +0 -0
  183. package/lib/python3.14/site-packages/PIL/__pycache__/_tkinter_finder.cpython-314.pyc +0 -0
  184. package/lib/python3.14/site-packages/PIL/__pycache__/_typing.cpython-314.pyc +0 -0
  185. package/lib/python3.14/site-packages/PIL/__pycache__/_util.cpython-314.pyc +0 -0
  186. package/lib/python3.14/site-packages/PIL/__pycache__/_version.cpython-314.pyc +0 -0
  187. package/lib/python3.14/site-packages/PIL/__pycache__/features.cpython-314.pyc +0 -0
  188. package/lib/python3.14/site-packages/PIL/__pycache__/report.cpython-314.pyc +0 -0
  189. package/lib/python3.14/site-packages/PIL/_avif.pyi +3 -0
  190. package/lib/python3.14/site-packages/PIL/_binary.py +113 -0
  191. package/lib/python3.14/site-packages/PIL/_deprecate.py +72 -0
  192. package/lib/python3.14/site-packages/PIL/_imaging.cpython-314-wasm32-wasix.so +0 -0
  193. package/lib/python3.14/site-packages/PIL/_imaging.pyi +31 -0
  194. package/lib/python3.14/site-packages/PIL/_imagingcms.pyi +143 -0
  195. package/lib/python3.14/site-packages/PIL/_imagingft.cpython-314-wasm32-wasix.so +0 -0
  196. package/lib/python3.14/site-packages/PIL/_imagingft.pyi +70 -0
  197. package/lib/python3.14/site-packages/PIL/_imagingmath.cpython-314-wasm32-wasix.so +0 -0
  198. package/lib/python3.14/site-packages/PIL/_imagingmath.pyi +3 -0
  199. package/lib/python3.14/site-packages/PIL/_imagingmorph.cpython-314-wasm32-wasix.so +0 -0
  200. package/lib/python3.14/site-packages/PIL/_imagingmorph.pyi +3 -0
  201. package/lib/python3.14/site-packages/PIL/_imagingtk.cpython-314-wasm32-wasix.so +0 -0
  202. package/lib/python3.14/site-packages/PIL/_imagingtk.pyi +3 -0
  203. package/lib/python3.14/site-packages/PIL/_tkinter_finder.py +20 -0
  204. package/lib/python3.14/site-packages/PIL/_typing.py +45 -0
  205. package/lib/python3.14/site-packages/PIL/_util.py +29 -0
  206. package/lib/python3.14/site-packages/PIL/_version.py +4 -0
  207. package/lib/python3.14/site-packages/PIL/_webp.pyi +3 -0
  208. package/lib/python3.14/site-packages/PIL/features.py +343 -0
  209. package/lib/python3.14/site-packages/PIL/py.typed +0 -0
  210. package/lib/python3.14/site-packages/PIL/report.py +5 -0
  211. package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/METADATA +180 -0
  212. package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/RECORD +117 -0
  213. package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/WHEEL +5 -0
  214. package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/licenses/LICENSE +30 -0
  215. package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/top_level.txt +1 -0
  216. package/lib/python3.14/site-packages/pillow-12.3.0.dist-info/zip-safe +1 -0
  217. 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")