summaryrefslogtreecommitdiff
path: root/src/ipa/vimc
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ragnatech.se>2020-09-24 23:16:25 +0200
committerNiklas Söderlund <niklas.soderlund@ragnatech.se>2020-09-30 14:24:42 +0200
commitdf64542035f7aab6f6d8eec801a9fcb9f19bed60 (patch)
treeea06addf17afe1cd6d8ad0bf040b65f8ddf4a599 /src/ipa/vimc
parentdf2af09050514c64c4af8cef0581423a705490af (diff)
libcamera: pipeline: rkisp1: Move path configuration generation and validation to RkISP1Path
Move the path configuration generation and validation to RkISP1Path. This is done to increase code reuse and to encapsulate the main and self path differences inside the RkISP1Path class. There is no functional change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/ipa/vimc')
0 files changed, 0 insertions, 0 deletions
a id='n109' href='#n109'>109 110 111 112 113 114 115 116 117 118
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * format_convert.cpp - qcam - Convert buffer to RGB
 */

#include <errno.h>

#include <linux/videodev2.h>

#include <QImage>

#include "format_converter.h"

#define RGBSHIFT		8
#ifndef MAX
#define MAX(a,b)		((a)>(b)?(a):(b))
#endif
#ifndef MIN
#define MIN(a,b)		((a)<(b)?(a):(b))
#endif
#ifndef CLAMP
#define CLAMP(a,low,high)	MAX((low),MIN((high),(a)))
#endif
#ifndef CLIP
#define CLIP(x)			CLAMP(x,0,255)
#endif

int FormatConverter::configure(unsigned int format, unsigned int width,
			       unsigned int height)
{
	switch (format) {
	case V4L2_PIX_FMT_VYUY:
		y_pos_ = 1;
		cb_pos_ = 2;
		break;
	case V4L2_PIX_FMT_YVYU:
		y_pos_ = 0;
		cb_pos_ = 3;
		break;
	case V4L2_PIX_FMT_UYVY:
		y_pos_ = 1;
		cb_pos_ = 0;
		break;
	case V4L2_PIX_FMT_YUYV:
		y_pos_ = 0;
		cb_pos_ = 1;
		break;
	case V4L2_PIX_FMT_MJPEG:
		break;
	default:
		return -EINVAL;
	};

	format_ = format;
	width_ = width;
	height_ = height;

	return 0;
}

void FormatConverter::convert(const unsigned char *src, size_t size,
			      QImage *dst)
{
	if (format_ == V4L2_PIX_FMT_MJPEG)
		dst->loadFromData(src, size, "JPEG");
	else
		convertYUV(src, dst->bits());
}

static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
{
	int c = y - 16;
	int d = u - 128;
	int e = v - 128;
	*r = CLIP(( 298 * c           + 409 * e + 128) >> RGBSHIFT);
	*g = CLIP(( 298 * c - 100 * d - 208 * e + 128) >> RGBSHIFT);
	*b = CLIP(( 298 * c + 516 * d           + 128) >> RGBSHIFT);
}

void FormatConverter::convertYUV(const unsigned char *src, unsigned char *dst)
{
	unsigned int src_x, src_y, dst_x, dst_y;
	unsigned int src_stride;
	unsigned int dst_stride;
	unsigned int cr_pos;
	int r, g, b, y, cr, cb;

	cr_pos = (cb_pos_ + 2) % 4;
	src_stride = width_ * 2;
	dst_stride = width_ * 4;

	for (src_y = 0, dst_y = 0; dst_y < height_; src_y++, dst_y++) {
		for (src_x = 0, dst_x = 0; dst_x < width_; ) {
			cb = src[src_y * src_stride + src_x * 4 + cb_pos_];
			cr = src[src_y * src_stride + src_x * 4 + cr_pos];

			y = src[src_y * src_stride + src_x * 4 + y_pos_];
			yuv_to_rgb(y, cb, cr, &r, &g, &b);
			dst[dst_y * dst_stride + 4 * dst_x + 0] = b;
			dst[dst_y * dst_stride + 4 * dst_x + 1] = g;
			dst[dst_y * dst_stride + 4 * dst_x + 2] = r;
			dst[dst_y * dst_stride + 4 * dst_x + 3] = 0xff;
			dst_x++;

			y = src[src_y * src_stride + src_x * 4 + y_pos_ + 2];
			yuv_to_rgb(y, cb, cr, &r, &g, &b);
			dst[dst_y * dst_stride + 4 * dst_x + 0] = b;
			dst[dst_y * dst_stride + 4 * dst_x + 1] = g;
			dst[dst_y * dst_stride + 4 * dst_x + 2] = r;
			dst[dst_y * dst_stride + 4 * dst_x + 3] = 0xff;
			dst_x++;

			src_x++;
		}
	}
}