1 /* 2 * Copyright (C) 2008-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 #include <malloc.h> 18 19 #include "RenderScript.h" 20 #include "rsCppInternal.h" 21 22 using namespace android; 23 using namespace RSC; 24 25 ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e) 26 : Script(NULL, rs) { 27 mID = createDispatch(rs, RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID())); 28 mElement = e; 29 } 30 31 ScriptIntrinsic::~ScriptIntrinsic() { 32 33 } 34 35 sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) { 36 if (e->isCompatible(Element::U8_4(rs)) == false) { 37 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic"); 38 return NULL; 39 } 40 return new ScriptIntrinsic3DLUT(rs, e); 41 } 42 43 ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e) 44 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) { 45 46 } 47 void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) { 48 if (ain->getType()->getElement()->isCompatible(mElement) == false || 49 aout->getType()->getElement()->isCompatible(mElement) == false) { 50 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch"); 51 return; 52 } 53 Script::forEach(0, ain, aout, NULL, 0); 54 } 55 void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) { 56 sp<const Type> t = lut->getType(); 57 if (!t->getElement()->isCompatible(mElement)) { 58 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match"); 59 return; 60 } 61 if (t->getZ() == 0) { 62 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D"); 63 return; 64 } 65 66 Script::setVar(0, lut); 67 } 68 69 sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) { 70 if (e->isCompatible(Element::U8_4(rs)) == false) { 71 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic"); 72 return NULL; 73 } 74 return new ScriptIntrinsicBlend(rs, e); 75 } 76 77 ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e) 78 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) { 79 } 80 81 void ScriptIntrinsicBlend::forEachClear(sp<Allocation> in, sp<Allocation> out) { 82 if (in->getType()->getElement()->isCompatible(mElement) == false || 83 out->getType()->getElement()->isCompatible(mElement) == false) { 84 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 85 } 86 Script::forEach(0, in, out, NULL, 0); 87 } 88 89 void ScriptIntrinsicBlend::forEachSrc(sp<Allocation> in, sp<Allocation> out) { 90 if (in->getType()->getElement()->isCompatible(mElement) == false || 91 out->getType()->getElement()->isCompatible(mElement) == false) { 92 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 93 } 94 Script::forEach(1, in, out, NULL, 0); 95 } 96 97 void ScriptIntrinsicBlend::forEachDst(sp<Allocation> in, sp<Allocation> out) { 98 if (in->getType()->getElement()->isCompatible(mElement) == false || 99 out->getType()->getElement()->isCompatible(mElement) == false) { 100 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 101 } 102 Script::forEach(2, in, out, NULL, 0); 103 } 104 105 void ScriptIntrinsicBlend::forEachSrcOver(sp<Allocation> in, sp<Allocation> out) { 106 if (in->getType()->getElement()->isCompatible(mElement) == false || 107 out->getType()->getElement()->isCompatible(mElement) == false) { 108 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 109 } 110 Script::forEach(3, in, out, NULL, 0); 111 } 112 113 void ScriptIntrinsicBlend::forEachDstOver(sp<Allocation> in, sp<Allocation> out) { 114 if (in->getType()->getElement()->isCompatible(mElement) == false || 115 out->getType()->getElement()->isCompatible(mElement) == false) { 116 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 117 } 118 Script::forEach(4, in, out, NULL, 0); 119 } 120 121 void ScriptIntrinsicBlend::forEachSrcIn(sp<Allocation> in, sp<Allocation> out) { 122 if (in->getType()->getElement()->isCompatible(mElement) == false || 123 out->getType()->getElement()->isCompatible(mElement) == false) { 124 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 125 } 126 Script::forEach(5, in, out, NULL, 0); 127 } 128 129 void ScriptIntrinsicBlend::forEachDstIn(sp<Allocation> in, sp<Allocation> out) { 130 if (in->getType()->getElement()->isCompatible(mElement) == false || 131 out->getType()->getElement()->isCompatible(mElement) == false) { 132 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 133 } 134 Script::forEach(6, in, out, NULL, 0); 135 } 136 137 void ScriptIntrinsicBlend::forEachSrcOut(sp<Allocation> in, sp<Allocation> out) { 138 if (in->getType()->getElement()->isCompatible(mElement) == false || 139 out->getType()->getElement()->isCompatible(mElement) == false) { 140 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 141 } 142 Script::forEach(7, in, out, NULL, 0); 143 } 144 145 void ScriptIntrinsicBlend::forEachDstOut(sp<Allocation> in, sp<Allocation> out) { 146 if (in->getType()->getElement()->isCompatible(mElement) == false || 147 out->getType()->getElement()->isCompatible(mElement) == false) { 148 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 149 } 150 Script::forEach(8, in, out, NULL, 0); 151 } 152 153 void ScriptIntrinsicBlend::forEachSrcAtop(sp<Allocation> in, sp<Allocation> out) { 154 if (in->getType()->getElement()->isCompatible(mElement) == false || 155 out->getType()->getElement()->isCompatible(mElement) == false) { 156 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 157 } 158 Script::forEach(9, in, out, NULL, 0); 159 } 160 161 void ScriptIntrinsicBlend::forEachDstAtop(sp<Allocation> in, sp<Allocation> out) { 162 if (in->getType()->getElement()->isCompatible(mElement) == false || 163 out->getType()->getElement()->isCompatible(mElement) == false) { 164 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 165 } 166 Script::forEach(10, in, out, NULL, 0); 167 } 168 169 void ScriptIntrinsicBlend::forEachXor(sp<Allocation> in, sp<Allocation> out) { 170 if (in->getType()->getElement()->isCompatible(mElement) == false || 171 out->getType()->getElement()->isCompatible(mElement) == false) { 172 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 173 } 174 Script::forEach(11, in, out, NULL, 0); 175 } 176 177 // Numbering jumps here 178 void ScriptIntrinsicBlend::forEachMultiply(sp<Allocation> in, sp<Allocation> out) { 179 if (in->getType()->getElement()->isCompatible(mElement) == false || 180 out->getType()->getElement()->isCompatible(mElement) == false) { 181 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 182 } 183 Script::forEach(14, in, out, NULL, 0); 184 } 185 186 // Numbering jumps here 187 void ScriptIntrinsicBlend::forEachAdd(sp<Allocation> in, sp<Allocation> out) { 188 if (in->getType()->getElement()->isCompatible(mElement) == false || 189 out->getType()->getElement()->isCompatible(mElement) == false) { 190 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 191 } 192 Script::forEach(34, in, out, NULL, 0); 193 } 194 195 void ScriptIntrinsicBlend::forEachSubtract(sp<Allocation> in, sp<Allocation> out) { 196 if (in->getType()->getElement()->isCompatible(mElement) == false || 197 out->getType()->getElement()->isCompatible(mElement) == false) { 198 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend"); 199 } 200 Script::forEach(35, in, out, NULL, 0); 201 } 202 203 204 205 206 sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) { 207 if ((e->isCompatible(Element::U8_4(rs)) == false) && 208 (e->isCompatible(Element::U8(rs)) == false)) { 209 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur"); 210 return NULL; 211 } 212 return new ScriptIntrinsicBlur(rs, e); 213 } 214 215 ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e) 216 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) { 217 218 } 219 220 void ScriptIntrinsicBlur::setInput(sp<Allocation> in) { 221 if (in->getType()->getElement()->isCompatible(mElement) == false) { 222 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input"); 223 return; 224 } 225 Script::setVar(1, in); 226 } 227 228 void ScriptIntrinsicBlur::forEach(sp<Allocation> out) { 229 if (out->getType()->getElement()->isCompatible(mElement) == false) { 230 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output"); 231 return; 232 } 233 Script::forEach(0, NULL, out, NULL, 0); 234 } 235 236 void ScriptIntrinsicBlur::setRadius(float radius) { 237 if (radius > 0.f && radius <= 25.f) { 238 Script::setVar(0, &radius, sizeof(float)); 239 } else { 240 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound"); 241 } 242 } 243 244 245 246 sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs) { 247 return new ScriptIntrinsicColorMatrix(rs, Element::RGBA_8888(rs)); 248 } 249 250 ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e) 251 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) { 252 float add[4] = {0.f, 0.f, 0.f, 0.f}; 253 setAdd(add); 254 255 } 256 257 void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) { 258 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) && 259 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) && 260 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) && 261 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) && 262 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) && 263 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) && 264 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) && 265 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) { 266 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix"); 267 return; 268 } 269 270 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) && 271 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) && 272 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) && 273 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) && 274 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) && 275 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) && 276 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) && 277 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) { 278 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix"); 279 return; 280 } 281 282 Script::forEach(0, in, out, NULL, 0); 283 } 284 285 void ScriptIntrinsicColorMatrix::setAdd(float* add) { 286 Script::setVar(1, (void*)add, sizeof(float) * 4); 287 } 288 289 void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) { 290 float temp[16]; 291 temp[0] = m[0]; 292 temp[1] = m[1]; 293 temp[2] = m[2]; 294 temp[3] = 0.f; 295 296 temp[4] = m[3]; 297 temp[5] = m[4]; 298 temp[6] = m[5]; 299 temp[7] = 0.f; 300 301 temp[8] = m[6]; 302 temp[9] = m[7]; 303 temp[10] = m[8]; 304 temp[11] = 0.f; 305 306 temp[12] = 0.f; 307 temp[13] = 0.f; 308 temp[14] = 0.f; 309 temp[15] = 1.f; 310 311 setColorMatrix4(temp); 312 } 313 314 315 void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) { 316 Script::setVar(0, (void*)m, sizeof(float) * 16); 317 } 318 319 320 void ScriptIntrinsicColorMatrix::setGreyscale() { 321 float matrix[] = {0.299f, 0.299f, 0.299f,0.587f,0.587f,0.587f,0.114f,0.114f, 0.114f}; 322 setColorMatrix3(matrix); 323 } 324 325 326 void ScriptIntrinsicColorMatrix::setRGBtoYUV() { 327 float matrix[] = { 0.299f, -0.14713f, 0.615f, 0.587f, -0.28886f, -0.51499f, 0.114f, 0.436f, -0.10001f}; 328 setColorMatrix3(matrix); 329 } 330 331 332 void ScriptIntrinsicColorMatrix::setYUVtoRGB() { 333 float matrix[] = {1.f, 1.f, 1.f, 0.f, -0.39465f, 2.03211f, 1.13983f, -0.5806f, 0.f}; 334 setColorMatrix3(matrix); 335 } 336 337 338 339 sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) { 340 if (!(e->isCompatible(Element::U8(rs))) && 341 !(e->isCompatible(Element::U8_2(rs))) && 342 !(e->isCompatible(Element::U8_3(rs))) && 343 !(e->isCompatible(Element::U8_4(rs))) && 344 !(e->isCompatible(Element::F32(rs))) && 345 !(e->isCompatible(Element::F32_2(rs))) && 346 !(e->isCompatible(Element::F32_3(rs))) && 347 !(e->isCompatible(Element::F32_4(rs)))) { 348 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3"); 349 return NULL; 350 } 351 352 return new ScriptIntrinsicConvolve3x3(rs, e); 353 } 354 355 ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e) 356 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) { 357 358 } 359 360 void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) { 361 if (!(in->getType()->getElement()->isCompatible(mElement))) { 362 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3"); 363 return; 364 } 365 Script::setVar(1, in); 366 } 367 368 void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) { 369 if (!(out->getType()->getElement()->isCompatible(mElement))) { 370 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3"); 371 return; 372 } 373 Script::forEach(0, NULL, out, NULL, 0); 374 } 375 376 void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) { 377 Script::setVar(0, (void*)v, sizeof(float) * 9); 378 } 379 380 sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) { 381 if (!(e->isCompatible(Element::U8(rs))) && 382 !(e->isCompatible(Element::U8_2(rs))) && 383 !(e->isCompatible(Element::U8_3(rs))) && 384 !(e->isCompatible(Element::U8_4(rs))) && 385 !(e->isCompatible(Element::F32(rs))) && 386 !(e->isCompatible(Element::F32_2(rs))) && 387 !(e->isCompatible(Element::F32_3(rs))) && 388 !(e->isCompatible(Element::F32_4(rs)))) { 389 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5"); 390 return NULL; 391 } 392 393 return new ScriptIntrinsicConvolve5x5(rs, e); 394 } 395 396 ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e) 397 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) { 398 399 } 400 401 void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) { 402 if (!(in->getType()->getElement()->isCompatible(mElement))) { 403 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input"); 404 return; 405 } 406 Script::setVar(1, in); 407 } 408 409 void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) { 410 if (!(out->getType()->getElement()->isCompatible(mElement))) { 411 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output"); 412 return; 413 } 414 415 Script::forEach(0, NULL, out, NULL, 0); 416 } 417 418 void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) { 419 Script::setVar(0, (void*)v, sizeof(float) * 25); 420 } 421 422 sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) { 423 return new ScriptIntrinsicHistogram(rs, NULL); 424 } 425 426 ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e) 427 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) { 428 429 } 430 431 void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) { 432 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) && 433 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) && 434 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) && 435 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) && 436 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) && 437 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) && 438 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) && 439 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) { 440 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output"); 441 return; 442 } 443 444 if (out->getType()->getX() != 256 || 445 out->getType()->getY() != 0 || 446 out->getType()->hasMipmaps()) { 447 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output"); 448 return; 449 } 450 mOut = out; 451 Script::setVar(1, out); 452 } 453 454 void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) { 455 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) { 456 return; 457 } 458 if ((r + g + b + a) > 1.f) { 459 return; 460 } 461 462 FieldPacker fp(16); 463 fp.add(r); 464 fp.add(g); 465 fp.add(b); 466 fp.add(a); 467 Script::setVar(0, fp.getData(), fp.getLength()); 468 469 } 470 471 void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) { 472 if (ain->getType()->getElement()->getVectorSize() < 473 mOut->getType()->getElement()->getVectorSize()) { 474 mRS->throwError(RS_ERROR_INVALID_PARAMETER, 475 "Input vector size must be >= output vector size"); 476 return; 477 } 478 479 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) || 480 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) { 481 mRS->throwError(RS_ERROR_INVALID_ELEMENT, 482 "Input allocation to Histogram must be U8 or U8_4"); 483 return; 484 } 485 486 Script::forEach(0, ain, NULL, NULL, 0); 487 } 488 489 490 void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) { 491 if (mOut->getType()->getElement()->getVectorSize() != 1) { 492 mRS->throwError(RS_ERROR_INVALID_PARAMETER, 493 "Output Histogram allocation must have vector size of 1 " \ 494 "when used with forEach_dot"); 495 return; 496 } 497 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) || 498 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) { 499 mRS->throwError(RS_ERROR_INVALID_ELEMENT, 500 "Input allocation to Histogram must be U8 or U8_4"); 501 return; 502 } 503 504 Script::forEach(1, ain, NULL, NULL, 0); 505 } 506 507 sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) { 508 if (!(e->isCompatible(Element::U8_4(rs)))) { 509 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT"); 510 return NULL; 511 } 512 return new ScriptIntrinsicLUT(rs, e); 513 } 514 515 ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e) 516 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) { 517 LUT = Allocation::createSized(rs, Element::U8(rs), 1024); 518 for (int i = 0; i < 256; i++) { 519 mCache[i] = i; 520 mCache[i+256] = i; 521 mCache[i+512] = i; 522 mCache[i+768] = i; 523 } 524 setVar(0, LUT); 525 } 526 527 void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) { 528 if (mDirty) { 529 LUT->copy1DFrom((void*)mCache); 530 mDirty = false; 531 } 532 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) || 533 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) { 534 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT"); 535 return; 536 } 537 Script::forEach(0, ain, aout, NULL, 0); 538 539 } 540 541 void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned int length, unsigned char* lutValues) { 542 if ((base + length) > 256 || length == 0) { 543 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range"); 544 return; 545 } 546 mDirty = true; 547 for (unsigned int i = 0; i < length; i++) { 548 mCache[offset + base + i] = lutValues[i]; 549 } 550 } 551 552 void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) { 553 setTable(0, base, length, lutValues); 554 } 555 556 void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) { 557 setTable(256, base, length, lutValues); 558 } 559 560 void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) { 561 setTable(512, base, length, lutValues); 562 } 563 564 void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) { 565 setTable(768, base, length, lutValues); 566 } 567 568 ScriptIntrinsicLUT::~ScriptIntrinsicLUT() { 569 570 } 571 572 sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) { 573 if (!(e->isCompatible(Element::U8_4(rs)))) { 574 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB"); 575 return NULL; 576 } 577 return new ScriptIntrinsicYuvToRGB(rs, e); 578 } 579 580 ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e) 581 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) { 582 583 } 584 585 void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) { 586 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) { 587 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB"); 588 return; 589 } 590 Script::setVar(0, in); 591 } 592 593 void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) { 594 if (!(out->getType()->getElement()->isCompatible(mElement))) { 595 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB"); 596 return; 597 } 598 599 Script::forEach(0, NULL, out, NULL, 0); 600 } 601