[vlc-commits] XWD decoder

Rémi Denis-Courmont git at videolan.org
Sun Nov 25 11:16:52 CET 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Nov 24 19:28:53 2012 +0200| [ce0db74040b472094ac77762ade60bd466903233] | committer: Rémi Denis-Courmont

XWD decoder

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ce0db74040b472094ac77762ade60bd466903233
---

 configure.ac             |   17 +++--
 modules/codec/Modules.am |    7 +++
 modules/codec/xwd.c      |  154 ++++++++++++++++++++++++++++++++++++++++++++++
 po/POTFILES.in           |    1 +
 4 files changed, 173 insertions(+), 6 deletions(-)

diff --git a/configure.ac b/configure.ac
index 8ae63c5..dbd27dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2946,13 +2946,18 @@ AS_IF([test "${enable_xcb}" != "no"], [
     AC_MSG_WARN([${XCB_RANDR_PKG_ERRORS}. Panoramix filter will not be supported.])
   ])
 
-  dnl xcb-utils
-  PKG_CHECK_MODULES(XCB_KEYSYMS, [xcb-keysyms >= 0.3.4], [
-    PKG_CHECK_MODULES(XPROTO, [xproto])
-    VLC_ADD_PLUGIN([globalhotkeys])
-    VLC_ADD_CFLAGS([xcb_window], [-DHAVE_XCB_KEYSYMS])
+  PKG_CHECK_MODULES(XPROTO, [xproto], [
+    VLC_ADD_PLUGIN([xwd])
+
+    dnl xcb-utils
+    PKG_CHECK_MODULES(XCB_KEYSYMS, [xcb-keysyms >= 0.3.4], [
+      VLC_ADD_PLUGIN([globalhotkeys])
+      VLC_ADD_CFLAGS([xcb_window], [-DHAVE_XCB_KEYSYMS])
+    ], [
+      AC_MSG_WARN([${XCB_KEYSYMS_PKG_ERRORS}. Hotkeys will not work.])
+    ])
   ], [
-    AC_MSG_WARN([${XCB_KEYSYMS_PKG_ERRORS}. Hotkeys will not work.])
+    AC_MSG_WARN([${XPROTO_PKG_ERRORS}. Hotkeys and XWD will not work.])
   ])
 
   AS_IF([test "${enable_glx}" != "no"], [
diff --git a/modules/codec/Modules.am b/modules/codec/Modules.am
index c2894bb..d701a26 100644
--- a/modules/codec/Modules.am
+++ b/modules/codec/Modules.am
@@ -149,6 +149,13 @@ if HAVE_AVCODEC_VDA
 libvlc_LTLIBRARIES += libvda_plugin.la
 endif
 
+### XWD ###
+libxwd_plugin_la_SOURCES = xwd.c
+libxwd_plugin_la_CFLAGS = $(AM_CFLAGS) $(XPROTO_CFLAGS)
+libxwd_plugin_la_LIBADD = $(AM_LIBADD) $(XPROTO_LIBS)
+libvlc_LTLIBRARIES += $(LTLIBxwd)
+EXTRA_LTLIBRARIES += libxwd_plugin.la
+
 ### OpenMAX ###
 noinst_HEADERS += \
 	omxil/OMX_Component.h \
diff --git a/modules/codec/xwd.c b/modules/codec/xwd.c
new file mode 100644
index 0000000..4de32a6
--- /dev/null
+++ b/modules/codec/xwd.c
@@ -0,0 +1,154 @@
+/*****************************************************************************
+ * xwd.c: X Window system raster image dump pseudo-decoder
+ *****************************************************************************
+ * Copyright (C) 2012 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <arpa/inet.h>
+#include <X11/XWDFile.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+
+static int Open(vlc_object_t *);
+
+vlc_module_begin()
+    set_description(N_("XWD image decoder"))
+    set_capability("decoder", 50)
+    set_category(CAT_INPUT)
+    set_subcategory(SUBCAT_INPUT_VCODEC)
+    set_callbacks(Open, NULL)
+vlc_module_end()
+
+static picture_t *Decode(decoder_t *, block_t **);
+
+static int Open(vlc_object_t *obj)
+{
+    decoder_t *dec = (decoder_t *)obj;
+
+    if (dec->fmt_in.i_codec != VLC_CODEC_XWD)
+        return VLC_EGENERIC;
+
+    dec->pf_decode_video = Decode;
+    es_format_Copy(&dec->fmt_out, &dec->fmt_in);
+    dec->fmt_out.i_codec = VLC_CODEC_RGB32;
+    dec->fmt_out.i_cat = VIDEO_ES;
+    return VLC_SUCCESS;
+}
+
+static picture_t *Decode (decoder_t *dec, block_t **pp)
+{
+    picture_t *pic = NULL;
+
+    if (pp == NULL)
+        return NULL;
+
+    block_t *block = *pp;
+    if (block == NULL)
+        return NULL;
+    *pp = NULL;
+
+    if (block->i_pts <= VLC_TS_INVALID)
+        goto drop; /* undated block, should never happen */
+    if (block->i_buffer < sz_XWDheader)
+        goto drop;
+
+    /* Skip XWD header */
+    const XWDFileHeader *hdr = (const void *)block->p_buffer;
+    uint32_t hdrlen = ntohl(hdr->header_size);
+    if (hdrlen < sz_XWDheader
+     || ntohl(hdr->file_version) < XWD_FILE_VERSION
+     || ntohl(hdr->pixmap_format) != 2 /* ZPixmap */)
+        goto drop;
+
+    hdrlen += ntohl(hdr->ncolors) * sz_XWDColor;
+    if (hdrlen > block->i_buffer)
+        goto drop;
+    block->p_buffer += hdrlen;
+    block->i_buffer -= hdrlen;
+
+    /* Parse XWD header */
+    vlc_fourcc_t chroma = 0;
+    switch (ntohl(hdr->pixmap_depth))
+    {
+        case 8:
+            if (ntohl(hdr->bits_per_pixel) == 8)
+                chroma = VLC_CODEC_RGB8;
+            break;
+        case 15:
+            if (ntohl(hdr->bits_per_pixel) == 16)
+                chroma = VLC_CODEC_RGB15;
+            break;
+        case 16:
+            if (ntohl(hdr->bits_per_pixel) == 16)
+                chroma = VLC_CODEC_RGB16;
+            break;
+        case 24:
+            switch (ntohl(hdr->bits_per_pixel))
+            {
+                case 32: chroma = VLC_CODEC_RGB32; break;
+                case 24: chroma = VLC_CODEC_RGB24; break;
+            }
+            break;
+        case 32:
+            if (ntohl(hdr->bits_per_pixel) == 32)
+                chroma = VLC_CODEC_RGBA;
+            break;
+    }
+    /* TODO: check image endianess, set RGB mask */
+    if (!chroma)
+        goto drop;
+
+    video_format_Setup(&dec->fmt_out.video, chroma,
+                       ntohl(hdr->pixmap_width), ntohl(hdr->pixmap_height),
+                       dec->fmt_in.video.i_sar_num,
+                       dec->fmt_in.video.i_sar_den);
+
+    const size_t copy = dec->fmt_out.video.i_width
+                        * (dec->fmt_out.video.i_bits_per_pixel / 8);
+    const uint32_t pitch = ntohl(hdr->bytes_per_line);
+
+    /* Build picture */
+    if (pitch < copy
+     || (block->i_buffer / pitch) < dec->fmt_out.video.i_height)
+        goto drop;
+
+    pic = decoder_NewPicture(dec);
+    if (pic == NULL)
+        goto drop;
+
+    const uint8_t *in = block->p_buffer;
+    uint8_t *out = pic->p->p_pixels;
+    for (unsigned i = 0; i < dec->fmt_out.video.i_height; i++)
+    {
+        memcpy(out, in, copy);
+        in += pitch;
+        out += pic->p->i_pitch;
+    }
+    pic->date = block->i_pts;
+    pic->b_progressive = true;
+
+drop:
+    block_Release(block);
+    return pic;
+}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1ad4d84..a8185d1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -406,6 +406,7 @@ modules/codec/uleaddvaudio.c
 modules/codec/vorbis.c
 modules/codec/wmafixed/wma.c
 modules/codec/x264.c
+modules/codec/xwd.c
 modules/codec/zvbi.c
 modules/control/dbus/dbus.c
 modules/control/dbus/dbus_common.h



More information about the vlc-commits mailing list