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