Rev 491 | Rev 502 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 491 | Rev 500 | ||
---|---|---|---|
Line 257... | Line 257... | ||
257 | extern value_type cell[], var[]; |
257 | extern value_type cell[], var[]; |
258 | extern unsigned char *image_ptr; |
258 | extern unsigned char* image_ptr; |
259 | 259 | ||
260 | // ------------------------------------------------------------------------------------------- |
260 | // ------------------------------------------------------------------------------------------- |
261 | 261 | ||
262 | double costab[COSTABSIZE]; |
- | |
263 | double tantab[TANTABSIZE]; |
- | |
264 | void init_trigtab(){ |
262 | void init_trigtab() { |
265 | #ifdef PARSERTEST |
263 | #ifdef PARSERTEST |
266 | return; |
264 | return; |
267 | #else |
265 | #else |
268 | int i; |
266 | int i; |
- | 267 | ||
- | 268 | if (gdata == NULL) return; // should not happen |
|
- | 269 | ||
- | 270 | if (gdata->costab == NULL) { |
|
- | 271 | gdata->costab = (double*)malloc(sizeof(double) * COSTABSIZE); |
|
- | 272 | if (gdata->costab) { |
|
269 | for(i=0;i<COSTABSIZE;++i){ |
273 | for (i = 0; i < COSTABSIZE; ++i) { |
270 | costab[i] = cos(FFANGLE(i)); |
274 | gdata->costab[i] = cos(FFANGLE(i)); |
- | 275 | } |
|
- | 276 | } |
|
271 | } |
277 | } |
- | 278 | ||
- | 279 | if (gdata->tantab == NULL) { |
|
- | 280 | gdata->tantab = (double*)malloc(sizeof(double) * TANTABSIZE); |
|
- | 281 | if (gdata->tantab) { |
|
272 | for(i=0;i<TANTABSIZE;++i){ |
282 | for (i = 0; i < TANTABSIZE; ++i) { |
273 | if (i>=TANTABSIZE/2) { |
283 | if (i >= TANTABSIZE / 2) { |
274 | /* the last '-1' in the expression '512-i-1' is for FilterFactory compatibility, and to avoid the undefined pi/2 area */ |
284 | /* the last '-1' in the expression '512-i-1' is for FilterFactory compatibility, and to avoid the undefined pi/2 area */ |
275 | tantab[i] = -tantab[TANTABSIZE-i-1]; |
285 | gdata->tantab[i] = -gdata->tantab[TANTABSIZE - i - 1]; |
- | 286 | } |
|
276 | } else { |
287 | else { |
277 | tantab[i] = tan(FFANGLE(i)); |
288 | gdata->tantab[i] = tan(FFANGLE(i)); |
- | 289 | } |
|
- | 290 | } |
|
278 | } |
291 | } |
279 | } |
292 | } |
280 | #endif |
293 | #endif |
281 | } |
294 | } |
282 | 295 | ||
Line 356... | Line 369... | ||
356 | 369 | ||
357 | value_type foundry_r2x(value_type d, value_type m) { |
370 | value_type foundry_r2x(value_type d, value_type m) { |
358 | #ifdef PARSERTEST |
371 | #ifdef PARSERTEST |
359 | return 0; |
372 | return 0; |
360 | #else |
373 | #else |
361 | return (value_type)RINT(m * costab[abs(d) % COSTABSIZE]); |
374 | return (value_type)RINT(m * gdata->costab[abs(d) % COSTABSIZE]); |
362 | #endif |
375 | #endif |
363 | } |
376 | } |
364 | 377 | ||
365 | value_type ff_r2x(value_type d, value_type m) { |
378 | value_type ff_r2x(value_type d, value_type m) { |
366 | #ifdef use_filterfactory_implementation_r2x |
379 | #ifdef use_filterfactory_implementation_r2x |
Line 386... | Line 399... | ||
386 | 399 | ||
387 | value_type foundry_r2y(value_type d, value_type m) { |
400 | value_type foundry_r2y(value_type d, value_type m) { |
388 | #ifdef PARSERTEST |
401 | #ifdef PARSERTEST |
389 | return 0; |
402 | return 0; |
390 | #else |
403 | #else |
391 | return (value_type)RINT(m * costab[abs(d - 256) % COSTABSIZE]); |
404 | return (value_type)RINT(m * gdata->costab[abs(d - 256) % COSTABSIZE]); |
392 | #endif |
405 | #endif |
393 | } |
406 | } |
394 | 407 | ||
395 | value_type ff_r2y(value_type d, value_type m) { |
408 | value_type ff_r2y(value_type d, value_type m) { |
396 | #ifdef use_filterfactory_implementation_r2y |
409 | #ifdef use_filterfactory_implementation_r2y |
Line 496... | Line 509... | ||
496 | inclusive */ |
509 | inclusive */ |
497 | value_type ff_map(value_type i,value_type n){ |
510 | value_type ff_map(value_type i, value_type n) { |
498 | #ifdef PARSERTEST |
511 | #ifdef PARSERTEST |
499 | return 0; |
512 | return 0; |
500 | #else |
513 | #else |
- | 514 | value_type H, L; |
|
- | 515 | const int i2 = i << 1; |
|
- | 516 | ||
- | 517 | // This is how Filter Factory for Windows implements it: |
|
- | 518 | if (i < 0) return 0; |
|
- | 519 | if (i > 3) return 0; |
|
- | 520 | H = slider[i2]; // ctl(2i) |
|
- | 521 | L = slider[i2 + 1]; // ctl(2i+1) |
|
- | 522 | if (n < 0) n = 0; |
|
- | 523 | if (n > 255) n = 255; // Note: MacFF probably does "return 255" if n>255 (see testcases/map1_factory_win.png) |
|
- | 524 | ||
- | 525 | if (H == L) { |
|
- | 526 | // This is undocumented in Filter Factory! (Taken from Windows implementation) |
|
- | 527 | if (n < H) return 0; |
|
- | 528 | if (n >= L) return 255; |
|
- | 529 | } else if (L > H) { |
|
- | 530 | // This is undocumented in Filter Factory! (Taken from Windows implementation) |
|
- | 531 | if (n <= H) return 255; |
|
- | 532 | if (n >= L) return 0; |
|
- | 533 | } else { |
|
- | 534 | if (n <= L) return 0; |
|
- | 535 | if (n >= H) return 255; |
|
- | 536 | } |
|
- | 537 | return (n - L) * 255 / (H - L); |
|
- | 538 | ||
- | 539 | // This is the original formula used by GIMP User Filter v0.8 (uf-pcode.h). |
|
- | 540 | // It was used in Filter Foundry till version 1.7.0.16, inclusive. |
|
501 | /* |
541 | /* |
502 | if( i>=0 && i<=3 && n>=0 && n<=255 ){ |
542 | value_type H = ff_ctl(i * 2); |
503 | int H = slider[i*2],L = slider[i*2+1]; |
543 | value_type L = ff_ctl(i * 2 + 1); |
504 | return n<=L || H==L ? 0 : ( n>=H ? 255 : ((n-L)*255L)/(H-L) ); |
544 | return abs(((long)n * (L - H) / 255) + H); |
505 | }else |
- | |
506 | return 0; |
- | |
507 | */ |
545 | */ |
508 | // this code is from GIMP User Filter |
- | |
509 | value_type x = ff_ctl(i*2), |
- | |
510 | y = ff_ctl(i*2+1); |
- | |
511 | return abs(((long)n*(y-x) / 255)+x); |
- | |
512 | #endif |
546 | #endif |
- | 547 | ||
513 | } |
548 | } |
514 | 549 | ||
515 | // ------------------------------------------------------------------------------------------- |
550 | // ------------------------------------------------------------------------------------------- |
516 | 551 | ||
517 | /* min(a,b) Lesser of a and b */ |
552 | /* min(a,b) Lesser of a and b */ |
Line 934... | Line 969... | ||
934 | value_type foundry_cos(value_type x) { |
969 | value_type foundry_cos(value_type x) { |
935 | #ifdef PARSERTEST |
970 | #ifdef PARSERTEST |
936 | return 0; |
971 | return 0; |
937 | #else |
972 | #else |
938 | //return RINT(TRIGAMP*cos(FFANGLE(x))); |
973 | //return RINT(TRIGAMP*cos(FFANGLE(x))); |
939 | return (value_type)RINT(TRIGAMP * costab[abs(x) % COSTABSIZE]); |
974 | return (value_type)RINT(TRIGAMP * gdata->costab[abs(x) % COSTABSIZE]); |
940 | #endif |
975 | #endif |
941 | } |
976 | } |
942 | 977 | ||
943 | value_type ff_cos(value_type x){ |
978 | value_type ff_cos(value_type x) { |
944 | #ifdef use_filterfactory_implementation_cos |
979 | #ifdef use_filterfactory_implementation_cos |
Line 1017... | Line 1052... | ||
1017 | // B = sin(x) > 1024 || sin(x) < -1024 || sin(-x) > 1024 || sin(-x) < -1024 ? 255 : 0 |
1052 | // B = sin(x) > 1024 || sin(x) < -1024 || sin(-x) > 1024 || sin(-x) < -1024 ? 255 : 0 |
1018 | // It outputs green stripes, showing that the output of tan() is not bounded. |
1053 | // It outputs green stripes, showing that the output of tan() is not bounded. |
1019 | // So, we do it the same way to stay compatible. |
1054 | // So, we do it the same way to stay compatible. |
1020 | if (x < 0) x--; /* required for Filter Factory compatibility */ |
1055 | if (x < 0) x--; /* required for Filter Factory compatibility */ |
1021 | while (x < 0) x += TANTABSIZE; |
1056 | while (x < 0) x += TANTABSIZE; |
1022 | return (value_type)RINT(2*TRIGAMP*tantab[x % TANTABSIZE]); // We need the x2 multiplicator for some reason |
1057 | return (value_type)RINT(2 * TRIGAMP * gdata->tantab[x % TANTABSIZE]); // We need the x2 multiplicator for some reason |
1023 | #endif |
1058 | #endif |
1024 | } |
1059 | } |
1025 | 1060 | ||
1026 | value_type ff_tan(value_type x) { |
1061 | value_type ff_tan(value_type x) { |
1027 | #ifdef use_filterfactory_implementation_tan |
1062 | #ifdef use_filterfactory_implementation_tan |
Line 1479... | Line 1514... | ||
1479 | #ifdef PARSERTEST |
1514 | #ifdef PARSERTEST |
1480 | return 0; |
1515 | return 0; |
1481 | #else |
1516 | #else |
1482 | long total; |
1517 | long total; |
1483 | int x, y, z; |
1518 | int x, y, z; |
1484 | // shift x,y from selection-relative to image relative |
1519 | // shift x,y from selection-relative to image relative required by rawsrc() |
1485 | if (HAS_BIG_DOC(gpb)) { |
1520 | if (HAS_BIG_DOC(gpb)) { |
1486 | x = var['x'] + BIGDOC_FILTER_RECT(gpb).left; |
1521 | x = var['x'] + BIGDOC_FILTER_RECT(gpb).left; |
1487 | y = var['y'] + BIGDOC_FILTER_RECT(gpb).top; |
1522 | y = var['y'] + BIGDOC_FILTER_RECT(gpb).top; |
1488 | } else { |
1523 | } else { |
1489 | x = var['x'] + FILTER_RECT(gpb).left; |
1524 | x = var['x'] + FILTER_RECT(gpb).left; |
1490 | y = var['y'] + FILTER_RECT(gpb).top; |
1525 | y = var['y'] + FILTER_RECT(gpb).top; |
1491 | } |
1526 | } |
1492 | z = var['z']; |
1527 | z = var['z']; |
1493 | 1528 | ||
- | 1529 | // rawsrc() will choose the neighbor pixels if x/y goes out-of-bounds (outer border pixels) |
|
1494 | if(z >= 0 && z < var['Z']) |
1530 | if (z >= 0 && z < var['Z']) |
1495 | total = m11*rawsrc(x-1,y-1,z) + m12*rawsrc(x,y-1,z) + m13*rawsrc(x+1,y-1,z) |
1531 | total = m11 * rawsrc(x - 1, y - 1, z) + m12 * rawsrc(x, y - 1, z) + m13 * rawsrc(x + 1, y - 1, z) |
1496 | + m21*rawsrc(x-1,y, z) + m22*rawsrc(x,y, z) + m23*rawsrc(x+1,y, z) |
1532 | + m21 * rawsrc(x - 1, y, z) + m22 * rawsrc(x, y, z) + m23 * rawsrc(x + 1, y, z) |
1497 | + m31*rawsrc(x-1,y+1,z) + m32*rawsrc(x,y+1,z) + m33*rawsrc(x+1,y+1,z); |
1533 | + m31 * rawsrc(x - 1, y + 1, z) + m32 * rawsrc(x, y + 1, z) + m33 * rawsrc(x + 1, y + 1, z); |
1498 | else |
1534 | else |
1499 | total = 0; |
1535 | total = 0; // ... can this happen at all ?! |
1500 | 1536 | ||
1501 | return d ? total/d : 0; |
1537 | return d ? total / d : 0; |
1502 | #endif |
1538 | #endif |
1503 | } |
1539 | } |
1504 | 1540 |