• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ScriptIntrinsic(sp<RS> rs,int id,sp<const Element> e)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 
~ScriptIntrinsic()31 ScriptIntrinsic::~ScriptIntrinsic() {
32 
33 }
34 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsic3DLUT(sp<RS> rs,sp<const Element> e)43 ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
44     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
45 
46 }
forEach(sp<Allocation> ain,sp<Allocation> aout)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 }
setLUT(sp<Allocation> lut)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 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsicBlend(sp<RS> rs,sp<const Element> e)77 ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
78     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
79 }
80 
forEachClear(sp<Allocation> in,sp<Allocation> out)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 
forEachSrc(sp<Allocation> in,sp<Allocation> out)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 
forEachDst(sp<Allocation> in,sp<Allocation> out)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 
forEachSrcOver(sp<Allocation> in,sp<Allocation> out)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 
forEachDstOver(sp<Allocation> in,sp<Allocation> out)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 
forEachSrcIn(sp<Allocation> in,sp<Allocation> out)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 
forEachDstIn(sp<Allocation> in,sp<Allocation> out)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 
forEachSrcOut(sp<Allocation> in,sp<Allocation> out)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 
forEachDstOut(sp<Allocation> in,sp<Allocation> out)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 
forEachSrcAtop(sp<Allocation> in,sp<Allocation> out)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 
forEachDstAtop(sp<Allocation> in,sp<Allocation> out)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 
forEachXor(sp<Allocation> in,sp<Allocation> out)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
forEachMultiply(sp<Allocation> in,sp<Allocation> out)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
forEachAdd(sp<Allocation> in,sp<Allocation> out)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 
forEachSubtract(sp<Allocation> in,sp<Allocation> out)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 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsicBlur(sp<RS> rs,sp<const Element> e)215 ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
216     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
217 
218 }
219 
setInput(sp<Allocation> in)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 
forEach(sp<Allocation> out)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 
setRadius(float radius)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 
create(sp<RS> rs)246 sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs) {
247     return new ScriptIntrinsicColorMatrix(rs, Element::RGBA_8888(rs));
248 }
249 
ScriptIntrinsicColorMatrix(sp<RS> rs,sp<const Element> e)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 
forEach(sp<Allocation> in,sp<Allocation> out)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 
setAdd(float * add)285 void ScriptIntrinsicColorMatrix::setAdd(float* add) {
286     Script::setVar(1, (void*)add, sizeof(float) * 4);
287 }
288 
setColorMatrix3(float * m)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 
setColorMatrix4(float * m)315 void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
316     Script::setVar(0, (void*)m, sizeof(float) * 16);
317 }
318 
319 
setGreyscale()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 
setRGBtoYUV()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 
setYUVtoRGB()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 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsicConvolve3x3(sp<RS> rs,sp<const Element> e)355 ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
356     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
357 
358 }
359 
setInput(sp<Allocation> in)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 
forEach(sp<Allocation> out)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 
setCoefficients(float * v)376 void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
377     Script::setVar(0, (void*)v, sizeof(float) * 9);
378 }
379 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsicConvolve5x5(sp<RS> rs,sp<const Element> e)396 ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
397     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
398 
399 }
400 
setInput(sp<Allocation> in)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 
forEach(sp<Allocation> out)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 
setCoefficients(float * v)418 void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
419     Script::setVar(0, (void*)v, sizeof(float) * 25);
420 }
421 
create(sp<RS> rs)422 sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) {
423     return new ScriptIntrinsicHistogram(rs, NULL);
424 }
425 
ScriptIntrinsicHistogram(sp<RS> rs,sp<const Element> e)426 ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
427     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) {
428 
429 }
430 
setOutput(sp<Allocation> out)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 
setDotCoefficients(float r,float g,float b,float a)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 
forEach(sp<Allocation> ain)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 
forEach_dot(sp<Allocation> ain)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 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsicLUT(sp<RS> rs,sp<const Element> e)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 
forEach(sp<Allocation> ain,sp<Allocation> aout)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 
setTable(unsigned int offset,unsigned char base,unsigned int length,unsigned char * lutValues)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 
setRed(unsigned char base,unsigned int length,unsigned char * lutValues)552 void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned int length, unsigned char* lutValues) {
553     setTable(0, base, length, lutValues);
554 }
555 
setGreen(unsigned char base,unsigned int length,unsigned char * lutValues)556 void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned int length, unsigned char* lutValues) {
557     setTable(256, base, length, lutValues);
558 }
559 
setBlue(unsigned char base,unsigned int length,unsigned char * lutValues)560 void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned int length, unsigned char* lutValues) {
561     setTable(512, base, length, lutValues);
562 }
563 
setAlpha(unsigned char base,unsigned int length,unsigned char * lutValues)564 void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned int length, unsigned char* lutValues) {
565     setTable(768, base, length, lutValues);
566 }
567 
~ScriptIntrinsicLUT()568 ScriptIntrinsicLUT::~ScriptIntrinsicLUT() {
569 
570 }
571 
create(sp<RS> rs,sp<const Element> e)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 
ScriptIntrinsicYuvToRGB(sp<RS> rs,sp<const Element> e)580 ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e)
581     : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) {
582 
583 }
584 
setInput(sp<Allocation> in)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 
forEach(sp<Allocation> out)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