# # 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. # import os import re from . import Image, ImageFile, ImagePalette from ._binary import i8 # -------------------------------------------------------------------- # 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"), "PA image": ("LA", "PA;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[f"L {i} image"] = ("F", f"F;{i}") OPEN[f"L*{i} image"] = ("F", f"F;{i}") for i in ["16", "16L", "16B"]: OPEN[f"L {i} image"] = (f"I;{i}", f"I;{i}") OPEN[f"L*{i} image"] = (f"I;{i}", f"I;{i}") for i in ["32S"]: OPEN[f"L {i} image"] = ("I", f"I;{i}") OPEN[f"L*{i} image"] = ("I", f"I;{i}") for i in range(2, 33): OPEN[f"L*{i} image"] = ("F", f"F;{i}") # -------------------------------------------------------------------- # Read IM directory split = re.compile(br"^([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" _close_exclusive_fp_after_loading = False def _open(self): # Quick rejection: if there's not an LF among the first # 100 bytes, this is (probably) not a text header. if b"\n" not 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 True: s = self.fp.read(1) # Some versions of IFUNC uses \n\r instead of \r\n... if s == b"\r": continue if not s or s == b"\0" or s == b"\x1A": 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:] == b"\r\n": s = s[:-2] elif s[-1:] == b"\n": s = s[:-1] try: m = split.match(s) except re.error as e: raise SyntaxError("not an IM file") from e if m: k, v = m.group(1, 2) # Don't know if this is the correct encoding, # but a decent guess (I guess) k = k.decode("latin-1", "replace") v = v.decode("latin-1", "replace") # Convert value as appropriate if k in [FRAMES, SCALE, SIZE]: v = v.replace("*", ",") v = tuple(map(number, v.split(","))) if len(v) == 1: v = v[0] elif k == MODE and v in OPEN: v, self.rawmode = OPEN[v] # Add to dictionary. Note that COMMENT tags are # combined into a list of strings. if k == COMMENT: if k in self.info: self.info[k].append(v) else: self.info[k] = [v] else: self.info[k] = v if k in TAGS: n += 1 else: raise SyntaxError( "Syntax error in IM header: " + s.decode("ascii", "replace") ) 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:1] != b"\x1A": s = self.fp.read(1) if not s: raise SyntaxError("File truncated") if LUT in self.info: # 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 i8(palette[i]) != i: linear = 0 else: greyscale = 0 if self.mode in ["L", "LA", "P", "PA"]: if greyscale: if not linear: self.lut = [i8(c) for c in palette[:256]] else: if self.mode in ["L", "P"]: self.mode = self.rawmode = "P" elif self.mode in ["LA", "PA"]: self.mode = "PA" self.rawmode = "PA;L" self.palette = ImagePalette.raw("RGB;L", palette) elif self.mode == "RGB": if not greyscale or not linear: self.lut = [i8(c) for c in 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))] @property def n_frames(self): return self.info[FRAMES] @property def is_animated(self): return self.info[FRAMES] > 1 def seek(self, frame): if not self._seek_check(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 def _close__fp(self): try: if self.__fp != self.fp: self.__fp.close() except AttributeError: pass finally: self.__fp = None # # -------------------------------------------------------------------- # 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): try: image_type, rawmode = SAVE[im.mode] except KeyError as e: raise ValueError(f"Cannot save {im.mode} images as IM") from e frames = im.encoderinfo.get("frames", 1) fp.write(f"Image type: {image_type} image\r\n".encode("ascii")) if filename: # Each line must be 100 characters or less, # or: SyntaxError("not an IM file") # 8 characters are used for "Name: " and "\r\n" # Keep just the filename, ditch the potentially overlong path name, ext = os.path.splitext(os.path.basename(filename)) name = "".join([name[: 92 - len(ext)], ext]) fp.write(f"Name: {name}\r\n".encode("ascii")) fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode("ascii")) fp.write(f"File size (no of images): {frames}\r\n".encode("ascii")) if im.mode in ["P", "PA"]: fp.write(b"Lut: 1\r\n") fp.write(b"\000" * (511 - fp.tell()) + b"\032") if im.mode in ["P", "PA"]: 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(ImImageFile.format, ImImageFile) Image.register_save(ImImageFile.format, _save) Image.register_extension(ImImageFile.format, ".im")
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
__pycache__ | Folder | 2755 |
|
|
BdfFontFile.py | File | 2.75 KB | 0644 |
|
BlpImagePlugin.py | File | 14 KB | 0644 |
|
BmpImagePlugin.py | File | 13.92 KB | 0644 |
|
BufrStubImagePlugin.py | File | 1.48 KB | 0644 |
|
ContainerIO.py | File | 2.82 KB | 0644 |
|
CurImagePlugin.py | File | 1.68 KB | 0644 |
|
DcxImagePlugin.py | File | 2.09 KB | 0644 |
|
DdsImagePlugin.py | File | 5.34 KB | 0644 |
|
EpsImagePlugin.py | File | 11.82 KB | 0644 |
|
ExifTags.py | File | 8.8 KB | 0644 |
|
FitsStubImagePlugin.py | File | 1.59 KB | 0644 |
|
FliImagePlugin.py | File | 4.23 KB | 0644 |
|
FontFile.py | File | 2.7 KB | 0644 |
|
FpxImagePlugin.py | File | 6.53 KB | 0644 |
|
FtexImagePlugin.py | File | 3.23 KB | 0644 |
|
GbrImagePlugin.py | File | 2.73 KB | 0644 |
|
GdImageFile.py | File | 2.47 KB | 0644 |
|
GifImagePlugin.py | File | 28.25 KB | 0644 |
|
GimpGradientFile.py | File | 3.27 KB | 0644 |
|
GimpPaletteFile.py | File | 1.24 KB | 0644 |
|
GribStubImagePlugin.py | File | 1.51 KB | 0644 |
|
Hdf5StubImagePlugin.py | File | 1.48 KB | 0644 |
|
IcnsImagePlugin.py | File | 11.44 KB | 0644 |
|
IcoImagePlugin.py | File | 9.94 KB | 0644 |
|
ImImagePlugin.py | File | 10.53 KB | 0644 |
|
Image.py | File | 113.4 KB | 0644 |
|
ImageChops.py | File | 7.13 KB | 0644 |
|
ImageCms.py | File | 36.22 KB | 0644 |
|
ImageColor.py | File | 8.44 KB | 0644 |
|
ImageDraw.py | File | 29.94 KB | 0644 |
|
ImageDraw2.py | File | 4.9 KB | 0644 |
|
ImageEnhance.py | File | 3.12 KB | 0644 |
|
ImageFile.py | File | 20.74 KB | 0644 |
|
ImageFilter.py | File | 15.46 KB | 0644 |
|
ImageFont.py | File | 43.49 KB | 0644 |
|
ImageGrab.py | File | 3.54 KB | 0644 |
|
ImageMath.py | File | 6.88 KB | 0644 |
|
ImageMode.py | File | 1.6 KB | 0644 |
|
ImageMorph.py | File | 7.67 KB | 0644 |
|
ImageOps.py | File | 18.03 KB | 0644 |
|
ImagePalette.py | File | 6.2 KB | 0644 |
|
ImagePath.py | File | 336 B | 0644 |
|
ImageQt.py | File | 5.67 KB | 0644 |
|
ImageSequence.py | File | 1.81 KB | 0644 |
|
ImageShow.py | File | 6.15 KB | 0644 |
|
ImageStat.py | File | 3.81 KB | 0644 |
|
ImageTk.py | File | 9.11 KB | 0644 |
|
ImageTransform.py | File | 2.78 KB | 0644 |
|
ImageWin.py | File | 7.02 KB | 0644 |
|
ImtImagePlugin.py | File | 2.15 KB | 0644 |
|
IptcImagePlugin.py | File | 5.6 KB | 0644 |
|
Jpeg2KImagePlugin.py | File | 8.52 KB | 0644 |
|
JpegImagePlugin.py | File | 27.16 KB | 0644 |
|
JpegPresets.py | File | 12.41 KB | 0644 |
|
McIdasImagePlugin.py | File | 1.71 KB | 0644 |
|
MicImagePlugin.py | File | 2.54 KB | 0644 |
|
MpegImagePlugin.py | File | 1.76 KB | 0644 |
|
MpoImagePlugin.py | File | 4.14 KB | 0644 |
|
MspImagePlugin.py | File | 5.43 KB | 0644 |
|
PSDraw.py | File | 6.51 KB | 0644 |
|
PaletteFile.py | File | 1.08 KB | 0644 |
|
PalmImagePlugin.py | File | 8.89 KB | 0644 |
|
PcdImagePlugin.py | File | 1.47 KB | 0644 |
|
PcfFontFile.py | File | 6.2 KB | 0644 |
|
PcxImagePlugin.py | File | 5.41 KB | 0644 |
|
PdfImagePlugin.py | File | 7.49 KB | 0644 |
|
PdfParser.py | File | 33.58 KB | 0644 |
|
PixarImagePlugin.py | File | 1.61 KB | 0644 |
|
PngImagePlugin.py | File | 42.79 KB | 0644 |
|
PpmImagePlugin.py | File | 4.34 KB | 0644 |
|
PsdImagePlugin.py | File | 7.56 KB | 0644 |
|
PyAccess.py | File | 9.37 KB | 0644 |
|
SgiImagePlugin.py | File | 5.96 KB | 0644 |
|
SpiderImagePlugin.py | File | 9.31 KB | 0644 |
|
SunImagePlugin.py | File | 4.2 KB | 0644 |
|
TarIO.py | File | 1.41 KB | 0644 |
|
TgaImagePlugin.py | File | 6.18 KB | 0644 |
|
TiffImagePlugin.py | File | 66.86 KB | 0644 |
|
TiffTags.py | File | 14.22 KB | 0644 |
|
WalImageFile.py | File | 5.4 KB | 0644 |
|
WebPImagePlugin.py | File | 10.54 KB | 0644 |
|
WmfImagePlugin.py | File | 4.56 KB | 0644 |
|
XVThumbImagePlugin.py | File | 1.9 KB | 0644 |
|
XbmImagePlugin.py | File | 2.37 KB | 0644 |
|
XpmImagePlugin.py | File | 3 KB | 0644 |
|
__init__.py | File | 3.18 KB | 0644 |
|
__main__.py | File | 41 B | 0644 |
|
_binary.py | File | 1.75 KB | 0644 |
|
_imaging.cpython-36m-x86_64-linux-gnu.so | File | 650.13 KB | 0755 |
|
_imagingcms.cpython-36m-x86_64-linux-gnu.so | File | 38.05 KB | 0755 |
|
_imagingft.cpython-36m-x86_64-linux-gnu.so | File | 41.98 KB | 0755 |
|
_imagingmath.cpython-36m-x86_64-linux-gnu.so | File | 24.43 KB | 0755 |
|
_imagingmorph.cpython-36m-x86_64-linux-gnu.so | File | 8.12 KB | 0755 |
|
_imagingtk.cpython-36m-x86_64-linux-gnu.so | File | 9.37 KB | 0755 |
|
_tkinter_finder.py | File | 224 B | 0644 |
|
_util.py | File | 359 B | 0644 |
|
_version.py | File | 50 B | 0644 |
|
_webp.cpython-36m-x86_64-linux-gnu.so | File | 40.82 KB | 0755 |
|
features.py | File | 8.8 KB | 0644 |
|