summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-25 22:29:49 +0100
committerwm4 <wm4@nowhere>2013-01-13 20:04:12 +0100
commit717d904bbc20e06e2c6c71613d59e065845ff209 (patch)
tree6f758cff6d98e579b767952894023997618c44d5
parentded932dbd40e326a8d42acb8c4b8297046f08695 (diff)
downloadmpv-717d904bbc20e06e2c6c71613d59e065845ff209.tar.bz2
mpv-717d904bbc20e06e2c6c71613d59e065845ff209.tar.xz
mp_image: add mp_image_crop()
Actually stolen from draw_bmp.c.
-rw-r--r--sub/draw_bmp.c14
-rw-r--r--video/img_format.c6
-rw-r--r--video/img_format.h2
-rw-r--r--video/mp_image.c22
-rw-r--r--video/mp_image.h3
5 files changed, 35 insertions, 12 deletions
diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c
index 64a12a2da5..9960d7b459 100644
--- a/sub/draw_bmp.c
+++ b/sub/draw_bmp.c
@@ -325,16 +325,6 @@ static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb,
}
}
-static void mp_image_crop(struct mp_image *img, struct mp_rect rc)
-{
- for (int p = 0; p < img->num_planes; ++p) {
- img->planes[p] +=
- (rc.y0 >> img->fmt.ys[p]) * img->stride[p] +
- (rc.x0 >> img->fmt.xs[p]) * img->fmt.bpp[p] / 8;
- }
- mp_image_set_size(img, rc.x1 - rc.x0, rc.y1 - rc.y0);
-}
-
static bool clip_to_bb(struct mp_rect bb, struct mp_rect *rc)
{
rc->x0 = FFMAX(bb.x0, rc->x0);
@@ -459,7 +449,7 @@ static bool get_sub_area(struct mp_rect bb, struct mp_image *temp,
*out_src_x = (dst.x0 - sb->x) + bb.x0;
*out_src_y = (dst.y0 - sb->y) + bb.y0;
*out_area = *temp;
- mp_image_crop(out_area, dst);
+ mp_image_crop_rc(out_area, dst);
return true;
}
@@ -486,7 +476,7 @@ void mp_draw_sub_bitmaps(struct mp_draw_sub_cache **cache, struct mp_image *dst,
struct mp_image *temp;
struct mp_image dst_region = *dst;
- mp_image_crop(&dst_region, bb);
+ mp_image_crop_rc(&dst_region, bb);
if (dst->imgfmt == format) {
temp = &dst_region;
} else {
diff --git a/video/img_format.c b/video/img_format.c
index 8a286be9fc..a6d92f1a1f 100644
--- a/video/img_format.c
+++ b/video/img_format.c
@@ -210,6 +210,12 @@ static struct mp_imgfmt_desc get_avutil_fmt(enum PixelFormat fmt)
desc.ys[p] = (p == 1 || p == 2) ? desc.chroma_ys : 0;
}
+ desc.align_x = 1 << desc.chroma_xs;
+ desc.align_y = 1 << desc.chroma_ys;
+
+ if ((desc.bpp[0] % 8) != 0)
+ desc.align_x = 8 / desc.bpp[0]; // expect power of 2
+
return desc;
}
diff --git a/video/img_format.h b/video/img_format.h
index f67971e5c6..37ac32ffac 100644
--- a/video/img_format.h
+++ b/video/img_format.h
@@ -64,6 +64,8 @@ struct mp_imgfmt_desc {
int flags; // MP_IMGFLAG_* bitfield
int8_t num_planes;
int8_t chroma_xs, chroma_ys; // chroma shift (i.e. log2 of chroma pixel size)
+ int8_t align_x, align_y; // pixel size to get byte alignment and to get
+ // to a pixel pos where luma & chroma aligns
int8_t avg_bpp;
int8_t bytes[MP_MAX_PLANES]; // bytes per pixel (MP_IMGFLAG_BYTE_ALIGNED)
int8_t bpp[MP_MAX_PLANES]; // bits per pixel
diff --git a/video/mp_image.c b/video/mp_image.c
index 4df4d2e17f..256e908198 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -335,6 +335,28 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
}
}
+// Crop the given image to (x0, y0)-(x1, y1) (bottom/right border exclusive)
+// x0/y0 must be naturally aligned.
+void mp_image_crop(struct mp_image *img, int x0, int y0, int x1, int y1)
+{
+ assert(x0 >= 0 && y0 >= 0);
+ assert(x0 <= x1 && y0 <= y1);
+ assert(x1 <= img->w && y1 <= img->h);
+ assert(!(x0 & (img->fmt.align_x - 1)));
+ assert(!(y0 & (img->fmt.align_y - 1)));
+
+ for (int p = 0; p < img->num_planes; ++p) {
+ img->planes[p] += (y0 >> img->fmt.ys[p]) * img->stride[p] +
+ (x0 >> img->fmt.xs[p]) * img->fmt.bpp[p] / 8;
+ }
+ mp_image_set_size(img, x1 - x0, y1 - y0);
+}
+
+void mp_image_crop_rc(struct mp_image *img, struct mp_rect rc)
+{
+ mp_image_crop(img, rc.x0, rc.y0, rc.x1, rc.y1);
+}
+
void mp_image_clear(struct mp_image *mpi, int x0, int y0, int w, int h)
{
int y;
diff --git a/video/mp_image.h b/video/mp_image.h
index 1d00115545..efbb7551b3 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -102,6 +102,9 @@ void mp_image_make_writeable(struct mp_image *img);
void mp_image_setrefp(struct mp_image **p_img, struct mp_image *new_value);
void mp_image_unrefp(struct mp_image **p_img);
+void mp_image_crop(struct mp_image *img, int x0, int y0, int x1, int y1);
+void mp_image_crop_rc(struct mp_image *img, struct mp_rect rc);
+
void mp_image_set_size(struct mp_image *mpi, int w, int h);
void mp_image_set_display_size(struct mp_image *mpi, int dw, int dh);