simple_take.c

Go to the documentation of this file.
00001 
00027 #include "edtinc.h"
00028 
00029 static void usage(char *progname);
00030 static void 
00031 save_image(u_char * image_p, int width, int height, int depth,
00032            char *basename, int count);
00033 
00034 /*
00035  *  NO_MAIN isn't that simple, but is for VXWORKS so we can type
00036  * name of subroutine instead of executable and not have multiple mains
00037  * (all in one namespace)
00038  */
00039 
00040 /*
00041  * main
00042  */
00043 #ifdef NO_MAIN
00044 #include "opt_util.h"
00045 char *argument ;
00046 int option ;
00047 simple_take(char *command_line)
00048 #else
00049 int
00050 main(argc, argv)
00051 int     argc;
00052 char  **argv;
00053 #endif
00054 {
00055     int     i;
00056     int     unit = 0;
00057     int     overrun, overruns=0;
00058     int     timeouts, last_timeouts = 0;
00059     int     recovering_timeout = FALSE;
00060     char   *progname ;
00061     char   *cameratype;
00062     char    bmpfname[128];
00063     int     numbufs = 4;
00064     int     started;
00065     u_char *image_p;
00066     PdvDev *pdv_p;
00067     char    errstr[64];
00068     int     loops = 1;
00069     int     width, height, depth;
00070     char    edt_devname[128];
00071     int     channel = 0;
00072 #ifdef NO_MAIN
00073     char **argv  = 0 ;
00074     int argc = 0 ;
00075     opt_create_argv("simple_take",command_line,&argc,&argv);
00076 #endif
00077 
00078     progname = argv[0];
00079 
00080 
00081     edt_devname[0] = '\0';
00082     *bmpfname = '\0';
00083 
00084     /*
00085      * process command line arguments
00086      */
00087     --argc;
00088     ++argv;
00089     while (argc && ((argv[0][0] == '-') || (argv[0][0] == '/')))
00090     {
00091         switch (argv[0][1])
00092         {
00093         case 'u':               /* device unit number */
00094             ++argv;
00095             --argc;
00096             if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00097                 unit = atoi(argv[0]);
00098             else
00099                 strncpy(edt_devname, argv[0], sizeof(edt_devname) - 1);
00100             break;
00101 
00102         case 'c':               /* device unit number */
00103             ++argv;
00104             --argc;
00105             if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00106                 channel = atoi(argv[0]);
00107             break;
00108 
00109         case 'N':
00110             ++argv;
00111             --argc;
00112             numbufs = atoi(argv[0]);
00113             break;
00114 
00115         case 'b':               /* bitmap save filename */
00116             ++argv;
00117             --argc;
00118             strcpy(bmpfname, argv[0]);
00119             break;
00120 
00121         case 'l':
00122             ++argv;
00123             --argc;
00124             loops = atoi(argv[0]);
00125             break;
00126 
00127         case '-':
00128                         if (strcmp(argv[0], "--help") == 0) {
00129                                 usage(progname);
00130                                 exit(0);
00131                         } else {
00132                                 fprintf(stderr, "unknown option: %s\n", argv[0]);
00133                                 usage(progname);
00134                                 exit(1);
00135                         }
00136                         break;
00137 
00138 
00139         default:
00140             fprintf(stderr, "unknown flag -'%c'\n", argv[0][1]);
00141         case '?':
00142         case 'h':
00143             usage(progname);
00144             exit(0);
00145         }
00146         argc--;
00147         argv++;
00148     }
00149 
00150     /*
00151      * open the interface
00152      * 
00153      * EDT_INTERFACE is defined in edtdef.h (included via edtinc.h)
00154      *
00155      * edt_parse_unit_channel and pdv_open_channel) are equivalent to
00156      * edt_parse_unit and pdv_open except for the extra channel arg and
00157      * would normally be 0 unless there's another camera (or simulator)
00158      * on the second channel (camera link) or daisy-chained RCI (PCI FOI)
00159      */
00160     if (edt_devname[0])
00161     {
00162         unit = edt_parse_unit_channel(edt_devname, edt_devname, EDT_INTERFACE, &channel);
00163     }
00164     else
00165     {
00166         strcpy(edt_devname, EDT_INTERFACE);
00167     }
00168 
00169     if ((pdv_p = pdv_open_channel(edt_devname, unit, channel)) == NULL)
00170     {
00171         sprintf(errstr, "pdv_open_channel(%s%d_%d)", edt_devname, unit, channel);
00172         pdv_perror(errstr);
00173         return (1);
00174     }
00175 
00176     /*
00177      * get image size and name for display, save, printfs, etc.
00178      */
00179     width = pdv_get_width(pdv_p);
00180     height = pdv_get_height(pdv_p);
00181     depth = pdv_get_depth(pdv_p);
00182     cameratype = pdv_get_cameratype(pdv_p);
00183 
00184     /*
00185      * allocate four buffers for optimal pdv ring buffer pipeline (reduce if
00186      * memory is at a premium)
00187      */
00188     pdv_multibuf(pdv_p, numbufs);
00189 
00190     printf("reading %d image%s from '%s'\nwidth %d height %d depth %d\n",
00191            loops, loops == 1 ? "" : "s", cameratype, width, height, depth);
00192 
00193     /*
00194      * prestart the first image or images outside the loop to get the
00195      * pipeline going. Start multiple images unless force_single set in
00196      * config file, since some cameras (e.g. ones that need a gap between
00197      * images or that take a serial command to start every image) don't
00198      * tolerate queueing of multiple images
00199      */
00200     if (pdv_p->dd_p->force_single)
00201     {
00202         pdv_start_image(pdv_p);
00203         started = 1;
00204     }
00205     else
00206     {
00207         pdv_start_images(pdv_p, numbufs);
00208         started = numbufs;
00209     }
00210 
00211     for (i = 0; i < loops; i++)
00212     {
00213         /*
00214          * get the image and immediately start the next one (if not the last
00215          * time through the loop). Processing (saving to a file in this case)
00216          * can then occur in parallel with the next acquisition
00217          */
00218         printf("image %d\r", i + 1);
00219         fflush(stdout);
00220         image_p = pdv_wait_image(pdv_p);
00221 
00222         if (overrun = (edt_reg_read(pdv_p, PDV_STAT) & PDV_OVERRUN))
00223             ++overruns;
00224 
00225         if (i < loops - started)
00226         {
00227             pdv_start_image(pdv_p);
00228         }
00229         timeouts = pdv_timeouts(pdv_p);
00230 
00231         /*
00232          * check for timeouts or data overruns -- timeouts occur when data
00233          * is lost, camera isn't hooked up, etc, and application programs
00234          * should always check for them. data overruns usually occur as a
00235          * result of a timeout but should be checked for separately since
00236          * ROI can sometimes mask timeouts
00237          */
00238         if (timeouts > last_timeouts)
00239         {
00240             /*
00241              * pdv_timeout_cleanup helps recover gracefully after a timeout,
00242              * particularly if multiple buffers were prestarted
00243              */
00244             pdv_timeout_restart(pdv_p, TRUE);
00245             last_timeouts = timeouts;
00246             recovering_timeout = TRUE;
00247             printf("\ntimeout....\n");
00248         } else if (recovering_timeout)
00249         {
00250             pdv_timeout_restart(pdv_p, TRUE);
00251             recovering_timeout = FALSE;
00252             printf("\nrestarted....\n");
00253         }
00254         if (*bmpfname)
00255             save_image(image_p, width, height, depth, bmpfname, i);
00256     }
00257     puts("");
00258 
00259     printf("%d images %d timeouts %d overruns\n", loops, last_timeouts, overruns);
00260 
00261     /*
00262      * if we got timeouts it indicates there is a problem
00263      */
00264     if (last_timeouts)
00265         printf("check camera and connections\n");
00266     pdv_close(pdv_p);
00267 
00268     exit(0);
00269 }
00270 
00271 static void
00272 save_image(u_char * image_p, int s_width, int s_height, int s_depth, char *tmpname, int count)
00273 {
00274     int     s_db = bits2bytes(s_depth);
00275     u_char *bbuf = NULL;
00276     char    fname[256];
00277 
00278 #ifdef _NT_
00279     if ((strcmp(&tmpname[strlen(tmpname) - 4], ".bmp") == 0)
00280         || (strcmp(&tmpname[strlen(tmpname) - 4], ".BMP") == 0))
00281         tmpname[strlen(tmpname) - 4] = '\0';
00282     sprintf(fname, "%s%02d.bmp", tmpname, count);
00283 #else
00284     if ((strcmp(&tmpname[strlen(tmpname) - 4], ".ras") == 0)
00285         || (strcmp(&tmpname[strlen(tmpname) - 4], ".RAS") == 0))
00286         tmpname[strlen(tmpname) - 4] = '\0';
00287     sprintf(fname, "%s%02d.ras", tmpname, count);
00288 #endif
00289 
00290     /*
00291      * write bmp file on Windows systems, or Sun Raster on Unux/Linux
00292      * systems. Switch on number of bytes per pixel
00293      */
00294     switch (s_db)
00295     {
00296     case 1:
00297 #ifdef _NT_
00298 
00299         dvu_write_bmp(fname, image_p, s_width, s_height);
00300 #else
00301         printf("writing %dx%dx%d raster file to %s\n",
00302                s_width, s_height, s_depth, fname);
00303 
00304         dvu_write_rasfile(fname, (u_char *) image_p, s_width, s_height);
00305 #endif
00306         break;
00307 
00308     case 2:
00309         printf("converting %dx%dx%d image to 8 bits, writing to %s\n",
00310                s_width, s_height, s_depth, fname);
00311 
00312 #ifdef _NT_
00313         if (!bbuf)
00314             bbuf = (u_char *) pdv_alloc(s_width * s_height);
00315 
00316         if (bbuf == NULL)
00317         {
00318             pdv_perror("data buf malloc");
00319             exit(1);
00320         }
00321         dvu_word2byte((u_short *) image_p, (u_char *) bbuf,
00322                       s_width * s_height, s_depth);
00323         dvu_write_bmp(fname, bbuf, s_width, s_height);
00324 #else
00325         dvu_write_rasfile16(fname, (u_char *) image_p, s_width, s_height, s_depth);
00326 #endif
00327         break;
00328 
00329     case 3:
00330         printf("writing %dx%dx%d bmp file to %s\n",
00331                s_width, s_height, s_depth, fname);
00332 
00333 #ifdef _NT_
00334         dvu_write_bmp_24(fname, (u_char *) image_p, s_width, s_height);
00335 #else
00336         dvu_write_rasfile24(fname, (u_char *) image_p, s_width, s_height);
00337 #endif
00338 
00339         break;
00340 
00341     default:
00342         printf("invalid image depth for file write...!\n");
00343         break;
00344     }
00345 }
00346 
00347 
00348 void
00349 usage(char *progname)
00350 {
00351     puts("");
00352     printf("%s: simple example program that acquires images from an\n", progname);
00353     printf("EDT Digital Video Interface board (PCI DV, PCI DVK, etc.)\n");
00354     puts("");
00355     printf("usage: %s [-b fname] [-l loops] [-N numbufs] [-u unit] [-c channel]\n", progname);
00356 #ifdef _NT_
00357     printf("  -b fname        output to MS bitmap file\n");
00358 #else
00359     printf("  -b fname        output to Sun Raster file\n");
00360 #endif
00361     printf("  -l loops        number of loops (images to take)\n");
00362     printf("  -N numbufs      number of ring buffers (see users guide) (default 4)\n");
00363     printf("  -u unit         %s unit number (default 0)\n", EDT_INTERFACE);
00364     printf("  -c channel      %s channel number (default 0)\n", EDT_INTERFACE);
00365     printf("  -h              this help message\n");
00366 }

Generated on Mon May 12 16:38:59 2008 by  doxygen 1.5.1