FFmpeg
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;
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  uint32_t pal[256];
45 
46  pixdepth = av_get_bits_per_pixel(desc);
47  if (desc->flags & AV_PIX_FMT_FLAG_BE)
48  be = 1;
49  switch (pix_fmt) {
50  case AV_PIX_FMT_ARGB:
51  case AV_PIX_FMT_BGRA:
52  case AV_PIX_FMT_RGBA:
53  case AV_PIX_FMT_ABGR:
54  if (pix_fmt == AV_PIX_FMT_ARGB ||
55  pix_fmt == AV_PIX_FMT_ABGR)
56  be = 1;
57  if (pix_fmt == AV_PIX_FMT_ABGR ||
58  pix_fmt == AV_PIX_FMT_RGBA) {
59  rgb[0] = 0xFF;
60  rgb[1] = 0xFF00;
61  rgb[2] = 0xFF0000;
62  } else {
63  rgb[0] = 0xFF0000;
64  rgb[1] = 0xFF00;
65  rgb[2] = 0xFF;
66  }
67  bpp = 32;
68  pixdepth = 24;
69  vclass = XWD_TRUE_COLOR;
70  bpad = 32;
71  break;
72  case AV_PIX_FMT_BGR24:
73  case AV_PIX_FMT_RGB24:
74  if (pix_fmt == AV_PIX_FMT_RGB24)
75  be = 1;
76  bpp = 24;
77  vclass = XWD_TRUE_COLOR;
78  bpad = 32;
79  rgb[0] = 0xFF0000;
80  rgb[1] = 0xFF00;
81  rgb[2] = 0xFF;
82  break;
87  if (pix_fmt == AV_PIX_FMT_BGR565LE ||
88  pix_fmt == AV_PIX_FMT_BGR565BE) {
89  rgb[0] = 0x1F;
90  rgb[1] = 0x7E0;
91  rgb[2] = 0xF800;
92  } else {
93  rgb[0] = 0xF800;
94  rgb[1] = 0x7E0;
95  rgb[2] = 0x1F;
96  }
97  bpp = 16;
98  vclass = XWD_TRUE_COLOR;
99  bpad = 16;
100  break;
101  case AV_PIX_FMT_RGB555LE:
102  case AV_PIX_FMT_RGB555BE:
103  case AV_PIX_FMT_BGR555LE:
104  case AV_PIX_FMT_BGR555BE:
105  if (pix_fmt == AV_PIX_FMT_BGR555LE ||
106  pix_fmt == AV_PIX_FMT_BGR555BE) {
107  rgb[0] = 0x1F;
108  rgb[1] = 0x3E0;
109  rgb[2] = 0x7C00;
110  } else {
111  rgb[0] = 0x7C00;
112  rgb[1] = 0x3E0;
113  rgb[2] = 0x1F;
114  }
115  bpp = 16;
116  vclass = XWD_TRUE_COLOR;
117  bpad = 16;
118  break;
119  case AV_PIX_FMT_RGB8:
120  case AV_PIX_FMT_BGR8:
123  case AV_PIX_FMT_PAL8:
124  bpp = 8;
125  vclass = XWD_PSEUDO_COLOR;
126  bpad = 8;
127  ncolors = 256;
128  break;
129  case AV_PIX_FMT_GRAY8:
130  bpp = 8;
131  bpad = 8;
132  vclass = XWD_STATIC_GRAY;
133  break;
135  be = 1;
136  bitorder = 1;
137  bpp = 1;
138  bpad = 8;
139  vclass = XWD_STATIC_GRAY;
140  break;
141  default:
142  av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
143  return AVERROR(EINVAL);
144  }
145 
146  lsize = FFALIGN(bpp * avctx->width, bpad) / 8;
147  header_size = XWD_HEADER_SIZE + WINDOW_NAME_SIZE;
148  out_size = header_size + ncolors * XWD_CMAP_SIZE + avctx->height * lsize;
149 
150  if ((ret = ff_alloc_packet2(avctx, pkt, out_size, 0)) < 0)
151  return ret;
152  buf = pkt->data;
153 
154  p->key_frame = 1;
156 
157  bytestream_put_be32(&buf, header_size);
158  bytestream_put_be32(&buf, XWD_VERSION); // file version
159  bytestream_put_be32(&buf, XWD_Z_PIXMAP); // pixmap format
160  bytestream_put_be32(&buf, pixdepth); // pixmap depth in pixels
161  bytestream_put_be32(&buf, avctx->width); // pixmap width in pixels
162  bytestream_put_be32(&buf, avctx->height); // pixmap height in pixels
163  bytestream_put_be32(&buf, 0); // bitmap x offset
164  bytestream_put_be32(&buf, be); // byte order
165  bytestream_put_be32(&buf, 32); // bitmap unit
166  bytestream_put_be32(&buf, bitorder); // bit-order of image data
167  bytestream_put_be32(&buf, bpad); // bitmap scan-line pad in bits
168  bytestream_put_be32(&buf, bpp); // bits per pixel
169  bytestream_put_be32(&buf, lsize); // bytes per scan-line
170  bytestream_put_be32(&buf, vclass); // visual class
171  bytestream_put_be32(&buf, rgb[0]); // red mask
172  bytestream_put_be32(&buf, rgb[1]); // green mask
173  bytestream_put_be32(&buf, rgb[2]); // blue mask
174  bytestream_put_be32(&buf, 8); // size of each bitmask in bits
175  bytestream_put_be32(&buf, ncolors); // number of colors
176  bytestream_put_be32(&buf, ncolors); // number of entries in color map
177  bytestream_put_be32(&buf, avctx->width); // window width
178  bytestream_put_be32(&buf, avctx->height); // window height
179  bytestream_put_be32(&buf, 0); // window upper left X coordinate
180  bytestream_put_be32(&buf, 0); // window upper left Y coordinate
181  bytestream_put_be32(&buf, 0); // window border width
182  bytestream_put_buffer(&buf, WINDOW_NAME, WINDOW_NAME_SIZE);
183 
184  if (pix_fmt == AV_PIX_FMT_PAL8) {
185  memcpy(pal, p->data[1], sizeof(pal));
186  } else {
187  avpriv_set_systematic_pal2(pal, pix_fmt);
188  }
189 
190  for (i = 0; i < ncolors; i++) {
191  uint32_t val;
192  uint8_t red, green, blue;
193 
194  val = pal[i];
195  red = (val >> 16) & 0xFF;
196  green = (val >> 8) & 0xFF;
197  blue = val & 0xFF;
198 
199  bytestream_put_be32(&buf, i); // colormap entry number
200  bytestream_put_be16(&buf, red << 8);
201  bytestream_put_be16(&buf, green << 8);
202  bytestream_put_be16(&buf, blue << 8);
203  bytestream_put_byte(&buf, 0x7); // bitmask flag
204  bytestream_put_byte(&buf, 0); // padding
205  }
206 
207  ptr = p->data[0];
208  for (i = 0; i < avctx->height; i++) {
209  bytestream_put_buffer(&buf, ptr, lsize);
210  ptr += p->linesize[0];
211  }
212 
213  pkt->flags |= AV_PKT_FLAG_KEY;
214  *got_packet = 1;
215  return 0;
216 }
217 
219  .name = "xwd",
220  .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
221  .type = AVMEDIA_TYPE_VIDEO,
222  .id = AV_CODEC_ID_XWD,
223  .encode2 = xwd_encode_frame,
224  .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGRA,
245  AV_PIX_FMT_NONE },
246 };
const char const char void * val
Definition: avisynth_c.h:863
static enum AVPixelFormat pix_fmt
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
const char * desc
Definition: nvenc.c:68
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:2474
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined ...
Definition: pixfmt.h:108
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian
Definition: pixfmt.h:111
int out_size
Definition: movenc.c:55
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3484
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:106
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: encode.c:32
uint8_t
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:152
#define XWD_STATIC_GRAY
Definition: xwd.h:34
AVCodec ff_xwd_encoder
Definition: xwdenc.c:218
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:105
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
uint8_t * data
Definition: avcodec.h:1480
#define XWD_HEADER_SIZE
Definition: xwd.h:27
#define XWD_CMAP_SIZE
Definition: xwd.h:28
#define XWD_VERSION
Definition: xwd.h:26
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1512
#define XWD_Z_PIXMAP
Definition: xwd.h:32
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#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. ...
Definition: internal.h:186
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
const char * name
Name of the codec implementation.
Definition: avcodec.h:3491
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1486
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
int width
picture width / height.
Definition: avcodec.h:1741
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian
Definition: pixfmt.h:110
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
main external API structure.
Definition: avcodec.h:1568
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it be(in the first position) for now.Options-------Then comes the options array.This is what will define the user accessible options.For example
void * buf
Definition: avisynth_c.h:766
#define WINDOW_NAME
Definition: xwdenc.c:30
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), little-endian, X=unused/undefined ...
Definition: pixfmt.h:113
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:107
#define XWD_TRUE_COLOR
Definition: xwd.h:38
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
Y , 8bpp.
Definition: pixfmt.h:74
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:75
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:128
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:368
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:373
packed BGR 5:5:5, 16bpp, (msb)1X 5B 5G 5R(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:112
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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.Frame references ownership and permissions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1457