| /* |
| * |
| * 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; |
| } |
| |