Libav
imgutils.c
Go to the documentation of this file.
1 /*
2  * This file is part of Libav.
3  *
4  * Libav is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * Libav is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with Libav; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
24 #include "common.h"
25 #include "imgutils.h"
26 #include "internal.h"
27 #include "intreadwrite.h"
28 #include "log.h"
29 #include "mathematics.h"
30 #include "pixdesc.h"
31 #include "rational.h"
32 
33 void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
34  const AVPixFmtDescriptor *pixdesc)
35 {
36  int i;
37  memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0]));
38  if (max_pixstep_comps)
39  memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0]));
40 
41  for (i = 0; i < 4; i++) {
42  const AVComponentDescriptor *comp = &(pixdesc->comp[i]);
43  if (comp->step > max_pixsteps[comp->plane]) {
44  max_pixsteps[comp->plane] = comp->step;
45  if (max_pixstep_comps)
46  max_pixstep_comps[comp->plane] = i;
47  }
48  }
49 }
50 
52 {
54  int max_step [4]; /* max pixel step for each plane */
55  int max_step_comp[4]; /* the component for each plane which has the max pixel step */
56  int s;
57 
58  if (!desc)
59  return AVERROR(EINVAL);
60 
61  if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
62  return (width * desc->comp[0].step + 7) >> 3;
63 
64  av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
65  s = (max_step_comp[plane] == 1 || max_step_comp[plane] == 2) ? desc->log2_chroma_w : 0;
66  return max_step[plane] * (((width + (1 << s) - 1)) >> s);
67 }
68 
69 int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
70 {
71  int i;
73  int max_step [4]; /* max pixel step for each plane */
74  int max_step_comp[4]; /* the component for each plane which has the max pixel step */
75 
76  memset(linesizes, 0, 4*sizeof(linesizes[0]));
77 
78  if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
79  return AVERROR(EINVAL);
80 
81  if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) {
82  if (width > (INT_MAX - 7) / desc->comp[0].step)
83  return AVERROR(EINVAL);
84  linesizes[0] = (width * desc->comp[0].step + 7) >> 3;
85  return 0;
86  }
87 
88  av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
89  for (i = 0; i < 4; i++) {
90  int s = (max_step_comp[i] == 1 || max_step_comp[i] == 2) ? desc->log2_chroma_w : 0;
91  int shifted_w = ((width + (1 << s) - 1)) >> s;
92  if (max_step[i] > INT_MAX / shifted_w)
93  return AVERROR(EINVAL);
94  linesizes[i] = max_step[i] * shifted_w;
95  }
96 
97  return 0;
98 }
99 
101  uint8_t *ptr, const int linesizes[4])
102 {
103  int i, total_size, size[4] = { 0 }, has_plane[4] = { 0 };
104 
105  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
106  memset(data , 0, sizeof(data[0])*4);
107 
108  if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
109  return AVERROR(EINVAL);
110 
111  data[0] = ptr;
112  if (linesizes[0] > (INT_MAX - 1024) / height)
113  return AVERROR(EINVAL);
114  size[0] = linesizes[0] * height;
115 
116  if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
118  size[0] = (size[0] + 3) & ~3;
119  data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */
120  return size[0] + 256 * 4;
121  }
122 
123  for (i = 0; i < 4; i++)
124  has_plane[desc->comp[i].plane] = 1;
125 
126  total_size = size[0];
127  for (i = 1; i < 4 && has_plane[i]; i++) {
128  int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
129  data[i] = data[i-1] + size[i-1];
130  h = (height + (1 << s) - 1) >> s;
131  if (linesizes[i] > INT_MAX / h)
132  return AVERROR(EINVAL);
133  size[i] = h * linesizes[i];
134  if (total_size > INT_MAX - size[i])
135  return AVERROR(EINVAL);
136  total_size += size[i];
137  }
138 
139  return total_size;
140 }
141 
143 {
144  int i;
145 
146  for (i = 0; i < 256; i++) {
147  int r, g, b;
148 
149  switch (pix_fmt) {
150  case AV_PIX_FMT_RGB8:
151  r = (i>>5 )*36;
152  g = ((i>>2)&7)*36;
153  b = (i&3 )*85;
154  break;
155  case AV_PIX_FMT_BGR8:
156  b = (i>>6 )*85;
157  g = ((i>>3)&7)*36;
158  r = (i&7 )*36;
159  break;
161  r = (i>>3 )*255;
162  g = ((i>>1)&3)*85;
163  b = (i&1 )*255;
164  break;
166  b = (i>>3 )*255;
167  g = ((i>>1)&3)*85;
168  r = (i&1 )*255;
169  break;
170  case AV_PIX_FMT_GRAY8:
171  r = b = g = i;
172  break;
173  default:
174  return AVERROR(EINVAL);
175  }
176  pal[i] = b + (g << 8) + (r << 16) + (0xFFU << 24);
177  }
178 
179  return 0;
180 }
181 
182 int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
183  int w, int h, enum AVPixelFormat pix_fmt, int align)
184 {
185  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
186  int i, ret;
187  uint8_t *buf;
188 
189  if (!desc)
190  return AVERROR(EINVAL);
191 
192  if ((ret = av_image_check_size(w, h, 0, NULL)) < 0)
193  return ret;
194  if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, w)) < 0)
195  return ret;
196 
197  for (i = 0; i < 4; i++)
198  linesizes[i] = FFALIGN(linesizes[i], align);
199 
200  if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, NULL, linesizes)) < 0)
201  return ret;
202  buf = av_malloc(ret + align);
203  if (!buf)
204  return AVERROR(ENOMEM);
205  if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) {
206  av_free(buf);
207  return ret;
208  }
210  avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt);
211 
212  return ret;
213 }
214 
215 typedef struct ImgUtils {
216  const AVClass *class;
218  void *log_ctx;
219 } ImgUtils;
220 
222 
223 int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
224 {
225  ImgUtils imgutils = { &imgutils_class, log_offset, log_ctx };
226 
227  if ((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8)
228  return 0;
229 
230  av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h);
231  return AVERROR(EINVAL);
232 }
233 
234 int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar)
235 {
236  int64_t scaled_dim;
237 
238  if (!sar.den)
239  return AVERROR(EINVAL);
240 
241  if (!sar.num || sar.num == sar.den)
242  return 0;
243 
244  if (sar.num < sar.den)
245  scaled_dim = av_rescale_rnd(w, sar.num, sar.den, AV_ROUND_ZERO);
246  else
247  scaled_dim = av_rescale_rnd(h, sar.den, sar.num, AV_ROUND_ZERO);
248 
249  if (scaled_dim > 0)
250  return 0;
251 
252  return AVERROR(EINVAL);
253 }
254 
255 void av_image_copy_plane(uint8_t *dst, int dst_linesize,
256  const uint8_t *src, int src_linesize,
257  int bytewidth, int height)
258 {
259  if (!dst || !src)
260  return;
261  for (;height > 0; height--) {
262  memcpy(dst, src, bytewidth);
263  dst += dst_linesize;
264  src += src_linesize;
265  }
266 }
267 
268 void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
269  const uint8_t *src_data[4], const int src_linesizes[4],
270  enum AVPixelFormat pix_fmt, int width, int height)
271 {
272  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
273 
274  if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
275  return;
276 
277  if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
279  av_image_copy_plane(dst_data[0], dst_linesizes[0],
280  src_data[0], src_linesizes[0],
281  width, height);
282  /* copy the palette */
283  memcpy(dst_data[1], src_data[1], 4*256);
284  } else {
285  int i, planes_nb = 0;
286 
287  for (i = 0; i < desc->nb_components; i++)
288  planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
289 
290  for (i = 0; i < planes_nb; i++) {
291  int h = height;
292  int bwidth = av_image_get_linesize(pix_fmt, width, i);
293  if (i == 1 || i == 2) {
294  h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h);
295  }
296  av_image_copy_plane(dst_data[i], dst_linesizes[i],
297  src_data[i], src_linesizes[i],
298  bwidth, h);
299  }
300  }
301 }
302 
303 int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
304  const uint8_t *src, enum AVPixelFormat pix_fmt,
305  int width, int height, int align)
306 {
307  int ret, i;
308 
309  ret = av_image_check_size(width, height, 0, NULL);
310  if (ret < 0)
311  return ret;
312 
313  ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width);
314  if (ret < 0)
315  return ret;
316 
317  for (i = 0; i < 4; i++)
318  dst_linesize[i] = FFALIGN(dst_linesize[i], align);
319 
320  return av_image_fill_pointers(dst_data, pix_fmt, height, src, dst_linesize);
321 }
322 
324  int width, int height, int align)
325 {
326  uint8_t *data[4];
327  int linesize[4];
328  int ret;
329  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
330  if (!desc)
331  return AVERROR_BUG;
332 
333  ret = av_image_check_size(width, height, 0, NULL);
334  if (ret < 0)
335  return ret;
336 
337  // do not include palette for these pseudo-paletted formats
338  if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
339  return width * height;
340 
341  return av_image_fill_arrays(data, linesize, NULL, pix_fmt,
342  width, height, align);
343 }
344 
345 int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
346  const uint8_t * const src_data[4],
347  const int src_linesize[4],
348  enum AVPixelFormat pix_fmt,
349  int width, int height, int align)
350 {
351  int i, j, nb_planes = 0, linesize[4];
352  int size = av_image_get_buffer_size(pix_fmt, width, height, align);
353  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
354 
355  if (size > dst_size || size < 0 || !desc)
356  return AVERROR(EINVAL);
357 
358  for (i = 0; i < desc->nb_components; i++)
359  nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
360 
361  nb_planes++;
362 
363  av_image_fill_linesizes(linesize, pix_fmt, width);
364  for (i = 0; i < nb_planes; i++) {
365  int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
366  const uint8_t *src = src_data[i];
367  h = (height + (1 << shift) - 1) >> shift;
368 
369  for (j = 0; j < h; j++) {
370  memcpy(dst, src, linesize[i]);
371  dst += FFALIGN(linesize[i], align);
372  src += src_linesize[i];
373  }
374  }
375 
376  if (desc->flags & AV_PIX_FMT_FLAG_PAL)
377  memcpy((unsigned char *)(((size_t)dst + 3) & ~3),
378  src_data[1], 256 * 4);
379 
380  return size;
381 }
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:134
int plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:34
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
Compute the size of an image line with format pix_fmt and width width for the plane plane...
Definition: imgutils.c:51
int size
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1768
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, const uint8_t *const src_data[4], const int src_linesize[4], enum AVPixelFormat pix_fmt, int width, int height, int align)
Copy image data from an image into a buffer.
Definition: imgutils.c:345
Definition: vf_drawbox.c:37
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:40
misc image utilities
const char * desc
Definition: nvenc.c:101
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align)
Allocate an image with size w and h and pixel format pix_fmt, and fill pointers and linesizes accordi...
Definition: imgutils.c:182
int num
numerator
Definition: rational.h:44
static const AVClass imgutils_class
Definition: imgutils.c:221
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align)
Setup the data pointers and linesizes based on the specified image parameters and the provided array...
Definition: imgutils.c:303
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:91
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:82
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], const AVPixFmtDescriptor *pixdesc)
Compute the max pixel step for each plane of an image with a format described by pixdesc.
Definition: imgutils.c:33
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:119
uint8_t
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:142
#define b
Definition: input.c:52
void * log_ctx
Definition: imgutils.c:218
const char data[16]
Definition: mxf.c:70
int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar)
Check if the given sample aspect ratio of an image is valid.
Definition: imgutils.c:234
#define FFALIGN(x, a)
Definition: macros.h:48
#define r
Definition: input.c:51
#define src
Definition: vp8dsp.c:254
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters...
Definition: imgutils.c:323
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:124
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:190
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:100
#define AVERROR(e)
Definition: error.h:43
g
Definition: yuv2rgb.c:546
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:142
#define FFMAX(a, b)
Definition: common.h:64
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:268
common internal API header
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:105
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:223
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:82
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:85
Round toward zero.
Definition: mathematics.h:50
#define AV_PIX_FMT_FLAG_PSEUDOPAL
The pixel format is "pseudo-paletted".
Definition: pixdesc.h:156
enum AVPixelFormat pix_fmt
Definition: movenc.c:853
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
int log_offset
Definition: imgutils.c:217
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:80
static int width
Definition: utils.c:156
int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int height, uint8_t *ptr, const int linesizes[4])
Fill plane data pointers for an image with pixel format pix_fmt and height height.
Definition: imgutils.c:100
av_default_item_name
Definition: dnxhdenc.c:55
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:80
#define AVERROR_BUG
Bug detected, please report the issue.
Definition: error.h:60
Describe the class of an AVClass context structure.
Definition: log.h:34
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:69
rational number numerator/denominator
Definition: rational.h:43
#define AV_PIX_FMT_FLAG_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:138
int height
Definition: gxfenc.c:72
Y , 8bpp.
Definition: pixfmt.h:67
common internal and external API header
rational numbers
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:83
int den
denominator
Definition: rational.h:45
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:83
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:255
AVPixelFormat
Pixel format.
Definition: pixfmt.h:57
for(j=16;j >0;--j)
int step
Number of elements between 2 horizontally consecutive pixels.
Definition: pixdesc.h:40
#define AV_CEIL_RSHIFT(a, b)
Fast a / (1 << b) rounded toward +inf, assuming a >= 0 and b >= 0.
Definition: common.h:57