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

Generated on Mon Mar 21 14:14:55 2011 by  doxygen 1.4.7