blob: 2f52896267bbe515647c84fc8a8f3202d951488b [file] [log] [blame]
Tim Murray7f0d5682012-11-08 16:35:24 -08001/*
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
Tim Murray7f0d5682012-11-08 16:35:24 -080017#include <malloc.h>
18
19#include "RenderScript.h"
Tim Murray7f0d5682012-11-08 16:35:24 -080020
21using namespace android;
Tim Murray9eb7f4b2012-11-16 14:02:18 -080022using namespace RSC;
Tim Murray7f0d5682012-11-08 16:35:24 -080023
Tim Murray3cd44af2012-11-14 11:25:27 -080024ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e)
Tim Murray7f0d5682012-11-08 16:35:24 -080025 : Script(NULL, rs) {
Tim Murraya4230962013-07-17 16:50:10 -070026 mID = RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID());
Tim Murray10913a52013-08-20 17:19:47 -070027 mElement = e;
Tim Murray7f0d5682012-11-08 16:35:24 -080028}
29
Tim Murrayb27b1812013-08-05 14:00:40 -070030ScriptIntrinsic::~ScriptIntrinsic() {
31
32}
33
Tim Murray21fa7a02013-08-15 16:25:03 -070034sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -070035 if (e->isCompatible(Element::U8_4(rs)) == false) {
36 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
37 return NULL;
38 }
Tim Murray21fa7a02013-08-15 16:25:03 -070039 return new ScriptIntrinsic3DLUT(rs, e);
40}
41
Tim Murray89daad62013-07-29 14:30:02 -070042ScriptIntrinsic3DLUT::ScriptIntrinsic3DLUT(sp<RS> rs, sp<const Element> e)
43 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_3DLUT, e) {
44
45}
46void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murray10913a52013-08-20 17:19:47 -070047 if (ain->getType()->getElement()->isCompatible(mElement) == false ||
48 aout->getType()->getElement()->isCompatible(mElement) == false) {
49 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch");
50 return;
51 }
Tim Murray89daad62013-07-29 14:30:02 -070052 Script::forEach(0, ain, aout, NULL, 0);
53}
54void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) {
Tim Murray10913a52013-08-20 17:19:47 -070055 sp<const Type> t = lut->getType();
56 if (!t->getElement()->isCompatible(mElement)) {
57 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match");
58 return;
59 }
60 if (t->getZ() == 0) {
61 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D");
62 return;
63 }
64
Tim Murray89daad62013-07-29 14:30:02 -070065 Script::setVar(0, lut);
66}
67
Tim Murray21fa7a02013-08-15 16:25:03 -070068sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -070069 if (e->isCompatible(Element::U8_4(rs)) == false) {
70 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
71 return NULL;
72 }
Tim Murray21fa7a02013-08-15 16:25:03 -070073 return new ScriptIntrinsicBlend(rs, e);
74}
75
Tim Murray3cd44af2012-11-14 11:25:27 -080076ScriptIntrinsicBlend::ScriptIntrinsicBlend(sp<RS> rs, sp<const Element> e)
Tim Murray7f0d5682012-11-08 16:35:24 -080077 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLEND, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -080078}
79
80void ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070081 if (in->getType()->getElement()->isCompatible(mElement) == false ||
82 out->getType()->getElement()->isCompatible(mElement) == false) {
83 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
84 }
Tim Murray7f0d5682012-11-08 16:35:24 -080085 Script::forEach(0, in, out, NULL, 0);
86}
87
88void ScriptIntrinsicBlend::blendSrc(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070089 if (in->getType()->getElement()->isCompatible(mElement) == false ||
90 out->getType()->getElement()->isCompatible(mElement) == false) {
91 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
92 }
Tim Murray7f0d5682012-11-08 16:35:24 -080093 Script::forEach(1, in, out, NULL, 0);
94}
95
96void ScriptIntrinsicBlend::blendDst(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -070097 if (in->getType()->getElement()->isCompatible(mElement) == false ||
98 out->getType()->getElement()->isCompatible(mElement) == false) {
99 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
100 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800101 Script::forEach(2, in, out, NULL, 0);
102}
103
104void ScriptIntrinsicBlend::blendSrcOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700105 if (in->getType()->getElement()->isCompatible(mElement) == false ||
106 out->getType()->getElement()->isCompatible(mElement) == false) {
107 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
108 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800109 Script::forEach(3, in, out, NULL, 0);
110}
111
112void ScriptIntrinsicBlend::blendDstOver(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700113 if (in->getType()->getElement()->isCompatible(mElement) == false ||
114 out->getType()->getElement()->isCompatible(mElement) == false) {
115 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
116 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800117 Script::forEach(4, in, out, NULL, 0);
118}
119
120void ScriptIntrinsicBlend::blendSrcIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700121 if (in->getType()->getElement()->isCompatible(mElement) == false ||
122 out->getType()->getElement()->isCompatible(mElement) == false) {
123 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
124 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800125 Script::forEach(5, in, out, NULL, 0);
126}
127
128void ScriptIntrinsicBlend::blendDstIn(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700129 if (in->getType()->getElement()->isCompatible(mElement) == false ||
130 out->getType()->getElement()->isCompatible(mElement) == false) {
131 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
132 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800133 Script::forEach(6, in, out, NULL, 0);
134}
135
136void ScriptIntrinsicBlend::blendSrcOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700137 if (in->getType()->getElement()->isCompatible(mElement) == false ||
138 out->getType()->getElement()->isCompatible(mElement) == false) {
139 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
140 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800141 Script::forEach(7, in, out, NULL, 0);
142}
143
144void ScriptIntrinsicBlend::blendDstOut(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700145 if (in->getType()->getElement()->isCompatible(mElement) == false ||
146 out->getType()->getElement()->isCompatible(mElement) == false) {
147 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
148 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800149 Script::forEach(8, in, out, NULL, 0);
150}
151
152void ScriptIntrinsicBlend::blendSrcAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700153 if (in->getType()->getElement()->isCompatible(mElement) == false ||
154 out->getType()->getElement()->isCompatible(mElement) == false) {
155 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
156 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800157 Script::forEach(9, in, out, NULL, 0);
158}
159
160void ScriptIntrinsicBlend::blendDstAtop(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700161 if (in->getType()->getElement()->isCompatible(mElement) == false ||
162 out->getType()->getElement()->isCompatible(mElement) == false) {
163 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
164 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800165 Script::forEach(10, in, out, NULL, 0);
166}
167
168void ScriptIntrinsicBlend::blendXor(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700169 if (in->getType()->getElement()->isCompatible(mElement) == false ||
170 out->getType()->getElement()->isCompatible(mElement) == false) {
171 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
172 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800173 Script::forEach(11, in, out, NULL, 0);
174}
175
176// Numbering jumps here
177void ScriptIntrinsicBlend::blendMultiply(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700178 if (in->getType()->getElement()->isCompatible(mElement) == false ||
179 out->getType()->getElement()->isCompatible(mElement) == false) {
180 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
181 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800182 Script::forEach(14, in, out, NULL, 0);
183}
184
185// Numbering jumps here
186void ScriptIntrinsicBlend::blendAdd(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700187 if (in->getType()->getElement()->isCompatible(mElement) == false ||
188 out->getType()->getElement()->isCompatible(mElement) == false) {
189 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
190 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800191 Script::forEach(34, in, out, NULL, 0);
192}
193
194void ScriptIntrinsicBlend::blendSubtract(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700195 if (in->getType()->getElement()->isCompatible(mElement) == false ||
196 out->getType()->getElement()->isCompatible(mElement) == false) {
197 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
198 }
Tim Murray7f0d5682012-11-08 16:35:24 -0800199 Script::forEach(35, in, out, NULL, 0);
200}
201
Tim Murray89daad62013-07-29 14:30:02 -0700202
203
204
Tim Murray21fa7a02013-08-15 16:25:03 -0700205sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700206 if ((e->isCompatible(Element::U8_4(rs)) == false) &&
207 (e->isCompatible(Element::U8(rs)) == false)) {
208 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur");
209 return NULL;
210 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700211 return new ScriptIntrinsicBlur(rs, e);
212}
213
Tim Murray3cd44af2012-11-14 11:25:27 -0800214ScriptIntrinsicBlur::ScriptIntrinsicBlur(sp<RS> rs, sp<const Element> e)
Tim Murray8f1e60c2012-11-13 12:25:11 -0800215 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLUR, e) {
Tim Murray7f0d5682012-11-08 16:35:24 -0800216
Tim Murray8f1e60c2012-11-13 12:25:11 -0800217}
Tim Murray7f0d5682012-11-08 16:35:24 -0800218
Tim Murray21fa7a02013-08-15 16:25:03 -0700219void ScriptIntrinsicBlur::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700220 if (in->getType()->getElement()->isCompatible(mElement) == false) {
221 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input");
222 return;
223 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800224 Script::setVar(1, in);
Tim Murray21fa7a02013-08-15 16:25:03 -0700225}
226
227void ScriptIntrinsicBlur::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700228 if (out->getType()->getElement()->isCompatible(mElement) == false) {
229 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output");
230 return;
231 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800232 Script::forEach(0, NULL, out, NULL, 0);
233}
Tim Murray7f0d5682012-11-08 16:35:24 -0800234
Tim Murray8f1e60c2012-11-13 12:25:11 -0800235void ScriptIntrinsicBlur::setRadius(float radius) {
Tim Murray10913a52013-08-20 17:19:47 -0700236 if (radius > 0.f && radius <= 25.f) {
237 Script::setVar(0, &radius, sizeof(float));
238 } else {
239 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound");
240 }
Tim Murray8f1e60c2012-11-13 12:25:11 -0800241}
Tim Murray89daad62013-07-29 14:30:02 -0700242
243
244
Tim Murray21fa7a02013-08-15 16:25:03 -0700245sp<ScriptIntrinsicColorMatrix> ScriptIntrinsicColorMatrix::create(sp<RS> rs, sp<const Element> e) {
246 return new ScriptIntrinsicColorMatrix(rs, e);
247}
248
Tim Murray89daad62013-07-29 14:30:02 -0700249ScriptIntrinsicColorMatrix::ScriptIntrinsicColorMatrix(sp<RS> rs, sp<const Element> e)
250 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_COLOR_MATRIX, e) {
251
252}
253
254void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700255 if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
256 !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
257 !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
258 !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
259 !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
260 !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
261 !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
262 !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
263 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
264 return;
265 }
266
267 if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
268 !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
269 !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
270 !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
271 !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
272 !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
273 !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
274 !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
275 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
276 return;
277 }
278
Tim Murray89daad62013-07-29 14:30:02 -0700279 Script::forEach(0, in, out, NULL, 0);
280}
281
Tim Murray10913a52013-08-20 17:19:47 -0700282void ScriptIntrinsicColorMatrix::setAdd(float* add) {
283 Script::setVar(1, (void*)add, sizeof(float) * 4);
284}
Tim Murray89daad62013-07-29 14:30:02 -0700285
286void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
287 Script::setVar(0, (void*)m, sizeof(float) * 9);
288}
289
290
291void ScriptIntrinsicColorMatrix::setColorMatrix4(float* m) {
292 Script::setVar(0, (void*)m, sizeof(float) * 16);
293}
294
295
296void ScriptIntrinsicColorMatrix::setGreyscale() {
297 float matrix[] = {0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f, 0.299f, 0.587f, 0.114f};
298 setColorMatrix3(matrix);
299}
300
301
302void ScriptIntrinsicColorMatrix::setRGBtoYUV() {
303 float matrix[] = {0.299f,0.587f,0.114f,-0.14713f,-0.28886f,0.436f,0.615f,-0.51499f,-0.10001f};
304 setColorMatrix3(matrix);
305}
306
307
308void ScriptIntrinsicColorMatrix::setYUVtoRGB() {
309 float matrix[] = {1.f,0.f,1.13983f,1.f,-0.39465f,-0.5806f,1.f,2.03211f,0.f};
310 setColorMatrix3(matrix);
311}
312
Tim Murray21fa7a02013-08-15 16:25:03 -0700313
314
315sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700316 if (!(e->isCompatible(Element::U8(rs))) &&
317 !(e->isCompatible(Element::U8_2(rs))) &&
318 !(e->isCompatible(Element::U8_3(rs))) &&
319 !(e->isCompatible(Element::U8_4(rs))) &&
320 !(e->isCompatible(Element::F32(rs))) &&
321 !(e->isCompatible(Element::F32_2(rs))) &&
322 !(e->isCompatible(Element::F32_3(rs))) &&
323 !(e->isCompatible(Element::F32_4(rs)))) {
324 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3");
325 return NULL;
326 }
327
Tim Murray21fa7a02013-08-15 16:25:03 -0700328 return new ScriptIntrinsicConvolve3x3(rs, e);
329}
330
Tim Murray89daad62013-07-29 14:30:02 -0700331ScriptIntrinsicConvolve3x3::ScriptIntrinsicConvolve3x3(sp<RS> rs, sp<const Element> e)
332 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_3x3, e) {
333
334}
335
336void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700337 if (!(in->getType()->getElement()->isCompatible(mElement))) {
338 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
339 return;
340 }
Tim Murray89daad62013-07-29 14:30:02 -0700341 Script::setVar(1, in);
342}
343
344void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700345 if (!(out->getType()->getElement()->isCompatible(mElement))) {
346 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
347 return;
348 }
Tim Murray89daad62013-07-29 14:30:02 -0700349 Script::forEach(0, NULL, out, NULL, 0);
350}
351
352void ScriptIntrinsicConvolve3x3::setCoefficients(float* v) {
353 Script::setVar(0, (void*)v, sizeof(float) * 9);
354}
355
Tim Murray21fa7a02013-08-15 16:25:03 -0700356sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700357 if (!(e->isCompatible(Element::U8(rs))) &&
358 !(e->isCompatible(Element::U8_2(rs))) &&
359 !(e->isCompatible(Element::U8_3(rs))) &&
360 !(e->isCompatible(Element::U8_4(rs))) &&
361 !(e->isCompatible(Element::F32(rs))) &&
362 !(e->isCompatible(Element::F32_2(rs))) &&
363 !(e->isCompatible(Element::F32_3(rs))) &&
364 !(e->isCompatible(Element::F32_4(rs)))) {
365 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5");
366 return NULL;
367 }
368
Tim Murray21fa7a02013-08-15 16:25:03 -0700369 return new ScriptIntrinsicConvolve5x5(rs, e);
370}
371
Tim Murray89daad62013-07-29 14:30:02 -0700372ScriptIntrinsicConvolve5x5::ScriptIntrinsicConvolve5x5(sp<RS> rs, sp<const Element> e)
373 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_CONVOLVE_5x5, e) {
374
375}
376
377void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
Tim Murray10913a52013-08-20 17:19:47 -0700378 if (!(in->getType()->getElement()->isCompatible(mElement))) {
379 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input");
380 return;
381 }
Tim Murray89daad62013-07-29 14:30:02 -0700382 Script::setVar(1, in);
383}
384
385void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700386 if (!(out->getType()->getElement()->isCompatible(mElement))) {
387 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output");
388 return;
389 }
390
Tim Murray89daad62013-07-29 14:30:02 -0700391 Script::forEach(0, NULL, out, NULL, 0);
392}
393
394void ScriptIntrinsicConvolve5x5::setCoefficients(float* v) {
395 Script::setVar(0, (void*)v, sizeof(float) * 25);
396}
397
Tim Murray10913a52013-08-20 17:19:47 -0700398sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) {
399 return new ScriptIntrinsicHistogram(rs, NULL);
Tim Murray21fa7a02013-08-15 16:25:03 -0700400}
401
Tim Murrayb27b1812013-08-05 14:00:40 -0700402ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
403 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_HISTOGRAM, e) {
Tim Murray89daad62013-07-29 14:30:02 -0700404
405}
406
Tim Murray10913a52013-08-20 17:19:47 -0700407void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) {
408 if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) &&
409 !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) &&
410 !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) &&
411 !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) &&
412 !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) &&
413 !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) &&
414 !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) &&
415 !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) {
416 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output");
417 return;
418 }
419
420 if (out->getType()->getX() != 256 ||
421 out->getType()->getY() != 0 ||
422 out->getType()->hasMipmaps()) {
423 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output");
424 return;
425 }
426 mOut = out;
427 Script::setVar(1, out);
Tim Murrayb27b1812013-08-05 14:00:40 -0700428}
429
430void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) {
431 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
432 return;
433 }
434 if ((r + g + b + a) > 1.f) {
435 return;
436 }
437
438 FieldPacker fp(16);
439 fp.add(r);
440 fp.add(g);
441 fp.add(b);
442 fp.add(a);
443 Script::setVar(0, fp.getData(), fp.getLength());
444
445}
446
447void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700448 if (ain->getType()->getElement()->getVectorSize() <
449 mOut->getType()->getElement()->getVectorSize()) {
450 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
451 "Input vector size must be >= output vector size");
452 return;
453 }
454
455 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
456 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
457 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
458 "Input allocation to Histogram must be U8 or U8_4");
459 return;
460 }
461
Tim Murrayb27b1812013-08-05 14:00:40 -0700462 Script::forEach(0, ain, NULL, NULL, 0);
463}
464
465
466void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) {
Tim Murray10913a52013-08-20 17:19:47 -0700467 if (mOut->getType()->getElement()->getVectorSize() != 1) {
468 mRS->throwError(RS_ERROR_INVALID_PARAMETER,
469 "Output Histogram allocation must have vector size of 1 " \
470 "when used with forEach_dot");
471 return;
472 }
473 if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
474 !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
475 mRS->throwError(RS_ERROR_INVALID_ELEMENT,
476 "Input allocation to Histogram must be U8 or U8_4");
477 return;
478 }
479
Tim Murrayb27b1812013-08-05 14:00:40 -0700480 Script::forEach(1, ain, NULL, NULL, 0);
481}
482
Tim Murray21fa7a02013-08-15 16:25:03 -0700483sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700484 if (!(e->isCompatible(Element::U8_4(rs)))) {
485 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
486 return NULL;
487 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700488 return new ScriptIntrinsicLUT(rs, e);
489}
490
Tim Murrayb27b1812013-08-05 14:00:40 -0700491ScriptIntrinsicLUT::ScriptIntrinsicLUT(sp<RS> rs, sp<const Element> e)
492 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_LUT, e), mDirty(true) {
493 LUT = Allocation::createSized(rs, e, 1024);
494 for (int i = 0; i < 256; i++) {
495 mCache[i] = i;
496 mCache[i+256] = i;
497 mCache[i+512] = i;
498 mCache[i+768] = i;
499 }
500}
501
Tim Murray89daad62013-07-29 14:30:02 -0700502void ScriptIntrinsicLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
Tim Murrayb27b1812013-08-05 14:00:40 -0700503 if (mDirty) {
504 LUT->copy1DFrom((void*)mCache);
505 mDirty = false;
506 }
Tim Murray10913a52013-08-20 17:19:47 -0700507 if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) ||
508 !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
509 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
510 return;
511 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700512 Script::forEach(0, ain, aout, NULL, 0);
Tim Murray89daad62013-07-29 14:30:02 -0700513
514}
515
Tim Murrayb27b1812013-08-05 14:00:40 -0700516void ScriptIntrinsicLUT::setTable(unsigned int offset, unsigned char base, unsigned char length, unsigned char* lutValues) {
517 if ((base + length) >= 256 || length == 0) {
518 return;
519 }
520 mDirty = true;
521 for (int i = 0; i < length; i++) {
522 mCache[offset + base + i] = lutValues[i];
523 }
524}
Tim Murray89daad62013-07-29 14:30:02 -0700525
Tim Murrayb27b1812013-08-05 14:00:40 -0700526void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned char length, unsigned char* lutValues) {
Tim Murray10913a52013-08-20 17:19:47 -0700527 if (base + length >= 256) {
528 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
529 return;
530 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700531 setTable(0, base, length, lutValues);
532}
Tim Murray89daad62013-07-29 14:30:02 -0700533
Tim Murrayb27b1812013-08-05 14:00:40 -0700534void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned char length, unsigned char* lutValues) {
Tim Murray10913a52013-08-20 17:19:47 -0700535 if (base + length >= 256) {
536 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
537 return;
538 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700539 setTable(256, base, length, lutValues);
540}
541
542void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned char length, unsigned char* lutValues) {
Tim Murray10913a52013-08-20 17:19:47 -0700543 if (base + length >= 256) {
544 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
545 return;
546 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700547 setTable(512, base, length, lutValues);
548}
549
550void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned char length, unsigned char* lutValues) {
Tim Murray10913a52013-08-20 17:19:47 -0700551 if (base + length >= 256) {
552 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
553 return;
554 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700555 setTable(768, base, length, lutValues);
556}
557
558ScriptIntrinsicLUT::~ScriptIntrinsicLUT() {
559
560}
561
Tim Murray21fa7a02013-08-15 16:25:03 -0700562sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) {
Tim Murray10913a52013-08-20 17:19:47 -0700563 if (!(e->isCompatible(Element::U8_4(rs)))) {
564 rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB");
565 return NULL;
566 }
Tim Murray21fa7a02013-08-15 16:25:03 -0700567 return new ScriptIntrinsicYuvToRGB(rs, e);
568}
569
Tim Murrayb27b1812013-08-05 14:00:40 -0700570ScriptIntrinsicYuvToRGB::ScriptIntrinsicYuvToRGB(sp<RS> rs, sp<const Element> e)
571 : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_YUV_TO_RGB, e) {
572
573}
574
575void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) {
Tim Murrayeb4426d2013-08-27 15:30:16 -0700576 if (!(in->getType()->getElement()->isCompatible(Element::YUV(mRS)))) {
Tim Murray10913a52013-08-20 17:19:47 -0700577 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB");
578 return;
579 }
Tim Murrayb27b1812013-08-05 14:00:40 -0700580 Script::setVar(0, in);
581}
582
583void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) {
Tim Murray10913a52013-08-20 17:19:47 -0700584 if (!(out->getType()->getElement()->isCompatible(mElement))) {
585 mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB");
586 return;
587 }
588
Tim Murrayb27b1812013-08-05 14:00:40 -0700589 Script::forEach(0, NULL, out, NULL, 0);
590}