[raw2rgbpnm 3/3] Add support for multi plane formats with stride

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Parsing NV16 that have a stride that is larger then the image width
results in incorrect frames, and no warning message being printed.

Fix this by extending the format information structure with how many
(concatenated) planes an image is constructed of. And by extending the
raw reader to take this information into account.

With this change it is possible to parse NV12, NV21, NV16, and NV61
frames from disk with a stride larger then the image width and have
correct frames produced.

Signed-off-by: Niklas Söderlund <niklas.soderlund@xxxxxxxxxxxx>
---
 raw2rgbpnm.c | 121 +++++++++++++++++++++++++++------------------------
 1 file changed, 65 insertions(+), 56 deletions(-)

diff --git a/raw2rgbpnm.c b/raw2rgbpnm.c
index d8d4bb198498..5838bc7347e9 100644
--- a/raw2rgbpnm.c
+++ b/raw2rgbpnm.c
@@ -55,60 +55,61 @@ static const struct format_info {
 	unsigned int y_pos;
 	unsigned int cb_pos;
 	unsigned int cr_pos;
+	unsigned int planes;
 } v4l2_pix_fmt_str[] = {
-	{ V4L2_PIX_FMT_RGB332,	8,  0,  "RGB332 (8 RGB-3-3-2)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_RGB555,	16, 5,  "RGB555 (16 RGB-5-5-5)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_RGB565,	16, 0,  "RGB565 (16 RGB-5-6-5)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_BGR24,	24, 8,  "BGR24 (24 BGR-8-8-8)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_RGB24,	24, 8,  "RGB24 (24 RGB-8-8-8)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_BGR32,	32, 8,  "BGR32 (32 BGR-8-8-8-8)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_RGB32,	32, 8,  "RGB32 (32 RGB-8-8-8-8)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_GREY,	8,  8,  "GREY (8 Greyscale)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_Y10,	16, 10, "Y10 (10 Greyscale)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_Y12,	16, 12, "Y12 (12 Greyscale)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_Y16,	16, 16, "Y16 (16 Greyscale)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_UYVY,	16, 8,  "UYVY (16 YUV 4:2:2)", 1, 0, 2 },
-	{ V4L2_PIX_FMT_VYUY,	16, 8,  "VYUY (16 YUV 4:2:2)", 1, 2, 0 },
-	{ V4L2_PIX_FMT_YUYV,	16, 8,  "YUYV (16 YUV 4:2:2)", 0, 1, 3 },
-	{ V4L2_PIX_FMT_YVYU,	16, 8,  "YVYU (16 YUV 4:2:2)", 0, 3, 1 },
-	{ V4L2_PIX_FMT_YUV32,	32, 8,  "YUV32 (32-bit A/XYUV 8-8-8-8)", 1, 2, 3 },
-	{ V4L2_PIX_FMT_AYUV32,	32, 8,  "AYUV32 (32-bit AYUV 8-8-8-8)", 1, 2, 3 },
-	{ V4L2_PIX_FMT_XYUV32,	32, 8,  "XYUV32 (32-bit XYUV 8-8-8-8)", 1, 2, 3 },
-	{ V4L2_PIX_FMT_VUYA32,	32, 8,  "VUYA32 (32-bit VUYA 8-8-8-8)", 2, 1, 0 },
-	{ V4L2_PIX_FMT_VUYX32,	32, 8,  "VUYX32 (32-bit VUYX 8-8-8-8)", 2, 1, 0 },
-	{ V4L2_PIX_FMT_YUVA32,	32, 8,  "YUVA32 (32-bit YUVA 8-8-8-8)", 0, 1, 2 },
-	{ V4L2_PIX_FMT_YUVX32,	32, 8,  "YUVX32 (32-bit YUVX 8-8-8-8)", 0, 1, 2 },
-	{ V4L2_PIX_FMT_YUV411P,	12, 8,  "YUV411P (12 YUV 4:1:1 planar)", 0, 0, 1 },
-	{ V4L2_PIX_FMT_YUV420,	12, 8,  "YUV420P (12 YUV 4:2:0 planar)", 0, 0, 1 },
-	{ V4L2_PIX_FMT_YVU420,	12, 8,  "YVU420P (12 YVU 4:2:2 planar)", 0, 1, 0 },
-	{ V4L2_PIX_FMT_YUV422P,	16, 8,  "YUV422P (16 YUV 4:2:2 planar)", 0, 0, 1 },
-	{ V4L2_PIX_FMT_YVU422M,	16, 8,  "YVU422P (16 YVU 4:2:2 planar)", 0, 1, 0 },
-	{ V4L2_PIX_FMT_YUV444M,	24, 8,  "YUV444P (24 YUV 4:4:4 planar)", 0, 0, 1 },
-	{ V4L2_PIX_FMT_YVU444M,	24, 8,  "YVU444P (24 YVU 4:4:4 planar)", 0, 1, 0 },
-	{ V4L2_PIX_FMT_NV12,	12, 8,  "NV12 (12 Y/CbCr 4:2:0)", 0, 0, 1 },
-	{ V4L2_PIX_FMT_NV21,	12, 8,  "NV21 (12 Y/CrCb 4:2:0)", 0, 1, 0 },
-	{ V4L2_PIX_FMT_NV16,	16, 8,  "NV16 (16 Y/CbCr 4:2:2)", 0, 0, 1 },
-	{ V4L2_PIX_FMT_NV61,	16, 8,  "NV61 (16 Y/CrCb 4:2:2)", 0, 1, 0 },
-	{ V4L2_PIX_FMT_SBGGR8,	8,  8,  "SBGGR8 (8 BGBG.. GRGR..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGBRG8,	8,  8,  "SGBRG8 (8 GBGB.. RGRG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGRBG8,	8,  8,  "SGRBG8 (8 GRGR.. BGBG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SRGGB8,	8,  8,  "SRGGB8 (8 RGRG.. GBGB..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SBGGR10,	16, 10, "SBGGR10 (10 BGBG.. GRGR..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGBRG10,	16, 10, "SGBRG10 (10 GBGB.. RGRG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGRBG10,	16, 10, "SGRBG10 (10 GRGR.. BGBG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SRGGB10,	16, 10, "SRGGB10 (10 RGRG.. GBGB..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SBGGR12,	16, 12, "SBGGR12 (12 BGBG.. GRGR..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGBRG12,	16, 12, "SGBRG12 (12 GBGB.. RGRG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGRBG12,	16, 12, "SGRBG12 (12 GRGR.. BGBG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SRGGB12,	16, 12, "SRGGB12 (12 RGRG.. GBGB..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SBGGR14,	16, 14, "SBGGR14 (14 BGBG.. GRGR..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGBRG14,	16, 14, "SGBRG14 (14 GBGB.. RGRG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGRBG14,	16, 14, "SGRBG14 (14 GRGR.. BGBG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SRGGB14,	16, 14, "SRGGB14 (14 RGRG.. GBGB..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SBGGR16,	16, 16, "SBGGR16 (16 BGBG.. GRGR..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGBRG16,	16, 16, "SGBRG16 (16 GBGB.. RGRG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SGRBG16,	16, 16, "SGRBG16 (16 GRGR.. BGBG..)", 0, 0, 0 },
-	{ V4L2_PIX_FMT_SRGGB16,	16, 16, "SRGGB16 (16 RGRG.. GBGB..)", 0, 0, 0 },
+	{ V4L2_PIX_FMT_RGB332,	8,  0,  "RGB332 (8 RGB-3-3-2)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_RGB555,	16, 5,  "RGB555 (16 RGB-5-5-5)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_RGB565,	16, 0,  "RGB565 (16 RGB-5-6-5)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_BGR24,	24, 8,  "BGR24 (24 BGR-8-8-8)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_RGB24,	24, 8,  "RGB24 (24 RGB-8-8-8)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_BGR32,	32, 8,  "BGR32 (32 BGR-8-8-8-8)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_RGB32,	32, 8,  "RGB32 (32 RGB-8-8-8-8)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_GREY,	8,  8,  "GREY (8 Greyscale)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_Y10,	16, 10, "Y10 (10 Greyscale)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_Y12,	16, 12, "Y12 (12 Greyscale)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_Y16,	16, 16, "Y16 (16 Greyscale)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_UYVY,	16, 8,  "UYVY (16 YUV 4:2:2)", 1, 0, 2, 1 },
+	{ V4L2_PIX_FMT_VYUY,	16, 8,  "VYUY (16 YUV 4:2:2)", 1, 2, 0, 1 },
+	{ V4L2_PIX_FMT_YUYV,	16, 8,  "YUYV (16 YUV 4:2:2)", 0, 1, 3, 1 },
+	{ V4L2_PIX_FMT_YVYU,	16, 8,  "YVYU (16 YUV 4:2:2)", 0, 3, 1, 1 },
+	{ V4L2_PIX_FMT_YUV32,	32, 8,  "YUV32 (32-bit A/XYUV 8-8-8-8)", 1, 2, 3, 1 },
+	{ V4L2_PIX_FMT_AYUV32,	32, 8,  "AYUV32 (32-bit AYUV 8-8-8-8)", 1, 2, 3, 1 },
+	{ V4L2_PIX_FMT_XYUV32,	32, 8,  "XYUV32 (32-bit XYUV 8-8-8-8)", 1, 2, 3, 1 },
+	{ V4L2_PIX_FMT_VUYA32,	32, 8,  "VUYA32 (32-bit VUYA 8-8-8-8)", 2, 1, 0, 1 },
+	{ V4L2_PIX_FMT_VUYX32,	32, 8,  "VUYX32 (32-bit VUYX 8-8-8-8)", 2, 1, 0, 1 },
+	{ V4L2_PIX_FMT_YUVA32,	32, 8,  "YUVA32 (32-bit YUVA 8-8-8-8)", 0, 1, 2, 1 },
+	{ V4L2_PIX_FMT_YUVX32,	32, 8,  "YUVX32 (32-bit YUVX 8-8-8-8)", 0, 1, 2, 1 },
+	{ V4L2_PIX_FMT_YUV411P,	12, 8,  "YUV411P (12 YUV 4:1:1 planar)", 0, 0, 1, 1 },
+	{ V4L2_PIX_FMT_YUV420,	12, 8,  "YUV420P (12 YUV 4:2:0 planar)", 0, 0, 1, 1 },
+	{ V4L2_PIX_FMT_YVU420,	12, 8,  "YVU420P (12 YVU 4:2:2 planar)", 0, 1, 0, 1 },
+	{ V4L2_PIX_FMT_YUV422P,	16, 8,  "YUV422P (16 YUV 4:2:2 planar)", 0, 0, 1, 1 },
+	{ V4L2_PIX_FMT_YVU422M,	16, 8,  "YVU422P (16 YVU 4:2:2 planar)", 0, 1, 0, 1 },
+	{ V4L2_PIX_FMT_YUV444M,	24, 8,  "YUV444P (24 YUV 4:4:4 planar)", 0, 0, 1, 1 },
+	{ V4L2_PIX_FMT_YVU444M,	24, 8,  "YVU444P (24 YVU 4:4:4 planar)", 0, 1, 0, 1 },
+	{ V4L2_PIX_FMT_NV12,	12, 8,  "NV12 (12 Y/CbCr 4:2:0)", 0, 0, 1, 2 },
+	{ V4L2_PIX_FMT_NV21,	12, 8,  "NV21 (12 Y/CrCb 4:2:0)", 0, 1, 0, 2 },
+	{ V4L2_PIX_FMT_NV16,	16, 8,  "NV16 (16 Y/CbCr 4:2:2)", 0, 0, 1, 2 },
+	{ V4L2_PIX_FMT_NV61,	16, 8,  "NV61 (16 Y/CrCb 4:2:2)", 0, 1, 0, 2 },
+	{ V4L2_PIX_FMT_SBGGR8,	8,  8,  "SBGGR8 (8 BGBG.. GRGR..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGBRG8,	8,  8,  "SGBRG8 (8 GBGB.. RGRG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGRBG8,	8,  8,  "SGRBG8 (8 GRGR.. BGBG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SRGGB8,	8,  8,  "SRGGB8 (8 RGRG.. GBGB..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SBGGR10,	16, 10, "SBGGR10 (10 BGBG.. GRGR..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGBRG10,	16, 10, "SGBRG10 (10 GBGB.. RGRG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGRBG10,	16, 10, "SGRBG10 (10 GRGR.. BGBG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SRGGB10,	16, 10, "SRGGB10 (10 RGRG.. GBGB..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SBGGR12,	16, 12, "SBGGR12 (12 BGBG.. GRGR..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGBRG12,	16, 12, "SGBRG12 (12 GBGB.. RGRG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGRBG12,	16, 12, "SGRBG12 (12 GRGR.. BGBG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SRGGB12,	16, 12, "SRGGB12 (12 RGRG.. GBGB..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SBGGR14,	16, 14, "SBGGR14 (14 BGBG.. GRGR..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGBRG14,	16, 14, "SGBRG14 (14 GBGB.. RGRG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGRBG14,	16, 14, "SGRBG14 (14 GRGR.. BGBG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SRGGB14,	16, 14, "SRGGB14 (14 RGRG.. GBGB..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SBGGR16,	16, 16, "SBGGR16 (16 BGBG.. GRGR..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGBRG16,	16, 16, "SGBRG16 (16 GBGB.. RGRG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SGRBG16,	16, 16, "SGRBG16 (16 GRGR.. BGBG..)", 0, 0, 0, 1 },
+	{ V4L2_PIX_FMT_SRGGB16,	16, 16, "SRGGB16 (16 RGRG.. GBGB..)", 0, 0, 0, 1 },
 };
 
 static void *xalloc(int size)
@@ -130,14 +131,17 @@ static const struct format_info *get_format_info(__u32 f)
 	return NULL;
 }
 
-/* Read and return raw image data at given bits per pixel (bpp) depth. */
-static unsigned char *read_raw_data(char *filename, int width, int height, int bpp)
+/* Read and return image data at given width, height and format information. */
+static unsigned char *read_raw_data(char *filename, int width, int height,
+				    const struct format_info *info)
 {
 	/* Get file size */
 	unsigned int line_length;
 	unsigned int padding = 0;
 	unsigned char *b = NULL;
 	unsigned int i;
+	int bpp = info->bpp;
+
 	FILE *f = fopen(filename, "rb");
 	if (!f) error("fopen failed");
 	int r = fseek(f, 0, SEEK_END);
@@ -147,6 +151,11 @@ static unsigned char *read_raw_data(char *filename, int width, int height, int b
 	r = fseek(f, 0, SEEK_SET);
 	if (r!=0) error("fseek");
 
+	if (info->planes > 1) {
+		bpp = info->bpc;
+		height *= info->planes;
+	}
+
 	if (file_size*8 < width*height*bpp) error("out of input data");
 	if (file_size*8 > width*height*bpp) printf("warning: too large image file\n");
 	if (file_size % height == 0) {
@@ -741,7 +750,7 @@ int main(int argc, char *argv[])
 	}
 
 	/* Read, convert, and save image */
-	src = read_raw_data(file_in, width, height, info->bpp);
+	src = read_raw_data(file_in, width, height, info);
 	printf("Image size: %ix%i, bytes per pixel: %i, format: %s\n",
 	       width, height, info->bpp, info->name);
 	dst = xalloc(width*height*3);
-- 
2.48.1





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux