Make error handling kill context activity. Add parameter validation.
bug 10427951
Change-Id: I4abba969e34903265b84ee88d6a90bc9b9df5481
diff --git a/cpp/ScriptIntrinsics.cpp b/cpp/ScriptIntrinsics.cpp
index ab24952..e4bf907 100644
--- a/cpp/ScriptIntrinsics.cpp
+++ b/cpp/ScriptIntrinsics.cpp
@@ -24,6 +24,7 @@
ScriptIntrinsic::ScriptIntrinsic(sp<RS> rs, int id, sp<const Element> e)
: Script(NULL, rs) {
mID = RS::dispatch->ScriptIntrinsicCreate(rs->getContext(), id, e->getID());
+ mElement = e;
}
ScriptIntrinsic::~ScriptIntrinsic() {
@@ -31,6 +32,10 @@
}
sp<ScriptIntrinsic3DLUT> ScriptIntrinsic3DLUT::create(sp<RS> rs, sp<const Element> e) {
+ if (e->isCompatible(Element::U8_4(rs)) == false) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
+ return NULL;
+ }
return new ScriptIntrinsic3DLUT(rs, e);
}
@@ -39,13 +44,32 @@
}
void ScriptIntrinsic3DLUT::forEach(sp<Allocation> ain, sp<Allocation> aout) {
+ if (ain->getType()->getElement()->isCompatible(mElement) == false ||
+ aout->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "3DLUT forEach element mismatch");
+ return;
+ }
Script::forEach(0, ain, aout, NULL, 0);
}
void ScriptIntrinsic3DLUT::setLUT(sp<Allocation> lut) {
+ sp<const Type> t = lut->getType();
+ if (!t->getElement()->isCompatible(mElement)) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "setLUT element does not match");
+ return;
+ }
+ if (t->getZ() == 0) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "setLUT Allocation must be 3D");
+ return;
+ }
+
Script::setVar(0, lut);
}
sp<ScriptIntrinsicBlend> ScriptIntrinsicBlend::create(sp<RS> rs, sp<const Element> e) {
+ if (e->isCompatible(Element::U8_4(rs)) == false) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Element not supported for intrinsic");
+ return NULL;
+ }
return new ScriptIntrinsicBlend(rs, e);
}
@@ -54,64 +78,124 @@
}
void ScriptIntrinsicBlend::blendClear(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(0, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendSrc(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(1, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendDst(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(2, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendSrcOver(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(3, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendDstOver(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(4, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendSrcIn(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(5, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendDstIn(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(6, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendSrcOut(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(7, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendDstOut(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(8, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendSrcAtop(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(9, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendDstAtop(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(10, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendXor(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(11, in, out, NULL, 0);
}
// Numbering jumps here
void ScriptIntrinsicBlend::blendMultiply(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(14, in, out, NULL, 0);
}
// Numbering jumps here
void ScriptIntrinsicBlend::blendAdd(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(34, in, out, NULL, 0);
}
void ScriptIntrinsicBlend::blendSubtract(sp<Allocation> in, sp<Allocation> out) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false ||
+ out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blend");
+ }
Script::forEach(35, in, out, NULL, 0);
}
@@ -119,6 +203,11 @@
sp<ScriptIntrinsicBlur> ScriptIntrinsicBlur::create(sp<RS> rs, sp<const Element> e) {
+ if ((e->isCompatible(Element::U8_4(rs)) == false) &&
+ (e->isCompatible(Element::U8(rs)) == false)) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur");
+ return NULL;
+ }
return new ScriptIntrinsicBlur(rs, e);
}
@@ -128,15 +217,27 @@
}
void ScriptIntrinsicBlur::setInput(sp<Allocation> in) {
+ if (in->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur input");
+ return;
+ }
Script::setVar(1, in);
}
void ScriptIntrinsicBlur::forEach(sp<Allocation> out) {
+ if (out->getType()->getElement()->isCompatible(mElement) == false) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element in blur output");
+ return;
+ }
Script::forEach(0, NULL, out, NULL, 0);
}
void ScriptIntrinsicBlur::setRadius(float radius) {
- Script::setVar(0, &radius, sizeof(float));
+ if (radius > 0.f && radius <= 25.f) {
+ Script::setVar(0, &radius, sizeof(float));
+ } else {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Blur radius out of 0-25 pixel bound");
+ }
}
@@ -151,9 +252,36 @@
}
void ScriptIntrinsicColorMatrix::forEach(sp<Allocation> in, sp<Allocation> out) {
+ if (!(in->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
+ !(in->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
+ return;
+ }
+
+ if (!(out->getType()->getElement()->isCompatible(Element::U8(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::U8_2(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::U8_3(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::U8_4(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::F32(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::F32_2(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::F32_3(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::F32_4(mRS)))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for ColorMatrix");
+ return;
+ }
+
Script::forEach(0, in, out, NULL, 0);
}
+void ScriptIntrinsicColorMatrix::setAdd(float* add) {
+ Script::setVar(1, (void*)add, sizeof(float) * 4);
+}
void ScriptIntrinsicColorMatrix::setColorMatrix3(float* m) {
Script::setVar(0, (void*)m, sizeof(float) * 9);
@@ -185,6 +313,18 @@
sp<ScriptIntrinsicConvolve3x3> ScriptIntrinsicConvolve3x3::create(sp<RS> rs, sp<const Element> e) {
+ if (!(e->isCompatible(Element::U8(rs))) &&
+ !(e->isCompatible(Element::U8_2(rs))) &&
+ !(e->isCompatible(Element::U8_3(rs))) &&
+ !(e->isCompatible(Element::U8_4(rs))) &&
+ !(e->isCompatible(Element::F32(rs))) &&
+ !(e->isCompatible(Element::F32_2(rs))) &&
+ !(e->isCompatible(Element::F32_3(rs))) &&
+ !(e->isCompatible(Element::F32_4(rs)))) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve3x3");
+ return NULL;
+ }
+
return new ScriptIntrinsicConvolve3x3(rs, e);
}
@@ -194,10 +334,18 @@
}
void ScriptIntrinsicConvolve3x3::setInput(sp<Allocation> in) {
+ if (!(in->getType()->getElement()->isCompatible(mElement))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
+ return;
+ }
Script::setVar(1, in);
}
void ScriptIntrinsicConvolve3x3::forEach(sp<Allocation> out) {
+ if (!(out->getType()->getElement()->isCompatible(mElement))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve3x3");
+ return;
+ }
Script::forEach(0, NULL, out, NULL, 0);
}
@@ -206,6 +354,18 @@
}
sp<ScriptIntrinsicConvolve5x5> ScriptIntrinsicConvolve5x5::create(sp<RS> rs, sp<const Element> e) {
+ if (!(e->isCompatible(Element::U8(rs))) &&
+ !(e->isCompatible(Element::U8_2(rs))) &&
+ !(e->isCompatible(Element::U8_3(rs))) &&
+ !(e->isCompatible(Element::U8_4(rs))) &&
+ !(e->isCompatible(Element::F32(rs))) &&
+ !(e->isCompatible(Element::F32_2(rs))) &&
+ !(e->isCompatible(Element::F32_3(rs))) &&
+ !(e->isCompatible(Element::F32_4(rs)))) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Convolve5x5");
+ return NULL;
+ }
+
return new ScriptIntrinsicConvolve5x5(rs, e);
}
@@ -215,10 +375,19 @@
}
void ScriptIntrinsicConvolve5x5::setInput(sp<Allocation> in) {
+ if (!(in->getType()->getElement()->isCompatible(mElement))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 input");
+ return;
+ }
Script::setVar(1, in);
}
void ScriptIntrinsicConvolve5x5::forEach(sp<Allocation> out) {
+ if (!(out->getType()->getElement()->isCompatible(mElement))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Element mismatch in Convolve5x5 output");
+ return;
+ }
+
Script::forEach(0, NULL, out, NULL, 0);
}
@@ -226,8 +395,8 @@
Script::setVar(0, (void*)v, sizeof(float) * 25);
}
-sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs, sp<const Element> e) {
- return new ScriptIntrinsicHistogram(rs, e);
+sp<ScriptIntrinsicHistogram> ScriptIntrinsicHistogram::create(sp<RS> rs) {
+ return new ScriptIntrinsicHistogram(rs, NULL);
}
ScriptIntrinsicHistogram::ScriptIntrinsicHistogram(sp<RS> rs, sp<const Element> e)
@@ -235,8 +404,27 @@
}
-void ScriptIntrinsicHistogram::setOutput(sp<Allocation> aout) {
- Script::setVar(1, aout);
+void ScriptIntrinsicHistogram::setOutput(sp<Allocation> out) {
+ if (!(out->getType()->getElement()->isCompatible(Element::U32(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::U32_2(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::U32_3(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::U32_4(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::I32(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::I32_2(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::I32_3(mRS))) &&
+ !(out->getType()->getElement()->isCompatible(Element::I32_4(mRS)))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for Histogram output");
+ return;
+ }
+
+ if (out->getType()->getX() != 256 ||
+ out->getType()->getY() != 0 ||
+ out->getType()->hasMipmaps()) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid Allocation type for Histogram output");
+ return;
+ }
+ mOut = out;
+ Script::setVar(1, out);
}
void ScriptIntrinsicHistogram::setDotCoefficients(float r, float g, float b, float a) {
@@ -257,15 +445,46 @@
}
void ScriptIntrinsicHistogram::forEach(sp<Allocation> ain) {
+ if (ain->getType()->getElement()->getVectorSize() <
+ mOut->getType()->getElement()->getVectorSize()) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER,
+ "Input vector size must be >= output vector size");
+ return;
+ }
+
+ if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
+ !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT,
+ "Input allocation to Histogram must be U8 or U8_4");
+ return;
+ }
+
Script::forEach(0, ain, NULL, NULL, 0);
}
void ScriptIntrinsicHistogram::forEach_dot(sp<Allocation> ain) {
+ if (mOut->getType()->getElement()->getVectorSize() != 1) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER,
+ "Output Histogram allocation must have vector size of 1 " \
+ "when used with forEach_dot");
+ return;
+ }
+ if (!(ain->getType()->getElement()->isCompatible(Element::U8(mRS))) ||
+ !(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT,
+ "Input allocation to Histogram must be U8 or U8_4");
+ return;
+ }
+
Script::forEach(1, ain, NULL, NULL, 0);
}
sp<ScriptIntrinsicLUT> ScriptIntrinsicLUT::create(sp<RS> rs, sp<const Element> e) {
+ if (!(e->isCompatible(Element::U8_4(rs)))) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
+ return NULL;
+ }
return new ScriptIntrinsicLUT(rs, e);
}
@@ -285,6 +504,11 @@
LUT->copy1DFrom((void*)mCache);
mDirty = false;
}
+ if (!(ain->getType()->getElement()->isCompatible(Element::U8_4(mRS))) ||
+ !(aout->getType()->getElement()->isCompatible(Element::U8_4(mRS)))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for LUT");
+ return;
+ }
Script::forEach(0, ain, aout, NULL, 0);
}
@@ -300,18 +524,34 @@
}
void ScriptIntrinsicLUT::setRed(unsigned char base, unsigned char length, unsigned char* lutValues) {
+ if (base + length >= 256) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
+ return;
+ }
setTable(0, base, length, lutValues);
}
void ScriptIntrinsicLUT::setGreen(unsigned char base, unsigned char length, unsigned char* lutValues) {
+ if (base + length >= 256) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
+ return;
+ }
setTable(256, base, length, lutValues);
}
void ScriptIntrinsicLUT::setBlue(unsigned char base, unsigned char length, unsigned char* lutValues) {
+ if (base + length >= 256) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
+ return;
+ }
setTable(512, base, length, lutValues);
}
void ScriptIntrinsicLUT::setAlpha(unsigned char base, unsigned char length, unsigned char* lutValues) {
+ if (base + length >= 256) {
+ mRS->throwError(RS_ERROR_INVALID_PARAMETER, "LUT out of range");
+ return;
+ }
setTable(768, base, length, lutValues);
}
@@ -320,6 +560,10 @@
}
sp<ScriptIntrinsicYuvToRGB> ScriptIntrinsicYuvToRGB::create(sp<RS> rs, sp<const Element> e) {
+ if (!(e->isCompatible(Element::U8_4(rs)))) {
+ rs->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for YuvToRGB");
+ return NULL;
+ }
return new ScriptIntrinsicYuvToRGB(rs, e);
}
@@ -329,9 +573,18 @@
}
void ScriptIntrinsicYuvToRGB::setInput(sp<Allocation> in) {
+ if (!(in->getType()->getElement()->isCompatible(mElement))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for input in YuvToRGB");
+ return;
+ }
Script::setVar(0, in);
}
void ScriptIntrinsicYuvToRGB::forEach(sp<Allocation> out) {
+ if (!(out->getType()->getElement()->isCompatible(mElement))) {
+ mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Invalid element for output in YuvToRGB");
+ return;
+ }
+
Script::forEach(0, NULL, out, NULL, 0);
}