Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 39 additions & 39 deletions src/Tk/tkImaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,29 +239,29 @@ TkImaging_Init(Tcl_Interp *interp) {

#define TKINTER_PKG "tkinter"

/**
* Load function `func_name` from `lib_handle`.
* Set Python exception if we can't find `func_name` in `lib_handle`.
*
* @return Function pointer or NULL if not present, with Python exception set.
*/
FARPROC
_dfunc(HMODULE lib_handle, const char *func_name) {
/*
* Load function `func_name` from `lib_handle`.
* Set Python exception if we can't find `func_name` in `lib_handle`.
* Returns function pointer or NULL if not present.
*/

FARPROC func = GetProcAddress(lib_handle, func_name);
if (func == NULL) {
PyErr_Format(PyExc_RuntimeError, "Cannot load function %s", func_name);
}
return func;
}

/**
* Try to fill Tcl global vars with function pointers.
*
* @return 0 for no functions found, 1 for all functions found,
* -1 for some but not all functions found.
*/
int
get_tcl(HMODULE hMod) {
/*
* Try to fill Tcl global vars with function pointers. Return 0 for no
* functions found, 1 for all functions found, -1 for some but not all
* functions found.
*/

if ((TCL_CREATE_COMMAND =
(Tcl_CreateCommand_t)GetProcAddress(hMod, "Tcl_CreateCommand")) == NULL) {
return 0; /* Maybe not Tcl module */
Expand All @@ -272,14 +272,14 @@ get_tcl(HMODULE hMod) {
: 1;
}

/**
* Try to fill Tk global vars with function pointers.
*
* @return 0 for no functions found, 1 for all functions found,
* -1 for some but not all functions found.
*/
int
get_tk(HMODULE hMod) {
/*
* Try to fill Tk global vars with function pointers. Return 0 for no
* functions found, 1 for all functions found, -1 for some but not all
* functions found.
*/

FARPROC func = GetProcAddress(hMod, "Tk_PhotoPutBlock");
if (func == NULL) { /* Maybe not Tk module */
return 0;
Expand All @@ -295,13 +295,13 @@ get_tk(HMODULE hMod) {
return 1;
}

/**
* Load Tcl and Tk functions by searching all modules in current process.
*
* @return 0 for success, non-zero for failure, with Python exception set.
*/
int
load_tkinter_funcs(void) {
/*
* Load Tcl and Tk functions by searching all modules in current process.
* Return 0 for success, non-zero for failure.
*/

HMODULE *hMods = NULL;
HANDLE hProcess;
DWORD cbNeeded;
Expand Down Expand Up @@ -373,14 +373,14 @@ load_tkinter_funcs(void) {

#include <dlfcn.h>

/**
* Load function `func_name` from `lib_handle`.
* Set Python exception if we can't find `func_name` in `lib_handle`.
*
* @return Function pointer or NULL if not present, with Python exception set.
*/
void *
_dfunc(void *lib_handle, const char *func_name) {
/*
* Load function `func_name` from `lib_handle`.
* Set Python exception if we can't find `func_name` in `lib_handle`.
* Returns function pointer or NULL if not present.
*/

void *func;
/* Reset errors. */
dlerror();
Expand All @@ -392,13 +392,13 @@ _dfunc(void *lib_handle, const char *func_name) {
return func;
}

/**
* Fill global function pointers from dynamic library.
*
* @return 1 if any pointer is NULL, 0 otherwise.
*/
int
_func_loader(void *lib) {
/*
* Fill global function pointers from dynamic lib.
* Return 1 if any pointer is NULL, 0 otherwise.
*/

if ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)_dfunc(lib, "Tcl_CreateCommand")) ==
NULL) {
return 1;
Expand All @@ -420,13 +420,13 @@ _func_loader(void *lib) {
);
}

/**
* Load tkinter global functions from tkinter compiled module.
*
* @return 0 for success, non-zero for failure, with Python exception set.
*/
int
load_tkinter_funcs(void) {
/*
* Load tkinter global funcs from tkinter compiled module.
* Return 0 for success, non-zero for failure.
*/

int ret = -1;
void *main_program, *tkinter_lib;
char *tkinter_libname;
Expand Down
10 changes: 7 additions & 3 deletions src/_avif.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@ irot_imir_to_exif_orientation(const avifImage *image) {
return 1; // Default orientation ("top-left", no-op).
}

/**
* Map EXIF orientation to irot and imir boxes.
*
* EXIF orientations are defined in JEITA CP-3451C section 4.6.4.A Orientation.
* irot and imir boxes are defined in HEIF ISO/IEC 28002-12:2021 sections 6.5.10
* and 6.5.12.
*/
static void
exif_orientation_to_irot_imir(avifImage *image, int orientation) {
// Mapping from Exif orientation as defined in JEITA CP-3451C section 4.6.4.A
// Orientation to irot and imir boxes as defined in HEIF ISO/IEC 28002-12:2021
// sections 6.5.10 and 6.5.12.
switch (orientation) {
case 2: // The 0th row is at the visual top of the image, and the 0th column is
// the visual right-hand side.
Expand Down
40 changes: 28 additions & 12 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,15 +408,21 @@ getbands(const ModeID mode) {
#define TYPE_FLOAT32 (0x300 | sizeof(FLOAT32))
#define TYPE_DOUBLE (0x400 | sizeof(double))

/**
* Allocates and returns a C array of the items in the Python sequence arg.
* The sequence's length is checked against the length parameter.
*
* @param arg The Python sequence to convert
* @param length The required number of items.
* @param wrong_length Error message to emit in exception if the sequence length does
* not match.
* @param type Type specifier (one of the TYPE_* constants above)
*
* @return A pointer to the allocated C array, or NULL on error. The caller is
* responsible for freeing the memory.
*/
static void *
getlist_impl(PyObject *arg, Py_ssize_t length, const char *wrong_length, int type) {
/* - allocates and returns a c array of the items in the Python sequence arg.
- the size of the returned array is in length
- all of the arg items must be numeric items of the type specified in type
- sequence length is checked against the length parameter
- caller is responsible for freeing the memory
*/

Py_ssize_t i, n;
int itemp;
double dtemp;
Expand Down Expand Up @@ -2104,9 +2110,13 @@ _reduce(ImagingObject *self, PyObject *args) {
return PyImagingNew(imOut);
}

/**
* Convert the given RGB/RGBX image to RGBA in-place.
*
* @return None on success, with Python exception set on failure.
*/
static PyObject *
im_setalpha(ImagingObject *self, PyObject *args) {
/* attempt to modify the mode of an image in place */
Imaging im = self->image;
if (im->mode != IMAGING_MODE_RGB && im->mode != IMAGING_MODE_RGBX) {
return ImagingError_ModeError();
Expand Down Expand Up @@ -2846,10 +2856,18 @@ textwidth(ImagingFontObject *self, const unsigned char *text) {
return xsize;
}

/**
* Convert the given Python string to a C Latin-1 string
* suitable for basic text rendering.
*
* @param encoded_string The Python string to convert. Can be a Unicode or bytes object.
* @param text Pointer to an unsigned char pointer that will be set to the allocated C
* string. The caller is responsible for freeing the memory with `free`.
* @return Void, but a Python exception will be set if an error occurs (e.g., memory
* allocation failure). `text` will not have been set in this case.
*/
void
_font_text_asBytes(PyObject *encoded_string, unsigned char **text) {
/* Allocates *text, returns a 'new reference'. Caller is required to free */

PyObject *bytes = NULL;
Py_ssize_t len = 0;
char *buffer;
Expand All @@ -2875,8 +2893,6 @@ _font_text_asBytes(PyObject *encoded_string, unsigned char **text) {
if (bytes) {
Py_DECREF(bytes);
}

return;
}

static PyObject *
Expand Down
25 changes: 21 additions & 4 deletions src/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,21 @@ _encode_cleanup(ImagingEncoderObject *encoder, PyObject *args) {
Py_RETURN_NONE;
}

/**
* Encode to a Python bytes object allocated by this method.
*
* Python arguments:
* - bufsize (int, optional): The size of the buffer to use for encoding.
*
* @return A tuple containing the number of bytes written, an error code if any, and the
* encoded bytes object. NULL if an error occurred, with a Python exception set.
*/
static PyObject *
_encode(ImagingEncoderObject *encoder, PyObject *args) {
PyObject *buf;
PyObject *result;
int bytes_consumed;

/* Encode to a Python string (allocated by this method) */

Py_ssize_t bufsize = 16384;

if (!PyArg_ParseTuple(args, "|n", &bufsize)) {
Expand Down Expand Up @@ -168,14 +175,24 @@ _encode_to_pyfd(ImagingEncoderObject *encoder, PyObject *args) {
return result;
}

/**
* Encode to a file descriptor.
*
* Python arguments:
* - fh (int): The open writable binary file descriptor to write the encoded data to.
* - bufsize (int, optional): The size of the buffer to use for encoding.
* Default is 16384.
*
* @return The error code from the encoder after encoding.
* The caller must ensure this is zero; otherwise encoding had failed.
* Returns NULL if an error occurred, with a Python exception set.
*/
static PyObject *
_encode_to_file(ImagingEncoderObject *encoder, PyObject *args) {
UINT8 *buf;
int bytes_consumed;
ImagingSectionCookie cookie;

/* Encode to a file handle */

Py_ssize_t fh;
Py_ssize_t bufsize = 16384;

Expand Down
17 changes: 14 additions & 3 deletions src/libImaging/Convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1062,15 +1062,24 @@ pa2ycbcr(UINT8 *out, const UINT8 *in, int xsize, ImagingPalette palette) {
ImagingConvertRGB2YCbCr(out, out, xsize);
}

/**
* Map palette image to L, RGB, RGBA, or CMYK.
*
* @param imOut The output image.
* Must be NULL or have the same size as imIn and the same mode as `mode`.
* @param imIn The input palette image.
* @param mode The desired output mode.
* @return The converted image, or NULL on error.
* FIXME: there's no way of knowing if Imaging2Dirty did the the conversion
* or if it returned the same image. This should be fixed.
*/
static Imaging
frompalette(Imaging imOut, Imaging imIn, const ModeID mode) {
ImagingSectionCookie cookie;
int alpha;
int y;
void (*convert)(UINT8 *, const UINT8 *, int, ImagingPalette);

/* Map palette image to L, RGB, RGBA, or CMYK */

if (!imIn->palette) {
return (Imaging)ImagingError_ValueError("no palette");
}
Expand Down Expand Up @@ -1332,13 +1341,15 @@ topalette(
return imOut;
}

/**
* Map L or RGB to dithered 1 image
*/
static Imaging
tobilevel(Imaging imOut, Imaging imIn) {
ImagingSectionCookie cookie;
int x, y;
int *errors;

/* Map L or RGB to dithered 1 image */
if (imIn->mode != IMAGING_MODE_L && imIn->mode != IMAGING_MODE_RGB) {
return (Imaging)ImagingError_ValueError("conversion not supported");
}
Expand Down
37 changes: 31 additions & 6 deletions src/libImaging/Effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,20 @@

#include <math.h>

/**
* Generate a grayscale Mandelbrot set covering the given extent.
* Allocates a new image of the given size and returns it.
*
* @param xsize Width of the output image in pixels.
* @param ysize Height of the output image in pixels.
* @param extent Array of four doubles specifying the extent of the Mandelbrot set to
* generate: [xmin, ymin, xmax, ymax].
* @param quality Maximum number of iterations for each pixel. Must be >= 2.
* @return A new grayscale image containing the Mandelbrot set,
* or NULL with a Python error set if an error occurred.
*/
Imaging
ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) {
/* Generate a Mandelbrot set covering the given extent */

Imaging im;
int x, y, k;
double width, height;
Expand Down Expand Up @@ -71,10 +81,18 @@ ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality) {
return im;
}

/**
* Generate Gaussian noise centered around 128 with the given standard deviation.
* Allocates a new grayscale image of the given size and returns it.
*
* @param xsize Width of the output image in pixels.
* @param ysize Height of the output image in pixels.
* @param sigma Standard deviation of the Gaussian noise.
* @return A new grayscale image containing the Gaussian noise,
* or NULL with a Python error set if an error occurred.
*/
Imaging
ImagingEffectNoise(int xsize, int ysize, float sigma) {
/* Generate Gaussian noise centered around 128 */

Imaging imOut;
int x, y;
int nextok;
Expand Down Expand Up @@ -113,10 +131,17 @@ ImagingEffectNoise(int xsize, int ysize, float sigma) {
return imOut;
}

/**
* Randomly spread pixels in an image into a new image,
* with a maximum distance of `distance` pixels.
*
* @param imIn Input image.
* @param distance Maximum distance to spread pixels.
* @return A new image with pixels randomly spread,
* or NULL with a Python error set if an error occurred.
*/
Imaging
ImagingEffectSpread(Imaging imIn, int distance) {
/* Randomly spread pixels in an image */

Imaging imOut;
int x, y;

Expand Down
Loading
Loading