take.c

Go to the documentation of this file.
00001 
00020 #include "edtinc.h"
00021 
00022 #define FOURGB ((double) (0x1000000) * 16.0)
00023 
00024 /*
00025  * defines
00026  */
00027 #define STARTSIG 0xa5
00028 #define ENDSIG   0x5a
00029 
00030 int
00031 get_usps_lines_xferred(PdvDev *pdv_p, int buffer)
00032 {
00033         u_int rasterlines;
00034 
00035         rasterlines = buffer % pdv_p->ring_buffer_numbufs;
00036 
00037         edt_ioctl(pdv_p, EDTG_LINES_XFERRED, &rasterlines);
00038 
00039         return rasterlines;
00040 
00041 }
00042 
00043 /*
00044  * fwd ref
00045  */
00046 void
00047 crop_and_subsample(int subsample, int src_width, int src_height,
00048                 int x0, int y0, int x1, int y1, u_char * src, u_char * dst);
00049 void
00050         resolve_fname(char *fname, char *newname, int loops, char *ext);
00051 static void usage(char *progname);
00052 
00053 /*
00054  * globals
00055  */
00056 int     ASnum = 0;
00057 int     ASinc = 1;
00058 
00059 void
00060 dumpbuf(char *name, u_short * buf, int size)
00061 {
00062     FILE   *fp = fopen(name, "wb");
00063 
00064     fwrite(buf, sizeof(short), size / 2, fp);
00065     fclose(fp);
00066 }
00067 
00068 static int quiet = 0;
00069 
00070 /*******************************
00071  *
00072  * simple method to suppress messages
00073  * using quiet variable
00074  *
00075  *******************************/
00076 
00077 int
00078 take_printf(char *format,...)
00079 
00080 {
00081     va_list stack;
00082 
00083     if (quiet)
00084         return 0;
00085 
00086     va_start(stack, format);
00087 
00088     return vprintf(format, stack);
00089 
00090 }
00091 
00092 int
00093 write_image_file(char *tmpname, u_char * image_p,
00094                  int s_width, int s_height, int s_depth)
00095 {
00096     int     s_db = bits2bytes(s_depth);
00097 #ifdef _NT_
00098     u_char *bbuf = NULL;
00099 #endif
00100         int retval;
00101 
00102     /*
00103      * write bmp file on Windows systems, or Sun Raster on Unux/Linux
00104      * systems. Switch on number of bytes per pixel
00105      */
00106     switch (s_db)
00107     {
00108     case 1:
00109 #ifdef _NT_
00110         take_printf("writing %dx%dx%d bmp file to %s\n",
00111                     s_width, s_height, s_depth, tmpname);
00112 
00113         retval = dvu_write_bmp(tmpname, image_p, s_width, s_height);
00114 #else
00115         take_printf("writing %dx%dx%d raster file to %s\n",
00116                     s_width, s_height, s_depth, tmpname);
00117 
00118         retval = dvu_write_rasfile(tmpname, (u_char *) image_p, s_width, s_height);
00119 #endif
00120         break;
00121 
00122     case 2:
00123         take_printf("converting %dx%dx%d image to 8 bits, writing to %s\n",
00124                     s_width, s_height, s_depth, tmpname);
00125 
00126 #ifdef _NT_
00127         if (!bbuf)
00128             bbuf = (u_char *) pdv_alloc(s_width * s_height);
00129 
00130         if (bbuf == NULL)
00131         {
00132             pdv_perror("data buf malloc");
00133             exit(1);
00134         }
00135         dvu_word2byte((u_short *) image_p, (u_char *) bbuf,
00136                       s_width * s_height, s_depth);
00137         retval = dvu_write_bmp(tmpname, bbuf, s_width, s_height);
00138 #else
00139         retval = dvu_write_rasfile16(tmpname, (u_char *) image_p, s_width, s_height, s_depth);
00140 #endif
00141         break;
00142 
00143     case 3:
00144         take_printf("writing %dx%dx%d bmp file to %s\n",
00145                     s_width, s_height, s_depth, tmpname);
00146 
00147 #ifdef _NT_
00148         retval = dvu_write_bmp_24(tmpname, (u_char *) image_p, s_width, s_height);
00149 #else
00150         retval = dvu_write_rasfile24(tmpname, (u_char *) image_p, s_width, s_height);
00151 #endif
00152 
00153         break;
00154 
00155     default:
00156         take_printf("invalid image depth for file write...!\n");
00157         return -1;
00158         break;
00159     }
00160 
00161     return retval;
00162 }
00163 
00164 /* keep this until we find out why without it, process cannot exit */
00165 /* even though wakeup from WAITBUF detects interrupt and does wakeup */
00166 
00167 int GetOut = 0 ;
00168 #ifdef __APPLE__
00169 static int
00170 gotit()
00171 {
00172         GetOut = 1 ;
00173         return 0;
00174 }
00175 #endif
00176 
00177 char cmdstr[80] ;
00178 
00179 /*
00180  * main
00181  */
00182 #ifdef NO_MAIN
00183 #include "opt_util.h"
00184 char   *argument;
00185 int     option;
00186 
00187 int
00188 take(char *command_line)
00189 #else
00190 int
00191 main(int argc, char *argv[])
00192 #endif
00193 {
00194     int     i, lc;
00195     int     waited = 0;
00196     int     unit = 0;
00197     char   *unitstr = "0";
00198     int     loops = 1;
00199     int     wait_for_enter = 0;
00200     int     user_delay = 0;
00201     int     numbufs = 1;
00202     int     do_ring = 0;
00203     int     verbose = 0;
00204     int     do_file = 0;
00205     int     rbtimeout = 0;
00206     int     bytesread;
00207     int     started;
00208     int     done;
00209     char    cfgfname[128];
00210     char    outfname[128];
00211     char    rawfname[128];
00212     char    edt_devname[256];
00213     char   *progname = "take";
00214     u_char *imagebuf = NULL;
00215     u_char *subimage = NULL;
00216     u_char *image_p = NULL;
00217     PdvDev *pdv_p;
00218     int     timeouts=0, last_timeouts=0;
00219     int     in_timeout_cleanup = 0;
00220     int     overruns=0, overrun;
00221     char    tmpname[128];
00222     int     subsample = 0, crop = 0;
00223     int     debug_timeout = 0;
00224     int     width, height, depth, imagesize, dmasize, bufsize, db;
00225     int     s_width, s_height, s_depth, s_size, s_db;
00226     int     crop_x0, crop_x1, crop_y0, crop_y1;
00227     int     exposure, gain, offset;
00228     int     set_exposure = 0, set_gain = 0, set_offset = 0;
00229     int     set_timeout = 0;
00230     int     do_timestamp = 0;
00231     int     do_timetype = 0;
00232     int     timetype = 0;
00233     int     do_lasttest = 0;
00234     int     timeout_val = 0;
00235     int     enable_burst_en = 1;
00236     int     si = -1;
00237     int     sc = -1;
00238     int     vskip, vactv, hskip, hactv;
00239     int     set_roi = 0;
00240     int     unset_roi = 0;
00241     int     checksig = 0, checkcount = 0;
00242     int     checksim = 0;
00243     int     checkclsim = 0;
00244     int     checkclk = 0;
00245     int     badstart = 0, badend = 0;
00246     int     just_print_the_last_one = 0;
00247     u_short startsig = STARTSIG, endsig = ENDSIG;
00248     u_int   sigcount;
00249     int     siginit = 0;
00250     char    errstr[64];
00251     u_int   timestamp[2];
00252     u_int   freqbuf[2];
00253     double  dtime;
00254     double  svtime = 0;
00255     double  curtime = 0;
00256     double  frequency = 0;
00257     double  sumsize = 0;
00258     int     checkfrm = 0;
00259     int     binning = 0;
00260     int     opto_trigger = 0;
00261     int     fldid_trigger = 0;
00262 
00263     int     channel = 0;
00264 
00265 
00266     int     mosaic = 0;
00267     int     mosaic_sample = 0;
00268     int     sample_height = 10;
00269     int     mosaic_size = 0;
00270     int     mosaic_width = 0;
00271     int     mosaic_height = 0;
00272     char    dvcmode[8];
00273     unsigned char *mosaic_ptr = NULL;
00274     unsigned char *mosaic_image = NULL;
00275     int     arg_channel = -1;
00276     int     dl;
00277 
00278     int noreset = 0;
00279 
00280 #ifdef NO_MAIN
00281     char  **argv = 0;
00282     int     argc = 0;
00283 
00284     opt_create_argv("take", command_line, &argc, &argv);
00285 #endif
00286 
00287 
00288     cfgfname[0] = '\0';
00289     rawfname[0] = '\0';
00290     outfname[0] = '\0';
00291     edt_devname[0] = '\0';
00292     dvcmode[0] = '\0';
00293     tmpname[0] = '\0';
00294     ASnum = 0;
00295     quiet = 0 ;
00296     siginit = 0 ;
00297 
00298 #ifdef __APPLE__
00299 /* debug for interrupted wakeup */
00300 signal(SIGINT,gotit);
00301 #endif
00302 
00303     --argc;
00304     ++argv;
00305     while (argc && ((argv[0][0] == '-') || (argv[0][0] == '/')))
00306     {
00307         switch (argv[0][1])
00308         {
00309         case 'u':               /* device unit number */
00310             ++argv;
00311             --argc;
00312             unitstr = argv[0];
00313             break;
00314 
00315         case 'B':               /* turn off burst enable */
00316             ++argv;
00317             --argc;
00318             if (argc > 0)
00319                 enable_burst_en = atoi(argv[0]);
00320             else
00321                 enable_burst_en = 1;
00322             break;
00323 
00324         case 'v':               /* verbose */
00325             verbose = 1;
00326             break;
00327 
00328         case 'w':               /* wait for user <cr> between frames */
00329             wait_for_enter = 1;
00330             break;
00331 
00332         case 'T':               /* on timeout, dump data to timeout.raw */
00333             debug_timeout = 1;
00334             break;
00335 
00336         case 'd':               /* timestamp */
00337             do_timestamp = 1;
00338             break;
00339 
00340         case 'D':               /* dvc mode setting (diagnostic) */
00341             ++argv;
00342             --argc;
00343             strcpy(dvcmode, argv[0]);
00344             break;
00345 
00346         case 'X':               /* use timer */
00347             ++argv;
00348             --argc;
00349             timetype = atoi(argv[0]);
00350             do_timetype = 1;
00351             break;
00352 
00353         case 'y':
00354             opto_trigger = 1;
00355             break;
00356 
00357         case 'Y':
00358             fldid_trigger = 1;
00359             break;
00360 
00361         case 'j':
00362             just_print_the_last_one = 1;
00363             break;
00364 
00365         case 'L':
00366             do_lasttest = 1;    /* freerun/bytecount with wait for next frame */
00367             break;
00368 
00369         case 'm':               /* microsec sleep between frames */
00370             ++argv;
00371             --argc;
00372             if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00373                 user_delay = atoi(argv[0]);
00374             break;
00375 
00376         case 'N':               /* specify numbufs */
00377             ++argv;
00378             --argc;
00379             do_ring = 1;
00380             numbufs = atoi(argv[0]);
00381             break;
00382 
00383         case 'H':               /* check count signature from testgen */
00384             checksim = 1;
00385             checksig = 0;
00386             checkcount = 0;
00387             break;
00388 
00389         case 'P':               /* check count signature from PCI CD sim */
00390             checkcount = 1;
00391             checksig = 0;
00392             break;
00393 
00394         case 'p':               /* check fixed signature from PCI CD sim */
00395             checksig = 1;
00396             checkcount = 0;
00397             break;
00398 
00399         case 'G':               /* check count signature from testgen */
00400             checkclsim = 1;
00401             checksim = 0;
00402             checksig = 0;
00403             checkcount = 0;
00404             break;
00405 
00406         case 'q':               /* binning */
00407             ++argv;
00408             --argc;
00409             binning = atoi(argv[0]);
00410             break;
00411 
00412         case 'Q':               /* turn on quiet mode */
00413             quiet = 1;
00414             break;
00415 
00416         case 't':               /* microsec sleep between frames */
00417             /* if no subarg, set to -1 (auto timeout) */
00418             if ((argc < 2) || (argv[1][0] == '-'))
00419             {
00420                 set_timeout = 1;
00421                 timeout_val = -1;
00422             }
00423             else
00424             {
00425                 ++argv;
00426                 --argc;
00427                 set_timeout = 1;
00428                 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00429                     timeout_val = atoi(argv[0]);
00430             }
00431             break;
00432 
00433         case 'l':               /* loops */
00434             ++argv;
00435             --argc;
00436             loops = atoi(argv[0]);
00437             break;
00438 
00439         case 'f':               /* save filename */
00440             ++argv;
00441             --argc;
00442             strcpy(rawfname, argv[0]);
00443             do_file = 1;
00444             break;
00445 
00446         case 'S':               /* subsample */
00447             ++argv;
00448             --argc;
00449             subsample = atoi(argv[0]);
00450             break;
00451 
00452         case 'C':               /* crop x0, y0, x1, y1 */
00453             crop = 1;
00454             ++argv;
00455             --argc;
00456             crop_x0 = atoi(argv[0]);
00457 
00458             ++argv;
00459             --argc;
00460             crop_y0 = atoi(argv[0]);
00461 
00462             ++argv;
00463             --argc;
00464             crop_x1 = atoi(argv[0]);
00465 
00466             ++argv;
00467             --argc;
00468             crop_y1 = atoi(argv[0]);
00469             break;
00470 
00471         case 'n':               /* autosequence start only */
00472             ++argv;
00473             --argc;
00474             ASnum = atoi(argv[0]);
00475             break;
00476 
00477         case 's':               /* autosequence start and inc */
00478             ++argv;
00479             --argc;
00480             ASnum = atoi(argv[0]);
00481             break;
00482 
00483         case 'e':               /* exposure time */
00484             ++argv;
00485             --argc;
00486             set_exposure = 1;
00487             exposure = atoi(argv[0]);
00488             break;
00489 
00490         case 'g':               /* gain */
00491             ++argv;
00492             --argc;
00493             set_gain = 1;
00494             gain = atoi(argv[0]);
00495             break;
00496 
00497         case 'o':               /* offset (blacklevel) */
00498             ++argv;
00499             --argc;
00500             set_offset = 1;
00501             offset = atoi(argv[0]);
00502             break;
00503 
00504         case 'I':               /* # to increment for multiple file writes */
00505             ++argv;
00506             --argc;
00507             ASinc = atoi(argv[0]);
00508             break;
00509 
00510         case 'b':               /* bitmap or sun raster save filename */
00511         case 'i':
00512             ++argv;
00513             --argc;
00514             strcpy(outfname, argv[0]);
00515             do_file = 1;
00516             break;
00517 
00518         case 'c':               /* channel */
00519             ++argv;
00520             --argc;
00521             arg_channel = atoi(argv[0]);
00522             break;
00523 
00524         case 'r':               /* ROI */
00525             if (argc < 5)
00526             {
00527                 usage(progname);
00528                 exit(1);
00529             }
00530             ++argv;
00531             --argc;
00532             hskip = atoi(argv[0]);
00533             ++argv;
00534             --argc;
00535             hactv = atoi(argv[0]);
00536             ++argv;
00537             --argc;
00538             vskip = atoi(argv[0]);
00539             ++argv;
00540             --argc;
00541             vactv = atoi(argv[0]);
00542             set_roi = 1;
00543             break;
00544 
00545         case 'R':               /* disable ROI */
00546             unset_roi = 1;
00547             break;
00548 
00549         case 'O':               /* try noreset - will be obsolete on clink? */
00550             noreset = 1 ;
00551             break;
00552 
00553         case 'x':               /* experimental -- strobe testing */
00554             ++argv;
00555             --argc;
00556             si = atoi(argv[0]);
00557             ++argv;
00558             --argc;
00559             sc = atoi(argv[0]);
00560             break;
00561 
00562         case 'M':               /* mosaic */
00563             mosaic = 1;
00564             break;
00565 
00566         case 'a':               /* call pdv_checkfrm */
00567             checkfrm = 1;
00568             break;
00569         case 'A':
00570             checkclk = 1;
00571             break;
00572 
00573         default:
00574             fprintf(stderr, "unknown flag -'%c'\n", argv[0][1]);
00575         case '?':
00576         case 'h':
00577             usage(progname);
00578             exit(0);
00579         }
00580         argc--;
00581         argv++;
00582     }
00583 
00584 
00585     unit = edt_parse_unit_channel(unitstr, edt_devname, "pdv", &channel);
00586 
00587     if (arg_channel != -1)
00588     {
00589         channel = arg_channel;
00590     }
00591 
00592     unit = edt_parse_unit(unitstr, edt_devname, "pdv");
00593 
00594     /*
00595      * pdv_open_channel is just pdv_open with an extra argument, the channel,
00596      * which is normally 0 unless you're running multiple cameras (2nd base
00597      * mode on a PCI DV C-Link or dasy-chained RCI boxes off a single PCI
00598      * FOI)
00599      */
00600     if ((pdv_p = pdv_open_channel(edt_devname, unit, channel)) == NULL)
00601     {
00602         sprintf(errstr, "pdv_open(%s%d_%d)", edt_devname, unit, channel);
00603         pdv_perror(errstr);
00604         return (1);
00605     }
00606 
00607     if (*dvcmode)
00608         pdv_set_mode_dvc(pdv_p, dvcmode);
00609 
00610     if (set_exposure)
00611         pdv_set_exposure(pdv_p, exposure);
00612 
00613     if (set_gain)
00614         pdv_set_gain(pdv_p, gain);
00615 
00616     if (set_offset)
00617         pdv_set_blacklevel(pdv_p, offset);
00618 
00619     if (set_timeout)
00620         pdv_set_timeout(pdv_p, timeout_val);
00621 
00622     if (opto_trigger)
00623         pdv_enable_external_trigger(pdv_p, PDV_PHOTO_TRIGGER);
00624 
00625     else if (fldid_trigger)
00626         pdv_enable_external_trigger(pdv_p, PDV_FLDID_TRIGGER);
00627 
00628 
00629     if (set_roi)
00630     {
00631         pdv_set_roi(pdv_p, hskip, hactv, vskip, vactv);
00632         pdv_enable_roi(pdv_p, 1);
00633     }
00634     else if (unset_roi)
00635     {
00636         pdv_enable_roi(pdv_p, 0);
00637     }
00638 
00639     if (binning)
00640     {
00641         pdv_set_binning(pdv_p, binning, binning);
00642     }
00643 
00644     if (checksig)
00645         take_printf("checking PCI CD Simulator fixed signature -- use simple_putframe -p\n");
00646     if (checksim)
00647         take_printf("checking testgen signature\n");
00648     if (checkclsim)
00649         take_printf("checking cl simulator signature\n");
00650     if (checkcount)
00651         take_printf("checking PCI CD Simulator count signature -- use simple_putframe -P\n");
00652 
00653     if (do_timetype)
00654     {
00655         edt_set_timetype(pdv_p, EDT_TM_FREQ);
00656         edt_get_reftime(pdv_p, freqbuf);
00657         frequency = (double) freqbuf[0] * FOURGB + freqbuf[1];
00658         edt_set_timetype(pdv_p, timetype);
00659     }
00660 
00661     /*
00662      * set size variables for image and initial subimage
00663      */
00664     width = s_width = pdv_get_width(pdv_p);
00665     height = s_height = pdv_get_height(pdv_p);
00666     depth = s_depth = pdv_get_depth(pdv_p);
00667     db = s_db = bits2bytes(depth);
00668     imagesize = s_size = pdv_get_imagesize(pdv_p);
00669     dmasize = s_size = pdv_get_dmasize(pdv_p);
00670 
00671     subimage = NULL;
00672     /*
00673      * turn off merge
00674      */
00675     edt_set_merge(pdv_p, 0, 0, 0, 0);
00676 
00677     if (s_size <= 0)
00678     {
00679         printf("%s%d: Invalid image size. Make sure device has been initialized.\n", edt_devname, unit);
00680         exit(1);
00681     }
00682  
00683     if (mosaic)
00684     {
00685         mosaic_sample = width * sample_height * db;
00686 
00687         mosaic_size = loops * mosaic_sample;
00688 
00689         mosaic_image = pdv_alloc(mosaic_size);
00690 
00691         mosaic_ptr = mosaic_image;
00692 
00693         mosaic_width = width * db;
00694 
00695         mosaic_height = loops * sample_height;
00696 
00697     }
00698  
00699     if (do_ring)
00700     {
00701         /* Construct a ring buffer */
00702         if (pdv_multibuf(pdv_p, numbufs) == -1)
00703         {
00704             char    msg[64];
00705 
00706             sprintf(msg, "pdv_multibuf(0x%p, %d)", pdv_p, numbufs);
00707             pdv_perror(msg);
00708             return (0);
00709         }
00710     }
00711     else
00712     {
00713         bufsize = ((dmasize > imagesize)? dmasize: imagesize);
00714         imagebuf = (u_char *) pdv_alloc(bufsize);
00715         if (imagebuf == NULL)
00716         {
00717             pdv_perror("data buf malloc");
00718             exit(1);
00719         }
00720     }
00721 
00722     pdv_cl_reset_fv_counter(pdv_p) ;
00723 
00724     /*
00725      * check for crazy subsample and crop values and sort out the params as
00726      * needed
00727      */
00728 
00729     if (do_file && (subsample || crop))
00730     {
00731         if ((subsample < 0)
00732             || (subsample > height / 4)
00733             || (subsample > width / 4))
00734         {
00735             printf("-S <subsample> arg out of range\n");
00736             usage(progname);
00737             exit(1);
00738         }
00739 
00740         /* force subsample since its used as an arg in processing */
00741         if (crop && (subsample == 0))
00742             subsample = 1;
00743 
00744         if (crop)
00745         {
00746             int     tmp;
00747 
00748             if (crop_x0 > crop_x1)
00749             {
00750                 tmp = crop_x1;
00751                 crop_x1 = crop_x0;
00752                 crop_x0 = tmp;
00753             }
00754             if (crop_y0 > crop_y1)
00755             {
00756                 tmp = crop_y1;
00757                 crop_y1 = crop_y0;
00758                 crop_y0 = tmp;
00759             }
00760 
00761             if (crop_x0 < 0)
00762                 crop_x0 = 0;
00763             if (crop_y0 < 0)
00764                 crop_y0 = 0;
00765             if (crop_x1 > width - 1)
00766                 crop_x1 = width - 1;
00767             if (crop_y1 > height - 1)
00768                 crop_y1 = height - 1;
00769         }
00770         else
00771         {
00772             crop_x0 = 0;
00773             crop_y0 = 0;
00774             crop_x1 = width - 1;
00775             crop_y1 = height - 1;
00776         }
00777 
00778         s_width = ((crop_x1 - crop_x0) + subsample) / subsample;
00779         s_height = ((crop_y1 - crop_y0) + subsample) / subsample;
00780         s_size = s_width * s_height * s_db;
00781         subimage = (u_char *) malloc(s_size);
00782     }
00783 
00784     /*
00785      * should normally only be set from the config file as "start_delay:",
00786      * but for testing allow it to be set here too
00787      */
00788     if (user_delay)
00789         pdv_p->dd_p->start_delay = user_delay;
00790 
00791     if (pdv_p->dd_p->start_delay)
00792         take_printf("%d millisecond delay added between images\n", pdv_p->dd_p->start_delay);
00793     if (pdv_p->dd_p->force_single)
00794         take_printf("force_single set; prestarting one image at a time\n");
00795 
00796 #ifdef WIN2K
00797     edt_get_kernel_event(pdv_p, EDT_EVENT_BUF);
00798 #endif
00799 
00800     /*
00801      * acquire the image
00802      */
00803     {
00804         char header_size[32];
00805         if (pdv_get_header_size(pdv_p))
00806             sprintf(header_size,"hdr %d", pdv_get_header_size(pdv_p));
00807         else
00808             header_size[0] = 0;
00809 
00810         take_printf("reading image from %s\nwidth %d height %d depth %d %s total bytes %d \n",
00811                 pdv_get_cameratype(pdv_p),
00812                 pdv_get_width(pdv_p),
00813                 pdv_get_height(pdv_p),
00814                 pdv_get_depth(pdv_p),
00815                 header_size,
00816                 imagesize);
00817     }
00818 
00819     if (do_ring)
00820     {
00821         if (pdv_p->dd_p->force_single)
00822         {
00823             pdv_start_image(pdv_p);
00824             started = 1;
00825         }
00826         else if (do_lasttest)
00827         {
00828             /* start freerun */
00829             pdv_start_images(pdv_p, 0);
00830         }
00831         else if (wait_for_enter)
00832         {
00833             printf("hit enter for first image");
00834             getchar();
00835             pdv_start_images(pdv_p, 1);
00836             started = 1;
00837         }
00838         else
00839         {
00840             pdv_start_images(pdv_p, numbufs);
00841             started = numbufs;
00842         }
00843     }
00844     if (do_lasttest)
00845     {
00846         for (;;)
00847         {
00848             int     ret;
00849             u_char  tmpbuf[80];
00850 
00851 #if 0
00852             printf("return to check");
00853             getchar();
00854 #endif
00855             take_printf("%d done count %x\n", edt_done_count(pdv_p), edt_get_bytecount(pdv_p));
00856             edt_send_msg(pdv_p, 0, "w a07a 6", 8);
00857             ret = edt_serial_wait(pdv_p, 1000, 0);
00858             if (ret > 0)
00859             {
00860                 take_printf("got %d resp\n", ret);
00861                 edt_get_msg(pdv_p, (char *) tmpbuf, sizeof(tmpbuf));
00862                 take_printf("resp %x %x %x\n", tmpbuf[0], tmpbuf[1], tmpbuf[2]);
00863                 if (tmpbuf[2])
00864                 {
00865                     printf("got %s - return to continue", &tmpbuf[2]);
00866                     getchar();
00867                 }
00868             }
00869             else
00870             {
00871                 printf("bad resp from serial wait %d\n", ret);
00872                 getchar();
00873             }
00874             edt_send_msg(pdv_p, 0, "w a07a 4", 8);
00875             ret = edt_serial_wait(pdv_p, 1000, 0);
00876             if (ret > 0)
00877             {
00878                 printf("got %d resp\n", ret);
00879                 edt_get_msg(pdv_p, (char *) tmpbuf, sizeof(tmpbuf));
00880                 printf("resp %x %x %x\n", tmpbuf[0], tmpbuf[1], tmpbuf[2]);
00881                 if (tmpbuf[2])
00882                 {
00883                     printf("got %s - return to continue", &tmpbuf[2]);
00884                     getchar();
00885                 }
00886             }
00887             else
00888             {
00889                 printf("bad resp from serial wait %d\n", ret);
00890                 getchar();
00891             }
00892         }
00893     }
00894     done = 0;
00895     (void) edt_dtime();         /* init time for check */
00896     for (lc = 0; lc < loops && !GetOut; lc++)
00897     {
00898         if (wait_for_enter)
00899         {
00900             printf("hit enter for next image");
00901             getchar();
00902         }
00903 
00904         if (do_ring)
00905         {
00906 
00907             if (do_timestamp)
00908             {
00909                 imagebuf = pdv_wait_image_timed(pdv_p, timestamp);
00910                 switch (timetype)
00911                 {
00912                 case EDT_TM_SEC_NSEC:
00913                     /* secs, nsec */
00914                     curtime = (double) timestamp[0] * 1000000000L + timestamp[1];
00915                     curtime /= 1000000000.0;
00916                     break;
00917                 case EDT_TM_CLICKS:
00918                     /* cpu cycles high32/low32 */
00919                     curtime = (double) timestamp[0] * FOURGB + timestamp[1];
00920                     break;
00921                 case EDT_TM_COUNTER:
00922                     /* counter high32/low32 */
00923                     curtime = (double) timestamp[0] * FOURGB + timestamp[1];
00924                     curtime /= frequency;
00925                     break;
00926                 }
00927                 take_printf("\ntime %3.9f ", curtime);
00928                 if (svtime > 0)
00929                 {
00930                     take_printf(" delta %3.9f ", (curtime - svtime));
00931                 }
00932                 svtime = curtime;
00933             }
00934             else
00935                 imagebuf = pdv_wait_image(pdv_p);
00936             ++waited;
00937         }
00938         else
00939         {
00940             if (wait_for_enter && done == 0)
00941             {
00942                 printf("hit enter for first image");
00943                 getchar();
00944             } 
00945             
00946             bytesread = pdv_read(pdv_p, imagebuf, dmasize);
00947 
00948             if (bytesread != dmasize)
00949             {
00950                 printf("dmasize 0x%x read 0x%x\n", dmasize, bytesread);
00951             }
00952             if (bytesread < 0)
00953             {
00954                 pdv_perror(edt_devname);
00955                 exit(1);
00956             }
00957         }
00958         if (checkfrm)
00959             pdv_checkfrm(pdv_p, (u_short *) imagebuf, width * height, verbose);
00960         timeouts = pdv_timeouts(pdv_p);
00961         if ((overrun = (edt_reg_read(pdv_p, PDV_STAT) & PDV_OVERRUN)))
00962             ++overruns;
00963 
00964         if (timeouts > last_timeouts)
00965         {
00966             bytesread = edt_get_timeout_count(pdv_p);
00967             if (debug_timeout)
00968             {
00969                 FILE   *tmpf;
00970 
00971                 tmpf = fopen("timeout.raw", "wb");
00972                 if (tmpf)
00973                 {
00974                     printf("saving timeout data\n");
00975                     fwrite(imagebuf, imagesize, 1, tmpf);
00976                     fclose(tmpf);
00977                 }
00978                 printf("got timeout xfer %d - return to continue: ",
00979                        edt_get_bytecount(pdv_p));
00980                 getchar();
00981             }
00982 
00983             /*
00984              * pdv_timeout_cleanup recovers from the timeout, in particular
00985              * when you've prestarted multiple buffers returns how many
00986              * buffers were pending before the reset so we can restart that
00987              * many again
00988              */
00989             if (do_ring)
00990             {
00991                 pdv_timeout_restart(pdv_p,TRUE);
00992                 in_timeout_cleanup = TRUE;
00993             }
00994 
00995             last_timeouts = timeouts;
00996             rbtimeout = 1;
00997 
00998         }
00999         else if (in_timeout_cleanup)
01000         {
01001             pdv_timeout_restart(pdv_p,TRUE);
01002             in_timeout_cleanup = FALSE;
01003         }
01004         
01005         done++;
01006 
01007         if (verbose)
01008         {
01009             int     j;
01010             u_char *tmp_p;
01011             int     lastval = 0;
01012 
01013             tmp_p = imagebuf;
01014 
01015             for (j = 0; j < 16; j++)
01016                 take_printf("%02x ", imagebuf[j]);
01017             take_printf("\n");
01018             for (j = imagesize - 16; j < imagesize; j++)
01019                 take_printf("%02x ", imagebuf[j]);
01020             take_printf("\n");
01021             if (checkclk)
01022             {
01023                 for (j = 0; j < 512; j++)
01024                 {
01025                     static int k = 0;
01026                     u_short tmpval = tmp_p[1] << 8 | tmp_p[0];
01027 
01028                     if (tmpval != lastval + 1)
01029                         printf("*");
01030                     else
01031                         printf(" ");
01032                     lastval = tmpval;
01033 
01034                     printf("%04x", tmpval);
01035 
01036                     if ((++k % 16) == 0)
01037                         printf("\n");
01038                     tmp_p += 4;
01039                 }
01040                 printf("\n");
01041             }
01042         }
01043         /*
01044          * check signature pixels from PCI CD simulator if -p or -P flag
01045          * specified -- expects first and last pixel to be count if -p, or
01046          * 0xA5 and 0x5A,  if -P, bombs out on first frame where this is not
01047          * the case
01048          */
01049         if (checksig || checkcount || checksim || checkclsim)
01050         {
01051             u_short bitmask = 0;
01052 
01053             for (i = 0; i < s_depth; i++)
01054                 bitmask += 1 << i;
01055 
01056             /*
01057              * signature counter -- pick up the first one we come to
01058              */
01059             if (checkcount)
01060             {
01061                 if (!siginit)
01062                 {
01063                     startsig = endsig = sigcount = ((u_short *) imagebuf)[0] & bitmask;
01064                     siginit = 1;
01065                 }
01066                 else
01067                     startsig = endsig = sigcount & bitmask;
01068                 ++sigcount;
01069             }
01070             if (checksim)
01071             {
01072                 if (!siginit)
01073                 {
01074                     u_short *sp = (u_short *) imagebuf;
01075 
01076                     startsig = sp[0];
01077                     endsig = sp[(imagesize / 2) - 1];
01078                     siginit = 1;
01079                 }
01080                 else
01081                 {
01082                     startsig ^= 0xffff;
01083                     endsig ^= 0xffff;
01084                 }
01085             }
01086             if (checkclsim)
01087             {
01088                 if (!siginit)
01089                 {
01090                     u_short *sp = (u_short *) imagebuf;
01091 
01092                     startsig = sp[0];
01093                     /* find 3333 */
01094                     if (sp[1] == 0x3333)
01095                     printf("init start  to %04x\n", startsig) ;
01096                     else
01097                     printf("buf is already not aligned\n") ;
01098                     
01099                     siginit = 1;
01100                 }
01101                 else
01102                 {
01103                     if (startsig == 0x7fff) startsig = 0 ;
01104                     else startsig = startsig + 1 ;
01105                 }
01106             }
01107 
01108 
01109             if (depth > 8 || checkclsim)
01110             {
01111                 u_short *sp = (u_short *) imagebuf;
01112                 u_short firstword = sp[0];
01113 
01114                 /*
01115                  * -4 because of one test xilinx which went into grid mode
01116                  * when fifo empty
01117                  */
01118                 u_short lastword = sp[(imagesize / 2) - 4];
01119 
01120                 if (checkclsim)
01121                 {
01122                     u_int frmcnt = pdv_cl_get_fv_counter(pdv_p) ;
01123                     int k ;
01124 
01125                     if (firstword != startsig)
01126                         badstart = 1;
01127                     k = 0 ;
01128                     /* deal with 3333rd image */
01129                     if (sp[0] == 0x3333 && sp[1] == 0x3333) k = 1 ;
01130                     for (; k < imagesize/2 ; k++)
01131                     {
01132                         if (sp[k] == 0x3333)
01133                         {
01134                              if (k != 1)
01135                             {
01136                              printf("image1 3333 at %x\n",k) ;
01137                             badend = 1 ;
01138                             }
01139                             printf("frm %x count %04x stat %04x reg %08x\n",
01140                                     frmcnt,
01141                                     sp[k-1],
01142                                     edt_reg_read(pdv_p,PDV_STAT),
01143                                     edt_reg_read(pdv_p,PDV_CL_JERRYDBG)) ;
01144                             break ;
01145                         }
01146                     }
01147                 }
01148                 else
01149                 {
01150                     if (firstword != startsig)
01151                         badstart = 1;
01152                     if (lastword != endsig)
01153                         badend = 1;
01154                 }
01155 
01156                 if (badstart || badend)
01157                 {
01158                     u_char **buf = edt_buffer_addresses(pdv_p);
01159 
01160                     printf("\n\nstat %04x reg %08x\n",
01161                     edt_reg_read(pdv_p,PDV_STAT),
01162                     edt_reg_read(pdv_p,PDV_CL_JERRYDBG)) ;
01163 
01164                     /*
01165                      * if we just missed a frame, report it and go on
01166                      */
01167                     if (checksim
01168                         && (firstword == (startsig ^ 0xffff))
01169                         && (lastword == (endsig ^ 0xffff)))
01170                     {
01171                         printf("\nMISSED a frame! start %04x s/b %04x, end %04x s/b %04x\n", firstword, startsig, lastword, endsig);
01172                         printf("buffers %d donecount %d PDV_STAT %02x\n",
01173                                waited, edt_done_count(pdv_p), edt_reg_read(pdv_p, PDV_STAT));
01174                         startsig ^= 0xffff;
01175                         endsig ^= 0xffff;
01176                     }
01177                     else
01178                     {
01179                         printf("\nbad signature! start %04x s/b %04x, end %04x s/b %04x\n",
01180                                firstword, startsig, lastword, endsig);
01181                         printf("bad buf addr at %p %04x %04x\n", sp, firstword, lastword);
01182                         printf("buffers %d donecount %d PDV_STAT %02x\n",
01183                                waited, edt_done_count(pdv_p), edt_reg_read(pdv_p, PDV_STAT));
01184 
01185                         edt_stop_buffers(pdv_p);
01186 
01187                         sprintf(cmdstr,"setdebug -d 0 -u %d -g >setdebug.out\n",unit);
01188                         printf("%s\n",cmdstr) ;
01189                         system(cmdstr) ;
01190 
01191 
01192                         printf("dumping %d buffers to buf01.raw, buf02.raw, ....\n",
01193                                numbufs);
01194                         for (i = 0; i < numbufs; i++)
01195                         {
01196                             char    bufname[32];
01197 
01198                             sprintf(bufname, "buf%02d.raw", i);
01199                             printf("dump buf %d from %p\n", i, buf[i]);
01200                             dumpbuf(bufname, (u_short *) buf[i], imagesize);
01201                         }
01202 
01203                         printf("return to continue");
01204                         getchar();
01205                         if (!(checkcount||checkclsim))
01206                         {
01207                             for (i = 0; i < imagesize / 2; i++)
01208                                 if (((sp[i] & bitmask) == startsig)
01209                                     || (sp[i] & bitmask) == endsig)
01210                                     printf("found %04x at %d\n", sp[i], i);
01211                         }
01212                         exit(1);
01213                     }
01214                 }
01215                 /*
01216                  * sp[0] = 0xaaaa ; sp[imagesize/2 - 1] = 0x5555 ;
01217                  */
01218             }
01219             else
01220             {
01221                 u_char *cp = imagebuf;
01222 
01223                 if (cp[0] != startsig)
01224                     badstart = 1;
01225                 if (cp[imagesize - 1] != endsig)
01226                     badend = 1;
01227                 if (badstart || badend)
01228                 {
01229                     printf("\nbad signature! start %02x s/b %02x, end %02x s/b %02x\n",
01230                            cp[0], startsig, cp[imagesize-1], endsig);
01231 
01232                     if (!checkcount)
01233                     {
01234                         for (i = 0; i < imagesize; i++)
01235                             if ((cp[i] == startsig)
01236                                 || (cp[i] == endsig))
01237                                 printf("found %02x at %d\n", cp[i], i);
01238                     }
01239                     exit(1);
01240                 }
01241             }
01242         }
01243         if (do_ring && started < loops)
01244         {
01245             if (!do_lasttest)
01246             {
01247                 pdv_start_images(pdv_p, 1);
01248             }
01249             started++;
01250         }
01251 
01252         /*
01253          * process subimage if needed, set up args for write
01254          */
01255         if (do_file && (subimage != NULL))
01256         {
01257             crop_and_subsample(subsample, width, height,
01258                     crop_x0, crop_y0, crop_x1, crop_y1, imagebuf, subimage);
01259             image_p = subimage;
01260         }
01261         else
01262             image_p = imagebuf;
01263 
01264 
01265         if (pdv_p->dd_p->fval_done)
01266         {       
01267                 int lines = pdv_get_lines_xferred(pdv_p);
01268                 s_size = s_width * lines * s_db;
01269         }
01270 
01271         /*
01272          * write the image to raw data file (no formatting)
01273          */
01274         sumsize += s_size;
01275 
01276         if (*rawfname)
01277         {
01278             resolve_fname(rawfname, tmpname, loops, ".raw");
01279             take_printf("writing %dx%dx%d raw file to %s (actual size %d)\n",
01280                         s_width, s_height, s_depth, tmpname, s_size);
01281 
01282             (void) dvu_write_raw(s_size, image_p, tmpname);
01283         }
01284 
01285         /*
01286          * write the image to Windows bitmap or Sun raster format file and
01287          * fix up the filename extension
01288          */
01289         if (*outfname && !mosaic)
01290         {
01291 #ifdef _NT_
01292             resolve_fname(outfname, tmpname, loops, ".bmp");
01293 #else
01294             resolve_fname(outfname, tmpname, loops, ".ras");
01295 #endif
01296             write_image_file(tmpname, image_p,
01297                              s_width, s_height, s_depth);
01298 
01299 
01300         }
01301         else if (mosaic)
01302         {
01303             memcpy(mosaic_ptr, image_p, mosaic_sample);
01304             mosaic_ptr += mosaic_sample;
01305         }
01306 
01307         dl = pdv_debug_level();
01308 
01309         if (rbtimeout)
01310         {
01311             if (bytesread == 0)
01312                 take_printf("%d images %d timeouts %d overruns 0 bytes", done, timeouts, overruns);
01313             else take_printf("%d images %d timeouts %d overruns %d bytes (%d short)", done, timeouts, overruns, bytesread, dmasize-bytesread);
01314         }
01315         else if (just_print_the_last_one)
01316         {
01317             if (lc == loops-1)
01318             take_printf("%d images %d timeouts %d overruns\n", done, timeouts, overruns);
01319         }
01320         else take_printf("%d images %d timeouts %d overruns", done, timeouts, overruns);
01321 
01322         if (!just_print_the_last_one)
01323         {
01324             if (verbose | rbtimeout | wait_for_enter | (pdv_debug_level() > 0))
01325                 take_printf("\n");
01326             else take_printf("                                \r");
01327         }
01328 
01329         rbtimeout = 0;
01330         fflush(stdout);
01331     }
01332     take_printf("\n");
01333 
01334     if (mosaic && *outfname)
01335     {
01336         write_image_file(outfname, mosaic_image,
01337                          s_width, mosaic_height, s_depth);
01338     }
01339 
01340     if (loops > 3)
01341     {
01342         dtime = edt_dtime();
01343         printf("%lf bytes/sec\n", sumsize / dtime);
01344         printf("%lf frames/sec\n", (double) (loops) / dtime);
01345     }
01346 
01347     if (!do_ring)
01348         pdv_free(imagebuf);
01349     /* else */
01350     pdv_stop_continuous(pdv_p);
01351 
01352     if (binning)
01353     {
01354         pdv_set_binning(pdv_p, 1, 1);
01355     }
01356 
01357     pdv_close(pdv_p);
01358 #ifdef NO_MAIN
01359     return (0);
01360 #else
01361     exit(0);
01362 #endif
01363 }
01364 
01365 void
01366 resolve_fname(char *fname, char *newname, int loops, char *ext)
01367 {
01368     int     l = strlen(fname);
01369     char    tmpname[256];
01370     char    tmpext[5];
01371 
01372     strcpy(tmpname, fname);
01373     if ((l > 4) && (tmpname[l - 4] == '.'))
01374     {
01375         strcpy(tmpext, &tmpname[l - 4]);
01376         tmpname[l - 4] = '\0';
01377     }
01378     else
01379         strcpy(tmpext, ext);
01380 
01381     if (loops > 1)
01382     {
01383         sprintf(newname, "%s%04d%s", tmpname, ASnum, tmpext);
01384         ASnum += ASinc;
01385     }
01386     else
01387         sprintf(newname, "%s%s", tmpname, tmpext);
01388 }
01389 
01390 
01391 /*
01392  * process the image, return in subimage. Handles both subsampling and
01393  * cropping.
01394  * 
01395  * NOTE: this only works on single-byte images (so far)
01396  */
01397 
01398 void
01399 crop_and_subsample(int subsample, int src_width, int src_height,
01400                  int x0, int y0, int x1, int y1, u_char * src, u_char * dst)
01401 {
01402     u_char *next_fromptr = src + (y0 * src_width) + x0;
01403     int     to_width = (x1 - x0) + 1;
01404     int     lines = (y1 - y0) + 1;
01405     u_char *to = dst;
01406     u_char *from;
01407     u_char *from_end;
01408 
01409     while (lines > 0)
01410     {
01411         from = (u_char *) next_fromptr;
01412         from_end = from + to_width;
01413 
01414         while (from < from_end)
01415         {
01416             *to++ = *from;
01417             from += subsample;
01418         }
01419         next_fromptr += src_width * subsample;
01420         lines -= subsample;
01421     }
01422 }
01423 
01424 
01425 void
01426 usage(char *progname)
01427 {
01428     printf("\n%s: Image acquisition and optional save for EDT PCI DV family digital\n", progname);
01429     printf("DMA interface products. Many options make it useful for diagnostics and\n");
01430     printf("also as an example for various methods of doing acquisition with EDT PCI DV\n");
01431     printf("family products. For a much a simpler example, see simple_take.c\n\n");
01432     printf("usage: %s\n", progname);
01433     printf("  -e exposuretime   set exposure time before acquiring (if supported)\n");
01434     printf("  -g gain           set camera gain (if supported)\n");
01435     printf("  -o offset         set camera offset (if supported)\n");
01436     printf("  -l loopcount      loop for loopcount images\n");
01437     printf("  -m msecs          delay msecs milliseconds between images\n");
01438     printf("  -f out_fname      output to raw file(s)\n");
01439 #ifdef _NT_
01440     printf("  -b fname.bmp      output to Microsoft bitmap file(s)\n");
01441 #else
01442     printf("  -i fname.ras      output to Sun Raster file(s)\n");
01443 #endif
01444     printf("  -C x0 y0 x1 y1    crop the output image to the coordinates given\n");
01445     printf("  -N n              number of multiple buffers (forces multibuf mode)\n");
01446     printf("  -S n              subsample -- take every nth pixel\n");
01447     printf("  -r [hs ha vs va]  region of interest -- to disable use -r alone (no subargs)\n");
01448     printf("  -t [msecs]        timeout # of msecs. if 0, disables timeouts, if no subarg,\n");
01449     printf("  -T                if image times out, dump any recieved data to timeout.raw\n");
01450     printf("                    re-enables auto timeouts\n");
01451     printf("  -w                wait for <CR> between images\n");
01452     printf("  -s start inc      specify start and increment for auto-numbered file-\n");
01453     printf("                    names (use with -l of 2 or more for auto-numbered filenames)\n");
01454     printf("  -I inc            specify increment for auto-numbered file (see -s)\n");
01455     printf("  -v                verbose output\n");
01456     printf("  -q binval         set binning (applicable cameras only)\n");
01457     printf("  -p                check pci dv simulator signature, exit if bad\n");
01458     printf("  -d                get and print a driver timestamp with every image\n");
01459     printf("  -j                just output the last take line (for output to file)\n");
01460     printf("  -c channel        channel # if multiple channels (2nd base Camera Link\n");
01461     printf("                    connector or multiple RCI units on one FOI card (default 0)\n");
01462     printf("  -u unit           pdv unit number (default 0)\n");
01463     printf("                    A full device pathname can also be used\n");
01464     printf("  -h                this help message\n");
01465 }

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