demux: heif: send extradata with avif
[vlc.git] / modules / codec / xwd.c
blobba54bf73433091bfc81e2701cc13910a220f37d9
1 /*****************************************************************************
2 * xwd.c: X Window system raster image dump pseudo-decoder
3 *****************************************************************************
4 * Copyright (C) 2012 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include <assert.h>
26 #ifdef HAVE_ARPA_INET_H
27 #include <arpa/inet.h>
28 #endif
29 #include <X11/XWDFile.h>
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
35 static int Open(vlc_object_t *);
37 vlc_module_begin()
38 set_description(N_("XWD image decoder"))
39 set_capability("video decoder", 50)
40 set_category(CAT_INPUT)
41 set_subcategory(SUBCAT_INPUT_VCODEC)
42 set_callbacks(Open, NULL)
43 vlc_module_end()
45 static int Decode(decoder_t *, block_t *);
47 static int Open(vlc_object_t *obj)
49 decoder_t *dec = (decoder_t *)obj;
51 if (dec->fmt_in.i_codec != VLC_CODEC_XWD)
52 return VLC_EGENERIC;
54 dec->pf_decode = Decode;
55 es_format_Copy(&dec->fmt_out, &dec->fmt_in);
56 dec->fmt_out.i_codec = VLC_CODEC_RGB32;
57 return VLC_SUCCESS;
60 static int Decode (decoder_t *dec, block_t *block)
62 picture_t *pic = NULL;
64 if (block == NULL) /* No Drain */
65 return VLCDEC_SUCCESS;
67 if (block->i_pts == VLC_TICK_INVALID)
68 goto drop; /* undated block, should never happen */
69 if (block->i_buffer < sz_XWDheader)
70 goto drop;
72 /* Skip XWD header */
73 const XWDFileHeader *hdr = (const void *)block->p_buffer;
74 uint32_t hdrlen = ntohl(hdr->header_size);
75 if (hdrlen < sz_XWDheader
76 || ntohl(hdr->file_version) < XWD_FILE_VERSION
77 || ntohl(hdr->pixmap_format) != 2 /* ZPixmap */)
78 goto drop;
80 hdrlen += ntohl(hdr->ncolors) * sz_XWDColor;
81 if (hdrlen > block->i_buffer)
82 goto drop;
83 block->p_buffer += hdrlen;
84 block->i_buffer -= hdrlen;
86 /* Parse XWD header */
87 vlc_fourcc_t chroma = 0;
88 switch (ntohl(hdr->pixmap_depth))
90 case 8:
91 if (ntohl(hdr->bits_per_pixel) == 8)
92 chroma = VLC_CODEC_RGB8;
93 break;
94 case 15:
95 if (ntohl(hdr->bits_per_pixel) == 16)
96 chroma = VLC_CODEC_RGB15;
97 break;
98 case 16:
99 if (ntohl(hdr->bits_per_pixel) == 16)
100 chroma = VLC_CODEC_RGB16;
101 break;
102 case 24:
103 switch (ntohl(hdr->bits_per_pixel))
105 case 32: chroma = VLC_CODEC_RGB32; break;
106 case 24: chroma = VLC_CODEC_RGB24; break;
108 break;
109 case 32:
110 if (ntohl(hdr->bits_per_pixel) == 32)
111 chroma = VLC_CODEC_ARGB;
112 break;
114 /* TODO: check image endianess, set RGB mask */
115 if (!chroma)
116 goto drop;
118 video_format_Setup(&dec->fmt_out.video, chroma,
119 ntohl(hdr->pixmap_width), ntohl(hdr->pixmap_height),
120 ntohl(hdr->pixmap_width), ntohl(hdr->pixmap_height),
121 dec->fmt_in.video.i_sar_num,
122 dec->fmt_in.video.i_sar_den);
124 const size_t copy = dec->fmt_out.video.i_width
125 * (dec->fmt_out.video.i_bits_per_pixel / 8);
126 const uint32_t pitch = ntohl(hdr->bytes_per_line);
128 /* Build picture */
129 if (pitch < copy
130 || (block->i_buffer / pitch) < dec->fmt_out.video.i_height)
131 goto drop;
133 if (decoder_UpdateVideoFormat(dec))
134 goto drop;
135 pic = decoder_NewPicture(dec);
136 if (pic == NULL)
137 goto drop;
139 const uint8_t *in = block->p_buffer;
140 uint8_t *out = pic->p->p_pixels;
141 for (unsigned i = 0; i < dec->fmt_out.video.i_height; i++)
143 memcpy(out, in, copy);
144 in += pitch;
145 out += pic->p->i_pitch;
147 pic->date = block->i_pts;
148 pic->b_progressive = true;
150 drop:
151 block_Release(block);
152 decoder_QueueVideo(dec, pic);
153 return VLCDEC_SUCCESS;