/* Bound an image to have a width between wmin and wmax, and height between * hmin and hmax, inclusive. Additionally, the width will be a multiple of * 2^walign, the height will be a multiple of 2^halign, and the overall size * (width*height) will be a multiple of 2^salign. The image may be shrunk * or enlarged to fit the alignment constraints. * * The width or height maximum must not be smaller than the corresponding * minimum. The alignments must not be so high there are no possible image * sizes within the allowed bounds. wmin and hmin must be at least 1 * (don't use 0). If you don't care about a certain alignment, specify 0, * as 2^0 is 1 and one byte alignment is equivalent to no alignment. If * you only want to adjust downward, specify a maximum that's the same as * the initial value. */ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, unsigned int walign, u32 *h, unsigned int hmin, unsigned int hmax, unsigned int halign, unsigned int salign) { *w = clamp_align(*w, wmin, wmax, walign); *h = clamp_align(*h, hmin, hmax, halign); /* Usually we don't need to align the size and are done now. */ if (!salign) return; /* How much alignment do we have? */ walign = __ffs(*w); halign = __ffs(*h); /* Enough to satisfy the image alignment? */ if (walign + halign < salign) { /* Max walign where there is still a valid width */ unsigned int wmaxa = __fls(wmax ^ (wmin - 1)); /* Max halign where there is still a valid height */ unsigned int hmaxa = __fls(hmax ^ (hmin - 1)); /* up the smaller alignment until we have enough */ do { if (halign >= hmaxa || (walign <= halign && walign < wmaxa)) { *w = clamp_align(*w, wmin, wmax, walign + 1); walign = __ffs(*w); } else { *h = clamp_align(*h, hmin, hmax, halign + 1); halign = __ffs(*h); } } while (halign + walign < salign); } }
void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, unsigned int walign, u32 *h, unsigned int hmin, unsigned int hmax, unsigned int halign, unsigned int salign) { *w = clamp_align(*w, wmin, wmax, walign); *h = clamp_align(*h, hmin, hmax, halign); if (!salign) return; walign = __ffs(*w); halign = __ffs(*h); if (walign + halign < salign) { unsigned int wmaxa = __fls(wmax ^ (wmin - 1)); unsigned int hmaxa = __fls(hmax ^ (hmin - 1)); do { if (halign >= hmaxa || (walign <= halign && walign < wmaxa)) { *w = clamp_align(*w, wmin, wmax, walign + 1); walign = __ffs(*w); } else { *h = clamp_align(*h, hmin, hmax, halign + 1); halign = __ffs(*h); } } while (halign + walign < salign); } }