PageRenderTime 58ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Windows/Python3.8/WPy64-3830/WPy64-3830/python-3.8.3.amd64/Lib/site-packages/PIL/ImImagePlugin.py

https://gitlab.com/abhi1tb/build
Python | 377 lines | 246 code | 69 blank | 62 comment | 64 complexity | d21c9ca89071da1cdb3cd954b265ed23 MD5 | raw file
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # IFUNC IM file handling for PIL
  6. #
  7. # history:
  8. # 1995-09-01 fl Created.
  9. # 1997-01-03 fl Save palette images
  10. # 1997-01-08 fl Added sequence support
  11. # 1997-01-23 fl Added P and RGB save support
  12. # 1997-05-31 fl Read floating point images
  13. # 1997-06-22 fl Save floating point images
  14. # 1997-08-27 fl Read and save 1-bit images
  15. # 1998-06-25 fl Added support for RGB+LUT images
  16. # 1998-07-02 fl Added support for YCC images
  17. # 1998-07-15 fl Renamed offset attribute to avoid name clash
  18. # 1998-12-29 fl Added I;16 support
  19. # 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7)
  20. # 2003-09-26 fl Added LA/PA support
  21. #
  22. # Copyright (c) 1997-2003 by Secret Labs AB.
  23. # Copyright (c) 1995-2001 by Fredrik Lundh.
  24. #
  25. # See the README file for information on usage and redistribution.
  26. #
  27. import os
  28. import re
  29. from . import Image, ImageFile, ImagePalette
  30. from ._binary import i8
  31. # --------------------------------------------------------------------
  32. # Standard tags
  33. COMMENT = "Comment"
  34. DATE = "Date"
  35. EQUIPMENT = "Digitalization equipment"
  36. FRAMES = "File size (no of images)"
  37. LUT = "Lut"
  38. NAME = "Name"
  39. SCALE = "Scale (x,y)"
  40. SIZE = "Image size (x*y)"
  41. MODE = "Image type"
  42. TAGS = {
  43. COMMENT: 0,
  44. DATE: 0,
  45. EQUIPMENT: 0,
  46. FRAMES: 0,
  47. LUT: 0,
  48. NAME: 0,
  49. SCALE: 0,
  50. SIZE: 0,
  51. MODE: 0,
  52. }
  53. OPEN = {
  54. # ifunc93/p3cfunc formats
  55. "0 1 image": ("1", "1"),
  56. "L 1 image": ("1", "1"),
  57. "Greyscale image": ("L", "L"),
  58. "Grayscale image": ("L", "L"),
  59. "RGB image": ("RGB", "RGB;L"),
  60. "RLB image": ("RGB", "RLB"),
  61. "RYB image": ("RGB", "RLB"),
  62. "B1 image": ("1", "1"),
  63. "B2 image": ("P", "P;2"),
  64. "B4 image": ("P", "P;4"),
  65. "X 24 image": ("RGB", "RGB"),
  66. "L 32 S image": ("I", "I;32"),
  67. "L 32 F image": ("F", "F;32"),
  68. # old p3cfunc formats
  69. "RGB3 image": ("RGB", "RGB;T"),
  70. "RYB3 image": ("RGB", "RYB;T"),
  71. # extensions
  72. "LA image": ("LA", "LA;L"),
  73. "PA image": ("LA", "PA;L"),
  74. "RGBA image": ("RGBA", "RGBA;L"),
  75. "RGBX image": ("RGBX", "RGBX;L"),
  76. "CMYK image": ("CMYK", "CMYK;L"),
  77. "YCC image": ("YCbCr", "YCbCr;L"),
  78. }
  79. # ifunc95 extensions
  80. for i in ["8", "8S", "16", "16S", "32", "32F"]:
  81. OPEN["L %s image" % i] = ("F", "F;%s" % i)
  82. OPEN["L*%s image" % i] = ("F", "F;%s" % i)
  83. for i in ["16", "16L", "16B"]:
  84. OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i)
  85. OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i)
  86. for i in ["32S"]:
  87. OPEN["L %s image" % i] = ("I", "I;%s" % i)
  88. OPEN["L*%s image" % i] = ("I", "I;%s" % i)
  89. for i in range(2, 33):
  90. OPEN["L*%s image" % i] = ("F", "F;%s" % i)
  91. # --------------------------------------------------------------------
  92. # Read IM directory
  93. split = re.compile(br"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
  94. def number(s):
  95. try:
  96. return int(s)
  97. except ValueError:
  98. return float(s)
  99. ##
  100. # Image plugin for the IFUNC IM file format.
  101. class ImImageFile(ImageFile.ImageFile):
  102. format = "IM"
  103. format_description = "IFUNC Image Memory"
  104. _close_exclusive_fp_after_loading = False
  105. def _open(self):
  106. # Quick rejection: if there's not an LF among the first
  107. # 100 bytes, this is (probably) not a text header.
  108. if b"\n" not in self.fp.read(100):
  109. raise SyntaxError("not an IM file")
  110. self.fp.seek(0)
  111. n = 0
  112. # Default values
  113. self.info[MODE] = "L"
  114. self.info[SIZE] = (512, 512)
  115. self.info[FRAMES] = 1
  116. self.rawmode = "L"
  117. while True:
  118. s = self.fp.read(1)
  119. # Some versions of IFUNC uses \n\r instead of \r\n...
  120. if s == b"\r":
  121. continue
  122. if not s or s == b"\0" or s == b"\x1A":
  123. break
  124. # FIXME: this may read whole file if not a text file
  125. s = s + self.fp.readline()
  126. if len(s) > 100:
  127. raise SyntaxError("not an IM file")
  128. if s[-2:] == b"\r\n":
  129. s = s[:-2]
  130. elif s[-1:] == b"\n":
  131. s = s[:-1]
  132. try:
  133. m = split.match(s)
  134. except re.error:
  135. raise SyntaxError("not an IM file")
  136. if m:
  137. k, v = m.group(1, 2)
  138. # Don't know if this is the correct encoding,
  139. # but a decent guess (I guess)
  140. k = k.decode("latin-1", "replace")
  141. v = v.decode("latin-1", "replace")
  142. # Convert value as appropriate
  143. if k in [FRAMES, SCALE, SIZE]:
  144. v = v.replace("*", ",")
  145. v = tuple(map(number, v.split(",")))
  146. if len(v) == 1:
  147. v = v[0]
  148. elif k == MODE and v in OPEN:
  149. v, self.rawmode = OPEN[v]
  150. # Add to dictionary. Note that COMMENT tags are
  151. # combined into a list of strings.
  152. if k == COMMENT:
  153. if k in self.info:
  154. self.info[k].append(v)
  155. else:
  156. self.info[k] = [v]
  157. else:
  158. self.info[k] = v
  159. if k in TAGS:
  160. n += 1
  161. else:
  162. raise SyntaxError(
  163. "Syntax error in IM header: " + s.decode("ascii", "replace")
  164. )
  165. if not n:
  166. raise SyntaxError("Not an IM file")
  167. # Basic attributes
  168. self._size = self.info[SIZE]
  169. self.mode = self.info[MODE]
  170. # Skip forward to start of image data
  171. while s and s[0:1] != b"\x1A":
  172. s = self.fp.read(1)
  173. if not s:
  174. raise SyntaxError("File truncated")
  175. if LUT in self.info:
  176. # convert lookup table to palette or lut attribute
  177. palette = self.fp.read(768)
  178. greyscale = 1 # greyscale palette
  179. linear = 1 # linear greyscale palette
  180. for i in range(256):
  181. if palette[i] == palette[i + 256] == palette[i + 512]:
  182. if i8(palette[i]) != i:
  183. linear = 0
  184. else:
  185. greyscale = 0
  186. if self.mode in ["L", "LA", "P", "PA"]:
  187. if greyscale:
  188. if not linear:
  189. self.lut = [i8(c) for c in palette[:256]]
  190. else:
  191. if self.mode in ["L", "P"]:
  192. self.mode = self.rawmode = "P"
  193. elif self.mode in ["LA", "PA"]:
  194. self.mode = "PA"
  195. self.rawmode = "PA;L"
  196. self.palette = ImagePalette.raw("RGB;L", palette)
  197. elif self.mode == "RGB":
  198. if not greyscale or not linear:
  199. self.lut = [i8(c) for c in palette]
  200. self.frame = 0
  201. self.__offset = offs = self.fp.tell()
  202. self.__fp = self.fp # FIXME: hack
  203. if self.rawmode[:2] == "F;":
  204. # ifunc95 formats
  205. try:
  206. # use bit decoder (if necessary)
  207. bits = int(self.rawmode[2:])
  208. if bits not in [8, 16, 32]:
  209. self.tile = [("bit", (0, 0) + self.size, offs, (bits, 8, 3, 0, -1))]
  210. return
  211. except ValueError:
  212. pass
  213. if self.rawmode in ["RGB;T", "RYB;T"]:
  214. # Old LabEye/3PC files. Would be very surprised if anyone
  215. # ever stumbled upon such a file ;-)
  216. size = self.size[0] * self.size[1]
  217. self.tile = [
  218. ("raw", (0, 0) + self.size, offs, ("G", 0, -1)),
  219. ("raw", (0, 0) + self.size, offs + size, ("R", 0, -1)),
  220. ("raw", (0, 0) + self.size, offs + 2 * size, ("B", 0, -1)),
  221. ]
  222. else:
  223. # LabEye/IFUNC files
  224. self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]
  225. @property
  226. def n_frames(self):
  227. return self.info[FRAMES]
  228. @property
  229. def is_animated(self):
  230. return self.info[FRAMES] > 1
  231. def seek(self, frame):
  232. if not self._seek_check(frame):
  233. return
  234. self.frame = frame
  235. if self.mode == "1":
  236. bits = 1
  237. else:
  238. bits = 8 * len(self.mode)
  239. size = ((self.size[0] * bits + 7) // 8) * self.size[1]
  240. offs = self.__offset + frame * size
  241. self.fp = self.__fp
  242. self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]
  243. def tell(self):
  244. return self.frame
  245. def _close__fp(self):
  246. try:
  247. if self.__fp != self.fp:
  248. self.__fp.close()
  249. except AttributeError:
  250. pass
  251. finally:
  252. self.__fp = None
  253. #
  254. # --------------------------------------------------------------------
  255. # Save IM files
  256. SAVE = {
  257. # mode: (im type, raw mode)
  258. "1": ("0 1", "1"),
  259. "L": ("Greyscale", "L"),
  260. "LA": ("LA", "LA;L"),
  261. "P": ("Greyscale", "P"),
  262. "PA": ("LA", "PA;L"),
  263. "I": ("L 32S", "I;32S"),
  264. "I;16": ("L 16", "I;16"),
  265. "I;16L": ("L 16L", "I;16L"),
  266. "I;16B": ("L 16B", "I;16B"),
  267. "F": ("L 32F", "F;32F"),
  268. "RGB": ("RGB", "RGB;L"),
  269. "RGBA": ("RGBA", "RGBA;L"),
  270. "RGBX": ("RGBX", "RGBX;L"),
  271. "CMYK": ("CMYK", "CMYK;L"),
  272. "YCbCr": ("YCC", "YCbCr;L"),
  273. }
  274. def _save(im, fp, filename):
  275. try:
  276. image_type, rawmode = SAVE[im.mode]
  277. except KeyError:
  278. raise ValueError("Cannot save %s images as IM" % im.mode)
  279. frames = im.encoderinfo.get("frames", 1)
  280. fp.write(("Image type: %s image\r\n" % image_type).encode("ascii"))
  281. if filename:
  282. # Each line must be 100 characters or less,
  283. # or: SyntaxError("not an IM file")
  284. # 8 characters are used for "Name: " and "\r\n"
  285. # Keep just the filename, ditch the potentially overlong path
  286. name, ext = os.path.splitext(os.path.basename(filename))
  287. name = "".join([name[: 92 - len(ext)], ext])
  288. fp.write(("Name: %s\r\n" % name).encode("ascii"))
  289. fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode("ascii"))
  290. fp.write(("File size (no of images): %d\r\n" % frames).encode("ascii"))
  291. if im.mode in ["P", "PA"]:
  292. fp.write(b"Lut: 1\r\n")
  293. fp.write(b"\000" * (511 - fp.tell()) + b"\032")
  294. if im.mode in ["P", "PA"]:
  295. fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
  296. ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))])
  297. #
  298. # --------------------------------------------------------------------
  299. # Registry
  300. Image.register_open(ImImageFile.format, ImImageFile)
  301. Image.register_save(ImImageFile.format, _save)
  302. Image.register_extension(ImImageFile.format, ".im")