aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorTrent Piepho <xyzzy@speakeasy.org>2009-05-30 20:45:46 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-23 02:21:19 -0400
commit1c657a99fd655c0daa7450854a914d21c1da805c (patch)
tree8872a5e58f98fc846627b8c45689c26f0f74e3c8 /drivers/media
parent4b89945e590f94e82a6e7f33e21cbd0d83774b9e (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')
-rw-r--r--drivers/media/video/w9968cf.c35
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);
460static int w9968cf_set_window(struct w9968cf_device*, struct video_window); 460static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
461static int w9968cf_postprocess_frame(struct w9968cf_device*, 461static int w9968cf_postprocess_frame(struct w9968cf_device*,
462 struct w9968cf_frame_t*); 462 struct w9968cf_frame_t*);
463static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h); 463static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h);
464static void w9968cf_init_framelist(struct w9968cf_device*); 464static void w9968cf_init_framelist(struct w9968cf_device*);
465static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); 465static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
466static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); 466static 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 --------------------------------------------------------------------------*/
1916static int 1915static int
1917w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) 1916w9968cf_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)