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