1 /*
2 test_pat_L
3 This frei0r plugin generates test patterns for levels and
4 linearity checking
5
6 Version 0.1 may 2010
7
8 Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu
9
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 */
26
27 /***********************************************************
28 Test patterns: Levels and Linearity
29
30 This plugin draws a set of test patterns, used for checking of
31 linearity, gamma, contrast, etc.
32
33 The patterns are drawn into a temporary float array, for two reasons:
34 1. drawing routines are color model independent,
35 2. drawing is done only when a parameter changes.
36
37 only the function float2color()
38 needs to care about color models, endianness, DV legality etc.
39
40 *************************************************************/
41
42 //compile: gcc -Wall -c -fPIC test_pat_L.c -o test_pat_L.o
43
44 //link: gcc -lm -shared -o test_pat_L.so test_pat_L.o
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <assert.h>
49 #include <math.h>
50
51 #include "frei0r.h"
52
53
54 double PI=3.14159265358979;
55
56
57 //----------------------------------------------------------
draw_rectangle(float * sl,int w,int h,int x,int y,int wr,int hr,float gray)58 void draw_rectangle(float *sl, int w, int h, int x, int y, int wr, int hr, float gray)
59 {
60 int i,j;
61 int zx,kx,zy,ky;
62
63 zx=x; if (zx<0) zx=0;
64 zy=y; if (zy<0) zy=0;
65 kx=x+wr; if (kx>w) kx=w;
66 ky=y+hr; if (ky>h) ky=h;
67 for (i=zy;i<ky;i++)
68 for (j=zx;j<kx;j++)
69 sl[w*i+j]=gray;
70
71 }
72
73 //----------------------------------------------------------
74 //rectangle with gray gradient
75 //dir: 0=left to right, 1=top to bottom, 2=r to l, 3=b to t
draw_gradient(float * sl,int w,int h,int x,int y,int wr,int hr,float gray1,float gray2,int dir)76 void draw_gradient(float *sl, int w, int h, int x, int y, int wr, int hr, float gray1, float gray2, int dir)
77 {
78 int i,j;
79 int zx,kx,zy,ky;
80 float g,dg;
81
82 if (wr<=1) return;
83 if (hr<=1) return;
84 zx=x; if (zx<0) zx=0;
85 zy=y; if (zy<0) zy=0;
86 kx=x+wr; if (kx>w) kx=w;
87 ky=y+hr; if (ky>h) ky=h;
88 switch (dir)
89 {
90 case 0:
91 dg=(gray2-gray1)/(wr-1);
92 g=gray1;
93 for (j=zx;j<kx;j++)
94 {
95 for (i=zy;i<ky;i++)
96 sl[w*i+j]=g;
97 g=g+dg;
98 }
99 break;
100 case 1:
101 dg=(gray2-gray1)/(hr-1);
102 g=gray1;
103 for (i=zy;i<ky;i++)
104 {
105 for (j=zx;j<kx;j++)
106 sl[w*i+j]=g;
107 g=g+dg;
108 }
109 break;
110 case 2:
111 dg=(gray1-gray2)/(wr-1);
112 g=gray2;
113 for (j=zx;j<kx;j++)
114 {
115 for (i=zy;i<ky;i++)
116 sl[w*i+j]=g;
117 g=g+dg;
118 }
119 break;
120 case 3:
121 dg=(gray1-gray2)/(hr-1);
122 g=gray2;
123 for (i=zy;i<ky;i++)
124 {
125 for (j=zx;j<kx;j++)
126 sl[w*i+j]=g;
127 g=g+dg;
128 }
129 default:
130 break;
131 }
132
133 }
134
135 //-----------------------------------------------------------
136 //pocasna za velike kroge.....
draw_circle(float * sl,int w,int h,float ar,int x,int y,int rn,int rz,float gray)137 void draw_circle(float *sl, int w, int h, float ar, int x, int y, int rn, int rz, float gray)
138 {
139 int i,j;
140 int zx,kx,zy,ky;
141 float rr,rmin,rmax;
142
143 zx=x-rz/ar-1; if (zx<0) zx=0;
144 zy=y-rz-1; if (zy<0) zy=0;
145 kx=x+rz/ar+1; if (kx>w) kx=w;
146 ky=y+rz+1; if (ky>h) ky=h;
147 rmin=(float)rn;
148 rmax=(float)rz;
149 for (i=zy;i<ky;i++)
150 for (j=zx;j<kx;j++)
151 {
152 rr=sqrtf((i-y)*(i-y)+(j-x)*(j-x)*ar*ar);
153 if ((rr>=rmin)&&(rr<=rmax)) sl[w*i+j]=gray;
154 }
155
156 }
157
158 //-------------------------------------------------------
159 //draw one numerical digit, 7-segment style
160 //v=size in x direction (in y it is 2*v)
161 //d= number [0...9]
disp7s(float * sl,int w,int h,int x,int y,int v,int d,float gray)162 void disp7s(float *sl, int w, int h, int x, int y, int v, int d, float gray)
163 {
164 char seg[10]={0xEE,0x24,0xBA,0xB6,0x74,0xD6,0xDE,0xA4,0xFE,0xF6};
165
166 if ((d<0)||(d>9)) return;
167
168 if ((seg[d]&128)!=0) draw_rectangle(sl,w,h,x,y-2*v,v,1,gray);
169 if ((seg[d]&64)!=0) draw_rectangle(sl,w,h,x,y-2*v,1,v,gray);
170 if ((seg[d]&32)!=0) draw_rectangle(sl,w,h,x+v,y-2*v,1,v,gray);
171 if ((seg[d]&16)!=0) draw_rectangle(sl,w,h,x,y-v,v,1,gray);
172 if ((seg[d]&8)!=0) draw_rectangle(sl,w,h,x,y-v,1,v,gray);
173 if ((seg[d]&4)!=0) draw_rectangle(sl,w,h,x+v,y-v,1,v,gray);
174 if ((seg[d]&2)!=0) draw_rectangle(sl,w,h,x,y,v,1,gray);
175 }
176
177 //----------------------------------------------------------------
178 //draw a floating point number
179 //v=size
180 //n=number
181 //f=format (as in printf)
dispF(float * sl,int w,int h,int x,int y,int v,float n,char * f,float gray)182 void dispF(float *sl, int w, int h, int x, int y, int v, float n, char *f, float gray)
183 {
184 char str[64];
185 int i;
186
187 sprintf(str,f,n);
188 i=0;
189 while (str[i]!=0)
190 {
191 if (str[i]=='-')
192 draw_rectangle(sl,w,h,x+i*(v+v/3+1),y-v,v,1,gray);
193 else
194 disp7s(sl,w,h,x+i*(v+v/3+1),y,v,str[i]-48,gray);
195 i++;
196 }
197
198 }
199
200 //----------------------------------------------------------
201 //gray staircase
stopnice(float * sl,int w,int h)202 void stopnice(float *sl, int w, int h)
203 {
204 int j,n;
205 float s;
206
207 n=8;
208 for (j=0;j<n;j++)
209 {
210 s=(float)j/(float)(n-1);
211 draw_rectangle(sl,w,h, j*w/n, 0, w/n, h, s);
212 }
213
214 }
215
216 //----------------------------------------------------------
217 //gray staircase with contrast check
stopnice_k(float * sl,int w,int h)218 void stopnice_k(float *sl, int w, int h)
219 {
220 int j,n,w1,h1;
221 float s,s1,s2;
222
223 n=8;
224 w1=w/n/3;
225 h1=w1; if (h1>h/20) h1=h/20;
226 for (j=0;j<n;j++)
227 {
228 s=((float)j+0.5)/(float)n;
229 draw_rectangle(sl,w,h, j*w/n, 0, w/n, h, s);
230
231 s1=s-0.01; if (s1<0.0) s1=0.0;
232 s2=s+0.01; if (s2>1.0) s2=1.0;
233 draw_rectangle(sl,w,h, j*w/n+w1,1*h/16, w1,h1, s1);
234 draw_rectangle(sl,w,h, j*w/n+w1,2*h/16, w1,h1, s2);
235
236 s1=s-0.02; if (s1<0.0) s1=0.0;
237 s2=s+0.02; if (s2>1.0) s2=1.0;
238 draw_rectangle(sl,w,h, j*w/n+w1,4*h/16, w1,h1, s1);
239 draw_rectangle(sl,w,h, j*w/n+w1,5*h/16, w1,h1, s2);
240
241 s1=s-0.05; if (s1<0.0) s1=0.0;
242 s2=s+0.05; if (s2>1.0) s2=1.0;
243 draw_rectangle(sl,w,h, j*w/n+w1,7*h/16, w1,h1, s1);
244 draw_rectangle(sl,w,h, j*w/n+w1,8*h/16, w1,h1, s2);
245
246 s1=s-0.1; if (s1<0.0) s1=0.0;
247 s2=s+0.1; if (s2>1.0) s2=1.0;
248 draw_rectangle(sl,w,h, j*w/n+w1,10*h/16, w1,h1, s1);
249 draw_rectangle(sl,w,h, j*w/n+w1,11*h/16, w1,h1, s2);
250
251 s1=s-0.2; if (s1<0.0) s1=0.0;
252 s2=s+0.2; if (s2>1.0) s2=1.0;
253 draw_rectangle(sl,w,h, j*w/n+w1,13*h/16, w1,w1, s1);
254 draw_rectangle(sl,w,h, j*w/n+w1,14*h/16, w1,w1, s2);
255 }
256
257 }
258
259 //-----------------------------------------------------
260 //gray gradient
sivi_klin(float * sl,int w,int h)261 void sivi_klin(float *sl, int w, int h)
262 {
263 draw_rectangle(sl,w,h, 0, 0, w/7, h, 0.5);
264 draw_rectangle(sl,w,h, 6*w/7, 0, w/7, h, 0.5);
265 draw_gradient(sl,w,h, w/8, 0, 3*w/4, h, 0.0, 1.0, 0);
266 }
267
268 //----------------------------------------------------
269 //256 grays
sivine256(float * sl,int w,int h)270 void sivine256(float *sl, int w, int h)
271 {
272 int i,j,w1,h1;
273 float s;
274
275 draw_rectangle(sl,w,h, 0, 0, w, h, 0.5);
276 if (w>h) w1=h/20; else w1=w/20;
277 h1=w1-2;
278 for (i=0;i<16;i++)
279 for (j=0;j<16;j++)
280 {
281 s=(float)(16*i+j)/255.0;
282 draw_rectangle(sl,w,h, (w-h)/2+(j+2)*w1, (i+2)*w1, h1, h1, s);
283 }
284 }
285
286 //------------------------------------------------------
287 //contrast bands
trakovi(float * sl,int w,int h)288 void trakovi(float *sl, int w, int h)
289 {
290 int i,h1;
291
292 draw_rectangle(sl,w,h, 0, 0, w, h, 0.5);
293 h1=h/64;
294 for (i=0;i<4;i++)
295 {
296 draw_gradient(sl,w,h, w/8, (7+2*i)*h1, 3*w/4, h1, 0.0, 0.99, 0);
297 draw_gradient(sl,w,h, w/8, (8+2*i)*h1, 3*w/4, h1, 0.01, 1.0, 0);
298 }
299 for (i=0;i<4;i++)
300 {
301 draw_gradient(sl,w,h, w/8, (21+2*i)*h1, 3*w/4, h1, 0.0, 0.98, 0);
302 draw_gradient(sl,w,h, w/8, (22+2*i)*h1, 3*w/4, h1, 0.02, 1.0, 0);
303 }
304 for (i=0;i<4;i++)
305 {
306 draw_gradient(sl,w,h, w/8, (35+2*i)*h1, 3*w/4, h1, 0.0, 0.95, 0);
307 draw_gradient(sl,w,h, w/8, (36+2*i)*h1, 3*w/4, h1, 0.05, 1.0, 0);
308 }
309 for (i=0;i<4;i++)
310 {
311 draw_gradient(sl,w,h, w/8, (49+2*i)*h1, 3*w/4, h1, 0.0, 0.90, 0);
312 draw_gradient(sl,w,h, w/8, (50+2*i)*h1, 3*w/4, h1, 0.1, 1.0, 0);
313 }
314
315 }
316
317 //----------------------------------------------------------
gamatest(float * sl,int w,int h)318 void gamatest(float *sl, int w, int h)
319 {
320 int i,s,x,y;
321 float g;
322
323 for (i=0;i<w*h;i++) sl[i]=0.5; //gray background
324
325 //gray patches
326 for (i=0;i<30;i++)
327 {
328 s=66+5*i;
329 g=1.0/(logf((float)s/255.0)/logf(0.5));
330 x=w/4+3*w/16*(i/10);
331 y=(i%10+1)*h/12;
332 draw_rectangle(sl,w,h,x,y,w/8,h/13,(float)s/255.0);
333 s=(s<140)?240:20;
334 dispF(sl,w,h, x+w/16-18,y+h/24+4, 6, g, "%4.2f", s/255.0);
335 }
336 //zebra bars
337 for (i=h/16;i<15*h/16;i++)
338 {
339 g=(i%2==0)?1.0:0.0;
340 draw_rectangle(sl,w,h,3*w/16,i,w/16,1,g);
341 draw_rectangle(sl,w,h,6*w/16,i,w/16,1,g);
342 draw_rectangle(sl,w,h,9*w/16,i,w/16,1,g);
343 draw_rectangle(sl,w,h,12*w/16,i,w/16,1,g);
344 }
345 //black and white level sidebars
346 draw_rectangle(sl,w,h,w/16,h/12,w/16,10*h/12,0.0);
347 draw_rectangle(sl,w,h,14*w/16,h/12,w/16,10*h/12,1.0);
348 for (i=1;i<11;i++)
349 {
350 g=(float)i*0.01;
351 draw_rectangle(sl,w,h,w/16+w/48,i*h/12+h/36,w/48,h/36,g);
352 g=(float)(100-i)*0.01;
353 draw_rectangle(sl,w,h,14*w/16+w/48,i*h/12+h/36,w/48,h/36,g);
354 }
355
356 }
357
358 //--------------------------------------------------
ortikon(float * sl,int w,int h)359 void ortikon(float *sl, int w, int h)
360 {
361 int i;
362 float s1,s2;
363
364 draw_rectangle(sl,w,h, 0, 0, w, h, 0.6);
365 //mali krogec
366 draw_circle(sl,w,h,1.0, 0.3*w, h/8, 0, 10, 0.95);
367 //crni in beli krog
368 draw_circle(sl,w,h,1.0, 0.6*w, h/8, 0, 20, 0.95);
369 draw_circle(sl,w,h,1.0, 0.6*w+40, h/8, 0, 20, 0.05);
370 //gradient levo
371 draw_gradient(sl,w,h, 0, h/4, 0.3*w, 3*h/4, 0.84, 0.094, 1);
372 //svetel trak
373 draw_rectangle(sl,w,h, 0.13*w, h/4, w/20, 3*h/4, 0.97);
374 //svetel trak z gradientom
375 draw_gradient(sl,w,h, 17*w/40,h/4, w/20,3*h/4, 0.97,0.6, 1);
376 s1=0.9; s2=0.1;
377 for (i=h/4;i<h;i=i+h/4.5)
378 {
379 draw_rectangle(sl,w,h,0.6*w,i,h/9,h/9,s2);
380 draw_rectangle(sl,w,h,0.6*w+h/9,i,h/9,h/9,s1);
381 draw_rectangle(sl,w,h,0.6*w+2*h/9,i,h/9,h/9,s2);
382 draw_rectangle(sl,w,h,0.6*w,i+h/9,h/9,h/9,s1);
383 draw_rectangle(sl,w,h,0.6*w+h/9,i+h/9,h/9,h/9,s2);
384 draw_rectangle(sl,w,h,0.6*w+2*h/9,i+h/9,h/9,h/9,s1);
385 }
386 }
387
388
389
390 //-----------------------------------------------------
391 //converts the internal monochrome float image into
392 //Frei0r rgba8888 color
393 //ch selects the channel 0=all 1=R 2=G 3=B
394 //sets alpha to opaque
float2color(float * sl,uint32_t * outframe,int w,int h,int ch)395 void float2color(float *sl, uint32_t* outframe, int w , int h, int ch)
396 {
397 int i,ri,gi,bi;
398 uint32_t p;
399 float r,g,b;
400
401 switch (ch)
402 {
403 case 0: //all (gray)
404 for (i=0;i<w*h;i++)
405 {
406 p=(uint32_t)(255.0*sl[i]) & 0xFF;
407 outframe[i] = (p<<16)+(p<<8)+p+0xFF000000;
408 }
409 break;
410 case 1: //R
411 for (i=0;i<w*h;i++)
412 {
413 p=(uint32_t)(255.0*sl[i]) & 0xFF;
414 outframe[i] = p+0xFF000000;
415 }
416 break;
417 case 2: //G
418 for (i=0;i<w*h;i++)
419 {
420 p=(uint32_t)(255.0*sl[i]) & 0xFF;
421 outframe[i] = (p<<8)+0xFF000000;
422 }
423 break;
424 case 3: //B
425 for (i=0;i<w*h;i++)
426 {
427 p=(uint32_t)(255.0*sl[i]) & 0xFF;
428 outframe[i] = (p<<16)+0xFF000000;
429 }
430 break;
431 case 4: //ccir rec 601 R-Y on 50 gray
432 for (i=0;i<w*h;i++)
433 {
434 r=sl[i];
435 b=0.5;
436 g=(0.5-0.299*r-0.114*b)/0.587;
437 ri=(int)(255.0*r);
438 gi=(int)(255.0*g);
439 bi=(int)(255.0*b);
440 outframe[i] = (bi<<16)+(gi<<8)+ri+0xFF000000;
441 }
442 break;
443 case 5: //ccir rec 601 B-Y on 50% gray
444 for (i=0;i<w*h;i++)
445 {
446 b=sl[i];
447 r=0.5;
448 g=(0.5-0.299*r-0.114*b)/0.587;
449 ri=(int)(255.0*r);
450 gi=(int)(255.0*g);
451 bi=(int)(255.0*b);
452 outframe[i] = (bi<<16)+(gi<<8)+ri+0xFF000000;
453 }
454 break;
455 case 6: //ccir rec 709 R-Y on 50 gray
456 for (i=0;i<w*h;i++)
457 {
458 r=sl[i];
459 b=0.5;
460 g=(0.5-0.2126*r-0.0722*b)/0.7152;
461 ri=(int)(255.0*r);
462 gi=(int)(255.0*g);
463 bi=(int)(255.0*b);
464 outframe[i] = (bi<<16)+(gi<<8)+ri+0xFF000000;
465 }
466 break;
467 case 7: //ccir rec 709 B-Y on 50% gray
468 for (i=0;i<w*h;i++)
469 {
470 b=sl[i];
471 r=0.5;
472 g=(0.5-0.2126*r-0.0722*b)/0.7152;
473 ri=(int)(255.0*r);
474 gi=(int)(255.0*g);
475 bi=(int)(255.0*b);
476 outframe[i] = (bi<<16)+(gi<<8)+ri+0xFF000000;
477 }
478 break;
479 default:
480 break;
481 }
482
483 }
484
485 //-----------------------------------------------------
486 //stretch [0...1] to parameter range [min...max] linear
map_value_forward(double v,float min,float max)487 float map_value_forward(double v, float min, float max)
488 {
489 return min+(max-min)*v;
490 }
491
492 //-----------------------------------------------------
493 //collapse from parameter range [min...max] to [0...1] linear
map_value_backward(float v,float min,float max)494 double map_value_backward(float v, float min, float max)
495 {
496 return (v-min)/(max-min);
497 }
498
499 //-----------------------------------------------------
500 //stretch [0...1] to parameter range [min...max] logarithmic
501 //min and max must be positive!
map_value_forward_log(double v,float min,float max)502 float map_value_forward_log(double v, float min, float max)
503 {
504 float sr,k;
505
506 sr=sqrtf(min*max);
507 k=2.0*log(max/sr);
508 return sr*expf(k*(v-0.5));
509 }
510
511 //-----------------------------------------------------
512 //collapse from parameter range [min...max] to [0...1] logarithmic
513 //min and max must be positive!
map_value_backward_log(float v,float min,float max)514 double map_value_backward_log(float v, float min, float max)
515 {
516 float sr,k;
517
518 sr=sqrtf(min*max);
519 k=2.0*log(max/sr);
520 return logf(v/sr)/k+0.5;
521 }
522
523 //**************************************************
524 //obligatory frei0r stuff follows
525
526 //------------------------------------------------
527 //this structure holds an instance of the test_pat_L plugin
528 typedef struct
529 {
530 unsigned int w;
531 unsigned int h;
532
533 int type;
534 int chan;
535
536 float *sl;
537
538 } tp_inst_t;
539
540 //----------------------------------------------------
f0r_init()541 int f0r_init()
542 {
543 return 1;
544 }
545
546 //--------------------------------------------------
f0r_deinit()547 void f0r_deinit()
548 { /* no initialization required */ }
549
550 //--------------------------------------------------
f0r_get_plugin_info(f0r_plugin_info_t * tp_info)551 void f0r_get_plugin_info(f0r_plugin_info_t* tp_info)
552 {
553 tp_info->name = "test_pat_L";
554 tp_info->author = "Marko Cebokli";
555 tp_info->plugin_type = F0R_PLUGIN_TYPE_SOURCE;
556 // tp_info->plugin_type = F0R_PLUGIN_TYPE_FILTER;
557 tp_info->color_model = F0R_COLOR_MODEL_RGBA8888;
558 tp_info->frei0r_version = FREI0R_MAJOR_VERSION;
559 tp_info->major_version = 0;
560 tp_info->minor_version = 1;
561 tp_info->num_params = 2;
562 tp_info->explanation = "Generates linearity checking patterns";
563 }
564
565 //--------------------------------------------------
f0r_get_param_info(f0r_param_info_t * info,int param_index)566 void f0r_get_param_info(f0r_param_info_t* info, int param_index)
567 {
568 switch (param_index)
569 {
570 case 0:
571 info->name = "Type";
572 info->type = F0R_PARAM_DOUBLE;
573 info->explanation = "Type of test pattern"; break;
574 case 1:
575 info->name ="Channel";
576 info->type = F0R_PARAM_DOUBLE;
577 info->explanation = "Into which color channel to draw";
578 break;
579 }
580 }
581
582 //--------------------------------------------------
f0r_construct(unsigned int width,unsigned int height)583 f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
584 {
585 tp_inst_t* inst = calloc(1, sizeof(*inst));
586 inst->w = width;
587 inst->h = height;
588
589 inst->type=0;
590 inst->chan=0;
591
592 inst->sl=(float*)calloc(width*height,sizeof(float));
593
594 stopnice(inst->sl, inst->w, inst->h);
595
596 return (f0r_instance_t)inst;
597 }
598
599 //--------------------------------------------------
f0r_destruct(f0r_instance_t instance)600 void f0r_destruct(f0r_instance_t instance)
601 {
602 tp_inst_t* inst = (tp_inst_t*)instance;
603
604 free(inst->sl);
605 free(inst);
606 }
607
608 //--------------------------------------------------
f0r_set_param_value(f0r_instance_t instance,f0r_param_t param,int param_index)609 void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index)
610 {
611 tp_inst_t* inst = (tp_inst_t*)instance;
612
613 f0r_param_double* p = (f0r_param_double*) param;
614
615 int chg,tmpi;
616 float tmpf;
617
618 chg=0;
619 switch (param_index)
620 {
621 case 0: //type
622 tmpf=*((double*)p);
623 if (tmpf>=1.0)
624 tmpi=(int)tmpf;
625 else
626 tmpi = map_value_forward(tmpf, 0.0, 6.9999);
627 if ((tmpi<0)||(tmpi>6.0)) break;
628 if (inst->type != tmpi) chg=1;
629 inst->type = tmpi;
630 break;
631 case 1: //channel
632 tmpf=*((double*)p);
633 if (tmpf>=1.0)
634 tmpi=(int)tmpf;
635 else
636 tmpi = map_value_forward(tmpf, 0.0, 7.9999);
637 if ((tmpi<0)||(tmpi>7.0)) break;
638 if (inst->chan != tmpi) chg=1;
639 inst->chan = tmpi;
640 }
641
642 if (chg==0) return;
643
644 switch (inst->type)
645 {
646 case 0: //gray steps
647 stopnice(inst->sl, inst->w, inst->h);
648 break;
649 case 1: //gray steps with contrast squares
650 stopnice_k(inst->sl, inst->w, inst->h);
651 break;
652 case 2: //gray gradient
653 sivi_klin(inst->sl, inst->w, inst->h);
654 break;
655 case 3: //256 gray squares in a 16x16 matrix
656 sivine256(inst->sl, inst->w, inst->h);
657 break;
658 case 4: //contrast bands
659 trakovi(inst->sl, inst->w, inst->h);
660 break;
661 case 5: //gama ckecking chart
662 gamatest(inst->sl, inst->w, inst->h);
663 break;
664 case 6: //for testing orthicon simulator
665 ortikon(inst->sl, inst->w, inst->h);
666 break;
667 default:
668 break;
669 }
670
671 }
672
673 //-------------------------------------------------
f0r_get_param_value(f0r_instance_t instance,f0r_param_t param,int param_index)674 void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index)
675 {
676 tp_inst_t* inst = (tp_inst_t*)instance;
677
678 f0r_param_double* p = (f0r_param_double*) param;
679
680 switch (param_index)
681 {
682 case 0: //type
683 *p = map_value_backward(inst->type, 0.0, 6.9999);
684 break;
685 case 1: //channel
686 *p = map_value_backward(inst->chan, 0.0, 7.9999);
687 break;
688 }
689 }
690
691 //---------------------------------------------------
f0r_update(f0r_instance_t instance,double time,const uint32_t * inframe,uint32_t * outframe)692 void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe)
693 {
694
695 assert(instance);
696 tp_inst_t* inst = (tp_inst_t*)instance;
697
698 float2color(inst->sl, outframe, inst->w , inst->h, inst->chan);
699
700 }
701