Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * v4l2-rect.h - v4l2_rect helper functions
0004  *
0005  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
0006  */
0007 
0008 #ifndef _V4L2_RECT_H_
0009 #define _V4L2_RECT_H_
0010 
0011 #include <linux/videodev2.h>
0012 
0013 /**
0014  * v4l2_rect_set_size_to() - copy the width/height values.
0015  * @r: rect whose width and height fields will be set
0016  * @size: rect containing the width and height fields you need.
0017  */
0018 static inline void v4l2_rect_set_size_to(struct v4l2_rect *r,
0019                      const struct v4l2_rect *size)
0020 {
0021     r->width = size->width;
0022     r->height = size->height;
0023 }
0024 
0025 /**
0026  * v4l2_rect_set_min_size() - width and height of r should be >= min_size.
0027  * @r: rect whose width and height will be modified
0028  * @min_size: rect containing the minimal width and height
0029  */
0030 static inline void v4l2_rect_set_min_size(struct v4l2_rect *r,
0031                       const struct v4l2_rect *min_size)
0032 {
0033     if (r->width < min_size->width)
0034         r->width = min_size->width;
0035     if (r->height < min_size->height)
0036         r->height = min_size->height;
0037 }
0038 
0039 /**
0040  * v4l2_rect_set_max_size() - width and height of r should be <= max_size
0041  * @r: rect whose width and height will be modified
0042  * @max_size: rect containing the maximum width and height
0043  */
0044 static inline void v4l2_rect_set_max_size(struct v4l2_rect *r,
0045                       const struct v4l2_rect *max_size)
0046 {
0047     if (r->width > max_size->width)
0048         r->width = max_size->width;
0049     if (r->height > max_size->height)
0050         r->height = max_size->height;
0051 }
0052 
0053 /**
0054  * v4l2_rect_map_inside()- r should be inside boundary.
0055  * @r: rect that will be modified
0056  * @boundary: rect containing the boundary for @r
0057  */
0058 static inline void v4l2_rect_map_inside(struct v4l2_rect *r,
0059                     const struct v4l2_rect *boundary)
0060 {
0061     v4l2_rect_set_max_size(r, boundary);
0062     if (r->left < boundary->left)
0063         r->left = boundary->left;
0064     if (r->top < boundary->top)
0065         r->top = boundary->top;
0066     if (r->left + r->width > boundary->left + boundary->width)
0067         r->left = boundary->left + boundary->width - r->width;
0068     if (r->top + r->height > boundary->top + boundary->height)
0069         r->top = boundary->top + boundary->height - r->height;
0070 }
0071 
0072 /**
0073  * v4l2_rect_same_size() - return true if r1 has the same size as r2
0074  * @r1: rectangle.
0075  * @r2: rectangle.
0076  *
0077  * Return true if both rectangles have the same size.
0078  */
0079 static inline bool v4l2_rect_same_size(const struct v4l2_rect *r1,
0080                        const struct v4l2_rect *r2)
0081 {
0082     return r1->width == r2->width && r1->height == r2->height;
0083 }
0084 
0085 /**
0086  * v4l2_rect_same_position() - return true if r1 has the same position as r2
0087  * @r1: rectangle.
0088  * @r2: rectangle.
0089  *
0090  * Return true if both rectangles have the same position
0091  */
0092 static inline bool v4l2_rect_same_position(const struct v4l2_rect *r1,
0093                        const struct v4l2_rect *r2)
0094 {
0095     return r1->top == r2->top && r1->left == r2->left;
0096 }
0097 
0098 /**
0099  * v4l2_rect_equal() - return true if r1 equals r2
0100  * @r1: rectangle.
0101  * @r2: rectangle.
0102  *
0103  * Return true if both rectangles have the same size and position.
0104  */
0105 static inline bool v4l2_rect_equal(const struct v4l2_rect *r1,
0106                    const struct v4l2_rect *r2)
0107 {
0108     return v4l2_rect_same_size(r1, r2) && v4l2_rect_same_position(r1, r2);
0109 }
0110 
0111 /**
0112  * v4l2_rect_intersect() - calculate the intersection of two rects.
0113  * @r: intersection of @r1 and @r2.
0114  * @r1: rectangle.
0115  * @r2: rectangle.
0116  */
0117 static inline void v4l2_rect_intersect(struct v4l2_rect *r,
0118                        const struct v4l2_rect *r1,
0119                        const struct v4l2_rect *r2)
0120 {
0121     int right, bottom;
0122 
0123     r->top = max(r1->top, r2->top);
0124     r->left = max(r1->left, r2->left);
0125     bottom = min(r1->top + r1->height, r2->top + r2->height);
0126     right = min(r1->left + r1->width, r2->left + r2->width);
0127     r->height = max(0, bottom - r->top);
0128     r->width = max(0, right - r->left);
0129 }
0130 
0131 /**
0132  * v4l2_rect_scale() - scale rect r by to/from
0133  * @r: rect to be scaled.
0134  * @from: from rectangle.
0135  * @to: to rectangle.
0136  *
0137  * This scales rectangle @r horizontally by @to->width / @from->width and
0138  * vertically by @to->height / @from->height.
0139  *
0140  * Typically @r is a rectangle inside @from and you want the rectangle as
0141  * it would appear after scaling @from to @to. So the resulting @r will
0142  * be the scaled rectangle inside @to.
0143  */
0144 static inline void v4l2_rect_scale(struct v4l2_rect *r,
0145                    const struct v4l2_rect *from,
0146                    const struct v4l2_rect *to)
0147 {
0148     if (from->width == 0 || from->height == 0) {
0149         r->left = r->top = r->width = r->height = 0;
0150         return;
0151     }
0152     r->left = (((r->left - from->left) * to->width) / from->width) & ~1;
0153     r->width = ((r->width * to->width) / from->width) & ~1;
0154     r->top = ((r->top - from->top) * to->height) / from->height;
0155     r->height = (r->height * to->height) / from->height;
0156 }
0157 
0158 /**
0159  * v4l2_rect_overlap() - do r1 and r2 overlap?
0160  * @r1: rectangle.
0161  * @r2: rectangle.
0162  *
0163  * Returns true if @r1 and @r2 overlap.
0164  */
0165 static inline bool v4l2_rect_overlap(const struct v4l2_rect *r1,
0166                      const struct v4l2_rect *r2)
0167 {
0168     /*
0169      * IF the left side of r1 is to the right of the right side of r2 OR
0170      *    the left side of r2 is to the right of the right side of r1 THEN
0171      * they do not overlap.
0172      */
0173     if (r1->left >= r2->left + r2->width ||
0174         r2->left >= r1->left + r1->width)
0175         return false;
0176     /*
0177      * IF the top side of r1 is below the bottom of r2 OR
0178      *    the top side of r2 is below the bottom of r1 THEN
0179      * they do not overlap.
0180      */
0181     if (r1->top >= r2->top + r2->height ||
0182         r2->top >= r1->top + r1->height)
0183         return false;
0184     return true;
0185 }
0186 
0187 /**
0188  * v4l2_rect_enclosed() - is r1 enclosed in r2?
0189  * @r1: rectangle.
0190  * @r2: rectangle.
0191  *
0192  * Returns true if @r1 is enclosed in @r2.
0193  */
0194 static inline bool v4l2_rect_enclosed(struct v4l2_rect *r1,
0195                       struct v4l2_rect *r2)
0196 {
0197     if (r1->left < r2->left || r1->top < r2->top)
0198         return false;
0199     if (r1->left + r1->width > r2->left + r2->width)
0200         return false;
0201     if (r1->top + r1->height > r2->top + r2->height)
0202         return false;
0203 
0204     return true;
0205 }
0206 
0207 #endif