diff options
Diffstat (limited to 'v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c')
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c | 93 |
1 files changed, 76 insertions, 17 deletions
diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c index 3d61225b9..4c9e67d52 100644 --- a/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c +++ b/v4l2-apps/lib/libv4l/libv4lconvert/libv4lconvert.c @@ -9,7 +9,7 @@ # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software @@ -30,6 +30,7 @@ /* Note for proper functioning of v4lconvert_enum_fmt the first entries in supported_src_pixfmts must match with the entries in supported_dst_pixfmts */ #define SUPPORTED_DST_PIXFMTS \ + V4L2_PIX_FMT_RGB24, \ V4L2_PIX_FMT_BGR24, \ V4L2_PIX_FMT_YUV420 @@ -170,7 +171,9 @@ int v4lconvert_try_format(struct v4lconvert_data *data, (int)dest_fmt->fmt.pix.height); unsigned int size_diff = size_x_diff * size_x_diff + size_y_diff * size_y_diff; - if (size_diff < closest_fmt_size_diff) { + if (size_diff < closest_fmt_size_diff || + (size_diff == closest_fmt_size_diff && + try_fmt.fmt.pix.pixelformat == desired_pixfmt)) { closest_fmt_size_diff = size_diff; closest_fmt = try_fmt; } @@ -191,6 +194,7 @@ int v4lconvert_try_format(struct v4lconvert_data *data, if (closest_fmt.fmt.pix.pixelformat != desired_pixfmt) { dest_fmt->fmt.pix.pixelformat = desired_pixfmt; switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: dest_fmt->fmt.pix.bytesperline = dest_fmt->fmt.pix.width * 3; dest_fmt->fmt.pix.sizeimage = dest_fmt->fmt.pix.width * @@ -228,6 +232,7 @@ int v4lconvert_convert(struct v4lconvert_data *data, /* sanity check, is the dest buffer large enough? */ switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: needed = dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height * 3; break; @@ -283,12 +288,19 @@ int v4lconvert_convert(struct v4lconvert_data *data, components[2] = components[1] + (dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height) / 4; - if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) { + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + tinyjpeg_set_components(data->jdec, components, 1); + result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_RGB24); + break; + case V4L2_PIX_FMT_BGR24: tinyjpeg_set_components(data->jdec, components, 1); result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_BGR24); - } else { + break; + default: tinyjpeg_set_components(data->jdec, components, 3); result = tinyjpeg_decode(data->jdec, TINYJPEG_FMT_YUV420P); + break; } /* If the JPEG header checked out ok and we get an error during actual @@ -304,12 +316,20 @@ int v4lconvert_convert(struct v4lconvert_data *data, case V4L2_PIX_FMT_SGBRG8: case V4L2_PIX_FMT_SGRBG8: case V4L2_PIX_FMT_SRGGB8: - if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_bayer_to_rgb24(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat); + break; + case V4L2_PIX_FMT_BGR24: v4lconvert_bayer_to_bgr24(src, dest, dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat); - else + break; + default: v4lconvert_bayer_to_yuv420(src, dest, dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat); + break; + } break; /* YUYV line by line formats */ @@ -319,8 +339,8 @@ int v4lconvert_convert(struct v4lconvert_data *data, { unsigned char tmpbuf[dest_fmt->fmt.pix.width * dest_fmt->fmt.pix.height * 3 / 2]; - unsigned char *my_dst = (dest_fmt->fmt.pix.pixelformat == - V4L2_PIX_FMT_BGR24) ? tmpbuf : dest; + unsigned char *my_dst = (dest_fmt->fmt.pix.pixelformat != + V4L2_PIX_FMT_YUV420) ? tmpbuf : dest; switch (src_fmt->fmt.pix.pixelformat) { case V4L2_PIX_FMT_SPCA501: @@ -337,10 +357,16 @@ int v4lconvert_convert(struct v4lconvert_data *data, break; } - if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_yuv420_to_rgb24(tmpbuf, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + case V4L2_PIX_FMT_BGR24: v4lconvert_yuv420_to_bgr24(tmpbuf, dest, dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height); - + break; + } break; } @@ -370,24 +396,57 @@ int v4lconvert_convert(struct v4lconvert_data *data, break; } - if (dest_fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_bayer_to_rgb24(tmpbuf, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height, bayer_fmt); + break; + case V4L2_PIX_FMT_BGR24: v4lconvert_bayer_to_bgr24(tmpbuf, dest, dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, bayer_fmt); - else + break; + default: v4lconvert_bayer_to_yuv420(tmpbuf, dest, dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, bayer_fmt); + break; + } break; } + case V4L2_PIX_FMT_RGB24: + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_BGR24: + v4lconvert_swap_rgb(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + case V4L2_PIX_FMT_YUV420: + printf("FIXME add rgb24 -> yuv420 conversion\n"); + break; + } + break; case V4L2_PIX_FMT_BGR24: - /* dest must be V4L2_PIX_FMT_YUV420 then */ - printf("FIXME add bgr24 -> yuv420 conversion\n"); + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_swap_rgb(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + case V4L2_PIX_FMT_YUV420: + printf("FIXME add bgr24 -> yuv420 conversion\n"); + break; + } break; case V4L2_PIX_FMT_YUV420: - /* dest must be V4L2_PIX_FMT_BGR24 then */ - v4lconvert_yuv420_to_bgr24(src, dest, dest_fmt->fmt.pix.width, - dest_fmt->fmt.pix.height); + switch (dest_fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_yuv420_to_rgb24(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + case V4L2_PIX_FMT_BGR24: + v4lconvert_yuv420_to_bgr24(src, dest, dest_fmt->fmt.pix.width, + dest_fmt->fmt.pix.height); + break; + } break; default: |