summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2025-04-04 04:51:46 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2025-04-05 03:02:33 +0300
commit14ed7467627ed3ad80030f8d97601bbcf78a6907 (patch)
tree94f94b35a1b523f506749770218ced5837f3e07e
parent6df1ad61158e9c2744786193619b873b3dedcd6b (diff)
gen-image: Round sub-sampled chroma towards zero
Based on tests, the VSP1 hardware seems to round averaged chroma values towards 0 when subsampling YUV formats. Replicate the same calculation in gen-image. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/gen-image.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/gen-image.c b/src/gen-image.c
index 170d694..d053d79 100644
--- a/src/gen-image.c
+++ b/src/gen-image.c
@@ -618,8 +618,15 @@ static void image_format_yuv_packed(const struct image *input, struct image *out
o_c[2*x + u_offset] = idata[3*x + 1];
o_c[2*x + v_offset] = idata[3*x + 2];
} else {
- o_c[2*x + u_offset] = (idata[3*x + 1] + idata[3*x + 4]) / 2;
- o_c[2*x + v_offset] = (idata[3*x + 2] + idata[3*x + 5]) / 2;
+ unsigned int u = idata[3*x + 1] + idata[3*x + 4];
+ unsigned int v = idata[3*x + 2] + idata[3*x + 5];
+
+ /* Round towards the middle value. */
+ u += u < 0x100 ? 1 : 0;
+ v += v < 0x100 ? 1 : 0;
+
+ o_c[2*x + u_offset] = u / 2;
+ o_c[2*x + v_offset] = v / 2;
}
}
@@ -674,8 +681,15 @@ static void image_format_yuv_planar(const struct image *input, struct image *out
}
} else {
for (x = 0; x < output->width; x += xsub) {
- o_u[x*c_stride/xsub] = (idata[3*x + 1] + idata[3*x + 4]) / 2;
- o_v[x*c_stride/xsub] = (idata[3*x + 2] + idata[3*x + 5]) / 2;
+ unsigned int u = idata[3*x + 1] + idata[3*x + 4];
+ unsigned int v = idata[3*x + 2] + idata[3*x + 5];
+
+ /* Round towards the middle value. */
+ u += u < 0x100 ? 1 : 0;
+ v += v < 0x100 ? 1 : 0;
+
+ o_u[x*c_stride/xsub] = u / 2;
+ o_v[x*c_stride/xsub] = v / 2;
}
}