xwdenc.c
Go to the documentation of this file.
1 /*
2  * XWD image format
3  *
4  * Copyright (c) 2012 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/pixdesc.h"
25 #include "avcodec.h"
26 #include "bytestream.h"
27 #include "internal.h"
28 #include "xwd.h"
29 
30 #define WINDOW_NAME "lavcxwdenc"
31 #define WINDOW_NAME_SIZE 11
32 
34  const AVFrame *pict, int *got_packet)
35 {
36  enum AVPixelFormat pix_fmt = avctx->pix_fmt;
37  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
38  uint32_t pixdepth, bpp, bpad, ncolors = 0, lsize, vclass, be = 0;
39  uint32_t rgb[3] = { 0 }, bitorder = 0;
40  uint32_t header_size;
41  int i, out_size, ret;
42  uint8_t *ptr, *buf;
43  AVFrame * const p = (AVFrame *)pict;
44 
45  pixdepth = av_get_bits_per_pixel(desc);
46  if (desc->flags & PIX_FMT_BE)
47  be = 1;
48  switch (pix_fmt) {
49  case AV_PIX_FMT_ARGB:
50  case AV_PIX_FMT_BGRA:
51  case AV_PIX_FMT_RGBA:
52  case AV_PIX_FMT_ABGR:
53  if (pix_fmt == AV_PIX_FMT_ARGB ||
54  pix_fmt == AV_PIX_FMT_ABGR)
55  be = 1;
56  if (pix_fmt == AV_PIX_FMT_ABGR ||
57  pix_fmt == AV_PIX_FMT_RGBA) {
58  rgb[0] = 0xFF;
59  rgb[1] = 0xFF00;
60  rgb[2] = 0xFF0000;
61  } else {
62  rgb[0] = 0xFF0000;
63  rgb[1] = 0xFF00;
64  rgb[2] = 0xFF;
65  }
66  bpp = 32;
67  pixdepth = 24;
68  vclass = XWD_TRUE_COLOR;
69  bpad = 32;
70  break;
71  case AV_PIX_FMT_BGR24:
72  case AV_PIX_FMT_RGB24:
73  if (pix_fmt == AV_PIX_FMT_RGB24)
74  be = 1;
75  bpp = 24;
76  vclass = XWD_TRUE_COLOR;
77  bpad = 32;
78  rgb[0] = 0xFF0000;
79  rgb[1] = 0xFF00;
80  rgb[2] = 0xFF;
81  break;
86  if (pix_fmt == AV_PIX_FMT_BGR565LE ||
87  pix_fmt == AV_PIX_FMT_BGR565BE) {
88  rgb[0] = 0x1F;
89  rgb[1] = 0x7E0;
90  rgb[2] = 0xF800;
91  } else {
92  rgb[0] = 0xF800;
93  rgb[1] = 0x7E0;
94  rgb[2] = 0x1F;
95  }
96  bpp = 16;
97  vclass = XWD_TRUE_COLOR;
98  bpad = 16;
99  break;
100  case AV_PIX_FMT_RGB555LE:
101  case AV_PIX_FMT_RGB555BE:
102  case AV_PIX_FMT_BGR555LE:
103  case AV_PIX_FMT_BGR555BE:
104  if (pix_fmt == AV_PIX_FMT_BGR555LE ||
105  pix_fmt == AV_PIX_FMT_BGR555BE) {
106  rgb[0] = 0x1F;
107  rgb[1] = 0x3E0;
108  rgb[2] = 0x7C00;
109  } else {
110  rgb[0] = 0x7C00;
111  rgb[1] = 0x3E0;
112  rgb[2] = 0x1F;
113  }
114  bpp = 16;
115  vclass = XWD_TRUE_COLOR;
116  bpad = 16;
117  break;
118  case AV_PIX_FMT_RGB8:
119  case AV_PIX_FMT_BGR8:
122  case AV_PIX_FMT_PAL8:
123  bpp = 8;
124  vclass = XWD_PSEUDO_COLOR;
125  bpad = 8;
126  ncolors = 256;
127  break;
128  case AV_PIX_FMT_GRAY8:
129  bpp = 8;
130  bpad = 8;
131  vclass = XWD_STATIC_GRAY;
132  break;
134  be = 1;
135  bitorder = 1;
136  bpp = 1;
137  bpad = 8;
138  vclass = XWD_STATIC_GRAY;
139  break;
140  default:
141  av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
142  return AVERROR(EINVAL);
143  }
144 
145  lsize = FFALIGN(bpp * avctx->width, bpad) / 8;
146  header_size = XWD_HEADER_SIZE + WINDOW_NAME_SIZE;
147  out_size = header_size + ncolors * XWD_CMAP_SIZE + avctx->height * lsize;
148 
149  if ((ret = ff_alloc_packet2(avctx, pkt, out_size)) < 0)
150  return ret;
151  buf = pkt->data;
152 
153  p->key_frame = 1;
155 
156  bytestream_put_be32(&buf, header_size);
157  bytestream_put_be32(&buf, XWD_VERSION); // file version
158  bytestream_put_be32(&buf, XWD_Z_PIXMAP); // pixmap format
159  bytestream_put_be32(&buf, pixdepth); // pixmap depth in pixels
160  bytestream_put_be32(&buf, avctx->width); // pixmap width in pixels
161  bytestream_put_be32(&buf, avctx->height); // pixmap height in pixels
162  bytestream_put_be32(&buf, 0); // bitmap x offset
163  bytestream_put_be32(&buf, be); // byte order
164  bytestream_put_be32(&buf, 32); // bitmap unit
165  bytestream_put_be32(&buf, bitorder); // bit-order of image data
166  bytestream_put_be32(&buf, bpad); // bitmap scan-line pad in bits
167  bytestream_put_be32(&buf, bpp); // bits per pixel
168  bytestream_put_be32(&buf, lsize); // bytes per scan-line
169  bytestream_put_be32(&buf, vclass); // visual class
170  bytestream_put_be32(&buf, rgb[0]); // red mask
171  bytestream_put_be32(&buf, rgb[1]); // green mask
172  bytestream_put_be32(&buf, rgb[2]); // blue mask
173  bytestream_put_be32(&buf, 8); // size of each bitmask in bits
174  bytestream_put_be32(&buf, ncolors); // number of colors
175  bytestream_put_be32(&buf, ncolors); // number of entries in color map
176  bytestream_put_be32(&buf, avctx->width); // window width
177  bytestream_put_be32(&buf, avctx->height); // window height
178  bytestream_put_be32(&buf, 0); // window upper left X coordinate
179  bytestream_put_be32(&buf, 0); // window upper left Y coordinate
180  bytestream_put_be32(&buf, 0); // window border width
181  bytestream_put_buffer(&buf, WINDOW_NAME, WINDOW_NAME_SIZE);
182 
183  for (i = 0; i < ncolors; i++) {
184  uint32_t val;
185  uint8_t red, green, blue;
186 
187  val = AV_RN32A(p->data[1] + i * 4);
188  red = (val >> 16) & 0xFF;
189  green = (val >> 8) & 0xFF;
190  blue = val & 0xFF;
191 
192  bytestream_put_be32(&buf, i); // colormap entry number
193  bytestream_put_be16(&buf, red << 8);
194  bytestream_put_be16(&buf, green << 8);
195  bytestream_put_be16(&buf, blue << 8);
196  bytestream_put_byte(&buf, 0x7); // bitmask flag
197  bytestream_put_byte(&buf, 0); // padding
198  }
199 
200  ptr = p->data[0];
201  for (i = 0; i < avctx->height; i++) {
202  bytestream_put_buffer(&buf, ptr, lsize);
203  ptr += p->linesize[0];
204  }
205 
206  pkt->flags |= AV_PKT_FLAG_KEY;
207  *got_packet = 1;
208  return 0;
209 }
210 
212  .name = "xwd",
213  .type = AVMEDIA_TYPE_VIDEO,
214  .id = AV_CODEC_ID_XWD,
215  .encode2 = xwd_encode_frame,
216  .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA,
237  AV_PIX_FMT_NONE },
238  .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
239 };
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:1731
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 ...
Definition: pixfmt.h:117
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
Definition: pixfmt.h:120
#define FFALIGN(x, a)
Definition: common.h:63
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:115
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:89
#define AV_RN32A(p)
Definition: intreadwrite.h:518
uint8_t
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define XWD_STATIC_GRAY
Definition: xwd.h:34
static AVPacket pkt
Definition: demuxing.c:56
AVCodec ff_xwd_encoder
Definition: xwdenc.c:211
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:114
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:98
uint8_t * data
#define XWD_HEADER_SIZE
Definition: xwd.h:27
#define XWD_CMAP_SIZE
Definition: xwd.h:28
enum AVPixelFormat pix_fmt
Definition: v4l.c:63
#define XWD_VERSION
Definition: xwd.h:26
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
#define XWD_Z_PIXMAP
Definition: xwd.h:32
#define WINDOW_NAME_SIZE
Definition: xwdenc.c:31
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:99
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
external API header
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:96
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:97
int flags
A combination of AV_PKT_FLAG values.
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:92
ret
Definition: avfilter.c:821
int width
picture width / height.
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:71
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
Definition: pixfmt.h:119
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
Check AVPacket size and/or allocate data.
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:87
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
uint8_t flags
Definition: pixdesc.h:76
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
main external API structure.
void * buf
Definition: avisynth_c.h:594
#define WINDOW_NAME
Definition: xwdenc.c:30
synthesis window for stochastic i
packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 ...
Definition: pixfmt.h:122
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 ...
Definition: pixfmt.h:116
#define XWD_TRUE_COLOR
Definition: xwd.h:38
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
Y , 8bpp.
Definition: pixfmt.h:76
common internal api header.
#define XWD_PSEUDO_COLOR
Definition: xwd.h:37
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:77
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:90
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:337
static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: xwdenc.c:33
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 ...
Definition: pixfmt.h:121
#define AV_LOG_INFO
Definition: log.h:156
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
This structure stores compressed data.
#define PIX_FMT_BE
Pixel format is big-endian.
Definition: pixdesc.h:89