summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRudolf Polzer <divverent@xonotic.org>2012-10-24 19:05:49 +0200
committerwm4 <wm4@nowhere>2012-10-24 21:56:15 +0200
commit1282f9d79e09160af67ec13c05c0eed1ae02bd46 (patch)
treedcba92d684a8d689eecc5ba0592e0f5b56bc341b
parent64ac38c4d30e30783032a4b65f34f4fb50761c7b (diff)
downloadmpv-1282f9d79e09160af67ec13c05c0eed1ae02bd46.tar.bz2
mpv-1282f9d79e09160af67ec13c05c0eed1ae02bd46.tar.xz
mp_image: fix copy_mpi() with 16 bit formats, add helper macros
Merged by wm4. copy_mpi() assumed that planar YUV formats always used 1 byte per component, which is not true for 9/10/16 bit YUV formats.
-rw-r--r--libmpcodecs/mp_image.c12
-rw-r--r--libmpcodecs/mp_image.h10
2 files changed, 17 insertions, 5 deletions
diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c
index 006b0bf4f3..28472d092c 100644
--- a/libmpcodecs/mp_image.c
+++ b/libmpcodecs/mp_image.c
@@ -40,7 +40,9 @@ void mp_image_alloc_planes(mp_image_t *mpi) {
if (!mpi->planes[0])
abort(); //out of memory
if (mpi->flags&MP_IMGFLAG_PLANAR) {
- int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
+ // FIXME this code only supports same bpp for all planes, and bpp divisible
+ // by 8. Currently the case for all planar formats.
+ int bpp = MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, 0) / 8;
// YV12/I420/YVU9/IF09. feel free to add other planar formats here...
mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
if(mpi->num_planes > 2){
@@ -82,15 +84,15 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
if(mpi->flags&MP_IMGFLAG_PLANAR){
- memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h,
+ memcpy_pic(dmpi->planes[0],mpi->planes[0], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 0), mpi->h,
dmpi->stride[0],mpi->stride[0]);
- memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
+ memcpy_pic(dmpi->planes[1],mpi->planes[1], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 1), mpi->chroma_height,
dmpi->stride[1],mpi->stride[1]);
- memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
+ memcpy_pic(dmpi->planes[2], mpi->planes[2], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 2), mpi->chroma_height,
dmpi->stride[2],mpi->stride[2]);
} else {
memcpy_pic(dmpi->planes[0],mpi->planes[0],
- mpi->w*(dmpi->bpp/8), mpi->h,
+ MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 0), mpi->h,
dmpi->stride[0],mpi->stride[0]);
}
}
diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h
index 6dbe3bfe02..e1cbe7d2cf 100644
--- a/libmpcodecs/mp_image.h
+++ b/libmpcodecs/mp_image.h
@@ -130,4 +130,14 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt);
void mp_image_alloc_planes(mp_image_t *mpi);
void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi);
+// this macro requires img_format.h to be included too:
+#define MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, p) \
+ (IMGFMT_IS_YUVP16((mpi)->imgfmt) ? 16 : 8)
+#define MP_IMAGE_BITS_PER_PIXEL_ON_PLANE(mpi, p) \
+ (((mpi)->flags & MP_IMGFLAG_PLANAR) \
+ ? MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, p) \
+ : (mpi)->bpp)
+#define MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, p) \
+ ((MP_IMAGE_BITS_PER_PIXEL_ON_PLANE(mpi, p) * ((mpi)->w >> (p ? mpi->chroma_x_shift : 0)) + 7) / 8)
+
#endif /* MPLAYER_MP_IMAGE_H */