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