101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams/* 201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * Copyright (C) 2012 The Android Open Source Project 301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * 401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * you may not use this file except in compliance with the License. 601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * You may obtain a copy of the License at 701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * 801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * 1001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * Unless required by applicable law or agreed to in writing, software 1101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 1201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * See the License for the specific language governing permissions and 1401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams * limitations under the License. 1501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams */ 1601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 1701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 1801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams#include "rsdCore.h" 1901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams#include "rsdIntrinsics.h" 2001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams#include "rsdAllocation.h" 2101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 2201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams#include "rsdIntrinsicInlines.h" 2301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 2401f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsusing namespace android; 2501f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsusing namespace android::renderscript; 2601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 2701f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsstruct YuvParams { 2801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams ObjectBaseRef<Allocation> alloc; 2901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams}; 3001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 3101f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsstatic void YuvToRGB_Bind(const Context *dc, const Script *script, 3201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams void * intrinsicData, uint32_t slot, Allocation *data) { 3301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams YuvParams *cp = (YuvParams *)intrinsicData; 3401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams rsAssert(slot == 0); 3501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams cp->alloc.set(data); 3601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 3701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 3801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 3901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 4001f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsstatic uchar4 rsYuvToRGBA_uchar4(uchar y, uchar u, uchar v) { 4101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short Y = ((short)y) - 16; 4201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short U = ((short)u) - 128; 4301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short V = ((short)v) - 128; 4401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 4501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams short4 p; 4601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.r = (Y * 298 + V * 409 + 128) >> 8; 4701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.g = (Y * 298 - U * 100 - V * 208 + 128) >> 8; 4801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.b = (Y * 298 + U * 516 + 128) >> 8; 4901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.a = 255; 5001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.r < 0) { 5101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.r = 0; 5201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 5301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.r > 255) { 5401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.r = 255; 5501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 5601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.g < 0) { 5701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.g = 0; 5801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 5901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.g > 255) { 6001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.g = 255; 6101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 6201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.b < 0) { 6301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.b = 0; 6401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 6501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(p.b > 255) { 6601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams p.b = 255; 6701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 6801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 6901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams return (uchar4){p.r, p.g, p.b, p.a}; 7001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 7101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 72915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 73915aa964a1a312f5e06c115112a3aea14fd31b33Jason Samsstatic short YuvCoeff[] = { 74915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 298, 409, -100, 516, -208, 255, 0, 0, 75915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 16, 16, 16, 16, 16, 16, 16, 16, 76915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 128, 128, 128, 128, 128, 128, 128, 128, 77915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 298, 298, 298, 298, 298, 298, 298, 298, 78915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 255, 255, 255, 255, 255, 255, 255, 255 79915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 80915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 81915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams}; 82915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams 83915aa964a1a312f5e06c115112a3aea14fd31b33Jason Samsextern "C" void rsdIntrinsicYuv_K(void *dst, const uchar *Y, const uchar *uv, uint32_t count, const short *param); 8401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 8501f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsstatic void YuvToRGB_uchar4(const RsForEachStubParamStruct *p, 8601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uint32_t xstart, uint32_t xend, 8701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uint32_t instep, uint32_t outstep) { 8801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams YuvParams *cp = (YuvParams *)p->usr; 89b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams if (!cp->alloc.get()) { 90b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams ALOGE("YuvToRGB executed without input, skipping"); 91b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams return; 92b801b949e286275b5d19a33135235ba68d3a19a9Jason Sams } 9301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams DrvAllocation *din = (DrvAllocation *)cp->alloc->mHal.drv; 9401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams const uchar *pin = (const uchar *)din->lod[0].mallocPtr; 9501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 9601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams const uchar *Y = pin + (p->y * p->dimX); 9701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams const uchar *uv = pin + (p->dimX * p->dimY); 9801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uv += (p->y>>1) * p->dimX; 9901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 10001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uchar4 *out = (uchar4 *)p->out; 10101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uint32_t x1 = xstart; 10201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uint32_t x2 = xend; 10301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 10401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(x2 > x1) { 105915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams#if defined(ARCH_ARM_HAVE_NEON) 106915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams int32_t len = (x2 - x1 - 1) >> 3; 10701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams if(len > 0) { 108915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams rsdIntrinsicYuv_K(out, Y, uv, len, YuvCoeff); 109915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams x1 += len << 3; 110915aa964a1a312f5e06c115112a3aea14fd31b33Jason Sams out += len << 3; 11101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 11201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams#endif 11301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 11401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams // ALOGE("y %i %i %i", p->y, x1, x2); 11501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams while(x1 < x2) { 11601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uchar u = uv[(x1 & 0xffffe) + 1]; 11701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams uchar v = uv[(x1 & 0xffffe) + 0]; 11801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams *out = rsYuvToRGBA_uchar4(Y[x1], u, v); 11901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams out++; 12001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams x1++; 12101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams *out = rsYuvToRGBA_uchar4(Y[x1], u, v); 12201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams out++; 12301f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams x1++; 12401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 12501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams } 12601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 12701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 12801f03a04da629b9a3e3ff33287dd277b12c54148Jason Samsvoid * rsdIntrinsic_InitYuvToRGB(const android::renderscript::Context *dc, 12901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams android::renderscript::Script *script, 13001f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams RsdIntriniscFuncs_t *funcs) { 13101f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 13201f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams script->mHal.info.exportedVariableCount = 1; 13378b050ea1e13108110ce3b8ead63252e5ebe2468Jason Sams funcs->setVarObj = YuvToRGB_Bind; 13401f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams funcs->root = YuvToRGB_uchar4; 13501f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams YuvParams *cp = (YuvParams *)calloc(1, sizeof(YuvParams)); 13601f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams return cp; 13701f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams} 13801f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 13901f03a04da629b9a3e3ff33287dd277b12c54148Jason Sams 140