diff src/_camera.c @ 1849:301bc61643a9 math_module

merged changes from trunk
author lorenz
date Mon, 16 Nov 2009 18:31:40 +0000
parents 19a59d1c410b
children
line wrap: on
line diff
--- a/src/_camera.c	Mon Nov 16 18:05:30 2009 +0000
+++ b/src/_camera.c	Mon Nov 16 18:31:40 2009 +0000
@@ -35,11 +35,14 @@
  
 #include "camera.h"
 
-#if defined(__unix__)
+/*
+#if defined(__unix__) || !defined(__APPLE__)
 #else
     #define V4L2_PIX_FMT_RGB24 1
     #define V4L2_PIX_FMT_RGB444 1
 #endif
+*/
+
 
 /* functions available to pygame users */
 PyObject* surf_colorspace (PyObject* self, PyObject* arg);
@@ -62,8 +65,7 @@
  */
 
 /* colorspace() - Surface colorspace conversion */
-PyObject* surf_colorspace (PyObject* self, PyObject* arg)
-{
+PyObject* surf_colorspace (PyObject* self, PyObject* arg) {
     PyObject *surfobj, *surfobj2;
     SDL_Surface* surf, *newsurf;
     char* color;
@@ -125,9 +127,8 @@
 }
 
 /* list_cameras() - lists cameras available on the computer */
-PyObject* list_cameras (PyObject* self, PyObject* arg)
-{
-#if defined(__unix__)
+PyObject* list_cameras (PyObject* self, PyObject* arg) {
+#if defined(__unix__) || defined (__APPLE__)
     PyObject* ret_list;
     PyObject* string;
     char** devices;
@@ -138,8 +139,12 @@
     ret_list = PyList_New (0);
     if (!ret_list)
         return NULL;
-
+    
+    #if defined(__unix__)
     devices = v4l2_list_cameras(&num_devices);
+    # elif defined(__APPLE__)
+    devices = mac_list_cameras(&num_devices);
+    # endif
     
     for(i = 0; i < num_devices; i++) {
         string = PyString_FromString(devices[i]);
@@ -156,8 +161,7 @@
 }
 
 /* start() - opens, inits, and starts capturing on the camera */
-PyObject* camera_start (PyCameraObject* self)
-{
+PyObject* camera_start (PyCameraObject* self) {
 #if defined(__unix__)
     if (v4l2_open_device(self) == 0) {
         if (v4l_open_device(self) == 0) {
@@ -185,13 +189,17 @@
             return NULL;
         }
     }
+#elif defined(__APPLE__)
+    if (! (mac_open_device(self) == 1 && mac_init_device(self) == 1 && mac_start_capturing(self) == 1)) {
+        mac_close_device(self);
+        return NULL;
+    }
 #endif
     Py_RETURN_NONE;
 }
 
 /* stop() - stops capturing, uninits, and closes the camera */
-PyObject* camera_stop (PyCameraObject* self)
-{
+PyObject* camera_stop (PyCameraObject* self) {
 #if defined(__unix__)
     if (v4l2_stop_capturing(self) == 0)
         return NULL;
@@ -199,16 +207,20 @@
         return NULL;
     if (v4l2_close_device(self) == 0)
         return NULL;
+#elif defined(__APPLE__)
+    if (mac_stop_capturing(self) == 0)
+        return NULL;
+    if (mac_close_device(self) == 0)
+        return NULL;
 #endif
     Py_RETURN_NONE;
 }
 
 /* get_controls() - gets current values of user controls */
 /* TODO: Support brightness, contrast, and other common controls */
-PyObject* camera_get_controls (PyCameraObject* self)
-{
+PyObject* camera_get_controls (PyCameraObject* self) {
+#if defined(__unix__)    
     int value;
-#if defined(__unix__)    
     if (v4l2_get_control(self->fd, V4L2_CID_HFLIP, &value))
         self->hflip = value;
     
@@ -217,13 +229,17 @@
 
     if (v4l2_get_control(self->fd, V4L2_CID_BRIGHTNESS, &value))
         self->brightness = value;
-#endif    
+    
     return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(self->brightness));
+#elif defined(__APPLE__)
+    return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(-1));
+#endif
+    Py_RETURN_NONE;
 }
 
 /* set_controls() - changes camera settings if supported by the camera */
-PyObject* camera_set_controls (PyCameraObject* self, PyObject* arg, PyObject *kwds)
-{
+PyObject* camera_set_controls (PyCameraObject* self, PyObject* arg, PyObject *kwds) {
+#if defined(__unix__)
     int hflip = 0, vflip = 0, brightness = 0;
     char *kwids[] = {"hflip", "vflip", "brightness", NULL};
 
@@ -234,7 +250,8 @@
     
     if (!PyArg_ParseTupleAndKeywords(arg, kwds, "|iii", kwids, &hflip, &vflip, &brightness))
         return NULL;
-#if defined(__unix__)        
+        
+/* #if defined(__unix__)         */
     if (v4l2_set_control(self->fd, V4L2_CID_HFLIP, hflip))
         self->hflip = hflip;
         
@@ -243,29 +260,51 @@
         
     if (v4l2_set_control(self->fd, V4L2_CID_BRIGHTNESS, brightness))
         self->brightness = brightness;
-#endif    
+           
     return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(self->brightness));
-}
+
+#elif defined(__APPLE__)
+    int hflip = 0, vflip = 0, brightness = 0;
+    char *kwids[] = {"hflip", "vflip", "brightness", NULL};
 
-/* get_size() - returns the dimensions of the images being recorded */
-PyObject* camera_get_size (PyCameraObject* self)
-{
-    return Py_BuildValue ("(ii)", self->width, self->height);
-}
-
-/* query_image() - checks if a frame is ready */
-PyObject* camera_query_image (PyCameraObject* self)
-{
-#if defined(__unix__)
-    return PyBool_FromLong(v4l2_query_buffer(self));
+    camera_get_controls(self);
+    hflip = self->hflip;
+    vflip = self->vflip;
+    brightness = -1;
+    
+    if (!PyArg_ParseTupleAndKeywords(arg, kwds, "|iii", kwids, &hflip, &vflip, &brightness))
+        return NULL;
+        
+    self->hflip = hflip;
+    self->vflip = vflip;
+           
+    return Py_BuildValue ("(NNN)", PyBool_FromLong(self->hflip), PyBool_FromLong(self->vflip), PyInt_FromLong(-1));
 #endif
     Py_RETURN_NONE;
 }
 
+/* get_size() - returns the dimensions of the images being recorded */
+PyObject* camera_get_size (PyCameraObject* self) {
+#if defined(__unix__)
+    return Py_BuildValue ("(ii)", self->width, self->height);
+#elif defined(__APPLE__)
+    return Py_BuildValue ("(ii)", self->boundsRect.right, self->boundsRect.bottom);
+#endif
+    Py_RETURN_NONE;
+}
+
+/* query_image() - checks if a frame is ready */
+PyObject* camera_query_image(PyCameraObject* self) {
+#if defined(__unix__)
+    return PyBool_FromLong(v4l2_query_buffer(self));
+#endif
+    Py_RETURN_TRUE;
+}
+
 /* get_image() - returns an RGB Surface */
 /* code to reuse Surface from René Dudfield */
-PyObject* camera_get_image (PyCameraObject* self, PyObject* arg)
-{
+PyObject* camera_get_image (PyCameraObject* self, PyObject* arg) {
+#if defined(__unix__)
     SDL_Surface* surf = NULL;
     PyObject *surfobj = NULL;
     
@@ -286,12 +325,12 @@
         return RAISE (PyExc_ValueError, 
                       "Destination surface not the correct width or height.");
     }
-#if defined(__unix__)
+    
     Py_BEGIN_ALLOW_THREADS;
     if (!v4l2_read_frame(self, surf))
         return NULL;
     Py_END_ALLOW_THREADS;
-#endif
+    
     if (!surf)
         return NULL;
         
@@ -301,13 +340,60 @@
     } else {
         return PySurface_New (surf);
     }
+#elif defined(__APPLE__)
+        SDL_Surface* surf = NULL;
+        PyObject *surfobj = NULL;
+
+        if (!PyArg_ParseTuple (arg, "|O!", &PySurface_Type, &surfobj))
+            return NULL;
+
+        if (!surfobj) {
+            surf = SDL_CreateRGBSurface(
+                0,
+                self->boundsRect.right,
+                self->boundsRect.bottom,
+                24,
+                0xFF<<16,
+                0xFF<<8,
+                0xFF,
+                0);
+            
+        } else {
+            surf = PySurface_AsSurface(surfobj);
+        }
+
+        if (!surf)
+            return NULL;
+
+        if (surf->w != self->boundsRect.right || surf->h != self->boundsRect.bottom) {
+            return RAISE (PyExc_ValueError, 
+                          "Destination surface not the correct width or height.");
+        }
+        /*is dit nodig op osx... */
+        Py_BEGIN_ALLOW_THREADS;
+        
+        if (!mac_read_frame(self, surf))
+            return NULL;
+        Py_END_ALLOW_THREADS;
+        if (!surf)
+            return NULL;
+
+        if (surfobj) {
+            Py_INCREF (surfobj);
+            return surfobj;
+        } else {
+            return PySurface_New (surf);
+        }
+#endif
+    Py_RETURN_NONE;
 }
 
 /* get_raw() - returns an unmodified image as a string from the buffer */
-PyObject* camera_get_raw(PyCameraObject* self)
-{
+PyObject* camera_get_raw(PyCameraObject* self) {
 #if defined(__unix__)
     return v4l2_read_raw(self);
+#elif defined(__APPLE__)
+    return mac_read_raw(self);
 #endif
     Py_RETURN_NONE;
 }
@@ -318,8 +404,7 @@
  
 /* converts from rgb Surface to yuv or hsv */
 /* TODO: Allow for conversion from yuv and hsv to all */
-void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace)
-{   
+void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace) {   
     switch (cspace) {
         case YUV_OUT:
             rgb_to_yuv (src->pixels, dst->pixels, src->h * src->w, 0, src->format);
@@ -671,8 +756,7 @@
 }
 
 /* Converts from rgb444 (R444) to rgb24 (RGB3) */
-void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format)
-{
+void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) {
     Uint8 *s, *d8;
     Uint16 *d16;
     Uint32 *d32;
@@ -731,8 +815,7 @@
 /* convert from 4:2:2 YUYV interlaced to RGB */
 /* colorspace conversion routine from libv4l. Licensed LGPL 2.1
    (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> */
-void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format)
-{
+void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format) {
     Uint8 *s, *d8;
     Uint16 *d16;
     Uint32 *d32;
@@ -802,8 +885,7 @@
 }
 
 /* turn yuyv into packed yuv. */
-void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format)
-{
+void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format) {
     Uint8 *s, *d8;
     Uint8 y1, u, y2, v;
     Uint16 *d16;
@@ -896,8 +978,7 @@
 /* FIXME: Seems to be grayscale and kind of dark on the OLPC XO
           Maybe the result of a different Bayer color order on the screen? */
 /* TODO: Certainly not the most efficient way of doing this conversion. */
-void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format)
-{
+void sbggr8_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) {
     Uint8 *rawpt, *d8;
     Uint16 *d16;
     Uint32 *d32;
@@ -999,8 +1080,7 @@
 
 /* convert from YUV 4:2:0 (YU12) to RGB24 */
 /* based on v4lconvert_yuv420_to_rgb24 in libv4l (C) 2008 Hans de Goede. LGPL */
-void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format)
-{
+void yuv420_to_rgb (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) {
     int rshift, gshift, bshift, rloss, gloss, bloss, i, j, u1, v1, rg, y;
     const Uint8 *y1, *y2, *u, *v;
     Uint8 *d8_1, *d8_2;
@@ -1190,8 +1270,7 @@
 }
 
 /* turn yuv420 into packed yuv. */
-void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format)
-{   
+void yuv420_to_yuv (const void* src, void* dst, int width, int height, SDL_PixelFormat* format) {   
     const Uint8 *y1, *y2, *u, *v;
     Uint8 *d8_1, *d8_2;
     Uint16 *d16_1, *d16_2;
@@ -1290,12 +1369,14 @@
 
 }
 
+
+
 /*
  * Python API stuff
  */
- 
-PyMethodDef cameraobj_builtins[] =
-{
+
+/* Camera class definition */
+PyMethodDef cameraobj_builtins[] = {
     { "start", (PyCFunction) camera_start, METH_NOARGS, DOC_CAMERASTART },
     { "stop", (PyCFunction) camera_stop, METH_NOARGS, DOC_CAMERASTOP },
     { "get_controls", (PyCFunction) camera_get_controls, METH_NOARGS, DOC_CAMERAGETCONTROLS },
@@ -1307,19 +1388,16 @@
     { NULL, NULL, 0, NULL }
 };
 
-void camera_dealloc (PyObject* self)
-{
+void camera_dealloc (PyObject* self) {
     free(((PyCameraObject*) self)->device_name);
     PyObject_DEL (self);
 }
 
-PyObject* camera_getattr(PyObject* self, char* attrname)
-{
+PyObject* camera_getattr(PyObject* self, char* attrname) {
     return Py_FindMethod(cameraobj_builtins, self, attrname);
 }
 
-PyTypeObject PyCamera_Type =
-{
+PyTypeObject PyCamera_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
     "Camera",
@@ -1328,21 +1406,21 @@
     camera_dealloc,
     0,
     camera_getattr,
-    NULL,			/*setattr*/
-    NULL,			/*compare*/
-    NULL,			/*repr*/
-    NULL,			/*as_number*/
-    NULL,			/*as_sequence*/
-    NULL,			/*as_mapping*/
+    NULL,			        /*setattr*/
+    NULL,			        /*compare*/
+    NULL,			        /*repr*/
+    NULL,			        /*as_number*/
+    NULL,			        /*as_sequence*/
+    NULL,			        /*as_mapping*/
     (hashfunc)NULL, 		/*hash*/
     (ternaryfunc)NULL,		/*call*/
     (reprfunc)NULL, 		/*str*/
     0L,0L,0L,0L,
-    DOC_PYGAMECAMERACAMERA /* Documentation string */
+    DOC_PYGAMECAMERACAMERA  /* Documentation string */
 };
 
-PyObject* Camera (PyCameraObject* self, PyObject* arg)
-{
+PyObject* Camera (PyCameraObject* self, PyObject* arg) {
+# if defined(__unix__)
     int w, h;
     char* dev_name = NULL;
     char* color = NULL;
@@ -1384,36 +1462,78 @@
     }
     
     return (PyObject*)cameraobj;
+    
+# elif defined(__APPLE__)
+    int w, h;
+    char* dev_name = NULL;
+    char* color = NULL;
+    PyCameraObject *cameraobj;
+    
+    w = DEFAULT_WIDTH;
+    h = DEFAULT_HEIGHT;
+    
+    if (!PyArg_ParseTuple(arg, "s|(ii)s", &dev_name, &w, &h, &color))
+        return NULL;
+    
+    cameraobj = PyObject_NEW (PyCameraObject, &PyCamera_Type);
+    
+    if (cameraobj) {
+        cameraobj->device_name = (char*) malloc((strlen(dev_name)+1)*sizeof(char));
+        strcpy(cameraobj->device_name, dev_name);
+        if (color) {
+            if (!strcmp(color, "YUV")) {
+                cameraobj->color_out = YUV_OUT;
+            } else if (!strcmp(color, "HSV")) {
+                cameraobj->color_out = HSV_OUT;
+            } else {
+                cameraobj->color_out = RGB_OUT;
+            }
+        } else {
+            cameraobj->color_out = RGB_OUT;
+        }
+        cameraobj->component = NULL;
+        cameraobj->channel = NULL;
+        cameraobj->gworld = NULL;
+        cameraobj->boundsRect.top = 0;                   
+        cameraobj->boundsRect.left = 0;
+        cameraobj->boundsRect.bottom = h;
+        cameraobj->boundsRect.right = w;
+        cameraobj->size =  w * h;
+        cameraobj->hflip = 0;
+        cameraobj->vflip = 0;
+    }
+    
+    return (PyObject*)cameraobj;    
+    # endif
 }
 
-PyMethodDef camera_builtins[] =
-{
-    { "colorspace", surf_colorspace, METH_VARARGS, DOC_PYGAMECAMERACOLORSPACE },
-    { "list_cameras", list_cameras, METH_NOARGS, DOC_PYGAMECAMERALISTCAMERAS },
-    { "Camera", (PyCFunction) Camera, METH_VARARGS, DOC_PYGAMECAMERACAMERA },
-    { NULL, NULL, 0, NULL }
+/* Camera module definition */
+PyMethodDef camera_builtins[] = {
+    {"colorspace", surf_colorspace, METH_VARARGS, DOC_PYGAMECAMERACOLORSPACE },
+    {"list_cameras", list_cameras, METH_NOARGS, DOC_PYGAMECAMERALISTCAMERAS },
+    {"Camera", (PyCFunction) Camera, METH_VARARGS, DOC_PYGAMECAMERACAMERA },
+    {NULL, NULL, 0, NULL }
 };
  
-void init_camera(void)
-{
-  PyObject *module, *dict;
-  /* imported needed apis; Do this first so if there is an error
-     the module is not loaded.
-  */
-  import_pygame_base ();
-  if (PyErr_Occurred ()) {
-    return;
-  }
-  import_pygame_surface ();
-  if (PyErr_Occurred ()) {
-    return;
-  }
+void init_camera(void) {
+    PyObject *module, *dict;
+    /* imported needed apis; Do this first so if there is an error
+     * the module is not loaded.
+     */
+    import_pygame_base();
+    if (PyErr_Occurred()) {
+        return;
+    }
+    import_pygame_surface();
+    if (PyErr_Occurred()) {
+        return;
+    }
 
-  /* type preparation */
-  PyType_Init(PyCamera_Type);
+    /* type preparation */
+    PyType_Init(PyCamera_Type);
   
-  /* create the module */
-  module = Py_InitModule3("_camera", camera_builtins, DOC_PYGAMECAMERA);
-  dict = PyModule_GetDict(module);
-  PyDict_SetItemString(dict, "CameraType", (PyObject *)&PyCamera_Type);
+    /* create the module */
+    module = Py_InitModule3("_camera", camera_builtins, DOC_PYGAMECAMERA);
+    dict = PyModule_GetDict(module);
+    PyDict_SetItemString(dict, "CameraType", (PyObject *)&PyCamera_Type);
 }