Skip to content

Commit 70b4b93

Browse files
josuahkartben
authored andcommitted
drivers: video: sw_generator: modify video_sw_generator_fill_colorbar()
Add a check for the array size to avoid overwriting unrelated memory when the buffer is too small for the full format. It first check if there is enough buffer for one line, and fill it programmatically. Then, it will try to duplicate that line over the entire buffer, in the limit of the room available. Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent 82d2f94 commit 70b4b93

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

drivers/video/video_sw_generator.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <zephyr/drivers/video-controls.h>
1212
#include <zephyr/logging/log.h>
1313
#include <zephyr/sys/util.h>
14+
#include <zephyr/sys/byteorder.h>
1415

1516
#include "video_ctrls.h"
1617
#include "video_device.h"
@@ -118,29 +119,50 @@ uint32_t xrgb32_colorbar_value[] = {
118119
0xFF00FF00, 0xFF00FFFF, 0xFFFFFF00, 0xFFFFFFFF,
119120
};
120121

122+
static inline int video_sw_generator_get_color_idx(uint16_t w, uint16_t width, bool hflip)
123+
{
124+
/* If hflip is on, start from the right instead */
125+
w = (hflip) ? (width - w - 1) : (w);
126+
127+
/* Downscale from w/width to #/8 */
128+
return 8 * w / width;
129+
}
130+
121131
static void video_sw_generator_fill_colorbar(struct video_sw_generator_data *data,
122132
struct video_buffer *vbuf)
123133
{
124134
int bw = data->fmt.width / 8;
125-
int h, w, i = 0;
126-
127-
for (h = 0; h < data->fmt.height; h++) {
128-
for (w = 0; w < data->fmt.width; w++) {
129-
int color_idx = data->ctrls.hflip.val ? 7 - w / bw : w / bw;
130-
if (data->fmt.pixelformat == VIDEO_PIX_FMT_RGB565) {
131-
uint16_t *pixel = (uint16_t *)&vbuf->buffer[i];
132-
*pixel = rgb565_colorbar_value[color_idx];
133-
i += 2;
134-
} else if (data->fmt.pixelformat == VIDEO_PIX_FMT_XRGB32) {
135-
uint32_t *pixel = (uint32_t *)&vbuf->buffer[i];
136-
*pixel = xrgb32_colorbar_value[color_idx];
137-
i += 4;
138-
}
135+
struct video_format *fmt = &data->fmt;
136+
size_t pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
137+
bool hflip = data->ctrls.hflip.val;
138+
139+
vbuf->bytesused = 0;
140+
141+
/* Generate the first line of data */
142+
for (int w = 0, i = 0; w < data->fmt.width; w++) {
143+
int color_idx = video_sw_generator_get_color_idx(w, width, hflip);
144+
145+
if (data->fmt.pixelformat == VIDEO_PIX_FMT_RGB565) {
146+
uint16_t *pixel = (uint16_t *)&vbuf->buffer[i];
147+
*pixel = sys_cpu_to_le16(rgb565_colorbar_value[color_idx]);
148+
} else if (data->fmt.pixelformat == VIDEO_PIX_FMT_XRGB32) {
149+
uint32_t *pixel = (uint32_t *)&vbuf->buffer[i];
150+
*pixel = sys_cpu_to_le32(xrgb32_colorbar_value[color_idx]);
139151
}
152+
i += video_bits_per_pixel(data->fmt.pixelformat) / BITS_PER_BYTE;
153+
}
154+
155+
/* Duplicate the first line all over the buffer */
156+
for (int h = 1; h < data->fmt.height; h++) {
157+
if (vbuf->size < vbuf->bytesused + pitch) {
158+
break;
159+
}
160+
161+
memcpy(vbuf->buffer + h * pitch, vbuf->buffer, pitch);
162+
vbuf->bytesused += pitch;
140163
}
141164

142165
vbuf->timestamp = k_uptime_get_32();
143-
vbuf->bytesused = i;
144166
vbuf->line_offset = 0;
145167
}
146168

0 commit comments

Comments
 (0)