Skip to content

Commit 93c94ed

Browse files
committed
fix: improve YUV420 to RGB conversion by adjusting stride calculations and clamping
1 parent af998a8 commit 93c94ed

1 file changed

Lines changed: 25 additions & 17 deletions

File tree

src/libcameracamera.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -543,37 +543,45 @@ QImage LibCameraWorker::convertBufferToImage(
543543
// YUV420 planar format (I420)
544544
unsigned int width = cfg.size.width;
545545
unsigned int height = cfg.size.height;
546-
unsigned int stride = cfg.stride;
547-
unsigned int uvStride = stride / 2;
546+
547+
// Use width as stride for packed YUV420 (not cfg.stride which may have padding)
548+
unsigned int yStride = width;
549+
unsigned int uvStride = width / 2;
548550

549551
image = QImage(width, height, QImage::Format_RGB888);
550552

551553
const uint8_t *yPlane = static_cast<const uint8_t *>(memory);
552-
const uint8_t *uPlane = yPlane + stride * height;
553-
const uint8_t *vPlane = uPlane + uvStride * (height / 2);
554+
const uint8_t *uPlane = yPlane + width * height;
555+
const uint8_t *vPlane = uPlane + (width / 2) * (height / 2);
554556

555557
qDebug() << "[DEBUG] YUV420: width=" << width << "height=" << height
556-
<< "stride=" << stride << "uvStride=" << uvStride;
558+
<< "yStride=" << yStride << "uvStride=" << uvStride
559+
<< "cfg.stride=" << cfg.stride;
557560

558-
for (unsigned int j = 0; j < height; ++j) {
559-
uint8_t *rgbRow = image.scanLine(j);
560-
for (unsigned int i = 0; i < width; ++i) {
561-
int Y = yPlane[j * stride + i];
562-
int U = uPlane[(j / 2) * uvStride + (i / 2)] - 128;
563-
int V = vPlane[(j / 2) * uvStride + (i / 2)] - 128;
561+
for (unsigned int y = 0; y < height; ++y) {
562+
uint8_t *rgbRow = image.scanLine(y);
563+
for (unsigned int x = 0; x < width; ++x) {
564+
int Y = yPlane[y * yStride + x];
565+
566+
unsigned int uvX = x / 2;
567+
unsigned int uvY = y / 2;
568+
569+
int U = uPlane[uvY * uvStride + uvX] - 128;
570+
int V = vPlane[uvY * uvStride + uvX] - 128;
564571

565572
// BT.601 / sYCC conversion (full range)
566573
int R = Y + static_cast<int>(1.402 * V);
567574
int G = Y - static_cast<int>(0.344136 * U) - static_cast<int>(0.714136 * V);
568575
int B = Y + static_cast<int>(1.772 * U);
569576

570-
R = std::clamp(R, 0, 255);
571-
G = std::clamp(G, 0, 255);
572-
B = std::clamp(B, 0, 255);
577+
// Clamp
578+
R = R < 0 ? 0 : (R > 255 ? 255 : R);
579+
G = G < 0 ? 0 : (G > 255 ? 255 : G);
580+
B = B < 0 ? 0 : (B > 255 ? 255 : B);
573581

574-
rgbRow[i * 3 + 0] = static_cast<uint8_t>(R);
575-
rgbRow[i * 3 + 1] = static_cast<uint8_t>(G);
576-
rgbRow[i * 3 + 2] = static_cast<uint8_t>(B);
582+
rgbRow[x * 3 + 0] = static_cast<uint8_t>(R);
583+
rgbRow[x * 3 + 1] = static_cast<uint8_t>(G);
584+
rgbRow[x * 3 + 2] = static_cast<uint8_t>(B);
577585
}
578586
}
579587

0 commit comments

Comments
 (0)