xref: /aosp_15_r20/external/libopenapv/app/oapv_app_util.h (revision abb65b4b03b69e1d508d4d9a44dcf199df16e7c3)
1*abb65b4bSAndroid Build Coastguard Worker /*
2*abb65b4bSAndroid Build Coastguard Worker  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3*abb65b4bSAndroid Build Coastguard Worker  * All Rights Reserved.
4*abb65b4bSAndroid Build Coastguard Worker  *
5*abb65b4bSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*abb65b4bSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
7*abb65b4bSAndroid Build Coastguard Worker  *
8*abb65b4bSAndroid Build Coastguard Worker  * - Redistributions of source code must retain the above copyright notice,
9*abb65b4bSAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer.
10*abb65b4bSAndroid Build Coastguard Worker  *
11*abb65b4bSAndroid Build Coastguard Worker  * - Redistributions in binary form must reproduce the above copyright notice,
12*abb65b4bSAndroid Build Coastguard Worker  *   this list of conditions and the following disclaimer in the documentation
13*abb65b4bSAndroid Build Coastguard Worker  *   and/or other materials provided with the distribution.
14*abb65b4bSAndroid Build Coastguard Worker  *
15*abb65b4bSAndroid Build Coastguard Worker  * - Neither the name of the copyright owner, nor the names of its contributors
16*abb65b4bSAndroid Build Coastguard Worker  *   may be used to endorse or promote products derived from this software
17*abb65b4bSAndroid Build Coastguard Worker  *   without specific prior written permission.
18*abb65b4bSAndroid Build Coastguard Worker  *
19*abb65b4bSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*abb65b4bSAndroid Build Coastguard Worker  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*abb65b4bSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*abb65b4bSAndroid Build Coastguard Worker  * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*abb65b4bSAndroid Build Coastguard Worker  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*abb65b4bSAndroid Build Coastguard Worker  * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*abb65b4bSAndroid Build Coastguard Worker  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*abb65b4bSAndroid Build Coastguard Worker  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*abb65b4bSAndroid Build Coastguard Worker  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*abb65b4bSAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*abb65b4bSAndroid Build Coastguard Worker  * POSSIBILITY OF SUCH DAMAGE.
30*abb65b4bSAndroid Build Coastguard Worker  */
31*abb65b4bSAndroid Build Coastguard Worker 
32*abb65b4bSAndroid Build Coastguard Worker #ifndef _OAPV_APP_UTIL_H_
33*abb65b4bSAndroid Build Coastguard Worker #define _OAPV_APP_UTIL_H_
34*abb65b4bSAndroid Build Coastguard Worker 
35*abb65b4bSAndroid Build Coastguard Worker #ifndef _CRT_SECURE_NO_WARNINGS
36*abb65b4bSAndroid Build Coastguard Worker #define _CRT_SECURE_NO_WARNINGS
37*abb65b4bSAndroid Build Coastguard Worker #endif
38*abb65b4bSAndroid Build Coastguard Worker 
39*abb65b4bSAndroid Build Coastguard Worker #include <stdlib.h>
40*abb65b4bSAndroid Build Coastguard Worker #include <stdio.h>
41*abb65b4bSAndroid Build Coastguard Worker #include <string.h>
42*abb65b4bSAndroid Build Coastguard Worker #include <time.h>
43*abb65b4bSAndroid Build Coastguard Worker #include <assert.h>
44*abb65b4bSAndroid Build Coastguard Worker #include <math.h>
45*abb65b4bSAndroid Build Coastguard Worker #include <stdarg.h>
46*abb65b4bSAndroid Build Coastguard Worker #include <ctype.h>
47*abb65b4bSAndroid Build Coastguard Worker #if LINUX
48*abb65b4bSAndroid Build Coastguard Worker #include <signal.h>
49*abb65b4bSAndroid Build Coastguard Worker #include <unistd.h>
50*abb65b4bSAndroid Build Coastguard Worker #endif
51*abb65b4bSAndroid Build Coastguard Worker 
52*abb65b4bSAndroid Build Coastguard Worker #define VERBOSE_NONE   0
53*abb65b4bSAndroid Build Coastguard Worker #define VERBOSE_ERROR  1
54*abb65b4bSAndroid Build Coastguard Worker #define VERBOSE_SIMPLE 2
55*abb65b4bSAndroid Build Coastguard Worker #define VERBOSE_FRAME  3
56*abb65b4bSAndroid Build Coastguard Worker 
57*abb65b4bSAndroid Build Coastguard Worker /* logging functions */
log_msg(char * filename,int line,const char * fmt,...)58*abb65b4bSAndroid Build Coastguard Worker static void log_msg(char *filename, int line, const char *fmt, ...)
59*abb65b4bSAndroid Build Coastguard Worker {
60*abb65b4bSAndroid Build Coastguard Worker     char str[1024] = { '\0' };
61*abb65b4bSAndroid Build Coastguard Worker     if(filename != NULL && line >= 0)
62*abb65b4bSAndroid Build Coastguard Worker         sprintf(str, "[%s:%d] ", filename, line);
63*abb65b4bSAndroid Build Coastguard Worker     va_list args;
64*abb65b4bSAndroid Build Coastguard Worker     va_start(args, fmt);
65*abb65b4bSAndroid Build Coastguard Worker     vsprintf(str + strlen(str), fmt, args);
66*abb65b4bSAndroid Build Coastguard Worker     va_end(args);
67*abb65b4bSAndroid Build Coastguard Worker     printf("%s", str);
68*abb65b4bSAndroid Build Coastguard Worker }
69*abb65b4bSAndroid Build Coastguard Worker 
log_line(char * pre)70*abb65b4bSAndroid Build Coastguard Worker static void log_line(char *pre)
71*abb65b4bSAndroid Build Coastguard Worker {
72*abb65b4bSAndroid Build Coastguard Worker     int       i, len;
73*abb65b4bSAndroid Build Coastguard Worker     char      str[128] = { '\0' };
74*abb65b4bSAndroid Build Coastguard Worker     const int chars = 80;
75*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < 3; i++) {
76*abb65b4bSAndroid Build Coastguard Worker         str[i] = '=';
77*abb65b4bSAndroid Build Coastguard Worker     }
78*abb65b4bSAndroid Build Coastguard Worker     str[i] = '\0';
79*abb65b4bSAndroid Build Coastguard Worker 
80*abb65b4bSAndroid Build Coastguard Worker     len = (pre == NULL) ? 0 : (int)strlen(pre);
81*abb65b4bSAndroid Build Coastguard Worker     if(len > 0) {
82*abb65b4bSAndroid Build Coastguard Worker         sprintf(str + 3, " %s ", pre);
83*abb65b4bSAndroid Build Coastguard Worker         len = (int)strlen(str);
84*abb65b4bSAndroid Build Coastguard Worker     }
85*abb65b4bSAndroid Build Coastguard Worker 
86*abb65b4bSAndroid Build Coastguard Worker     for(i = len; i < chars; i++) {
87*abb65b4bSAndroid Build Coastguard Worker         str[i] = '=';
88*abb65b4bSAndroid Build Coastguard Worker     }
89*abb65b4bSAndroid Build Coastguard Worker     str[chars] = '\0';
90*abb65b4bSAndroid Build Coastguard Worker     printf("%s\n", str);
91*abb65b4bSAndroid Build Coastguard Worker }
92*abb65b4bSAndroid Build Coastguard Worker 
93*abb65b4bSAndroid Build Coastguard Worker #if defined(__GNUC__)
94*abb65b4bSAndroid Build Coastguard Worker #define __FILENAME__ \
95*abb65b4bSAndroid Build Coastguard Worker     (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
96*abb65b4bSAndroid Build Coastguard Worker 
97*abb65b4bSAndroid Build Coastguard Worker #define logerr(args...)                   \
98*abb65b4bSAndroid Build Coastguard Worker     {                                     \
99*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_ERROR) { \
100*abb65b4bSAndroid Build Coastguard Worker             log_msg(NULL, -1, args);      \
101*abb65b4bSAndroid Build Coastguard Worker         }                                 \
102*abb65b4bSAndroid Build Coastguard Worker     }
103*abb65b4bSAndroid Build Coastguard Worker #define logv2(args...)                     \
104*abb65b4bSAndroid Build Coastguard Worker     {                                      \
105*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_SIMPLE) { \
106*abb65b4bSAndroid Build Coastguard Worker             log_msg(NULL, -1, args);       \
107*abb65b4bSAndroid Build Coastguard Worker         }                                  \
108*abb65b4bSAndroid Build Coastguard Worker     }
109*abb65b4bSAndroid Build Coastguard Worker #define logv3(args...)                    \
110*abb65b4bSAndroid Build Coastguard Worker     {                                     \
111*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_FRAME) { \
112*abb65b4bSAndroid Build Coastguard Worker             log_msg(NULL, -1, args);      \
113*abb65b4bSAndroid Build Coastguard Worker         }                                 \
114*abb65b4bSAndroid Build Coastguard Worker     }
115*abb65b4bSAndroid Build Coastguard Worker #else
116*abb65b4bSAndroid Build Coastguard Worker #define __FILENAME__ \
117*abb65b4bSAndroid Build Coastguard Worker     (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
118*abb65b4bSAndroid Build Coastguard Worker #define logerr(args, ...)                         \
119*abb65b4bSAndroid Build Coastguard Worker     {                                             \
120*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_ERROR) {         \
121*abb65b4bSAndroid Build Coastguard Worker             log_msg(NULL, -1, args, __VA_ARGS__); \
122*abb65b4bSAndroid Build Coastguard Worker         }                                         \
123*abb65b4bSAndroid Build Coastguard Worker     }
124*abb65b4bSAndroid Build Coastguard Worker #define logv2(args, ...)                          \
125*abb65b4bSAndroid Build Coastguard Worker     {                                             \
126*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_SIMPLE) {        \
127*abb65b4bSAndroid Build Coastguard Worker             log_msg(NULL, -1, args, __VA_ARGS__); \
128*abb65b4bSAndroid Build Coastguard Worker         }                                         \
129*abb65b4bSAndroid Build Coastguard Worker     }
130*abb65b4bSAndroid Build Coastguard Worker #define logv3(args, ...)                          \
131*abb65b4bSAndroid Build Coastguard Worker     {                                             \
132*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_FRAME) {         \
133*abb65b4bSAndroid Build Coastguard Worker             log_msg(NULL, -1, args, __VA_ARGS__); \
134*abb65b4bSAndroid Build Coastguard Worker         }                                         \
135*abb65b4bSAndroid Build Coastguard Worker     }
136*abb65b4bSAndroid Build Coastguard Worker #endif
137*abb65b4bSAndroid Build Coastguard Worker #define logv2_line(pre)                    \
138*abb65b4bSAndroid Build Coastguard Worker     {                                      \
139*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_SIMPLE) { \
140*abb65b4bSAndroid Build Coastguard Worker             log_line(pre);                 \
141*abb65b4bSAndroid Build Coastguard Worker         }                                  \
142*abb65b4bSAndroid Build Coastguard Worker     }
143*abb65b4bSAndroid Build Coastguard Worker #define logv3_line(pre)                   \
144*abb65b4bSAndroid Build Coastguard Worker     {                                     \
145*abb65b4bSAndroid Build Coastguard Worker         if(op_verbose >= VERBOSE_FRAME) { \
146*abb65b4bSAndroid Build Coastguard Worker             log_line(pre);                \
147*abb65b4bSAndroid Build Coastguard Worker         }                                 \
148*abb65b4bSAndroid Build Coastguard Worker     }
149*abb65b4bSAndroid Build Coastguard Worker 
150*abb65b4bSAndroid Build Coastguard Worker /* assert function */
151*abb65b4bSAndroid Build Coastguard Worker #include <assert.h>
152*abb65b4bSAndroid Build Coastguard Worker #define assert_r(x)    \
153*abb65b4bSAndroid Build Coastguard Worker     {                  \
154*abb65b4bSAndroid Build Coastguard Worker         if(!(x)) {     \
155*abb65b4bSAndroid Build Coastguard Worker             assert(x); \
156*abb65b4bSAndroid Build Coastguard Worker             return;    \
157*abb65b4bSAndroid Build Coastguard Worker         }              \
158*abb65b4bSAndroid Build Coastguard Worker     }
159*abb65b4bSAndroid Build Coastguard Worker #define assert_rv(x, r) \
160*abb65b4bSAndroid Build Coastguard Worker     {                   \
161*abb65b4bSAndroid Build Coastguard Worker         if(!(x)) {      \
162*abb65b4bSAndroid Build Coastguard Worker             assert(x);  \
163*abb65b4bSAndroid Build Coastguard Worker             return (r); \
164*abb65b4bSAndroid Build Coastguard Worker         }               \
165*abb65b4bSAndroid Build Coastguard Worker     }
166*abb65b4bSAndroid Build Coastguard Worker #define assert_g(x, g) \
167*abb65b4bSAndroid Build Coastguard Worker     {                  \
168*abb65b4bSAndroid Build Coastguard Worker         if(!(x)) {     \
169*abb65b4bSAndroid Build Coastguard Worker             assert(x); \
170*abb65b4bSAndroid Build Coastguard Worker             goto g;    \
171*abb65b4bSAndroid Build Coastguard Worker         }              \
172*abb65b4bSAndroid Build Coastguard Worker     }
173*abb65b4bSAndroid Build Coastguard Worker #define assert_gv(x, r, v, g) \
174*abb65b4bSAndroid Build Coastguard Worker     {                         \
175*abb65b4bSAndroid Build Coastguard Worker         if(!(x)) {            \
176*abb65b4bSAndroid Build Coastguard Worker             assert(x);        \
177*abb65b4bSAndroid Build Coastguard Worker             (r) = (v);        \
178*abb65b4bSAndroid Build Coastguard Worker             goto g;           \
179*abb65b4bSAndroid Build Coastguard Worker         }                     \
180*abb65b4bSAndroid Build Coastguard Worker     }
181*abb65b4bSAndroid Build Coastguard Worker 
182*abb65b4bSAndroid Build Coastguard Worker static int op_verbose = VERBOSE_SIMPLE;
183*abb65b4bSAndroid Build Coastguard Worker 
184*abb65b4bSAndroid Build Coastguard Worker /* Clocks */
185*abb65b4bSAndroid Build Coastguard Worker #if defined(_WIN64) || defined(_WIN32)
186*abb65b4bSAndroid Build Coastguard Worker #include <windows.h>
187*abb65b4bSAndroid Build Coastguard Worker 
188*abb65b4bSAndroid Build Coastguard Worker typedef DWORD oapv_clk_t;
189*abb65b4bSAndroid Build Coastguard Worker #define OAPV_CLK_PER_SEC  (1000)
190*abb65b4bSAndroid Build Coastguard Worker #define OAPV_CLK_PER_MSEC (1)
191*abb65b4bSAndroid Build Coastguard Worker #define OAPV_CLK_MAX      ((oapv_clk_t)(-1))
192*abb65b4bSAndroid Build Coastguard Worker #define oapv_clk_get()    GetTickCount()
193*abb65b4bSAndroid Build Coastguard Worker 
194*abb65b4bSAndroid Build Coastguard Worker #elif __linux__ || __CYGWIN__ || __APPLE__
195*abb65b4bSAndroid Build Coastguard Worker #include <time.h>
196*abb65b4bSAndroid Build Coastguard Worker #include <sys/time.h>
197*abb65b4bSAndroid Build Coastguard Worker typedef unsigned long oapv_clk_t;
198*abb65b4bSAndroid Build Coastguard Worker #define OAPV_CLK_MAX      ((oapv_clk_t)(-1))
199*abb65b4bSAndroid Build Coastguard Worker #define OAPV_CLK_PER_SEC  (10000)
200*abb65b4bSAndroid Build Coastguard Worker #define OAPV_CLK_PER_MSEC (10)
oapv_clk_get(void)201*abb65b4bSAndroid Build Coastguard Worker static oapv_clk_t     oapv_clk_get(void)
202*abb65b4bSAndroid Build Coastguard Worker {
203*abb65b4bSAndroid Build Coastguard Worker     oapv_clk_t     clk;
204*abb65b4bSAndroid Build Coastguard Worker     struct timeval t;
205*abb65b4bSAndroid Build Coastguard Worker     gettimeofday(&t, NULL);
206*abb65b4bSAndroid Build Coastguard Worker     clk = t.tv_sec * 10000L + t.tv_usec / 100L;
207*abb65b4bSAndroid Build Coastguard Worker     return clk;
208*abb65b4bSAndroid Build Coastguard Worker }
209*abb65b4bSAndroid Build Coastguard Worker 
210*abb65b4bSAndroid Build Coastguard Worker #else
211*abb65b4bSAndroid Build Coastguard Worker #error THIS PLATFORM CANNOT SUPPORT CLOCK
212*abb65b4bSAndroid Build Coastguard Worker #endif
213*abb65b4bSAndroid Build Coastguard Worker 
oapv_clk_diff(oapv_clk_t t1,oapv_clk_t t2)214*abb65b4bSAndroid Build Coastguard Worker static __inline oapv_clk_t oapv_clk_diff(oapv_clk_t t1, oapv_clk_t t2)
215*abb65b4bSAndroid Build Coastguard Worker {
216*abb65b4bSAndroid Build Coastguard Worker     return (((t2) >= (t1)) ? ((t2) - (t1)) : ((OAPV_CLK_MAX - (t1)) + (t2)));
217*abb65b4bSAndroid Build Coastguard Worker }
218*abb65b4bSAndroid Build Coastguard Worker 
oapv_clk_from(oapv_clk_t from)219*abb65b4bSAndroid Build Coastguard Worker static __inline oapv_clk_t oapv_clk_from(oapv_clk_t from)
220*abb65b4bSAndroid Build Coastguard Worker {
221*abb65b4bSAndroid Build Coastguard Worker     oapv_clk_t now = oapv_clk_get();
222*abb65b4bSAndroid Build Coastguard Worker     return oapv_clk_diff(from, now);
223*abb65b4bSAndroid Build Coastguard Worker }
224*abb65b4bSAndroid Build Coastguard Worker 
oapv_clk_msec(oapv_clk_t clk)225*abb65b4bSAndroid Build Coastguard Worker static __inline oapv_clk_t oapv_clk_msec(oapv_clk_t clk)
226*abb65b4bSAndroid Build Coastguard Worker {
227*abb65b4bSAndroid Build Coastguard Worker     return ((oapv_clk_t)((clk + (OAPV_CLK_PER_MSEC / 2)) / OAPV_CLK_PER_MSEC));
228*abb65b4bSAndroid Build Coastguard Worker }
229*abb65b4bSAndroid Build Coastguard Worker 
oapv_clk_sec(oapv_clk_t clk)230*abb65b4bSAndroid Build Coastguard Worker static __inline oapv_clk_t oapv_clk_sec(oapv_clk_t clk)
231*abb65b4bSAndroid Build Coastguard Worker {
232*abb65b4bSAndroid Build Coastguard Worker     return ((oapv_clk_t)((clk + (OAPV_CLK_PER_SEC / 2)) / OAPV_CLK_PER_SEC));
233*abb65b4bSAndroid Build Coastguard Worker }
234*abb65b4bSAndroid Build Coastguard Worker 
235*abb65b4bSAndroid Build Coastguard Worker #define CLIP_VAL(n, min, max) (((n) > (max)) ? (max) : (((n) < (min)) ? (min) : (n)))
236*abb65b4bSAndroid Build Coastguard Worker #define ALIGN_VAL(val, align) ((((val) + (align) - 1) / (align)) * (align))
237*abb65b4bSAndroid Build Coastguard Worker 
238*abb65b4bSAndroid Build Coastguard Worker /* Function for atomic increament:
239*abb65b4bSAndroid Build Coastguard Worker    This function might need to modify according to O/S or CPU platform
240*abb65b4bSAndroid Build Coastguard Worker */
atomic_inc(volatile int * pcnt)241*abb65b4bSAndroid Build Coastguard Worker static int atomic_inc(volatile int *pcnt)
242*abb65b4bSAndroid Build Coastguard Worker {
243*abb65b4bSAndroid Build Coastguard Worker     int ret;
244*abb65b4bSAndroid Build Coastguard Worker     ret = *pcnt;
245*abb65b4bSAndroid Build Coastguard Worker     ret++;
246*abb65b4bSAndroid Build Coastguard Worker     *pcnt = ret;
247*abb65b4bSAndroid Build Coastguard Worker     return ret;
248*abb65b4bSAndroid Build Coastguard Worker }
249*abb65b4bSAndroid Build Coastguard Worker 
250*abb65b4bSAndroid Build Coastguard Worker /* Function for atomic decrement:
251*abb65b4bSAndroid Build Coastguard Worker    This function might need to modify according to O/S or CPU platform
252*abb65b4bSAndroid Build Coastguard Worker */
atomic_dec(volatile int * pcnt)253*abb65b4bSAndroid Build Coastguard Worker static int atomic_dec(volatile int *pcnt)
254*abb65b4bSAndroid Build Coastguard Worker {
255*abb65b4bSAndroid Build Coastguard Worker     int ret;
256*abb65b4bSAndroid Build Coastguard Worker     ret = *pcnt;
257*abb65b4bSAndroid Build Coastguard Worker     ret--;
258*abb65b4bSAndroid Build Coastguard Worker     *pcnt = ret;
259*abb65b4bSAndroid Build Coastguard Worker     return ret;
260*abb65b4bSAndroid Build Coastguard Worker }
261*abb65b4bSAndroid Build Coastguard Worker 
262*abb65b4bSAndroid Build Coastguard Worker /* Function to allocate memory for picture buffer:
263*abb65b4bSAndroid Build Coastguard Worker    This function might need to modify according to O/S or CPU platform
264*abb65b4bSAndroid Build Coastguard Worker */
picbuf_alloc(int size)265*abb65b4bSAndroid Build Coastguard Worker static void *picbuf_alloc(int size)
266*abb65b4bSAndroid Build Coastguard Worker {
267*abb65b4bSAndroid Build Coastguard Worker     return malloc(size);
268*abb65b4bSAndroid Build Coastguard Worker }
269*abb65b4bSAndroid Build Coastguard Worker 
270*abb65b4bSAndroid Build Coastguard Worker /* Function to free memory allocated for picture buffer:
271*abb65b4bSAndroid Build Coastguard Worker    This function might need to modify according to O/S or CPU platform
272*abb65b4bSAndroid Build Coastguard Worker */
picbuf_free(void * p)273*abb65b4bSAndroid Build Coastguard Worker static void picbuf_free(void *p)
274*abb65b4bSAndroid Build Coastguard Worker {
275*abb65b4bSAndroid Build Coastguard Worker     if(p) {
276*abb65b4bSAndroid Build Coastguard Worker         free(p);
277*abb65b4bSAndroid Build Coastguard Worker     }
278*abb65b4bSAndroid Build Coastguard Worker }
279*abb65b4bSAndroid Build Coastguard Worker 
imgb_addref(oapv_imgb_t * imgb)280*abb65b4bSAndroid Build Coastguard Worker static int imgb_addref(oapv_imgb_t *imgb)
281*abb65b4bSAndroid Build Coastguard Worker {
282*abb65b4bSAndroid Build Coastguard Worker     assert_rv(imgb, OAPV_ERR_INVALID_ARGUMENT);
283*abb65b4bSAndroid Build Coastguard Worker     return atomic_inc(&imgb->refcnt);
284*abb65b4bSAndroid Build Coastguard Worker }
285*abb65b4bSAndroid Build Coastguard Worker 
imgb_getref(oapv_imgb_t * imgb)286*abb65b4bSAndroid Build Coastguard Worker static int imgb_getref(oapv_imgb_t *imgb)
287*abb65b4bSAndroid Build Coastguard Worker {
288*abb65b4bSAndroid Build Coastguard Worker     assert_rv(imgb, OAPV_ERR_INVALID_ARGUMENT);
289*abb65b4bSAndroid Build Coastguard Worker     return imgb->refcnt;
290*abb65b4bSAndroid Build Coastguard Worker }
291*abb65b4bSAndroid Build Coastguard Worker 
imgb_release(oapv_imgb_t * imgb)292*abb65b4bSAndroid Build Coastguard Worker static int imgb_release(oapv_imgb_t *imgb)
293*abb65b4bSAndroid Build Coastguard Worker {
294*abb65b4bSAndroid Build Coastguard Worker     int refcnt, i;
295*abb65b4bSAndroid Build Coastguard Worker     assert_rv(imgb, OAPV_ERR_INVALID_ARGUMENT);
296*abb65b4bSAndroid Build Coastguard Worker     refcnt = atomic_dec(&imgb->refcnt);
297*abb65b4bSAndroid Build Coastguard Worker     if(refcnt == 0) {
298*abb65b4bSAndroid Build Coastguard Worker         for(i = 0; i < OAPV_MAX_CC; i++) {
299*abb65b4bSAndroid Build Coastguard Worker             if(imgb->baddr[i])
300*abb65b4bSAndroid Build Coastguard Worker                 picbuf_free(imgb->baddr[i]);
301*abb65b4bSAndroid Build Coastguard Worker         }
302*abb65b4bSAndroid Build Coastguard Worker         free(imgb);
303*abb65b4bSAndroid Build Coastguard Worker     }
304*abb65b4bSAndroid Build Coastguard Worker     return refcnt;
305*abb65b4bSAndroid Build Coastguard Worker }
306*abb65b4bSAndroid Build Coastguard Worker 
imgb_create(int w,int h,int cs)307*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_create(int w, int h, int cs)
308*abb65b4bSAndroid Build Coastguard Worker {
309*abb65b4bSAndroid Build Coastguard Worker     int          i, bd;
310*abb65b4bSAndroid Build Coastguard Worker     oapv_imgb_t *imgb;
311*abb65b4bSAndroid Build Coastguard Worker 
312*abb65b4bSAndroid Build Coastguard Worker     imgb = (oapv_imgb_t *)malloc(sizeof(oapv_imgb_t));
313*abb65b4bSAndroid Build Coastguard Worker     if(imgb == NULL)
314*abb65b4bSAndroid Build Coastguard Worker         goto ERR;
315*abb65b4bSAndroid Build Coastguard Worker     memset(imgb, 0, sizeof(oapv_imgb_t));
316*abb65b4bSAndroid Build Coastguard Worker 
317*abb65b4bSAndroid Build Coastguard Worker     bd = OAPV_CS_GET_BYTE_DEPTH(cs); /* byte unit */
318*abb65b4bSAndroid Build Coastguard Worker 
319*abb65b4bSAndroid Build Coastguard Worker     imgb->w[0] = w;
320*abb65b4bSAndroid Build Coastguard Worker     imgb->h[0] = h;
321*abb65b4bSAndroid Build Coastguard Worker     switch(OAPV_CS_GET_FORMAT(cs)) {
322*abb65b4bSAndroid Build Coastguard Worker     case OAPV_CF_YCBCR400:
323*abb65b4bSAndroid Build Coastguard Worker         imgb->w[1] = imgb->w[2] = w;
324*abb65b4bSAndroid Build Coastguard Worker         imgb->h[1] = imgb->h[2] = h;
325*abb65b4bSAndroid Build Coastguard Worker         imgb->np = 1;
326*abb65b4bSAndroid Build Coastguard Worker         break;
327*abb65b4bSAndroid Build Coastguard Worker     case OAPV_CF_YCBCR420:
328*abb65b4bSAndroid Build Coastguard Worker         imgb->w[1] = imgb->w[2] = (w + 1) >> 1;
329*abb65b4bSAndroid Build Coastguard Worker         imgb->h[1] = imgb->h[2] = (h + 1) >> 1;
330*abb65b4bSAndroid Build Coastguard Worker         imgb->np = 3;
331*abb65b4bSAndroid Build Coastguard Worker         break;
332*abb65b4bSAndroid Build Coastguard Worker     case OAPV_CF_YCBCR422:
333*abb65b4bSAndroid Build Coastguard Worker         imgb->w[1] = imgb->w[2] = (w + 1) >> 1;
334*abb65b4bSAndroid Build Coastguard Worker         imgb->h[1] = imgb->h[2] = h;
335*abb65b4bSAndroid Build Coastguard Worker         imgb->np = 3;
336*abb65b4bSAndroid Build Coastguard Worker         break;
337*abb65b4bSAndroid Build Coastguard Worker     case OAPV_CF_YCBCR444:
338*abb65b4bSAndroid Build Coastguard Worker         imgb->w[1] = imgb->w[2] = w;
339*abb65b4bSAndroid Build Coastguard Worker         imgb->h[1] = imgb->h[2] = h;
340*abb65b4bSAndroid Build Coastguard Worker         imgb->np = 3;
341*abb65b4bSAndroid Build Coastguard Worker         break;
342*abb65b4bSAndroid Build Coastguard Worker     case OAPV_CF_YCBCR4444:
343*abb65b4bSAndroid Build Coastguard Worker         imgb->w[1] = imgb->w[2] = imgb->w[3] = w;
344*abb65b4bSAndroid Build Coastguard Worker         imgb->h[1] = imgb->h[2] = imgb->h[3] = h;
345*abb65b4bSAndroid Build Coastguard Worker         imgb->np = 4;
346*abb65b4bSAndroid Build Coastguard Worker         break;
347*abb65b4bSAndroid Build Coastguard Worker     case OAPV_CF_PLANAR2:
348*abb65b4bSAndroid Build Coastguard Worker         imgb->w[1] = w;
349*abb65b4bSAndroid Build Coastguard Worker         imgb->h[1] = h;
350*abb65b4bSAndroid Build Coastguard Worker         imgb->np = 2;
351*abb65b4bSAndroid Build Coastguard Worker         break;
352*abb65b4bSAndroid Build Coastguard Worker     default:
353*abb65b4bSAndroid Build Coastguard Worker         logv3("unsupported color format\n");
354*abb65b4bSAndroid Build Coastguard Worker         goto ERR;
355*abb65b4bSAndroid Build Coastguard Worker     }
356*abb65b4bSAndroid Build Coastguard Worker 
357*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < imgb->np; i++) {
358*abb65b4bSAndroid Build Coastguard Worker         // width and height need to be aligned to macroblock size
359*abb65b4bSAndroid Build Coastguard Worker         imgb->aw[i] = ALIGN_VAL(imgb->w[i], OAPV_MB_W);
360*abb65b4bSAndroid Build Coastguard Worker         imgb->s[i] = imgb->aw[i] * bd;
361*abb65b4bSAndroid Build Coastguard Worker         imgb->ah[i] = ALIGN_VAL(imgb->h[i], OAPV_MB_H);
362*abb65b4bSAndroid Build Coastguard Worker         imgb->e[i] = imgb->ah[i];
363*abb65b4bSAndroid Build Coastguard Worker 
364*abb65b4bSAndroid Build Coastguard Worker         imgb->bsize[i] = imgb->s[i] * imgb->e[i];
365*abb65b4bSAndroid Build Coastguard Worker         imgb->a[i] = imgb->baddr[i] = picbuf_alloc(imgb->bsize[i]);
366*abb65b4bSAndroid Build Coastguard Worker         assert_g(imgb->a[i] != NULL, ERR);
367*abb65b4bSAndroid Build Coastguard Worker         memset(imgb->a[i], 0, imgb->bsize[i]);
368*abb65b4bSAndroid Build Coastguard Worker     }
369*abb65b4bSAndroid Build Coastguard Worker     imgb->cs = cs;
370*abb65b4bSAndroid Build Coastguard Worker     imgb->addref = imgb_addref;
371*abb65b4bSAndroid Build Coastguard Worker     imgb->getref = imgb_getref;
372*abb65b4bSAndroid Build Coastguard Worker     imgb->release = imgb_release;
373*abb65b4bSAndroid Build Coastguard Worker 
374*abb65b4bSAndroid Build Coastguard Worker     imgb->addref(imgb); /* increase reference count */
375*abb65b4bSAndroid Build Coastguard Worker     return imgb;
376*abb65b4bSAndroid Build Coastguard Worker 
377*abb65b4bSAndroid Build Coastguard Worker ERR:
378*abb65b4bSAndroid Build Coastguard Worker     logerr("cannot create image buffer\n");
379*abb65b4bSAndroid Build Coastguard Worker     if(imgb) {
380*abb65b4bSAndroid Build Coastguard Worker         for(int i = 0; i < OAPV_MAX_CC; i++) {
381*abb65b4bSAndroid Build Coastguard Worker             if(imgb->a[i])
382*abb65b4bSAndroid Build Coastguard Worker                 picbuf_free(imgb->a[i]);
383*abb65b4bSAndroid Build Coastguard Worker         }
384*abb65b4bSAndroid Build Coastguard Worker         free(imgb);
385*abb65b4bSAndroid Build Coastguard Worker     }
386*abb65b4bSAndroid Build Coastguard Worker     return NULL;
387*abb65b4bSAndroid Build Coastguard Worker }
388*abb65b4bSAndroid Build Coastguard Worker 
imgb_read(FILE * fp,oapv_imgb_t * img,int width,int height,int is_y4m)389*abb65b4bSAndroid Build Coastguard Worker static int imgb_read(FILE *fp, oapv_imgb_t *img, int width, int height, int is_y4m)
390*abb65b4bSAndroid Build Coastguard Worker {
391*abb65b4bSAndroid Build Coastguard Worker     int            f_w, f_h;
392*abb65b4bSAndroid Build Coastguard Worker     unsigned char *p8;
393*abb65b4bSAndroid Build Coastguard Worker 
394*abb65b4bSAndroid Build Coastguard Worker     /* handling Y4M frame header */
395*abb65b4bSAndroid Build Coastguard Worker     char           t_buf[10];
396*abb65b4bSAndroid Build Coastguard Worker     if(is_y4m) {
397*abb65b4bSAndroid Build Coastguard Worker         if(6 != fread(t_buf, 1, 6, fp))
398*abb65b4bSAndroid Build Coastguard Worker             return -1;
399*abb65b4bSAndroid Build Coastguard Worker         if(memcmp(t_buf, "FRAME", 5)) {
400*abb65b4bSAndroid Build Coastguard Worker             logerr("Loss of framing in Y4M input data\n");
401*abb65b4bSAndroid Build Coastguard Worker             return -1;
402*abb65b4bSAndroid Build Coastguard Worker         }
403*abb65b4bSAndroid Build Coastguard Worker         if(t_buf[5] != '\n') {
404*abb65b4bSAndroid Build Coastguard Worker             logerr("Error parsing Y4M frame header\n");
405*abb65b4bSAndroid Build Coastguard Worker             return -1;
406*abb65b4bSAndroid Build Coastguard Worker         }
407*abb65b4bSAndroid Build Coastguard Worker     }
408*abb65b4bSAndroid Build Coastguard Worker 
409*abb65b4bSAndroid Build Coastguard Worker     /* reading YUV format */
410*abb65b4bSAndroid Build Coastguard Worker     int chroma_format = OAPV_CS_GET_FORMAT(img->cs);
411*abb65b4bSAndroid Build Coastguard Worker     int bit_depth = OAPV_CS_GET_BIT_DEPTH(img->cs);
412*abb65b4bSAndroid Build Coastguard Worker     int w_shift = (chroma_format == OAPV_CF_YCBCR420) || ((chroma_format == OAPV_CF_YCBCR422) || (chroma_format == OAPV_CF_PLANAR2)) ? 1 : 0;
413*abb65b4bSAndroid Build Coastguard Worker     int h_shift = chroma_format == OAPV_CF_YCBCR420 ? 1 : 0;
414*abb65b4bSAndroid Build Coastguard Worker 
415*abb65b4bSAndroid Build Coastguard Worker     if(bit_depth == 8) {
416*abb65b4bSAndroid Build Coastguard Worker         f_w = width;
417*abb65b4bSAndroid Build Coastguard Worker         f_h = height;
418*abb65b4bSAndroid Build Coastguard Worker     }
419*abb65b4bSAndroid Build Coastguard Worker     else if(bit_depth >= 10 && bit_depth <= 14) {
420*abb65b4bSAndroid Build Coastguard Worker         f_w = width * sizeof(short);
421*abb65b4bSAndroid Build Coastguard Worker         f_h = height;
422*abb65b4bSAndroid Build Coastguard Worker     }
423*abb65b4bSAndroid Build Coastguard Worker     else {
424*abb65b4bSAndroid Build Coastguard Worker         logerr("not supported bit-depth (%d)\n", bit_depth);
425*abb65b4bSAndroid Build Coastguard Worker         return -1;
426*abb65b4bSAndroid Build Coastguard Worker     }
427*abb65b4bSAndroid Build Coastguard Worker 
428*abb65b4bSAndroid Build Coastguard Worker     p8 = (unsigned char *)img->a[0];
429*abb65b4bSAndroid Build Coastguard Worker     for(int j = 0; j < f_h; j++) {
430*abb65b4bSAndroid Build Coastguard Worker         if(fread(p8, 1, f_w, fp) != (unsigned)f_w) {
431*abb65b4bSAndroid Build Coastguard Worker             return -1;
432*abb65b4bSAndroid Build Coastguard Worker         }
433*abb65b4bSAndroid Build Coastguard Worker         p8 += img->s[0];
434*abb65b4bSAndroid Build Coastguard Worker     }
435*abb65b4bSAndroid Build Coastguard Worker 
436*abb65b4bSAndroid Build Coastguard Worker     if(chroma_format == OAPV_CF_PLANAR2) {
437*abb65b4bSAndroid Build Coastguard Worker         p8 = (unsigned char *)img->a[1];
438*abb65b4bSAndroid Build Coastguard Worker         for(int j = 0; j < f_h; j++) {
439*abb65b4bSAndroid Build Coastguard Worker             if(fread(p8, 1, f_w, fp) != (unsigned)f_w) {
440*abb65b4bSAndroid Build Coastguard Worker                 return -1;
441*abb65b4bSAndroid Build Coastguard Worker             }
442*abb65b4bSAndroid Build Coastguard Worker             p8 += img->s[1];
443*abb65b4bSAndroid Build Coastguard Worker         }
444*abb65b4bSAndroid Build Coastguard Worker     }
445*abb65b4bSAndroid Build Coastguard Worker     else if(chroma_format != OAPV_CF_YCBCR400) {
446*abb65b4bSAndroid Build Coastguard Worker         f_w = f_w >> w_shift;
447*abb65b4bSAndroid Build Coastguard Worker         f_h = f_h >> h_shift;
448*abb65b4bSAndroid Build Coastguard Worker 
449*abb65b4bSAndroid Build Coastguard Worker         p8 = (unsigned char *)img->a[1];
450*abb65b4bSAndroid Build Coastguard Worker         for(int j = 0; j < f_h; j++) {
451*abb65b4bSAndroid Build Coastguard Worker             if(fread(p8, 1, f_w, fp) != (unsigned)f_w) {
452*abb65b4bSAndroid Build Coastguard Worker                 return -1;
453*abb65b4bSAndroid Build Coastguard Worker             }
454*abb65b4bSAndroid Build Coastguard Worker             p8 += img->s[1];
455*abb65b4bSAndroid Build Coastguard Worker         }
456*abb65b4bSAndroid Build Coastguard Worker 
457*abb65b4bSAndroid Build Coastguard Worker         p8 = (unsigned char *)img->a[2];
458*abb65b4bSAndroid Build Coastguard Worker         for(int j = 0; j < f_h; j++) {
459*abb65b4bSAndroid Build Coastguard Worker             if(fread(p8, 1, f_w, fp) != (unsigned)f_w) {
460*abb65b4bSAndroid Build Coastguard Worker                 return -1;
461*abb65b4bSAndroid Build Coastguard Worker             }
462*abb65b4bSAndroid Build Coastguard Worker             p8 += img->s[2];
463*abb65b4bSAndroid Build Coastguard Worker         }
464*abb65b4bSAndroid Build Coastguard Worker     }
465*abb65b4bSAndroid Build Coastguard Worker 
466*abb65b4bSAndroid Build Coastguard Worker     if(chroma_format == OAPV_CF_YCBCR4444) {
467*abb65b4bSAndroid Build Coastguard Worker         f_w = f_w >> w_shift;
468*abb65b4bSAndroid Build Coastguard Worker         f_h = f_h >> h_shift;
469*abb65b4bSAndroid Build Coastguard Worker 
470*abb65b4bSAndroid Build Coastguard Worker         p8 = (unsigned char *)img->a[3];
471*abb65b4bSAndroid Build Coastguard Worker         for(int j = 0; j < f_h; j++) {
472*abb65b4bSAndroid Build Coastguard Worker             if(fread(p8, 1, f_w, fp) != (unsigned)f_w) {
473*abb65b4bSAndroid Build Coastguard Worker                 return -1;
474*abb65b4bSAndroid Build Coastguard Worker             }
475*abb65b4bSAndroid Build Coastguard Worker             p8 += img->s[3];
476*abb65b4bSAndroid Build Coastguard Worker         }
477*abb65b4bSAndroid Build Coastguard Worker     }
478*abb65b4bSAndroid Build Coastguard Worker 
479*abb65b4bSAndroid Build Coastguard Worker     return 0;
480*abb65b4bSAndroid Build Coastguard Worker }
481*abb65b4bSAndroid Build Coastguard Worker 
imgb_write(char * fname,oapv_imgb_t * imgb)482*abb65b4bSAndroid Build Coastguard Worker static int imgb_write(char *fname, oapv_imgb_t *imgb)
483*abb65b4bSAndroid Build Coastguard Worker {
484*abb65b4bSAndroid Build Coastguard Worker     unsigned char *p8;
485*abb65b4bSAndroid Build Coastguard Worker     int            i, j, bd;
486*abb65b4bSAndroid Build Coastguard Worker     FILE          *fp;
487*abb65b4bSAndroid Build Coastguard Worker 
488*abb65b4bSAndroid Build Coastguard Worker     int            chroma_format = OAPV_CS_GET_FORMAT(imgb->cs);
489*abb65b4bSAndroid Build Coastguard Worker     int            bit_depth = OAPV_CS_GET_BIT_DEPTH(imgb->cs);
490*abb65b4bSAndroid Build Coastguard Worker 
491*abb65b4bSAndroid Build Coastguard Worker     fp = fopen(fname, "ab");
492*abb65b4bSAndroid Build Coastguard Worker     if(fp == NULL) {
493*abb65b4bSAndroid Build Coastguard Worker         logerr("cannot open file = %s\n", fname);
494*abb65b4bSAndroid Build Coastguard Worker         return -1;
495*abb65b4bSAndroid Build Coastguard Worker     }
496*abb65b4bSAndroid Build Coastguard Worker     if(bit_depth == 8 && (chroma_format == OAPV_CF_YCBCR400 || chroma_format == OAPV_CF_YCBCR420 || chroma_format == OAPV_CF_YCBCR422 ||
497*abb65b4bSAndroid Build Coastguard Worker                           chroma_format == OAPV_CF_YCBCR444 || chroma_format == OAPV_CF_YCBCR4444)) {
498*abb65b4bSAndroid Build Coastguard Worker         bd = 1;
499*abb65b4bSAndroid Build Coastguard Worker     }
500*abb65b4bSAndroid Build Coastguard Worker     else if(bit_depth >= 10 && bit_depth <= 14 && (chroma_format == OAPV_CF_YCBCR400 || chroma_format == OAPV_CF_YCBCR420 || chroma_format == OAPV_CF_YCBCR422 || chroma_format == OAPV_CF_YCBCR444 || chroma_format == OAPV_CF_YCBCR4444)) {
501*abb65b4bSAndroid Build Coastguard Worker         bd = 2;
502*abb65b4bSAndroid Build Coastguard Worker     }
503*abb65b4bSAndroid Build Coastguard Worker     else if(bit_depth >= 10 && chroma_format == OAPV_CF_PLANAR2) {
504*abb65b4bSAndroid Build Coastguard Worker         bd = 2;
505*abb65b4bSAndroid Build Coastguard Worker     }
506*abb65b4bSAndroid Build Coastguard Worker     else {
507*abb65b4bSAndroid Build Coastguard Worker         logerr("cannot support the color space\n");
508*abb65b4bSAndroid Build Coastguard Worker         fclose(fp);
509*abb65b4bSAndroid Build Coastguard Worker         return -1;
510*abb65b4bSAndroid Build Coastguard Worker     }
511*abb65b4bSAndroid Build Coastguard Worker 
512*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < imgb->np; i++) {
513*abb65b4bSAndroid Build Coastguard Worker         p8 = (unsigned char *)imgb->a[i] + (imgb->s[i] * imgb->y[i]) + (imgb->x[i] * bd);
514*abb65b4bSAndroid Build Coastguard Worker 
515*abb65b4bSAndroid Build Coastguard Worker         for(j = 0; j < imgb->h[i]; j++) {
516*abb65b4bSAndroid Build Coastguard Worker             fwrite(p8, imgb->w[i] * bd, 1, fp);
517*abb65b4bSAndroid Build Coastguard Worker             p8 += imgb->s[i];
518*abb65b4bSAndroid Build Coastguard Worker         }
519*abb65b4bSAndroid Build Coastguard Worker     }
520*abb65b4bSAndroid Build Coastguard Worker 
521*abb65b4bSAndroid Build Coastguard Worker     fclose(fp);
522*abb65b4bSAndroid Build Coastguard Worker     return 0;
523*abb65b4bSAndroid Build Coastguard Worker }
524*abb65b4bSAndroid Build Coastguard Worker 
imgb_cpy_plane(oapv_imgb_t * dst,oapv_imgb_t * src)525*abb65b4bSAndroid Build Coastguard Worker static void imgb_cpy_plane(oapv_imgb_t *dst, oapv_imgb_t *src)
526*abb65b4bSAndroid Build Coastguard Worker {
527*abb65b4bSAndroid Build Coastguard Worker     int            i, j;
528*abb65b4bSAndroid Build Coastguard Worker     unsigned char *s, *d;
529*abb65b4bSAndroid Build Coastguard Worker     int            numbyte = OAPV_CS_GET_BYTE_DEPTH(src->cs);
530*abb65b4bSAndroid Build Coastguard Worker 
531*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < src->np; i++) {
532*abb65b4bSAndroid Build Coastguard Worker         s = (unsigned char *)src->a[i];
533*abb65b4bSAndroid Build Coastguard Worker         d = (unsigned char *)dst->a[i];
534*abb65b4bSAndroid Build Coastguard Worker 
535*abb65b4bSAndroid Build Coastguard Worker         for(j = 0; j < src->ah[i]; j++) {
536*abb65b4bSAndroid Build Coastguard Worker             memcpy(d, s, numbyte * src->aw[i]);
537*abb65b4bSAndroid Build Coastguard Worker             s += src->s[i];
538*abb65b4bSAndroid Build Coastguard Worker             d += dst->s[i];
539*abb65b4bSAndroid Build Coastguard Worker         }
540*abb65b4bSAndroid Build Coastguard Worker     }
541*abb65b4bSAndroid Build Coastguard Worker }
542*abb65b4bSAndroid Build Coastguard Worker 
imgb_cpy_shift_left_8b(oapv_imgb_t * dst,oapv_imgb_t * src,int shift)543*abb65b4bSAndroid Build Coastguard Worker static void imgb_cpy_shift_left_8b(oapv_imgb_t *dst, oapv_imgb_t *src, int shift)
544*abb65b4bSAndroid Build Coastguard Worker {
545*abb65b4bSAndroid Build Coastguard Worker     int            i, j, k;
546*abb65b4bSAndroid Build Coastguard Worker 
547*abb65b4bSAndroid Build Coastguard Worker     unsigned char *s;
548*abb65b4bSAndroid Build Coastguard Worker     short         *d;
549*abb65b4bSAndroid Build Coastguard Worker 
550*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < dst->np; i++) {
551*abb65b4bSAndroid Build Coastguard Worker         s = (unsigned char *)src->a[i];
552*abb65b4bSAndroid Build Coastguard Worker         d = (short *)dst->a[i];
553*abb65b4bSAndroid Build Coastguard Worker 
554*abb65b4bSAndroid Build Coastguard Worker         for(j = 0; j < src->ah[i]; j++) {
555*abb65b4bSAndroid Build Coastguard Worker             for(k = 0; k < src->aw[i]; k++) {
556*abb65b4bSAndroid Build Coastguard Worker                 d[k] = (short)(s[k] << shift);
557*abb65b4bSAndroid Build Coastguard Worker             }
558*abb65b4bSAndroid Build Coastguard Worker             s = s + src->s[i];
559*abb65b4bSAndroid Build Coastguard Worker             d = (short *)(((unsigned char *)d) + dst->s[i]);
560*abb65b4bSAndroid Build Coastguard Worker         }
561*abb65b4bSAndroid Build Coastguard Worker     }
562*abb65b4bSAndroid Build Coastguard Worker }
563*abb65b4bSAndroid Build Coastguard Worker 
imgb_cpy_shift_right_8b(oapv_imgb_t * dst,oapv_imgb_t * src,int shift)564*abb65b4bSAndroid Build Coastguard Worker static void imgb_cpy_shift_right_8b(oapv_imgb_t *dst, oapv_imgb_t *src, int shift)
565*abb65b4bSAndroid Build Coastguard Worker {
566*abb65b4bSAndroid Build Coastguard Worker     int            i, j, k, t0, add;
567*abb65b4bSAndroid Build Coastguard Worker 
568*abb65b4bSAndroid Build Coastguard Worker     short         *s;
569*abb65b4bSAndroid Build Coastguard Worker     unsigned char *d;
570*abb65b4bSAndroid Build Coastguard Worker 
571*abb65b4bSAndroid Build Coastguard Worker     if(shift)
572*abb65b4bSAndroid Build Coastguard Worker         add = 1 << (shift - 1);
573*abb65b4bSAndroid Build Coastguard Worker     else
574*abb65b4bSAndroid Build Coastguard Worker         add = 0;
575*abb65b4bSAndroid Build Coastguard Worker 
576*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < dst->np; i++) {
577*abb65b4bSAndroid Build Coastguard Worker         s = (short *)src->a[i];
578*abb65b4bSAndroid Build Coastguard Worker         d = (unsigned char *)dst->a[i];
579*abb65b4bSAndroid Build Coastguard Worker 
580*abb65b4bSAndroid Build Coastguard Worker         for(j = 0; j < src->ah[i]; j++) {
581*abb65b4bSAndroid Build Coastguard Worker             for(k = 0; k < src->aw[i]; k++) {
582*abb65b4bSAndroid Build Coastguard Worker                 t0 = ((s[k] + add) >> shift);
583*abb65b4bSAndroid Build Coastguard Worker                 d[k] = (unsigned char)(CLIP_VAL(t0, 0, 255));
584*abb65b4bSAndroid Build Coastguard Worker             }
585*abb65b4bSAndroid Build Coastguard Worker             s = (short *)(((unsigned char *)s) + src->s[i]);
586*abb65b4bSAndroid Build Coastguard Worker             d = d + dst->s[i];
587*abb65b4bSAndroid Build Coastguard Worker         }
588*abb65b4bSAndroid Build Coastguard Worker     }
589*abb65b4bSAndroid Build Coastguard Worker }
590*abb65b4bSAndroid Build Coastguard Worker 
imgb_cpy_shift_left(oapv_imgb_t * dst,oapv_imgb_t * src,int shift)591*abb65b4bSAndroid Build Coastguard Worker static void imgb_cpy_shift_left(oapv_imgb_t *dst, oapv_imgb_t *src, int shift)
592*abb65b4bSAndroid Build Coastguard Worker {
593*abb65b4bSAndroid Build Coastguard Worker     int             i, j, k;
594*abb65b4bSAndroid Build Coastguard Worker 
595*abb65b4bSAndroid Build Coastguard Worker     unsigned short *s;
596*abb65b4bSAndroid Build Coastguard Worker     unsigned short *d;
597*abb65b4bSAndroid Build Coastguard Worker 
598*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < dst->np; i++) {
599*abb65b4bSAndroid Build Coastguard Worker         s = (unsigned short *)src->a[i];
600*abb65b4bSAndroid Build Coastguard Worker         d = (unsigned short *)dst->a[i];
601*abb65b4bSAndroid Build Coastguard Worker 
602*abb65b4bSAndroid Build Coastguard Worker         for(j = 0; j < src->h[i]; j++) {
603*abb65b4bSAndroid Build Coastguard Worker             for(k = 0; k < src->w[i]; k++) {
604*abb65b4bSAndroid Build Coastguard Worker                 d[k] = (unsigned short)(s[k] << shift);
605*abb65b4bSAndroid Build Coastguard Worker             }
606*abb65b4bSAndroid Build Coastguard Worker             s = (unsigned short *)(((unsigned char *)s) + src->s[i]);
607*abb65b4bSAndroid Build Coastguard Worker             d = (unsigned short *)(((unsigned char *)d) + dst->s[i]);
608*abb65b4bSAndroid Build Coastguard Worker         }
609*abb65b4bSAndroid Build Coastguard Worker     }
610*abb65b4bSAndroid Build Coastguard Worker }
611*abb65b4bSAndroid Build Coastguard Worker 
imgb_cpy_shift_right(oapv_imgb_t * dst,oapv_imgb_t * src,int shift)612*abb65b4bSAndroid Build Coastguard Worker static void imgb_cpy_shift_right(oapv_imgb_t *dst, oapv_imgb_t *src, int shift)
613*abb65b4bSAndroid Build Coastguard Worker {
614*abb65b4bSAndroid Build Coastguard Worker     int             i, j, k, t0, add;
615*abb65b4bSAndroid Build Coastguard Worker 
616*abb65b4bSAndroid Build Coastguard Worker     int             clip_min = 0;
617*abb65b4bSAndroid Build Coastguard Worker     int             clip_max = 0;
618*abb65b4bSAndroid Build Coastguard Worker 
619*abb65b4bSAndroid Build Coastguard Worker     unsigned short *s;
620*abb65b4bSAndroid Build Coastguard Worker     unsigned short *d;
621*abb65b4bSAndroid Build Coastguard Worker 
622*abb65b4bSAndroid Build Coastguard Worker     if(shift)
623*abb65b4bSAndroid Build Coastguard Worker         add = 1 << (shift - 1);
624*abb65b4bSAndroid Build Coastguard Worker     else
625*abb65b4bSAndroid Build Coastguard Worker         add = 0;
626*abb65b4bSAndroid Build Coastguard Worker 
627*abb65b4bSAndroid Build Coastguard Worker     clip_max = (1 << (OAPV_CS_GET_BIT_DEPTH(dst->cs))) - 1;
628*abb65b4bSAndroid Build Coastguard Worker 
629*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < dst->np; i++) {
630*abb65b4bSAndroid Build Coastguard Worker         s = (unsigned short *)src->a[i];
631*abb65b4bSAndroid Build Coastguard Worker         d = (unsigned short *)dst->a[i];
632*abb65b4bSAndroid Build Coastguard Worker 
633*abb65b4bSAndroid Build Coastguard Worker         for(j = 0; j < src->h[i]; j++) {
634*abb65b4bSAndroid Build Coastguard Worker             for(k = 0; k < src->w[i]; k++) {
635*abb65b4bSAndroid Build Coastguard Worker                 t0 = ((s[k] + add) >> shift);
636*abb65b4bSAndroid Build Coastguard Worker                 d[k] = (CLIP_VAL(t0, clip_min, clip_max));
637*abb65b4bSAndroid Build Coastguard Worker             }
638*abb65b4bSAndroid Build Coastguard Worker             s = (unsigned short *)(((unsigned char *)s) + src->s[i]);
639*abb65b4bSAndroid Build Coastguard Worker             d = (unsigned short *)(((unsigned char *)d) + dst->s[i]);
640*abb65b4bSAndroid Build Coastguard Worker         }
641*abb65b4bSAndroid Build Coastguard Worker     }
642*abb65b4bSAndroid Build Coastguard Worker }
643*abb65b4bSAndroid Build Coastguard Worker 
imgb_cpy(oapv_imgb_t * dst,oapv_imgb_t * src)644*abb65b4bSAndroid Build Coastguard Worker static void imgb_cpy(oapv_imgb_t *dst, oapv_imgb_t *src)
645*abb65b4bSAndroid Build Coastguard Worker {
646*abb65b4bSAndroid Build Coastguard Worker     int i, bd_src, bd_dst;
647*abb65b4bSAndroid Build Coastguard Worker     bd_src = OAPV_CS_GET_BIT_DEPTH(src->cs);
648*abb65b4bSAndroid Build Coastguard Worker     bd_dst = OAPV_CS_GET_BIT_DEPTH(dst->cs);
649*abb65b4bSAndroid Build Coastguard Worker 
650*abb65b4bSAndroid Build Coastguard Worker     if(src->cs == dst->cs) {
651*abb65b4bSAndroid Build Coastguard Worker         imgb_cpy_plane(dst, src);
652*abb65b4bSAndroid Build Coastguard Worker     }
653*abb65b4bSAndroid Build Coastguard Worker     else if(bd_src == 8 && bd_dst > 8) {
654*abb65b4bSAndroid Build Coastguard Worker         imgb_cpy_shift_left_8b(dst, src, bd_dst - bd_src);
655*abb65b4bSAndroid Build Coastguard Worker     }
656*abb65b4bSAndroid Build Coastguard Worker     else if(bd_src > 8 && bd_dst == 8) {
657*abb65b4bSAndroid Build Coastguard Worker         imgb_cpy_shift_right_8b(dst, src, bd_src - bd_dst);
658*abb65b4bSAndroid Build Coastguard Worker     }
659*abb65b4bSAndroid Build Coastguard Worker     else if(bd_src < bd_dst) {
660*abb65b4bSAndroid Build Coastguard Worker         imgb_cpy_shift_left(dst, src, bd_dst - bd_src);
661*abb65b4bSAndroid Build Coastguard Worker     }
662*abb65b4bSAndroid Build Coastguard Worker     else if(bd_src > bd_dst) {
663*abb65b4bSAndroid Build Coastguard Worker         imgb_cpy_shift_right(dst, src, bd_src - bd_dst);
664*abb65b4bSAndroid Build Coastguard Worker     }
665*abb65b4bSAndroid Build Coastguard Worker     else {
666*abb65b4bSAndroid Build Coastguard Worker         logerr("ERROR: unsupported image copy\n");
667*abb65b4bSAndroid Build Coastguard Worker         return;
668*abb65b4bSAndroid Build Coastguard Worker     }
669*abb65b4bSAndroid Build Coastguard Worker     for(i = 0; i < OAPV_MAX_CC; i++) {
670*abb65b4bSAndroid Build Coastguard Worker         dst->x[i] = src->x[i];
671*abb65b4bSAndroid Build Coastguard Worker         dst->y[i] = src->y[i];
672*abb65b4bSAndroid Build Coastguard Worker         dst->w[i] = src->w[i];
673*abb65b4bSAndroid Build Coastguard Worker         dst->h[i] = src->h[i];
674*abb65b4bSAndroid Build Coastguard Worker         dst->ts[i] = src->ts[i];
675*abb65b4bSAndroid Build Coastguard Worker     }
676*abb65b4bSAndroid Build Coastguard Worker }
677*abb65b4bSAndroid Build Coastguard Worker 
measure_psnr(oapv_imgb_t * org,oapv_imgb_t * rec,double psnr[4],int bit_depth)678*abb65b4bSAndroid Build Coastguard Worker static void measure_psnr(oapv_imgb_t *org, oapv_imgb_t *rec, double psnr[4], int bit_depth)
679*abb65b4bSAndroid Build Coastguard Worker {
680*abb65b4bSAndroid Build Coastguard Worker     double sum[4], mse[4];
681*abb65b4bSAndroid Build Coastguard Worker 
682*abb65b4bSAndroid Build Coastguard Worker     if(bit_depth == 8) {
683*abb65b4bSAndroid Build Coastguard Worker         unsigned char *o, *r;
684*abb65b4bSAndroid Build Coastguard Worker         int            i, j, k;
685*abb65b4bSAndroid Build Coastguard Worker 
686*abb65b4bSAndroid Build Coastguard Worker         for(i = 0; i < org->np; i++) {
687*abb65b4bSAndroid Build Coastguard Worker             o = (unsigned char *)org->a[i];
688*abb65b4bSAndroid Build Coastguard Worker             r = (unsigned char *)rec->a[i];
689*abb65b4bSAndroid Build Coastguard Worker             sum[i] = 0;
690*abb65b4bSAndroid Build Coastguard Worker 
691*abb65b4bSAndroid Build Coastguard Worker             for(j = 0; j < org->h[i]; j++) {
692*abb65b4bSAndroid Build Coastguard Worker                 for(k = 0; k < org->w[i]; k++) {
693*abb65b4bSAndroid Build Coastguard Worker                     sum[i] += (o[k] - r[k]) * (o[k] - r[k]);
694*abb65b4bSAndroid Build Coastguard Worker                 }
695*abb65b4bSAndroid Build Coastguard Worker 
696*abb65b4bSAndroid Build Coastguard Worker                 o += org->s[i];
697*abb65b4bSAndroid Build Coastguard Worker                 r += rec->s[i];
698*abb65b4bSAndroid Build Coastguard Worker             }
699*abb65b4bSAndroid Build Coastguard Worker             mse[i] = sum[i] / (org->w[i] * org->h[i]);
700*abb65b4bSAndroid Build Coastguard Worker             psnr[i] = (mse[i] == 0.0) ? 100. : fabs(10 * log10(((255 * 255) / mse[i])));
701*abb65b4bSAndroid Build Coastguard Worker         }
702*abb65b4bSAndroid Build Coastguard Worker     }
703*abb65b4bSAndroid Build Coastguard Worker     else {
704*abb65b4bSAndroid Build Coastguard Worker         /* more than 8bit, ex) 10bit */
705*abb65b4bSAndroid Build Coastguard Worker         unsigned short *o, *r;
706*abb65b4bSAndroid Build Coastguard Worker         int             i, j, k;
707*abb65b4bSAndroid Build Coastguard Worker         int             factor = 1 << (bit_depth - 8);
708*abb65b4bSAndroid Build Coastguard Worker         factor *= factor;
709*abb65b4bSAndroid Build Coastguard Worker         for(i = 0; i < org->np; i++) {
710*abb65b4bSAndroid Build Coastguard Worker             o = (unsigned short *)org->a[i];
711*abb65b4bSAndroid Build Coastguard Worker             r = (unsigned short *)rec->a[i];
712*abb65b4bSAndroid Build Coastguard Worker             sum[i] = 0;
713*abb65b4bSAndroid Build Coastguard Worker             for(j = 0; j < org->h[i]; j++) {
714*abb65b4bSAndroid Build Coastguard Worker                 for(k = 0; k < org->w[i]; k++) {
715*abb65b4bSAndroid Build Coastguard Worker                     if(OAPV_CS_GET_FORMAT(org->cs) == OAPV_CF_PLANAR2) {
716*abb65b4bSAndroid Build Coastguard Worker                         sum[i] += (((int)o[k] - (int)r[k]) >> 6) * (((int)o[k] - (int)r[k]) >> 6);
717*abb65b4bSAndroid Build Coastguard Worker                     }
718*abb65b4bSAndroid Build Coastguard Worker                     else {
719*abb65b4bSAndroid Build Coastguard Worker                         sum[i] += (o[k] - r[k]) * (o[k] - r[k]);
720*abb65b4bSAndroid Build Coastguard Worker                     }
721*abb65b4bSAndroid Build Coastguard Worker                 }
722*abb65b4bSAndroid Build Coastguard Worker                 o = (unsigned short *)((unsigned char *)o + org->s[i]);
723*abb65b4bSAndroid Build Coastguard Worker                 r = (unsigned short *)((unsigned char *)r + rec->s[i]);
724*abb65b4bSAndroid Build Coastguard Worker             }
725*abb65b4bSAndroid Build Coastguard Worker             mse[i] = sum[i] / (org->w[i] * org->h[i]);
726*abb65b4bSAndroid Build Coastguard Worker             psnr[i] = (mse[i] == 0.0) ? 100. : fabs(10 * log10(((255 * 255 * factor) / mse[i])));
727*abb65b4bSAndroid Build Coastguard Worker         }
728*abb65b4bSAndroid Build Coastguard Worker     }
729*abb65b4bSAndroid Build Coastguard Worker }
730*abb65b4bSAndroid Build Coastguard Worker 
write_data(char * fname,unsigned char * data,int size)731*abb65b4bSAndroid Build Coastguard Worker static int write_data(char *fname, unsigned char *data, int size)
732*abb65b4bSAndroid Build Coastguard Worker {
733*abb65b4bSAndroid Build Coastguard Worker     FILE *fp;
734*abb65b4bSAndroid Build Coastguard Worker 
735*abb65b4bSAndroid Build Coastguard Worker     fp = fopen(fname, "ab");
736*abb65b4bSAndroid Build Coastguard Worker     if(fp == NULL) {
737*abb65b4bSAndroid Build Coastguard Worker         logerr("cannot open an writing file=%s\n", fname);
738*abb65b4bSAndroid Build Coastguard Worker         return -1;
739*abb65b4bSAndroid Build Coastguard Worker     }
740*abb65b4bSAndroid Build Coastguard Worker     fwrite(data, 1, size, fp);
741*abb65b4bSAndroid Build Coastguard Worker     fclose(fp);
742*abb65b4bSAndroid Build Coastguard Worker     return 0;
743*abb65b4bSAndroid Build Coastguard Worker }
744*abb65b4bSAndroid Build Coastguard Worker 
clear_data(char * fname)745*abb65b4bSAndroid Build Coastguard Worker static int clear_data(char *fname)
746*abb65b4bSAndroid Build Coastguard Worker {
747*abb65b4bSAndroid Build Coastguard Worker     FILE *fp;
748*abb65b4bSAndroid Build Coastguard Worker     fp = fopen(fname, "wb");
749*abb65b4bSAndroid Build Coastguard Worker     if(fp == NULL) {
750*abb65b4bSAndroid Build Coastguard Worker         logerr("cannot remove file (%s)\n", fname);
751*abb65b4bSAndroid Build Coastguard Worker         return -1;
752*abb65b4bSAndroid Build Coastguard Worker     }
753*abb65b4bSAndroid Build Coastguard Worker     fclose(fp);
754*abb65b4bSAndroid Build Coastguard Worker     return 0;
755*abb65b4bSAndroid Build Coastguard Worker }
char_to_hex(char a)756*abb65b4bSAndroid Build Coastguard Worker static unsigned char char_to_hex(char a)
757*abb65b4bSAndroid Build Coastguard Worker {
758*abb65b4bSAndroid Build Coastguard Worker     unsigned char ret;
759*abb65b4bSAndroid Build Coastguard Worker 
760*abb65b4bSAndroid Build Coastguard Worker     switch(a) {
761*abb65b4bSAndroid Build Coastguard Worker     case 'a':
762*abb65b4bSAndroid Build Coastguard Worker     case 'A':
763*abb65b4bSAndroid Build Coastguard Worker         ret = 10;
764*abb65b4bSAndroid Build Coastguard Worker         break;
765*abb65b4bSAndroid Build Coastguard Worker     case 'b':
766*abb65b4bSAndroid Build Coastguard Worker     case 'B':
767*abb65b4bSAndroid Build Coastguard Worker         ret = 11;
768*abb65b4bSAndroid Build Coastguard Worker         break;
769*abb65b4bSAndroid Build Coastguard Worker     case 'c':
770*abb65b4bSAndroid Build Coastguard Worker     case 'C':
771*abb65b4bSAndroid Build Coastguard Worker         ret = 12;
772*abb65b4bSAndroid Build Coastguard Worker         break;
773*abb65b4bSAndroid Build Coastguard Worker     case 'd':
774*abb65b4bSAndroid Build Coastguard Worker     case 'D':
775*abb65b4bSAndroid Build Coastguard Worker         ret = 13;
776*abb65b4bSAndroid Build Coastguard Worker         break;
777*abb65b4bSAndroid Build Coastguard Worker     case 'e':
778*abb65b4bSAndroid Build Coastguard Worker     case 'E':
779*abb65b4bSAndroid Build Coastguard Worker         ret = 14;
780*abb65b4bSAndroid Build Coastguard Worker         break;
781*abb65b4bSAndroid Build Coastguard Worker     case 'f':
782*abb65b4bSAndroid Build Coastguard Worker     case 'F':
783*abb65b4bSAndroid Build Coastguard Worker         ret = 15;
784*abb65b4bSAndroid Build Coastguard Worker         break;
785*abb65b4bSAndroid Build Coastguard Worker     default:
786*abb65b4bSAndroid Build Coastguard Worker         ret = (unsigned char)a - '0';
787*abb65b4bSAndroid Build Coastguard Worker         break;
788*abb65b4bSAndroid Build Coastguard Worker     }
789*abb65b4bSAndroid Build Coastguard Worker     return ret;
790*abb65b4bSAndroid Build Coastguard Worker }
791*abb65b4bSAndroid Build Coastguard Worker 
792*abb65b4bSAndroid Build Coastguard Worker #endif /* _OAPV_APP_UTIL_H_ */
793