diff --git a/src/libcamera/software_isp/swstats_linaro.cpp b/src/libcamera/software_isp/swstats_linaro.cpp
index 0323f45f..2f203b17 100644
--- a/src/libcamera/software_isp/swstats_linaro.cpp
+++ b/src/libcamera/software_isp/swstats_linaro.cpp
@@ -38,80 +38,55 @@ static const unsigned int RED_Y_MUL = 77;		/* 0.30 * 256 */
 static const unsigned int GREEN_Y_MUL = 150;		/* 0.59 * 256 */
 static const unsigned int BLUE_Y_MUL = 29;		/* 0.11 * 256 */
 
-/*
- * These need to be macros because it accesses a whole bunch of local
- * variables (and copy and pasting this x times is undesirable)
- */
-#define SWISP_LINARO_START_LINE_STATS()			\
-	uint8_t r, g, b;				\
-	unsigned int y_val;				\
-							\
-	unsigned int sumR = 0;				\
-	unsigned int sumG = 0;				\
-	unsigned int sumB = 0;				\
-							\
-	unsigned int bright_sum = 0;			\
-	unsigned int too_bright_sum = 0;
-
-#define SWISP_LINARO_ACCUMULATE_LINE_STATS()		\
-	sumR += r;					\
-	sumG += g;					\
-	sumB += b;					\
-							\
-	y_val = r * RED_Y_MUL;				\
-	y_val += g * GREEN_Y_MUL;			\
-	y_val += b * BLUE_Y_MUL;			\
-	if (y_val > BRIGHT_LVL) ++bright_sum;		\
-	if (y_val > TOO_BRIGHT_LVL) ++too_bright_sum;
-
-#define SWISP_LINARO_FINISH_LINE_STATS()		\
-	stats_.sumR_ += sumR;				\
-	stats_.sumG_ += sumG;				\
-	stats_.sumB_ += sumB;				\
-							\
-	bright_sum_ += bright_sum;			\
-	too_bright_sum_ += too_bright_sum;
-
-void SwStatsLinaro::statsBGGR10PLine(const uint8_t *src0, const uint8_t *src1)
+static void inline statsBayer(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, unsigned int &bright_sum, unsigned int &too_bright_sum, StatsLinaro &stats)
 {
-	const int width_in_bytes = width_ * 5 / 4;
-	uint8_t g2;
+	const int width_in_bytes = width * 5 / 4;
+	uint8_t r, g, b, g2;
+	unsigned int y_val;
 
-	SWISP_LINARO_START_LINE_STATS()
+	stats.sumR_ = 0;
+	stats.sumG_ = 0;
+	stats.sumB_ = 0;
 
-	for (int x = 0; x < width_in_bytes; x += 5) {
-		/* BGGR */
-		b  = src0[x];
-		g  = src0[x + 1];
-		g2 = src1[x];
-		r  = src1[x + 1];
+	bright_sum = 0;
+	too_bright_sum = 0;
 
+	for (int x = 0; x < width_in_bytes; x += 5) {
+		if (bggr) {
+			/* BGGR */
+			b  = src0[x];
+			g  = src0[x + 1];
+			g2 = src1[x];
+			r  = src1[x + 1];
+		} else {
+			/* GBRG */
+			g  = src0[x];
+			b  = src0[x + 1];
+			r  = src1[x];
+			g2 = src1[x + 1];
+		}
 		g = g + g2 / 2;
 
-		SWISP_LINARO_ACCUMULATE_LINE_STATS()
+		stats.sumR_ += r;
+		stats.sumG_ += g;
+		stats.sumB_ += b;
+
+		y_val = r * RED_Y_MUL;
+		y_val += g * GREEN_Y_MUL;
+		y_val += b * BLUE_Y_MUL;
+		if (y_val > BRIGHT_LVL) ++bright_sum;
+		if (y_val > TOO_BRIGHT_LVL) ++too_bright_sum;
 	}
-	SWISP_LINARO_FINISH_LINE_STATS()
 }
 
-void SwStatsLinaro::statsGBRG10PLine(const uint8_t *src0, const uint8_t *src1)
+void SwStatsLinaro::statsBGGR10PLine(const uint8_t *src0, const uint8_t *src1)
 {
-	const int width_in_bytes = width_ * 5 / 4;
-	uint8_t g2;
-
-	SWISP_LINARO_START_LINE_STATS()
-
-	for (int x = 0; x < width_in_bytes; x += 5) {
-		/* GBRG */
-		g  = src0[x];
-		b  = src0[x + 1];
-		r  = src1[x];
-		g2 = src1[x + 1];
-
-		g = g + g2 / 2;
+	statsBayer(width_, src0, src1, true, bright_sum_, too_bright_sum_, stats_);
+}
 
-		SWISP_LINARO_ACCUMULATE_LINE_STATS()
-	}
-	SWISP_LINARO_FINISH_LINE_STATS()
+void SwStatsLinaro::statsGBRG10PLine(const uint8_t *src0, const uint8_t *src1)
+{
+	statsBayer(width_, src0, src1, false, bright_sum_, too_bright_sum_, stats_);
 }
 
 void SwStatsLinaro::statsBGGR10PLine0(const uint8_t *src, unsigned int stride)
