1ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams/* 2ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Copyright (C) 2012 The Android Open Source Project 3ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 4ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * you may not use this file except in compliance with the License. 6ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * You may obtain a copy of the License at 7ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 8ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * http://www.apache.org/licenses/LICENSE-2.0 9ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * 10ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * Unless required by applicable law or agreed to in writing, software 11ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * See the License for the specific language governing permissions and 14ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams * limitations under the License. 15ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams */ 16ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 17ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 18ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdCore.h" 19ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdIntrinsics.h" 20ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdAllocation.h" 21ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 22ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdIntrinsicInlines.h" 23ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 24ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsusing namespace android; 25ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsusing namespace android::renderscript; 26ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 27ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstruct YuvParams { 28ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams ObjectBaseRef<Allocation> alloc; 29ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}; 30ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 31ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void YuvToRGB_Bind(const Context *dc, const Script *script, 32ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams void * intrinsicData, uint32_t slot, Allocation *data) { 33ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams YuvParams *cp = (YuvParams *)intrinsicData; 34ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams rsAssert(slot == 0); 35ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams cp->alloc.set(data); 36ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams} 37ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 38ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 39ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 40ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic uchar4 rsYuvToRGBA_uchar4(uchar y, uchar u, uchar v) { 41ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams short Y = ((short)y) - 16; 42ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams short U = ((short)u) - 128; 43ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams short V = ((short)v) - 128; 44ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 45ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams short4 p; 46ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.r = (Y * 298 + V * 409 + 128) >> 8; 47ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.g = (Y * 298 - U * 100 - V * 208 + 128) >> 8; 48ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.b = (Y * 298 + U * 516 + 128) >> 8; 49ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.a = 255; 50ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(p.r < 0) { 51ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.r = 0; 52ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 53ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(p.r > 255) { 54ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.r = 255; 55ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 56ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(p.g < 0) { 57ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.g = 0; 58ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 59ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(p.g > 255) { 60ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.g = 255; 61ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 62ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(p.b < 0) { 63ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.b = 0; 64ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 65ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(p.b > 255) { 66ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams p.b = 255; 67ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 68ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 69ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return (uchar4){p.r, p.g, p.b, p.a}; 70ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams} 71ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 72ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 73ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic short YuvCoeff[] = { 74ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 298, 409, -100, 516, -208, 255, 0, 0, 75ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 16, 16, 16, 16, 16, 16, 16, 16, 76ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 128, 128, 128, 128, 128, 128, 128, 128, 77ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 298, 298, 298, 298, 298, 298, 298, 298, 78ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 255, 255, 255, 255, 255, 255, 255, 255 79ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 80ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 81ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams}; 82ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 83ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsextern "C" void rsdIntrinsicYuv_K(void *dst, const uchar *Y, const uchar *uv, uint32_t count, const short *param); 84ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 85ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsstatic void YuvToRGB_uchar4(const RsForEachStubParamStruct *p, 86ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uint32_t xstart, uint32_t xend, 87ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uint32_t instep, uint32_t outstep) { 88ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams YuvParams *cp = (YuvParams *)p->usr; 89ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams DrvAllocation *din = (DrvAllocation *)cp->alloc->mHal.drv; 90ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams const uchar *pin = (const uchar *)din->lod[0].mallocPtr; 91ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 92ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams const uchar *Y = pin + (p->y * p->dimX); 93ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams const uchar *uv = pin + (p->dimX * p->dimY); 94ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uv += (p->y>>1) * p->dimX; 95ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 96ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uchar4 *out = (uchar4 *)p->out; 97ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uint32_t x1 = xstart; 98ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uint32_t x2 = xend; 99ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 100ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(x2 > x1) { 101ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#if defined(ARCH_ARM_HAVE_NEON) 102ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams int32_t len = (x2 - x1 - 1) >> 3; 103ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams if(len > 0) { 104ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams rsdIntrinsicYuv_K(out, Y, uv, len, YuvCoeff); 105ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams x1 += len << 3; 106ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams out += len << 3; 107ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 108ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#endif 109ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 110ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams // ALOGE("y %i %i %i", p->y, x1, x2); 111ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams while(x1 < x2) { 112ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uchar u = uv[(x1 & 0xffffe) + 1]; 113ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams uchar v = uv[(x1 & 0xffffe) + 0]; 114ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams *out = rsYuvToRGBA_uchar4(Y[x1], u, v); 115ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams out++; 116ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams x1++; 117ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams *out = rsYuvToRGBA_uchar4(Y[x1], u, v); 118ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams out++; 119ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams x1++; 120ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 121ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams } 122ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams} 123ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 124ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsvoid * rsdIntrinsic_InitYuvToRGB(const android::renderscript::Context *dc, 125ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams android::renderscript::Script *script, 126ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams RsdIntriniscFuncs_t *funcs) { 127ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 128ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams script->mHal.info.exportedVariableCount = 1; 129ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams funcs->bind = YuvToRGB_Bind; 130ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams funcs->root = YuvToRGB_uchar4; 131ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams YuvParams *cp = (YuvParams *)calloc(1, sizeof(YuvParams)); 132ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams return cp; 133ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams} 134ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 135ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams 136