int
 zoran_check_jpg_settings (struct zoran              *zr,
-                         struct zoran_jpg_settings *settings)
+                         struct zoran_jpg_settings *settings,
+                         int try)
 {
        int err = 0, err0 = 0;
 
                /* We have to check the data the user has set */
 
                if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
-                   (zr->card.type == DC10_new || settings->HorDcm != 4))
+                   (zr->card.type == DC10_new || settings->HorDcm != 4)) {
+                       settings->HorDcm = clamp(settings->HorDcm, 1, 2);
                        err0++;
-               if (settings->VerDcm != 1 && settings->VerDcm != 2)
+               }
+               if (settings->VerDcm != 1 && settings->VerDcm != 2) {
+                       settings->VerDcm = clamp(settings->VerDcm, 1, 2);
                        err0++;
-               if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
+               }
+               if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
+                       settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
                        err0++;
+               }
                if (settings->field_per_buff != 1 &&
-                   settings->field_per_buff != 2)
+                   settings->field_per_buff != 2) {
+                       settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
                        err0++;
-               if (settings->img_x < 0)
+               }
+               if (settings->img_x < 0) {
+                       settings->img_x = 0;
                        err0++;
-               if (settings->img_y < 0)
+               }
+               if (settings->img_y < 0) {
+                       settings->img_y = 0;
                        err0++;
-               if (settings->img_width < 0)
+               }
+               if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
                        err0++;
-               if (settings->img_height < 0)
+               }
+               if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
+                       settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
                        err0++;
-               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
+               }
+               if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+                       settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
+                       err0++;
+               }
+               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
+                       settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
                        err0++;
-               if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2)
+               }
+               if (settings->img_width % (16 * settings->HorDcm) != 0) {
+                       settings->img_width -= settings->img_width % (16 * settings->HorDcm);
+                       if (settings->img_width == 0)
+                               settings->img_width = 16 * settings->HorDcm;
+                       err0++;
+               }
+               if (settings->img_height % (8 * settings->VerDcm) != 0) {
+                       settings->img_height -= settings->img_height % (8 * settings->VerDcm);
+                       if (settings->img_height == 0)
+                               settings->img_height = 8 * settings->VerDcm;
                        err0++;
-               if (settings->HorDcm && settings->VerDcm) {
-                       if (settings->img_width % (16 * settings->HorDcm) != 0)
-                               err0++;
-                       if (settings->img_height % (8 * settings->VerDcm) != 0)
-                               err0++;
                }
 
-               if (err0) {
+               if (!try && err0) {
                        dprintk(1,
                                KERN_ERR
                                "%s: check_jpg_settings() - error in params for decimation = 0\n",
               sizeof(zr->jpg_settings.jpg_comp.COM_data));
        zr->jpg_settings.jpg_comp.jpeg_markers =
            JPEG_MARKER_DHT | JPEG_MARKER_DQT;
-       i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
+       i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
        if (i)
                dprintk(1,
                        KERN_ERR
 
 
                /* Check the params first before overwriting our
                 * nternal values */
-               if (zoran_check_jpg_settings(zr, &settings)) {
+               if (zoran_check_jpg_settings(zr, &settings, 0)) {
                        res = -EINVAL;
                        goto sparams_unlock_and_return;
                }
                settings.field_per_buff = 1;
 
        /* check */
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 1);
        if (res)
                goto tryfmt_unlock_and_return;
 
 {
        struct zoran_fh *fh = __fh;
        struct zoran *zr = fh->zr;
+       int bpp;
        int i;
 
        if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
                return -EINVAL;
        }
 
+       bpp = (zoran_formats[i].depth + 7) / 8;
+       fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
        if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
                fmt->fmt.pix.width = BUZ_MAX_WIDTH;
        if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
        else
                settings.field_per_buff = 1;
 
+       if (settings.HorDcm > 1) {
+               settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+               settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+       } else {
+               settings.img_x = 0;
+               settings.img_width = BUZ_MAX_WIDTH;
+       }
+
        /* check */
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 0);
        if (res)
                goto sfmtjpg_unlock_and_return;
 
        settings.img_height = crop->c.height;
 
        /* check validity */
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 0);
        if (res)
                goto scrop_unlock_and_return;
 
                goto sjpegc_unlock_and_return;
        }
 
-       res = zoran_check_jpg_settings(zr, &settings);
+       res = zoran_check_jpg_settings(zr, &settings, 0);
        if (res)
                goto sjpegc_unlock_and_return;
        if (!fh->jpg_buffers.allocated)