imgutils.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * misc image utilities
22  */
23 
24 #include "avassert.h"
25 #include "common.h"
26 #include "imgutils.h"
27 #include "internal.h"
28 #include "intreadwrite.h"
29 #include "log.h"
30 #include "pixdesc.h"
31 
32 void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
33  const AVPixFmtDescriptor *pixdesc)
34 {
35  int i;
36  memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0]));
37  if (max_pixstep_comps)
38  memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0]));
39 
40  for (i = 0; i < 4; i++) {
41  const AVComponentDescriptor *comp = &(pixdesc->comp[i]);
42  if ((comp->step_minus1+1) > max_pixsteps[comp->plane]) {
43  max_pixsteps[comp->plane] = comp->step_minus1+1;
44  if (max_pixstep_comps)
45  max_pixstep_comps[comp->plane] = i;
46  }
47  }
48 }
49 
50 static inline
51 int image_get_linesize(int width, int plane,
52  int max_step, int max_step_comp,
53  const AVPixFmtDescriptor *desc)
54 {
55  int s, shifted_w, linesize;
56 
57  if (!desc)
58  return AVERROR(EINVAL);
59 
60  if (width < 0)
61  return AVERROR(EINVAL);
62  s = (max_step_comp == 1 || max_step_comp == 2) ? desc->log2_chroma_w : 0;
63  shifted_w = ((width + (1 << s) - 1)) >> s;
64  if (shifted_w && max_step > INT_MAX / shifted_w)
65  return AVERROR(EINVAL);
66  linesize = max_step * shifted_w;
67 
68  if (desc->flags & PIX_FMT_BITSTREAM)
69  linesize = (linesize + 7) >> 3;
70  return linesize;
71 }
72 
74 {
75  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
76  int max_step [4]; /* max pixel step for each plane */
77  int max_step_comp[4]; /* the component for each plane which has the max pixel step */
78 
79  if ((unsigned)pix_fmt >= AV_PIX_FMT_NB || desc->flags & PIX_FMT_HWACCEL)
80  return AVERROR(EINVAL);
81 
82  av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
83  return image_get_linesize(width, plane, max_step[plane], max_step_comp[plane], desc);
84 }
85 
86 int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
87 {
88  int i, ret;
89  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
90  int max_step [4]; /* max pixel step for each plane */
91  int max_step_comp[4]; /* the component for each plane which has the max pixel step */
92 
93  memset(linesizes, 0, 4*sizeof(linesizes[0]));
94 
95  if (!desc || desc->flags & PIX_FMT_HWACCEL)
96  return AVERROR(EINVAL);
97 
98  av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
99  for (i = 0; i < 4; i++) {
100  if ((ret = image_get_linesize(width, i, max_step[i], max_step_comp[i], desc)) < 0)
101  return ret;
102  linesizes[i] = ret;
103  }
104 
105  return 0;
106 }
107 
109  uint8_t *ptr, const int linesizes[4])
110 {
111  int i, total_size, size[4] = { 0 }, has_plane[4] = { 0 };
112 
113  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
114  memset(data , 0, sizeof(data[0])*4);
115 
116  if (!desc || desc->flags & PIX_FMT_HWACCEL)
117  return AVERROR(EINVAL);
118 
119  data[0] = ptr;
120  if (linesizes[0] > (INT_MAX - 1024) / height)
121  return AVERROR(EINVAL);
122  size[0] = linesizes[0] * height;
123 
124  if (desc->flags & PIX_FMT_PAL ||
125  desc->flags & PIX_FMT_PSEUDOPAL) {
126  size[0] = (size[0] + 3) & ~3;
127  data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */
128  return size[0] + 256 * 4;
129  }
130 
131  for (i = 0; i < 4; i++)
132  has_plane[desc->comp[i].plane] = 1;
133 
134  total_size = size[0];
135  for (i = 1; i < 4 && has_plane[i]; i++) {
136  int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
137  data[i] = data[i-1] + size[i-1];
138  h = (height + (1 << s) - 1) >> s;
139  if (linesizes[i] > INT_MAX / h)
140  return AVERROR(EINVAL);
141  size[i] = h * linesizes[i];
142  if (total_size > INT_MAX - size[i])
143  return AVERROR(EINVAL);
144  total_size += size[i];
145  }
146 
147  return total_size;
148 }
149 
151 {
152  int i;
153 
154  for (i = 0; i < 256; i++) {
155  int r, g, b;
156 
157  switch (pix_fmt) {
158  case AV_PIX_FMT_RGB8:
159  r = (i>>5 )*36;
160  g = ((i>>2)&7)*36;
161  b = (i&3 )*85;
162  break;
163  case AV_PIX_FMT_BGR8:
164  b = (i>>6 )*85;
165  g = ((i>>3)&7)*36;
166  r = (i&7 )*36;
167  break;
169  r = (i>>3 )*255;
170  g = ((i>>1)&3)*85;
171  b = (i&1 )*255;
172  break;
174  b = (i>>3 )*255;
175  g = ((i>>1)&3)*85;
176  r = (i&1 )*255;
177  break;
178  case AV_PIX_FMT_GRAY8:
179  r = b = g = i;
180  break;
181  default:
182  return AVERROR(EINVAL);
183  }
184  pal[i] = b + (g<<8) + (r<<16) + (0xFFU<<24);
185  }
186 
187  return 0;
188 }
189 
190 int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
191  int w, int h, enum AVPixelFormat pix_fmt, int align)
192 {
193  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
194  int i, ret;
195  uint8_t *buf;
196 
197  if (!desc)
198  return AVERROR(EINVAL);
199 
200  if ((ret = av_image_check_size(w, h, 0, NULL)) < 0)
201  return ret;
202  if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0)
203  return ret;
204 
205  for (i = 0; i < 4; i++)
206  linesizes[i] = FFALIGN(linesizes[i], align);
207 
208  if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, NULL, linesizes)) < 0)
209  return ret;
210  buf = av_malloc(ret + align);
211  if (!buf)
212  return AVERROR(ENOMEM);
213  if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) {
214  av_free(buf);
215  return ret;
216  }
217  if (desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL)
218  avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt);
219 
220  return ret;
221 }
222 
223 typedef struct ImgUtils {
224  const AVClass *class;
226  void *log_ctx;
227 } ImgUtils;
228 
230 
231 int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
232 {
233  ImgUtils imgutils = { &imgutils_class, log_offset, log_ctx };
234 
235  if ((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8)
236  return 0;
237 
238  av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h);
239  return AVERROR(EINVAL);
240 }
241 
242 void av_image_copy_plane(uint8_t *dst, int dst_linesize,
243  const uint8_t *src, int src_linesize,
244  int bytewidth, int height)
245 {
246  if (!dst || !src)
247  return;
248  av_assert0(abs(src_linesize) >= bytewidth);
249  av_assert0(abs(dst_linesize) >= bytewidth);
250  for (;height > 0; height--) {
251  memcpy(dst, src, bytewidth);
252  dst += dst_linesize;
253  src += src_linesize;
254  }
255 }
256 
257 void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
258  const uint8_t *src_data[4], const int src_linesizes[4],
259  enum AVPixelFormat pix_fmt, int width, int height)
260 {
261  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
262 
263  if (!desc || desc->flags & PIX_FMT_HWACCEL)
264  return;
265 
266  if (desc->flags & PIX_FMT_PAL ||
267  desc->flags & PIX_FMT_PSEUDOPAL) {
268  av_image_copy_plane(dst_data[0], dst_linesizes[0],
269  src_data[0], src_linesizes[0],
270  width, height);
271  /* copy the palette */
272  memcpy(dst_data[1], src_data[1], 4*256);
273  } else {
274  int i, planes_nb = 0;
275 
276  for (i = 0; i < desc->nb_components; i++)
277  planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
278 
279  for (i = 0; i < planes_nb; i++) {
280  int h = height;
281  int bwidth = av_image_get_linesize(pix_fmt, width, i);
282  if (bwidth < 0) {
283  av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n");
284  return;
285  }
286  if (i == 1 || i == 2) {
287  h= -((-height)>>desc->log2_chroma_h);
288  }
289  av_image_copy_plane(dst_data[i], dst_linesizes[i],
290  src_data[i], src_linesizes[i],
291  bwidth, h);
292  }
293  }
294 }
295 
296 int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
297  const uint8_t *src,
298  enum AVPixelFormat pix_fmt, int width, int height, int align)
299 {
300  int ret, i;
301 
302  if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
303  return ret;
304 
305  if ((ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width)) < 0)
306  return ret;
307 
308  for (i = 0; i < 4; i++)
309  dst_linesize[i] = FFALIGN(dst_linesize[i], align);
310 
311  if ((ret = av_image_fill_pointers(dst_data, pix_fmt, width, NULL, dst_linesize)) < 0)
312  return ret;
313 
314  return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);
315 }
316 
318 {
319  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
320  uint8_t *data[4];
321  int linesize[4];
322 
323  if (!desc)
324  return AVERROR(EINVAL);
325  if (av_image_check_size(width, height, 0, NULL) < 0)
326  return AVERROR(EINVAL);
327  if (desc->flags & PIX_FMT_PSEUDOPAL)
328  // do not include palette for these pseudo-paletted formats
329  return width * height;
330  return av_image_fill_arrays(data, linesize, NULL, pix_fmt, width, height, align);
331 }
332 
334  const uint8_t * const src_data[4], const int src_linesize[4],
335  enum AVPixelFormat pix_fmt, int width, int height, int align)
336 {
337  int i, j, nb_planes = 0, linesize[4];
338  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
339  int size = av_image_get_buffer_size(pix_fmt, width, height, align);
340 
341  if (size > dst_size || size < 0)
342  return AVERROR(EINVAL);
343 
344  for (i = 0; i < desc->nb_components; i++)
345  nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
346  nb_planes++;
347 
348  av_image_fill_linesizes(linesize, pix_fmt, width);
349  for (i = 0; i < nb_planes; i++) {
350  int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
351  const uint8_t *src = src_data[i];
352  h = (height + (1 << shift) - 1) >> shift;
353 
354  for (j = 0; j < h; j++) {
355  memcpy(dst, src, linesize[i]);
356  dst += FFALIGN(linesize[i], align);
357  src += src_linesize[i];
358  }
359  }
360 
361  if (desc->flags & PIX_FMT_PAL) {
362  uint32_t *d32 = (uint32_t *)(((size_t)dst + 3) & ~3);
363  for (i = 0; i<256; i++)
364  AV_WL32(d32 + i, AV_RN32(src_data[1] + 4*i));
365  }
366 
367  return size;
368 }
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:73
const char * s
Definition: avisynth_c.h:668
static int shift(int a, int b)
Definition: sonic.c:86
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
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:333
av_default_item_name
misc image utilities
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:190
static const AVClass imgutils_class
Definition: imgutils.c:229
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:296
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:66
output residual component w
#define FFALIGN(x, a)
Definition: common.h:63
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:89
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:32
#define AV_WL32(p, darg)
Definition: intreadwrite.h:282
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:86
uint8_t
#define b
Definition: input.c:42
void * log_ctx
Definition: imgutils.c:226
enum AVPixelFormat pix_fmt
Definition: v4l.c:63
#define U(x)
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:317
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:75
Spectrum Plot time data
const char * r
Definition: vf_curves.c:94
simple assert() macros that are a bit more flexible than ISO C assert().
#define PIX_FMT_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:90
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:150
#define FFMAX(a, b)
Definition: common.h:56
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:257
int size
struct ImgUtils ImgUtils
common internal API header
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:231
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:57
FFT buffer for g
Definition: stft_peak.m:17
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:92
ret
Definition: avfilter.c:821
#define PIX_FMT_BITSTREAM
All values of a component are bit-wise packed end to end.
Definition: pixdesc.h:91
static int image_get_linesize(int width, int plane, int max_step, int max_step_comp, const AVPixFmtDescriptor *desc)
Definition: imgutils.c:51
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
const AVS_VideoInfo int align
Definition: avisynth_c.h:695
int log_offset
Definition: imgutils.c:225
#define PIX_FMT_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:92
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:87
static int width
Definition: tests/utils.c:158
AVS_Value src
Definition: avisynth_c.h:523
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:108
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
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
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:73
Describe the class of an AVClass context structure.
Definition: log.h:50
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:86
synthesis window for stochastic i
uint16_t step_minus1
Number of elements between 2 horizontally consecutive pixels minus 1.
Definition: pixdesc.h:35
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
#define AV_RN32(p)
Definition: intreadwrite.h:356
uint16_t plane
which of the 4 planes contains the component
Definition: pixdesc.h:29
Y , 8bpp.
Definition: pixfmt.h:76
common internal and external API header
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:90
#define PIX_FMT_PSEUDOPAL
The pixel format is "pseudo-paletted".
Definition: pixdesc.h:100
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:237
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
Definition: eamad.c:71
const uint8_t * d32
Definition: yuv2rgb.c:486
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:242
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
for(j=16;j >0;--j)