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