VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / usb / media / pwc-misc.c
index 500ddad..09f629d 100644 (file)
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/  
+*/
 
 #include <linux/slab.h>
 
 #include "pwc.h"
 
-struct pwc_coord pwc_image_sizes[PSZ_MAX] = 
+struct pwc_coord pwc_image_sizes[PSZ_MAX] =
 {
        { 128,  96, 0 },
        { 160, 120, 0 },
@@ -36,11 +36,30 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
 {
        int i, find;
 
-       /* Make sure we don't go beyond our max size */
-       if (width > pdev->view_max.x || height > pdev->view_max.y)
-               return -1;
+       /* Make sure we don't go beyond our max size.
+           NB: we have different limits for RAW and normal modes. In case
+           you don't have the decompressor loaded or use RAW mode, 
+           the maximum viewable size is smaller.
+        */
+       if (pdev->vpalette == VIDEO_PALETTE_RAW)
+       {
+               if (width > pdev->abs_max.x || height > pdev->abs_max.y)
+               {
+                       Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
+                       return -1;
+                }
+       }
+       else
+       {
+               if (width > pdev->view_max.x || height > pdev->view_max.y)
+               {
+                       Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n");
+                       return -1;
+               }
+       }
+
        /* Find the largest size supported by the camera that fits into the
-          requested size. 
+          requested size.
         */
        find = -1;
        for (i = 0; i < PSZ_MAX; i++) {
@@ -62,6 +81,8 @@ void pwc_construct(struct pwc_device *pdev)
                pdev->view_min.y =  96;
                pdev->view_max.x = 352;
                pdev->view_max.y = 288;
+                pdev->abs_max.x  = 352;
+                pdev->abs_max.y  = 288;
                pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
                pdev->vcinterface = 2;
                pdev->vendpoint = 4;
@@ -77,13 +98,14 @@ void pwc_construct(struct pwc_device *pdev)
                if (pdev->decompressor != NULL) {
                        pdev->view_max.x = 640;
                        pdev->view_max.y = 480;
-                       pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
                }
                else {
                        pdev->view_max.x = 352;
                        pdev->view_max.y = 288;
-                       pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF;
                }
+               pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
+                pdev->abs_max.x = 640;
+                pdev->abs_max.y = 480;
                pdev->vcinterface = 3;
                pdev->vendpoint = 4;
                pdev->frame_header_size = 0;
@@ -99,24 +121,26 @@ void pwc_construct(struct pwc_device *pdev)
                if (pdev->decompressor != NULL) {
                        pdev->view_max.x = 640;
                        pdev->view_max.y = 480;
-                       pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
                }
                else {
-                       /* Tell CIF, even though SIF really is the maximum, but some tools really need CIF */
+                       /* We use CIF, not SIF since some tools really need CIF. So we cheat a bit. */
                        pdev->view_max.x = 352;
                        pdev->view_max.y = 288;
-                       pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF;
                }
+               pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
+                pdev->abs_max.x = 640;
+                pdev->abs_max.y = 480;
                pdev->vcinterface = 3;
                pdev->vendpoint = 5;
                pdev->frame_header_size = TOUCAM_HEADER_SIZE;
                pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
                break;
        }
+       pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
        pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
        pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
-       /* length of image, in YUV format */
-       pdev->len_per_image = (pdev->view_max.size * 3) / 2;
+       /* length of image, in YUV format; always allocate enough memory. */
+       pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2;
 }