simple_take.c

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

Generated on 19 Jun 2015 by  doxygen 1.4.7