FFmpeg
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 #include "avcodec.h"
28 #include "internal.h"
29 #include "mathops.h"
30 #include "libavutil/avassert.h"
31 #include "libavutil/colorspace.h"
32 #include "libavutil/common.h"
33 #include "libavutil/pixdesc.h"
34 #include "libavutil/internal.h"
35 #include "libavutil/imgutils.h"
36 
37 #if FF_API_GETCHROMA
38 void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
39 {
42  *h_shift = desc->log2_chroma_w;
43  *v_shift = desc->log2_chroma_h;
44 }
45 #endif
46 
47 #if FF_API_AVCODEC_PIX_FMT
49  enum AVPixelFormat src_pix_fmt,
50  int has_alpha)
51 {
52  return av_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
53 }
54 
55 enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
56  enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
57 {
58  return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
59 }
60 
61 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
62  enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
63 {
64  return av_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
65 }
66 
67 #endif
69  enum AVPixelFormat src_pix_fmt,
70  int has_alpha, int *loss_ptr){
71  int i;
72 
73  enum AVPixelFormat best = AV_PIX_FMT_NONE;
74  int loss;
75 
76  for (i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++) {
77  loss = loss_ptr ? *loss_ptr : 0;
78  best = av_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, &loss);
79  }
80 
81  if (loss_ptr)
82  *loss_ptr = loss;
83  return best;
84 }
85 
86 #if FF_API_AVPICTURE
88 /* return true if yuv planar */
89 static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
90 {
91  int i;
92  int planes[4] = { 0 };
93 
94  if ( desc->flags & AV_PIX_FMT_FLAG_RGB
95  || !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))
96  return 0;
97 
98  /* set the used planes */
99  for (i = 0; i < desc->nb_components; i++)
100  planes[desc->comp[i].plane] = 1;
101 
102  /* if there is an unused plane, the format is not planar */
103  for (i = 0; i < desc->nb_components; i++)
104  if (!planes[i])
105  return 0;
106  return 1;
107 }
108 
110  enum AVPixelFormat pix_fmt, int top_band, int left_band)
111 {
113  int y_shift;
114  int x_shift;
115  int max_step[4];
116 
117  if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
118  return -1;
119 
120  y_shift = desc->log2_chroma_h;
121  x_shift = desc->log2_chroma_w;
123 
124  if (is_yuv_planar(desc)) {
125  dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
126  dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
127  dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
128  } else{
129  if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
130  return -1;
131  dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + (left_band * max_step[0]);
132  }
133 
134  dst->linesize[0] = src->linesize[0];
135  dst->linesize[1] = src->linesize[1];
136  dst->linesize[2] = src->linesize[2];
137  return 0;
138 }
139 
140 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
141  enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
142  int *color)
143 {
145  uint8_t *optr;
146  int y_shift;
147  int x_shift;
148  int yheight;
149  int i, y;
150  int max_step[4];
151 
152  if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
153  return -1;
154 
155  if (!is_yuv_planar(desc)) {
156  if (src)
157  return -1; //TODO: Not yet implemented
158 
160 
161  if (padtop || padleft) {
162  memset(dst->data[0], color[0],
163  dst->linesize[0] * padtop + (padleft * max_step[0]));
164  }
165 
166  if (padleft || padright) {
167  optr = dst->data[0] + dst->linesize[0] * padtop +
168  (dst->linesize[0] - (padright * max_step[0]));
169  yheight = height - 1 - (padtop + padbottom);
170  for (y = 0; y < yheight; y++) {
171  memset(optr, color[0], (padleft + padright) * max_step[0]);
172  optr += dst->linesize[0];
173  }
174  }
175 
176  if (padbottom || padright) {
177  optr = dst->data[0] + dst->linesize[0] * (height - padbottom) -
178  (padright * max_step[0]);
179  memset(optr, color[0], dst->linesize[0] * padbottom +
180  (padright * max_step[0]));
181  }
182 
183  return 0;
184  }
185 
186  for (i = 0; i < 3; i++) {
187  x_shift = i ? desc->log2_chroma_w : 0;
188  y_shift = i ? desc->log2_chroma_h : 0;
189 
190  if (padtop || padleft) {
191  memset(dst->data[i], color[i],
192  dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
193  }
194 
195  if (padleft || padright) {
196  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
197  (dst->linesize[i] - (padright >> x_shift));
198  yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
199  for (y = 0; y < yheight; y++) {
200  memset(optr, color[i], (padleft + padright) >> x_shift);
201  optr += dst->linesize[i];
202  }
203  }
204 
205  if (src) { /* first line */
206  uint8_t *iptr = src->data[i];
207  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
208  (padleft >> x_shift);
209  memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
210  iptr += src->linesize[i];
211  optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
212  (dst->linesize[i] - (padright >> x_shift));
213  yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
214  for (y = 0; y < yheight; y++) {
215  memset(optr, color[i], (padleft + padright) >> x_shift);
216  memcpy(optr + ((padleft + padright) >> x_shift), iptr,
217  (width - padleft - padright) >> x_shift);
218  iptr += src->linesize[i];
219  optr += dst->linesize[i];
220  }
221  }
222 
223  if (padbottom || padright) {
224  optr = dst->data[i] + dst->linesize[i] *
225  ((height - padbottom) >> y_shift) - (padright >> x_shift);
226  memset(optr, color[i],dst->linesize[i] *
227  (padbottom >> y_shift) + (padright >> x_shift));
228  }
229  }
230 
231  return 0;
232 }
234 #endif /* FF_API_AVPICTURE */
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
is_yuv_planar
static FF_DISABLE_DEPRECATION_WARNINGS int is_yuv_planar(const AVPixFmtDescriptor *desc)
Definition: imgconvert.c:89
color
Definition: vf_paletteuse.c:583
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
pixdesc.h
internal.h
avcodec_find_best_pix_fmt_of_list
enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const 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:68
AVPicture::data
attribute_deprecated uint8_t * data[AV_NUM_DATA_POINTERS]
pointers to the image data planes
Definition: avcodec.h:2657
AV_PIX_FMT_NB
@ AV_PIX_FMT_NB
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:363
avassert.h
colorspace.h
width
#define width
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVPicture
Picture data structure.
Definition: avcodec.h:2655
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:40
NULL
#define NULL
Definition: coverity.c:32
avcodec_find_best_pix_fmt_of_2
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)
Definition: imgconvert.c:55
src
#define src
Definition: vp8dsp.c:255
mathops.h
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
av_get_pix_fmt_loss
int av_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: pixdesc.c:2853
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
avcodec_find_best_pix_fmt2
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:61
height
#define height
av_picture_pad
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:140
av_picture_crop
int av_picture_crop(AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int top_band, int left_band)
Definition: imgconvert.c:109
i
int i
Definition: input.c:407
internal.h
common.h
uint8_t
uint8_t
Definition: audio_convert.c:194
avcodec.h
avcodec_get_chroma_sub_sample
void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Definition: imgconvert.c:38
av_find_best_pix_fmt_of_2
enum AVPixelFormat av_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)
Compute what kind of losses will occur when converting from one specific pixel format to another.
Definition: pixdesc.c:2864
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_PIX_FMT_FLAG_PLANAR
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:144
av_image_fill_max_pixsteps
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:35
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
planes
static const struct @322 planes[]
desc
const char * desc
Definition: libsvtav1.c:79
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
AVPicture::linesize
attribute_deprecated int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
Definition: avcodec.h:2659
imgutils.h
avcodec_get_pix_fmt_loss
int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt, int has_alpha)
Definition: imgconvert.c:48