diff options
author | Trent Piepho <xyzzy@speakeasy.org> | 2009-05-30 20:45:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-23 02:21:19 -0400 |
commit | 1c657a99fd655c0daa7450854a914d21c1da805c (patch) | |
tree | 8872a5e58f98fc846627b8c45689c26f0f74e3c8 /drivers/media/video/w9968cf.c | |
parent | 4b89945e590f94e82a6e7f33e21cbd0d83774b9e (diff) |
V4L/DVB (11908): w8968cf: Use v4l bounding/alignment function
The v4l function has a better algorithm for aligning image size.
The existing code was casting pointers to u32 and to unsigned int into
pointers to u16. This could mess up if someone passed in an image size
greater than 65,535 and on big-endian platforms it won't work at all.
The existing bounding code would shrink an image if it was too big, but
returned ERANGE if it was too small. The code will not shrink or expand as
necessary.
Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/w9968cf.c')
-rw-r--r-- | drivers/media/video/w9968cf.c | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index f59b2bd07e89..6c3f23e31b5c 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c | |||
@@ -460,7 +460,7 @@ static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture); | |||
460 | static int w9968cf_set_window(struct w9968cf_device*, struct video_window); | 460 | static int w9968cf_set_window(struct w9968cf_device*, struct video_window); |
461 | static int w9968cf_postprocess_frame(struct w9968cf_device*, | 461 | static int w9968cf_postprocess_frame(struct w9968cf_device*, |
462 | struct w9968cf_frame_t*); | 462 | struct w9968cf_frame_t*); |
463 | static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h); | 463 | static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h); |
464 | static void w9968cf_init_framelist(struct w9968cf_device*); | 464 | static void w9968cf_init_framelist(struct w9968cf_device*); |
465 | static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); | 465 | static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); |
466 | static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); | 466 | static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); |
@@ -1763,8 +1763,7 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) | |||
1763 | #define UNSC(x) ((x) >> 10) | 1763 | #define UNSC(x) ((x) >> 10) |
1764 | 1764 | ||
1765 | /* Make sure we are using a supported resolution */ | 1765 | /* Make sure we are using a supported resolution */ |
1766 | if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, | 1766 | if ((err = w9968cf_adjust_window_size(cam, &win.width, &win.height))) |
1767 | (u16*)&win.height))) | ||
1768 | goto error; | 1767 | goto error; |
1769 | 1768 | ||
1770 | /* Scaling factors */ | 1769 | /* Scaling factors */ |
@@ -1914,12 +1913,9 @@ error: | |||
1914 | Return 0 on success, -1 otherwise. | 1913 | Return 0 on success, -1 otherwise. |
1915 | --------------------------------------------------------------------------*/ | 1914 | --------------------------------------------------------------------------*/ |
1916 | static int | 1915 | static int |
1917 | w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) | 1916 | w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height) |
1918 | { | 1917 | { |
1919 | u16 maxw, maxh; | 1918 | unsigned int maxw, maxh, align; |
1920 | |||
1921 | if ((*width < cam->minwidth) || (*height < cam->minheight)) | ||
1922 | return -ERANGE; | ||
1923 | 1919 | ||
1924 | maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && | 1920 | maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && |
1925 | w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) | 1921 | w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) |
@@ -1927,16 +1923,10 @@ w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) | |||
1927 | maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && | 1923 | maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && |
1928 | w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) | 1924 | w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) |
1929 | : cam->maxheight; | 1925 | : cam->maxheight; |
1926 | align = (cam->vpp_flag & VPP_DECOMPRESSION) ? 4 : 0; | ||
1930 | 1927 | ||
1931 | if (*width > maxw) | 1928 | v4l_bound_align_image(width, cam->minwidth, maxw, align, |
1932 | *width = maxw; | 1929 | height, cam->minheight, maxh, align, 0); |
1933 | if (*height > maxh) | ||
1934 | *height = maxh; | ||
1935 | |||
1936 | if (cam->vpp_flag & VPP_DECOMPRESSION) { | ||
1937 | *width &= ~15L; /* multiple of 16 */ | ||
1938 | *height &= ~15L; | ||
1939 | } | ||
1940 | 1930 | ||
1941 | PDBGG("Window size adjusted w=%u, h=%u ", *width, *height) | 1931 | PDBGG("Window size adjusted w=%u, h=%u ", *width, *height) |
1942 | 1932 | ||
@@ -3043,8 +3033,8 @@ static long w9968cf_v4l_ioctl(struct file *filp, | |||
3043 | if (win.clipcount != 0 || win.flags != 0) | 3033 | if (win.clipcount != 0 || win.flags != 0) |
3044 | return -EINVAL; | 3034 | return -EINVAL; |
3045 | 3035 | ||
3046 | if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, | 3036 | if ((err = w9968cf_adjust_window_size(cam, &win.width, |
3047 | (u16*)&win.height))) { | 3037 | &win.height))) { |
3048 | DBG(4, "Resolution not supported (%ux%u). " | 3038 | DBG(4, "Resolution not supported (%ux%u). " |
3049 | "VIDIOCSWIN failed", win.width, win.height) | 3039 | "VIDIOCSWIN failed", win.width, win.height) |
3050 | return err; | 3040 | return err; |
@@ -3116,6 +3106,7 @@ static long w9968cf_v4l_ioctl(struct file *filp, | |||
3116 | { | 3106 | { |
3117 | struct video_mmap mmap; | 3107 | struct video_mmap mmap; |
3118 | struct w9968cf_frame_t* fr; | 3108 | struct w9968cf_frame_t* fr; |
3109 | u32 w, h; | ||
3119 | int err = 0; | 3110 | int err = 0; |
3120 | 3111 | ||
3121 | if (copy_from_user(&mmap, arg, sizeof(mmap))) | 3112 | if (copy_from_user(&mmap, arg, sizeof(mmap))) |
@@ -3164,8 +3155,10 @@ static long w9968cf_v4l_ioctl(struct file *filp, | |||
3164 | } | 3155 | } |
3165 | } | 3156 | } |
3166 | 3157 | ||
3167 | if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, | 3158 | w = mmap.width; h = mmap.height; |
3168 | (u16*)&mmap.height))) { | 3159 | err = w9968cf_adjust_window_size(cam, &w, &h); |
3160 | mmap.width = w; mmap.height = h; | ||
3161 | if (err) { | ||
3169 | DBG(4, "Resolution not supported (%dx%d). " | 3162 | DBG(4, "Resolution not supported (%dx%d). " |
3170 | "VIDIOCMCAPTURE failed", | 3163 | "VIDIOCMCAPTURE failed", |
3171 | mmap.width, mmap.height) | 3164 | mmap.width, mmap.height) |