Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Imaging/libImaging/Point.c
diff options
context:
space:
mode:
Diffstat (limited to 'Imaging/libImaging/Point.c')
-rw-r--r--Imaging/libImaging/Point.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/Imaging/libImaging/Point.c b/Imaging/libImaging/Point.c
new file mode 100644
index 0000000..45693f0
--- /dev/null
+++ b/Imaging/libImaging/Point.c
@@ -0,0 +1,263 @@
+/*
+ * The Python Imaging Library
+ * $Id: Point.c 2207 2004-12-19 15:06:45Z fredrik $
+ *
+ * point (pixel) translation
+ *
+ * history:
+ * 1995-11-27 fl Created
+ * 1996-03-31 fl Fixed colour support
+ * 1996-08-13 fl Support 8-bit to "1" thresholding
+ * 1997-05-31 fl Added floating point transform
+ * 1998-07-02 fl Added integer point transform
+ * 1998-07-17 fl Support L to anything lookup
+ * 2004-12-18 fl Refactored; added I to L lookup
+ *
+ * Copyright (c) 1997-2004 by Secret Labs AB.
+ * Copyright (c) 1995-2004 by Fredrik Lundh.
+ *
+ * See the README file for information on usage and redistribution.
+ */
+
+
+#include "Imaging.h"
+
+typedef struct {
+ const void* table;
+} im_point_context;
+
+static void
+im_point_8_8(Imaging imOut, Imaging imIn, im_point_context* context)
+{
+ int x, y;
+ /* 8-bit source, 8-bit destination */
+ UINT8* table = (UINT8*) context->table;
+ for (y = 0; y < imIn->ysize; y++) {
+ UINT8* in = imIn->image8[y];
+ UINT8* out = imOut->image8[y];
+ for (x = 0; x < imIn->xsize; x++)
+ out[x] = table[in[x]];
+ }
+}
+
+static void
+im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context* context)
+{
+ int x, y;
+ /* 2x8-bit source, 2x8-bit destination */
+ UINT8* table = (UINT8*) context->table;
+ for (y = 0; y < imIn->ysize; y++) {
+ UINT8* in = (UINT8*) imIn->image[y];
+ UINT8* out = (UINT8*) imOut->image[y];
+ for (x = 0; x < imIn->xsize; x++) {
+ out[0] = table[in[0]];
+ out[3] = table[in[3]+256];
+ in += 4; out += 4;
+ }
+ }
+}
+
+static void
+im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context* context)
+{
+ int x, y;
+ /* 3x8-bit source, 3x8-bit destination */
+ UINT8* table = (UINT8*) context->table;
+ for (y = 0; y < imIn->ysize; y++) {
+ UINT8* in = (UINT8*) imIn->image[y];
+ UINT8* out = (UINT8*) imOut->image[y];
+ for (x = 0; x < imIn->xsize; x++) {
+ out[0] = table[in[0]];
+ out[1] = table[in[1]+256];
+ out[2] = table[in[2]+512];
+ in += 4; out += 4;
+ }
+ }
+}
+
+static void
+im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context* context)
+{
+ int x, y;
+ /* 4x8-bit source, 4x8-bit destination */
+ UINT8* table = (UINT8*) context->table;
+ for (y = 0; y < imIn->ysize; y++) {
+ UINT8* in = (UINT8*) imIn->image[y];
+ UINT8* out = (UINT8*) imOut->image[y];
+ for (x = 0; x < imIn->xsize; x++) {
+ out[0] = table[in[0]];
+ out[1] = table[in[1]+256];
+ out[2] = table[in[2]+512];
+ out[3] = table[in[3]+768];
+ in += 4; out += 4;
+ }
+ }
+}
+
+static void
+im_point_8_32(Imaging imOut, Imaging imIn, im_point_context* context)
+{
+ int x, y;
+ /* 8-bit source, 32-bit destination */
+ INT32* table = (INT32*) context->table;
+ for (y = 0; y < imIn->ysize; y++) {
+ UINT8* in = imIn->image8[y];
+ INT32* out = imOut->image32[y];
+ for (x = 0; x < imIn->xsize; x++)
+ out[x] = table[in[x]];
+ }
+}
+
+static void
+im_point_32_8(Imaging imOut, Imaging imIn, im_point_context* context)
+{
+ int x, y;
+ /* 32-bit source, 8-bit destination */
+ UINT8* table = (UINT8*) context->table;
+ for (y = 0; y < imIn->ysize; y++) {
+ INT32* in = imIn->image32[y];
+ UINT8* out = imOut->image8[y];
+ for (x = 0; x < imIn->xsize; x++) {
+ int v = in[x];
+ if (v < 0)
+ v = 0;
+ else if (v > 65535)
+ v = 65535;
+ out[x] = table[v];
+ }
+ }
+}
+
+Imaging
+ImagingPoint(Imaging imIn, const char* mode, const void* table)
+{
+ /* lookup table transform */
+
+ ImagingSectionCookie cookie;
+ Imaging imOut;
+ im_point_context context;
+ void (*point)(Imaging imIn, Imaging imOut, im_point_context* context);
+
+ if (!imIn)
+ return (Imaging) ImagingError_ModeError();
+
+ if (!mode)
+ mode = imIn->mode;
+
+ if (imIn->type != IMAGING_TYPE_UINT8) {
+ if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0)
+ goto mode_mismatch;
+ } else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0)
+ goto mode_mismatch;
+
+ imOut = ImagingNew(mode, imIn->xsize, imIn->ysize);
+ if (!imOut)
+ return NULL;
+
+ /* find appropriate handler */
+ if (imIn->type == IMAGING_TYPE_UINT8) {
+ if (imIn->bands == imOut->bands && imIn->type == imOut->type) {
+ switch (imIn->bands) {
+ case 1:
+ point = im_point_8_8;
+ break;
+ case 2:
+ point = im_point_2x8_2x8;
+ break;
+ case 3:
+ point = im_point_3x8_3x8;
+ break;
+ case 4:
+ point = im_point_4x8_4x8;
+ break;
+ default:
+ /* this cannot really happen */
+ point = im_point_8_8;
+ break;
+ }
+ } else
+ point = im_point_8_32;
+ } else
+ point = im_point_32_8;
+
+ ImagingCopyInfo(imOut, imIn);
+
+ ImagingSectionEnter(&cookie);
+
+ context.table = table;
+ point(imOut, imIn, &context);
+
+ ImagingSectionLeave(&cookie);
+
+ return imOut;
+
+ mode_mismatch:
+ return (Imaging) ImagingError_ValueError(
+ "point operation not supported for this mode"
+ );
+}
+
+
+Imaging
+ImagingPointTransform(Imaging imIn, double scale, double offset)
+{
+ /* scale/offset transform */
+
+ ImagingSectionCookie cookie;
+ Imaging imOut;
+ int x, y;
+
+ if (!imIn || (strcmp(imIn->mode, "I") != 0 &&
+ strcmp(imIn->mode, "I;16") != 0 &&
+ strcmp(imIn->mode, "F") != 0))
+ return (Imaging) ImagingError_ModeError();
+
+ imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
+ if (!imOut)
+ return NULL;
+
+ ImagingCopyInfo(imOut, imIn);
+
+ switch (imIn->type) {
+ case IMAGING_TYPE_INT32:
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < imIn->ysize; y++) {
+ INT32* in = imIn->image32[y];
+ INT32* out = imOut->image32[y];
+ /* FIXME: add clipping? */
+ for (x = 0; x < imIn->xsize; x++)
+ out[x] = in[x] * scale + offset;
+ }
+ ImagingSectionLeave(&cookie);
+ break;
+ case IMAGING_TYPE_FLOAT32:
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < imIn->ysize; y++) {
+ FLOAT32* in = (FLOAT32*) imIn->image32[y];
+ FLOAT32* out = (FLOAT32*) imOut->image32[y];
+ for (x = 0; x < imIn->xsize; x++)
+ out[x] = in[x] * scale + offset;
+ }
+ ImagingSectionLeave(&cookie);
+ break;
+ case IMAGING_TYPE_SPECIAL:
+ if (strcmp(imIn->mode,"I;16") == 0) {
+ ImagingSectionEnter(&cookie);
+ for (y = 0; y < imIn->ysize; y++) {
+ UINT16* in = (UINT16 *)imIn->image[y];
+ UINT16* out = (UINT16 *)imOut->image[y];
+ /* FIXME: add clipping? */
+ for (x = 0; x < imIn->xsize; x++)
+ out[x] = in[x] * scale + offset;
+ }
+ ImagingSectionLeave(&cookie);
+ break;
+ }
+ /* FALL THROUGH */
+ default:
+ ImagingDelete(imOut);
+ return (Imaging) ImagingError_ValueError("internal error");
+ }
+
+ return imOut;
+}