__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
#
# The Python Imaging Library.
# $Id$
#
# EPS file handling
#
# History:
# 1995-09-01 fl   Created (0.1)
# 1996-05-18 fl   Don't choke on "atend" fields, Ghostscript interface (0.2)
# 1996-08-22 fl   Don't choke on floating point BoundingBox values
# 1996-08-23 fl   Handle files from Macintosh (0.3)
# 2001-02-17 fl   Use 're' instead of 'regex' (Python 2.1) (0.4)
# 2003-09-07 fl   Check gs.close status (from Federico Di Gregorio) (0.5)
# 2014-05-07 e    Handling of EPS with binary preview and fixed resolution
#                 resizing
#
# Copyright (c) 1997-2003 by Secret Labs AB.
# Copyright (c) 1995-2003 by Fredrik Lundh
#
# See the README file for information on usage and redistribution.
#
from __future__ import annotations

import io
import os
import re
import subprocess
import sys
import tempfile
from typing import IO

from . import Image, ImageFile
from ._binary import i32le as i32

# --------------------------------------------------------------------


split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$")
field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$")

gs_binary: str | bool | None = None
gs_windows_binary = None


def has_ghostscript() -> bool:
    global gs_binary, gs_windows_binary
    if gs_binary is None:
        if sys.platform.startswith("win"):
            if gs_windows_binary is None:
                import shutil

                for binary in ("gswin32c", "gswin64c", "gs"):
                    if shutil.which(binary) is not None:
                        gs_windows_binary = binary
                        break
                else:
                    gs_windows_binary = False
            gs_binary = gs_windows_binary
        else:
            try:
                subprocess.check_call(["gs", "--version"], stdout=subprocess.DEVNULL)
                gs_binary = "gs"
            except OSError:
                gs_binary = False
    return gs_binary is not False


def Ghostscript(
    tile: list[ImageFile._Tile],
    size: tuple[int, int],
    fp: IO[bytes],
    scale: int = 1,
    transparency: bool = False,
) -> Image.core.ImagingCore:
    """Render an image using Ghostscript"""
    global gs_binary
    if not has_ghostscript():
        msg = "Unable to locate Ghostscript on paths"
        raise OSError(msg)
    assert isinstance(gs_binary, str)

    # Unpack decoder tile
    args = tile[0].args
    assert isinstance(args, tuple)
    length, bbox = args

    # Hack to support hi-res rendering
    scale = int(scale) or 1
    width = size[0] * scale
    height = size[1] * scale
    # resolution is dependent on bbox and size
    res_x = 72.0 * width / (bbox[2] - bbox[0])
    res_y = 72.0 * height / (bbox[3] - bbox[1])

    out_fd, outfile = tempfile.mkstemp()
    os.close(out_fd)

    infile_temp = None
    if hasattr(fp, "name") and os.path.exists(fp.name):
        infile = fp.name
    else:
        in_fd, infile_temp = tempfile.mkstemp()
        os.close(in_fd)
        infile = infile_temp

        # Ignore length and offset!
        # Ghostscript can read it
        # Copy whole file to read in Ghostscript
        with open(infile_temp, "wb") as f:
            # fetch length of fp
            fp.seek(0, io.SEEK_END)
            fsize = fp.tell()
            # ensure start position
            # go back
            fp.seek(0)
            lengthfile = fsize
            while lengthfile > 0:
                s = fp.read(min(lengthfile, 100 * 1024))
                if not s:
                    break
                lengthfile -= len(s)
                f.write(s)

    if transparency:
        # "RGBA"
        device = "pngalpha"
    else:
        # "pnmraw" automatically chooses between
        # PBM ("1"), PGM ("L"), and PPM ("RGB").
        device = "pnmraw"

    # Build Ghostscript command
    command = [
        gs_binary,
        "-q",  # quiet mode
        f"-g{width:d}x{height:d}",  # set output geometry (pixels)
        f"-r{res_x:f}x{res_y:f}",  # set input DPI (dots per inch)
        "-dBATCH",  # exit after processing
        "-dNOPAUSE",  # don't pause between pages
        "-dSAFER",  # safe mode
        f"-sDEVICE={device}",
        f"-sOutputFile={outfile}",  # output file
        # adjust for image origin
        "-c",
        f"{-bbox[0]} {-bbox[1]} translate",
        "-f",
        infile,  # input file
        # showpage (see https://bugs.ghostscript.com/show_bug.cgi?id=698272)
        "-c",
        "showpage",
    ]

    # push data through Ghostscript
    try:
        startupinfo = None
        if sys.platform.startswith("win"):
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        subprocess.check_call(command, startupinfo=startupinfo)
        with Image.open(outfile) as out_im:
            out_im.load()
            return out_im.im.copy()
    finally:
        try:
            os.unlink(outfile)
            if infile_temp:
                os.unlink(infile_temp)
        except OSError:
            pass


def _accept(prefix: bytes) -> bool:
    return prefix[:4] == b"%!PS" or (len(prefix) >= 4 and i32(prefix) == 0xC6D3D0C5)


##
# Image plugin for Encapsulated PostScript. This plugin supports only
# a few variants of this format.


class EpsImageFile(ImageFile.ImageFile):
    """EPS File Parser for the Python Imaging Library"""

    format = "EPS"
    format_description = "Encapsulated Postscript"

    mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"}

    def _open(self) -> None:
        (length, offset) = self._find_offset(self.fp)

        # go to offset - start of "%!PS"
        self.fp.seek(offset)

        self._mode = "RGB"

        # When reading header comments, the first comment is used.
        # When reading trailer comments, the last comment is used.
        bounding_box: list[int] | None = None
        imagedata_size: tuple[int, int] | None = None

        byte_arr = bytearray(255)
        bytes_mv = memoryview(byte_arr)
        bytes_read = 0
        reading_header_comments = True
        reading_trailer_comments = False
        trailer_reached = False

        def check_required_header_comments() -> None:
            """
            The EPS specification requires that some headers exist.
            This should be checked when the header comments formally end,
            when image data starts, or when the file ends, whichever comes first.
            """
            if "PS-Adobe" not in self.info:
                msg = 'EPS header missing "%!PS-Adobe" comment'
                raise SyntaxError(msg)
            if "BoundingBox" not in self.info:
                msg = 'EPS header missing "%%BoundingBox" comment'
                raise SyntaxError(msg)

        def read_comment(s: str) -> bool:
            nonlocal bounding_box, reading_trailer_comments
            try:
                m = split.match(s)
            except re.error as e:
                msg = "not an EPS file"
                raise SyntaxError(msg) from e

            if not m:
                return False

            k, v = m.group(1, 2)
            self.info[k] = v
            if k == "BoundingBox":
                if v == "(atend)":
                    reading_trailer_comments = True
                elif not bounding_box or (trailer_reached and reading_trailer_comments):
                    try:
                        # Note: The DSC spec says that BoundingBox
                        # fields should be integers, but some drivers
                        # put floating point values there anyway.
                        bounding_box = [int(float(i)) for i in v.split()]
                    except Exception:
                        pass
            return True

        while True:
            byte = self.fp.read(1)
            if byte == b"":
                # if we didn't read a byte we must be at the end of the file
                if bytes_read == 0:
                    if reading_header_comments:
                        check_required_header_comments()
                    break
            elif byte in b"\r\n":
                # if we read a line ending character, ignore it and parse what
                # we have already read. if we haven't read any other characters,
                # continue reading
                if bytes_read == 0:
                    continue
            else:
                # ASCII/hexadecimal lines in an EPS file must not exceed
                # 255 characters, not including line ending characters
                if bytes_read >= 255:
                    # only enforce this for lines starting with a "%",
                    # otherwise assume it's binary data
                    if byte_arr[0] == ord("%"):
                        msg = "not an EPS file"
                        raise SyntaxError(msg)
                    else:
                        if reading_header_comments:
                            check_required_header_comments()
                            reading_header_comments = False
                        # reset bytes_read so we can keep reading
                        # data until the end of the line
                        bytes_read = 0
                byte_arr[bytes_read] = byte[0]
                bytes_read += 1
                continue

            if reading_header_comments:
                # Load EPS header

                # if this line doesn't start with a "%",
                # or does start with "%%EndComments",
                # then we've reached the end of the header/comments
                if byte_arr[0] != ord("%") or bytes_mv[:13] == b"%%EndComments":
                    check_required_header_comments()
                    reading_header_comments = False
                    continue

                s = str(bytes_mv[:bytes_read], "latin-1")
                if not read_comment(s):
                    m = field.match(s)
                    if m:
                        k = m.group(1)
                        if k[:8] == "PS-Adobe":
                            self.info["PS-Adobe"] = k[9:]
                        else:
                            self.info[k] = ""
                    elif s[0] == "%":
                        # handle non-DSC PostScript comments that some
                        # tools mistakenly put in the Comments section
                        pass
                    else:
                        msg = "bad EPS header"
                        raise OSError(msg)
            elif bytes_mv[:11] == b"%ImageData:":
                # Check for an "ImageData" descriptor
                # https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577413_pgfId-1035096

                # If we've already read an "ImageData" descriptor,
                # don't read another one.
                if imagedata_size:
                    bytes_read = 0
                    continue

                # Values:
                # columns
                # rows
                # bit depth (1 or 8)
                # mode (1: L, 2: LAB, 3: RGB, 4: CMYK)
                # number of padding channels
                # block size (number of bytes per row per channel)
                # binary/ascii (1: binary, 2: ascii)
                # data start identifier (the image data follows after a single line
                #   consisting only of this quoted value)
                image_data_values = byte_arr[11:bytes_read].split(None, 7)
                columns, rows, bit_depth, mode_id = (
                    int(value) for value in image_data_values[:4]
                )

                if bit_depth == 1:
                    self._mode = "1"
                elif bit_depth == 8:
                    try:
                        self._mode = self.mode_map[mode_id]
                    except ValueError:
                        break
                else:
                    break

                # Parse the columns and rows after checking the bit depth and mode
                # in case the bit depth and/or mode are invalid.
                imagedata_size = columns, rows
            elif bytes_mv[:5] == b"%%EOF":
                break
            elif trailer_reached and reading_trailer_comments:
                # Load EPS trailer
                s = str(bytes_mv[:bytes_read], "latin-1")
                read_comment(s)
            elif bytes_mv[:9] == b"%%Trailer":
                trailer_reached = True
            bytes_read = 0

        # A "BoundingBox" is always required,
        # even if an "ImageData" descriptor size exists.
        if not bounding_box:
            msg = "cannot determine EPS bounding box"
            raise OSError(msg)

        # An "ImageData" size takes precedence over the "BoundingBox".
        self._size = imagedata_size or (
            bounding_box[2] - bounding_box[0],
            bounding_box[3] - bounding_box[1],
        )

        self.tile = [
            ImageFile._Tile("eps", (0, 0) + self.size, offset, (length, bounding_box))
        ]

    def _find_offset(self, fp: IO[bytes]) -> tuple[int, int]:
        s = fp.read(4)

        if s == b"%!PS":
            # for HEAD without binary preview
            fp.seek(0, io.SEEK_END)
            length = fp.tell()
            offset = 0
        elif i32(s) == 0xC6D3D0C5:
            # FIX for: Some EPS file not handled correctly / issue #302
            # EPS can contain binary data
            # or start directly with latin coding
            # more info see:
            # https://web.archive.org/web/20160528181353/http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf
            s = fp.read(8)
            offset = i32(s)
            length = i32(s, 4)
        else:
            msg = "not an EPS file"
            raise SyntaxError(msg)

        return length, offset

    def load(
        self, scale: int = 1, transparency: bool = False
    ) -> Image.core.PixelAccess | None:
        # Load EPS via Ghostscript
        if self.tile:
            self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency)
            self._mode = self.im.mode
            self._size = self.im.size
            self.tile = []
        return Image.Image.load(self)

    def load_seek(self, pos: int) -> None:
        # we can't incrementally load, so force ImageFile.parser to
        # use our custom load method by defining this method.
        pass


# --------------------------------------------------------------------


def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes, eps: int = 1) -> None:
    """EPS Writer for the Python Imaging Library."""

    # make sure image data is available
    im.load()

    # determine PostScript image mode
    if im.mode == "L":
        operator = (8, 1, b"image")
    elif im.mode == "RGB":
        operator = (8, 3, b"false 3 colorimage")
    elif im.mode == "CMYK":
        operator = (8, 4, b"false 4 colorimage")
    else:
        msg = "image mode is not supported"
        raise ValueError(msg)

    if eps:
        # write EPS header
        fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n")
        fp.write(b"%%Creator: PIL 0.1 EpsEncode\n")
        # fp.write("%%CreationDate: %s"...)
        fp.write(b"%%%%BoundingBox: 0 0 %d %d\n" % im.size)
        fp.write(b"%%Pages: 1\n")
        fp.write(b"%%EndComments\n")
        fp.write(b"%%Page: 1 1\n")
        fp.write(b"%%ImageData: %d %d " % im.size)
        fp.write(b'%d %d 0 1 1 "%s"\n' % operator)

    # image header
    fp.write(b"gsave\n")
    fp.write(b"10 dict begin\n")
    fp.write(b"/buf %d string def\n" % (im.size[0] * operator[1]))
    fp.write(b"%d %d scale\n" % im.size)
    fp.write(b"%d %d 8\n" % im.size)  # <= bits
    fp.write(b"[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]))
    fp.write(b"{ currentfile buf readhexstring pop } bind\n")
    fp.write(operator[2] + b"\n")
    if hasattr(fp, "flush"):
        fp.flush()

    ImageFile._save(im, fp, [ImageFile._Tile("eps", (0, 0) + im.size)])

    fp.write(b"\n%%%%EndBinary\n")
    fp.write(b"grestore end\n")
    if hasattr(fp, "flush"):
        fp.flush()


# --------------------------------------------------------------------


Image.register_open(EpsImageFile.format, EpsImageFile, _accept)

Image.register_save(EpsImageFile.format, _save)

Image.register_extensions(EpsImageFile.format, [".ps", ".eps"])

Image.register_mime(EpsImageFile.format, "application/postscript")

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
BdfFontFile.py File 3.4 KB 0644
BlpImagePlugin.py File 16.29 KB 0644
BmpImagePlugin.py File 19.29 KB 0644
BufrStubImagePlugin.py File 1.71 KB 0644
ContainerIO.py File 4.5 KB 0644
CurImagePlugin.py File 1.75 KB 0644
DcxImagePlugin.py File 1.99 KB 0644
DdsImagePlugin.py File 16.54 KB 0644
EpsImagePlugin.py File 15.98 KB 0644
ExifTags.py File 9.7 KB 0644
FitsImagePlugin.py File 4.53 KB 0644
FliImagePlugin.py File 4.57 KB 0644
FontFile.py File 3.49 KB 0644
FpxImagePlugin.py File 7.12 KB 0644
FtexImagePlugin.py File 3.44 KB 0644
GbrImagePlugin.py File 2.94 KB 0644
GdImageFile.py File 2.74 KB 0644
GifImagePlugin.py File 40.48 KB 0644
GimpGradientFile.py File 3.81 KB 0644
GimpPaletteFile.py File 1.39 KB 0644
GribStubImagePlugin.py File 1.71 KB 0644
Hdf5StubImagePlugin.py File 1.71 KB 0644
IcnsImagePlugin.py File 12.65 KB 0644
IcoImagePlugin.py File 12.18 KB 0644
ImImagePlugin.py File 11.17 KB 0644
Image.py File 142.7 KB 0644
ImageChops.py File 7.76 KB 0644
ImageCms.py File 41.03 KB 0644
ImageColor.py File 9.22 KB 0644
ImageDraw.py File 41.28 KB 0644
ImageDraw2.py File 7.06 KB 0644
ImageEnhance.py File 3.54 KB 0644
ImageFile.py File 25.51 KB 0644
ImageFilter.py File 18.27 KB 0644
ImageFont.py File 62.75 KB 0644
ImageGrab.py File 5.86 KB 0644
ImageMath.py File 11.66 KB 0644
ImageMode.py File 2.62 KB 0644
ImageMorph.py File 8.36 KB 0644
ImageOps.py File 24.5 KB 0644
ImagePalette.py File 8.79 KB 0644
ImagePath.py File 371 B 0644
ImageQt.py File 6.67 KB 0644
ImageSequence.py File 2.15 KB 0644
ImageShow.py File 9.76 KB 0644
ImageStat.py File 5.2 KB 0644
ImageTransform.py File 3.79 KB 0644
ImageWin.py File 7.9 KB 0644
ImtImagePlugin.py File 2.6 KB 0644
IptcImagePlugin.py File 6.51 KB 0644
Jpeg2KImagePlugin.py File 13.56 KB 0644
JpegImagePlugin.py File 31.05 KB 0644
JpegPresets.py File 12.09 KB 0644
McIdasImagePlugin.py File 1.89 KB 0644
MicImagePlugin.py File 2.62 KB 0644
MpegImagePlugin.py File 2.05 KB 0644
MpoImagePlugin.py File 6.07 KB 0644
MspImagePlugin.py File 5.74 KB 0644
PSDraw.py File 6.75 KB 0644
PaletteFile.py File 1.18 KB 0644
PalmImagePlugin.py File 9.13 KB 0644
PcdImagePlugin.py File 1.55 KB 0644
PcfFontFile.py File 6.98 KB 0644
PcxImagePlugin.py File 6.1 KB 0644
PdfImagePlugin.py File 9.13 KB 0644
PdfParser.py File 37.09 KB 0644
PixarImagePlugin.py File 1.71 KB 0644
PngImagePlugin.py File 49.67 KB 0644
PpmImagePlugin.py File 12.06 KB 0644
PsdImagePlugin.py File 8.42 KB 0644
QoiImagePlugin.py File 4.08 KB 0644
SgiImagePlugin.py File 6.57 KB 0644
SpiderImagePlugin.py File 9.9 KB 0644
SunImagePlugin.py File 4.48 KB 0644
TarIO.py File 1.34 KB 0644
TgaImagePlugin.py File 6.82 KB 0644
TiffImagePlugin.py File 81.44 KB 0644
TiffTags.py File 16.68 KB 0644
WalImageFile.py File 5.57 KB 0644
WebPImagePlugin.py File 9.83 KB 0644
WmfImagePlugin.py File 5.02 KB 0644
XVThumbImagePlugin.py File 2.06 KB 0644
XbmImagePlugin.py File 2.6 KB 0644
XpmImagePlugin.py File 3.15 KB 0644
__init__.py File 1.96 KB 0644
__main__.py File 133 B 0644
_binary.py File 2.49 KB 0644
_deprecate.py File 1.89 KB 0644
_imaging.cpython-313-x86_64-linux-gnu.so File 750.65 KB 0644
_imaging.pyi File 868 B 0644
_imagingcms.cpython-313-x86_64-linux-gnu.so File 41.73 KB 0644
_imagingcms.pyi File 4.29 KB 0644
_imagingft.cpython-313-x86_64-linux-gnu.so File 45.63 KB 0644
_imagingft.pyi File 1.75 KB 0644
_imagingmath.cpython-313-x86_64-linux-gnu.so File 34.48 KB 0644
_imagingmath.pyi File 63 B 0644
_imagingmorph.cpython-313-x86_64-linux-gnu.so File 14.48 KB 0644
_imagingmorph.pyi File 63 B 0644
_imagingtk.pyi File 63 B 0644
_tkinter_finder.py File 540 B 0644
_typing.py File 1.21 KB 0644
_util.py File 635 B 0644
_version.py File 87 B 0644
_webp.cpython-313-x86_64-linux-gnu.so File 23.97 KB 0644
_webp.pyi File 63 B 0644
features.py File 11 KB 0644
py.typed File 0 B 0644
report.py File 100 B 0644
Filemanager