| 1 18 19 package org.apache.batik.ext.awt.image.rendered; 20 21 import java.awt.Rectangle ; 22 import java.awt.color.ColorSpace ; 23 import java.awt.geom.AffineTransform ; 24 import java.awt.geom.Rectangle2D ; 25 import java.awt.image.ColorModel ; 26 import java.awt.image.DataBuffer ; 27 import java.awt.image.DataBufferInt ; 28 import java.awt.image.DirectColorModel ; 29 import java.awt.image.SinglePixelPackedSampleModel ; 30 import java.awt.image.WritableRaster ; 31 63 public final class TurbulencePatternRed extends AbstractRed { 64 68 static final class StitchInfo { 69 72 int width; 73 74 77 int height; 78 79 84 int wrapX; 85 86 91 int wrapY; 92 93 96 StitchInfo(){ 97 } 98 99 102 StitchInfo(StitchInfo stitchInfo){ 103 this.width = stitchInfo.width; 104 this.height = stitchInfo.height; 105 this.wrapX = stitchInfo.wrapX; 106 this.wrapY = stitchInfo.wrapY; 107 } 108 109 final void assign(StitchInfo stitchInfo) { 110 this.width = stitchInfo.width; 111 this.height = stitchInfo.height; 112 this.wrapX = stitchInfo.wrapX; 113 this.wrapY = stitchInfo.wrapY; 114 } 115 116 127 final void doubleFrequency(){ 128 width *= 2; 129 height *= 2; 130 wrapX *= 2; 131 wrapY *= 2; 132 wrapX -= PerlinN; 133 wrapY -= PerlinN; 134 } 135 } 136 137 140 private StitchInfo stitchInfo = null; 141 142 146 private static final AffineTransform IDENTITY = new AffineTransform (); 147 148 151 private double baseFrequencyX; 152 153 156 private double baseFrequencyY; 157 158 161 private int numOctaves; 162 163 166 private int seed; 167 168 174 private Rectangle2D tile; 175 176 179 private AffineTransform txf; 180 181 184 private boolean isFractalNoise; 185 186 189 private int channels[]; 190 191 double tx[] = {1, 0}; 195 double ty[] = {0, 1}; 196 197 205 private static final int RAND_m = 2147483647; 206 private static final int RAND_a = 16807; 207 private static final int RAND_q = 127773; 208 private static final int RAND_r = 2836; 209 210 private static final int BSize = 0x100; 211 private static final int BM = 0xff; 212 private static final double PerlinN = 0x1000; 213 private static final int NP = 12 ; 214 private static final int NM = 0xfff; 215 private final int latticeSelector[] = new int[BSize + 1]; 216 private final double gradient[] = new double[(BSize+1)*8]; 217 218 public double getBaseFrequencyX(){ 219 return baseFrequencyX; 220 } 221 222 public double getBaseFrequencyY(){ 223 return baseFrequencyY; 224 } 225 226 public int getNumOctaves(){ 227 return numOctaves; 228 } 229 230 public int getSeed(){ 231 return seed; 232 } 233 234 public Rectangle2D getTile(){ 235 return (Rectangle2D )tile.clone(); 236 } 237 238 public boolean isFractalNoise(){ 239 return isFractalNoise; 240 } 241 242 public boolean[] getChannels(){ 243 boolean channels[] = new boolean[4]; 244 for(int i=0; i<this.channels.length; i++) 245 channels[this.channels[i]] = true; 246 247 return channels; 248 } 249 250 public final int setupSeed(int seed) { 251 if (seed <= 0) seed = -(seed % (RAND_m - 1)) + 1; 252 if (seed > RAND_m - 1) seed = RAND_m - 1; 253 return seed; 254 } 255 256 public final int random(int seed) { 257 int result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q); 258 if (result <= 0) result += RAND_m; 259 return result; 260 } 261 262 private void initLattice(int seed) { 263 double u, v, s; 264 int i, j, k, s1, s2; 265 seed = setupSeed(seed); 266 267 for(k = 0; k < 4; k++){ 268 for(i = 0; i < BSize; i++){ 269 u = (((seed = random(seed)) % (BSize + BSize)) - BSize); 270 v = (((seed = random(seed)) % (BSize + BSize)) - BSize); 271 272 s = 1/Math.sqrt(u*u + v*v); 273 gradient[i*8 + k*2 ] = u*s; 274 gradient[i*8 + k*2 + 1] = v*s; 275 } 276 } 277 278 for(i = 0; i < BSize; i++) 279 latticeSelector[i] = i; 280 281 while(--i > 0){ 282 k = latticeSelector[i]; 283 j = (seed = random(seed)) % BSize; 284 latticeSelector[i] = latticeSelector[j]; 285 latticeSelector[j] = k; 286 287 s1 = i<<3; 290 s2 = j<<3; 291 for (j=0; j<8; j++) { 292 s = gradient[s1+j]; 293 gradient[s1+j] = gradient[s2+j]; 294 gradient[s2+j] = s; 295 } 296 } 297 latticeSelector[BSize] = latticeSelector[0]; 298 for (j=0; j<8; j++) 299 gradient[(BSize*8)+j] = gradient[j]; 300 } 301 302 303 private static final double s_curve(final double t) { 304 return (t * t * (3 - 2 * t) ); 305 } 306 307 private static final double lerp(double t, double a, double b) { 308 return ( a + t * (b - a) ); 309 } 310 311 319 private final void noise2(final double noise[], double vec0, double vec1) { 320 int b0, b1; 321 final int i, j; 322 final double rx0, rx1, ry0, ry1, sx, sy; 323 324 vec0 += PerlinN; 325 b0 = ((int)vec0)&BM; 326 327 i = latticeSelector[b0]; 328 j = latticeSelector[b0+1]; 329 330 rx0 = vec0 - (int)vec0; 331 rx1 = rx0 - 1.0; 332 sx = s_curve(rx0); 333 334 vec1 += PerlinN; 335 b0 = (int)vec1; 336 337 b1 = ((j + b0)&BM)<<3; 340 b0 = ((i + b0)&BM)<<3; 341 342 ry0 = vec1 - (int)vec1; 343 ry1 = ry0 - 1.0; 344 sy = s_curve(ry0); 345 346 switch (channels.length) { 347 case 4: 349 noise[3] = 350 lerp(sy, 351 lerp(sx, 352 rx0*gradient[b0+6] + ry0*gradient[b0+7], 353 rx1*gradient[b1+6] + ry0*gradient[b1+7]), 354 lerp(sx, 355 rx0*gradient[b0+8+6] + ry1*gradient[b0+8+7], 356 rx1*gradient[b1+8+6] + ry1*gradient[b1+8+7])); 357 case 3: 358 noise[2] = 359 lerp(sy, 360 lerp(sx, 361 rx0*gradient[b0+4] + ry0*gradient[b0+5], 362 rx1*gradient[b1+4] + ry0*gradient[b1+5]), 363 lerp(sx, 364 rx0*gradient[b0+8+4] + ry1*gradient[b0+8+5], 365 rx1*gradient[b1+8+4] + ry1*gradient[b1+8+5])); 366 case 2: 367 noise[1] = 368 lerp(sy, 369 lerp(sx, 370 rx0*gradient[b0+2] + ry0*gradient[b0+3], 371 rx1*gradient[b1+2] + ry0*gradient[b1+3]), 372 lerp(sx, 373 rx0*gradient[b0+8+2] + ry1*gradient[b0+8+3], 374 rx1*gradient[b1+8+2] + ry1*gradient[b1+8+3])); 375 case 1: 376 noise[0] = 377 lerp(sy, 378 lerp(sx, 379 rx0*gradient[b0+0] + ry0*gradient[b0+1], 380 rx1*gradient[b1+0] + ry0*gradient[b1+1]), 381 lerp(sx, 382 rx0*gradient[b0+8+0] + ry1*gradient[b0+8+1], 383 rx1*gradient[b1+8+0] + ry1*gradient[b1+8+1])); 384 } 385 } 386 387 397 private final void noise2Stitch(final double noise[], 398 final double vec0, final double vec1, 399 final StitchInfo stitchInfo){ 400 int b0, b1; 401 final int i, j, b00, b10, b01, b11; 402 double t; 403 final double rx0, rx1, ry0, ry1, sx, sy; 404 405 t = vec0 + PerlinN; 406 b0 = ((int)t); 407 b1 = b0+1; 408 if (b1 >= stitchInfo.wrapX) { 410 if (b0 >= stitchInfo.wrapX) { 411 b0 -= stitchInfo.width; 412 b1 -= stitchInfo.width; 413 } else { 414 b1 -= stitchInfo.width; 415 } 416 } 417 i = latticeSelector[b0&BM]; 418 j = latticeSelector[b1&BM]; 419 420 rx0 = t - (int)t; 421 rx1 = rx0 - 1.0; 422 sx = s_curve(rx0); 423 424 t = vec1 + PerlinN; 425 b0 = ((int)t); 426 b1 = b0+1; 427 if (b1 >= stitchInfo.wrapY) { 429 if (b0 >= stitchInfo.wrapY) { 430 b0 -= stitchInfo.height; 431 b1 -= stitchInfo.height; 432 } else { 433 b1 -= stitchInfo.height; 434 } 435 } 436 b00 = ((i + b0)&BM)<<3; 441 b10 = ((j + b0)&BM)<<3; 442 b01 = ((i + b1)&BM)<<3; 443 b11 = ((j + b1)&BM)<<3; 444 445 ry0 = t - (int)t; 446 ry1 = ry0 - 1.0; 447 sy = s_curve(ry0); 448 449 switch (channels.length) { 450 case 4: 452 noise[3] = 453 lerp(sy, 454 lerp(sx, 455 rx0*gradient[b00+6] + ry0*gradient[b00+7], 456 rx1*gradient[b10+6] + ry0*gradient[b10+7]), 457 lerp(sx, 458 rx0*gradient[b01+6] + ry1*gradient[b01+7], 459 rx1*gradient[b11+6] + ry1*gradient[b11+7])); 460 case 3: 461 noise[2] = 462 lerp(sy, 463 lerp(sx, 464 rx0*gradient[b00+4] + ry0*gradient[b00+5], 465 rx1*gradient[b10+4] + ry0*gradient[b10+5]), 466 lerp(sx, 467 rx0*gradient[b01+4] + ry1*gradient[b01+5], 468 rx1*gradient[b11+4] + ry1*gradient[b11+5])); 469 case 2: 470 noise[1] = 471 lerp(sy, 472 lerp(sx, 473 rx0*gradient[b00+2] + ry0*gradient[b00+3], 474 rx1*gradient[b10+2] + ry0*gradient[b10+3]), 475 lerp(sx, 476 rx0*gradient[b01+2] + ry1*gradient[b01+3], 477 rx1*gradient[b11+2] + ry1*gradient[b11+3])); 478 case 1: 479 noise[0] = 480 lerp(sy, 481 lerp(sx, 482 rx0*gradient[b00+0] + ry0*gradient[b00+1], 483 rx1*gradient[b10+0] + ry0*gradient[b10+1]), 484 lerp(sx, 485 rx0*gradient[b01+0] + ry1*gradient[b01+1], 486 rx1*gradient[b11+0] + ry1*gradient[b11+1])); 487 } 488 } 489 490 499 private final int turbulence_4(double pointX, 500 double pointY, 501 final double fSum[]) { 502 double n, ratio = 255; 503 int i, j, b0, b1, nOctave; 504 double px, py, rx0, rx1, ry0, ry1, sx, sy; 505 506 pointX *= baseFrequencyX; 507 pointY *= baseFrequencyY; 508 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 0; 509 510 for (nOctave = numOctaves; nOctave > 0; nOctave--){ 511 px = pointX+PerlinN; 512 513 b0 = ((int)px)&BM; 514 i = latticeSelector[b0 ]; 515 j = latticeSelector[b0+1]; 516 517 rx0 = px - (int)px; 518 rx1 = rx0 - 1.0; 519 sx = s_curve(rx0); 520 521 py = pointY+PerlinN; 522 b0 = ((int)py) & BM; 523 b1 = (b0+1) & BM; 524 525 b1 = ((j + b0)&BM)<<3; 526 b0 = ((i + b0)&BM)<<3; 527 528 ry0 = py - (int)py; 529 ry1 = ry0 - 1.0; 530 sy = s_curve(ry0); 531 532 n = lerp(sy, 533 lerp(sx, 534 rx0*gradient[b0+0] + ry0*gradient[b0+1], 535 rx1*gradient[b1+0] + ry0*gradient[b1+1]), 536 lerp(sx, 537 rx0*gradient[b0+8+0] + ry1*gradient[b0+8+1], 538 rx1*gradient[b1+8+0] + ry1*gradient[b1+8+1])); 539 540 if (n<0) fSum[0] -= (n * ratio); 541 else fSum[0] += (n * ratio); 542 543 n = lerp(sy, 544 lerp(sx, 545 rx0*gradient[b0+2] + ry0*gradient[b0+3], 546 rx1*gradient[b1+2] + ry0*gradient[b1+3]), 547 lerp(sx, 548 rx0*gradient[b0+8+2] + ry1*gradient[b0+8+3], 549 rx1*gradient[b1+8+2] + ry1*gradient[b1+8+3])); 550 551 if (n<0) fSum[1] -= (n * ratio); 552 else fSum[1] += (n * ratio); 553 554 n = lerp(sy, 555 lerp(sx, 556 rx0*gradient[b0+4] + ry0*gradient[b0+5], 557 rx1*gradient[b1+4] + ry0*gradient[b1+5]), 558 lerp(sx, 559 rx0*gradient[b0+8+4] + ry1*gradient[b0+8+5], 560 rx1*gradient[b1+8+4] + ry1*gradient[b1+8+5])); 561 562 if (n<0) fSum[2] -= (n * ratio); 563 else fSum[2] += (n * ratio); 564 565 n = lerp(sy, 566 lerp(sx, 567 rx0*gradient[b0+6] + ry0*gradient[b0+7], 568 rx1*gradient[b1+6] + ry0*gradient[b1+7]), 569 lerp(sx, 570 rx0*gradient[b0+8+6] + ry1*gradient[b0+8+7], 571 rx1*gradient[b1+8+6] + ry1*gradient[b1+8+7])); 572 if (n<0) fSum[3] -= (n * ratio); 573 else fSum[3] += (n * ratio); 574 575 ratio *= .5; 576 pointX *= 2; 577 pointY *= 2; 578 } 579 580 i = (int)fSum[0]; 581 if ((i & 0xFFFFFF00) == 0) j = i<<16; 582 else j = ((i & 0x80000000) != 0)?0:0xFF0000; 583 584 i = (int)fSum[1]; 585 if ((i & 0xFFFFFF00) == 0) j |= i<<8; 586 else j |= ((i & 0x80000000) != 0)?0:0xFF00; 587 588 i = (int)fSum[2]; 589 if ((i & 0xFFFFFF00) == 0) j |= i; 590 else j |= ((i & 0x80000000) != 0)?0:0xFF; 591 592 i = (int)fSum[3]; 593 if ((i & 0xFFFFFF00) == 0) j |= i<<24; 594 else j |= ((i & 0x80000000) != 0)?0:0xFF000000; 595 return j; 596 } 597 598 599 608 private final void turbulence(final int rgb[], 609 double pointX, 610 double pointY, 611 final double fSum[], 612 final double noise[]) { 613 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 0; 614 double ratio = 255; 615 pointX *= baseFrequencyX; 616 pointY *= baseFrequencyY; 617 switch (channels.length) { 618 case 4: 619 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 620 noise2(noise, pointX, pointY); 621 622 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 623 else fSum[0] += (noise[0] * ratio); 624 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 625 else fSum[1] += (noise[1] * ratio); 626 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 627 else fSum[2] += (noise[2] * ratio); 628 if (noise[3]<0) fSum[3] -= (noise[3] * ratio); 629 else fSum[3] += (noise[3] * ratio); 630 ratio *= .5; 631 pointX *= 2; 632 pointY *= 2; 633 } 634 635 rgb[0] = (int)fSum[0]; 636 if ((rgb[0] & 0xFFFFFF00) != 0) 637 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 638 rgb[1] = (int)fSum[1]; 639 if ((rgb[1] & 0xFFFFFF00) != 0) 640 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 641 rgb[2] = (int)fSum[2]; 642 if ((rgb[2] & 0xFFFFFF00) != 0) 643 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 644 rgb[3] = (int)fSum[3]; 645 if ((rgb[3] & 0xFFFFFF00) != 0) 646 rgb[3] = ((rgb[3] & 0x80000000) != 0)?0:255; 647 break; 648 case 3: 649 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 650 noise2(noise, pointX, pointY); 651 652 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 653 else fSum[2] += (noise[2] * ratio); 654 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 655 else fSum[1] += (noise[1] * ratio); 656 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 657 else fSum[0] += (noise[0] * ratio); 658 ratio *= .5; 659 pointX *= 2; 660 pointY *= 2; 661 } 662 rgb[2] = (int)fSum[2]; 663 if ((rgb[2] & 0xFFFFFF00) != 0) 664 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 665 rgb[1] = (int)fSum[1]; 666 if ((rgb[1] & 0xFFFFFF00) != 0) 667 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 668 rgb[0] = (int)fSum[0]; 669 if ((rgb[0] & 0xFFFFFF00) != 0) 670 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 671 break; 672 case 2: 673 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 674 noise2(noise, pointX, pointY); 675 676 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 677 else fSum[1] += (noise[1] * ratio); 678 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 679 else fSum[0] += (noise[0] * ratio); 680 ratio *= .5; 681 pointX *= 2; 682 pointY *= 2; 683 } 684 685 rgb[1] = (int)fSum[1]; 686 if ((rgb[1] & 0xFFFFFF00) != 0) 687 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 688 rgb[0] = (int)fSum[0]; 689 if ((rgb[0] & 0xFFFFFF00) != 0) 690 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 691 break; 692 case 1: 693 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 694 noise2(noise, pointX, pointY); 695 696 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 697 else fSum[0] += (noise[0] * ratio); 698 ratio *= .5; 699 pointX *= 2; 700 pointY *= 2; 701 } 702 703 rgb[0] = (int)fSum[0]; 704 if ((rgb[0] & 0xFFFFFF00) != 0) 705 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 706 break; 707 } 708 } 709 710 720 private final void turbulenceStitch(final int rgb[], 721 double pointX, double pointY, 722 final double fSum[], 723 final double noise[], 724 StitchInfo stitchInfo){ 725 double ratio = 1; 726 pointX *= baseFrequencyX; 727 pointY *= baseFrequencyY; 728 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 0; 729 switch (channels.length) { 730 case 4: 731 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 732 noise2Stitch(noise, pointX, pointY, stitchInfo); 733 734 if (noise[3]<0) fSum[3] -= (noise[3] * ratio); 735 else fSum[3] += (noise[3] * ratio); 736 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 737 else fSum[2] += (noise[2] * ratio); 738 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 739 else fSum[1] += (noise[1] * ratio); 740 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 741 else fSum[0] += (noise[0] * ratio); 742 ratio *= .5; 743 pointX *= 2; 744 pointY *= 2; 745 746 stitchInfo.doubleFrequency(); 747 } 748 rgb[3] = (int)(fSum[3] * 255); 749 if ((rgb[3] & 0xFFFFFF00) != 0) 750 rgb[3] = ((rgb[3] & 0x80000000) != 0)?0:255; 751 rgb[2] = (int)(fSum[2] * 255); 752 |