Exemple #1
0
def magick_raise(exc, force=False):
    """If the given `ExceptionInfo` pointer contains an exception, convert it
    to a Python one and throw it.

    Set `force` to True to throw a generic error even if the pointer doesn't
    seem to indicate an exception.  This is useful in cases where a function
    uses both exceptions and `NULL` returns, which are sadly all too common in
    ImageMagick.
    """
    if exc == ffi.NULL or exc.severity == lib.UndefinedException:
        if force:
            raise MysteryError
        return

    # TODO have more exception classes

    # An exception's description tends to be blank; the actual message
    # is in `reason`
    if exc.reason == ffi.NULL:
        message = b''
    else:
        message = ffi.string(exc.reason)

    severity_name = ffi.string(ffi.cast("ExceptionType", exc.severity))
    # severity_name is an enum name and thus a string, not bytes
    message = message + b'   ' + severity_name.encode('ascii')

    if exc.severity < lib.ErrorException:
        # This is a warning, so do a warning
        cls = magick_exception_map.get(exc.severity, GenericMagickWarning)
        warnings.warn(cls(message))
    else:
        # ERROR ERROR
        cls = magick_exception_map.get(exc.severity, GenericMagickError)
        raise cls(message)
Exemple #2
0
def _get_formats():
    formats = dict()

    num_formats = ffi.new("size_t *")

    # Snag the list of known supported image formats
    with magick_try() as exc:
        magick_infos = ffi.gc(lib.GetMagickInfoList(b"*", num_formats, exc.ptr), lib.RelinquishMagickMemory)
        # Sometimes this call can generate an exception (such as a module not
        # being loadable) but then succeed anyway and return a useful value, in
        # which case we want to ignore the exception
        if magick_infos != ffi.NULL:
            exc.clear()

    for i in range(num_formats[0]):
        name = ffi.string(magick_infos[i].name).decode("latin-1")
        formats[name.lower()] = ImageFormat(
            name=name,
            description=ffi.string(magick_infos[i].description).decode("latin-1"),
            can_read=magick_infos[i].decoder != ffi.NULL,
            can_write=magick_infos[i].encoder != ffi.NULL,
            supports_frames=magick_infos[i].adjoin != 0,
        )

    return formats
Exemple #3
0
def _get_formats():
    formats = dict()
    formats_by_mime = dict()

    num_formats = ffi.new("size_t *")

    # Snag the list of known supported image formats
    with magick_try() as exc:
        magick_infos = ffi.gc(
            lib.GetMagickInfoList(b"*", num_formats, exc.ptr),
            lib.RelinquishMagickMemory)

    for i in range(num_formats[0]):
        imageformat = ImageFormat(
            name=ffi.string(magick_infos[i].name).decode('latin-1'),
            description=ffi.string(magick_infos[i].description).decode('latin-1'),
            can_read=magick_infos[i].decoder != ffi.NULL,
            can_write=magick_infos[i].encoder != ffi.NULL,
            supports_frames=magick_infos[i].adjoin != 0,
            mime_type=ffi.string(magick_infos[i].mime_type).decode('ascii') if magick_infos[i].mime_type else None,
        )
        formats[imageformat.name.lower()] = imageformat
        formats_by_mime[imageformat.mime_type] = imageformat

    return formats, formats_by_mime
Exemple #4
0
def magick_raise(exc, force=False):
    """If the given `ExceptionInfo` pointer contains an exception, convert it
    to a Python one and throw it.

    Set `force` to True to throw a generic error even if the pointer doesn't
    seem to indicate an exception.  This is useful in cases where a function
    uses both exceptions and `NULL` returns, which are sadly all too common in
    ImageMagick.
    """
    if exc == ffi.NULL or exc.severity == lib.UndefinedException:
        if force:
            raise MysteryError
        return

    # TODO have more exception classes

    # An exception's description tends to be blank; the actual message
    # is in `reason`
    if exc.reason == ffi.NULL:
        message = b''
    else:
        message = ffi.string(exc.reason)

    severity_name = ffi.string(ffi.cast("ExceptionType", exc.severity))
    # severity_name is an enum name and thus a string, not bytes
    message = message + b'   ' + severity_name.encode('ascii')

    if exc.severity < lib.ErrorException:
        # This is a warning, so do a warning
        cls = magick_exception_map.get(exc.severity, GenericMagickWarning)
        warnings.warn(cls(message))
    else:
        # ERROR ERROR
        cls = magick_exception_map.get(exc.severity, GenericMagickError)
        raise cls(message)
Exemple #5
0
    def raw_properties(self):
        # TODO may need SyncImageProfiles() somewhere?  it updates EXIF res and
        # orientation
        ret = {}

        # This tricks IM into actually reading the EXIF properties...
        lib.GetImageProperty(self._stack, "exif:*")

        lib.ResetImagePropertyIterator(self._stack)
        while True:
            # XXX this only examines the top image uhoh.  do we care?  what
            # happens if i load a GIF; what does each frame say?  what happens
            # if i have multiple images with different props and save as one
            # image?
            prop = lib.GetNextImageProperty(self._stack)
            if prop == ffi.NULL:
                break

            ret[ffi.string(prop)] = ffi.string(lib.GetImageProperty(self._stack, prop))

        return ret
Exemple #6
0
    def raw_properties(self):
        # TODO may need SyncImageProfiles() somewhere?  it updates EXIF res and
        # orientation
        ret = {}

        # This tricks IM into actually reading the EXIF properties...
        lib.GetImageProperty(self._stack, "exif:*")

        lib.ResetImagePropertyIterator(self._stack)
        while True:
            # XXX this only examines the top image uhoh.  do we care?  what
            # happens if i load a GIF; what does each frame say?  what happens
            # if i have multiple images with different props and save as one
            # image?
            prop = lib.GetNextImageProperty(self._stack)
            if prop == ffi.NULL:
                break

            ret[ffi.string(prop)] = ffi.string(
                lib.GetImageProperty(self._stack, prop))

        return ret
Exemple #7
0
def _get_formats():
    formats = dict()

    num_formats = ffi.new("size_t *")

    # Snag the list of known supported image formats
    with magick_try() as exc:
        magick_infos = ffi.gc(
            lib.GetMagickInfoList(b"*", num_formats, exc.ptr),
            lib.RelinquishMagickMemory)

    for i in range(num_formats[0]):
        name = ffi.string(magick_infos[i].name).decode('latin-1')
        formats[name.lower()] = ImageFormat(
            name=name,
            description=ffi.string(
                magick_infos[i].description).decode('latin-1'),
            can_read=magick_infos[i].decoder != ffi.NULL,
            can_write=magick_infos[i].encoder != ffi.NULL,
            supports_frames=magick_infos[i].adjoin != 0,
        )

    return formats
Exemple #8
0
 def original_format(self):
     return ffi.string(self._stack.magick)
Exemple #9
0
"""Various information about the underlying ImageMagick library and the
features it supports.

Deliberately not named ``features`` to emphasize that everything herein is
highly specific to ImageMagick and completely out of the library's hands.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from collections import namedtuple

from sanpera._api import ffi, lib
from sanpera.exception import magick_try

FEATURES = frozenset(ffi.string(lib.GetMagickFeatures()).decode('ascii').split(' '))
HAS_OPENMP = 'OpenMP' in FEATURES
HAS_OPENCL = 'OpenCL' in FEATURES
HAS_HDRI = 'HDRI' in FEATURES


# Version number is given as hex; version A.B.C is 0xABC
_out = ffi.new("size_t *")
lib.GetMagickVersion(_out)
VERSION = (
    (_out[0] & 0xf00) >> 8,
    (_out[0] & 0x0f0) >> 4,
    (_out[0] & 0x00f) >> 0,
)
del _out
Exemple #10
0
"""Various information about the underlying ImageMagick library and the
features it supports.

Deliberately not named ``features`` to emphasize that everything herein is
highly specific to ImageMagick and completely out of the library's hands.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from collections import namedtuple

from sanpera._api import ffi, lib
from sanpera.exception import magick_try

FEATURES = frozenset(ffi.string(lib.GetMagickFeatures()).decode("ascii").split(" "))
HAS_OPENMP = "OpenMP" in FEATURES
HAS_OPENCL = "OpenCL" in FEATURES
HAS_HDRI = "HDRI" in FEATURES


# Version number is given as hex; version A.B.C is 0xABC
_out = ffi.new("size_t *")
lib.GetMagickVersion(_out)
VERSION = ((_out[0] & 0xF00) >> 8, (_out[0] & 0x0F0) >> 4, (_out[0] & 0x00F) >> 0)
del _out


ImageFormat = namedtuple("ImageFormat", ["name", "description", "can_read", "can_write", "supports_frames"])

Exemple #11
0
 def original_format(self):
     return ffi.string(self._stack.magick)
Exemple #12
0
features it supports.

Deliberately not named ``features`` to emphasize that everything herein is
highly specific to ImageMagick and completely out of the library's hands.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from collections import namedtuple

from sanpera._api import ffi, lib
from sanpera.exception import magick_try

FEATURES = frozenset(
    ffi.string(lib.GetMagickFeatures()).decode('ascii').split(' '))
HAS_OPENMP = 'OpenMP' in FEATURES
HAS_OPENCL = 'OpenCL' in FEATURES
HAS_HDRI = 'HDRI' in FEATURES

# Version number is given as hex; version A.B.C is 0xABC
_out = ffi.new("size_t *")
lib.GetMagickVersion(_out)
VERSION = (
    (_out[0] & 0xf00) >> 8,
    (_out[0] & 0x0f0) >> 4,
    (_out[0] & 0x00f) >> 0,
)
del _out

ImageFormat = namedtuple(