aboutsummaryrefslogtreecommitdiffstats
path: root/op.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2004-03-28 11:31:57 +0000
committerkraxel <kraxel>2004-03-28 11:31:57 +0000
commite9e9684117719204929821028ba9dbb7915ea119 (patch)
tree6dd2d71940b33a9f960945335e9124ef4fea9fe7 /op.c
downloadfbida-e9e9684117719204929821028ba9dbb7915ea119.tar.gz
Initial revision
Diffstat (limited to 'op.c')
-rw-r--r--op.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/op.c b/op.c
new file mode 100644
index 0000000..b4e95fe
--- /dev/null
+++ b/op.c
@@ -0,0 +1,289 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "readers.h"
+#include "op.h"
+#include "filter.h"
+
+/* ----------------------------------------------------------------------- */
+/* functions */
+
+static char op_none_data;
+
+static void
+op_flip_vert(struct ida_image *src, struct ida_rect *rect,
+ unsigned char *dst, int line, void *data)
+{
+ char *scanline;
+
+ scanline = src->data + (src->i.height - line - 1) * src->i.width * 3;
+ memcpy(dst,scanline,src->i.width*3);
+}
+
+static void
+op_flip_horz(struct ida_image *src, struct ida_rect *rect,
+ unsigned char *dst, int line, void *data)
+{
+ char *scanline;
+ unsigned int i;
+
+ scanline = src->data + (line+1) * src->i.width * 3;
+ for (i = 0; i < src->i.width; i++) {
+ scanline -= 3;
+ dst[0] = scanline[0];
+ dst[1] = scanline[1];
+ dst[2] = scanline[2];
+ dst += 3;
+ }
+}
+
+static void*
+op_rotate_init(struct ida_image *src, struct ida_rect *rect,
+ struct ida_image_info *i, void *parm)
+{
+ *i = src->i;
+ i->height = src->i.width;
+ i->width = src->i.height;
+ i->dpi = src->i.dpi;
+ return &op_none_data;
+}
+
+static void
+op_rotate_cw(struct ida_image *src, struct ida_rect *rect,
+ unsigned char *dst, int line, void *data)
+{
+ char *pix;
+ unsigned int i;
+
+ pix = src->data + src->i.width * src->i.height * 3 + line * 3;
+ for (i = 0; i < src->i.height; i++) {
+ pix -= src->i.width * 3;
+ dst[0] = pix[0];
+ dst[1] = pix[1];
+ dst[2] = pix[2];
+ dst += 3;
+ }
+}
+
+static void
+op_rotate_ccw(struct ida_image *src, struct ida_rect *rect,
+ unsigned char *dst, int line, void *data)
+{
+ char *pix;
+ unsigned int i;
+
+ pix = src->data + (src->i.width-line-1) * 3;
+ for (i = 0; i < src->i.height; i++) {
+ dst[0] = pix[0];
+ dst[1] = pix[1];
+ dst[2] = pix[2];
+ pix += src->i.width * 3;
+ dst += 3;
+ }
+}
+
+static void
+op_invert(struct ida_image *src, struct ida_rect *rect,
+ unsigned char *dst, int line, void *data)
+{
+ unsigned char *scanline;
+ int i;
+
+ scanline = src->data + line * src->i.width * 3;
+ memcpy(dst,scanline,src->i.width * 3);
+ if (line < rect->y1 || line >= rect->y2)
+ return;
+ dst += 3*rect->x1;
+ scanline += 3*rect->x1;
+ for (i = rect->x1; i < rect->x2; i++) {
+ dst[0] = 255-scanline[0];
+ dst[1] = 255-scanline[1];
+ dst[2] = 255-scanline[2];
+ scanline += 3;
+ dst += 3;
+ }
+}
+
+static void*
+op_crop_init(struct ida_image *src, struct ida_rect *rect,
+ struct ida_image_info *i, void *parm)
+{
+ if (rect->x2 - rect->x1 == src->i.width &&
+ rect->y2 - rect->y1 == src->i.height)
+ return NULL;
+ *i = src->i;
+ i->width = rect->x2 - rect->x1;
+ i->height = rect->y2 - rect->y1;
+ return &op_none_data;
+}
+
+static void
+op_crop_work(struct ida_image *src, struct ida_rect *rect,
+ unsigned char *dst, int line, void *data)
+{
+ unsigned char *scanline;
+ int i;
+
+ scanline = src->data + (line+rect->y1) * src->i.width * 3 + rect->x1 * 3;
+ for (i = rect->x1; i < rect->x2; i++) {
+ dst[0] = scanline[0];
+ dst[1] = scanline[1];
+ dst[2] = scanline[2];
+ scanline += 3;
+ dst += 3;
+ }
+}
+
+static void*
+op_autocrop_init(struct ida_image *src, struct ida_rect *unused,
+ struct ida_image_info *i, void *parm)
+{
+ static struct op_3x3_parm filter = {
+ f1: { -1, -1, -1 },
+ f2: { -1, 8, -1 },
+ f3: { -1, -1, -1 },
+ };
+ struct ida_rect rect;
+ struct ida_image img;
+ int x,y,limit;
+ unsigned char *line;
+ void *data;
+
+ /* detect edges */
+ rect.x1 = 0;
+ rect.x2 = src->i.width;
+ rect.y1 = 0;
+ rect.y2 = src->i.height;
+ data = desc_3x3.init(src, &rect, &img.i, &filter);
+
+ img.data = malloc(img.i.width * img.i.height * 3);
+ for (y = 0; y < (int)img.i.height; y++)
+ desc_3x3.work(src, &rect, img.data+3*img.i.width*y, y, data);
+ desc_3x3.done(data);
+ limit = 64;
+
+ /* y border */
+ for (y = 0; y < (int)img.i.height; y++) {
+ line = img.data + img.i.width*y*3;
+ for (x = 0; x < (int)img.i.width; x++)
+ if (line[3*x+0] > limit ||
+ line[3*x+1] > limit ||
+ line[3*x+2] > limit)
+ break;
+ if (x != (int)img.i.width)
+ break;
+ }
+ rect.y1 = y;
+ for (y = (int)img.i.height-1; y > rect.y1; y--) {
+ line = img.data + img.i.width*y*3;
+ for (x = 0; x < (int)img.i.width; x++)
+ if (line[3*x+0] > limit ||
+ line[3*x+1] > limit ||
+ line[3*x+2] > limit)
+ break;
+ if (x != (int)img.i.width)
+ break;
+ }
+ rect.y2 = y+1;
+
+ /* x border */
+ for (x = 0; x < (int)img.i.width; x++) {
+ for (y = 0; y < (int)img.i.height; y++) {
+ line = img.data + (img.i.width*y+x) * 3;
+ if (line[0] > limit ||
+ line[1] > limit ||
+ line[2] > limit)
+ break;
+ }
+ if (y != (int)img.i.height)
+ break;
+ }
+ rect.x1 = x;
+ for (x = (int)img.i.width-1; x > rect.x1; x--) {
+ for (y = 0; y < (int)img.i.height; y++) {
+ line = img.data + (img.i.width*y+x) * 3;
+ if (line[0] > limit ||
+ line[1] > limit ||
+ line[2] > limit)
+ break;
+ }
+ if (y != (int)img.i.height)
+ break;
+ }
+ rect.x2 = x+1;
+
+ free(img.data);
+ if (debug)
+ fprintf(stderr,"y: %d-%d/%d -- x: %d-%d/%d\n",
+ rect.y1, rect.y2, img.i.height,
+ rect.x1, rect.x2, img.i.width);
+
+ if (0 == rect.x2 - rect.x1 || 0 == rect.y2 - rect.y1)
+ return NULL;
+
+ *unused = rect;
+ *i = src->i;
+ i->width = rect.x2 - rect.x1;
+ i->height = rect.y2 - rect.y1;
+ return &op_none_data;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static char op_none_data;
+
+void* op_none_init(struct ida_image *src, struct ida_rect *sel,
+ struct ida_image_info *i, void *parm)
+{
+ *i = src->i;
+ return &op_none_data;
+}
+
+void op_none_done(void *data) {}
+void op_free_done(void *data) { free(data); }
+
+/* ----------------------------------------------------------------------- */
+
+struct ida_op desc_flip_vert = {
+ name: "flip-vert",
+ init: op_none_init,
+ work: op_flip_vert,
+ done: op_none_done,
+};
+struct ida_op desc_flip_horz = {
+ name: "flip-horz",
+ init: op_none_init,
+ work: op_flip_horz,
+ done: op_none_done,
+};
+struct ida_op desc_rotate_cw = {
+ name: "rotate-cw",
+ init: op_rotate_init,
+ work: op_rotate_cw,
+ done: op_none_done,
+};
+struct ida_op desc_rotate_ccw = {
+ name: "rotate-ccw",
+ init: op_rotate_init,
+ work: op_rotate_ccw,
+ done: op_none_done,
+};
+struct ida_op desc_invert = {
+ name: "invert",
+ init: op_none_init,
+ work: op_invert,
+ done: op_none_done,
+};
+struct ida_op desc_crop = {
+ name: "crop",
+ init: op_crop_init,
+ work: op_crop_work,
+ done: op_none_done,
+};
+struct ida_op desc_autocrop = {
+ name: "autocrop",
+ init: op_autocrop_init,
+ work: op_crop_work,
+ done: op_none_done,
+};