freeimagedec: Move utility functions to gstfreeimageutils.c/.h and other minor cleanup
Also removed static pad templates, changed elements to have underscore rather than hyphen in their name, and fix caps handling (BGR/RGB)
This commit is contained in:
parent
4fc7cd5ec8
commit
992d159add
@ -27,11 +27,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstfreeimagedec.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include "gstfreeimagedec.h"
|
||||
#include "gstfreeimageutils.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (freeimagedec_debug);
|
||||
#define GST_CAT_DEFAULT freeimagedec_debug
|
||||
@ -41,21 +41,6 @@ typedef struct
|
||||
FREE_IMAGE_FORMAT fif;
|
||||
} GstFreeImageDecClassData;
|
||||
|
||||
|
||||
static GstStaticPadTemplate gst_freeimagedec_src_pad_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("ANY")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_freeimagedec_sink_pad_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("ANY")
|
||||
);
|
||||
|
||||
static void gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
||||
GstFreeImageDecClassData * class_data);
|
||||
static void gst_freeimagedec_init (GstFreeImageDec * freeimagedec);
|
||||
@ -78,18 +63,17 @@ static gboolean gst_freeimagedec_freeimage_init (GstFreeImageDec * freeimagedec)
|
||||
static gboolean gst_freeimagedec_freeimage_clear (GstFreeImageDec * freeimagedec);
|
||||
static GstFlowReturn gst_freeimagedec_caps_create_and_set (GstFreeImageDec * freeimagedec);
|
||||
static GstFlowReturn gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec);
|
||||
static GstCaps * gst_freeimagedec_caps_from_freeimage_format (FREE_IMAGE_FORMAT fif);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
void DLL_CALLCONV
|
||||
user_error (FREE_IMAGE_FORMAT fif, const char *message)
|
||||
gst_freeimagedec_user_error (FREE_IMAGE_FORMAT fif, const char *message)
|
||||
{
|
||||
GST_ERROR ("%s", message);
|
||||
}
|
||||
|
||||
static int DLL_CALLCONV
|
||||
user_seek (fi_handle handle, long offset, int origin)
|
||||
gst_freeimagedec_user_seek (fi_handle handle, long offset, int origin)
|
||||
{
|
||||
GstFreeImageDec *freeimagedec = GST_FREEIMAGEDEC (handle);
|
||||
|
||||
@ -108,7 +92,7 @@ user_seek (fi_handle handle, long offset, int origin)
|
||||
}
|
||||
|
||||
static long DLL_CALLCONV
|
||||
user_tell (fi_handle handle)
|
||||
gst_freeimagedec_user_tell (fi_handle handle)
|
||||
{
|
||||
GstFreeImageDec *freeimagedec = GST_FREEIMAGEDEC (handle);
|
||||
|
||||
@ -205,7 +189,7 @@ gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
||||
gst_element_class_add_pad_template (gstelement_class, templ);
|
||||
|
||||
/* add src pad template */
|
||||
caps = gst_freeimagedec_caps_from_freeimage_format (klass->fif);
|
||||
caps = gst_freeimageutils_caps_from_freeimage_format (klass->fif);
|
||||
templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
|
||||
gst_element_class_add_pad_template (gstelement_class, templ);
|
||||
|
||||
@ -226,8 +210,11 @@ gst_freeimagedec_class_init (GstFreeImageDecClass * klass,
|
||||
static void
|
||||
gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
||||
{
|
||||
freeimagedec->sinkpad =
|
||||
gst_pad_new_from_static_template (&gst_freeimagedec_sink_pad_template, "sink");
|
||||
GstElementClass * klass = GST_ELEMENT_GET_CLASS (freeimagedec);
|
||||
|
||||
freeimagedec->sinkpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (klass, "sink"), "sink");
|
||||
|
||||
gst_pad_set_activate_function (freeimagedec->sinkpad, gst_freeimagedec_sink_activate);
|
||||
gst_pad_set_activatepull_function (freeimagedec->sinkpad,
|
||||
gst_freeimagedec_sink_activate_pull);
|
||||
@ -238,8 +225,8 @@ gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
||||
gst_pad_set_setcaps_function (freeimagedec->sinkpad, gst_freeimagedec_sink_setcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (freeimagedec), freeimagedec->sinkpad);
|
||||
|
||||
freeimagedec->srcpad =
|
||||
gst_pad_new_from_static_template (&gst_freeimagedec_src_pad_template, "src");
|
||||
freeimagedec->srcpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (klass, "src"), "src");
|
||||
gst_pad_use_fixed_caps (freeimagedec->srcpad);
|
||||
gst_element_add_pad (GST_ELEMENT (freeimagedec), freeimagedec->srcpad);
|
||||
|
||||
@ -249,9 +236,6 @@ gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
||||
freeimagedec->in_timestamp = GST_CLOCK_TIME_NONE;
|
||||
freeimagedec->in_duration = GST_CLOCK_TIME_NONE;
|
||||
|
||||
freeimagedec->width = -1;
|
||||
freeimagedec->height = -1;
|
||||
freeimagedec->bpp = -1;
|
||||
freeimagedec->fps_n = 0;
|
||||
freeimagedec->fps_d = 1;
|
||||
|
||||
@ -260,8 +244,8 @@ gst_freeimagedec_init (GstFreeImageDec * freeimagedec)
|
||||
/* Set user IO functions to FreeImageIO struct */
|
||||
freeimagedec->fiio.read_proc = user_read;
|
||||
freeimagedec->fiio.write_proc = NULL;
|
||||
freeimagedec->fiio.seek_proc = user_seek;
|
||||
freeimagedec->fiio.tell_proc = user_tell;
|
||||
freeimagedec->fiio.seek_proc = gst_freeimagedec_user_seek;
|
||||
freeimagedec->fiio.tell_proc = gst_freeimagedec_user_tell;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
@ -270,114 +254,48 @@ gst_freeimagedec_caps_create_and_set (GstFreeImageDec * freeimagedec)
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstCaps *caps = NULL, *res = NULL;
|
||||
GstPadTemplate *templ = NULL;
|
||||
gint image_type, video_format = -1, endianness;
|
||||
|
||||
/* Get bits per channel */
|
||||
freeimagedec->bpp = FreeImage_GetBPP (freeimagedec->dib);
|
||||
caps = gst_freeimageutils_caps_from_dib (freeimagedec->dib,
|
||||
freeimagedec->fps_n, freeimagedec->fps_d);
|
||||
|
||||
/* Get image type */
|
||||
image_type = FreeImage_GetImageType (freeimagedec->dib);
|
||||
|
||||
/* Get width and height */
|
||||
freeimagedec->width = FreeImage_GetWidth (freeimagedec->dib);
|
||||
freeimagedec->height = FreeImage_GetHeight (freeimagedec->dib);
|
||||
|
||||
GST_LOG ("Image_type=%d, %dx%dx%d", image_type, freeimagedec->width, freeimagedec->height, freeimagedec->bpp);
|
||||
|
||||
switch (image_type) {
|
||||
case FIT_BITMAP:
|
||||
if (freeimagedec->bpp < 16) {
|
||||
if (caps == NULL) {
|
||||
/* we have an unsupported type, we'll try converting to RGB/RGBA */
|
||||
FIBITMAP * dib;
|
||||
if (FreeImage_IsTransparent (freeimagedec->dib)) {
|
||||
GST_DEBUG ("Image is palletised with transparency, convert to 32-bit RGB");
|
||||
GST_DEBUG ("Image is non-standard format with transparency, convert to 32-bit RGB");
|
||||
dib = FreeImage_ConvertTo32Bits (freeimagedec->dib);
|
||||
video_format = GST_VIDEO_FORMAT_RGBA;
|
||||
}
|
||||
else {
|
||||
GST_DEBUG ("Image is palletised, convert to 24-bit RGB");
|
||||
GST_DEBUG ("Image is non-standard format, convert to 24-bit RGB");
|
||||
dib = FreeImage_ConvertTo24Bits (freeimagedec->dib);
|
||||
video_format = GST_VIDEO_FORMAT_RGB;
|
||||
}
|
||||
|
||||
caps = gst_freeimageutils_caps_from_dib (freeimagedec->dib,
|
||||
freeimagedec->fps_n, freeimagedec->fps_d);
|
||||
if (caps == NULL) {
|
||||
GST_DEBUG ("Image could not be converted to RGB/RGBA, try grayscale");
|
||||
if (dib)
|
||||
FreeImage_Unload (dib);
|
||||
dib = FreeImage_ConvertToStandardType (freeimagedec->dib, TRUE);
|
||||
|
||||
caps = gst_freeimageutils_caps_from_dib (freeimagedec->dib,
|
||||
freeimagedec->fps_n, freeimagedec->fps_d);
|
||||
|
||||
if (caps == NULL) {
|
||||
GST_WARNING ("Failed to convert image");
|
||||
if (dib)
|
||||
FreeImage_Unload (dib);
|
||||
ret = GST_FLOW_NOT_SUPPORTED;
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the converted dib as our new dib */
|
||||
FreeImage_Unload (freeimagedec->dib);
|
||||
freeimagedec->dib = dib;
|
||||
}
|
||||
else if (freeimagedec->bpp == 24) {
|
||||
if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_24_INT &&
|
||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_24_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_RGB;
|
||||
}
|
||||
else if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_24_INT &&
|
||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_24_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_BGR;
|
||||
}
|
||||
else {
|
||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||
("freeimagedec only supports RGB or BGR 24-bit bitmaps"));
|
||||
}
|
||||
}
|
||||
else if (freeimagedec->bpp == 32) {
|
||||
if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_32_INT &&
|
||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_32_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_RGBA;
|
||||
}
|
||||
else if (FreeImage_GetRedMask (freeimagedec->dib) == GST_VIDEO_BYTE3_MASK_32_INT &&
|
||||
FreeImage_GetGreenMask (freeimagedec->dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
||||
FreeImage_GetBlueMask (freeimagedec->dib) == GST_VIDEO_BYTE1_MASK_32_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_BGRA;
|
||||
}
|
||||
else {
|
||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||
("freeimagedec only supports RGBA or BGRA 32-bit bitmaps"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||
("freeimagedec does not support this image type"));
|
||||
}
|
||||
|
||||
/* We could not find a supported format */
|
||||
if (video_format == -1) {
|
||||
ret = GST_FLOW_NOT_SUPPORTED;
|
||||
goto beach;
|
||||
}
|
||||
|
||||
caps = gst_video_format_new_caps (video_format, freeimagedec->width,
|
||||
freeimagedec->height, freeimagedec->fps_n, freeimagedec->fps_d, 1, 1);
|
||||
break;
|
||||
case FIT_UINT16:
|
||||
endianness = G_BYTE_ORDER;
|
||||
|
||||
caps = gst_caps_new_simple ("video/x-raw-gray",
|
||||
"width", G_TYPE_INT, freeimagedec->width,
|
||||
"height", G_TYPE_INT, freeimagedec->height,
|
||||
"bpp", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, endianness,
|
||||
"framerate", GST_TYPE_FRACTION, freeimagedec->fps_n, freeimagedec->fps_d,
|
||||
NULL);
|
||||
break;
|
||||
case FIT_INT16:
|
||||
endianness = G_BYTE_ORDER;
|
||||
|
||||
caps = gst_caps_new_simple ("video/x-raw-gray",
|
||||
"width", G_TYPE_INT, freeimagedec->width,
|
||||
"height", G_TYPE_INT, freeimagedec->height,
|
||||
"bpp", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, endianness,
|
||||
"framerate", GST_TYPE_FRACTION, freeimagedec->fps_n, freeimagedec->fps_d,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
GST_ELEMENT_ERROR (freeimagedec, STREAM, NOT_IMPLEMENTED, (NULL),
|
||||
("freeimagedec does not support this image type"));
|
||||
ret = GST_FLOW_NOT_SUPPORTED;
|
||||
goto beach;
|
||||
}
|
||||
GST_DEBUG_OBJECT (caps, "are the caps");
|
||||
|
||||
if (!gst_pad_set_caps (freeimagedec->srcpad, caps))
|
||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||
@ -407,7 +325,7 @@ gst_freeimagedec_task (GstPad * pad)
|
||||
|
||||
GST_LOG_OBJECT (freeimagedec, "read frame");
|
||||
|
||||
/* Query length of file for use by user_seek (SEEK_END) */
|
||||
/* Query length of file for use by gst_freeimagedec_user_seek (SEEK_END) */
|
||||
format = GST_FORMAT_BYTES;
|
||||
gst_pad_query_peer_duration (pad, &format, &freeimagedec->length);
|
||||
|
||||
@ -611,8 +529,6 @@ gst_freeimagedec_freeimage_clear (GstFreeImageDec * freeimagedec)
|
||||
freeimagedec->in_timestamp = GST_CLOCK_TIME_NONE;
|
||||
freeimagedec->in_duration = GST_CLOCK_TIME_NONE;
|
||||
|
||||
freeimagedec->bpp = freeimagedec->height = freeimagedec->width = -1;
|
||||
|
||||
freeimagedec->setup = FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -714,7 +630,7 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
||||
GstFlowReturn ret;
|
||||
GstBuffer *buffer = NULL;
|
||||
size_t buffer_size = 0;
|
||||
guint pitch;
|
||||
guint pitch, height;
|
||||
gint i;
|
||||
|
||||
if (freeimagedec->dib == NULL)
|
||||
@ -727,8 +643,9 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
||||
}
|
||||
|
||||
/* Allocate output buffer */
|
||||
height = FreeImage_GetHeight (freeimagedec->dib);
|
||||
pitch = FreeImage_GetPitch (freeimagedec->dib);
|
||||
buffer_size = pitch * freeimagedec->height;
|
||||
buffer_size = pitch * height;
|
||||
|
||||
GST_LOG ("Buffer size must be %d", buffer_size);
|
||||
|
||||
@ -739,9 +656,9 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
||||
return ret;
|
||||
|
||||
/* flip image and copy to buffer */
|
||||
for (i = 0; i < freeimagedec->height; i++) {
|
||||
for (i = 0; i < height; i++) {
|
||||
memcpy (GST_BUFFER_DATA (buffer) + i * pitch,
|
||||
FreeImage_GetBits (freeimagedec->dib) + (freeimagedec->height - i - 1) * pitch, pitch);
|
||||
FreeImage_GetBits (freeimagedec->dib) + (height - i - 1) * pitch, pitch);
|
||||
}
|
||||
|
||||
|
||||
@ -756,111 +673,6 @@ gst_freeimagedec_push_dib (GstFreeImageDec * freeimagedec)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef GST_VIDEO_CAPS_FLOAT
|
||||
#define GST_VIDEO_CAPS_FLOAT \
|
||||
"video/x-raw-gray-float, " \
|
||||
"bpp = (int) 32, " \
|
||||
"depth = (int) 32, " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"framerate = " GST_VIDEO_FPS_RANGE
|
||||
#endif
|
||||
|
||||
#ifndef GST_VIDEO_CAPS_RGBF
|
||||
#define GST_VIDEO_CAPS_RGBF \
|
||||
"video/x-raw-rgb-float, " \
|
||||
"bpp = (int) 96, " \
|
||||
"depth = (int) 96, " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"framerate = " GST_VIDEO_FPS_RANGE
|
||||
#endif
|
||||
|
||||
#ifndef GST_VIDEO_CAPS_RGBAF
|
||||
#define GST_VIDEO_CAPS_RGBAF \
|
||||
"video/x-raw-rgba-float, " \
|
||||
"bpp = (int) 96, " \
|
||||
"depth = (int) 96, " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"framerate = " GST_VIDEO_FPS_RANGE
|
||||
#endif
|
||||
|
||||
#ifndef GST_VIDEO_CAPS_GRAY8
|
||||
#define GST_VIDEO_CAPS_GRAY8 \
|
||||
"video/x-raw-gray, " \
|
||||
"bpp = (int) 8, " \
|
||||
"depth = (int) 8, " \
|
||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||
"framerate = " GST_VIDEO_FPS_RANGE
|
||||
#endif
|
||||
|
||||
static GstCaps *
|
||||
gst_freeimagedec_caps_from_freeimage_format (FREE_IMAGE_FORMAT fif)
|
||||
{
|
||||
GstCaps * caps = gst_caps_new_empty ();
|
||||
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_BITMAP)) {
|
||||
if (FreeImage_FIFSupportsExportBPP (fif, 1) ||
|
||||
FreeImage_FIFSupportsExportBPP (fif, 4) ||
|
||||
FreeImage_FIFSupportsExportBPP (fif, 8) ||
|
||||
FreeImage_FIFSupportsExportBPP (fif, 24)) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGR));
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportBPP (fif, 16)) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_15));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_16));
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportBPP (fif, 32)) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGRA));
|
||||
}
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT16)) {
|
||||
if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||
gst_caps_append (caps, gst_caps_from_string (
|
||||
GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN")));
|
||||
else
|
||||
gst_caps_append (caps, gst_caps_from_string (
|
||||
GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN")));
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_INT16)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT32)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_INT32)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_FLOAT)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_DOUBLE)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_COMPLEX)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGB16)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBA16)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBF)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBAF)) {
|
||||
}
|
||||
|
||||
/* non-standard format, we'll convert to RGB */
|
||||
if (gst_caps_get_size (caps) == 0) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gboolean
|
||||
gst_freeimagedec_register_plugin (GstPlugin * plugin, FREE_IMAGE_FORMAT fif)
|
||||
{
|
||||
@ -889,7 +701,7 @@ gst_freeimagedec_register_plugin (GstPlugin * plugin, FREE_IMAGE_FORMAT fif)
|
||||
tmp = g_strdup_printf ("fidec_%s", format);
|
||||
type_name = g_ascii_strdown (tmp, -1);
|
||||
g_free (tmp);
|
||||
g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+", '-');
|
||||
g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+_", '-');
|
||||
|
||||
GST_LOG ("Trying to use name %s", type_name);
|
||||
|
||||
|
||||
@ -60,9 +60,6 @@ struct _GstFreeImageDec
|
||||
|
||||
gboolean setup;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
gint bpp;
|
||||
gint fps_n;
|
||||
gint fps_d;
|
||||
|
||||
|
||||
216
ext/freeimage/gstfreeimageutils.c
Normal file
216
ext/freeimage/gstfreeimageutils.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include "gstfreeimageutils.h"
|
||||
|
||||
GstCaps *
|
||||
gst_freeimageutils_caps_from_dib (FIBITMAP * dib, gint fps_n, gint fps_d)
|
||||
{
|
||||
FREE_IMAGE_TYPE image_type;
|
||||
guint width, height, bpp;
|
||||
gint video_format = -1;
|
||||
GstCaps * caps = NULL;
|
||||
gint endianness;
|
||||
|
||||
if (dib == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Get bits per channel */
|
||||
bpp = FreeImage_GetBPP (dib);
|
||||
|
||||
/* Get image type */
|
||||
image_type = FreeImage_GetImageType (dib);
|
||||
|
||||
/* Get width and height */
|
||||
width = FreeImage_GetWidth (dib);
|
||||
height = FreeImage_GetHeight (dib);
|
||||
|
||||
GST_LOG ("Image_type=%d, %dx%dx%d", image_type, width, height, bpp);
|
||||
|
||||
switch (image_type) {
|
||||
case FIT_BITMAP:
|
||||
if (bpp == 24) {
|
||||
if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE1_MASK_24_INT &&
|
||||
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
||||
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE3_MASK_24_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_RGB;
|
||||
}
|
||||
else if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE3_MASK_24_INT &&
|
||||
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_24_INT &&
|
||||
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE1_MASK_24_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_BGR;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (bpp == 32) {
|
||||
if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE1_MASK_32_INT &&
|
||||
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
||||
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE3_MASK_32_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_RGBA;
|
||||
}
|
||||
else if (FreeImage_GetRedMask (dib) == GST_VIDEO_BYTE3_MASK_32_INT &&
|
||||
FreeImage_GetGreenMask (dib) == GST_VIDEO_BYTE2_MASK_32_INT &&
|
||||
FreeImage_GetBlueMask (dib) == GST_VIDEO_BYTE1_MASK_32_INT) {
|
||||
video_format = GST_VIDEO_FORMAT_BGRA;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We could not find a supported format */
|
||||
if (video_format == -1) {
|
||||
caps = NULL;
|
||||
}
|
||||
else {
|
||||
caps = gst_video_format_new_caps (video_format, width, height,
|
||||
fps_n, fps_d, 1, 1);
|
||||
}
|
||||
break;
|
||||
case FIT_UINT16:
|
||||
endianness = G_BYTE_ORDER;
|
||||
|
||||
caps = gst_caps_new_simple ("video/x-raw-gray",
|
||||
"width", G_TYPE_INT, width,
|
||||
"height", G_TYPE_INT, height,
|
||||
"bpp", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, endianness,
|
||||
"framerate", GST_TYPE_FRACTION, fps_n, fps_d,
|
||||
NULL);
|
||||
break;
|
||||
case FIT_INT16:
|
||||
endianness = G_BYTE_ORDER;
|
||||
|
||||
caps = gst_caps_new_simple ("video/x-raw-gray",
|
||||
"width", G_TYPE_INT, width,
|
||||
"height", G_TYPE_INT, height,
|
||||
"bpp", G_TYPE_INT, 16,
|
||||
"depth", G_TYPE_INT, 16,
|
||||
"endianness", G_TYPE_INT, endianness,
|
||||
"framerate", GST_TYPE_FRACTION, fps_n, fps_d,
|
||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
caps = NULL;
|
||||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_freeimageutils_caps_from_freeimage_format (FREE_IMAGE_FORMAT fif)
|
||||
{
|
||||
GstCaps * caps = gst_caps_new_empty ();
|
||||
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_BITMAP)) {
|
||||
if (FreeImage_FIFSupportsExportBPP (fif, 1) ||
|
||||
FreeImage_FIFSupportsExportBPP (fif, 4) ||
|
||||
FreeImage_FIFSupportsExportBPP (fif, 8) ||
|
||||
FreeImage_FIFSupportsExportBPP (fif, 24)) {
|
||||
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGR));
|
||||
}
|
||||
else {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
||||
}
|
||||
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportBPP (fif, 16)) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_15));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB_16));
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportBPP (fif, 32)) {
|
||||
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGRA));
|
||||
}
|
||||
else {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT16)) {
|
||||
if (G_BYTE_ORDER == G_BIG_ENDIAN)
|
||||
gst_caps_append (caps, gst_caps_from_string (
|
||||
GST_VIDEO_CAPS_GRAY16 ("BIG_ENDIAN")));
|
||||
else
|
||||
gst_caps_append (caps, gst_caps_from_string (
|
||||
GST_VIDEO_CAPS_GRAY16 ("LITTLE_ENDIAN")));
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_INT16)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_UINT32)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_INT32)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_FLOAT)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_DOUBLE)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_COMPLEX)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGB16)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBA16)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBF)) {
|
||||
}
|
||||
if (FreeImage_FIFSupportsExportType (fif, FIT_RGBAF)) {
|
||||
}
|
||||
|
||||
/* non-standard format, we'll try and convert to RGB */
|
||||
if (gst_caps_get_size (caps) == 0) {
|
||||
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGR));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_BGRA));
|
||||
}
|
||||
else {
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGB));
|
||||
gst_caps_append (caps, gst_caps_from_string (GST_VIDEO_CAPS_RGBA));
|
||||
}
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_freeimageutils_parse_caps (const GstCaps * caps, FREE_IMAGE_TYPE * type,
|
||||
gint * width, gint * height, gint * bpp, guint32 * red_mask,
|
||||
guint32 * green_mask, guint32 * blue_mask)
|
||||
{
|
||||
GstStructure * s;
|
||||
|
||||
s = gst_caps_get_structure (caps, 0);
|
||||
|
||||
gst_structure_get_int (s, "width", width);
|
||||
gst_structure_get_int (s, "height", height);
|
||||
gst_structure_get_int (s, "bpp", bpp);
|
||||
|
||||
if (g_strcmp0 (gst_structure_get_name (s), "video/x-raw-rgb") == 0) {
|
||||
*type = FIT_BITMAP;
|
||||
gst_structure_get_int (s, "red_mask", red_mask);
|
||||
gst_structure_get_int (s, "green_mask", green_mask);
|
||||
gst_structure_get_int (s, "blue_mask", blue_mask);
|
||||
}
|
||||
else if (g_strcmp0 (gst_structure_get_name (s), "video/x-raw-gray") == 0) {
|
||||
gboolean is_signed;
|
||||
if (!gst_structure_get_boolean (s, "signed", &is_signed))
|
||||
is_signed = FALSE;
|
||||
|
||||
if (*bpp == 8)
|
||||
*type = FIT_BITMAP; /* need to create palette for this later */
|
||||
else if (*bpp == 16 && is_signed == FALSE)
|
||||
*type = FIT_UINT16;
|
||||
else if (*bpp == 16 && is_signed == TRUE)
|
||||
*type = FIT_INT16;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
16
ext/freeimage/gstfreeimageutils.h
Normal file
16
ext/freeimage/gstfreeimageutils.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef __GST_FREEIMAGEUTILS_H__
|
||||
#define __GST_FREEIMAGEUTILS_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <FreeImage.h>
|
||||
|
||||
GstCaps * gst_freeimageutils_caps_from_dib (FIBITMAP * dib,
|
||||
gint fps_n, gint fps_d);
|
||||
GstCaps * gst_freeimageutils_caps_from_freeimage_format (
|
||||
FREE_IMAGE_FORMAT fif);
|
||||
|
||||
gboolean gst_freeimageutils_parse_caps (const GstCaps * caps,
|
||||
FREE_IMAGE_TYPE * type, gint * width, gint * height, gint * bpp,
|
||||
unsigned * red_mask, unsigned * green_mask, unsigned * blue_mask);
|
||||
|
||||
#endif // __GST_FREEIMAGEUTILS_H__
|
||||
Loading…
x
Reference in New Issue
Block a user