Libav
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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
27 #include "avcodec.h"
28 #include "internal.h"
29 #include "mathops.h"
30 #include "libavutil/colorspace.h"
31 #include "libavutil/common.h"
32 #include "libavutil/pixdesc.h"
33 #include "libavutil/internal.h"
34 #include "libavutil/imgutils.h"
35 
36 #if FF_API_GETCHROMA
37 void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
38 {
40  *h_shift = desc->log2_chroma_w;
41  *v_shift = desc->log2_chroma_h;
42 }
43 #endif
44 
45 static int is_gray(const AVPixFmtDescriptor *desc)
46 {
47  return desc->nb_components - (desc->flags & AV_PIX_FMT_FLAG_ALPHA) == 1;
48 }
49 
51  enum AVPixelFormat src_pix_fmt,
52  int has_alpha)
53 {
54  const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
55  const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
56  int loss, i, nb_components = FFMIN(src_desc->nb_components,
57  dst_desc->nb_components);
58 
59  /* compute loss */
60  loss = 0;
61 
62  if (dst_pix_fmt == src_pix_fmt)
63  return 0;
64 
65  for (i = 0; i < nb_components; i++)
66  if (src_desc->comp[i].depth > dst_desc->comp[i].depth)
67  loss |= FF_LOSS_DEPTH;
68 
69  if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
70  dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
71  loss |= FF_LOSS_RESOLUTION;
72 
73  if ((src_desc->flags & AV_PIX_FMT_FLAG_RGB) != (dst_desc->flags & AV_PIX_FMT_FLAG_RGB))
74  loss |= FF_LOSS_COLORSPACE;
75 
76  if (has_alpha && !(dst_desc->flags & AV_PIX_FMT_FLAG_ALPHA) &&
77  (src_desc->flags & AV_PIX_FMT_FLAG_ALPHA))
78  loss |= FF_LOSS_ALPHA;
79 
80  if (dst_pix_fmt == AV_PIX_FMT_PAL8 && !is_gray(src_desc))
81  return loss | FF_LOSS_COLORQUANT;
82 
83  if (src_desc->nb_components > dst_desc->nb_components)
84  if (is_gray(dst_desc))
85  loss |= FF_LOSS_CHROMA;
86 
87  return loss;
88 }
89 
91  enum AVPixelFormat src_pix_fmt,
92  int has_alpha,
93  int loss_mask)
94 {
95  int dist, i, loss, min_dist;
96  enum AVPixelFormat dst_pix_fmt;
97 
98  /* find exact color match with smallest size */
99  dst_pix_fmt = AV_PIX_FMT_NONE;
100  min_dist = 0x7fffffff;
101  i = 0;
102  while (pix_fmt_list[i] != AV_PIX_FMT_NONE) {
103  enum AVPixelFormat pix_fmt = pix_fmt_list[i];
104 
105  if (i > AV_PIX_FMT_NB) {
106  av_log(NULL, AV_LOG_ERROR, "Pixel format list longer than expected, "
107  "it is either not properly terminated or contains duplicates\n");
108  return AV_PIX_FMT_NONE;
109  }
110 
111  loss = avcodec_get_pix_fmt_loss(pix_fmt, src_pix_fmt, has_alpha) & loss_mask;
112  if (loss == 0) {
114  if (dist < min_dist) {
115  min_dist = dist;
116  dst_pix_fmt = pix_fmt;
117  }
118  }
119  i++;
120  }
121  return dst_pix_fmt;
122 }
123 
125  enum AVPixelFormat src_pix_fmt,
126  int has_alpha, int *loss_ptr)
127 {
128  enum AVPixelFormat dst_pix_fmt;
129  int loss_mask, i;
130  static const int loss_mask_order[] = {
131  ~0, /* no loss first */
132  ~FF_LOSS_ALPHA,
136  ~FF_LOSS_DEPTH,
137  0,
138  };
139 
140  /* try with successive loss */
141  i = 0;
142  for(;;) {
143  loss_mask = loss_mask_order[i++];
144  dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_list, src_pix_fmt,
145  has_alpha, loss_mask);
146  if (dst_pix_fmt >= 0)
147  goto found;
148  if (loss_mask == 0)
149  break;
150  }
151  return AV_PIX_FMT_NONE;
152  found:
153  if (loss_ptr)
154  *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
155  return dst_pix_fmt;
156 }
157 
158 #if FF_API_AVPICTURE
160 /* return true if yuv planar */
161 static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
162 {
163  return (!(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
164  (desc->flags & AV_PIX_FMT_FLAG_PLANAR));
165 }
166 
168  enum AVPixelFormat pix_fmt, int top_band, int left_band)
169 {
170  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
171  int y_shift;
172  int x_shift;
173 
174  if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB || !is_yuv_planar(desc))
175  return -1;
176 
177  y_shift = desc->log2_chroma_h;
178  x_shift = desc->log2_chroma_w;
179 
180  dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
181  dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
182  dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
183 
184  dst->linesize[0] = src->linesize[0];
185  dst->linesize[1] = src->linesize[1];
186  dst->linesize[2] = src->linesize[2];
187  return 0;
188 }
189 
190 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
191  enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
192  int *color)
193 {
194  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
195  uint8_t *optr;
196  int y_shift;
197  int x_shift;
198  int yheight;
199  int i, y;
200 
201  if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB ||
202  !is_yuv_planar(desc)) return -1;
203 
204  for (i = 0; i < 3; i++) {
205  x_shift = i ? desc->log2_chroma_w : 0;
206  y_shift = i ? desc->log2_chroma_h : 0;
207 
208  if (padtop || padleft) {
209  memset(dst->data[i], color[i],
210  dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
211  }
212 
213  if (padleft || padright) {
214  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
215  (dst->linesize[i] - (padright >> x_shift));
216  yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
217  for (y = 0; y < yheight; y++) {
218  memset(optr, color[i], (padleft + padright) >> x_shift);
219  optr += dst->linesize[i];
220  }
221  }
222 
223  if (src) { /* first line */
224  uint8_t *iptr = src->data[i];
225  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
226  (padleft >> x_shift);
227  memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
228  iptr += src->linesize[i];
229  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
230  (dst->linesize[i] - (padright >> x_shift));
231  yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
232  for (y = 0; y < yheight; y++) {
233  memset(optr, color[i], (padleft + padright) >> x_shift);
234  memcpy(optr + ((padleft + padright) >> x_shift), iptr,
235  (width - padleft - padright) >> x_shift);
236  iptr += src->linesize[i];
237  optr += dst->linesize[i];
238  }
239  }
240 
241  if (padbottom || padright) {
242  optr = dst->data[i] + dst->linesize[i] *
243  ((height - padbottom) >> y_shift) - (padright >> x_shift);
244  memset(optr, color[i],dst->linesize[i] *
245  (padbottom >> y_shift) + (padright >> x_shift));
246  }
247  }
248  return 0;
249 }
250 
252 #endif /* FF_API_AVPICTURE */
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1768
#define FF_LOSS_COLORQUANT
loss due to color quantization
Definition: avcodec.h:4807
misc image utilities
const char * desc
Definition: nvenc.c:101
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:1740
int av_picture_crop(AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int top_band, int left_band)
Definition: imgconvert.c:167
static int is_gray(const AVPixFmtDescriptor *desc)
Definition: imgconvert.c:45
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)
Various defines for YUV<->RGB conversion.
void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Definition: imgconvert.c:37
four components are given, that&#39;s all.
Definition: avcodec.h:3390
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)
Definition: imgconvert.c:190
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:91
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:50
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:119
uint8_t
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:160
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:70
attribute_deprecated int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
Definition: avcodec.h:3394
#define src
Definition: vp8dsp.c:254
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:124
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:100
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:150
static FF_DISABLE_DEPRECATION_WARNINGS int is_yuv_planar(const AVPixFmtDescriptor *desc)
Definition: imgconvert.c:161
common internal API header
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:105
#define FF_LOSS_ALPHA
loss of alpha bits
Definition: avcodec.h:4806
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:82
#define FFMIN(a, b)
Definition: common.h:66
attribute_deprecated uint8_t * data[AV_NUM_DATA_POINTERS]
Definition: avcodec.h:3392
enum AVPixelFormat pix_fmt
Definition: movenc.c:853
static enum AVPixelFormat avcodec_find_best_pix_fmt1(enum AVPixelFormat *pix_fmt_list, enum AVPixelFormat src_pix_fmt, int has_alpha, int loss_mask)
Definition: imgconvert.c:90
NULL
Definition: eval.c:55
static int width
Definition: utils.c:156
Libavcodec external API header.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:80
#define FF_LOSS_CHROMA
loss of chroma (e.g.
Definition: avcodec.h:4808
#define FF_LOSS_DEPTH
loss due to color depth change
Definition: avcodec.h:4804
static const uint8_t color[NB_LEVELS]
Definition: log.c:62
#define FF_LOSS_COLORSPACE
loss due to color space conversion
Definition: avcodec.h:4805
int height
Definition: gxfenc.c:72
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:77
common internal api header.
common internal and external API header
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:78
#define FF_LOSS_RESOLUTION
loss due to resolution change
Definition: avcodec.h:4803
enum AVPixelFormat avcodec_find_best_pix_fmt2(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:124
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:233
int depth
Number of bits in the component.
Definition: pixdesc.h:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:57
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:146