summaryrefslogtreecommitdiff
path: root/libavcodec/pnmdec.c
diff options
context:
space:
mode:
authorLeo Izen <leo.izen@gmail.com>2022-11-16 06:43:06 -0500
committerJames Almer <jamrial@gmail.com>2022-12-27 10:41:25 -0300
commitcd9dd0300639689630171893b3dfb6c9ba63a692 (patch)
tree6bb3415330e46f9825f685781406f547efad7352 /libavcodec/pnmdec.c
parent64007595dcb5bb3c5f7bfa74d0b0f2e378f6007e (diff)
avcodec/pnm: avoid mirroring PFM images vertically
PFM (aka Portable FloatMap) encodes its scanlines from bottom-to-top, not from top-to-bottom, unlike other NetPBM formats. Without this patch, FFmpeg ignores this exception and decodes/encodes PFM images mirrored vertically from their proper orientation. For reference, see the NetPBM tool pfmtopam, which encodes a .pam from a .pfm, using the correct orientation (and which FFmpeg reads correctly). Also compare ffplay to magick display, which shows the correct orientation as well. See: http://www.pauldebevec.com/Research/HDR/PFM/ and see: https://netpbm.sourceforge.net/doc/pfm.html for descriptions of this image format. Signed-off-by: Leo Izen <leo.izen@gmail.com> Reviewed-by: Anton Khirnov <anton@khirnov.net> Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/pnmdec.c')
-rw-r--r--libavcodec/pnmdec.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index e95b4072eb..978e4c037e 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -346,6 +346,13 @@ static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p,
}
}
}
+ /* PFM is encoded from bottom to top */
+ p->data[0] += (avctx->height - 1) * p->linesize[0];
+ p->data[1] += (avctx->height - 1) * p->linesize[1];
+ p->data[2] += (avctx->height - 1) * p->linesize[2];
+ p->linesize[0] = -p->linesize[0];
+ p->linesize[1] = -p->linesize[1];
+ p->linesize[2] = -p->linesize[2];
break;
case AV_PIX_FMT_GRAYF32:
if (!s->half) {
@@ -395,6 +402,9 @@ static int pnm_decode_frame(AVCodecContext *avctx, AVFrame *p,
}
}
}
+ /* PFM is encoded from bottom to top */
+ p->data[0] += (avctx->height - 1) * p->linesize[0];
+ p->linesize[0] = -p->linesize[0];
break;
}
*got_frame = 1;