1*32afb93cSXin Li /* 2*32afb93cSXin Li * Copyright (C) 2021 The Android Open Source Project 3*32afb93cSXin Li * 4*32afb93cSXin Li * Licensed under the Apache License, Version 2.0 (the "License"); 5*32afb93cSXin Li * you may not use this file except in compliance with the License. 6*32afb93cSXin Li * You may obtain a copy of the License at 7*32afb93cSXin Li * 8*32afb93cSXin Li * http://www.apache.org/licenses/LICENSE-2.0 9*32afb93cSXin Li * 10*32afb93cSXin Li * Unless required by applicable law or agreed to in writing, software 11*32afb93cSXin Li * distributed under the License is distributed on an "AS IS" BASIS, 12*32afb93cSXin Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*32afb93cSXin Li * See the License for the specific language governing permissions and 14*32afb93cSXin Li * limitations under the License. 15*32afb93cSXin Li */ 16*32afb93cSXin Li 17*32afb93cSXin Li #ifndef ANDROID_RENDERSCRIPT_TOOLKIT_TOOLKIT_H 18*32afb93cSXin Li #define ANDROID_RENDERSCRIPT_TOOLKIT_TOOLKIT_H 19*32afb93cSXin Li 20*32afb93cSXin Li #include <cstdint> 21*32afb93cSXin Li #include <memory> 22*32afb93cSXin Li 23*32afb93cSXin Li namespace renderscript { 24*32afb93cSXin Li 25*32afb93cSXin Li class TaskProcessor; 26*32afb93cSXin Li 27*32afb93cSXin Li /** 28*32afb93cSXin Li * Define a range of data to process. 29*32afb93cSXin Li * 30*32afb93cSXin Li * This class is used to restrict a Toolkit operation to a rectangular subset of the input 31*32afb93cSXin Li * tensor. 32*32afb93cSXin Li * 33*32afb93cSXin Li * @property startX The index of the first value to be included on the X axis. 34*32afb93cSXin Li * @property endX The index after the last value to be included on the X axis. 35*32afb93cSXin Li * @property startY The index of the first value to be included on the Y axis. 36*32afb93cSXin Li * @property endY The index after the last value to be included on the Y axis. 37*32afb93cSXin Li */ 38*32afb93cSXin Li struct Restriction { 39*32afb93cSXin Li size_t startX; 40*32afb93cSXin Li size_t endX; 41*32afb93cSXin Li size_t startY; 42*32afb93cSXin Li size_t endY; 43*32afb93cSXin Li }; 44*32afb93cSXin Li 45*32afb93cSXin Li /** 46*32afb93cSXin Li * A collection of high-performance graphic utility functions like blur and blend. 47*32afb93cSXin Li * 48*32afb93cSXin Li * This toolkit provides ten image manipulation functions: blend, blur, color matrix, convolve, 49*32afb93cSXin Li * histogram, histogramDot, lut, lut3d, resize, and YUV to RGB. These functions execute 50*32afb93cSXin Li * multithreaded on the CPU. 51*32afb93cSXin Li * 52*32afb93cSXin Li * These functions work over raw byte arrays. You'll need to specify the width and height of 53*32afb93cSXin Li * the data to be processed, as well as the number of bytes per pixel. For most use cases, 54*32afb93cSXin Li * this will be 4. 55*32afb93cSXin Li * 56*32afb93cSXin Li * You should instantiate the Toolkit once and reuse it throughout your application. 57*32afb93cSXin Li * On instantiation, the Toolkit creates a thread pool that's used for processing all the functions. 58*32afb93cSXin Li * You can limit the number of pool threads used by the Toolkit via the constructor. The pool 59*32afb93cSXin Li * threads are destroyed once the Toolkit is destroyed, after any pending work is done. 60*32afb93cSXin Li * 61*32afb93cSXin Li * This library is thread safe. You can call methods from different pool threads. The functions will 62*32afb93cSXin Li * execute sequentially. 63*32afb93cSXin Li * 64*32afb93cSXin Li * A Java/Kotlin Toolkit is available. It calls this library through JNI. 65*32afb93cSXin Li * 66*32afb93cSXin Li * This toolkit can be used as a replacement for most RenderScript Intrinsic functions. Compared 67*32afb93cSXin Li * to RenderScript, it's simpler to use and more than twice as fast on the CPU. However RenderScript 68*32afb93cSXin Li * Intrinsics allow more flexibility for the type of allocation supported. In particular, this 69*32afb93cSXin Li * toolkit does not support allocations of floats. 70*32afb93cSXin Li */ 71*32afb93cSXin Li class RenderScriptToolkit { 72*32afb93cSXin Li /** Each Toolkit method call is converted to a Task. The processor owns the thread pool. It 73*32afb93cSXin Li * tiles the tasks and schedule them over the pool threads. 74*32afb93cSXin Li */ 75*32afb93cSXin Li std::unique_ptr<TaskProcessor> processor; 76*32afb93cSXin Li 77*32afb93cSXin Li public: 78*32afb93cSXin Li /** 79*32afb93cSXin Li * Creates the pool threads that are used for processing the method calls. 80*32afb93cSXin Li */ 81*32afb93cSXin Li RenderScriptToolkit(int numberOfThreads = 0); 82*32afb93cSXin Li /** 83*32afb93cSXin Li * Destroys the thread pool. This stops any in-progress work; the Toolkit methods called from 84*32afb93cSXin Li * other pool threads will return without having completed the work. Because of the undefined 85*32afb93cSXin Li * state of the output buffers, an application should avoid destroying the Toolkit if other pool 86*32afb93cSXin Li * threads are executing Toolkit methods. 87*32afb93cSXin Li */ 88*32afb93cSXin Li ~RenderScriptToolkit(); 89*32afb93cSXin Li 90*32afb93cSXin Li /** 91*32afb93cSXin Li * Determines how a source buffer is blended into a destination buffer. 92*32afb93cSXin Li * 93*32afb93cSXin Li * See {@link RenderScriptToolkit::blend}. 94*32afb93cSXin Li * 95*32afb93cSXin Li * blend only works on 4 byte RGBA data. In the descriptions below, ".a" represents 96*32afb93cSXin Li * the alpha channel. 97*32afb93cSXin Li */ 98*32afb93cSXin Li enum class BlendingMode { 99*32afb93cSXin Li /** 100*32afb93cSXin Li * dest = 0 101*32afb93cSXin Li * 102*32afb93cSXin Li * The destination is cleared, i.e. each pixel is set to (0, 0, 0, 0) 103*32afb93cSXin Li */ 104*32afb93cSXin Li CLEAR = 0, 105*32afb93cSXin Li /** 106*32afb93cSXin Li * dest = src 107*32afb93cSXin Li * 108*32afb93cSXin Li * Sets each pixel of the destination to the corresponding one in the source. 109*32afb93cSXin Li */ 110*32afb93cSXin Li SRC = 1, 111*32afb93cSXin Li /** 112*32afb93cSXin Li * dest = dest 113*32afb93cSXin Li * 114*32afb93cSXin Li * Leaves the destination untouched. This is a no-op. 115*32afb93cSXin Li */ 116*32afb93cSXin Li DST = 2, 117*32afb93cSXin Li /** 118*32afb93cSXin Li * dest = src + dest * (1.0 - src.a) 119*32afb93cSXin Li */ 120*32afb93cSXin Li SRC_OVER = 3, 121*32afb93cSXin Li /** 122*32afb93cSXin Li * dest = dest + src * (1.0 - dest.a) 123*32afb93cSXin Li */ 124*32afb93cSXin Li DST_OVER = 4, 125*32afb93cSXin Li /** 126*32afb93cSXin Li * dest = src * dest.a 127*32afb93cSXin Li */ 128*32afb93cSXin Li SRC_IN = 5, 129*32afb93cSXin Li /** 130*32afb93cSXin Li * dest = dest * src.a 131*32afb93cSXin Li */ 132*32afb93cSXin Li DST_IN = 6, 133*32afb93cSXin Li /** 134*32afb93cSXin Li * dest = src * (1.0 - dest.a) 135*32afb93cSXin Li */ 136*32afb93cSXin Li SRC_OUT = 7, 137*32afb93cSXin Li /** 138*32afb93cSXin Li * dest = dest * (1.0 - src.a) 139*32afb93cSXin Li */ 140*32afb93cSXin Li DST_OUT = 8, 141*32afb93cSXin Li /** 142*32afb93cSXin Li * dest.rgb = src.rgb * dest.a + (1.0 - src.a) * dest.rgb, dest.a = dest.a 143*32afb93cSXin Li */ 144*32afb93cSXin Li SRC_ATOP = 9, 145*32afb93cSXin Li /** 146*32afb93cSXin Li * dest = dest.rgb * src.a + (1.0 - dest.a) * src.rgb, dest.a = src.a 147*32afb93cSXin Li */ 148*32afb93cSXin Li DST_ATOP = 10, 149*32afb93cSXin Li /** 150*32afb93cSXin Li * dest = {src.r ^ dest.r, src.g ^ dest.g, src.b ^ dest.b, src.a ^ dest.a} 151*32afb93cSXin Li * 152*32afb93cSXin Li * Note: this is NOT the Porter/Duff XOR mode; this is a bitwise xor. 153*32afb93cSXin Li */ 154*32afb93cSXin Li XOR = 11, 155*32afb93cSXin Li /** 156*32afb93cSXin Li * dest = src * dest 157*32afb93cSXin Li */ 158*32afb93cSXin Li MULTIPLY = 12, 159*32afb93cSXin Li /** 160*32afb93cSXin Li * dest = min(src + dest, 1.0) 161*32afb93cSXin Li */ 162*32afb93cSXin Li ADD = 13, 163*32afb93cSXin Li /** 164*32afb93cSXin Li * dest = max(dest - src, 0.0) 165*32afb93cSXin Li */ 166*32afb93cSXin Li SUBTRACT = 14 167*32afb93cSXin Li }; 168*32afb93cSXin Li 169*32afb93cSXin Li /** 170*32afb93cSXin Li * Blend a source buffer with the destination buffer. 171*32afb93cSXin Li * 172*32afb93cSXin Li * Blends a source buffer and a destination buffer, placing the result in the destination 173*32afb93cSXin Li * buffer. The blending is done pairwise between two corresponding RGBA values found in 174*32afb93cSXin Li * each buffer. The mode parameter specifies one of fifteen blending operations. 175*32afb93cSXin Li * See {@link BlendingMode}. 176*32afb93cSXin Li * 177*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 178*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 179*32afb93cSXin Li * described by sizeX and sizeY. 180*32afb93cSXin Li * 181*32afb93cSXin Li * The source and destination buffers must have the same dimensions. Both buffers should be 182*32afb93cSXin Li * large enough for sizeX * sizeY * 4 bytes. The buffers have a row-major layout. 183*32afb93cSXin Li * 184*32afb93cSXin Li * @param mode The specific blending operation to do. 185*32afb93cSXin Li * @param source The RGBA input buffer. 186*32afb93cSXin Li * @param dest The destination buffer. Used for input and output. 187*32afb93cSXin Li * @param sizeX The width of both buffers, as a number of RGBA values. 188*32afb93cSXin Li * @param sizeY The height of both buffers, as a number of RGBA values. 189*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 190*32afb93cSXin Li */ 191*32afb93cSXin Li void blend(BlendingMode mode, const uint8_t* _Nonnull source, uint8_t* _Nonnull dst, 192*32afb93cSXin Li size_t sizeX, size_t sizeY, const Restriction* _Nullable restriction = nullptr); 193*32afb93cSXin Li 194*32afb93cSXin Li /** 195*32afb93cSXin Li * Blur an image. 196*32afb93cSXin Li * 197*32afb93cSXin Li * Performs a Gaussian blur of the input image and stores the result in the out buffer. 198*32afb93cSXin Li * 199*32afb93cSXin Li * The radius determines which pixels are used to compute each blurred pixels. This Toolkit 200*32afb93cSXin Li * accepts values between 1 and 25. Larger values create a more blurred effect but also 201*32afb93cSXin Li * take longer to compute. When the radius extends past the edge, the edge pixel will 202*32afb93cSXin Li * be used as replacement for the pixel that's out off boundary. 203*32afb93cSXin Li * 204*32afb93cSXin Li * Each input pixel can either be represented by four bytes (RGBA format) or one byte 205*32afb93cSXin Li * for the less common blurring of alpha channel only image. 206*32afb93cSXin Li * 207*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 208*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 209*32afb93cSXin Li * described by sizeX and sizeY. 210*32afb93cSXin Li * 211*32afb93cSXin Li * The input and output buffers must have the same dimensions. Both buffers should be 212*32afb93cSXin Li * large enough for sizeX * sizeY * vectorSize bytes. The buffers have a row-major layout. 213*32afb93cSXin Li * 214*32afb93cSXin Li * @param in The buffer of the image to be blurred. 215*32afb93cSXin Li * @param out The buffer that receives the blurred image. 216*32afb93cSXin Li * @param sizeX The width of both buffers, as a number of 1 or 4 byte cells. 217*32afb93cSXin Li * @param sizeY The height of both buffers, as a number of 1 or 4 byte cells. 218*32afb93cSXin Li * @param vectorSize Either 1 or 4, the number of bytes in each cell, i.e. A vs. RGBA. 219*32afb93cSXin Li * @param radius The radius of the pixels used to blur. 220*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 221*32afb93cSXin Li */ 222*32afb93cSXin Li void blur(const uint8_t* _Nonnull in, uint8_t* _Nonnull out, size_t sizeX, size_t sizeY, 223*32afb93cSXin Li size_t vectorSize, int radius, const Restriction* _Nullable restriction = nullptr); 224*32afb93cSXin Li 225*32afb93cSXin Li /** 226*32afb93cSXin Li * Identity matrix that can be passed to the {@link RenderScriptToolkit::colorMatrix} method. 227*32afb93cSXin Li * 228*32afb93cSXin Li * Using this matrix will result in no change to the pixel through multiplication although 229*32afb93cSXin Li * the pixel value can still be modified by the add vector, or transformed to a different 230*32afb93cSXin Li * format. 231*32afb93cSXin Li */ 232*32afb93cSXin Li static constexpr float kIdentityMatrix[] = { 233*32afb93cSXin Li 1.0f, 0.0f, 0.0f, 0.0f, 234*32afb93cSXin Li 0.0f, 1.0f, 0.0f, 0.0f, 235*32afb93cSXin Li 0.0f, 0.0f, 1.0f, 0.0f, 236*32afb93cSXin Li 0.0f, 0.0f, 0.0f, 1.0f 237*32afb93cSXin Li }; 238*32afb93cSXin Li 239*32afb93cSXin Li /** 240*32afb93cSXin Li * Matrix to turn color pixels to a grey scale. 241*32afb93cSXin Li * 242*32afb93cSXin Li * Use this matrix with the {@link RenderScriptToolkit::colorMatrix} method to convert an 243*32afb93cSXin Li * image from color to greyscale. 244*32afb93cSXin Li */ 245*32afb93cSXin Li static constexpr float kGreyScaleColorMatrix[] = { 246*32afb93cSXin Li 0.299f, 0.299f, 0.299f, 0.0f, 247*32afb93cSXin Li 0.587f, 0.587f, 0.587f, 0.0f, 248*32afb93cSXin Li 0.114f, 0.114f, 0.114f, 0.0f, 249*32afb93cSXin Li 0.0f, 0.0f, 0.0f, 1.0f 250*32afb93cSXin Li }; 251*32afb93cSXin Li 252*32afb93cSXin Li /** 253*32afb93cSXin Li * Matrix to convert RGB to YUV. 254*32afb93cSXin Li * 255*32afb93cSXin Li * Use this matrix with the {@link RenderScriptToolkit::colorMatrix} method to convert the 256*32afb93cSXin Li * first three bytes of each pixel from RGB to YUV. This leaves the last byte (the alpha 257*32afb93cSXin Li * channel) untouched. 258*32afb93cSXin Li * 259*32afb93cSXin Li * This is a simplistic conversion. Most YUV buffers have more complicated format, not supported 260*32afb93cSXin Li * by this method. 261*32afb93cSXin Li */ 262*32afb93cSXin Li static constexpr float kRgbToYuvMatrix[] = { 263*32afb93cSXin Li 0.299f, -0.14713f, 0.615f, 0.0f, 264*32afb93cSXin Li 0.587f, -0.28886f, -0.51499f, 0.0f, 265*32afb93cSXin Li 0.114f, 0.436f, -0.10001f, 0.0f, 266*32afb93cSXin Li 0.0f, 0.0f, 0.0f, 1.0f 267*32afb93cSXin Li }; 268*32afb93cSXin Li 269*32afb93cSXin Li /** 270*32afb93cSXin Li * Matrix to convert YUV to RGB. 271*32afb93cSXin Li * 272*32afb93cSXin Li * Use this matrix with the {@link RenderScriptToolkit::colorMatrix} method to convert the 273*32afb93cSXin Li * first three bytes of each pixel from YUV to RGB. This leaves the last byte (the alpha 274*32afb93cSXin Li * channel) untouched. 275*32afb93cSXin Li * 276*32afb93cSXin Li * This is a simplistic conversion. Most YUV buffers have more complicated format, not supported 277*32afb93cSXin Li * by this method. Use {@link RenderScriptToolkit::yuvToRgb} to convert these buffers. 278*32afb93cSXin Li */ 279*32afb93cSXin Li static constexpr float kYuvToRgbMatrix[] = { 280*32afb93cSXin Li 1.0f, 1.0f, 1.0f, 0.0f, 281*32afb93cSXin Li 0.0f, -0.39465f, 2.03211f, 0.0f, 282*32afb93cSXin Li 1.13983f, -0.5806f, 0.0f, 0.0f, 283*32afb93cSXin Li 0.0f, 0.0f, 0.0f, 1.0f 284*32afb93cSXin Li }; 285*32afb93cSXin Li 286*32afb93cSXin Li /** 287*32afb93cSXin Li * Transform an image using a color matrix. 288*32afb93cSXin Li * 289*32afb93cSXin Li * Converts a 2D array of vectors of unsigned bytes, multiplying each vectors by a 4x4 matrix 290*32afb93cSXin Li * and adding an optional vector. 291*32afb93cSXin Li * 292*32afb93cSXin Li * Each input vector is composed of 1-4 unsigned bytes. If less than 4 bytes, it's extended to 293*32afb93cSXin Li * 4, padding with zeroes. The unsigned bytes are converted from 0-255 to 0.0-1.0 floats 294*32afb93cSXin Li * before the multiplication is done. 295*32afb93cSXin Li * 296*32afb93cSXin Li * The resulting value is normalized from 0.0-1.0 to a 0-255 value and stored in the output. 297*32afb93cSXin Li * If the output vector size is less than four, the unused channels are discarded. 298*32afb93cSXin Li * 299*32afb93cSXin Li * If addVector is null, a vector of zeroes is added, i.e. a noop. 300*32afb93cSXin Li * 301*32afb93cSXin Li * Check kIdentityMatrix, kGreyScaleColorMatrix, kRgbToYuvMatrix, and kYuvToRgbMatrix for sample 302*32afb93cSXin Li * matrices. The YUV conversion may not work for all color spaces. 303*32afb93cSXin Li * 304*32afb93cSXin Li * @param in The buffer of the image to be converted. 305*32afb93cSXin Li * @param out The buffer that receives the converted image. 306*32afb93cSXin Li * @param inputVectorSize The number of bytes in each input cell, a value from 1 to 4. 307*32afb93cSXin Li * @param outputVectorSize The number of bytes in each output cell, a value from 1 to 4. 308*32afb93cSXin Li * @param sizeX The width of both buffers, as a number of 1 to 4 byte cells. 309*32afb93cSXin Li * @param sizeY The height of both buffers, as a number of 1 to 4 byte cells. 310*32afb93cSXin Li * @param matrix The 4x4 matrix to multiply, in row major format. 311*32afb93cSXin Li * @param addVector A vector of four floats that's added to the result of the multiplication. 312*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 313*32afb93cSXin Li */ 314*32afb93cSXin Li void colorMatrix(const void* _Nonnull in, void* _Nonnull out, size_t inputVectorSize, 315*32afb93cSXin Li size_t outputVectorSize, size_t sizeX, size_t sizeY, 316*32afb93cSXin Li const float* _Nonnull matrix, const float* _Nullable addVector = nullptr, 317*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 318*32afb93cSXin Li 319*32afb93cSXin Li /** 320*32afb93cSXin Li * Convolve a ByteArray. 321*32afb93cSXin Li * 322*32afb93cSXin Li * Applies a 3x3 or 5x5 convolution to the input array using the provided coefficients. 323*32afb93cSXin Li * 324*32afb93cSXin Li * For 3x3 convolutions, 9 coefficients must be provided. For 5x5, 25 coefficients are needed. 325*32afb93cSXin Li * The coefficients should be provided in row-major format. 326*32afb93cSXin Li * 327*32afb93cSXin Li * When the square extends past the edge, the edge values will be used as replacement for the 328*32afb93cSXin Li * values that's are off boundary. 329*32afb93cSXin Li * 330*32afb93cSXin Li * Each input cell can either be represented by one to four bytes. Each byte is multiplied 331*32afb93cSXin Li * and accumulated independently of the other bytes of the cell. 332*32afb93cSXin Li * 333*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 334*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 335*32afb93cSXin Li * described by sizeX and sizeY. 336*32afb93cSXin Li * 337*32afb93cSXin Li * The input and output buffers must have the same dimensions. Both buffers should be 338*32afb93cSXin Li * large enough for sizeX * sizeY * vectorSize bytes. The buffers have a row-major layout. 339*32afb93cSXin Li * 340*32afb93cSXin Li * @param in The buffer of the image to be blurred. 341*32afb93cSXin Li * @param out The buffer that receives the blurred image. 342*32afb93cSXin Li * @param vectorSize The number of bytes in each cell, a value from 1 to 4. 343*32afb93cSXin Li * @param sizeX The width of both buffers, as a number of 1 or 4 byte cells. 344*32afb93cSXin Li * @param sizeY The height of both buffers, as a number of 1 or 4 byte cells. 345*32afb93cSXin Li * @param coefficients 9 or 25 multipliers. 346*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 347*32afb93cSXin Li */ 348*32afb93cSXin Li void convolve3x3(const void* _Nonnull in, void* _Nonnull out, size_t vectorSize, size_t sizeX, 349*32afb93cSXin Li size_t sizeY, const float* _Nonnull coefficients, 350*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 351*32afb93cSXin Li 352*32afb93cSXin Li void convolve5x5(const void* _Nonnull in, void* _Nonnull out, size_t vectorSize, size_t sizeX, 353*32afb93cSXin Li size_t sizeY, const float* _Nonnull coefficients, 354*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 355*32afb93cSXin Li 356*32afb93cSXin Li /** 357*32afb93cSXin Li * Compute the histogram of an image. 358*32afb93cSXin Li * 359*32afb93cSXin Li * Tallies how many times each of the 256 possible values of a byte is found in the input. 360*32afb93cSXin Li * 361*32afb93cSXin Li * An input cell can be represented by one to four bytes. The tally is done independently 362*32afb93cSXin Li * for each of the bytes of the cell. Correspondingly, the out array will have 363*32afb93cSXin Li * 256 * vectorSize entries. The counts for value 0 are consecutive, followed by those for 364*32afb93cSXin Li * value 1, etc. 365*32afb93cSXin Li * 366*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 367*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 368*32afb93cSXin Li * described by sizeX and sizeY. 369*32afb93cSXin Li * 370*32afb93cSXin Li * The source buffers should be large enough for sizeX * sizeY * vectorSize bytes. The buffers 371*32afb93cSXin Li * have a row-major layout. The out buffer should be large enough for 256 * vectorSize ints. 372*32afb93cSXin Li * 373*32afb93cSXin Li * @param in The buffer of the image to be analyzed. 374*32afb93cSXin Li * @param out The resulting vector of counts. 375*32afb93cSXin Li * @param sizeX The width of the input buffers, as a number of 1 or 4 byte cells. 376*32afb93cSXin Li * @param sizeY The height of the input buffers, as a number of 1 or 4 byte cells. 377*32afb93cSXin Li * @param vectorSize The number of bytes in each cell, a value from 1 to 4. 378*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 379*32afb93cSXin Li */ 380*32afb93cSXin Li void histogram(const uint8_t* _Nonnull in, int32_t* _Nonnull out, size_t sizeX, size_t sizeY, 381*32afb93cSXin Li size_t vectorSize, const Restriction* _Nullable restriction = nullptr); 382*32afb93cSXin Li 383*32afb93cSXin Li /** 384*32afb93cSXin Li * Compute the histogram of the dot product of an image. 385*32afb93cSXin Li * 386*32afb93cSXin Li * This method supports cells of 1 to 4 bytes in length. For each cell of the array, 387*32afb93cSXin Li * the dot product of its bytes with the provided coefficients is computed. The resulting 388*32afb93cSXin Li * floating point value is converted to an unsigned byte and tallied in the histogram. 389*32afb93cSXin Li * 390*32afb93cSXin Li * If coefficients is null, the coefficients used for RGBA luminosity calculation will be used, 391*32afb93cSXin Li * i.e. the values [0.299f, 0.587f, 0.114f, 0.f]. 392*32afb93cSXin Li * 393*32afb93cSXin Li * Each coefficients must be >= 0 and their sum must be 1.0 or less. There must be the same 394*32afb93cSXin Li * number of coefficients as vectorSize. 395*32afb93cSXin Li * 396*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 397*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 398*32afb93cSXin Li * described by sizeX and sizeY. 399*32afb93cSXin Li * 400*32afb93cSXin Li * The source buffers should be large enough for sizeX * sizeY * vectorSize bytes. The buffers 401*32afb93cSXin Li * have a row-major layout. The out array should be large enough for 256 ints. 402*32afb93cSXin Li * 403*32afb93cSXin Li * @param in The buffer of the image to be analyzed. 404*32afb93cSXin Li * @param out The resulting vector of counts. 405*32afb93cSXin Li * @param sizeX The width of the input buffers, as a number of 1 or 4 byte cells. 406*32afb93cSXin Li * @param sizeY The height of the input buffers, as a number of 1 or 4 byte cells. 407*32afb93cSXin Li * @param vectorSize The number of bytes in each cell, a value from 1 to 4. 408*32afb93cSXin Li * @param coefficients The values used for the dot product. Can be nullptr. 409*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 410*32afb93cSXin Li */ 411*32afb93cSXin Li void histogramDot(const uint8_t* _Nonnull in, int32_t* _Nonnull out, size_t sizeX, size_t sizeY, 412*32afb93cSXin Li size_t vectorSize, const float* _Nullable coefficients, 413*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 414*32afb93cSXin Li 415*32afb93cSXin Li /** 416*32afb93cSXin Li * Transform an image using a look up table 417*32afb93cSXin Li * 418*32afb93cSXin Li * Transforms an image by using a per-channel lookup table. Each channel of the input has an 419*32afb93cSXin Li * independent lookup table. The tables are 256 entries in size and can cover the full value 420*32afb93cSXin Li * range of a byte. 421*32afb93cSXin Li * 422*32afb93cSXin Li * The input array should be in RGBA format, where four consecutive bytes form an cell. 423*32afb93cSXin Li * 424*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 425*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 426*32afb93cSXin Li * described by sizeX and sizeY. 427*32afb93cSXin Li * 428*32afb93cSXin Li * The input and output buffers must have the same dimensions. Both buffers should be 429*32afb93cSXin Li * large enough for sizeX * sizeY * vectorSize bytes. The buffers have a row-major layout. 430*32afb93cSXin Li * 431*32afb93cSXin Li * @param in The buffer of the image to be transformed. 432*32afb93cSXin Li * @param out The buffer that receives the transformed image. 433*32afb93cSXin Li * @param sizeX The width of both buffers, as a number of 4 byte cells. 434*32afb93cSXin Li * @param sizeY The height of both buffers, as a number of 4 byte cells. 435*32afb93cSXin Li * @param red An array of 256 values that's used to convert the R channel. 436*32afb93cSXin Li * @param green An array of 256 values that's used to convert the G channel. 437*32afb93cSXin Li * @param blue An array of 256 values that's used to convert the B channel. 438*32afb93cSXin Li * @param alpha An array of 256 values that's used to convert the A channel. 439*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 440*32afb93cSXin Li */ 441*32afb93cSXin Li void lut(const uint8_t* _Nonnull in, uint8_t* _Nonnull out, size_t sizeX, size_t sizeY, 442*32afb93cSXin Li const uint8_t* _Nonnull red, const uint8_t* _Nonnull green, 443*32afb93cSXin Li const uint8_t* _Nonnull blue, const uint8_t* _Nonnull alpha, 444*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 445*32afb93cSXin Li 446*32afb93cSXin Li /** 447*32afb93cSXin Li * Transform an image using a 3D look up table 448*32afb93cSXin Li * 449*32afb93cSXin Li * Transforms an image, converting RGB to RGBA by using a 3D lookup table. The incoming R, G, 450*32afb93cSXin Li * and B values are normalized to the dimensions of the provided 3D buffer. The eight nearest 451*32afb93cSXin Li * values in that 3D buffer are sampled and linearly interpolated. The resulting RGBA entry 452*32afb93cSXin Li * is stored in the output. 453*32afb93cSXin Li * 454*32afb93cSXin Li * The input array should be in RGBA format, where four consecutive bytes form an cell. 455*32afb93cSXin Li * The fourth byte of each input cell is ignored. 456*32afb93cSXin Li * 457*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 458*32afb93cSXin Li * of each buffer. If provided, the range must be wholly contained with the dimensions 459*32afb93cSXin Li * described by sizeX and sizeY. 460*32afb93cSXin Li * 461*32afb93cSXin Li * The input and output buffers must have the same dimensions. Both buffers should be 462*32afb93cSXin Li * large enough for sizeX * sizeY * vectorSize bytes. The buffers have a row-major layout. 463*32afb93cSXin Li * 464*32afb93cSXin Li * @param in The buffer of the image to be transformed. 465*32afb93cSXin Li * @param out The buffer that receives the transformed image. 466*32afb93cSXin Li * @param sizeX The width of both buffers, as a number of 4 byte cells. 467*32afb93cSXin Li * @param sizeY The height of both buffers, as a number of 4 byte cells. 468*32afb93cSXin Li * @param cube The translation cube, in row major-format. 469*32afb93cSXin Li * @param cubeSizeX The number of RGBA entries in the cube in the X direction. 470*32afb93cSXin Li * @param cubeSizeY The number of RGBA entries in the cube in the Y direction. 471*32afb93cSXin Li * @param cubeSizeZ The number of RGBA entries in the cube in the Z direction. 472*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 473*32afb93cSXin Li */ 474*32afb93cSXin Li void lut3d(const uint8_t* _Nonnull in, uint8_t* _Nonnull out, size_t sizeX, size_t sizeY, 475*32afb93cSXin Li const uint8_t* _Nonnull cube, size_t cubeSizeX, size_t cubeSizeY, size_t cubeSizeZ, 476*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 477*32afb93cSXin Li 478*32afb93cSXin Li /** 479*32afb93cSXin Li * Resize an image. 480*32afb93cSXin Li * 481*32afb93cSXin Li * Resizes an image using bicubic interpolation. 482*32afb93cSXin Li * 483*32afb93cSXin Li * This method supports cells of 1 to 4 bytes in length. Each byte of the cell is 484*32afb93cSXin Li * interpolated independently from the others. 485*32afb93cSXin Li * 486*32afb93cSXin Li * An optional range parameter can be set to restrict the operation to a rectangular subset 487*32afb93cSXin Li * of the output buffer. The corresponding scaled range of the input will be used. If provided, 488*32afb93cSXin Li * the range must be wholly contained with the dimensions described by outputSizeX and 489*32afb93cSXin Li * outputSizeY. 490*32afb93cSXin Li * 491*32afb93cSXin Li * The input and output buffers have a row-major layout. Both buffers should be 492*32afb93cSXin Li * large enough for sizeX * sizeY * vectorSize bytes. 493*32afb93cSXin Li * 494*32afb93cSXin Li * @param in The buffer of the image to be resized. 495*32afb93cSXin Li * @param out The buffer that receives the resized image. 496*32afb93cSXin Li * @param inputSizeX The width of the input buffer, as a number of 1-4 byte cells. 497*32afb93cSXin Li * @param inputSizeY The height of the input buffer, as a number of 1-4 byte cells. 498*32afb93cSXin Li * @param vectorSize The number of bytes in each cell of both buffers. A value from 1 to 4. 499*32afb93cSXin Li * @param outputSizeX The width of the output buffer, as a number of 1-4 byte cells. 500*32afb93cSXin Li * @param outputSizeY The height of the output buffer, as a number of 1-4 byte cells. 501*32afb93cSXin Li * @param restriction When not null, restricts the operation to a 2D range of pixels. 502*32afb93cSXin Li */ 503*32afb93cSXin Li void resize(const uint8_t* _Nonnull in, uint8_t* _Nonnull out, size_t inputSizeX, 504*32afb93cSXin Li size_t inputSizeY, size_t vectorSize, size_t outputSizeX, size_t outputSizeY, 505*32afb93cSXin Li const Restriction* _Nullable restriction = nullptr); 506*32afb93cSXin Li 507*32afb93cSXin Li /** 508*32afb93cSXin Li * The YUV formats supported by yuvToRgb. 509*32afb93cSXin Li */ 510*32afb93cSXin Li enum class YuvFormat { 511*32afb93cSXin Li NV21 = 0x11, 512*32afb93cSXin Li YV12 = 0x32315659, 513*32afb93cSXin Li }; 514*32afb93cSXin Li 515*32afb93cSXin Li /** 516*32afb93cSXin Li * Convert an image from YUV to RGB. 517*32afb93cSXin Li * 518*32afb93cSXin Li * Converts an Android YUV buffer to RGB. The input allocation should be 519*32afb93cSXin Li * supplied in a supported YUV format as a YUV cell Allocation. 520*32afb93cSXin Li * The output is RGBA; the alpha channel will be set to 255. 521*32afb93cSXin Li * 522*32afb93cSXin Li * Note that for YV12 and a sizeX that's not a multiple of 32, the 523*32afb93cSXin Li * RenderScript Intrinsic may not have converted the image correctly. 524*32afb93cSXin Li * This Toolkit method should. 525*32afb93cSXin Li * 526*32afb93cSXin Li * @param in The buffer of the image to be converted. 527*32afb93cSXin Li * @param out The buffer that receives the converted image. 528*32afb93cSXin Li * @param sizeX The width in pixels of the image. Must be even. 529*32afb93cSXin Li * @param sizeY The height in pixels of the image. 530*32afb93cSXin Li * @param format Either YV12 or NV21. 531*32afb93cSXin Li */ 532*32afb93cSXin Li void yuvToRgb(const uint8_t* _Nonnull in, uint8_t* _Nonnull out, size_t sizeX, size_t sizeY, 533*32afb93cSXin Li YuvFormat format); 534*32afb93cSXin Li }; 535*32afb93cSXin Li 536*32afb93cSXin Li } // namespace renderscript 537*32afb93cSXin Li 538*32afb93cSXin Li #endif // ANDROID_RENDERSCRIPT_TOOLKIT_TOOLKIT_H 539