1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4
5 #include "readers.h"
6 #include "viewer.h"
7 #include "lut.h"
8
9 /* ----------------------------------------------------------------------- */
10
11 struct op_map_parm_ch op_map_nothing = {
12 gamma: 1,
13 bottom: 0,
14 top: 255,
15 left: 0,
16 right: 255
17 };
18
19 struct op_map_lut {
20 unsigned char red[256];
21 unsigned char green[256];
22 unsigned char blue[256];
23 };
24
25 /* ----------------------------------------------------------------------- */
26 /* functions */
27
build_lut(struct op_map_parm_ch * arg,unsigned char * lut)28 static void build_lut(struct op_map_parm_ch *arg, unsigned char *lut)
29 {
30 int i,val;
31 int inrange,outrange;
32 float p;
33
34 inrange = arg->right - arg->left +1;
35 outrange = arg->top - arg->bottom +1;
36 p = 1/arg->gamma;
37
38 for (i = 0; i < arg->left; i++)
39 lut[i] = 0;
40 for (; i <= arg->right; i++) {
41 val = pow((float)(i-arg->left)/inrange,p) * outrange + 0.5;
42 val += arg->bottom;
43 if (val < 0) val = 0;
44 if (val > 255) val = 255;
45 lut[i] = val;
46 }
47 for (; i < 256; i++)
48 lut[i] = 255;
49 }
50
51 static void*
op_map_init(struct ida_image * src,struct ida_rect * rect,struct ida_image_info * i,void * parm)52 op_map_init(struct ida_image *src, struct ida_rect *rect,
53 struct ida_image_info *i, void *parm)
54 {
55 struct op_map_parm *args = parm;
56 struct op_map_lut *lut;
57
58 lut = malloc(sizeof(*lut));
59 build_lut(&args->red,lut->red);
60 build_lut(&args->green,lut->green);
61 build_lut(&args->blue,lut->blue);
62
63 *i = src->i;
64 return lut;
65 }
66
67 static void
op_map_work(struct ida_image * src,struct ida_rect * rect,unsigned char * dst,int line,void * data)68 op_map_work(struct ida_image *src, struct ida_rect *rect,
69 unsigned char *dst, int line, void *data)
70 {
71 struct op_map_lut *lut = data;
72 unsigned char *scanline;
73 int i;
74
75 scanline = ida_image_scanline(src, line);
76 memcpy(dst,scanline,src->i.width * 3);
77 if (line < rect->y1 || line >= rect->y2)
78 return;
79 dst += 3*rect->x1;
80 scanline += 3*rect->x1;
81 for (i = rect->x1; i < rect->x2; i++) {
82 dst[0] = lut->red[scanline[0]];
83 dst[1] = lut->green[scanline[1]];
84 dst[2] = lut->blue[scanline[2]];
85 scanline += 3;
86 dst += 3;
87 }
88 }
89
90 /* ----------------------------------------------------------------------- */
91
92 struct ida_op desc_map = {
93 name: "map",
94 init: op_map_init,
95 work: op_map_work,
96 done: op_free_done,
97 };
98