1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.renderscript.cts; 18 19 import android.renderscript.Allocation; 20 21 import android.renderscript.Byte2; 22 import android.renderscript.Byte3; 23 import android.renderscript.Byte4; 24 25 import android.renderscript.Double2; 26 import android.renderscript.Double3; 27 import android.renderscript.Double4; 28 29 import android.renderscript.Element; 30 31 import android.renderscript.Float2; 32 import android.renderscript.Float3; 33 import android.renderscript.Float4; 34 35 import android.renderscript.Int2; 36 import android.renderscript.Int3; 37 import android.renderscript.Int4; 38 39 import android.renderscript.Long2; 40 import android.renderscript.Long3; 41 import android.renderscript.Long4; 42 43 import android.renderscript.RSRuntimeException; 44 45 import android.renderscript.Short2; 46 import android.renderscript.Short3; 47 import android.renderscript.Short4; 48 49 import android.renderscript.Matrix4f; 50 import android.renderscript.Script; 51 52 import android.renderscript.Type; 53 54 import android.renderscript.ScriptGroup; 55 56 import android.renderscript.ScriptIntrinsicBlend; 57 import android.renderscript.ScriptIntrinsicBlur; 58 import android.renderscript.ScriptIntrinsicColorMatrix; 59 import android.renderscript.ScriptIntrinsicConvolve3x3; 60 import android.renderscript.ScriptIntrinsicConvolve5x5; 61 import android.renderscript.ScriptIntrinsicLUT; 62 import android.util.Log; 63 64 public class ImageProcessingTest extends RSBaseCompute { 65 private Allocation a1, a2; 66 67 private final int MAX_RADIUS = 25; 68 private final int dimX = 256; 69 70 @Override setUp()71 protected void setUp() throws Exception { 72 super.setUp(); 73 74 Type t = new Type.Builder(mRS, Element.U8_4(mRS)).setX(dimX).setY(dimX).create(); 75 a1 = Allocation.createTyped(mRS, t); 76 a2 = Allocation.createTyped(mRS, t); 77 } 78 79 @Override tearDown()80 protected void tearDown() throws Exception { 81 a1.destroy(); 82 a2.destroy(); 83 super.tearDown(); 84 } 85 testBlur()86 public void testBlur() { 87 ScriptIntrinsicBlur mBlur; 88 mBlur = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS)); 89 90 Allocation a1_copy, a2_copy; 91 a1_copy = Allocation.createTyped(mRS, a1.getType()); 92 a2_copy = Allocation.createTyped(mRS, a2.getType()); 93 94 for (int i = 1; i < MAX_RADIUS; i++) { 95 96 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 97 98 mBlur.setRadius(i); 99 mBlur.setInput(a1_copy); 100 101 mBlur.forEach(a2_copy); 102 103 // validate 104 105 } 106 107 a1_copy.destroy(); 108 a2_copy.destroy(); 109 mBlur.destroy(); 110 } 111 testBlend()112 public void testBlend() { 113 ScriptIntrinsicBlend mBlend; 114 mBlend = ScriptIntrinsicBlend.create(mRS, Element.U8_4(mRS)); 115 int w = 256; 116 int h = 256; 117 Allocation src = creatAllocation(w, h); 118 Allocation dst = creatAllocation(w, h); 119 byte[] srcData = new byte[w * h * 4]; 120 byte[] dstData = new byte[w * h * 4]; 121 byte[] resultData = new byte[w * h * 4]; 122 Script.LaunchOptions opt = new Script.LaunchOptions(); 123 // unclipped but with options 124 for (int i = 0; i < 28; i++) { 125 buildSrc(srcData, w, h); 126 buildDst(dstData, w, h); 127 src.copyFromUnchecked(srcData); 128 dst.copyFromUnchecked(dstData); 129 130 switch (i) { 131 case 0: 132 mBlend.forEachSrc(src, dst); 133 break; 134 case 1: 135 mBlend.forEachDst(src, dst); 136 break; 137 case 2: 138 mBlend.forEachSrcOver(src, dst); 139 break; 140 case 3: 141 mBlend.forEachDstOver(src, dst); 142 break; 143 case 4: 144 mBlend.forEachSrcIn(src, dst); 145 break; 146 case 5: 147 mBlend.forEachDstIn(src, dst); 148 break; 149 case 6: 150 mBlend.forEachSrcOut(src, dst); 151 break; 152 case 7: 153 mBlend.forEachDstOut(src, dst); 154 break; 155 case 8: 156 mBlend.forEachSrcAtop(src, dst); 157 break; 158 case 9: 159 mBlend.forEachDstAtop(src, dst); 160 break; 161 case 10: 162 mBlend.forEachXor(src, dst); 163 break; 164 case 11: 165 mBlend.forEachAdd(src, dst); 166 break; 167 case 12: 168 mBlend.forEachSubtract(src, dst); 169 break; 170 case 13: 171 mBlend.forEachMultiply(src, dst); 172 break; 173 case 14: 174 mBlend.forEachSrc(src, dst, opt); 175 break; 176 case 15: 177 mBlend.forEachDst(src, dst, opt); 178 break; 179 case 16: 180 mBlend.forEachSrcOver(src, dst, opt); 181 break; 182 case 17: 183 mBlend.forEachDstOver(src, dst, opt); 184 break; 185 case 18: 186 mBlend.forEachSrcIn(src, dst, opt); 187 break; 188 case 19: 189 mBlend.forEachDstIn(src, dst, opt); 190 break; 191 case 20: 192 mBlend.forEachSrcOut(src, dst, opt); 193 break; 194 case 21: 195 mBlend.forEachDstOut(src, dst, opt); 196 break; 197 case 22: 198 mBlend.forEachSrcAtop(src, dst, opt); 199 break; 200 case 23: 201 mBlend.forEachDstAtop(src, dst, opt); 202 break; 203 case 24: 204 mBlend.forEachXor(src, dst, opt); 205 break; 206 case 25: 207 mBlend.forEachAdd(src, dst, opt); 208 break; 209 case 26: 210 mBlend.forEachSubtract(src, dst, opt); 211 break; 212 case 27: 213 mBlend.forEachMultiply(src, dst, opt); 214 break; 215 } 216 dst.copyTo(resultData); 217 String name = javaBlend(i%14, srcData, dstData); 218 assertTrue(name, similar(resultData,dstData)); 219 Log.v("BlendUnit", name + " " + similar(resultData, dstData)); 220 221 } 222 223 src.destroy(); 224 dst.destroy(); 225 mBlend.destroy(); 226 } 227 228 // utility to create and allocation of a given dimension creatAllocation(int w, int h)229 protected Allocation creatAllocation(int w, int h) { 230 Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS)); 231 b.setX(w); 232 b.setY(h); 233 return Allocation.createTyped(mRS, b.create(), Allocation.USAGE_SCRIPT); 234 } 235 236 // Compare two images ensuring returning false if error is greater than 2 237 // so that it can support integer and float non identical versions similar(byte[] a, byte[] b)238 public boolean similar(byte[] a, byte[] b) { 239 for (int i = 0; i < a.length; i++) { 240 int v1 = 0xFF & a[i]; 241 int v2 = 0xFF & b[i]; 242 int error = Math.abs(v1 - v2); 243 if (error > 2) { 244 return false; 245 } 246 } 247 return true; 248 } 249 // Build a test pattern to be the source pattern designed to provide a wide range of values buildSrc(byte[] srcData, int width, int height)250 public void buildSrc(byte[] srcData, int width, int height) { 251 for (int i = 0; i < srcData.length / 4; i++) { 252 int x = i % width; 253 int y = i / width; 254 int d = (x - width / 2) * (x - width / 2) + (y - height / 2) * (y - height / 2); 255 d = (255 * d) / ((width / 2) * (width / 2)); 256 d = (d > 255) ? 0 : d; 257 258 srcData[i * 4 + 0] = (byte) d; // red 259 srcData[i * 4 + 1] = (byte) d; // green 260 srcData[i * 4 + 2] = (byte) 0; // blue 261 srcData[i * 4 + 3] = (byte) y; // alpha 262 } 263 } 264 265 // Build a test pattern to be the destination pattern designed to provide a wide range of values buildDst(byte[] dstData, int width, int height)266 public void buildDst(byte[] dstData, int width, int height) { 267 for (int i = 0; i < dstData.length / 4; i++) { 268 int x = i % width; 269 int y = i / width; 270 271 dstData[i * 4 + 0] = (byte) 0; // red 272 dstData[i * 4 + 1] = (byte) 0; // green 273 dstData[i * 4 + 2] = (byte) y; // blue 274 dstData[i * 4 + 3] = (byte) x; // alpha 275 } 276 277 } 278 javaBlend(int type, byte[] src, byte[] dst)279 public String javaBlend(int type, byte[] src, byte[] dst) { 280 281 for (int i = 0; i < dst.length; i += 4) { 282 byte[] rgba = func[type].filter(src[i], src[i + 1], src[i + 2], src[i + 3], 283 dst[i], dst[i + 1], dst[i + 2], dst[i + 3]); 284 dst[i] = rgba[0]; 285 dst[i + 1] = rgba[1]; 286 dst[i + 2] = rgba[2]; 287 dst[i + 3] = rgba[3]; 288 } 289 return func[type].name; 290 } 291 292 // Base class for Java blend implementation supporting float and int implementations 293 294 abstract class BlendFunc { 295 float srcR, srcG, srcB, srcA; 296 float dstR, dstG, dstB, dstA; 297 int s_srcR, s_srcG, s_srcB, s_srcA; 298 int s_dstR, s_dstG, s_dstB, s_dstA; 299 byte[] rgba = new byte[4]; 300 String name; 301 clamp(int c)302 final int clamp(int c) { 303 final int N = 255; 304 c &= ~(c >> 31); 305 c -= N; 306 c &= (c >> 31); 307 c += N; 308 return c; 309 } 310 pack(float a, float r, float g, float b)311 int pack(float a, float r, float g, float b) { 312 int ia = clamp((int) (255 * a)); 313 int ir = clamp((int) (255 * r)); 314 int ig = clamp((int) (255 * g)); 315 int ib = clamp((int) (255 * b)); 316 rgba[0] = (byte) ir; 317 rgba[1] = (byte) ig; 318 rgba[2] = (byte) ib; 319 rgba[3] = (byte) ia; 320 return (ia << 24) | (ir << 16) | (ig << 8) | ib; 321 } 322 pack(int a, int r, int g, int b)323 int pack(int a, int r, int g, int b) { 324 325 rgba[0] = (byte) clamp(r); 326 rgba[1] = (byte) clamp(g); 327 rgba[2] = (byte) clamp(b); 328 rgba[3] = (byte) clamp(a); 329 return 0; 330 } 331 unpackSrc(int src)332 void unpackSrc(int src) { 333 s_srcR = (0xFF & (src >> 16)); 334 s_srcG = (0xFF & (src >> 8)); 335 s_srcB = (0xFF & (src >> 0)); 336 s_srcA = (0xFF & (src >> 24)); 337 float scale = 1 / 255f; 338 339 srcR = (0xFF & (src >> 16)) * scale; 340 srcG = (0xFF & (src >> 8)) * scale; 341 srcB = (0xFF & (src >> 0)) * scale; 342 srcA = (0xFF & (src >> 24)) * scale; 343 } 344 unpackDst(int dst)345 void unpackDst(int dst) { 346 float scale = 1 / 255f; 347 348 s_dstR = (0xFF & (dst >> 16)); 349 s_dstG = (0xFF & (dst >> 8)); 350 s_dstB = (0xFF & (dst >> 0)); 351 s_dstA = (0xFF & (dst >> 24)); 352 353 dstR = (0xFF & (dst >> 16)) * scale; 354 dstG = (0xFF & (dst >> 8)) * scale; 355 dstB = (0xFF & (dst >> 0)) * scale; 356 dstA = (0xFF & (dst >> 24)) * scale; 357 } 358 filter(int scr, int dst)359 int filter(int scr, int dst) { 360 unpackSrc(scr); 361 unpackDst(dst); 362 return blend(); 363 } 364 filter(byte srcR, byte srcG, byte srcB, byte srcA, byte dstR, byte dstG, byte dstB, byte dstA)365 byte[] filter(byte srcR, byte srcG, byte srcB, byte srcA, 366 byte dstR, byte dstG, byte dstB, byte dstA) { 367 float scale = 1 / 255f; 368 this.srcR = (0xFF & (srcR)) * scale; 369 this.srcG = (0xFF & (srcG)) * scale; 370 this.srcB = (0xFF & (srcB)) * scale; 371 this.srcA = (0xFF & (srcA)) * scale; 372 373 this.dstR = (0xFF & (dstR)) * scale; 374 this.dstG = (0xFF & (dstG)) * scale; 375 this.dstB = (0xFF & (dstB)) * scale; 376 this.dstA = (0xFF & (dstA)) * scale; 377 s_dstR = (0xFF & (dstR)); 378 s_dstG = (0xFF & (dstG)); 379 s_dstB = (0xFF & (dstB)); 380 s_dstA = (0xFF & (dstA)); 381 382 s_srcR = (0xFF & (srcR)); 383 s_srcG = (0xFF & (srcG)); 384 s_srcB = (0xFF & (srcB)); 385 s_srcA = (0xFF & (srcA)); 386 387 blend(); 388 return rgba; 389 } 390 blend()391 abstract int blend(); 392 } 393 394 BlendFunc blend_dstAtop = new BlendFunc() { 395 // dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb 396 // dst.a = src.a 397 { 398 name = "blend_dstAtop"; 399 } 400 401 @Override 402 int blend() { 403 float r = (dstR * srcA + (1 - dstA) * srcR); 404 float g = (dstG * srcA + (1 - dstA) * srcG); 405 float b = (dstB * srcA + (1 - dstA) * srcB); 406 float a = srcA; 407 408 return pack(a, r, g, b); 409 } 410 }; 411 BlendFunc blend_dstIn = new BlendFunc() { 412 // Sets dst = dst * src.a 413 { 414 name = "blend_dstIn"; 415 } 416 417 @Override 418 int blend() { 419 float r = (dstR * srcA); 420 float g = (dstG * srcA); 421 float b = (dstB * srcA); 422 float a = (dstA * srcA); 423 return pack(a, r, g, b); 424 } 425 }; 426 427 BlendFunc blend_add = new BlendFunc() { 428 // dst = dst + src 429 { 430 name = "blend_add"; 431 } 432 433 @Override 434 int blend() { 435 436 int r = Math.min(s_dstR + s_srcR, 255); 437 int g = Math.min(s_dstG + s_srcG, 255); 438 int b = Math.min(s_dstB + s_srcB, 255); 439 int a = Math.min(s_dstA + s_srcA, 255); 440 return pack(a, r, g, b); 441 442 } 443 }; 444 445 BlendFunc blend_clear = new BlendFunc() { 446 // Sets dst = {0, 0, 0, 0} 447 { 448 name = "blend_clear"; 449 } 450 451 @Override 452 int blend() { 453 return pack(0, 0, 0, 0); 454 } 455 }; 456 457 BlendFunc blend_dst = new BlendFunc() { 458 // Sets dst = dst 459 { 460 name = "blend_dst"; 461 } 462 463 @Override 464 int blend() { 465 return pack(dstA, dstR, dstG, dstB); 466 } 467 }; 468 469 BlendFunc blend_dstOut = new BlendFunc() { 470 // Sets dst = dst * (1.0 - src.a) 471 { 472 name = "blend_dstOut"; 473 } 474 475 @Override 476 int blend() { 477 float r = (dstR * (1 - srcA)); 478 float g = (dstG * (1 - srcA)); 479 float b = (dstB * (1 - srcA)); 480 float a = (dstA * (1 - srcA)); 481 return pack(a, r, g, b); 482 } 483 }; 484 BlendFunc blend_dstOver = new BlendFunc() { 485 // Sets dst = dst + src * (1.0 - dst.a) 486 { 487 name = "blend_dstOver"; 488 } 489 490 @Override 491 int blend() { 492 float r = dstR + (srcR * (1 - dstA)); 493 float g = dstG + (srcG * (1 - dstA)); 494 float b = dstB + (srcB * (1 - dstA)); 495 float a = dstA + (srcA * (1 - dstA)); 496 return pack(a, r, g, b); 497 } 498 }; 499 500 BlendFunc blend_multiply = new BlendFunc() { 501 // dst = dst * src 502 { 503 name = "blend_multiply"; 504 } 505 506 @Override 507 int blend() { 508 float r = (srcR * dstR); 509 float g = (srcG * dstG); 510 float b = (srcB * dstB); 511 float a = (srcA * dstA); 512 return pack(a, r, g, b); 513 } 514 }; 515 516 BlendFunc blend_src = new BlendFunc() { 517 // Sets dst = src 518 { 519 name = "blend_src"; 520 } 521 522 int blend() { 523 return pack(srcA, srcR, srcG, srcB); 524 525 } 526 }; 527 528 BlendFunc blend_srcAtop = new BlendFunc() { 529 // dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb 530 // dst.a = dst.a 531 { 532 name = "blend_srcAtop"; 533 } 534 535 @Override 536 int blend() { 537 float r = (srcR * dstA + (1 - srcA) * dstR); 538 float g = (srcG * dstA + (1 - srcA) * dstG); 539 float b = (srcB * dstA + (1 - srcA) * dstB); 540 float a = (srcA * dstA + (1 - srcA) * dstA); 541 return pack(a, r, g, b); 542 } 543 }; 544 545 BlendFunc blend_srcIn = new BlendFunc() { 546 // dst = src * dst.a 547 { 548 name = "blend_srcIn"; 549 } 550 551 @Override 552 int blend() { 553 float r = (srcR * dstA); 554 float g = (srcG * dstA); 555 float b = (srcB * dstA); 556 float a = (srcA * dstA); 557 ; 558 return pack(a, r, g, b); 559 } 560 }; 561 562 BlendFunc blend_srcOut = new BlendFunc() { 563 // Sets dst = src * (1.0 - dst.a) 564 { 565 name = "blend_srcOut"; 566 } 567 568 @Override 569 int blend() { 570 float r = (srcR * (1 - dstA)); 571 float g = (srcG * (1 - dstA)); 572 float b = (srcB * (1 - dstA)); 573 float a = (srcA * (1 - dstA)); 574 ; 575 return pack(a, r, g, b); 576 } 577 }; 578 579 BlendFunc blend_srcOver = new BlendFunc() { 580 // Sets dst = src + dst * (1.0 - src.a) 581 { 582 name = "blend_srcOver"; 583 } 584 585 @Override 586 int blend() { 587 float r = srcR + (dstR * (1 - srcA)); 588 float g = srcG + (dstG * (1 - srcA)); 589 float b = srcB + (dstB * (1 - srcA)); 590 float a = srcA + (dstA * (1 - srcA)); 591 return pack(a, r, g, b); 592 } 593 }; 594 595 BlendFunc blend_subtract = new BlendFunc() { 596 // Sets dst = dst - src 597 { 598 name = "blend_subtract"; 599 } 600 601 @Override 602 int blend() { 603 float r = Math.max(dstR - srcR, 0); 604 float g = Math.max(dstG - srcG, 0); 605 float b = Math.max(dstB - srcB, 0); 606 float a = Math.max(dstA - srcA, 0); 607 return pack(a, r, g, b); 608 } 609 }; 610 611 // Porter/Duff xor compositing 612 BlendFunc blend_pdxor = new BlendFunc() { 613 // dst.rgb = src.rgb*(1-dst.a)+(1-src.a)*dst.rgb; 614 // dst.a = src.a+dst.a - 2*src.a*dst.a 615 { 616 name = "blend_pdxor"; 617 } 618 619 @Override 620 int blend() { 621 float r = srcR * (1 - dstA) + (dstR * (1 - srcA)); 622 float g = srcG * (1 - dstA) + (dstG * (1 - srcA)); 623 float b = srcB * (1 - dstA) + (dstB * (1 - srcA)); 624 float a = srcA + dstA - (2 * srcA * dstA); 625 return pack(a, r, g, b); 626 } 627 }; 628 629 // NOT Porter/Duff xor compositing simple XOR 630 BlendFunc blend_xor = new BlendFunc() { 631 // Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a} 632 { 633 name = "blend_xor"; 634 } 635 636 @Override 637 int blend() { 638 float scale = 1 / 255f; 639 float r = (((int) (dstR * 255)) ^ ((int) (srcR * 255))) * scale; 640 float g = (((int) (dstG * 255)) ^ ((int) (srcG * 255))) * scale; 641 float b = (((int) (dstB * 255)) ^ ((int) (srcB * 255))) * scale; 642 float a = (((int) (dstA * 255)) ^ ((int) (srcA * 255))) * scale; 643 return pack(a, r, g, b); 644 } 645 }; 646 647 BlendFunc[] func = { 648 blend_src, 649 blend_dst, 650 blend_srcOver, 651 blend_dstOver, 652 blend_srcIn, 653 blend_dstIn, 654 blend_srcOut, 655 blend_dstOut, 656 blend_srcAtop, 657 blend_dstAtop, 658 blend_xor, 659 blend_add, 660 blend_subtract, 661 blend_multiply, 662 }; 663 testColorMatrix()664 public void testColorMatrix() { 665 ScriptIntrinsicColorMatrix mColorMatrix; 666 mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 667 668 Allocation a1_copy, a2_copy; 669 a1_copy = Allocation.createTyped(mRS, a1.getType()); 670 a2_copy = Allocation.createTyped(mRS, a2.getType()); 671 672 Matrix4f m = new Matrix4f(); 673 m.set(1, 0, 0.2f); 674 m.set(1, 1, 0.9f); 675 m.set(1, 2, 0.2f); 676 677 //test greyscale 678 mColorMatrix.setGreyscale(); 679 680 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 681 a2_copy.copy2DRangeFrom(0, 0, a2.getType().getX(), a2.getType().getY(), a2, 0, 0); 682 683 mColorMatrix.forEach(a1_copy, a2_copy); 684 685 //validate greyscale 686 687 688 //test color matrix 689 mColorMatrix.setColorMatrix(m); 690 691 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 692 a2_copy.copy2DRangeFrom(0, 0, a2.getType().getX(), a2.getType().getY(), a2, 0, 0); 693 694 mColorMatrix.forEach(a1_copy, a2_copy); 695 696 a1_copy.destroy(); 697 a2_copy.destroy(); 698 mColorMatrix.destroy(); 699 } 700 testConvolve3x3()701 public void testConvolve3x3() { 702 ScriptIntrinsicConvolve3x3 mConvolve3x3; 703 mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS)); 704 705 Allocation a1_copy, a2_copy; 706 a1_copy = Allocation.createTyped(mRS, a1.getType()); 707 a2_copy = Allocation.createTyped(mRS, a2.getType()); 708 709 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 710 711 float f[] = new float[9]; 712 f[0] = 0.f; f[1] = -1.f; f[2] = 0.f; 713 f[3] = -1.f; f[4] = 5.f; f[5] = -1.f; 714 f[6] = 0.f; f[7] = -1.f; f[8] = 0.f; 715 716 mConvolve3x3.setCoefficients(f); 717 mConvolve3x3.setInput(a1_copy); 718 mConvolve3x3.forEach(a2_copy); 719 720 a1_copy.destroy(); 721 a2_copy.destroy(); 722 mConvolve3x3.destroy(); 723 } 724 testConvolve5x5()725 public void testConvolve5x5() { 726 ScriptIntrinsicConvolve5x5 mConvolve5x5; 727 mConvolve5x5 = ScriptIntrinsicConvolve5x5.create(mRS, Element.U8_4(mRS)); 728 729 Allocation a1_copy, a2_copy; 730 a1_copy = Allocation.createTyped(mRS, a1.getType()); 731 a2_copy = Allocation.createTyped(mRS, a2.getType()); 732 733 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 734 735 float f[] = new float[25]; 736 f[0] = -1.f; f[1] = -3.f; f[2] = -4.f; f[3] = -3.f; f[4] = -1.f; 737 f[5] = -3.f; f[6] = 0.f; f[7] = 6.f; f[8] = 0.f; f[9] = -3.f; 738 f[10]= -4.f; f[11]= 6.f; f[12]= 20.f; f[13]= 6.f; f[14]= -4.f; 739 f[15]= -3.f; f[16]= 0.f; f[17]= 6.f; f[18]= 0.f; f[19]= -3.f; 740 f[20]= -1.f; f[21]= -3.f; f[22]= -4.f; f[23]= -3.f; f[24]= -1.f; 741 742 mConvolve5x5.setCoefficients(f); 743 mConvolve5x5.setInput(a1_copy); 744 mConvolve5x5.forEach(a2_copy); 745 746 a1_copy.destroy(); 747 a2_copy.destroy(); 748 mConvolve5x5.destroy(); 749 } 750 testLUT()751 public void testLUT() { 752 ScriptIntrinsicLUT mLUT; 753 mLUT = ScriptIntrinsicLUT.create(mRS, Element.U8_4(mRS)); 754 755 Allocation a1_copy, a2_copy; 756 a1_copy = Allocation.createTyped(mRS, a1.getType()); 757 a2_copy = Allocation.createTyped(mRS, a2.getType()); 758 759 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 760 761 for (int ct=0; ct < 256; ct++) { 762 float f = ((float)ct) / 255.f; 763 764 float r = f; 765 if (r < 0.5f) { 766 r = 4.0f * r * r * r; 767 } else { 768 r = 1.0f - r; 769 r = 1.0f - (4.0f * r * r * r); 770 } 771 mLUT.setRed(ct, (int)(r * 255.f + 0.5f)); 772 773 float g = f; 774 if (g < 0.5f) { 775 g = 2.0f * g * g; 776 } else { 777 g = 1.0f - g; 778 g = 1.0f - (2.0f * g * g); 779 } 780 mLUT.setGreen(ct, (int)(g * 255.f + 0.5f)); 781 782 float b = f * 0.5f + 0.25f; 783 mLUT.setBlue(ct, (int)(b * 255.f + 0.5f)); 784 } 785 786 mLUT.forEach(a1_copy, a2_copy); 787 788 a1_copy.destroy(); 789 a2_copy.destroy(); 790 mLUT.destroy(); 791 } 792 testScriptGroup()793 public void testScriptGroup() { 794 ScriptGroup group; 795 796 ScriptIntrinsicConvolve3x3 mConvolve3x3; 797 ScriptIntrinsicColorMatrix mColorMatrix; 798 799 mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS)); 800 mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 801 802 Allocation a1_copy, a2_copy; 803 a1_copy = Allocation.createTyped(mRS, a1.getType()); 804 a2_copy = Allocation.createTyped(mRS, a2.getType()); 805 806 a1_copy.copy2DRangeFrom(0, 0, a1.getType().getX(), a1.getType().getY(), a1, 0, 0); 807 808 float f[] = new float[9]; 809 f[0] = 0.f; f[1] = -1.f; f[2] = 0.f; 810 f[3] = -1.f; f[4] = 5.f; f[5] = -1.f; 811 f[6] = 0.f; f[7] = -1.f; f[8] = 0.f; 812 813 mConvolve3x3.setCoefficients(f); 814 815 Matrix4f m = new Matrix4f(); 816 m.set(1, 0, 0.2f); 817 m.set(1, 1, 0.9f); 818 m.set(1, 2, 0.2f); 819 mColorMatrix.setColorMatrix(m); 820 821 Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(dimX).setY(dimX).create(); 822 823 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 824 b.addKernel(mConvolve3x3.getKernelID()); 825 b.addKernel(mColorMatrix.getKernelID()); 826 b.addConnection(connect, mConvolve3x3.getKernelID(), mColorMatrix.getKernelID()); 827 group = b.create(); 828 829 mConvolve3x3.setInput(a1_copy); 830 group.setOutput(mColorMatrix.getKernelID(), a2_copy); 831 group.execute(); 832 833 // validate 834 835 a1_copy.destroy(); 836 a2_copy.destroy(); 837 mConvolve3x3.destroy(); 838 mColorMatrix.destroy(); 839 } 840 841 842 } 843