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