fixed svace issues
[platform/adaptation/ap_samsung/libexynos-common.git] / libcsc / csc.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file        csc.c
20  *
21  * @brief       color space convertion abstract source
22  *
23  * @author      Pyoungjae Jung(pjet.jung@samsung.com)
24  *
25  * @version     1.0.0
26  *
27  * @history
28  *   2012.1.11 : Create
29  */
30 #include <exynos_log.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <system/graphics.h>
35
36 #include <csc.h>
37 #include <exynos_format.h>
38 #include <swconverter.h>
39
40 #ifdef USES_FIMC
41 #include "exynos_fimc.h"
42 #endif
43
44 #ifdef USES_GSCALER
45 #include "exynos_gscaler.h"
46 #include "exynos_scaler.h"
47 #endif
48
49 #define GSCALER_IMG_ALIGN 16
50 #define FIMC_IMG_ALIGN_WIDTH 16
51 #define FIMC_IMG_ALIGN_HEIGHT 2
52 #define MFC_IMG_ALIGN_WIDTH 16
53
54 static CSC_ERRORCODE copy_mfc_data(CSC_HANDLE *handle) {
55     CSC_ERRORCODE ret = CSC_ErrorNone;
56
57     int i;
58     char *pSrc = NULL;
59     char *pDst = NULL;
60
61     ALOGV("%s: convert %x to %x", __FUNCTION__, handle->src_format.color_format, handle->dst_format.color_format);
62
63     switch (handle->src_format.color_format) {
64     /* Multi FD to Single FD : decoder */
65     /* remove a padding data */
66     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
67     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
68     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
69         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
70         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
71         for (i = 0; i < (int)handle->src_format.crop_height; i++) {
72             memcpy(pDst + (handle->src_format.crop_width * i),
73                    pSrc + (handle->src_format.width * i),
74                    handle->src_format.crop_width);
75         }
76
77         pSrc = (char *)handle->src_buffer.planes[CSC_U_PLANE];
78         pDst = (char *)handle->dst_buffer.planes[CSC_U_PLANE];
79         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
80             memcpy(pDst + ((handle->src_format.crop_width >> 1) * i),
81                    pSrc + (ALIGN((handle->src_format.crop_width >> 1), MFC_IMG_ALIGN_WIDTH) * i),
82                    (handle->src_format.crop_width >> 1));
83         }
84
85         pSrc = (char *)handle->src_buffer.planes[CSC_V_PLANE];
86         pDst = (char *)handle->dst_buffer.planes[CSC_V_PLANE];
87         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
88             memcpy(pDst + ((handle->src_format.crop_width >> 1) * i),
89                    pSrc + (ALIGN((handle->src_format.crop_width >> 1), MFC_IMG_ALIGN_WIDTH) * i),
90                    (handle->src_format.crop_width >> 1));
91         }
92         break;
93     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
94     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
95     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
96     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
97     case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
98         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
99         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
100         for (i = 0; i < (int)handle->src_format.crop_height; i++) {
101             memcpy(pDst + (handle->src_format.crop_width * i),
102                    pSrc + (handle->src_format.width * i),
103                    handle->src_format.crop_width);
104         }
105
106         pSrc = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
107         pDst = (char *)handle->dst_buffer.planes[CSC_UV_PLANE];
108         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
109             memcpy(pDst + (handle->src_format.crop_width * i),
110                    pSrc + (handle->src_format.width * i),
111                    handle->src_format.crop_width);
112         }
113         break;
114     /* Single FD to Multi FD : encoder */
115     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
116     case HAL_PIXEL_FORMAT_YV12:
117         /* adding a padding data for u/v plane : 420P */
118         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
119         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
120         if (handle->src_format.width == handle->src_format.crop_width) {
121             memcpy(pDst, pSrc, (handle->src_format.width * handle->src_format.height));
122         } else {
123             for (i = 0; i < (int)handle->src_format.height; i++) {
124                 memcpy(pDst + (handle->src_format.width * i),
125                        pSrc + (handle->src_format.crop_width * i),
126                        handle->src_format.crop_width);
127             }
128         }
129
130         pSrc = (char *)handle->src_buffer.planes[CSC_U_PLANE];
131         pDst = (char *)handle->dst_buffer.planes[CSC_U_PLANE];
132         for (i = 0; i < (int)(handle->src_format.height >> 1); i++) {
133             memcpy(pDst + (ALIGN((handle->src_format.width >> 1), MFC_IMG_ALIGN_WIDTH) * i),
134                    pSrc + ((handle->src_format.crop_width >> 1) * i),
135                    (handle->src_format.crop_width >> 1));
136         }
137
138         pSrc = (char *)handle->src_buffer.planes[CSC_V_PLANE];
139         pDst = (char *)handle->dst_buffer.planes[CSC_V_PLANE];
140         for (i = 0; i < (int)(handle->src_format.height >> 1); i++) {
141             memcpy(pDst + (ALIGN((handle->src_format.width >> 1), MFC_IMG_ALIGN_WIDTH) * i),
142                    pSrc + ((handle->src_format.crop_width >> 1) * i),
143                    (handle->src_format.crop_width >> 1));
144         }
145         break;
146     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
147     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
148         if (handle->src_format.width == handle->src_format.crop_width) {
149             pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
150             pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
151             memcpy(pDst, pSrc, (handle->src_format.width * handle->src_format.height));
152
153             pSrc = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
154             pDst = (char *)handle->dst_buffer.planes[CSC_UV_PLANE];
155             memcpy(pDst, pSrc, (handle->src_format.width * (handle->src_format.height >> 1)));
156         } else {
157             pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
158             pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
159             for (i = 0; i < (int)handle->src_format.height; i++) {
160                 memcpy(pDst + (handle->src_format.width * i),
161                        pSrc + (handle->src_format.crop_width * i),
162                        handle->src_format.crop_width);
163             }
164
165             pSrc = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
166             pDst = (char *)handle->dst_buffer.planes[CSC_UV_PLANE];
167             memcpy(pDst, pSrc, (handle->src_format.width * (handle->src_format.height >> 1)));
168             for (i = 0; i < (int)(handle->src_format.height >> 1); i++) {
169                 memcpy(pDst + (handle->src_format.width * i),
170                        pSrc + (handle->src_format.crop_width * i),
171                        handle->src_format.crop_width);
172             }
173         }
174         break;
175     case HAL_PIXEL_FORMAT_BGRA_8888:
176     case HAL_PIXEL_FORMAT_RGBA_8888:
177     case HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888:
178         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
179         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
180         memcpy(pDst, pSrc, (handle->src_format.width * handle->src_format.height * 4));
181         break;
182     default:
183         ret = CSC_ErrorUnsupportFormat;
184         break;
185     }
186
187     return ret;
188 }
189
190 /* source is BRGA888 */
191 static CSC_ERRORCODE conv_sw_src_argb888(
192     CSC_HANDLE *handle)
193 {
194     CSC_ERRORCODE ret = CSC_ErrorNone;
195
196     switch (handle->dst_format.color_format) {
197     case HAL_PIXEL_FORMAT_BGRA_8888:
198         if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) {
199             ret = copy_mfc_data(handle);
200         } else {
201             ret = CSC_ErrorUnsupportFormat;
202         }
203         break;
204     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
205     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
206     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
207         csc_BGRA8888_to_YUV420P(
208             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
209             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
210             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
211             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
212             handle->src_format.width,
213             handle->src_format.height);
214         ret = CSC_ErrorNone;
215         break;
216     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
217     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
218     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
219         csc_BGRA8888_to_YUV420SP(
220             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
221             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
222             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
223             handle->src_format.width,
224             handle->src_format.height);
225         ret = CSC_ErrorNone;
226         break;
227     case HAL_PIXEL_FORMAT_YV12:
228     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
229         csc_BGRA8888_to_YUV420P(
230             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
231             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
232             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
233             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
234             handle->src_format.width,
235             handle->src_format.height);
236         ret = CSC_ErrorNone;
237         break;
238     default:
239         ret = CSC_ErrorUnsupportFormat;
240         break;
241     }
242
243     return ret;
244 }
245
246 /* source is RGBA888 */
247 static CSC_ERRORCODE conv_sw_src_rgba888(
248     CSC_HANDLE *handle)
249 {
250     CSC_ERRORCODE ret = CSC_ErrorNone;
251
252     switch (handle->dst_format.color_format) {
253     case HAL_PIXEL_FORMAT_RGBA_8888:
254         if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) {
255             ret = copy_mfc_data(handle);
256         } else {
257             ret = CSC_ErrorUnsupportFormat;
258         }
259         break;
260     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
261     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
262     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
263         csc_RGBA8888_to_YUV420P(
264             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
265             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
266             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
267             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
268             handle->src_format.width,
269             handle->src_format.height);
270         ret = CSC_ErrorNone;
271         break;
272     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
273     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
274     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
275         csc_RGBA8888_to_YUV420SP(
276             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
277             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
278             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
279             handle->src_format.width,
280             handle->src_format.height);
281         ret = CSC_ErrorNone;
282         break;
283     case HAL_PIXEL_FORMAT_YV12:
284     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
285         csc_RGBA8888_to_YUV420P(
286             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
287             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
288             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
289             (unsigned char *)handle->src_buffer.planes[CSC_RGB_PLANE],
290             handle->src_format.width,
291             handle->src_format.height);
292         ret = CSC_ErrorNone;
293         break;
294     default:
295         ret = CSC_ErrorUnsupportFormat;
296         break;
297     }
298
299     return ret;
300 }
301
302
303 /* source is NV12T */
304 static CSC_ERRORCODE conv_sw_src_nv12t(
305     CSC_HANDLE *handle)
306 {
307     CSC_ERRORCODE ret = CSC_ErrorNone;
308
309     switch (handle->dst_format.color_format) {
310     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
311     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
312     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
313         csc_tiled_to_linear_y(
314             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
315             (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
316             handle->src_format.crop_width,
317             handle->src_format.crop_height);
318         csc_tiled_to_linear_uv_deinterleave(
319             (unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
320             (unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
321             (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
322             handle->src_format.crop_width,
323             handle->src_format.crop_height / 2);
324         ret = CSC_ErrorNone;
325         break;
326     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
327     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
328     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
329         csc_tiled_to_linear_y(
330             (unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
331             (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
332             handle->src_format.crop_width,
333             handle->src_format.crop_height);
334         csc_tiled_to_linear_uv(
335             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
336             (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
337             handle->src_format.crop_width,
338             handle->src_format.crop_height / 2);
339         ret = CSC_ErrorNone;
340         break;
341     default:
342         ret = CSC_ErrorUnsupportFormat;
343         break;
344     }
345
346     return ret;
347 }
348
349 /* source is YUV420P */
350 static CSC_ERRORCODE conv_sw_src_yuv420p(
351     CSC_HANDLE *handle)
352 {
353     CSC_ERRORCODE ret = CSC_ErrorNone;
354
355     switch (handle->dst_format.color_format) {
356     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:    /* bypass */
357     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
358     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
359         if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) {
360             ret = copy_mfc_data(handle);
361         } else {
362             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
363                    (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
364                    handle->src_format.width * handle->src_format.height);
365             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
366                    (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
367                    (handle->src_format.width * handle->src_format.height) >> 2);
368             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
369                    (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
370                    (handle->src_format.width * handle->src_format.height) >> 2);
371             ret = CSC_ErrorNone;
372         }
373         break;
374     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
375     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
376     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
377         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
378                (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
379                handle->src_format.width * handle->src_format.height);
380         csc_interleave_memcpy(
381             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
382             (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
383             (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
384             (handle->src_format.width * handle->src_format.height) >> 2);
385         ret = CSC_ErrorNone;
386         break;
387     default:
388         ret = CSC_ErrorUnsupportFormat;
389         break;
390     }
391
392     return ret;
393 }
394
395 /* source is YVU420P */
396 static CSC_ERRORCODE conv_sw_src_yvu420p(
397     CSC_HANDLE *handle)
398 {
399     CSC_ERRORCODE ret = CSC_ErrorNone;
400
401     switch (handle->dst_format.color_format) {
402     case HAL_PIXEL_FORMAT_YV12:  /* bypass */
403     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
404         if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) {
405             ret = copy_mfc_data(handle);
406         } else {
407             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
408                    (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
409                    handle->src_format.width * handle->src_format.height);
410             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_U_PLANE],
411                    (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
412                    (handle->src_format.width * handle->src_format.height) >> 2);
413             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_V_PLANE],
414                    (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
415                    (handle->src_format.width * handle->src_format.height) >> 2);
416             ret = CSC_ErrorNone;
417         }
418         break;
419     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
420     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
421     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
422         memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
423                (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
424                handle->src_format.width * handle->src_format.height);
425         csc_interleave_memcpy(
426             (unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
427             (unsigned char *)handle->src_buffer.planes[CSC_V_PLANE],
428             (unsigned char *)handle->src_buffer.planes[CSC_U_PLANE],
429             (handle->src_format.width * handle->src_format.height) >> 2);
430         ret = CSC_ErrorNone;
431         break;
432     default:
433         ret = CSC_ErrorUnsupportFormat;
434         break;
435     }
436
437     return ret;
438 }
439
440 /* source is YUV420SP */
441 static CSC_ERRORCODE conv_sw_src_yuv420sp(
442     CSC_HANDLE *handle)
443 {
444     CSC_ERRORCODE ret = CSC_ErrorNone;
445
446     char *pSrc  = NULL;
447     char *pDst  = NULL;
448     char *pDstU = NULL;
449     char *pDstV = NULL;
450     int srcOffset, dstOffset;
451     int i, j;
452
453     switch (handle->dst_format.color_format) {
454     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:    /* bypass */
455     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
456     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
457         if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) {
458             ret = copy_mfc_data(handle);
459         } else {
460             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
461                    (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
462                    handle->src_format.width * handle->src_format.height);
463             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
464                    (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
465                    handle->src_format.width * handle->src_format.height >> 1);
466             ret = CSC_ErrorNone;
467         }
468         break;
469     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
470     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
471     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
472     {
473         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
474         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
475         for (i = 0; i < (int)handle->src_format.crop_height; i++) {
476             memcpy(pDst + (handle->src_format.crop_width * i),
477                    pSrc + (handle->src_format.width * i),
478                    handle->src_format.crop_width);
479         }
480
481         pSrc  = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
482         pDstU = (char *)handle->dst_buffer.planes[CSC_U_PLANE];
483         pDstV = (char *)handle->dst_buffer.planes[CSC_V_PLANE];
484         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
485             for (j = 0; j < (int)(handle->src_format.crop_width >> 1); j++) {
486                 srcOffset = (i * handle->src_format.width) + (j * 2);
487                 dstOffset = i * (handle->src_format.crop_width >> 1);
488
489                 pDstU[dstOffset + j] = pSrc[srcOffset];
490                 pDstV[dstOffset + j] = pSrc[srcOffset + 1];
491             }
492         }
493         ret = CSC_ErrorNone;
494     }
495         break;
496     case HAL_PIXEL_FORMAT_YV12:
497     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
498         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
499         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
500         for (i = 0; i < (int)handle->src_format.crop_height; i++) {
501             memcpy(pDst + (handle->src_format.crop_width * i),
502                    pSrc + (handle->src_format.width * i),
503                    handle->src_format.crop_width);
504         }
505
506         pSrc  = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
507         pDstU = (char *)handle->dst_buffer.planes[CSC_U_PLANE];
508         pDstV = (char *)handle->dst_buffer.planes[CSC_V_PLANE];
509         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
510             for (j = 0; j < (int)(handle->src_format.crop_width >> 1); j++) {
511                 srcOffset = (i * handle->src_format.width) + (j * 2);
512                 dstOffset = i * (handle->src_format.crop_width >> 1);
513
514                 pDstU[dstOffset + j] = pSrc[srcOffset + 1];
515                 pDstV[dstOffset + j] = pSrc[srcOffset];
516             }
517         }
518         ret = CSC_ErrorNone;
519         break;
520     default:
521         ret = CSC_ErrorUnsupportFormat;
522         break;
523     }
524
525     return ret;
526 }
527
528 /* source is YVU420SP */
529 static CSC_ERRORCODE conv_sw_src_yvu420sp(
530     CSC_HANDLE *handle)
531 {
532     CSC_ERRORCODE ret = CSC_ErrorNone;
533
534     char *pSrc  = NULL;
535     char *pDst  = NULL;
536     char *pDstU = NULL;
537     char *pDstV = NULL;
538     int srcOffset, dstOffset;
539     int i, j;
540
541     switch (handle->dst_format.color_format) {
542     case HAL_PIXEL_FORMAT_YCrCb_420_SP:  /* bypass */
543     case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
544         if (handle->src_buffer.mem_type == CSC_MEMORY_MFC) {
545             ret = copy_mfc_data(handle);
546         } else {
547             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_Y_PLANE],
548                    (unsigned char *)handle->src_buffer.planes[CSC_Y_PLANE],
549                    handle->src_format.width * handle->src_format.height);
550             memcpy((unsigned char *)handle->dst_buffer.planes[CSC_UV_PLANE],
551                    (unsigned char *)handle->src_buffer.planes[CSC_UV_PLANE],
552                    handle->src_format.width * handle->src_format.height >> 1);
553             ret = CSC_ErrorNone;
554         }
555         break;
556     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
557     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
558     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
559         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
560         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
561         for (i = 0; i < (int)handle->src_format.crop_height; i++) {
562             memcpy(pDst + (handle->src_format.crop_width * i),
563                    pSrc + (handle->src_format.width * i),
564                    handle->src_format.crop_width);
565         }
566
567         pSrc  = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
568         pDstU = (char *)handle->dst_buffer.planes[CSC_U_PLANE];
569         pDstV = (char *)handle->dst_buffer.planes[CSC_V_PLANE];
570         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
571             for (j = 0; j < (int)(handle->src_format.crop_width >> 1); j++) {
572                 srcOffset = (i * handle->src_format.width) + (j * 2);
573                 dstOffset = i * (handle->src_format.crop_width >> 1);
574
575                 pDstU[dstOffset + j] = pSrc[srcOffset + 1];
576                 pDstV[dstOffset + j] = pSrc[srcOffset];
577             }
578         }
579         ret = CSC_ErrorNone;
580         break;
581     case HAL_PIXEL_FORMAT_YV12:
582     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
583         pSrc = (char *)handle->src_buffer.planes[CSC_Y_PLANE];
584         pDst = (char *)handle->dst_buffer.planes[CSC_Y_PLANE];
585         for (i = 0; i < (int)handle->src_format.crop_height; i++) {
586             memcpy(pDst + (handle->src_format.crop_width * i),
587                    pSrc + (handle->src_format.width * i),
588                    handle->src_format.crop_width);
589         }
590
591         pSrc  = (char *)handle->src_buffer.planes[CSC_UV_PLANE];
592         pDstU = (char *)handle->dst_buffer.planes[CSC_U_PLANE];
593         pDstV = (char *)handle->dst_buffer.planes[CSC_V_PLANE];
594         for (i = 0; i < (int)(handle->src_format.crop_height >> 1); i++) {
595             for (j = 0; j < (int)(handle->src_format.crop_width >> 1); j++) {
596                 srcOffset = (i * handle->src_format.width) + (j * 2);
597                 dstOffset = i * (handle->src_format.crop_width >> 1);
598
599                 pDstU[dstOffset + j] = pSrc[srcOffset];
600                 pDstV[dstOffset + j] = pSrc[srcOffset + 1];
601             }
602         }
603         ret = CSC_ErrorNone;
604         break;
605     default:
606         ret = CSC_ErrorUnsupportFormat;
607         break;
608     }
609
610     return ret;
611 }
612
613 static CSC_ERRORCODE conv_sw(
614     CSC_HANDLE *handle)
615 {
616     CSC_ERRORCODE ret = CSC_ErrorNone;
617
618     switch (handle->src_format.color_format) {
619     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
620     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED:
621         ret = conv_sw_src_nv12t(handle);
622         break;
623     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
624     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
625     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN:
626         ret = conv_sw_src_yuv420p(handle);
627         break;
628     case HAL_PIXEL_FORMAT_YV12:
629     case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
630         ret = conv_sw_src_yvu420p(handle);
631         break;
632     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP:
633     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
634     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
635     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
636     case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
637         ret = conv_sw_src_yuv420sp(handle);
638         break;
639     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
640     case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
641         ret = conv_sw_src_yvu420sp(handle);
642         break;
643     case HAL_PIXEL_FORMAT_BGRA_8888:
644         ret = conv_sw_src_argb888(handle);
645         break;
646     case HAL_PIXEL_FORMAT_RGBA_8888:
647         ret = conv_sw_src_rgba888(handle);
648         break;
649     case HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888:
650         ret = copy_mfc_data(handle);
651         break;
652     default:
653         ret = CSC_ErrorUnsupportFormat;
654         break;
655     }
656
657     return ret;
658 }
659
660 static CSC_ERRORCODE conv_hw(
661     CSC_HANDLE *handle)
662 {
663     CSC_ERRORCODE ret = CSC_ErrorNone;
664     switch (handle->csc_hw_type) {
665 #ifdef USES_FIMC
666     case CSC_HW_TYPE_FIMC:
667         if (exynos_fimc_convert(handle->csc_hw_handle) != 0) {
668             ALOGE("%s:: exynos_fimc_convert() fail", __func__);
669             ret = CSC_Error;
670         }
671         break;
672 #endif
673 #ifdef USES_GSCALER
674     case CSC_HW_TYPE_GSCALER:
675         if (handle->hw_property.fixed_node < CSC_HW_SC0) {
676             if (exynos_gsc_convert(handle->csc_hw_handle) != 0) {
677                 ALOGE("%s:: exynos_gsc_convert() fail", __func__);
678                 ret = CSC_Error;
679             }
680         } else {
681             if (exynos_sc_convert(handle->csc_hw_handle) != 0) {
682                 ALOGE("%s:: exynos_sc_convert() fail", __func__);
683                 ret = CSC_Error;
684             }
685         }
686         break;
687 #endif
688     default:
689         ALOGE("%s:: unsupported csc_hw_type(%d)", __func__, handle->csc_hw_type);
690         ret = CSC_ErrorNotImplemented;
691         break;
692     }
693
694     return ret;
695 }
696
697 static CSC_ERRORCODE csc_init_hw(
698     void *handle)
699 {
700     CSC_HANDLE *csc_handle;
701     CSC_ERRORCODE ret = CSC_ErrorNone;
702
703     csc_handle = (CSC_HANDLE *)handle;
704     if (csc_handle->csc_method == CSC_METHOD_HW) {
705 #ifdef USES_FIMC
706         csc_handle->csc_hw_type = CSC_HW_TYPE_FIMC;
707 #endif
708 #ifdef USES_GSCALER
709         csc_handle->csc_hw_type = CSC_HW_TYPE_GSCALER;
710 #endif
711         switch (csc_handle->csc_hw_type) {
712 #ifdef USES_FIMC
713         case CSC_HW_TYPE_FIMC:
714             if (csc_handle->hw_property.fixed_node >= 0)
715                 csc_handle->csc_hw_handle = exynos_fimc_create_exclusive(csc_handle->hw_property.fixed_node, FIMC_M2M_MODE, 0, 0);
716             else
717             csc_handle->csc_hw_handle = exynos_fimc_create();
718             ALOGV("%s:: CSC_HW_TYPE_FIMC", __func__);
719             break;
720 #endif
721 #ifdef USES_GSCALER
722         case CSC_HW_TYPE_GSCALER:
723             if (csc_handle->hw_property.fixed_node >= 0) {
724                 if (csc_handle->hw_property.fixed_node < CSC_HW_SC0)
725                     csc_handle->csc_hw_handle = exynos_gsc_create_exclusive(csc_handle->hw_property.fixed_node, GSC_M2M_MODE, 0, 0);
726                 else if (csc_handle->hw_property.fixed_node < CSC_HW_MAX)
727                     csc_handle->csc_hw_handle = exynos_sc_create(csc_handle->hw_property.fixed_node - CSC_HW_SC0);
728                 else
729                     csc_handle->csc_hw_handle = NULL;
730             } else {
731                 csc_handle->csc_hw_handle = exynos_gsc_create();
732             }
733             ALOGV("%s:: CSC_HW_TYPE_GSCALER", __func__);
734             break;
735 #endif
736         default:
737             ALOGE("%s:: unsupported csc_hw_type, csc use sw", __func__);
738             csc_handle->csc_hw_handle = NULL;
739             break;
740         }
741     }
742
743     if (csc_handle->csc_method == CSC_METHOD_HW) {
744         if (csc_handle->csc_hw_handle == NULL) {
745             ALOGE("%s:: CSC_METHOD_HW can't open HW", __func__);
746             free(csc_handle);
747             csc_handle = NULL;
748             ret = CSC_ErrorNotInit;
749         }
750     }
751     if (csc_handle)
752       ALOGV("%s:: CSC_METHOD=%d", __func__, csc_handle->csc_method);
753
754     return ret;
755 }
756
757 static CSC_ERRORCODE csc_set_format(
758     void *handle)
759 {
760     CSC_HANDLE *csc_handle;
761     CSC_ERRORCODE ret = CSC_ErrorNone;
762
763     if (handle == NULL)
764         return CSC_ErrorNotInit;
765
766     csc_handle = (CSC_HANDLE *)handle;
767     if (csc_handle->csc_method == CSC_METHOD_HW) {
768         switch (csc_handle->csc_hw_type) {
769 #ifdef USES_FIMC
770         case CSC_HW_TYPE_FIMC:
771             exynos_fimc_set_src_format(
772                 csc_handle->csc_hw_handle,
773                 ALIGN(csc_handle->src_format.width, FIMC_IMG_ALIGN_WIDTH),
774                 ALIGN(csc_handle->src_format.height, FIMC_IMG_ALIGN_HEIGHT),
775                 csc_handle->src_format.crop_left,
776                 csc_handle->src_format.crop_top,
777                 csc_handle->src_format.crop_width,
778                 csc_handle->src_format.crop_height,
779                 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format),
780                 csc_handle->src_format.cacheable,
781                 csc_handle->hw_property.mode_drm);
782
783             exynos_fimc_set_dst_format(
784                 csc_handle->csc_hw_handle,
785                 ALIGN(csc_handle->dst_format.width, FIMC_IMG_ALIGN_WIDTH),
786                 ALIGN(csc_handle->dst_format.height, FIMC_IMG_ALIGN_HEIGHT),
787                 csc_handle->dst_format.crop_left,
788                 csc_handle->dst_format.crop_top,
789                 csc_handle->dst_format.crop_width,
790                 csc_handle->dst_format.crop_height,
791                 HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format),
792                 csc_handle->dst_format.cacheable,
793                 csc_handle->hw_property.mode_drm,
794                 0);
795             break;
796 #endif
797 #ifdef USES_GSCALER
798         case CSC_HW_TYPE_GSCALER:
799             if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) {
800                 exynos_gsc_set_csc_property(
801                     csc_handle->csc_hw_handle,
802                     csc_handle->csc_mode,
803                     csc_handle->csc_range,
804                     csc_handle->colorspace);
805
806                 exynos_gsc_set_src_format(
807                     csc_handle->csc_hw_handle,
808                     csc_handle->src_format.width,
809                     csc_handle->src_format.height,
810                     csc_handle->src_format.crop_left,
811                     csc_handle->src_format.crop_top,
812                     csc_handle->src_format.crop_width,
813                     csc_handle->src_format.crop_height,
814                     HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format),
815                     csc_handle->src_format.cacheable,
816                     csc_handle->hw_property.mode_drm);
817
818                 exynos_gsc_set_dst_format(
819                     csc_handle->csc_hw_handle,
820                     csc_handle->dst_format.width,
821                     csc_handle->dst_format.height,
822                     csc_handle->dst_format.crop_left,
823                     csc_handle->dst_format.crop_top,
824                     csc_handle->dst_format.crop_width,
825                     csc_handle->dst_format.crop_height,
826                     HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format),
827                     csc_handle->dst_format.cacheable,
828                     csc_handle->hw_property.mode_drm);
829             } else {
830                 exynos_sc_set_csc_property(
831                     csc_handle->csc_hw_handle,
832                     csc_handle->csc_range,
833                     csc_handle->colorspace,
834                     csc_handle->filter);
835
836                 exynos_sc_set_src_format(
837                     csc_handle->csc_hw_handle,
838                     csc_handle->src_format.width,
839                     csc_handle->src_format.height,
840                     csc_handle->src_format.crop_left,
841                     csc_handle->src_format.crop_top,
842                     csc_handle->src_format.crop_width,
843                     csc_handle->src_format.crop_height,
844                     HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->src_format.color_format),
845                     csc_handle->src_format.cacheable,
846                     csc_handle->hw_property.mode_drm,
847                     1);
848
849                 exynos_sc_set_dst_format(
850                     csc_handle->csc_hw_handle,
851                     csc_handle->dst_format.width,
852                     csc_handle->dst_format.height,
853                     csc_handle->dst_format.crop_left,
854                     csc_handle->dst_format.crop_top,
855                     csc_handle->dst_format.crop_width,
856                     csc_handle->dst_format.crop_height,
857                     HAL_PIXEL_FORMAT_2_V4L2_PIX(csc_handle->dst_format.color_format),
858                     csc_handle->dst_format.cacheable,
859                     csc_handle->hw_property.mode_drm,
860                     1);
861             }
862             break;
863 #endif
864         default:
865             ALOGE("%s:: unsupported csc_hw_type", __func__);
866             break;
867         }
868     }
869
870     return ret;
871 }
872
873 static CSC_ERRORCODE csc_set_buffer(
874     void *handle)
875 {
876     CSC_HANDLE *csc_handle;
877     CSC_ERRORCODE ret = CSC_ErrorNone;
878
879     if (handle == NULL)
880         return CSC_ErrorNotInit;
881
882     csc_handle = (CSC_HANDLE *)handle;
883     if (csc_handle->csc_method == CSC_METHOD_HW) {
884         switch (csc_handle->csc_hw_type) {
885 #ifdef USES_FIMC
886         case CSC_HW_TYPE_FIMC:
887             exynos_fimc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1);
888             exynos_fimc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1);
889             break;
890 #endif
891 #ifdef USES_GSCALER
892         case CSC_HW_TYPE_GSCALER:
893             if (csc_handle->hw_property.fixed_node < CSC_HW_SC0) {
894                 exynos_gsc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1);
895                 exynos_gsc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1);
896             } else {
897                 exynos_sc_set_src_addr(csc_handle->csc_hw_handle, csc_handle->src_buffer.planes, csc_handle->src_buffer.mem_type, -1);
898                 exynos_sc_set_dst_addr(csc_handle->csc_hw_handle, csc_handle->dst_buffer.planes, csc_handle->dst_buffer.mem_type, -1);
899             }
900             break;
901 #endif
902         default:
903             ALOGE("%s:: unsupported csc_hw_type", __func__);
904             break;
905         }
906     }
907
908     return ret;
909 }
910
911 void *csc_init(
912     CSC_METHOD method)
913 {
914     CSC_HANDLE *csc_handle;
915     csc_handle = (CSC_HANDLE *)malloc(sizeof(CSC_HANDLE));
916     if (csc_handle == NULL)
917         return NULL;
918
919     memset(csc_handle, 0, sizeof(CSC_HANDLE));
920 #ifdef USES_DEFAULT_CSC_HW_SCALER
921     csc_handle->hw_property.fixed_node = DEFAULT_CSC_HW;        /* CSC_HW_SC1 == 5 */
922 #else
923     csc_handle->hw_property.fixed_node = -1;
924 #endif
925     csc_handle->hw_property.mode_drm = 0;
926     csc_handle->csc_method = method;
927
928     return (void *)csc_handle;
929 }
930
931 CSC_ERRORCODE csc_deinit(
932     void *handle)
933 {
934     CSC_ERRORCODE ret = CSC_ErrorNone;
935     CSC_HANDLE *csc_handle;
936
937     if (handle == NULL)
938         return ret;
939
940     csc_handle = (CSC_HANDLE *)handle;
941     if (csc_handle->csc_method == CSC_METHOD_HW) {
942         switch (csc_handle->csc_hw_type) {
943 #ifdef USES_FIMC
944         case CSC_HW_TYPE_FIMC:
945             exynos_fimc_destroy(csc_handle->csc_hw_handle);
946             break;
947 #endif
948 #ifdef USES_GSCALER
949         case CSC_HW_TYPE_GSCALER:
950             if (csc_handle->hw_property.fixed_node < CSC_HW_SC0)
951                 exynos_gsc_destroy(csc_handle->csc_hw_handle);
952             else
953                 exynos_sc_destroy(csc_handle->csc_hw_handle);
954             break;
955 #endif
956         default:
957             ALOGE("%s:: unsupported csc_hw_type", __func__);
958             break;
959         }
960     }
961
962     free(csc_handle);
963     ret = CSC_ErrorNone;
964
965     return ret;
966 }
967
968 CSC_ERRORCODE csc_get_method(
969     void           *handle,
970     CSC_METHOD     *method)
971 {
972     CSC_HANDLE *csc_handle;
973     CSC_ERRORCODE ret = CSC_ErrorNone;
974
975     if (handle == NULL)
976         return CSC_ErrorNotInit;
977
978     csc_handle = (CSC_HANDLE *)handle;
979     *method = csc_handle->csc_method;
980
981     return ret;
982 }
983
984 CSC_ERRORCODE csc_set_method(
985     void           *handle,
986     CSC_METHOD      method)
987 {
988     CSC_HANDLE *csc_handle;
989     CSC_ERRORCODE ret = CSC_ErrorNone;
990
991     if (handle == NULL)
992         return CSC_ErrorNotInit;
993     csc_handle = (CSC_HANDLE *)handle;
994
995     switch (method) {
996     case CSC_METHOD_SW:
997     case CSC_METHOD_HW:
998         csc_handle->csc_method = method;
999         break;
1000     default:
1001         ret = CSC_Error;
1002         break;
1003     }
1004
1005     return ret;
1006 }
1007
1008 CSC_ERRORCODE csc_set_hw_property(
1009     void                *handle,
1010     CSC_HW_PROPERTY_TYPE property,
1011     int                  value)
1012 {
1013     CSC_HANDLE *csc_handle;
1014     CSC_ERRORCODE ret = CSC_ErrorNone;
1015
1016     if (handle == NULL)
1017         return CSC_ErrorNotInit;
1018
1019     csc_handle = (CSC_HANDLE *)handle;
1020     switch (property) {
1021     case CSC_HW_PROPERTY_FIXED_NODE:
1022         csc_handle->hw_property.fixed_node = value;
1023         break;
1024     case CSC_HW_PROPERTY_MODE_DRM:
1025         csc_handle->hw_property.mode_drm = value;
1026         break;
1027     default:
1028         ALOGE("%s:: not supported hw property", __func__);
1029         ret = CSC_ErrorUnsupportFormat;
1030     }
1031
1032     return ret;
1033 }
1034
1035 CSC_ERRORCODE csc_get_eq_property(
1036     void              *handle,
1037     CSC_EQ_MODE       *csc_mode,
1038     CSC_EQ_RANGE      *csc_range,
1039     CSC_EQ_COLORSPACE *colorspace)
1040 {
1041     CSC_HANDLE *csc_handle;
1042     CSC_ERRORCODE ret = CSC_ErrorNone;
1043
1044     if (handle == NULL)
1045         return CSC_ErrorNotInit;
1046
1047     csc_handle = (CSC_HANDLE *)handle;
1048     *csc_mode = csc_handle->csc_mode;
1049     *csc_range = csc_handle->csc_range;
1050     *colorspace = csc_handle->colorspace;
1051
1052     return ret;
1053 }
1054
1055 CSC_ERRORCODE csc_set_eq_property(
1056     void              *handle,
1057     CSC_EQ_MODE        csc_mode,
1058     CSC_EQ_RANGE       csc_range,
1059     CSC_EQ_COLORSPACE  colorspace)
1060 {
1061     CSC_HANDLE *csc_handle;
1062     CSC_ERRORCODE ret = CSC_ErrorNone;
1063
1064     if (handle == NULL)
1065         return CSC_Error;
1066
1067     csc_handle = (CSC_HANDLE *)handle;
1068     csc_handle->csc_mode = csc_mode;
1069     csc_handle->csc_range = csc_range;
1070     csc_handle->colorspace = colorspace;
1071
1072     return ret;
1073 }
1074
1075 CSC_ERRORCODE csc_set_filter_property(
1076     void              *handle,
1077     CSC_HW_FILTER    filter)
1078 {
1079     CSC_HANDLE *csc_handle;
1080
1081     if (handle == NULL)
1082         return CSC_Error;
1083
1084     csc_handle = (CSC_HANDLE *)handle;
1085     if (filter >= CSC_FT_MAX)
1086         return CSC_Error;
1087
1088     csc_handle->filter = filter;
1089     csc_handle->hw_property.fixed_node = CSC_HW_SC1;
1090
1091     return 0;
1092 }
1093
1094 CSC_ERRORCODE csc_get_src_format(
1095     void           *handle,
1096     unsigned int   *width,
1097     unsigned int   *height,
1098     unsigned int   *crop_left,
1099     unsigned int   *crop_top,
1100     unsigned int   *crop_width,
1101     unsigned int   *crop_height,
1102     unsigned int   *color_format,
1103     unsigned int   *cacheable)
1104 {
1105     CSC_HANDLE *csc_handle;
1106     CSC_ERRORCODE ret = CSC_ErrorNone;
1107
1108     if (handle == NULL)
1109         return CSC_ErrorNotInit;
1110
1111     csc_handle = (CSC_HANDLE *)handle;
1112     *width = csc_handle->src_format.width;
1113     *height = csc_handle->src_format.height;
1114     *crop_left = csc_handle->src_format.crop_left;
1115     *crop_top = csc_handle->src_format.crop_top;
1116     *crop_width = csc_handle->src_format.crop_width;
1117     *crop_height = csc_handle->src_format.crop_height;
1118     *color_format = csc_handle->src_format.color_format;
1119     *cacheable = csc_handle->src_format.cacheable;
1120
1121     return ret;
1122 }
1123
1124 CSC_ERRORCODE csc_set_src_format(
1125     void           *handle,
1126     unsigned int    width,
1127     unsigned int    height,
1128     unsigned int    crop_left,
1129     unsigned int    crop_top,
1130     unsigned int    crop_width,
1131     unsigned int    crop_height,
1132     unsigned int    color_format,
1133     unsigned int    cacheable)
1134 {
1135     CSC_HANDLE *csc_handle;
1136     CSC_ERRORCODE ret = CSC_ErrorNone;
1137
1138     if (handle == NULL)
1139         return CSC_ErrorNotInit;
1140
1141     csc_handle = (CSC_HANDLE *)handle;
1142     csc_handle->src_format.width = width;
1143     csc_handle->src_format.height = height;
1144     csc_handle->src_format.crop_left = crop_left;
1145     csc_handle->src_format.crop_top = crop_top;
1146     csc_handle->src_format.crop_width = crop_width;
1147     csc_handle->src_format.crop_height = crop_height;
1148     csc_handle->src_format.color_format = color_format;
1149     csc_handle->src_format.cacheable = cacheable;
1150
1151     return ret;
1152 }
1153
1154 CSC_ERRORCODE csc_get_dst_format(
1155     void           *handle,
1156     unsigned int   *width,
1157     unsigned int   *height,
1158     unsigned int   *crop_left,
1159     unsigned int   *crop_top,
1160     unsigned int   *crop_width,
1161     unsigned int   *crop_height,
1162     unsigned int   *color_format,
1163     unsigned int   *cacheable)
1164 {
1165     CSC_HANDLE *csc_handle;
1166     CSC_ERRORCODE ret = CSC_ErrorNone;
1167
1168     if (handle == NULL)
1169         return CSC_ErrorNotInit;
1170
1171     csc_handle = (CSC_HANDLE *)handle;
1172     *width = csc_handle->dst_format.width;
1173     *height = csc_handle->dst_format.height;
1174     *crop_left = csc_handle->dst_format.crop_left;
1175     *crop_top = csc_handle->dst_format.crop_top;
1176     *crop_width = csc_handle->dst_format.crop_width;
1177     *crop_height = csc_handle->dst_format.crop_height;
1178     *color_format = csc_handle->dst_format.color_format;
1179     *cacheable = csc_handle->dst_format.cacheable;
1180
1181     return ret;
1182 }
1183
1184 CSC_ERRORCODE csc_set_dst_format(
1185     void           *handle,
1186     unsigned int    width,
1187     unsigned int    height,
1188     unsigned int    crop_left,
1189     unsigned int    crop_top,
1190     unsigned int    crop_width,
1191     unsigned int    crop_height,
1192     unsigned int    color_format,
1193     unsigned int    cacheable)
1194 {
1195     CSC_HANDLE *csc_handle;
1196     CSC_ERRORCODE ret = CSC_ErrorNone;
1197
1198     if (handle == NULL)
1199         return CSC_ErrorNotInit;
1200
1201     csc_handle = (CSC_HANDLE *)handle;
1202     csc_handle->dst_format.width = width;
1203     csc_handle->dst_format.height = height;
1204     csc_handle->dst_format.crop_left = crop_left;
1205     csc_handle->dst_format.crop_top = crop_top;
1206     csc_handle->dst_format.crop_width = crop_width;
1207     csc_handle->dst_format.crop_height = crop_height;
1208     csc_handle->dst_format.color_format = color_format;
1209     csc_handle->dst_format.cacheable = cacheable;
1210
1211     return ret;
1212 }
1213
1214 CSC_ERRORCODE csc_set_src_buffer(
1215     void *handle,
1216     void *addr[3],
1217     int mem_type)
1218 {
1219     CSC_HANDLE *csc_handle;
1220     CSC_ERRORCODE ret = CSC_ErrorNone;
1221
1222     if (handle == NULL)
1223         return CSC_ErrorNotInit;
1224
1225     csc_handle = (CSC_HANDLE *)handle;
1226     csc_handle->src_buffer.planes[CSC_Y_PLANE] = addr[0];
1227     csc_handle->src_buffer.planes[CSC_U_PLANE] = addr[1];
1228     csc_handle->src_buffer.planes[CSC_V_PLANE] = addr[2];
1229     csc_handle->src_buffer.mem_type = mem_type;
1230
1231     return ret;
1232 }
1233
1234 CSC_ERRORCODE csc_set_dst_buffer(
1235     void *handle,
1236     void *addr[3],
1237     int mem_type)
1238 {
1239     CSC_HANDLE *csc_handle;
1240     CSC_ERRORCODE ret = CSC_ErrorNone;
1241
1242     if (handle == NULL)
1243         return CSC_ErrorNotInit;
1244
1245     csc_handle = (CSC_HANDLE *)handle;
1246     csc_handle->dst_buffer.planes[CSC_Y_PLANE] = addr[0];
1247     csc_handle->dst_buffer.planes[CSC_U_PLANE] = addr[1];
1248     csc_handle->dst_buffer.planes[CSC_V_PLANE] = addr[2];
1249     csc_handle->dst_buffer.mem_type = mem_type;
1250
1251     return ret;
1252 }
1253
1254 CSC_ERRORCODE csc_convert(
1255     void *handle)
1256 {
1257     CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle;
1258     CSC_ERRORCODE ret = CSC_ErrorNone;
1259
1260     if (csc_handle == NULL)
1261         return CSC_ErrorNotInit;
1262
1263     if ((csc_handle->csc_method == CSC_METHOD_HW) &&
1264         (csc_handle->csc_hw_handle == NULL)) {
1265         ret = csc_init_hw(handle);
1266
1267         if (ret != CSC_ErrorNone)
1268             return ret;
1269     }
1270
1271     csc_set_format(csc_handle);
1272     csc_set_buffer(csc_handle);
1273
1274     if (csc_handle->csc_method == CSC_METHOD_HW)
1275         ret = conv_hw(csc_handle);
1276     else
1277         ret = conv_sw(csc_handle);
1278
1279     return ret;
1280 }
1281
1282 CSC_ERRORCODE csc_convert_with_rotation(
1283     void *handle, int rotation, int flip_horizontal, int flip_vertical)
1284 {
1285     CSC_HANDLE *csc_handle = (CSC_HANDLE *)handle;
1286     CSC_ERRORCODE ret = CSC_ErrorNone;
1287
1288     if (csc_handle == NULL)
1289         return CSC_ErrorNotInit;
1290
1291     if ((csc_handle->csc_method == CSC_METHOD_HW) &&
1292         (csc_handle->csc_hw_handle == NULL)) {
1293         ret = csc_init_hw(handle);
1294
1295         if (ret != CSC_ErrorNone)
1296             return ret;
1297     }
1298
1299     csc_set_format(csc_handle);
1300     csc_set_buffer(csc_handle);
1301
1302 #ifdef USES_FIMC
1303     exynos_fimc_set_rotation(csc_handle->csc_hw_handle, rotation, flip_horizontal, flip_vertical);
1304 #endif
1305 #ifdef USES_GSCALER
1306     if (csc_handle->hw_property.fixed_node < CSC_HW_SC0)
1307         exynos_gsc_set_rotation(csc_handle->csc_hw_handle, rotation, flip_horizontal, flip_vertical);
1308     else
1309         exynos_sc_set_rotation(csc_handle->csc_hw_handle, rotation, flip_horizontal, flip_vertical);
1310 #endif
1311
1312     if (csc_handle->csc_method == CSC_METHOD_HW)
1313         ret = conv_hw(csc_handle);
1314     else
1315         ret = conv_sw(csc_handle);
1316
1317     return ret;
1318 }