mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
jpegdec: Adds 8bit grayscale support
Adds decoding support for jpeg images in 8 bit grayscale format.
This commit is contained in:
parent
d7a25fd109
commit
bca4ca631f
1 changed files with 58 additions and 5 deletions
|
@ -67,7 +67,8 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") "; "
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420") "; "
|
||||||
GST_VIDEO_CAPS_RGB "; " GST_VIDEO_CAPS_BGR "; "
|
GST_VIDEO_CAPS_RGB "; " GST_VIDEO_CAPS_BGR "; "
|
||||||
GST_VIDEO_CAPS_RGBx "; " GST_VIDEO_CAPS_xRGB "; "
|
GST_VIDEO_CAPS_RGBx "; " GST_VIDEO_CAPS_xRGB "; "
|
||||||
GST_VIDEO_CAPS_BGRx "; " GST_VIDEO_CAPS_xBGR)
|
GST_VIDEO_CAPS_BGRx "; " GST_VIDEO_CAPS_xBGR "; "
|
||||||
|
GST_VIDEO_CAPS_GRAY8)
|
||||||
);
|
);
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
@ -746,6 +747,42 @@ gst_jpeg_dec_ensure_buffers (GstJpegDec * dec, guint maxrowbytes)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_jpeg_dec_decode_grayscale (GstJpegDec * dec, guchar * base[1],
|
||||||
|
guint width, guint height, guint pstride, guint rstride)
|
||||||
|
{
|
||||||
|
guchar *rows[16];
|
||||||
|
guchar **scanarray[1] = { rows };
|
||||||
|
gint i, j, k;
|
||||||
|
gint lines;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (dec, "indirect decoding of grayscale");
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!gst_jpeg_dec_ensure_buffers (dec, GST_ROUND_UP_32 (width))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy (rows, dec->idr_y, 16 * sizeof (gpointer));
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < height) {
|
||||||
|
lines = jpeg_read_raw_data (&dec->cinfo, scanarray, DCTSIZE);
|
||||||
|
if (G_LIKELY (lines > 0)) {
|
||||||
|
for (j = 0; (j < DCTSIZE) && (i < height); j++, i++) {
|
||||||
|
gint p;
|
||||||
|
|
||||||
|
p = 0;
|
||||||
|
for (k = 0; k < width; k++) {
|
||||||
|
base[0][p] = rows[j][k];
|
||||||
|
p += pstride;
|
||||||
|
}
|
||||||
|
base[0] += rstride;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_jpeg_dec_decode_rgb (GstJpegDec * dec, guchar * base[3],
|
gst_jpeg_dec_decode_rgb (GstJpegDec * dec, guchar * base[3],
|
||||||
guint width, guint height, guint pstride, guint rstride)
|
guint width, guint height, guint pstride, guint rstride)
|
||||||
|
@ -1092,6 +1129,16 @@ gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc)
|
||||||
/* equal for all components */
|
/* equal for all components */
|
||||||
dec->stride = gst_video_format_get_row_stride (format, 0, width);
|
dec->stride = gst_video_format_get_row_stride (format, 0, width);
|
||||||
dec->inc = gst_video_format_get_pixel_stride (format, 0);
|
dec->inc = gst_video_format_get_pixel_stride (format, 0);
|
||||||
|
} else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
|
||||||
|
/* TODO is anything else then 8bit supported in jpeg? */
|
||||||
|
format = GST_VIDEO_FORMAT_GRAY8;
|
||||||
|
caps = gst_video_format_new_caps (format, width, height,
|
||||||
|
dec->framerate_numerator, dec->framerate_denominator, 1, 1);
|
||||||
|
dec->outsize = gst_video_format_get_size (format, width, height);
|
||||||
|
dec->offset[0] =
|
||||||
|
gst_video_format_get_component_offset (format, 0, width, height);
|
||||||
|
dec->stride = gst_video_format_get_row_stride (format, 0, width);
|
||||||
|
dec->inc = gst_video_format_get_pixel_stride (format, 0);
|
||||||
} else {
|
} else {
|
||||||
/* go for plain and simple I420 */
|
/* go for plain and simple I420 */
|
||||||
/* TODO other YUV cases ? */
|
/* TODO other YUV cases ? */
|
||||||
|
@ -1258,11 +1305,13 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
/* sanity checks to get safe and reasonable output */
|
/* sanity checks to get safe and reasonable output */
|
||||||
switch (dec->cinfo.jpeg_color_space) {
|
switch (dec->cinfo.jpeg_color_space) {
|
||||||
case JCS_GRAYSCALE:
|
case JCS_GRAYSCALE:
|
||||||
|
if (dec->cinfo.num_components != 1)
|
||||||
|
goto invalid_yuvrgbgrayscale;
|
||||||
break;
|
break;
|
||||||
case JCS_RGB:
|
case JCS_RGB:
|
||||||
if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
|
if (dec->cinfo.num_components != 3 || dec->cinfo.max_v_samp_factor > 1 ||
|
||||||
dec->cinfo.max_h_samp_factor > 1)
|
dec->cinfo.max_h_samp_factor > 1)
|
||||||
goto invalid_yuvrgb;
|
goto invalid_yuvrgbgrayscale;
|
||||||
break;
|
break;
|
||||||
case JCS_YCbCr:
|
case JCS_YCbCr:
|
||||||
if (dec->cinfo.num_components != 3 ||
|
if (dec->cinfo.num_components != 3 ||
|
||||||
|
@ -1270,7 +1319,7 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
r_v < dec->cinfo.comp_info[1].v_samp_factor ||
|
r_v < dec->cinfo.comp_info[1].v_samp_factor ||
|
||||||
r_h < dec->cinfo.comp_info[0].h_samp_factor ||
|
r_h < dec->cinfo.comp_info[0].h_samp_factor ||
|
||||||
r_h < dec->cinfo.comp_info[1].h_samp_factor)
|
r_h < dec->cinfo.comp_info[1].h_samp_factor)
|
||||||
goto invalid_yuvrgb;
|
goto invalid_yuvrgbgrayscale;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
@ -1322,6 +1371,10 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
base[1] = outdata + dec->offset[1];
|
base[1] = outdata + dec->offset[1];
|
||||||
base[2] = outdata + dec->offset[2];
|
base[2] = outdata + dec->offset[2];
|
||||||
gst_jpeg_dec_decode_rgb (dec, base, width, height, dec->inc, dec->stride);
|
gst_jpeg_dec_decode_rgb (dec, base, width, height, dec->inc, dec->stride);
|
||||||
|
} else if (dec->cinfo.jpeg_color_space == JCS_GRAYSCALE) {
|
||||||
|
base[0] = outdata + dec->offset[0];
|
||||||
|
gst_jpeg_dec_decode_grayscale (dec, base, width, height, dec->inc,
|
||||||
|
dec->stride);
|
||||||
} else {
|
} else {
|
||||||
/* mind the swap, jpeglib outputs blue chroma first
|
/* mind the swap, jpeglib outputs blue chroma first
|
||||||
* ensonic: I see no swap?
|
* ensonic: I see no swap?
|
||||||
|
@ -1495,10 +1548,10 @@ unsupported_colorspace:
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
invalid_yuvrgb:
|
invalid_yuvrgbgrayscale:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
|
GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
|
||||||
("Picture is corrupt or unhandled YUV/RGB layout"));
|
("Picture is corrupt or unhandled YUV/RGB/grayscale layout"));
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue