summaryrefslogtreecommitdiff
path: root/libavcodec/imgconvert.c
diff options
context:
space:
mode:
authorStefano Sabatini <stefano.sabatini-lala@poste.it>2011-07-24 15:38:59 +0200
committerStefano Sabatini <stefano.sabatini-lala@poste.it>2011-07-27 01:52:09 +0200
commite324619ca9294458892b29dfdbdcce9cb65363a7 (patch)
treea848b68424ac4084f889e9a00a8e57d044511a4a /libavcodec/imgconvert.c
parent07f49ca1d1027f57400acbf7ca1aada9a1812648 (diff)
imgconvert: change logic in avcodec_get_pix_fmt_loss()
Avoid the use of the brittle/inconsistent information in PixFmtInfo.depth, and implement a possibly more robust logic which exposes the information in pixdesc. Also allow the removal of PixFmtInfo.depth, since this is the only use of it.
Diffstat (limited to 'libavcodec/imgconvert.c')
-rw-r--r--libavcodec/imgconvert.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index fbe8141336..c48478cafc 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -393,28 +393,50 @@ int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
}
+static int get_pix_fmt_depth(int *min, int *max, enum PixelFormat pix_fmt)
+{
+ const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
+ int i;
+
+ if (!desc->nb_components) {
+ *min = *max = 0;
+ return AVERROR(EINVAL);
+ }
+
+ *min = INT_MAX, *max = -INT_MAX;
+ for (i = 0; i < desc->nb_components; i++) {
+ *min = FFMIN(desc->comp[i].depth_minus1+1, *min);
+ *max = FFMAX(desc->comp[i].depth_minus1+1, *max);
+ }
+ return 0;
+}
+
int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
int has_alpha)
{
const PixFmtInfo *pf, *ps;
const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
- int loss;
+ int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
+ int ret, loss;
ps = &pix_fmt_info[src_pix_fmt];
/* compute loss */
loss = 0;
- pf = &pix_fmt_info[dst_pix_fmt];
- if (pf->depth < ps->depth ||
- ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
- dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
- (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
- src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
+
+ if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
+ return ret;
+ if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0)
+ return ret;
+ if (dst_min_depth < src_min_depth ||
+ dst_max_depth < src_max_depth)
loss |= FF_LOSS_DEPTH;
if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
loss |= FF_LOSS_RESOLUTION;
+
+ pf = &pix_fmt_info[dst_pix_fmt];
switch(pf->color_type) {
case FF_COLOR_RGB:
if (ps->color_type != FF_COLOR_RGB &&