2010-07-31 06:52:47 +04:00
|
|
|
/*
|
|
|
|
* The Python Imaging Library
|
|
|
|
* $Id$
|
2013-07-01 02:42:19 +04:00
|
|
|
*
|
2010-07-31 06:52:47 +04:00
|
|
|
* declarations for the imaging core library
|
|
|
|
*
|
|
|
|
* Copyright (c) 1997-2005 by Secret Labs AB
|
|
|
|
* Copyright (c) 1995-2005 by Fredrik Lundh
|
|
|
|
*
|
|
|
|
* See the README file for information on usage and redistribution.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ImPlatform.h"
|
|
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef M_PI
|
2017-09-16 20:46:09 +03:00
|
|
|
#define M_PI 3.1415926535897932384626433832795
|
2010-07-31 06:52:47 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Image data organization:
|
|
|
|
*
|
2017-09-16 20:46:09 +03:00
|
|
|
* mode bytes byte order
|
2010-07-31 06:52:47 +04:00
|
|
|
* -------------------------------
|
2017-09-16 20:46:09 +03:00
|
|
|
* 1 1 1
|
|
|
|
* L 1 L
|
|
|
|
* P 1 P
|
2010-07-31 06:52:47 +04:00
|
|
|
* I 4 I (32-bit integer, native byte order)
|
|
|
|
* F 4 F (32-bit IEEE float, native byte order)
|
2017-09-16 20:46:09 +03:00
|
|
|
* RGB 4 R, G, B, -
|
|
|
|
* RGBA 4 R, G, B, A
|
|
|
|
* CMYK 4 C, M, Y, K
|
|
|
|
* YCbCr 4 Y, Cb, Cr, -
|
|
|
|
* Lab 4 L, a, b, -
|
2010-07-31 06:52:47 +04:00
|
|
|
*
|
|
|
|
* experimental modes (incomplete):
|
|
|
|
* LA 4 L, -, -, A
|
|
|
|
* PA 4 P, -, -, A
|
|
|
|
* I;16 2 I (16-bit integer, native byte order)
|
|
|
|
*
|
|
|
|
* "P" is an 8-bit palette mode, which should be mapped through the
|
|
|
|
* palette member to get an output image. Check palette->mode to
|
|
|
|
* find the corresponding "real" mode.
|
|
|
|
*
|
|
|
|
* For information on how to access Imaging objects from your own C
|
|
|
|
* extensions, see http://www.effbot.org/zone/pil-extending.htm
|
|
|
|
*/
|
|
|
|
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
#ifdef Py_GIL_DISABLED
|
2025-01-30 16:27:18 +03:00
|
|
|
#if defined(__cplusplus)
|
|
|
|
#define IMAGING_TLS thread_local
|
|
|
|
#elif defined(HAVE_THREAD_LOCAL)
|
|
|
|
#define IMAGING_TLS thread_local
|
|
|
|
#elif defined(HAVE__THREAD_LOCAL)
|
|
|
|
#define IMAGING_TLS _Thread_local
|
|
|
|
#elif defined(HAVE___THREAD)
|
|
|
|
#define IMAGING_TLS __thread
|
|
|
|
#elif defined(HAVE___DECLSPEC_THREAD_)
|
|
|
|
#define IMAGING_TLS __declspec(thread)
|
|
|
|
#endif
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
#endif
|
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
/* Handles */
|
|
|
|
|
|
|
|
typedef struct ImagingMemoryInstance *Imaging;
|
|
|
|
|
|
|
|
typedef struct ImagingAccessInstance *ImagingAccess;
|
|
|
|
typedef struct ImagingHistogramInstance *ImagingHistogram;
|
|
|
|
typedef struct ImagingOutlineInstance *ImagingOutline;
|
|
|
|
typedef struct ImagingPaletteInstance *ImagingPalette;
|
|
|
|
|
2024-10-07 11:51:44 +03:00
|
|
|
/* handle magics (used with PyCapsule). */
|
2024-09-02 01:19:44 +03:00
|
|
|
#define IMAGING_MAGIC "Pillow Imaging"
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* pixel types */
|
|
|
|
#define IMAGING_TYPE_UINT8 0
|
|
|
|
#define IMAGING_TYPE_INT32 1
|
|
|
|
#define IMAGING_TYPE_FLOAT32 2
|
|
|
|
#define IMAGING_TYPE_SPECIAL 3 /* check mode for details */
|
|
|
|
|
2013-03-15 03:36:51 +04:00
|
|
|
#define IMAGING_MODE_LENGTH \
|
|
|
|
6 + 1 /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "BGR;xy") */
|
|
|
|
|
2017-09-18 22:41:28 +03:00
|
|
|
typedef struct {
|
|
|
|
char *ptr;
|
|
|
|
int size;
|
|
|
|
} ImagingMemoryBlock;
|
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
struct ImagingMemoryInstance {
|
|
|
|
/* Format */
|
2017-09-16 20:46:09 +03:00
|
|
|
char mode[IMAGING_MODE_LENGTH]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK",
|
|
|
|
"YCbCr", "BGR;xy") */
|
|
|
|
int type; /* Data type (IMAGING_TYPE_*) */
|
|
|
|
int depth; /* Depth (ignored in this version) */
|
|
|
|
int bands; /* Number of bands (1, 2, 3, or 4) */
|
|
|
|
int xsize; /* Image dimension. */
|
2010-07-31 06:52:47 +04:00
|
|
|
int ysize;
|
|
|
|
|
|
|
|
/* Colour palette (for "P" images only) */
|
|
|
|
ImagingPalette palette;
|
|
|
|
|
|
|
|
/* Data pointers */
|
2017-09-16 20:46:09 +03:00
|
|
|
UINT8 **image8; /* Set for 8-bit images (pixelsize=1). */
|
|
|
|
INT32 **image32; /* Set for 32-bit images (pixelsize=4). */
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* Internals */
|
2017-09-16 20:46:09 +03:00
|
|
|
char **image; /* Actual raster data. */
|
|
|
|
char *block; /* Set if data is allocated in a single block. */
|
2017-09-18 22:41:28 +03:00
|
|
|
ImagingMemoryBlock *blocks; /* Memory blocks for pixel storage */
|
2010-07-31 06:52:47 +04:00
|
|
|
|
2017-09-16 20:46:09 +03:00
|
|
|
int pixelsize; /* Size of a pixel, in bytes (1, 2 or 4) */
|
|
|
|
int linesize; /* Size of a line, in bytes (xsize * pixelsize) */
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* Virtual methods */
|
|
|
|
void (*destroy)(Imaging im);
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
|
|
|
|
#ifdef IMAGING_TLS
|
|
|
|
int arenaindex; /* Index of the arena this image is associated with. */
|
|
|
|
#endif
|
2010-07-31 06:52:47 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#define IMAGING_PIXEL_1(im, x, y) ((im)->image8[(y)][(x)])
|
|
|
|
#define IMAGING_PIXEL_L(im, x, y) ((im)->image8[(y)][(x)])
|
2024-04-25 15:51:20 +03:00
|
|
|
#define IMAGING_PIXEL_LA(im, x, y) ((im)->image[(y)][(x) * 4])
|
2010-07-31 06:52:47 +04:00
|
|
|
#define IMAGING_PIXEL_P(im, x, y) ((im)->image8[(y)][(x)])
|
2024-04-25 15:51:20 +03:00
|
|
|
#define IMAGING_PIXEL_PA(im, x, y) ((im)->image[(y)][(x) * 4])
|
2010-07-31 06:52:47 +04:00
|
|
|
#define IMAGING_PIXEL_I(im, x, y) ((im)->image32[(y)][(x)])
|
|
|
|
#define IMAGING_PIXEL_F(im, x, y) (((FLOAT32 *)(im)->image32[y])[x])
|
2024-04-25 15:51:20 +03:00
|
|
|
#define IMAGING_PIXEL_RGB(im, x, y) ((im)->image[(y)][(x) * 4])
|
|
|
|
#define IMAGING_PIXEL_RGBA(im, x, y) ((im)->image[(y)][(x) * 4])
|
|
|
|
#define IMAGING_PIXEL_CMYK(im, x, y) ((im)->image[(y)][(x) * 4])
|
|
|
|
#define IMAGING_PIXEL_YCbCr(im, x, y) ((im)->image[(y)][(x) * 4])
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
#define IMAGING_PIXEL_UINT8(im, x, y) ((im)->image8[(y)][(x)])
|
|
|
|
#define IMAGING_PIXEL_INT32(im, x, y) ((im)->image32[(y)][(x)])
|
|
|
|
#define IMAGING_PIXEL_FLOAT32(im, x, y) (((FLOAT32 *)(im)->image32[y])[x])
|
|
|
|
|
|
|
|
struct ImagingAccessInstance {
|
|
|
|
const char *mode;
|
|
|
|
void (*get_pixel)(Imaging im, int x, int y, void *pixel);
|
|
|
|
void (*put_pixel)(Imaging im, int x, int y, const void *pixel);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ImagingHistogramInstance {
|
|
|
|
/* Format */
|
2017-09-16 20:46:09 +03:00
|
|
|
char mode[IMAGING_MODE_LENGTH]; /* Band names (of corresponding source image) */
|
|
|
|
int bands; /* Number of bands (1, 3, or 4) */
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* Data */
|
2017-09-16 20:46:09 +03:00
|
|
|
long *histogram; /* Histogram (bands*256 longs) */
|
2010-07-31 06:52:47 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ImagingPaletteInstance {
|
|
|
|
/* Format */
|
2017-09-16 20:46:09 +03:00
|
|
|
char mode[IMAGING_MODE_LENGTH]; /* Band names */
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* Data */
|
2022-02-16 01:56:13 +03:00
|
|
|
int size;
|
2010-07-31 06:52:47 +04:00
|
|
|
UINT8 palette[1024]; /* Palette data (same format as image data) */
|
|
|
|
|
2017-09-16 20:46:09 +03:00
|
|
|
INT16 *cache; /* Palette cache (used for predefined palettes) */
|
|
|
|
int keep_cache; /* This palette will be reused; keep cache */
|
2010-07-31 06:52:47 +04:00
|
|
|
};
|
|
|
|
|
2017-09-17 21:31:50 +03:00
|
|
|
typedef struct ImagingMemoryArena {
|
2017-09-23 04:15:19 +03:00
|
|
|
int alignment; /* Alignment in memory of each line of an image */
|
2017-09-30 15:03:28 +03:00
|
|
|
int block_size; /* Preferred block size, bytes */
|
2017-09-23 04:15:19 +03:00
|
|
|
int blocks_max; /* Maximum number of cached blocks */
|
2017-09-30 15:03:28 +03:00
|
|
|
int blocks_cached; /* Current number of blocks not associated with images */
|
|
|
|
ImagingMemoryBlock *blocks_pool;
|
2017-09-23 04:15:19 +03:00
|
|
|
int stats_new_count; /* Number of new allocated images */
|
|
|
|
int stats_allocated_blocks; /* Number of allocated blocks */
|
2017-09-30 15:03:28 +03:00
|
|
|
int stats_reused_blocks; /* Number of blocks which were retrieved from a pool */
|
|
|
|
int stats_reallocated_blocks; /* Number of blocks which were actually reallocated
|
|
|
|
after retrieving */
|
2017-09-23 04:15:19 +03:00
|
|
|
int stats_freed_blocks; /* Number of freed blocks */
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
#ifdef IMAGING_TLS
|
|
|
|
int index; /* Index of the arena in the global array. */
|
|
|
|
#endif
|
2024-07-16 11:13:26 +03:00
|
|
|
#ifdef Py_GIL_DISABLED
|
|
|
|
PyMutex mutex;
|
|
|
|
#endif
|
2024-04-25 15:51:20 +03:00
|
|
|
} *ImagingMemoryArena;
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* Objects */
|
|
|
|
/* ------- */
|
|
|
|
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
#ifdef IMAGING_TLS
|
|
|
|
/* In this case we both do not have the GIL and have thread-local storage, so we
|
|
|
|
* will allocate a set of arenas and associated them with threads one at a time.
|
|
|
|
*/
|
|
|
|
#define IMAGING_ARENAS_COUNT 8
|
|
|
|
extern struct ImagingMemoryArena ImagingArenas[IMAGING_ARENAS_COUNT];
|
|
|
|
|
|
|
|
/* Provide a macro that loops through each arena that has been
|
|
|
|
* statically-allocated. This is necessary to properly handle stats.
|
|
|
|
*/
|
|
|
|
#define IMAGING_ARENAS_FOREACH(arena) \
|
|
|
|
for ((arena) = &ImagingArenas[0]; arena->block_size; ++(arena))
|
|
|
|
#else
|
|
|
|
/* In this case we either have the GIL or do not have thread-local storage, in
|
|
|
|
* which case we will only allocate a single arena.
|
|
|
|
*/
|
2017-09-17 21:31:50 +03:00
|
|
|
extern struct ImagingMemoryArena ImagingDefaultArena;
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
|
|
|
|
/* Provide a macro that loops through each arena that has been
|
|
|
|
* statically-allocated. In this case because there is only one, this is
|
|
|
|
* effectively a single block of code.
|
|
|
|
*/
|
|
|
|
#define IMAGING_ARENAS_FOREACH(arena) \
|
|
|
|
for ((arena) = &ImagingDefaultArena; (arena); (arena) = NULL)
|
|
|
|
#endif
|
|
|
|
|
2025-01-30 16:27:18 +03:00
|
|
|
ImagingMemoryArena
|
|
|
|
ImagingGetArena(void);
|
Reduce memory arena contention
Previously there was one memory arena for all threads, making it
the bottleneck for multi-threaded performance. As the number of
threads increased, the contention for the lock on the arena would
grow, causing other threads to wait to acquire it.
This commit makes it use 8 memory arenas, and round-robbins how
they are assigned to threads. Threads keep track of the index that
they should use into the arena array, assigned the first time the
arena is accessed on a given thread.
When an image is first created, it is allocated from an arena.
When the logic to have multiple arenas is enabled, it then keeps
track of the index on the image, so that when deleted it can be
returned to the correct arena.
Effectively this means that in single-threaded programs, this
should not really have an effect. We also do not do this logic if
the GIL is enabled, as it effectively acts as the lock on the
default arena for us.
As expected, this approach has no real noticable effect on regular
CPython. On free-threaded CPython, however, there is a massive
difference (measuring up to about 70%).
2025-01-24 22:14:33 +03:00
|
|
|
|
2017-09-18 01:41:39 +03:00
|
|
|
extern int
|
|
|
|
ImagingMemorySetBlocksMax(ImagingMemoryArena arena, int blocks_max);
|
2017-09-18 03:57:43 +03:00
|
|
|
extern void
|
|
|
|
ImagingMemoryClearCache(ImagingMemoryArena arena, int new_size);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingNew(const char *mode, int xsize, int ysize);
|
2017-08-06 01:50:55 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingNewDirty(const char *mode, int xsize, int ysize);
|
2017-08-06 20:08:07 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingNew2Dirty(const char *mode, Imaging imOut, Imaging imIn);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern void
|
|
|
|
ImagingDelete(Imaging im);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingNewBlock(const char *mode, int xsize, int ysize);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingNewPrologue(const char *mode, int xsize, int ysize);
|
|
|
|
extern Imaging
|
|
|
|
ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int structure_size);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2017-09-19 20:42:13 +03:00
|
|
|
extern void
|
|
|
|
ImagingCopyPalette(Imaging destination, Imaging source);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern void
|
|
|
|
ImagingHistogramDelete(ImagingHistogram histogram);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern void
|
|
|
|
ImagingAccessInit(void);
|
|
|
|
extern ImagingAccess
|
|
|
|
ImagingAccessNew(Imaging im);
|
|
|
|
extern void
|
|
|
|
_ImagingAccessDelete(Imaging im, ImagingAccess access);
|
|
|
|
#define ImagingAccessDelete(im, access) /* nop, for now */
|
|
|
|
|
|
|
|
extern ImagingPalette
|
|
|
|
ImagingPaletteNew(const char *mode);
|
|
|
|
extern ImagingPalette
|
|
|
|
ImagingPaletteNewBrowser(void);
|
|
|
|
extern ImagingPalette
|
|
|
|
ImagingPaletteDuplicate(ImagingPalette palette);
|
|
|
|
extern void
|
|
|
|
ImagingPaletteDelete(ImagingPalette palette);
|
|
|
|
|
|
|
|
extern int
|
|
|
|
ImagingPaletteCachePrepare(ImagingPalette palette);
|
|
|
|
extern void
|
|
|
|
ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b);
|
|
|
|
extern void
|
|
|
|
ImagingPaletteCacheDelete(ImagingPalette palette);
|
|
|
|
|
2017-09-16 20:46:09 +03:00
|
|
|
#define ImagingPaletteCache(p, r, g, b) \
|
2010-07-31 06:52:47 +04:00
|
|
|
p->cache[(r >> 2) + (g >> 2) * 64 + (b >> 2) * 64 * 64]
|
|
|
|
|
|
|
|
extern Imaging
|
|
|
|
ImagingQuantize(Imaging im, int colours, int mode, int kmeans);
|
|
|
|
|
|
|
|
/* Threading */
|
|
|
|
/* --------- */
|
|
|
|
|
|
|
|
typedef void *ImagingSectionCookie;
|
|
|
|
|
|
|
|
extern void
|
|
|
|
ImagingSectionEnter(ImagingSectionCookie *cookie);
|
|
|
|
extern void
|
|
|
|
ImagingSectionLeave(ImagingSectionCookie *cookie);
|
|
|
|
|
|
|
|
/* Exceptions */
|
|
|
|
/* ---------- */
|
|
|
|
|
2020-04-07 09:58:21 +03:00
|
|
|
extern void *
|
|
|
|
ImagingError_OSError(void);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern void *
|
|
|
|
ImagingError_MemoryError(void);
|
|
|
|
extern void *
|
|
|
|
ImagingError_ModeError(void); /* maps to ValueError by default */
|
|
|
|
extern void *
|
|
|
|
ImagingError_Mismatch(void); /* maps to ValueError by default */
|
|
|
|
extern void *
|
|
|
|
ImagingError_ValueError(const char *message);
|
|
|
|
extern void
|
|
|
|
ImagingError_Clear(void);
|
|
|
|
|
|
|
|
/* Transform callbacks */
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
/* standard transforms */
|
|
|
|
#define IMAGING_TRANSFORM_AFFINE 0
|
|
|
|
#define IMAGING_TRANSFORM_PERSPECTIVE 2
|
|
|
|
#define IMAGING_TRANSFORM_QUAD 3
|
|
|
|
|
|
|
|
/* standard filters */
|
|
|
|
#define IMAGING_TRANSFORM_NEAREST 0
|
2016-06-16 20:04:20 +03:00
|
|
|
#define IMAGING_TRANSFORM_BOX 4
|
2010-07-31 06:52:47 +04:00
|
|
|
#define IMAGING_TRANSFORM_BILINEAR 2
|
2016-06-16 20:04:20 +03:00
|
|
|
#define IMAGING_TRANSFORM_HAMMING 5
|
2010-07-31 06:52:47 +04:00
|
|
|
#define IMAGING_TRANSFORM_BICUBIC 3
|
2016-06-16 20:04:20 +03:00
|
|
|
#define IMAGING_TRANSFORM_LANCZOS 1
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
typedef int (*ImagingTransformMap)(double *X, double *Y, int x, int y, void *data);
|
|
|
|
typedef int (*ImagingTransformFilter)(void *out, Imaging im, double x, double y);
|
|
|
|
|
|
|
|
/* Image Manipulation Methods */
|
|
|
|
/* -------------------------- */
|
|
|
|
|
2012-12-04 19:44:26 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingAlphaComposite(Imaging imIn1, Imaging imIn2);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha);
|
|
|
|
extern Imaging
|
|
|
|
ImagingCopy(Imaging im);
|
|
|
|
extern Imaging
|
|
|
|
ImagingConvert(Imaging im, const char *mode, ImagingPalette palette, int dither);
|
|
|
|
extern Imaging
|
|
|
|
ImagingConvertInPlace(Imaging im, const char *mode);
|
|
|
|
extern Imaging
|
|
|
|
ImagingConvertMatrix(Imaging im, const char *mode, float m[]);
|
2013-11-27 00:24:19 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingConvertTransparent(Imaging im, const char *mode, int r, int g, int b);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingCrop(Imaging im, int x0, int y0, int x1, int y1);
|
|
|
|
extern Imaging
|
2023-06-10 08:57:05 +03:00
|
|
|
ImagingExpand(Imaging im, int x, int y);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingFill(Imaging im, const void *ink);
|
|
|
|
extern int
|
|
|
|
ImagingFill2(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging into, const void *ink, Imaging mask, int x0, int y0, int x1, int y1
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingFillBand(Imaging im, int band, int color);
|
|
|
|
extern Imaging
|
|
|
|
ImagingFillLinearGradient(const char *mode);
|
|
|
|
extern Imaging
|
|
|
|
ImagingFillRadialGradient(const char *mode);
|
|
|
|
extern Imaging
|
|
|
|
ImagingFilter(Imaging im, int xsize, int ysize, const FLOAT32 *kernel, FLOAT32 offset);
|
|
|
|
extern Imaging
|
|
|
|
ImagingFlipLeftRight(Imaging imOut, Imaging imIn);
|
|
|
|
extern Imaging
|
|
|
|
ImagingFlipTopBottom(Imaging imOut, Imaging imIn);
|
2014-10-25 17:16:14 +04:00
|
|
|
extern Imaging
|
2024-04-25 15:51:20 +03:00
|
|
|
ImagingGaussianBlur(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging imOut, Imaging imIn, float xradius, float yradius, int passes
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingGetBand(Imaging im, int band);
|
2017-08-12 19:08:07 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingMerge(const char *mode, Imaging bands[4]);
|
2017-08-12 03:43:19 +03:00
|
|
|
extern int
|
|
|
|
ImagingSplit(Imaging im, Imaging bands[4]);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
2023-04-29 12:11:02 +03:00
|
|
|
ImagingGetBBox(Imaging im, int bbox[4], int alpha_only);
|
2010-07-31 06:52:47 +04:00
|
|
|
typedef struct {
|
|
|
|
int x, y;
|
|
|
|
INT32 count;
|
|
|
|
INT32 pixel;
|
|
|
|
} ImagingColorItem;
|
|
|
|
extern ImagingColorItem *
|
|
|
|
ImagingGetColors(Imaging im, int maxcolors, int *colors);
|
|
|
|
extern int
|
|
|
|
ImagingGetExtrema(Imaging im, void *extrema);
|
|
|
|
extern int
|
|
|
|
ImagingGetProjection(Imaging im, UINT8 *xproj, UINT8 *yproj);
|
|
|
|
extern ImagingHistogram
|
|
|
|
ImagingGetHistogram(Imaging im, Imaging mask, void *extrema);
|
|
|
|
extern Imaging
|
|
|
|
ImagingModeFilter(Imaging im, int size);
|
|
|
|
extern Imaging
|
|
|
|
ImagingNegative(Imaging im);
|
|
|
|
extern Imaging
|
|
|
|
ImagingOffset(Imaging im, int xoffset, int yoffset);
|
|
|
|
extern int
|
|
|
|
ImagingPaste(Imaging into, Imaging im, Imaging mask, int x0, int y0, int x1, int y1);
|
|
|
|
extern Imaging
|
|
|
|
ImagingPoint(Imaging im, const char *tablemode, const void *table);
|
|
|
|
extern Imaging
|
|
|
|
ImagingPointTransform(Imaging imIn, double scale, double offset);
|
|
|
|
extern Imaging
|
|
|
|
ImagingPutBand(Imaging im, Imaging imIn, int band);
|
|
|
|
extern Imaging
|
|
|
|
ImagingRankFilter(Imaging im, int size, int rank);
|
|
|
|
extern Imaging
|
|
|
|
ImagingRotate90(Imaging imOut, Imaging imIn);
|
|
|
|
extern Imaging
|
|
|
|
ImagingRotate180(Imaging imOut, Imaging imIn);
|
|
|
|
extern Imaging
|
|
|
|
ImagingRotate270(Imaging imOut, Imaging imIn);
|
2014-10-25 04:12:24 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingTranspose(Imaging imOut, Imaging imIn);
|
2017-09-11 22:58:22 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingTransverse(Imaging imOut, Imaging imIn);
|
2017-09-11 01:47:47 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]);
|
2019-12-02 04:32:08 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]);
|
2016-06-02 15:47:27 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingTransform(
|
|
|
|
Imaging imOut,
|
|
|
|
Imaging imIn,
|
|
|
|
int method,
|
|
|
|
int x0,
|
|
|
|
int y0,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
2021-06-10 12:01:12 +03:00
|
|
|
double a[8],
|
2016-06-02 15:47:27 +03:00
|
|
|
int filter,
|
2024-07-16 15:58:00 +03:00
|
|
|
int fill
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
2014-10-25 17:16:14 +04:00
|
|
|
ImagingUnsharpMask(Imaging imOut, Imaging im, float radius, int percent, int threshold);
|
2014-10-25 04:28:05 +04:00
|
|
|
extern Imaging
|
2023-08-12 05:09:20 +03:00
|
|
|
ImagingBoxBlur(Imaging imOut, Imaging imIn, float xradius, float yradius, int n);
|
2018-03-25 15:49:42 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingColorLUT3D_linear(
|
|
|
|
Imaging imOut,
|
|
|
|
Imaging imIn,
|
|
|
|
int table_channels,
|
|
|
|
int size1D,
|
|
|
|
int size2D,
|
|
|
|
int size3D,
|
2024-07-16 15:58:00 +03:00
|
|
|
INT16 *table
|
|
|
|
);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern Imaging
|
|
|
|
ImagingCopy2(Imaging imOut, Imaging imIn);
|
|
|
|
extern Imaging
|
|
|
|
ImagingConvert2(Imaging imOut, Imaging imIn);
|
|
|
|
|
|
|
|
/* Channel operations */
|
|
|
|
/* any mode, except "F" */
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopLighter(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopDarker(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopDifference(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopMultiply(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopScreen(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopAddModulo(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2);
|
2019-11-22 16:03:59 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingChopSoftLight(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopHardLight(Imaging imIn1, Imaging imIn2);
|
2019-11-22 16:30:43 +03:00
|
|
|
extern Imaging
|
|
|
|
ImagingOverlay(Imaging imIn1, Imaging imIn2);
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* "1" images only */
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopAnd(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopOr(Imaging imIn1, Imaging imIn2);
|
|
|
|
extern Imaging
|
|
|
|
ImagingChopXor(Imaging imIn1, Imaging imIn2);
|
|
|
|
|
|
|
|
/* Graphics */
|
|
|
|
extern int
|
|
|
|
ImagingDrawArc(
|
|
|
|
Imaging im,
|
|
|
|
int x0,
|
|
|
|
int y0,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
2018-04-13 08:37:54 +03:00
|
|
|
float start,
|
|
|
|
float end,
|
|
|
|
const void *ink,
|
|
|
|
int width,
|
2024-07-16 15:58:00 +03:00
|
|
|
int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, const void *ink, int op);
|
|
|
|
extern int
|
|
|
|
ImagingDrawChord(
|
|
|
|
Imaging im,
|
|
|
|
int x0,
|
|
|
|
int y0,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
2015-12-08 16:28:52 +03:00
|
|
|
float start,
|
|
|
|
float end,
|
|
|
|
const void *ink,
|
|
|
|
int fill,
|
2018-04-13 08:37:54 +03:00
|
|
|
int width,
|
2024-07-16 15:58:00 +03:00
|
|
|
int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawEllipse(
|
|
|
|
Imaging im,
|
|
|
|
int x0,
|
|
|
|
int y0,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
2018-04-13 08:37:54 +03:00
|
|
|
const void *ink,
|
|
|
|
int fill,
|
|
|
|
int width,
|
2024-07-16 15:58:00 +03:00
|
|
|
int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, const void *ink, int op);
|
|
|
|
extern int
|
|
|
|
ImagingDrawWideLine(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, int x0, int y0, int x1, int y1, const void *ink, int width, int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawPieslice(
|
2015-12-08 16:28:52 +03:00
|
|
|
Imaging im,
|
|
|
|
int x0,
|
|
|
|
int y0,
|
|
|
|
int x1,
|
2021-01-03 06:17:51 +03:00
|
|
|
int y1,
|
2015-12-08 16:28:52 +03:00
|
|
|
float start,
|
|
|
|
float end,
|
|
|
|
const void *ink,
|
|
|
|
int fill,
|
2018-04-13 08:37:54 +03:00
|
|
|
int width,
|
2024-07-16 15:58:00 +03:00
|
|
|
int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawPoint(Imaging im, int x, int y, const void *ink, int op);
|
|
|
|
extern int
|
2024-04-25 15:51:20 +03:00
|
|
|
ImagingDrawPolygon(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, int points, int *xy, const void *ink, int fill, int width, int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawRectangle(
|
|
|
|
Imaging im,
|
|
|
|
int x0,
|
|
|
|
int y0,
|
|
|
|
int x1,
|
|
|
|
int y1,
|
2018-04-12 18:15:27 +03:00
|
|
|
const void *ink,
|
|
|
|
int fill,
|
|
|
|
int width,
|
2024-07-16 15:58:00 +03:00
|
|
|
int op
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
|
|
|
|
/* Level 2 graphics (WORK IN PROGRESS) */
|
|
|
|
extern ImagingOutline
|
|
|
|
ImagingOutlineNew(void);
|
|
|
|
extern void
|
|
|
|
ImagingOutlineDelete(ImagingOutline outline);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingDrawOutline(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingOutline outline, const void *ink, int fill, int op
|
|
|
|
);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingOutlineMove(ImagingOutline outline, float x, float y);
|
|
|
|
extern int
|
|
|
|
ImagingOutlineLine(ImagingOutline outline, float x, float y);
|
|
|
|
extern int
|
|
|
|
ImagingOutlineCurve(
|
2024-07-16 15:58:00 +03:00
|
|
|
ImagingOutline outline, float x1, float y1, float x2, float y2, float x3, float y3
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingOutlineTransform(ImagingOutline outline, double a[6]);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingOutlineClose(ImagingOutline outline);
|
|
|
|
|
|
|
|
/* Special effects */
|
|
|
|
extern Imaging
|
|
|
|
ImagingEffectSpread(Imaging imIn, int distance);
|
|
|
|
extern Imaging
|
|
|
|
ImagingEffectNoise(int xsize, int ysize, float sigma);
|
|
|
|
extern Imaging
|
|
|
|
ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality);
|
|
|
|
|
|
|
|
/* File I/O */
|
|
|
|
/* -------- */
|
|
|
|
|
|
|
|
/* Built-in drivers */
|
|
|
|
extern Imaging
|
|
|
|
ImagingOpenPPM(const char *filename);
|
|
|
|
extern int
|
|
|
|
ImagingSavePPM(Imaging im, const char *filename);
|
|
|
|
|
|
|
|
/* Codecs */
|
|
|
|
typedef struct ImagingCodecStateInstance *ImagingCodecState;
|
|
|
|
typedef int (*ImagingCodec)(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes
|
|
|
|
);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2016-08-11 02:16:32 +03:00
|
|
|
extern int
|
|
|
|
ImagingBcnDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingBitDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
2019-04-15 10:33:28 +03:00
|
|
|
extern int
|
2010-07-31 06:52:47 +04:00
|
|
|
ImagingEpsEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2017-09-16 20:46:09 +03:00
|
|
|
extern int
|
2010-07-31 06:52:47 +04:00
|
|
|
ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingGifDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2017-09-16 20:46:09 +03:00
|
|
|
extern int
|
2010-07-31 06:52:47 +04:00
|
|
|
ImagingHexDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
2017-09-16 20:46:09 +03:00
|
|
|
#ifdef HAVE_LIBJPEG
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
2013-05-16 08:16:37 +04:00
|
|
|
extern int
|
|
|
|
ImagingJpegDecodeCleanup(ImagingCodecState state);
|
2017-08-11 04:07:54 +03:00
|
|
|
extern int
|
|
|
|
ImagingJpegUseJCSExtensions(void);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
|
|
|
#endif
|
2014-03-12 20:25:59 +04:00
|
|
|
#ifdef HAVE_OPENJPEG
|
|
|
|
extern int
|
|
|
|
ImagingJpeg2KDecode(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
|
|
|
|
);
|
2014-03-12 20:25:59 +04:00
|
|
|
extern int
|
|
|
|
ImagingJpeg2KDecodeCleanup(ImagingCodecState state);
|
2014-03-13 22:27:16 +04:00
|
|
|
extern int
|
|
|
|
ImagingJpeg2KEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
|
|
|
extern int
|
|
|
|
ImagingJpeg2KEncodeCleanup(ImagingCodecState state);
|
2014-03-12 20:25:59 +04:00
|
|
|
#endif
|
2017-09-16 20:46:09 +03:00
|
|
|
#ifdef HAVE_LIBTIFF
|
2013-03-09 07:51:59 +04:00
|
|
|
extern int
|
|
|
|
ImagingLibTiffDecode(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
|
|
|
|
);
|
2013-03-09 07:51:59 +04:00
|
|
|
extern int
|
|
|
|
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
|
|
|
#endif
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingPackbitsDecode(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingPcdDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingPcxEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2017-09-16 20:46:09 +03:00
|
|
|
extern int
|
2010-07-31 06:52:47 +04:00
|
|
|
ImagingRawDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2017-09-16 20:46:09 +03:00
|
|
|
extern int
|
2017-07-22 10:34:06 +03:00
|
|
|
ImagingSgiRleDecode(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
|
|
|
|
);
|
2019-04-15 10:33:28 +03:00
|
|
|
extern int
|
2010-07-31 06:52:47 +04:00
|
|
|
ImagingSunRleDecode(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
|
|
|
|
);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingTgaRleDecode(
|
2024-07-16 15:58:00 +03:00
|
|
|
Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes
|
|
|
|
);
|
2018-06-15 23:01:06 +03:00
|
|
|
extern int
|
|
|
|
ImagingTgaRleEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingXbmDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
ImagingXbmEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2017-09-16 20:46:09 +03:00
|
|
|
#ifdef HAVE_LIBZ
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingZipDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
2017-05-23 17:26:13 +03:00
|
|
|
extern int
|
|
|
|
ImagingZipDecodeCleanup(ImagingCodecState state);
|
2010-07-31 06:52:47 +04:00
|
|
|
extern int
|
|
|
|
ImagingZipEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
2016-04-15 18:48:57 +03:00
|
|
|
extern int
|
|
|
|
ImagingZipEncodeCleanup(ImagingCodecState state);
|
2010-07-31 06:52:47 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef void (*ImagingShuffler)(UINT8 *out, const UINT8 *in, int pixels);
|
|
|
|
|
|
|
|
/* Public shufflers */
|
|
|
|
extern void
|
|
|
|
ImagingPackBGR(UINT8 *out, const UINT8 *in, int pixels);
|
|
|
|
extern void
|
|
|
|
ImagingUnpackYCC(UINT8 *out, const UINT8 *in, int pixels);
|
|
|
|
extern void
|
|
|
|
ImagingUnpackYCCA(UINT8 *out, const UINT8 *in, int pixels);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern void
|
|
|
|
ImagingConvertRGB2YCbCr(UINT8 *out, const UINT8 *in, int pixels);
|
|
|
|
extern void
|
|
|
|
ImagingConvertYCbCr2RGB(UINT8 *out, const UINT8 *in, int pixels);
|
2021-01-03 06:17:51 +03:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
extern ImagingShuffler
|
|
|
|
ImagingFindUnpacker(const char *mode, const char *rawmode, int *bits_out);
|
|
|
|
extern ImagingShuffler
|
|
|
|
ImagingFindPacker(const char *mode, const char *rawmode, int *bits_out);
|
|
|
|
|
|
|
|
struct ImagingCodecStateInstance {
|
|
|
|
int count;
|
|
|
|
int state;
|
|
|
|
int errcode;
|
|
|
|
int x, y;
|
|
|
|
int ystep;
|
|
|
|
int xsize, ysize, xoff, yoff;
|
|
|
|
ImagingShuffler shuffle;
|
|
|
|
int bits, bytes;
|
|
|
|
UINT8 *buffer;
|
|
|
|
void *context;
|
2016-05-29 01:07:36 +03:00
|
|
|
PyObject *fd;
|
2010-07-31 06:52:47 +04:00
|
|
|
};
|
|
|
|
|
2016-06-17 13:03:21 +03:00
|
|
|
/* Codec read/write python fd */
|
2016-05-29 01:07:36 +03:00
|
|
|
extern Py_ssize_t
|
|
|
|
_imaging_read_pyFd(PyObject *fd, char *dest, Py_ssize_t bytes);
|
|
|
|
extern Py_ssize_t
|
|
|
|
_imaging_write_pyFd(PyObject *fd, char *src, Py_ssize_t bytes);
|
|
|
|
extern int
|
|
|
|
_imaging_seek_pyFd(PyObject *fd, Py_ssize_t offset, int whence);
|
|
|
|
extern Py_ssize_t
|
|
|
|
_imaging_tell_pyFd(PyObject *fd);
|
2014-03-12 20:25:59 +04:00
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
/* Errcodes */
|
2017-09-16 20:46:09 +03:00
|
|
|
#define IMAGING_CODEC_END 1
|
|
|
|
#define IMAGING_CODEC_OVERRUN -1
|
|
|
|
#define IMAGING_CODEC_BROKEN -2
|
|
|
|
#define IMAGING_CODEC_UNKNOWN -3
|
|
|
|
#define IMAGING_CODEC_CONFIG -8
|
|
|
|
#define IMAGING_CODEC_MEMORY -9
|
2017-08-19 15:30:41 +03:00
|
|
|
|
|
|
|
#include "ImagingUtils.h"
|
2018-03-26 18:02:08 +03:00
|
|
|
extern UINT8 *clip8_lookups;
|
|
|
|
|
2024-07-16 11:13:26 +03:00
|
|
|
/* Mutex lock/unlock helpers */
|
|
|
|
#ifdef Py_GIL_DISABLED
|
|
|
|
#define MUTEX_LOCK(m) PyMutex_Lock(m)
|
|
|
|
#define MUTEX_UNLOCK(m) PyMutex_Unlock(m)
|
|
|
|
#else
|
|
|
|
#define MUTEX_LOCK(m)
|
|
|
|
#define MUTEX_UNLOCK(m)
|
|
|
|
#endif
|
|
|
|
|
2010-07-31 06:52:47 +04:00
|
|
|
#if defined(__cplusplus)
|
|
|
|
}
|
|
|
|
#endif
|