blob: 5b92bece9544a29a10649bade76ca1b1d9ef1ae2 [file] [log] [blame]
/*
*
* Copyright (C) 2022 ASR Micro Ltd.
* All rights reserved.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include "asrfb.h"
#include "pix_fmt.h"
int var_to_pixfmt(struct fb_var_screeninfo *var)
{
/*
* Check for YUV422PLANAR.
*/
if (var->bits_per_pixel == 16 && var->red.length == 8 &&
var->green.length == 4 && var->blue.length == 4) {
if (var->green.offset >= var->blue.offset)
return PIXFMT_YUV422P;
else
return PIXFMT_YVU422P;
}
/*
* Check for YUV420PLANAR.
*/
if (var->bits_per_pixel == 12 && var->red.length == 8 &&
var->green.length == 2 && var->blue.length == 2) {
if (var->green.offset >= var->blue.offset)
return PIXFMT_YUV420P;
else
return PIXFMT_YVU420P;
}
/*
* Check for YUV420SEMIPLANAR.
*/
if (var->bits_per_pixel == 12 && var->red.length == 8 &&
(var->green.length == 0 || var->blue.length == 0)) {
if (var->green.length)
return PIXFMT_YUV420SP;
else
return PIXFMT_YVU420SP;
}
/*
* Check for YUV422PACK.
*/
if (var->bits_per_pixel == 16 && var->red.length == 16 &&
var->green.length == 16 && var->blue.length == 16) {
if (var->red.offset == 0) {
if (var->green.offset < var->blue.offset)
return PIXFMT_YUYV;
else
return PIXFMT_YVYU;
} else if (var->green.offset >= var->blue.offset)
return PIXFMT_UYVY;
else
return PIXFMT_VYUY;
}
/*
* Check for 565/1555.
*/
if (var->bits_per_pixel == 16 && var->red.length <= 5 &&
var->green.length <= 6 && var->blue.length <= 5) {
if (var->transp.length == 0) {
if (var->red.offset >= var->blue.offset)
return PIXFMT_BGR565;
else
return PIXFMT_RGB565;
}
}
/*
* Check for 888/A888.
*/
if (var->bits_per_pixel <= 32 && var->red.length <= 8 &&
var->green.length <= 8 && var->blue.length <= 8) {
if (var->bits_per_pixel == 24 && var->transp.length == 0) {
if (var->red.offset >= var->blue.offset)
return PIXFMT_BGR888PACK;
else
return PIXFMT_RGB888PACK;
}
if (var->bits_per_pixel == 32 && var->transp.offset == 24) {
if (var->red.offset >= var->blue.offset)
return PIXFMT_BGRA888;
else
return PIXFMT_RGBA888;
} else {
if (var->red.offset >= var->blue.offset)
return PIXFMT_BGR888UNPACK;
else
return PIXFMT_RGB888UNPACK;
}
/* fall through */
}
return -EINVAL;
}
void pixfmt_to_var(struct fb_var_screeninfo *var, int pix_fmt)
{
switch (pix_fmt) {
case PIXFMT_BGR565:
var->bits_per_pixel = 16;
var->red.offset = 11; var->red.length = 5;
var->green.offset = 5; var->green.length = 6;
var->blue.offset = 0; var->blue.length = 5;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_RGB565:
var->bits_per_pixel = 16;
var->red.offset = 0; var->red.length = 5;
var->green.offset = 5; var->green.length = 6;
var->blue.offset = 11; var->blue.length = 5;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_BGR888UNPACK:
var->bits_per_pixel = 32;
var->red.offset = 16; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 0; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_RGB888UNPACK:
var->bits_per_pixel = 32;
var->red.offset = 0; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 16; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_BGRA888:
var->bits_per_pixel = 32;
var->red.offset = 16; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 0; var->blue.length = 8;
var->transp.offset = 24; var->transp.length = 8;
break;
case PIXFMT_RGBA888:
var->bits_per_pixel = 32;
var->red.offset = 0; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 16; var->blue.length = 8;
var->transp.offset = 24; var->transp.length = 8;
break;
case PIXFMT_BGR888PACK:
var->bits_per_pixel = 24;
var->red.offset = 16; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 0; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_RGB888PACK:
var->bits_per_pixel = 24;
var->red.offset = 0; var->red.length = 8;
var->green.offset = 8; var->green.length = 8;
var->blue.offset = 16; var->blue.length = 8;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YUV420P:
var->bits_per_pixel = 12;
var->red.offset = 4; var->red.length = 8;
var->green.offset = 2; var->green.length = 2;
var->blue.offset = 0; var->blue.length = 2;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YVU420P:
var->bits_per_pixel = 12;
var->red.offset = 4; var->red.length = 8;
var->green.offset = 0; var->green.length = 2;
var->blue.offset = 2; var->blue.length = 2;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YUV420SP:
var->bits_per_pixel = 12;
var->red.offset = 4; var->red.length = 8;
var->green.offset = 2; var->green.length = 4;
var->blue.offset = 0; var->blue.length = 0;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YVU420SP:
var->bits_per_pixel = 12;
var->red.offset = 4; var->red.length = 8;
var->green.offset = 0; var->green.length = 0;
var->blue.offset = 2; var->blue.length = 4;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YUV422P:
var->bits_per_pixel = 16;
var->red.offset = 8; var->red.length = 8;
var->green.offset = 4; var->green.length = 4;
var->blue.offset = 0; var->blue.length = 4;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YVU422P:
var->bits_per_pixel = 16;
var->red.offset = 8; var->red.length = 8;
var->green.offset = 0; var->green.length = 4;
var->blue.offset = 4; var->blue.length = 4;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_UYVY:
var->bits_per_pixel = 16;
var->red.offset = 8; var->red.length = 16;
var->green.offset = 4; var->green.length = 16;
var->blue.offset = 0; var->blue.length = 16;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_VYUY:
var->bits_per_pixel = 16;
var->red.offset = 8; var->red.length = 16;
var->green.offset = 0; var->green.length = 16;
var->blue.offset = 4; var->blue.length = 16;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YUYV:
var->bits_per_pixel = 16;
var->red.offset = 0; var->red.length = 16;
var->green.offset = 4; var->green.length = 16;
var->blue.offset = 8; var->blue.length = 16;
var->transp.offset = 0; var->transp.length = 0;
break;
case PIXFMT_YVYU:
var->bits_per_pixel = 16;
var->red.offset = 0; var->red.length = 16;
var->green.offset = 8; var->green.length = 16;
var->blue.offset = 4; var->blue.length = 16;
var->transp.offset = 0; var->transp.length = 0;
break;
}
}
int pixfmt_to_stride(int pix_fmt)
{
switch (pix_fmt) {
case PIXFMT_RGB565:
case PIXFMT_BGR565:
case PIXFMT_RGB1555:
case PIXFMT_BGR1555:
case PIXFMT_UYVY:
case PIXFMT_VYUY:
case PIXFMT_YUYV:
case PIXFMT_YVYU:
return 2;
case PIXFMT_RGB888UNPACK:
case PIXFMT_BGR888UNPACK:
case PIXFMT_RGBA888:
case PIXFMT_BGRA888:
return 4;
case PIXFMT_RGB888PACK:
case PIXFMT_BGR888PACK:
return 3;
case PIXFMT_YUV422P:
case PIXFMT_YVU422P:
case PIXFMT_YUV420P:
case PIXFMT_YVU420P:
case PIXFMT_YUV420SP:
case PIXFMT_YVU420SP:
return 1;
default:
return 0;
}
}
int pixfmt_yuv(int pix_fmt)
{
switch(pix_fmt){
case PIXFMT_YUYV:
case PIXFMT_YVYU:
case PIXFMT_UYVY:
case PIXFMT_VYUY:
case PIXFMT_YUV422P:
case PIXFMT_YUV420P:
case PIXFMT_YUV420SP:
case PIXFMT_YVU422P:
case PIXFMT_YVU420P:
case PIXFMT_YVU420SP:
return 1;
}
return 0;
}