imgconvert.c
Go to the documentation of this file.
1 /*
2  * Misc image conversion routines
3  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * misc image conversion routines
25  */
26 
27 /* TODO:
28  * - write 'ffimg' program to test all the image related stuff
29  * - move all api to slice based system
30  * - integrate deinterlacing, postprocessing and scaling in the conversion process
31  */
32 
33 #include "avcodec.h"
34 #include "dsputil.h"
35 #include "imgconvert.h"
36 #include "internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/colorspace.h"
39 #include "libavutil/common.h"
40 #include "libavutil/pixdesc.h"
41 #include "libavutil/imgutils.h"
42 
43 #if HAVE_MMX_EXTERNAL
44 #include "x86/dsputil_mmx.h"
45 #endif
46 
47 #define FF_COLOR_NA -1
48 #define FF_COLOR_RGB 0 /**< RGB color space */
49 #define FF_COLOR_GRAY 1 /**< gray color space */
50 #define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
51 #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
52 
53 #if HAVE_MMX_EXTERNAL
54 #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
55 #define deinterlace_line ff_deinterlace_line_mmx
56 #else
57 #define deinterlace_line_inplace deinterlace_line_inplace_c
58 #define deinterlace_line deinterlace_line_c
59 #endif
60 
61 #define pixdesc_has_alpha(pixdesc) \
62  ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & PIX_FMT_PAL)
63 
64 
65 void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
66 {
67  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
68  av_assert0(desc);
69  *h_shift = desc->log2_chroma_w;
70  *v_shift = desc->log2_chroma_h;
71 }
72 
73 static int get_color_type(const AVPixFmtDescriptor *desc) {
74  if(desc->nb_components == 1 || desc->nb_components == 2)
75  return FF_COLOR_GRAY;
76 
77  if(desc->name && !strncmp(desc->name, "yuvj", 4))
78  return FF_COLOR_YUV_JPEG;
79 
80  if(desc->flags & PIX_FMT_RGB)
81  return FF_COLOR_RGB;
82 
83  if(desc->nb_components == 0)
84  return FF_COLOR_NA;
85 
86  return FF_COLOR_YUV;
87 }
88 
89 static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt)
90 {
91  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
92  int i;
93 
94  if (!desc || !desc->nb_components) {
95  *min = *max = 0;
96  return AVERROR(EINVAL);
97  }
98 
99  *min = INT_MAX, *max = -INT_MAX;
100  for (i = 0; i < desc->nb_components; i++) {
101  *min = FFMIN(desc->comp[i].depth_minus1+1, *min);
102  *max = FFMAX(desc->comp[i].depth_minus1+1, *max);
103  }
104  return 0;
105 }
106 
107 static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt,
108  enum AVPixelFormat src_pix_fmt,
109  unsigned *lossp, unsigned consider)
110 {
111  const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
112  const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
113  int src_color, dst_color;
114  int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
115  int ret, loss, i, nb_components;
116  int score = INT_MAX;
117 
118  if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
119  return ~0;
120 
121  /* compute loss */
122  *lossp = loss = 0;
123 
124  if (dst_pix_fmt == src_pix_fmt)
125  return INT_MAX;
126 
127  if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
128  return ret;
129  if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0)
130  return ret;
131 
132  src_color = get_color_type(src_desc);
133  dst_color = get_color_type(dst_desc);
134  nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components);
135 
136  for (i = 0; i < nb_components; i++)
137  if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1 && (consider & FF_LOSS_DEPTH)) {
138  loss |= FF_LOSS_DEPTH;
139  score -= 65536 >> dst_desc->comp[i].depth_minus1;
140  }
141 
142  if (consider & FF_LOSS_RESOLUTION) {
143  if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w) {
144  loss |= FF_LOSS_RESOLUTION;
145  score -= 256 << dst_desc->log2_chroma_w;
146  }
147  if (dst_desc->log2_chroma_h > src_desc->log2_chroma_h) {
148  loss |= FF_LOSS_RESOLUTION;
149  score -= 256 << dst_desc->log2_chroma_h;
150  }
151  // dont favor 422 over 420 if downsampling is needed, because 420 has much better support on the decoder side
152  if (dst_desc->log2_chroma_w == 1 && src_desc->log2_chroma_w == 0 &&
153  dst_desc->log2_chroma_h == 1 && src_desc->log2_chroma_h == 0 ) {
154  score += 512;
155  }
156  }
157 
158  if(consider & FF_LOSS_COLORSPACE)
159  switch(dst_color) {
160  case FF_COLOR_RGB:
161  if (src_color != FF_COLOR_RGB &&
162  src_color != FF_COLOR_GRAY)
163  loss |= FF_LOSS_COLORSPACE;
164  break;
165  case FF_COLOR_GRAY:
166  if (src_color != FF_COLOR_GRAY)
167  loss |= FF_LOSS_COLORSPACE;
168  break;
169  case FF_COLOR_YUV:
170  if (src_color != FF_COLOR_YUV)
171  loss |= FF_LOSS_COLORSPACE;
172  break;
173  case FF_COLOR_YUV_JPEG:
174  if (src_color != FF_COLOR_YUV_JPEG &&
175  src_color != FF_COLOR_YUV &&
176  src_color != FF_COLOR_GRAY)
177  loss |= FF_LOSS_COLORSPACE;
178  break;
179  default:
180  /* fail safe test */
181  if (src_color != dst_color)
182  loss |= FF_LOSS_COLORSPACE;
183  break;
184  }
185  if(loss & FF_LOSS_COLORSPACE)
186  score -= (nb_components * 65536) >> FFMIN(dst_desc->comp[0].depth_minus1, src_desc->comp[0].depth_minus1);
187 
188  if (dst_color == FF_COLOR_GRAY &&
189  src_color != FF_COLOR_GRAY && (consider & FF_LOSS_CHROMA)) {
190  loss |= FF_LOSS_CHROMA;
191  score -= 2 * 65536;
192  }
193  if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))) {
194  loss |= FF_LOSS_ALPHA;
195  score -= 65536;
196  }
197  if (dst_pix_fmt == AV_PIX_FMT_PAL8 && (consider & FF_LOSS_COLORQUANT) &&
198  (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && (consider & FF_LOSS_ALPHA))))) {
199  loss |= FF_LOSS_COLORQUANT;
200  score -= 65536;
201  }
202 
203  *lossp = loss;
204  return score;
205 }
206 
208  enum AVPixelFormat src_pix_fmt,
209  int has_alpha)
210 {
211  int loss;
212  int ret = get_pix_fmt_score(dst_pix_fmt, src_pix_fmt, &loss, has_alpha ? ~0 : ~FF_LOSS_ALPHA);
213  if (ret < 0)
214  return ret;
215  return loss;
216 }
217 
219  enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
220 {
221  enum AVPixelFormat dst_pix_fmt;
222  int loss1, loss2, loss_mask;
223  const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1);
224  const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2);
225  int score1, score2;
226 
227  loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */
228  if(!has_alpha)
229  loss_mask &= ~FF_LOSS_ALPHA;
230 
231  dst_pix_fmt = AV_PIX_FMT_NONE;
232  score1 = get_pix_fmt_score(dst_pix_fmt1, src_pix_fmt, &loss1, loss_mask);
233  score2 = get_pix_fmt_score(dst_pix_fmt2, src_pix_fmt, &loss2, loss_mask);
234 
235  if (score1 == score2) {
237  dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1;
238  } else {
239  dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1;
240  }
241  } else {
242  dst_pix_fmt = score1 < score2 ? dst_pix_fmt2 : dst_pix_fmt1;
243  }
244 
245  if (loss_ptr)
246  *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
247  return dst_pix_fmt;
248 }
249 
250 #if AV_HAVE_INCOMPATIBLE_FORK_ABI
252  enum AVPixelFormat src_pix_fmt,
253  int has_alpha, int *loss_ptr){
254  return avcodec_find_best_pix_fmt_of_list(pix_fmt_list, src_pix_fmt, has_alpha, loss_ptr);
255 }
256 #else
257 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
258  enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
259 {
260  return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
261 }
262 #endif
263 
265  enum AVPixelFormat src_pix_fmt,
266  int has_alpha, int *loss_ptr){
267  int i;
268 
269  enum AVPixelFormat best = AV_PIX_FMT_NONE;
270 
271  for(i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++)
272  best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, loss_ptr);
273 
274  return best;
275 }
276 
277 /* 2x2 -> 1x1 */
278 void ff_shrink22(uint8_t *dst, int dst_wrap,
279  const uint8_t *src, int src_wrap,
280  int width, int height)
281 {
282  int w;
283  const uint8_t *s1, *s2;
284  uint8_t *d;
285 
286  for(;height > 0; height--) {
287  s1 = src;
288  s2 = s1 + src_wrap;
289  d = dst;
290  for(w = width;w >= 4; w-=4) {
291  d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
292  d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
293  d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
294  d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
295  s1 += 8;
296  s2 += 8;
297  d += 4;
298  }
299  for(;w > 0; w--) {
300  d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
301  s1 += 2;
302  s2 += 2;
303  d++;
304  }
305  src += 2 * src_wrap;
306  dst += dst_wrap;
307  }
308 }
309 
310 /* 4x4 -> 1x1 */
311 void ff_shrink44(uint8_t *dst, int dst_wrap,
312  const uint8_t *src, int src_wrap,
313  int width, int height)
314 {
315  int w;
316  const uint8_t *s1, *s2, *s3, *s4;
317  uint8_t *d;
318 
319  for(;height > 0; height--) {
320  s1 = src;
321  s2 = s1 + src_wrap;
322  s3 = s2 + src_wrap;
323  s4 = s3 + src_wrap;
324  d = dst;
325  for(w = width;w > 0; w--) {
326  d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
327  s2[0] + s2[1] + s2[2] + s2[3] +
328  s3[0] + s3[1] + s3[2] + s3[3] +
329  s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
330  s1 += 4;
331  s2 += 4;
332  s3 += 4;
333  s4 += 4;
334  d++;
335  }
336  src += 4 * src_wrap;
337  dst += dst_wrap;
338  }
339 }
340 
341 /* 8x8 -> 1x1 */
342 void ff_shrink88(uint8_t *dst, int dst_wrap,
343  const uint8_t *src, int src_wrap,
344  int width, int height)
345 {
346  int w, i;
347 
348  for(;height > 0; height--) {
349  for(w = width;w > 0; w--) {
350  int tmp=0;
351  for(i=0; i<8; i++){
352  tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
353  src += src_wrap;
354  }
355  *(dst++) = (tmp + 32)>>6;
356  src += 8 - 8*src_wrap;
357  }
358  src += 8*src_wrap - 8*width;
359  dst += dst_wrap - width;
360  }
361 }
362 
363 /* return true if yuv planar */
364 static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
365 {
366  int i;
367  int planes[4] = { 0 };
368 
369  if ( desc->flags & PIX_FMT_RGB
370  || !(desc->flags & PIX_FMT_PLANAR))
371  return 0;
372 
373  /* set the used planes */
374  for (i = 0; i < desc->nb_components; i++)
375  planes[desc->comp[i].plane] = 1;
376 
377  /* if there is an unused plane, the format is not planar */
378  for (i = 0; i < desc->nb_components; i++)
379  if (!planes[i])
380  return 0;
381  return 1;
382 }
383 
385  enum AVPixelFormat pix_fmt, int top_band, int left_band)
386 {
387  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
388  int y_shift;
389  int x_shift;
390 
391  if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
392  return -1;
393 
394  y_shift = desc->log2_chroma_h;
395  x_shift = desc->log2_chroma_w;
396 
397  if (is_yuv_planar(desc)) {
398  dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
399  dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
400  dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
401  } else{
402  if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
403  return -1;
404  if(left_band) //FIXME add support for this too
405  return -1;
406  dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
407  }
408 
409  dst->linesize[0] = src->linesize[0];
410  dst->linesize[1] = src->linesize[1];
411  dst->linesize[2] = src->linesize[2];
412  return 0;
413 }
414 
416  enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
417  int *color)
418 {
419  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
420  uint8_t *optr;
421  int y_shift;
422  int x_shift;
423  int yheight;
424  int i, y;
425 
426  if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB ||
427  !is_yuv_planar(desc)) return -1;
428 
429  for (i = 0; i < 3; i++) {
430  x_shift = i ? desc->log2_chroma_w : 0;
431  y_shift = i ? desc->log2_chroma_h : 0;
432 
433  if (padtop || padleft) {
434  memset(dst->data[i], color[i],
435  dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
436  }
437 
438  if (padleft || padright) {
439  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
440  (dst->linesize[i] - (padright >> x_shift));
441  yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
442  for (y = 0; y < yheight; y++) {
443  memset(optr, color[i], (padleft + padright) >> x_shift);
444  optr += dst->linesize[i];
445  }
446  }
447 
448  if (src) { /* first line */
449  uint8_t *iptr = src->data[i];
450  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
451  (padleft >> x_shift);
452  memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
453  iptr += src->linesize[i];
454  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
455  (dst->linesize[i] - (padright >> x_shift));
456  yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
457  for (y = 0; y < yheight; y++) {
458  memset(optr, color[i], (padleft + padright) >> x_shift);
459  memcpy(optr + ((padleft + padright) >> x_shift), iptr,
460  (width - padleft - padright) >> x_shift);
461  iptr += src->linesize[i];
462  optr += dst->linesize[i];
463  }
464  }
465 
466  if (padbottom || padright) {
467  optr = dst->data[i] + dst->linesize[i] *
468  ((height - padbottom) >> y_shift) - (padright >> x_shift);
469  memset(optr, color[i],dst->linesize[i] *
470  (padbottom >> y_shift) + (padright >> x_shift));
471  }
472  }
473  return 0;
474 }
475 
476 #if FF_API_DEINTERLACE
477 
478 #if !HAVE_MMX_EXTERNAL
479 /* filter parameters: [-1 4 2 4 -1] // 8 */
480 static void deinterlace_line_c(uint8_t *dst,
481  const uint8_t *lum_m4, const uint8_t *lum_m3,
482  const uint8_t *lum_m2, const uint8_t *lum_m1,
483  const uint8_t *lum,
484  int size)
485 {
486  const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
487  int sum;
488 
489  for(;size > 0;size--) {
490  sum = -lum_m4[0];
491  sum += lum_m3[0] << 2;
492  sum += lum_m2[0] << 1;
493  sum += lum_m1[0] << 2;
494  sum += -lum[0];
495  dst[0] = cm[(sum + 4) >> 3];
496  lum_m4++;
497  lum_m3++;
498  lum_m2++;
499  lum_m1++;
500  lum++;
501  dst++;
502  }
503 }
504 
505 static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
506  uint8_t *lum_m2, uint8_t *lum_m1,
507  uint8_t *lum, int size)
508 {
509  const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
510  int sum;
511 
512  for(;size > 0;size--) {
513  sum = -lum_m4[0];
514  sum += lum_m3[0] << 2;
515  sum += lum_m2[0] << 1;
516  lum_m4[0]=lum_m2[0];
517  sum += lum_m1[0] << 2;
518  sum += -lum[0];
519  lum_m2[0] = cm[(sum + 4) >> 3];
520  lum_m4++;
521  lum_m3++;
522  lum_m2++;
523  lum_m1++;
524  lum++;
525  }
526 }
527 #endif /* !HAVE_MMX_EXTERNAL */
528 
529 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
530  top field is copied as is, but the bottom field is deinterlaced
531  against the top field. */
532 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
533  const uint8_t *src1, int src_wrap,
534  int width, int height)
535 {
536  const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
537  int y;
538 
539  src_m2 = src1;
540  src_m1 = src1;
541  src_0=&src_m1[src_wrap];
542  src_p1=&src_0[src_wrap];
543  src_p2=&src_p1[src_wrap];
544  for(y=0;y<(height-2);y+=2) {
545  memcpy(dst,src_m1,width);
546  dst += dst_wrap;
547  deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
548  src_m2 = src_0;
549  src_m1 = src_p1;
550  src_0 = src_p2;
551  src_p1 += 2*src_wrap;
552  src_p2 += 2*src_wrap;
553  dst += dst_wrap;
554  }
555  memcpy(dst,src_m1,width);
556  dst += dst_wrap;
557  /* do last line */
558  deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
559 }
560 
561 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
562  int width, int height)
563 {
564  uint8_t *src_m1, *src_0, *src_p1, *src_p2;
565  int y;
566  uint8_t *buf;
567  buf = av_malloc(width);
568 
569  src_m1 = src1;
570  memcpy(buf,src_m1,width);
571  src_0=&src_m1[src_wrap];
572  src_p1=&src_0[src_wrap];
573  src_p2=&src_p1[src_wrap];
574  for(y=0;y<(height-2);y+=2) {
575  deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
576  src_m1 = src_p1;
577  src_0 = src_p2;
578  src_p1 += 2*src_wrap;
579  src_p2 += 2*src_wrap;
580  }
581  /* do last line */
582  deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
583  av_free(buf);
584 }
585 
586 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
587  enum AVPixelFormat pix_fmt, int width, int height)
588 {
589  int i;
590 
591  if (pix_fmt != AV_PIX_FMT_YUV420P &&
598  return -1;
599  if ((width & 3) != 0 || (height & 3) != 0)
600  return -1;
601 
602  for(i=0;i<3;i++) {
603  if (i == 1) {
604  switch(pix_fmt) {
605  case AV_PIX_FMT_YUVJ420P:
606  case AV_PIX_FMT_YUV420P:
607  width >>= 1;
608  height >>= 1;
609  break;
610  case AV_PIX_FMT_YUV422P:
611  case AV_PIX_FMT_YUVJ422P:
612  width >>= 1;
613  break;
614  case AV_PIX_FMT_YUV411P:
615  width >>= 2;
616  break;
617  default:
618  break;
619  }
620  if (pix_fmt == AV_PIX_FMT_GRAY8) {
621  break;
622  }
623  }
624  if (src == dst) {
625  deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
626  width, height);
627  } else {
628  deinterlace_bottom_field(dst->data[i],dst->linesize[i],
629  src->data[i], src->linesize[i],
630  width, height);
631  }
632  }
633  emms_c();
634  return 0;
635 }
636 
637 #endif /* FF_API_DEINTERLACE */
638 
639 #ifdef TEST
640 
641 int main(void){
642  int i;
643  int err=0;
644  int skip = 0;
645 
646  for (i=0; i<AV_PIX_FMT_NB*2; i++) {
648  if(!desc || !desc->name) {
649  skip ++;
650  continue;
651  }
652  if (skip) {
653  av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
654  skip = 0;
655  }
656  av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d colortype:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc), get_color_type(desc));
657  if ((!(desc->flags & PIX_FMT_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
658  av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
659  err = 1;
660  }
661  }
662  return err;
663 }
664 
665 #endif
static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt)
Definition: imgconvert.c:89
#define ff_cropTbl
int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
#define deinterlace_line_inplace
Definition: imgconvert.c:57
#define FF_LOSS_COLORQUANT
loss due to color quantization
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:73
misc image utilities
static int is_yuv_planar(const AVPixFmtDescriptor *desc)
Definition: imgconvert.c:364
if max(w)>1 w=0.9 *w/max(w)
#define MAX_NEG_CROP
Definition: dsputil.h:47
Various defines for YUV<->RGB conversion.
int av_picture_crop(AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int top_band, int left_band)
Crop image top and left side.
Definition: imgconvert.c:384
static int get_pix_fmt_score(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, unsigned *lossp, unsigned consider)
Definition: imgconvert.c:107
four components are given, that&#39;s all.
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
int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, int has_alpha)
Compute what kind of losses will occur when converting from one specific pixel format to another...
Definition: imgconvert.c:207
set threshold d
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define FF_COLOR_YUV_JPEG
YUV color space.
Definition: imgconvert.c:51
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:86
uint8_t
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:77
uint8_t * data[AV_NUM_DATA_POINTERS]
#define emms_c()
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_...
Definition: pixfmt.h:81
enum AVPixelFormat pix_fmt
Definition: v4l.c:63
void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height)
Definition: imgconvert.c:311
#define cm
Definition: dvbsubdec.c:34
const char * name
Definition: pixdesc.h:56
uint16_t depth_minus1
number of bits in the component minus 1
Definition: pixdesc.h:43
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
#define s2
Definition: regdef.h:39
int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel for the pixel format described by pixdesc, including any padding ...
Definition: pixdesc.c:1744
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
#define FFMAX(a, b)
Definition: common.h:56
external API header
int size
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:72
#define FF_LOSS_ALPHA
loss of alpha bits
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:57
void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height)
Definition: imgconvert.c:342
void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height)
Definition: imgconvert.c:278
#define FFMIN(a, b)
Definition: common.h:58
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_...
Definition: pixfmt.h:80
ret
Definition: avfilter.c:821
#define deinterlace_line
Definition: imgconvert.c:58
#define s4
Definition: regdef.h:41
void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: imgconvert.c:65
#define s3
Definition: regdef.h:40
#define pixdesc_has_alpha(pixdesc)
Definition: imgconvert.c:61
enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
Find the best pixel format to convert to given a certain source pixel format and a selection of two d...
Definition: imgconvert.c:218
enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
Definition: imgconvert.c:257
NULL
Definition: eval.c:55
static int width
Definition: tests/utils.c:158
AVS_Value src
Definition: avisynth_c.h:523
#define PIX_FMT_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:93
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 FF_COLOR_RGB
RGB color space.
Definition: imgconvert.c:48
#define FF_LOSS_CHROMA
loss of chroma (e.g.
#define FF_LOSS_DEPTH
loss due to color depth change
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
Find the best pixel format to convert to given a certain source pixel format.
Definition: imgconvert.c:264
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
static int get_color_type(const AVPixFmtDescriptor *desc)
Definition: imgconvert.c:73
synthesis window for stochastic i
#define s1
Definition: regdef.h:38
#define FF_LOSS_COLORSPACE
loss due to color space conversion
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 PIX_FMT_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale)
Definition: pixdesc.h:94
static double lum(void *priv, double x, double y)
Definition: vf_geq.c:83
uint16_t plane
which of the 4 planes contains the component
Definition: pixdesc.h:29
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
Y , 8bpp.
Definition: pixfmt.h:76
common internal api header.
common internal and external API header
#define FF_COLOR_GRAY
gray color space
Definition: imgconvert.c:49
#define PIX_FMT_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:102
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:75
function y
Definition: D.m:1
DSP utils.
int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright, int *color)
Pad image.
Definition: imgconvert.c:415
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
#define FF_COLOR_YUV
YUV color space.
Definition: imgconvert.c:50
#define FF_LOSS_RESOLUTION
loss due to resolution change
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:237
#define AV_LOG_INFO
Definition: log.h:156
int main(int argc, char **argv)
Definition: main.c:22
float min
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
#define FF_COLOR_NA
Definition: imgconvert.c:47
for(j=16;j >0;--j)