diff --git a/src/libImaging/AlphaComposite.c b/src/libImaging/AlphaComposite.c index d1a1e7ad34a..fff9d8537e1 100644 --- a/src/libImaging/AlphaComposite.c +++ b/src/libImaging/AlphaComposite.c @@ -19,6 +19,10 @@ typedef struct { UINT8 a; } rgba8; +/** + * Alpha-composite imSrc over imDst, returning a newly allocated result. + * Contract: imDst and imSrc are read-only and may alias each other. + */ Imaging ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { Imaging imOut; diff --git a/src/libImaging/Bands.c b/src/libImaging/Bands.c index d1fa16addff..4c0652a9978 100644 --- a/src/libImaging/Bands.c +++ b/src/libImaging/Bands.c @@ -17,6 +17,10 @@ #include "Imaging.h" +/** + * Extract a single band from imIn into a newly allocated single-band image. + * Contract: imIn is read-only and the returned image is a distinct allocation. + */ Imaging ImagingGetBand(Imaging imIn, int band) { Imaging imOut; @@ -68,6 +72,14 @@ ImagingGetBand(Imaging imIn, int band) { return imOut; } +/** + * Split imIn into its component bands. + * The caller must provide an array of 4 Imaging pointers, + * which will be allocated and filled with the individual bands. + * The number of bands returned is the number of bands in imIn. + * + * Contract: imIn is read-only. + */ int ImagingSplit(Imaging imIn, Imaging bands[4]) { int i, j, x, y; @@ -173,6 +185,11 @@ ImagingSplit(Imaging imIn, Imaging bands[4]) { return imIn->bands; } +/** + * Insert single-band imIn into `band` of imOut, in place. + * + * Contract: imIn and imOut MUST be distinct images and not alias. + */ Imaging ImagingPutBand(Imaging imOut, Imaging imIn, int band) { int x, y; @@ -219,6 +236,9 @@ ImagingPutBand(Imaging imOut, Imaging imIn, int band) { return imOut; } +/** + * Fill a single band of imOut with a constant colour, in place. + */ Imaging ImagingFillBand(Imaging imOut, int band, int color) { int x, y; @@ -253,6 +273,11 @@ ImagingFillBand(Imaging imOut, int band, int color) { return imOut; } +/** + * Merge the caller-supplied bands[] into a newly allocated multi-band image. + * + * Contract: the bands[] inputs are read-only, and the output is new. + */ Imaging ImagingMerge(const ModeID mode, Imaging bands[4]) { int i, x, y; diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index 19662abf044..1589bf2bdc5 100644 --- a/src/libImaging/Blend.c +++ b/src/libImaging/Blend.c @@ -17,6 +17,12 @@ #include "Imaging.h" +/** + * Interpolate (or, for alpha outside [0, 1], extrapolate) between imIn1 and + * imIn2 by `alpha`, returning a newly allocated result. + * + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { Imaging imOut; diff --git a/src/libImaging/Chops.c b/src/libImaging/Chops.c index 557c2f52f10..bd18a06ace0 100644 --- a/src/libImaging/Chops.c +++ b/src/libImaging/Chops.c @@ -84,66 +84,124 @@ create(Imaging im1, Imaging im2, const ModeID mode) { return ImagingNewDirty(im1->mode, xsize, ysize); } +/** + * Return a newly allocated image containing the lighter pixels of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopLighter(Imaging imIn1, Imaging imIn2) { CHOP((in1[x] > in2[x]) ? in1[x] : in2[x]); } +/** + * Return a newly allocated image containing the darker pixels of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopDarker(Imaging imIn1, Imaging imIn2) { CHOP((in1[x] < in2[x]) ? in1[x] : in2[x]); } +/** + * Return a newly allocated image containing the absolute per-pixel difference of the + * two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopDifference(Imaging imIn1, Imaging imIn2) { CHOP(abs((int)in1[x] - (int)in2[x])); } +/** + * Return a newly allocated image containing the per-pixel product (scaled to 0-255) of + * the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopMultiply(Imaging imIn1, Imaging imIn2) { CHOP((int)in1[x] * (int)in2[x] / 255); } +/** + * Return a newly allocated image containing the screen blend of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopScreen(Imaging imIn1, Imaging imIn2) { CHOP(255 - ((int)(255 - in1[x]) * (int)(255 - in2[x])) / 255); } +/** + * Return a newly allocated image containing the per-pixel sum, divided by `scale` and + * shifted by `offset`, clipped to 0-255. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset) { CHOP(((int)in1[x] + (int)in2[x]) / scale + offset); } +/** + * Return a newly allocated image containing the per-pixel difference, divided by + * `scale` and shifted by `offset`, clipped to 0-255. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) { CHOP(((int)in1[x] - (int)in2[x]) / scale + offset); } +/** + * Return a newly allocated "1" image that is the logical AND of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2) { CHOP2((in1[x] && in2[x]) ? 255 : 0, IMAGING_MODE_1); } +/** + * Return a newly allocated "1" image that is the logical OR of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2) { CHOP2((in1[x] || in2[x]) ? 255 : 0, IMAGING_MODE_1); } +/** + * Return a newly allocated "1" image that is the logical XOR of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2) { CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, IMAGING_MODE_1); } +/** + * Return a newly allocated image containing the per-pixel sum of the two images, + * wrapping on overflow (no clipping). + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) { CHOP2(in1[x] + in2[x], IMAGING_MODE_UNKNOWN); } +/** + * Return a newly allocated image containing the per-pixel difference of the two images, + * wrapping on underflow (no clipping). + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) { CHOP2(in1[x] - in2[x], IMAGING_MODE_UNKNOWN); } +/** + * Return a newly allocated image containing the soft-light blend of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) { CHOP2( @@ -153,6 +211,10 @@ ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) { ); } +/** + * Return a newly allocated image containing the hard-light blend of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingChopHardLight(Imaging imIn1, Imaging imIn2) { CHOP2( @@ -162,6 +224,10 @@ ImagingChopHardLight(Imaging imIn1, Imaging imIn2) { ); } +/** + * Return a newly allocated image containing the overlay blend of the two images. + * Contract: imIn1 and imIn2 are read-only and may alias each other. + */ Imaging ImagingOverlay(Imaging imIn1, Imaging imIn2) { CHOP2( diff --git a/src/libImaging/ColorLUT.c b/src/libImaging/ColorLUT.c index 5559de689b2..55fc808f04a 100644 --- a/src/libImaging/ColorLUT.c +++ b/src/libImaging/ColorLUT.c @@ -55,6 +55,12 @@ table_index3D(int index1D, int index2D, int index3D, int size1D, int size1D_2D) Each element is signed 16-bit int where 0 is lowest output value and 255 << PRECISION_BITS (16320) is highest value. */ +/** + * Apply a 3D colour lookup table to imIn, writing the result to imOut. + * + * Contract: unlike the other point-style loops in libImaging, + * imIn and imOut MAY be the same image to support running in place. + */ Imaging ImagingColorLUT3D_linear( Imaging imOut, diff --git a/src/libImaging/Fill.c b/src/libImaging/Fill.c index 25344cf3a7e..ee61ec8d8ec 100644 --- a/src/libImaging/Fill.c +++ b/src/libImaging/Fill.c @@ -19,6 +19,9 @@ #include "math.h" +/** + * Fill an entire image with a constant colour, in place. + */ Imaging ImagingFill(Imaging im, const void *colour) { ImagingSectionCookie cookie; diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index b5f971d40c2..1a8843526e1 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -120,6 +120,11 @@ kernel_i16(int size, UINT8 *in0, int x, const float *kernel, int bigendian) { return result; } +/** + * Convolve `im` with a 3x3 kernel, writing the result to imOut. + * + * Contract: imOut and im *MUST* be distinct images. + */ static void ImagingFilter3x3(Imaging imOut, Imaging im, const float *kernel, float offset) { #define KERNEL1x3(in0, x, kernel, d) \ @@ -271,6 +276,11 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float *kernel, float offset) { memcpy(imOut->image[y], im->image[y], im->linesize); } +/** + * Convolve `im` with a 5x5 kernel, writing the result to imOut. + * + * Contract: imOut and im *MUST* be distinct images. + */ static void ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) { #define KERNEL1x5(in0, x, kernel, d) \ diff --git a/src/libImaging/Histo.c b/src/libImaging/Histo.c index 7af60003511..c51677901c6 100644 --- a/src/libImaging/Histo.c +++ b/src/libImaging/Histo.c @@ -56,6 +56,11 @@ ImagingHistogramNew(Imaging im) { return h; } +/** + * Accumulate a histogram over `im`, optionally restricted to imMask. + * + * Contract: Both im and imMask are read-only. + */ ImagingHistogram ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) { ImagingSectionCookie cookie; diff --git a/src/libImaging/Matrix.c b/src/libImaging/Matrix.c index 02676c9e31a..cd317ba264e 100644 --- a/src/libImaging/Matrix.c +++ b/src/libImaging/Matrix.c @@ -17,6 +17,12 @@ #define CLIPF(v) ((v <= 0.0) ? 0 : (v >= 255.0F) ? 255 : (UINT8)v) +/** + * Convert `im` to `mode` by applying the colour matrix `m`, + * returning a newly allocated result. + * + * Contract: im is read-only. + */ Imaging ImagingConvertMatrix(Imaging im, const ModeID mode, const float m[12]) { Imaging imOut; diff --git a/src/libImaging/Negative.c b/src/libImaging/Negative.c index 114e8608e87..ea04563851d 100644 --- a/src/libImaging/Negative.c +++ b/src/libImaging/Negative.c @@ -18,6 +18,11 @@ #include "Imaging.h" +/** + * Invert every byte of `im`, returning a newly allocated result. + * + * Contract: im is read-only. + */ Imaging ImagingNegative(Imaging im) { Imaging imOut; diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index 99c2dbac3af..5712f6bd39c 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1663,6 +1663,12 @@ quantize2( return 0; } +/** + * Quantize `im` down to at most `colors` palette entries, + * returning a newly allocated result. + * + * Contract: im is read-only. + */ Imaging ImagingQuantize(Imaging im, int colors, int mode, int kmeans) { int i, j;