apps/ccam/ccam.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! File: ccam.c
00003 *! Copyright (C) 2002-2007 Elphel, Inc
00004 *! -----------------------------------------------------------------------------**
00005 *!
00006 *!  This program is free software: you can redistribute it and/or modifyF
00007 *!  it under the terms of the GNU General Public License as published by
00008 *!  the Free Software Foundation, either version 3 of the License, or
00009 *!  (at your option) any later version.
00010 *!
00011 *!  This program is distributed in the hope that it will be useful,
00012 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *!  GNU General Public License for more details.
00015 *!
00016 *!  You should have received a copy of the GNU General Public License
00017 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 *! -----------------------------------------------------------------------------**
00019 *!  $Log: ccam.c,v $
00020 *!  Revision 1.5  2008/04/20 06:51:28  elphel
00021 *!  comment-question
00022 *!
00023 *!  Revision 1.4  2008/04/16 07:01:56  elphel
00024 *!  replaced MAP_OPTIONS to fight "Eeeks!"
00025 *!
00026 *!  Revision 1.3  2008/03/20 22:23:54  elphel
00027 *!  added "opt="a" - async mode (external triggering)
00028 *!
00029 *!  Revision 1.2  2008/01/09 10:22:47  elphel
00030 *!  fixed uninitialized variable in white balance function
00031 *!
00032 *!  Revision 1.1.1.1  2007/10/02 21:09:15  elphel
00033 *!  This is a fresh tree based on elphel353-2.10
00034 *!
00035 *!  Revision 1.17  2007/09/30 03:22:47  elphel
00036 *!  edited comments. Needs support of acquiring into circbuf w/o pointer reset (was disabled because of the broken driver)
00037 *!
00038 *!  Revision 1.16  2007/09/29 16:19:15  elphel
00039 *!  removed IOCTL access to /dev/circbuf
00040 *!
00041 *!  Revision 1.15  2007/09/23 06:41:43  elphel
00042 *!  added more optional (compile-time) debug information
00043 *!
00044 *!  Revision 1.14  2007/09/19 00:34:59  elphel
00045 *!  Support for new parameters for fps control
00046 *!
00047 *!  Revision 1.13  2007/09/18 06:07:10  elphel
00048 *!  modified to support combined P_FLIP (instead of P_FLIPH, P_FLIPV), support for P_FPSLM (fps limit mode)
00049 *!
00050 *!  Revision 1.12  2007/09/03 08:14:52  spectr_rain
00051 *!  *** empty log message ***
00052 *!
00053 *!  Revision 1.11  2007/08/31 21:46:16  spectr_rain
00054 *!  *** empty log message ***
00055 *!
00056 *!  Revision 1.9  2007/08/28 21:26:45  spectr_rain
00057 *!  mmap for JPEG files
00058 *!
00059 *!  Revision 1.8  2007/08/27 04:46:16  elphel
00060 *!  Restoring JP4 format (option "j" in ccam.cgi "opt=" parameter). FPGA code for this mode is not fixed yet (but it does something different than in modes color & mono).
00061 *!
00062 *!  Revision 1.7  2007/08/17 12:09:28  spectr_rain
00063 *!  switch to GPL3 license
00064 *!
00065 *!  Revision 1.6  2007/08/15 16:37:51  spectr_rain
00066 *!  test for option 'o'
00067 *!
00068 *!  Revision 1.5  2007/08/03 15:15:22  spectr_rain
00069 *!  *** empty log message ***
00070 *!
00071 *!  Revision 1.4  2007/08/01 15:10:36  spectr_rain
00072 *!  ccam.c
00073 *!
00074 *!  Revision 1.2  2007/06/25 18:20:19  spectr_rain
00075 *!  *** empty log message ***
00076 *!
00077 *!  Revision 1.2  2007/04/16 17:27:53  spectr_rain
00078 *!  *** empty log message ***
00079 *!
00080 *!  Revision 1.1.1.1  2007/02/23 10:11:49  elphel
00081 *!  initial import into CVS
00082 *!
00083 *!  Revision 1.6  2007/01/08 17:18:36  spectr_rain
00084 *!  *** empty log message ***
00085 *!
00086 *!  Revision 1.5  2006/12/01 00:17:48  spectr_rain
00087 *!  *** empty log message ***
00088 *!
00089 *!  Revision 1.4  2006/09/15 17:17:48  spectr_rain
00090 *!  add parameter ve
00091 *!
00092 *!  Revision 1.3  2006/07/17 12:23:43  spectr_rain
00093 *!  comment zoran gain parameters
00094 *!
00095 *!  Revision 1.2  2006/07/12 07:13:59  elphel
00096 *!  fixed "resetsensor" for new addresses for 333
00097 *!
00098 *!  Revision 1.1.1.1  2006/07/11 19:15:05  spectr_rain
00099 *!  unwork with less than 5MPx Micron sensor, initial branch
00100 *!
00101 *!  Revision 1.33  2006/04/16 00:18:08  elphel
00102 *!  added timestamps to frame data in circbuf (streamers are not yet updated)
00103 *!
00104 *!  Revision 1.32  2006/03/26 01:55:30  elphel
00105 *!  made ccamftp.sh script support ED=, EN=,SD=,SN= parameters, modified default date/night gain and exposure thresholds
00106 *!
00107 *!  Revision 1.31  2006/03/01 16:58:04  elphel
00108 *!  no "camera in use" for images with "-" in "opt="
00109 *!
00110 *!  Revision 1.30  2006/02/22 19:34:53  elphel
00111 *!  bug fix in calculating start of frame in circular buffer (video)
00112 *!
00113 *!  Revision 1.29  2006/02/22 17:29:25  elphel
00114 *!  added day/night sensitivity automation. just use sens=auto, or add (shown defaults) &de=1000&ne=10000&sd=2&sn=16 parameters
00115 *!
00116 *!  Revision 1.28  2006/02/22 09:06:45  elphel
00117 *!  Made ccam.cgi return last image from the buffer when streamer is running. Same as acquireing image, with "-" in the options, i.e. "admin-bin/ccam.cgi?opt=vhcxy-" (all parameters will be ignored)
00118 *!
00119 *!  Revision 1.27  2006/02/21 08:30:32  elphel
00120 *!  fixed wrong reporting of binning parameters
00121 *!
00122 *!  Revision 1.26  2006/02/19 19:56:12  khlut
00123 *!  bug fixed: possibility of infinite loop when fwrite returns 0
00124 *!
00125 *!  Revision 1.25  2006/02/16 19:25:44  khlut
00126 *!  skip too long lines in streamer.conf
00127 *!
00128 *!  Revision 1.24  2006/02/16 14:20:15  khlut
00129 *!  Streamer parameters are printed with S_ prefix
00130 *!
00131 *!  Revision 1.23  2006/02/09 21:15:12  alexlp
00132 *!  Check what is the current API
00133 *!
00134 *!  Revision 1.22  2006/02/06 19:05:08  elphel
00135 *!  added modifier that makes ccam.cgi wait till the compressor is actually stopped after stop command
00136 *!
00137 *!  Revision 1.21  2006/02/03 13:09:26  spectr_rain
00138 *!  *** empty log message ***
00139 *!
00140 *!  Revision 1.20  2006/02/03 12:30:43  spectr_rain
00141 *!  *** empty log message ***
00142 *!
00143 *!  Revision 1.19  2006/02/01 21:11:55  spectr_rain
00144 *!  *** empty log message ***
00145 *!
00146 *!  Revision 1.18  2006/01/22 09:24:00  elphel
00147 *!  added "rscale=auto" and "bscale=auto",
00148 *!  "wbth=" (white balance threshold - default=250),
00149 *!  "wbpc=" (white balance percent - default=1.0),
00150 *!  and "wbstat=1" - return xml file with recommended rscale, bscale values and possible error code
00151 *!
00152 *!  Revision 1.9  2006/01/09 05:49:45  elphel
00153 *!  removed extra HTTP/1.0 line from the image headers that prevented internal wget from getting images from 127.0.0.1
00154 *!
00155 *!  Revision 1.8  2006/01/05 05:07:02  spectr_rain
00156 *!  new sensitivity/scale iface
00157 *!
00158 *!  Revision 1.7  2005/12/27 01:40:16  elphel
00159 *!  Added option (opt=.) to supress "pragma no-cache"
00160 *!
00161 *!  Revision 1.6  2005/11/29 20:41:45  elphel
00162 *!  *** empty log message ***
00163 *!
00164 *!  Revision 1.12  2005/11/29 09:15:31  spectr_rain
00165 *!  remove histogram window control
00166 *!
00167 *!  Revision 1.5  2005/10/27 12:02:54  alexlp
00168 *!  Move html from /etc/httpd to /usr
00169 *!
00170 *!  Revision 1.4  2005/09/10 23:33:21  elphel
00171 *!  Support of realtime clock and timestamps in the images
00172 *!
00173 *!  Revision 1.9  2005/09/06 03:37:14  elphel
00174 *!  support for "photo-finish" mode, programmable vertical sync interrupt delay
00175 *!
00176 *!  Revision 1.8  2005/08/28 19:02:49  elphel
00177 *!  now histogram window width and height should be provided as needed, not decremented by 2
00178 *!
00179 *!  Revision 1.7  2005/08/28 15:47:54  elphel
00180 *!  added histogram window control in the URL
00181 *!
00182 *!  Revision 1.6  2005/08/27 05:16:27  elphel
00183 *!  binning
00184 *!
00185 *!  Revision 1.5  2005/08/27 00:46:08  elphel
00186 *!  continue on histograms
00187 *!
00188 *!  Revision 1.4  2005/08/26 02:59:06  elphel
00189 *!  working on histogram
00190 *!
00191 *!  Revision 1.2  2005/05/10 23:55:55  elphel
00192 *!  *** empty log message ***
00193 *!
00194 *!  Revision 1.7  2004/06/19 05:52:06  elphel
00195 *!  made separate "Stop" and "Acquire" command instead of "Stop/Acquire"
00196 *!
00197 *!  Revision 1.6  2004/06/03 07:16:57  elphel
00198 *!  improved clip per-frame viewing (now from clip start too, not just from the end)
00199 *!
00200 *!  Revision 1.3  2004/05/07 03:05:36  elphel
00201 *!  support for P_SENSOR_WIDTH, P_SENSOR_HEIGHT
00202 *!
00203 *!  Revision 1.2  2004/04/29 06:46:01  elphel
00204 *!  support for the FPS setting
00205 *!
00206 *!
00207 *! Modified for model 313
00208 *! 11/07/2002
00209 *! modified states, removed "still mode" (always video),
00210 *! added 2 image pages for interleaved access
00211 */
00212 #include <fcntl.h>  /*open*/
00213 #include <unistd.h> /* close, sleep */
00214 
00215 #include <stdio.h>
00216 #include <stdlib.h>
00217 #include <sys/ioctl.h>
00218 
00219 #include <sys/types.h> /* for fstat */
00220 #include <sys/stat.h> /* for fstat */
00221 #include <signal.h>
00222 
00223 #include <sys/time.h>
00224 #include <time.h>
00225 
00226 #undef SYSLOG
00227 
00228 #include <syslog.h>
00229 #define SLOG "ccam.cgi"
00230 
00231 // #include "jpeg/jpeglib.h"
00232 
00233 #include <sys/mman.h>           /* mmap */
00234 
00235 #define USE_MMAP
00236 
00237 #define SOCKETBUF_SIZE 4096
00238 
00239 #include <time.h>
00240 #include <string.h>
00241 
00242 #include <errno.h>
00243 #include <math.h>
00244 
00245 #include "imageaccess.h"
00246 #include "dma2jpeg.h"
00247 #include "dma2bmp.h"
00248 #include "lasercalc.h"
00249 #include "vrml303.h"
00250 #include "qtime.h"
00251 
00252 #include <asm/elphel/autoexp.h>
00253 #include <asm/elphel/hist.h>
00254 
00255 
00256 //#include <asm/cmoscama.h>
00257 #include <asm/elphel/fpgaconfa.h>
00258 #include <asm/elphel/c313a.h>
00259 #include <asm/elphel/ext353.h>
00260 //#include <asm/fpgaconfa.h>
00261 
00262 // for trigger
00263 #include <netinet/ip.h>
00264 #include <netinet/in.h>
00265 #include <sys/types.h>
00266 #include <sys/socket.h>
00267 #include <arpa/inet.h>
00268 #include <poll.h>
00269 #include <pthread.h>
00270 #include <asm/atomic.h>
00271 
00272 #define D(x)
00273 #define DD(x)
00274 
00275 //#define D5(x) fprintf(stderr,"%s:%d:",__FILE__,__LINE__);x
00276 #define D5(x)
00277 //#define D6(x) fprintf(stderr,"%s:%d:",__FILE__,__LINE__);x
00278 #define D6(x)
00279 
00280 extern char **environ;
00281 #define QRY_MAXPARAMS 64
00282 #define MAX_TIMEOUT 5 /*seconds/transfer of SOCKETBUF_SIZE bytes */
00283 #define SENSOR_W 1280
00284 #define SENSOR_H 1024
00285 
00286 // define "html=" modes
00287 
00288 #define HTML_SENSOR_JS   1
00289 #define HTML_SENSOR_HTML 2
00290 #define HTML_BEAM_JS     3
00291 #define HTML_BEAM_HTML   4
00292 #define HTML_STATE_JS    5
00293 #define HTML_STATE_HTML  6
00294 #define HTML_ACQUIRE     7
00295 #define HTML_RESET       8
00296 #define XML_SENSOR      10
00297 #define XML_BEAM        11
00298 #define XML_STATE       12
00299 #define XML_ACQUIRE     13
00300 #define XML_RESET       14
00301 #define HIST_SIZE 256 * 4 * 4
00302 #define GAMMA_SIZE   256 * 4 * 2
00303 
00304 
00305 #define MAP_OPTIONS MAP_SHARED
00306 
00307 struct exif_desc_t {
00308         unsigned long image_id;
00309 } exif_desc = {
00310         .image_id = 0xFFFFFFFF,
00311 };
00312 
00313 struct trig_desc_t {
00314         int enable;
00315         int enable_ping;
00316         long port_in;
00317         long port_out;
00318         unsigned long number;
00319         unsigned long id;
00320         long timeout;
00321 } trig_desc = {
00322         .enable = 0,
00323         .enable_ping = 0,
00324         .port_in = 40000,
00325         .port_out = 40001,
00326         .number = 0xFFFFFFFF,
00327         .id = 0xFFFFFFFF,
00328         .timeout = 50,
00329 };
00330 
00331 atomic_t accept_trigger;
00332 
00333 /*
00334  * UDP sensor triggering
00335  * send "ready" broadcast pulse
00336  */
00337 void *bcast_trigger_f(void *ptr) {
00338         unsigned long counter = 0;
00339         unsigned long d[3];
00340         //d[0] = 0x5244592D; // "RDY-"
00341         d[0] = 0x2D594452; // "RDY-"
00342         d[1] = htonl(exif_desc.image_id);
00343 //      t_log(0, "trigger thread");
00344         // prepare data to send...
00345         int s_out;
00346         struct sockaddr_in addr_out;
00347         int zu = 1;
00348         s_out = socket(PF_INET, SOCK_DGRAM, 0);
00349         if(s_out < 0)
00350                 return NULL;
00351         memset(&addr_out, 0, sizeof(struct sockaddr_in));
00352         addr_out.sin_family = AF_INET;
00353         addr_out.sin_port = htons(trig_desc.port_out);
00354         addr_out.sin_addr.s_addr = INADDR_BROADCAST;
00355         zu = 1;
00356         if(setsockopt(s_out, SOL_SOCKET, SO_BROADCAST, &zu, sizeof(zu)) != 0)
00357                 return NULL;
00358         if(connect(s_out, (struct sockaddr*)&addr_out, sizeof(struct sockaddr_in)) != 0)
00359                 return NULL;
00360         while(atomic_read(&accept_trigger) == 0) {
00361                 d[2] = htonl(counter);
00362 //              send(s_out, d_out, sizeof(d_out), O_NONBLOCK);
00363                 send(s_out, (void *)&d[0], 12, 0);
00364                 //...
00365                 counter++;
00366                 usleep(10000);
00367         }
00368         usleep(200000);
00369         close(s_out);
00370         return NULL;
00371 }
00372 
00373 struct prof_t {
00374         int count;
00375         struct timeval tv;
00376 } prof;
00377 
00378 void prof_start(void) {
00379         prof.count = 0;
00380         gettimeofday(&prof.tv, NULL);
00381         syslog(LOG_ALERT, "\n-->prof: start\n");
00382 }
00383 
00384 void prof_time(const char *m) {
00385         struct timeval tv;
00386         gettimeofday(&tv, NULL);
00387         prof.count++;
00388         syslog(LOG_ALERT, "prof at point %d: time == %d:%06d, message=\"%s\"\n", prof.count, tv.tv_sec, tv.tv_usec, m);
00389 }
00390 
00391 
00392 void prof_next(const char *m) {
00393         struct timeval tv, tv_new;
00394         gettimeofday(&tv_new, NULL);
00395         tv = prof.tv;
00396         long delta = (tv_new.tv_sec - tv.tv_sec) * 1000000;
00397         delta += tv_new.tv_usec;
00398         delta -= tv.tv_usec;
00399         tv.tv_sec = delta / 1000000;
00400         tv.tv_usec = delta % 1000000;
00401         prof.tv = tv_new;
00402         prof.count++;
00403         syslog(LOG_ALERT, "prof at point %d: delta == %d:%06d, message=\"%s\"\n", prof.count, tv.tv_sec, tv.tv_usec, m);
00404 }
00405 
00406 /*
00407  * UDP sensor triggering
00408  * wait for start broadcast pulse, and start thread what send "ready" broadcast pulse
00409  */
00410 void bcast_trigger(void) {
00411         pthread_t pth;
00412         int pth_id;
00413 
00414         atomic_set(&accept_trigger, 0);
00415 //      int s_in, s_out;
00416         struct sockaddr_in addr_in;
00417         int zu = 1;
00418 
00419         // wait for trigger packet...
00420         // cancel ready thread...
00421         // read
00422         // open incoming socket...
00423         int s_in = socket(PF_INET, SOCK_DGRAM, 0);
00424         if(s_in < 0)
00425                 return;
00426         memset(&addr_in, 0, sizeof(struct sockaddr_in));
00427         addr_in.sin_family = AF_INET;
00428         addr_in.sin_port = htons(trig_desc.port_in);
00429         addr_in.sin_addr.s_addr = INADDR_BROADCAST;
00430 
00431         if(setsockopt(s_in, SOL_SOCKET, SO_BROADCAST, &zu, sizeof(zu)) != 0)
00432                 return;
00433         if(bind(s_in, (struct sockaddr*)&addr_in, sizeof(struct sockaddr_in)) != 0)
00434                 return;
00435 
00436         // thread for "pong" signals
00437         if(trig_desc.enable_ping)
00438                 pth_id = pthread_create(&pth, NULL, bcast_trigger_f, NULL);
00439         // accept incoming packet
00440         unsigned long d[3];
00441         int f = 0;
00442         struct pollfd fds[1];
00443         fds[0].fd = s_in;
00444         fds[0].events = POLLIN | POLLPRI;
00445         fds[0].revents = 0;
00446         while(f == 0) {
00447                 if(trig_desc.timeout != 0) {
00448 //                      syslog(LOG_ALERT, "do poll()");
00449                         poll(&fds[0], 1, trig_desc.timeout * 1000);
00450 //                      poll(&fds[0], 1, 1);
00451                         if(fds[0].revents == 0) {
00452                                 f = 1;
00453                                 break;
00454                         }
00455                 }
00456 //              syslog(LOG_ALERT, "skip poll()");
00457                 int in = recv(s_in, (void *)&d[0], 12, 0);
00458 //              char _z[64];
00459 //              sprintf(_z, "accept: %d bytes\n", in);
00460 //              _log(12, _z);
00461                 if(in == 12) {
00462                         trig_desc.number = htonl(d[1]);
00463                         trig_desc.id = htonl(d[2]);
00464                         if(d[0] == 0x2D475254)// 0x5452472D)
00465                                 f = 1;
00466                 } else
00467                         f = 1;
00468         }
00469         atomic_inc(&accept_trigger);
00470 //      close(s_in);
00471 }
00472 
00473 
00474 // seems there is extra "HTTP/1.0 200 OK" line output in the JPEG headers - remove it
00475 #define USEHTTP10(x)
00476 //#define USEHTTP10(x) x
00477 
00478 /*
00479  * Name: process_get
00480  * Description: Writes a chunk of data to the socket.
00481  *
00482  * Return values:
00483  *  -1: request blocked, move to blocked queue
00484  *   0: EOF or error, close it down
00485  *   1: successful write, recycle in ready queue
00486  */
00487 struct key_value {
00488         char *key;
00489         char *value;
00490 };
00491 
00492 struct key_value gparams[QRY_MAXPARAMS+1];
00493 
00494 struct autoexp_t autoexp;
00495 
00496 int process_get(int data_fd, unsigned long filesize, char * data_mem, long *filepos);
00497 int hexdigit (char c);
00498 int unescape (char * s, int l);
00499 //int accumData(const char * ImgFileName, const char * bufFileName);
00500 int accumData(int ifd, const char * bufFileName);
00501 int frameShr(const char * fn, int shft);
00502 
00503 int frameSub(const char * sfn, const char * dfn);
00504 int processCal (const char * wfn, const char * bfn, const char * cfn);
00505 // store in 10-bit format (same as DMA)
00506 #define MAXIMAGEWIDTH 2048
00507 int imageCorr (int ImageWidth, const char * dfn, const char * bfn, const char * cfn, const char * ImgFileName );
00508 int send_buf_image (int ImageWidth, int ImageHeight, int Quality, int Contrast, int Color,
00509                                         int bayerOrient, int Depth, const char * pseudo, const char * ImgFileName, const char * bufFileName);
00510 
00511 int send_immed_image(int ImageWidth, int ImageHeight, int Quality, int Contrast, int Color,
00512                                          int bayerOrient, int Depth, const char * pseudo, const char * ImgFileName);
00513 int parseQuery(struct key_value * params, char * qry);
00514 char * paramValue(struct key_value * params, char * skey); // returns pointer to parameter value, NULL if not defined
00515 int optionPresent(struct key_value * params, char * skey, char c); // returns 1 if c is in argument skey
00516 void printDocumentLine(const char* name, const char* value, int format) ; //0 - html, 1 - javaScript, 2 - xml
00517 int send_html_data(const char * devfn, const char * dmafn, int mode, int refreshPeriod, const char * onLoad, const char * javaScript);
00518 int set_fpga_time(int seconds, int useconds);
00519 int processImage(struct key_value * params,  const char * ImgFileName,
00520                  const char * bufFileName,
00521                                  const char * pc_par, int iq_par, int gd_par,
00522                                  int html_par, int htmlr_par, const char * htmll_par,  const char * htmlj_par,
00523                                  int vrml_par, int vrmlm_par, int vrmld_par, int vrmlb_par,  int vrmli_par,
00524                                  int vrmlf_par, int vrmll_par, int vrmlo_par, int vrmlz_par );
00525 int calcWhiteBalance(int thrsh,   // threshold (0..255) for the "brightest color"
00526                      int min_pixels, // minimal number of pixels above threshold for the brightest color (threshold will be lowered to satisfy min_pixels)
00527                      float diffGains[3]);
00528 
00529 static char * error304= "HTTP/1.0 304 Not Modified\n"\
00530                         "Content-Length: 0\n"\
00531                         "Content-Type: image/jpeg\n"\
00532                         "Pragma: no-cache\n\n";
00533 
00534 int process_get(int data_fd, unsigned long filesize, char * data_mem, long *filepos) {
00535         int bytes_written, bytes_to_write;
00536         bytes_to_write = filesize - filepos[0];
00537         if(bytes_to_write > SOCKETBUF_SIZE)
00538                 bytes_to_write = SOCKETBUF_SIZE;
00539 //      bytes_written = write(stdout, data_mem + filepos[0], bytes_to_write);
00540 //      bytes_written = write(2, data_mem + filepos[0], bytes_to_write);
00541         bytes_written = fwrite(data_mem + filepos[0], 1, bytes_to_write, stdout);
00542 //      fprintf(stderr,"bytes_written=%d, errno = %d\r\n",bytes_written,errno);
00543         if(bytes_written <= 0) {
00544                 if(errno == EAGAIN || errno == EWOULDBLOCK) {  /* no room in pipe */
00545                         return -1;
00546                 } else {                /* something wrong, includes EPIPE possibility */
00547 //                      SQUASH_KA(req);      /* force close fd */
00548                         return 0;
00549                 }
00550         }
00551         filepos[0] += bytes_written;
00552         if(filepos[0] == filesize)
00553                 return 0;       /* EOF */
00554         else
00555                 return 1;                               /* more to do */
00556 }
00557 
00558 int hexdigit (char c) {
00559   int i;
00560   i=c-'0';
00561   if ((i>=0) && (i<10)) return i;
00562   i=c-'a'+10;
00563   if ((i>=10) && (i<16)) return i;
00564   i=c-'A'+10;
00565   if ((i>=10) && (i<16)) return i;
00566   return 0;     // could be -1??
00567 }
00568 
00569 int unescape (char * s, int l) {
00570   int i=0;
00571   int j=0;
00572   while ((i<l) && s[i]) {
00573     if ((s[i]=='%') && (i<(l-2)) && s[i+1]){ // behavior from Mozilla
00574       s[j++]=(hexdigit(s[i+1])<<4) | hexdigit(s[i+2]);
00575       i+=3;
00576     } else s[j++]=s[i++];
00577   }
00578   if (i<l) s[j]=0;
00579   return j;
00580 }
00581 
00582 #define USEBUFFERSIZE 1024
00583 
00584 int programFPN(const char * backgroundFileName,const char * calibrationFileName, const char * FPNFileName,
00585                int fpns, int fpnm, int fat_zero) {
00586   int bfd, cfd, ffd, nr, i ,d;
00587   unsigned short dbb[USEBUFFERSIZE];
00588   unsigned short dbc[USEBUFFERSIZE];
00589 // later calibration data file should be window-independent (or be used with the full window)
00590   if ((bfd=open(backgroundFileName,O_RDONLY))<0) return bfd;
00591   if ((ffd=open(FPNFileName,       O_RDWR))<0) return ffd;
00592 
00593 cfd=open(calibrationFileName,     O_RDONLY); // may be inexistent;
00594   fpns= (fpns>0)? (fpns-1):0;
00595   while ((nr=read(bfd,dbb,USEBUFFERSIZE<<1))>0) {
00596     if (cfd>=0) read(cfd,dbc,USEBUFFERSIZE<<1);
00597     for (i=0;i<(nr>>1); i++) {
00598       d=(dbb[i]>fat_zero)? ((dbb[i]-fat_zero)<<1):0;
00599       d=((d>>fpns)+1)>>1;
00600       if (d>255) d=255;
00601       dbb[i]=d;
00602       if ((cfd>=0) && (fpnm!=0)){
00603         dbb[i]+=(dbc[i]<<8);    // put here something real
00604       }
00605     }
00606     write (ffd,dbb,nr);
00607   }
00608   close (bfd);
00609   close (ffd);
00610   if (cfd>=0)  close (cfd);
00611   return 0;
00612 }
00613 
00614 int accumData(int ifd, const char * bufFileName) {
00615  int  ofd, nr, i;
00616   unsigned short dbi[USEBUFFERSIZE];
00617   unsigned short dbo[USEBUFFERSIZE];
00618   off_t filepos;
00619   if ((ofd=open(bufFileName,O_RDWR | O_CREAT))<0) return ofd;
00620    lseek (ifd,0,SEEK_SET);
00621 //  if ((ifd=open(ImgFileName,O_RDONLY))<0) return ifd;
00622   while ((nr=read(ifd,dbi,USEBUFFERSIZE<<1))>0) {
00623     memset (dbo,0,USEBUFFERSIZE<<1);
00624     filepos=lseek (ofd,0,SEEK_CUR);     // store current file position
00625     read(ofd,dbo,nr);                   // read same amount of data, OK if nothing read
00626     for (i=0;i<(nr>>1); i++) dbo[i]+=dbi[i];
00627     lseek (ofd,filepos,SEEK_SET);       // restore file position to the buffer start
00628     write (ofd,dbo,nr);
00629   }
00630 //  close (ifd);
00631   close (ofd);
00632   return 0;
00633 }
00634 
00635 int frameShr(const char * fn, int shft) {
00636 
00637   int fd, nr, i;
00638   unsigned short db[USEBUFFERSIZE];
00639   off_t filepos;
00640   if ((fd=open(fn,O_RDWR | O_CREAT))<0) return fd;
00641   filepos=0;
00642   while ((nr=read(fd,db,USEBUFFERSIZE<<1))>0) {
00643     for (i=0;i<(nr>>1); i++) db[i]=db[i]>>shft;
00644     lseek (fd,filepos,SEEK_SET);        // restore file position to the buffer start
00645     write (fd,db,nr);
00646     filepos=lseek (fd,0,SEEK_CUR);      // store current file position
00647   }
00648   close (fd);
00649   return 0;
00650 }
00651 
00652 
00653 int frameSub(const char * sfn, const char * dfn) {
00654   int sfd, dfd, nr, i, d;
00655 
00656   unsigned short dbs[USEBUFFERSIZE];
00657   unsigned short dbd[USEBUFFERSIZE];
00658   off_t filepos;
00659   if ((dfd=open(dfn,O_RDWR | O_CREAT))<0) return dfd;
00660   if ((sfd=open(sfn,O_RDONLY))<0) return sfd;
00661   while ((nr=read(sfd,dbs,USEBUFFERSIZE<<1))>0) {
00662     memset (dbd,0,USEBUFFERSIZE<<1);
00663     filepos=lseek (dfd,0,SEEK_CUR);     // store current file position
00664     read(dfd,dbd,nr);                   // read same amount of data, OK if nothing read
00665     for (i=0;i<(nr>>1); i++) {d=dbd[i]; d-=dbs[i]; dbd[i]=(d<0)? 0:d;}
00666     lseek (dfd,filepos,SEEK_SET);       // restore file position to the buffer start
00667     write (dfd,dbd,nr);
00668   }
00669   close (sfd);
00670   close (dfd);
00671   return 0;
00672 }
00673 
00674 int processCal (const char * wfn, const char * bfn, const char * cfn){
00675   int r;
00676   int fd,nr,i;
00677   double k=0x400*0x300; // after dividing by 400 maximum will be expected to be 0x300
00678   double a;
00679   off_t filepos=0;
00680   unsigned short db[USEBUFFERSIZE];
00681   remove (cfn);
00682   if ((r=rename (wfn,cfn))<0) return r;
00683   if ((r=frameSub(bfn, cfn))<0) return r;
00684 
00685   if ((fd=open(cfn,O_RDWR))<0) return fd;
00686   while ((nr=read(fd,db,USEBUFFERSIZE<<1))>0) {
00687     for (i=0;i<(nr>>1); i++) {
00688       a=db[i];
00689       a= (a>0)?k/a:0;
00690       if (a>65535) a=65535;
00691       db[i]=a;
00692     }
00693     lseek (fd,filepos,SEEK_SET);        // restore file position to the buffer start
00694     write (fd,db,nr);
00695     filepos=lseek (fd,0,SEEK_CUR);      // store current file position
00696   }
00697   close (fd);
00698   return 0;
00699 }
00700 
00701 // store in 10-bit format (same as DMA)
00702 #define MAXIMAGEWIDTH 2048
00703 int imageCorr (int ImageWidth, const char * dfn, const char * bfn, const char * cfn, const char * ImgFileName ) {
00704   int dfd, bfd, cfd, ifd;
00705   int i,nr,d;
00706   int n;
00707   unsigned short db [MAXIMAGEWIDTH];
00708                                                                                                                                                                                                                 unsigned short dbb[MAXIMAGEWIDTH];
00709   unsigned short dbc[MAXIMAGEWIDTH];
00710   unsigned long  d10b[(MAXIMAGEWIDTH / 3)+1];
00711   int DMALongsPerRow;
00712   if ((ImageWidth<1) || (ImageWidth > MAXIMAGEWIDTH)) return -1;
00713 
00714   DMALongsPerRow = ImageWidth/3;
00715   if (ImageWidth > (3*DMALongsPerRow)) DMALongsPerRow++;
00716 
00717 
00718   if ((dfd=open(dfn,O_RDONLY))<0) return dfd;
00719   if ((bfd=open(bfn,O_RDONLY))<0) {close (dfd);return bfd;}
00720 //  if ((cfd=open(cfn,O_RDONLY))<0) {close (dfd);close (bfd);return cfd;}
00721   cfd= cfn? open(cfn,O_RDONLY):-1;
00722   if ((ifd=open(ImgFileName,O_RDWR | O_CREAT))<0) {close (dfd);close (bfd);close (cfd);return ifd;} // output file
00723   while ((nr=read(dfd,db,ImageWidth<<1))>0) {
00724     read(bfd,dbb,nr);
00725     if (cfd >= 0) read(cfd,dbc,nr);
00726     for (i=0;i<(nr>>1); i++) {
00727       d=(db[i]-dbb[i]);
00728       if (d<0) d=0;
00729       if (cfd >= 0) {
00730         d=(d*dbc[i])>>10;
00731         if (d>0x3ff) d=0x3ff;
00732       }
00733       db[i]=d;
00734     }
00735 // compress row to "dma" format (3x10bit in each 32-bit word)
00736     n=0;
00737     for (i=0;i<DMALongsPerRow;i++) {
00738       d10b[i]=db[n]+(db[n+1]<<10)+(db[n+2]<<20);
00739       n+=3;
00740     }
00741     write (ifd,d10b,DMALongsPerRow << 2);
00742   }
00743   close (dfd);
00744   close (bfd);
00745   if (cfd >= 0)   close (cfd);
00746   close (ifd);
00747 
00748   return 0;
00749 }
00750 
00751 int send_buf_image (int ImageWidth, int ImageHeight, int Quality, int Contrast, int Color,
00752                                         int bayerOrient, int Depth, const char * pseudo, const char * ImgFileName, const char * bufFileName){
00753 // if color =0  - monochrome, else 2 LSBs 0..3 - bayer filter (r/gr/gb/b) under x=0,y=0
00754    time_t       t;
00755 
00756 /* from boa's init_get */
00757   struct stat statbuf;
00758     unsigned long filesize;                     /* filesize */
00759     char * data_mem;                            /* mmapped char array */
00760     long filepos;                               /* position in file */
00761 
00762 /* sendfile */
00763  off_t offset;
00764 
00765  int data_fd; // input file (used with mmap)
00766 
00767  int i;
00768 
00769 
00770 
00771   if (Quality>=0){
00772     if ((i=dma2jpeg (ImageWidth,ImageHeight,Quality,Contrast, Color, bayerOrient, Depth, pseudo, ImgFileName, bufFileName))) {
00773        fprintf(stderr,"dma2jpeg failed\r\n");
00774        return i;
00775     }
00776   } else {
00777     if ((i=dma2bmp (ImageWidth,ImageHeight,-1-Quality, Contrast, Color, bayerOrient, Depth, pseudo, ImgFileName, bufFileName))) {
00778        fprintf(stderr,"dma2bmp failed\r\n");
00779        return i;
00780     }
00781   }
00782 
00783 /* Now send that file to the client - we needed it's size to do so */
00784 
00785         data_fd = open(bufFileName, O_RDONLY);
00786         if(data_fd == -1) {
00787           fprintf(stderr,"Could not open %s\r\n",bufFileName);
00788           exit (1);
00789         }
00790         fstat(data_fd, &statbuf);
00791         filesize = statbuf.st_size;
00792         filepos =0;
00793 
00794         data_mem = mmap(0, statbuf.st_size, PROT_READ, MAP_OPTIONS, data_fd, 0);
00795         if((int)data_mem == -1) {
00796           fprintf(stderr,"Error in mmap %s\r\n",bufFileName);
00797                 close(data_fd);
00798                 exit(1);
00799         }
00800 
00801 USEHTTP10(printf("HTTP/1.0 200 OK\n"));
00802    printf("Content-Length: %ld\n",filesize);
00803    if (Quality>=0) printf("Content-Type: image/jpeg\n");
00804    else            printf("Content-Type: image/bmp\n");
00805                    printf("Pragma: no-cache\n\n");
00806 
00807 
00808   /* Write body */
00809 
00810        offset=0;
00811 
00812 
00813 /*  -1: request blocked, move to blocked queue
00814  *   0: EOF or error, close it down
00815  *   1: successful write, recycle in ready queue
00816  */
00817         t=time (NULL) + MAX_TIMEOUT;
00818   while (1) {
00819 //  fprintf(stderr,"filepos=%lx\r\n",filepos);
00820 
00821     switch (process_get(data_fd,filesize,data_mem,&filepos)) {
00822     case 0: {
00823 //              fprintf(stderr,"process_get returned 0 - OK? \r\n");
00824                 close(data_fd);
00825                 return 0;
00826             }
00827     case -1: if (time(NULL) > t ){
00828                 fprintf(stderr,"tired of waiting - increase MAX_TIMEOUT\r\n");
00829                 close(data_fd);
00830                 exit (1);
00831             } else break; // continue waiting
00832 
00833     case 1: {   // reset timeout
00834                 t=time (NULL) + MAX_TIMEOUT;
00835             }
00836     }
00837 
00838   }
00839 
00840   close(data_fd);                               /* close data file  ???*/
00841   return 0;
00842 
00843 }
00844 
00845 int send_jpegfile_image (const char * ImgFileName){
00846    time_t       t;
00847 /* from boa's init_get */
00848   struct stat statbuf;
00849     unsigned long filesize;                     /* filesize */
00850     char * data_mem;                            /* mmapped char array */
00851     long filepos;                               /* position in file */
00852 
00853 /* sendfile */
00854  off_t offset;
00855 
00856  int data_fd; // input file (used with mmap)
00857 
00858 
00859 /* Now send that file to the client - we needed it's size to do so */
00860 
00861         data_fd = open(ImgFileName, O_RDONLY);
00862         if(data_fd == -1) {
00863           fprintf(stderr,"Could not open %s\r\n",ImgFileName);
00864           exit (1);
00865         }
00866 
00867         fstat(data_fd, &statbuf);
00868         filesize = statbuf.st_size;
00869         filepos =0;
00870 
00871         data_mem = mmap(0, statbuf.st_size, PROT_READ, MAP_OPTIONS, data_fd, 0);
00872         if((int)data_mem == -1) {
00873           fprintf(stderr,"Error in mmap %s\r\n",ImgFileName);
00874                 close(data_fd);
00875                 exit(1);
00876         }
00877 
00878    USEHTTP10(printf("HTTP/1.0 200 OK\n"));
00879    printf("Content-Length: %ld\n",filesize);
00880    printf("Content-Type: image/jpeg\n");
00881    printf("Pragma: no-cache\n\n");
00882 
00883 
00884   /* Write body */
00885 
00886        offset=0;
00887 
00888 
00889 /*  -1: request blocked, move to blocked queue
00890  *   0: EOF or error, close it down
00891  *   1: successful write, recycle in ready queue
00892  */
00893         t=time (NULL) + MAX_TIMEOUT;
00894   while (1) {
00895 
00896     switch (process_get(data_fd,filesize,data_mem,&filepos)) {
00897     case 0: {
00898                 close(data_fd);
00899                 return 0;
00900             }
00901     case -1: if (time(NULL) > t ){
00902                 fprintf(stderr,"tired of waiting - increase MAX_TIMEOUT\r\n");
00903                 close(data_fd);
00904                 exit (1);
00905             } else break; // continue waiting
00906 
00907     case 1: {   // reset timeout
00908                 t=time (NULL) + MAX_TIMEOUT;
00909             }
00910     }
00911 
00912   }
00913 
00914   close(data_fd);
00915   return 0;
00916 
00917 }
00918 
00919 
00920 
00921 
00922 
00923 int send_immed_image(int ImageWidth, int ImageHeight, int Quality, int Contrast, int Color,
00924                                          int bayerOrient, int Depth, const char * pseudo, const char * ImgFileName){
00925  int i;
00926 
00927 //   MD(fprintf(stderr,"width- %d, height %d, quality - %d, contrast - %d, color - %d, orient - %d, depth - %d\r\n", ImageWidth,ImageHeight, Quality, Contrast, Color, bayerOrient, Depth));
00928 //  fprintf(stderr,"width- %d, height %d, quality - %d, contrast - %d, color - %d, orient - %d, depth - %d\r\n", ImageWidth,ImageHeight, Quality, Contrast, Color, bayerOrient, Depth);
00929    USEHTTP10(printf("HTTP/1.0 200 OK\n"));
00930 //   printf("Content-Length: %ld\n",filesize); // we don't know it !
00931 
00932 
00933   if (Quality>=0){
00934     printf("Content-Type: image/jpeg\n");
00935     printf("Pragma: no-cache\n\n");
00936 
00937     if ((i=dma2jpeg (ImageWidth,ImageHeight,Quality,Contrast, Color, bayerOrient, Depth, pseudo, ImgFileName, NULL))) {
00938        fprintf(stderr,"dma2jpeg failed\r\n");
00939        return i;
00940     }
00941   } else {
00942      printf("Content-Type: image/bmp\n");
00943      printf("Pragma: no-cache\n\n");
00944     if ((i=dma2bmp (ImageWidth,ImageHeight,-1-Quality, Contrast, Color, bayerOrient, Depth, pseudo, ImgFileName, NULL))) {
00945        fprintf(stderr,"dma2bmp failed\r\n");
00946        return i;
00947     }
00948   }
00949 
00950   return 0;
00951 
00952 }
00953 #if 0
00954 int send_hardware_image (const char * ImgFileName){
00955 
00956 // if color =0  - monochrome, else 2 LSBs 0..3 - bayer filter (r/gr/gb/b) under x=0,y=0
00957    time_t       t;
00958 
00959 /* from boa's init_get */
00960   struct stat statbuf;
00961 
00962     unsigned long filesize;                     /* filesize */
00963     char * data_mem;                            /* mmapped char array */
00964     long filepos;                               /* position in file */
00965 
00966 /* sendfile */
00967  off_t offset;
00968 
00969  int data_fd; // input file (used with mmap)
00970  int i;
00971 
00972 
00973  // wait
00974 
00975 
00976 /* Now send that file to the client - we needed it's size to do so */
00977 
00978         data_fd = open(ImgFileName, O_RDONLY);
00979         if(data_fd == -1) {
00980           fprintf(stderr,"Could not open %s\r\n",ImgFileName);
00981           exit (1);
00982         }
00983         fstat(data_fd, &statbuf);
00984         filesize = statbuf.st_size;
00985         filepos =0;
00986 
00987         data_mem = mmap(0, statbuf.st_size, PROT_READ, MAP_OPTIONS, data_fd, 0);
00988 //      close(data_fd);                         /* close data file  ???*/
00989 
00990         if((int)data_mem == -1) {
00991           fprintf(stderr,"Error in mmap %s\r\n",ImgFileName);
00992                 close(data_fd);
00993                 exit(1);
00994         }
00995 
00996    USEHTTP10(printf("HTTP/1.0 200 OK\n"));
00997    printf("Content-Length: %ld\n",filesize);
00998    printf("Content-Type: image/jpeg\n");
00999    printf("Pragma: no-cache\n\n");
01000 
01001 
01002   /* Write body */
01003 
01004        offset=0;
01005 
01006 /*  -1: request blocked, move to blocked queue
01007  *   0: EOF or error, close it down
01008  *   1: successful write, recycle in ready queue
01009  */
01010         t=time (NULL) + MAX_TIMEOUT;
01011   while (1) {
01012 //  fprintf(stderr,"filepos=%lx\r\n",filepos);
01013 
01014     switch (process_get(data_fd,filesize,data_mem,&filepos)) {
01015     case 0: {
01016 //              fprintf(stderr,"process_get returned 0 - OK? \r\n");
01017                 close(data_fd);
01018                 return 0;
01019             }
01020     case -1: if (time(NULL) > t ){
01021                 fprintf(stderr,"tired of waiting - increase MAX_TIMEOUT\r\n");
01022                 close(data_fd);
01023                 exit (1);
01024             } else break; // continue waiting
01025 
01026     case 1: {   // reset timeout
01027                 t=time (NULL) + MAX_TIMEOUT;
01028             }
01029     }
01030 
01031   }
01032 
01033   close(data_fd);                               /* close data file  ???*/
01034   return 0;
01035 
01036 }
01037 
01038 #endif
01039 //#define D6(x) fprintf(stderr,"%s:%d:",__FILE__,__LINE__);x
01040 
01041 
01042 int send_hardware_image(const char * ImgFileName, int cache) { // no mmap
01043         struct stat statbuf;
01044         unsigned long filesize;                 /* filesize */
01045         long filepos;                           /* position in file */
01046         /* sendfile */
01047 //      off_t offset;
01048         int data_fd; // input file (used with mmap)
01049         int i;
01050         char thisbuffer[SOCKETBUF_SIZE];
01051         char b[48];
01052 //struct timeval tv;
01053         struct tm *t;
01054         int e;
01055         time_t tt;
01056         unsigned long tl[2];
01057         
01058         /* Now send that file to the client - we'd better have it's size to do so */
01059 
01060         data_fd = open(ImgFileName, O_RDONLY);
01061         if(data_fd == -1) {
01062                 fprintf(stderr, "Could not open %s\r\n", ImgFileName);
01063                 exit(1);
01064         }
01065         fstat(data_fd, &statbuf);
01066         filesize = statbuf.st_size;
01067         filepos = 0;
01068 
01069         USEHTTP10(printf("HTTP/1.0 200 OK\n"));
01070         printf("Content-Length: %ld\n", filesize);
01071         printf("Content-Type: image/jpeg\n");
01072         if(!cache)
01073                 printf("Pragma: no-cache\n");
01074         printf("\n");
01075 
01076         /* prepare Exif !!! */
01077         e = open("/dev/ext353", O_RDWR);
01078         ioctl(e, EXIF_IOC_TIME_GET, (void *)tl);
01079 //      gettimeofday(&tv, NULL);
01080 //      tt = tv.tv_sec;
01081         tt = tl[0];
01082         t = gmtime(&tt);
01083         sprintf(b, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
01084         ioctl(e, EXIF_IOC_TIME_SET, (void *)b);
01085         ioctl(e, EXIF_IOC_TIME_OR_SET, (void *)b);
01086         sprintf(b, "%06d", (int) tl[1]);
01087         ioctl(e, EXIF_IOC_SUBSEC_OR_SET, (void *)b);
01088 #ifdef USE_MMAP
01089         void *exif = NULL;
01090         void *jpeg = NULL;
01091         struct ext_jpeg_mmap_desc_t mdesc;
01092         ioctl(e, EXT_JPEG_MMAP_DESC, (void *)&mdesc);
01093         exif = mmap((void *)mdesc.mmap_start, mdesc.mmap_exif_length, PROT_READ, MAP_SHARED, e, 0);
01094         jpeg = mmap(0, mdesc.mmap_jpeg_length, PROT_READ, MAP_SHARED, e, 0);
01095         void *jpeg_2 = mmap(jpeg + mdesc.mmap_jpeg_length, mdesc.mmap_jpeg_length, PROT_READ, MAP_SHARED | MAP_FIXED, e, 0);
01096  D6(fprintf(stderr,"mdesc.mmap_start=%p, exif=%p, jpeg=%p jpeg_2=%p mdesc.mmap_jpeg_length=%d:",mdesc.mmap_start, exif, jpeg, jpeg_2, mdesc.mmap_jpeg_length));
01097 
01098         fwrite(exif, 1, mdesc.exif_length, stdout);
01099         long c = mdesc.jpeg_length;
01100         int to_send = 65536;
01101         void *ptr = jpeg;
01102         ptr += mdesc.jpeg_addr;
01103         do {
01104                 fwrite(ptr, 1, (c > to_send) ? to_send : c, stdout);
01105                 c -= to_send;
01106                 ptr += to_send;
01107         } while(c > 0);
01108         char trailer[2] = {0xff, 0xd9};
01109         fwrite((void *)trailer, 1, 2, stdout);
01110 #endif
01111         close(e);
01112         /* Write body */
01113 //      offset=0;
01114 #ifndef USE_MMAP
01115         while((i = read(data_fd, thisbuffer, SOCKETBUF_SIZE)) > 0)
01116                 fwrite(thisbuffer, 1, i, stdout);
01117 #endif
01118         close(data_fd);
01119         return 0;
01120 }
01121 
01122 int send_quicktime (const char * ImgFileName, const char * qtSourceFileName, const char * headerFileName,  int nrep, int safe, int sample_dur){
01123 // safe - percents. if current size > (100-safe) - the quality will decrease, if < 100-2*safe - increase
01124 
01125    int fr;
01126    int data_fd, header_fd;
01127    int i,l,z,ImageWidth,ImageHeight;
01128 
01129   char  thisbuffer[SOCKETBUF_SIZE];
01130 
01131 
01132    int samplesPerChunk=10;
01133 
01134    int framesize;
01135    int timescale=600;
01136    int frmax;
01137    int frmin;
01138 
01139     struct stat statbuf;
01140     unsigned long filesize;                     /* filesize */
01141 
01142 
01143 
01144    data_fd = open(ImgFileName, O_RDONLY);
01145 
01146    if(data_fd == -1) {
01147      fprintf(stderr,"Could not open %s\r\n",ImgFileName);
01148      exit (1);
01149    }
01150 // here - "small" size, w/o boarders
01151    ImageWidth =  ioctl(data_fd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0);
01152    ImageHeight = ioctl(data_fd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0);
01153 
01154    if (safe <1) safe = 1;
01155    if (safe >40) safe = 40;
01156 
01157    ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_CATCHUP); // will point to the latest got or being acquired (if
01158    ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET); // Start fresh - image in memory may be obsolete...
01159 //    if  ((l=lseek(data_fd,0,2))==0) { // if no image available
01160         ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_ACQUIRE); // get one
01161         while ((l=lseek(data_fd,0,2))==0);
01162 // will return 0 until xfer is over // and wait
01163 //    }
01164     framesize= l;
01165     l=(l*safe)/200;
01166     framesize+= 3*l;
01167     frmax= framesize - 2*l;
01168     frmin= frmax     - 2*l;
01169 // just round it
01170     framesize &= 0xfffffff0;
01171 
01172 // find the appropriate frame size
01173 
01174    if ((i= qtime (qtSourceFileName,
01175            headerFileName,
01176            ImageWidth,  // width in pixels
01177            ImageHeight,
01178            nrep,
01179            sample_dur,
01180            samplesPerChunk,
01181            framesize,
01182            timescale,
01183            NULL // all frames the same size
01184          ))<0) return i;
01185 
01186 
01187 
01188    USEHTTP10(printf("HTTP/1.0 200 OK\n"));
01189 
01190 
01191   // Write header file if any
01192   if ((headerFileName !=NULL) && ((header_fd = open(headerFileName, O_RDONLY)) >=0) ) {
01193      fstat(header_fd, &statbuf);
01194      filesize = statbuf.st_size;
01195      filesize+=framesize*nrep;
01196      printf("Content-Length: %ld\n",filesize);
01197      printf("Content-Type: video/quicktime\n");
01198      printf("Pragma: no-cache\n\n");
01199 
01200      while ((i=read (header_fd,thisbuffer,SOCKETBUF_SIZE))>0) fwrite (thisbuffer,1,i,stdout);
01201      close(header_fd);
01202   } else {
01203      printf("Content-Type: video/quicktime\n");
01204      printf("Pragma: no-cache\n\n");
01205   }
01206   // Now send out the whole thing
01207 
01208   data_fd = open(ImgFileName, O_RDONLY);
01209   if(data_fd == -1) {
01210     fprintf(stderr,"Could not open %s\r\n",ImgFileName);
01211     exit (1);
01212   }
01213   ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_CATCHUP); // will point to the latest got or being acquired (if none got ever)
01214   ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
01215   ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_ACQUIRE); // start compression AND acquisition.
01216   fr=0;
01217   while (fr < nrep) {
01218     while ((l=lseek(data_fd,0,2))==0);
01219 // will return 0 until xfer is over
01220 // see if quality needs adjustment
01221      if (l>frmax) {
01222          ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG_QUALITY ),
01223          ioctl (data_fd, _CCCMD( CCAM_RPARS , P_QUALITY), 0) -2); // decrease by 2
01224 
01225 
01226      } else if (l <frmin) {
01227          ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG_QUALITY ),
01228          ioctl (data_fd, _CCCMD( CCAM_RPARS , P_QUALITY), 0) + 2); // increase by 2
01229      }
01230      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_ACQUIRE); // start compression AND acquisition.
01231 //start next frame acquisition
01232 
01233     lseek(data_fd,0,0); // beginning of a file
01234     if ((l<=framesize)) { // do not send frames bigger than padsize
01235       while ((i=read (data_fd,thisbuffer,SOCKETBUF_SIZE))>0) fwrite (thisbuffer,1,i,stdout);
01236       memset (thisbuffer,0xff,SOCKETBUF_SIZE); // or change to 0x00??
01237         z=framesize-l;
01238         while (z>0) {
01239           i=z;
01240           if (i>SOCKETBUF_SIZE) i= SOCKETBUF_SIZE;
01241           fwrite (thisbuffer,1,i,stdout);
01242           z-=i;
01243       }
01244       fr++;     // only for frames sent out
01245     }
01246     ioctl (data_fd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET); // done with this frame (any size, sent or not)
01247   }
01248   close(data_fd);
01249 
01250   return 0;
01251 }
01252 
01253 
01254 #define CCAM_SPARE_MEM 100000   // number of 32-bit words to leave anused during JPEG clip capturing
01255 #define CCAM_MAX_NUM_FRAMES 16384 // maximal number of frames in a clip
01256 
01257 //    send_jpegfile_image ("/etc/1pix.jpeg");
01258 //    1 - start constant compression of all acquired frames
01259 //    2 - stop constant compression. If was not running - then start, acquire the whole buffer and stop
01260 //    4 - read movie from buffer
01261 //    6 (and 5?) - stop, then read
01262 
01263 // make a clip in memory
01264 
01265 // will return <=0 if 1x1 pix JPEG is needed to be returned. >0 - number of sent frames in the clip
01266 int send_quicktime_clip (const char * ImgFileName,
01267                  const char * qtSourceFileName,
01268                  const char * headerFileName,
01269                  int qcmd,        // command to perform
01270                  int tscale){ // scale to slow down playback
01271 
01272    int data_fd, header_fd;
01273    int i,l,ImageWidth,ImageHeight;
01274 
01275   char  thisbuffer[SOCKETBUF_SIZE];
01276 
01277    int samplesPerChunk=10;
01278    int timescale=10000;
01279    int sample_dur,nrep;
01280    int frame_sizes[CCAM_MAX_NUM_FRAMES];
01281 
01282     struct stat statbuf;
01283     unsigned long filesize;                     /* filesize */
01284 
01285 
01286 
01287    data_fd = open(ImgFileName, O_RDONLY);
01288 
01289    if(data_fd == -1) {
01290      fprintf(stderr,"Could not open %s\r\n",ImgFileName);
01291      exit (1);
01292    }
01293    if (((i=ioctl(data_fd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0))== CAMSEQ_SINGLE) ||
01294        ( i==                                                                CAMSEQ_STOP)) {
01295      qcmd &= 4; //no start/stop - or nothing at all ??
01296    } else if (i== CAMSEQ_RUN) { // running - stop it!
01297      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_STOP); // stop constant acquisition/acquire full memory
01298    }  else if ((qcmd & 3) ==3) { // STOP/ACQUIRE
01299      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_STOP); // start filling buffer once (old "stop")
01300    }  else if ((qcmd & 2) !=0) {
01301      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_JUST_STOP); // "stop", no "acquire"
01302    }  else if ((qcmd & 1) !=0) {
01303      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_START); // just start it
01304      qcmd &=3; //will not read
01305    }
01306 
01307    if ((qcmd & 4)==0) return 0; // reading clip is not needed  - will send 1x1 pix jpeg
01308 
01309 //#define      JPEG_CMD_START      0x0a // start constant compression mode
01310 //#define      JPEG_CMD_STOP       0x0b // stop constant compression mode (may want to wait for CAMSEQ_DONE)
01311 //#define      JPEG_CMD_FRAMES     0x0c // returns number of frames in buffer, (re)uilds frames chain
01312 
01313 // now wait for fininshing compression (or external resetting)
01314    while (((i=ioctl(data_fd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0))== CAMSEQ_STOP) ||
01315           (i                                                                == CAMSEQ_SINGLE)) ; // cannot be CAMSEQ_RUN
01316 //stop if it was running
01317    if (ioctl(data_fd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0)==CAMSEQ_JPEG) {
01318      // those 2 next commands not needed? - yes, or it will somehow continue (when advancing read pointer?)
01319      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_DMA ), CCAM_DMA_CMD_STOP); // stop acquisition (or it will continue to acquire)
01320      ioctl (data_fd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // stop acquisition and reset "CAMSEQ_JPEG"
01321    }
01322 // find out how many frames are there in the buffer:
01323 
01324    i=ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_FRAMES); // build frames chain
01325 
01326    if (i==0) return 0; // no frames in the buffer to make a movie
01327    ImageWidth =  ioctl(data_fd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0);
01328    ImageHeight = ioctl(data_fd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0);
01329    if (tscale<1) tscale=1;
01330    if (tscale>10000) tscale=10000;
01331 //   i=ioctl(data_fd, _CCCMD( CCAM_RPARS , P_CLK_SENSOR), 0)*1000000/timescale; // for 10000 it will be 100
01332    i=ioctl(data_fd, _CCCMD( CCAM_RPARS , P_CLK_SENSOR), 0)*1/timescale; // for 10000 it will be 100
01333    sample_dur=ioctl(data_fd, _CCCMD( CCAM_RPARS , P_PERIOD), 0)/i; // temporary 20 MHz, result - usec
01334 
01335 // first pass find frame lengths and number of frames
01336    ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_SAVE_RP); // save read pointer
01337    nrep=0;
01338    while ((nrep<CCAM_MAX_NUM_FRAMES) && ((l=lseek(data_fd,0,2))>0) ) {
01339      frame_sizes[nrep++]=l;
01340      ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
01341    }
01342    if (nrep==0) {close(data_fd);return -1;} // empty file
01343 // adjust samplesPerChunk
01344    if ((nrep/samplesPerChunk)<10) {
01345      samplesPerChunk=nrep/10;
01346      if (samplesPerChunk <1) samplesPerChunk=1;
01347    }
01348    nrep=samplesPerChunk*(nrep/samplesPerChunk); // losing some frames??
01349 
01350    filesize=0;
01351    for (i=0;i<nrep;i++) filesize+=frame_sizes[i];
01352    ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_RESTORE_RP); // restore read pointer to the first frame in a clip
01353 
01354    if ((i= qtime (qtSourceFileName,
01355            headerFileName,
01356            ImageWidth,  // width in pixels
01357            ImageHeight,
01358            nrep,
01359            sample_dur,
01360            samplesPerChunk,
01361            0,
01362            timescale/tscale,
01363            frame_sizes
01364          ))<0) return i;
01365 
01366 
01367 
01368    USEHTTP10(printf("HTTP/1.0 200 OK\n"));
01369 
01370   // Write header file if any
01371   if ((headerFileName !=NULL) && ((header_fd = open(headerFileName, O_RDONLY)) >=0) ) {
01372      fstat(header_fd, &statbuf);
01373      filesize+=statbuf.st_size;
01374      printf("Content-Length: %ld\n",filesize);
01375      printf("Content-Type: video/quicktime\n");
01376      printf("Pragma: no-cache\n\n");
01377 
01378      while ((l=read (header_fd,thisbuffer,SOCKETBUF_SIZE))>0) fwrite (thisbuffer,1,l,stdout);
01379      close(header_fd);
01380   } else {
01381      printf("Content-Type: video/quicktime\n");
01382      printf("Pragma: no-cache\n\n");
01383   }
01384   // Now send out the whole thing
01385   for (i=0; i<nrep;i++) {
01386     lseek(data_fd,0,0); // beginning of a file
01387     while ((l=read (data_fd,thisbuffer,SOCKETBUF_SIZE))>0) fwrite (thisbuffer,1,l,stdout);
01388     ioctl (data_fd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
01389   }
01390   close(data_fd);
01391   return 0;
01392 }
01393 
01394 
01395 
01396 void printDocumentLine(const char* name, const char* value, int format) { //0 - html, 1 - javaScript, 2 - xml
01397   switch (format) {
01398 //   case 0: {printf("<br>%s=%s\n",name,value);break;}
01399    case 0: {printf("<tr><td>%s</td><td>%s</td></tr>\n",name,value);break;}
01400    case 1: {printf("document.%s=%s;\n",name,value);break;}
01401    case 2: {printf("<%s>%s</%s>",name,value,name);break;}
01402   }
01403 }
01404 
01405 void printStreamerParameters(int fmode) {
01406         int run = 0;
01407         #define STREAMER_CONF_RUN   "/var/state/streamer.conf";
01408         #define STREAMER_CONF_STOP  "/etc/streamer.conf";
01409         const char *conf = STREAMER_CONF_STOP;
01410         int fd = open("/dev/stream", O_RDONLY);
01411         if(fd < 0) {
01412                 run = 1;
01413                 conf = STREAMER_CONF_RUN;
01414         } else {
01415                 close(fd);
01416                 conf = STREAMER_CONF_STOP;
01417         }
01418         FILE *f = fopen(conf, "r");
01419         char buf[102] = "S_", *v, *e;
01420         char *b = buf + 2;
01421         if(f)
01422                 while(fgets(b, sizeof buf - 2, f)) {
01423                         v = strchr(b, '=');
01424                         if(!v)
01425                                 continue;
01426                         *v++ = 0;
01427                         e = strchr(v,'\n');
01428                         if(e) {
01429                                 *e = 0;
01430                                 if(strcmp(b,"pid") == 0) {
01431                                         if(kill(atoi(v), 0) == 0)
01432                                                 run = 1;   
01433                                 } else
01434                                         printDocumentLine(buf, v, fmode);
01435                         } else
01436                                 while(getc(f) != '\n' && !feof(f) && !ferror(f));
01437                 }
01438         printDocumentLine("S_STREAM", (run ? "1" : "0"), fmode);
01439 /*
01440     FILE *f=fopen("/var/state/streamer.conf","r");
01441     char buf[102]="S_", *v, *e;
01442     char *b=buf+2;
01443     int run=0;
01444     if(f)while(fgets(b, sizeof buf - 2, f)) {
01445         v=strchr(b,'=');
01446         if(!v)continue;
01447         *v++=0;
01448         e=strchr(v,'\n'); 
01449         if(e) {
01450           *e=0; 
01451           if(strcmp(b,"pid")==0) {
01452             if(kill(atoi(v),0)==0) run=1;
01453           }
01454           else printDocumentLine(buf, v, fmode);
01455         } else while(getc(f)!='\n' && !feof(f) && !ferror(f));
01456     }
01457     printDocumentLine("S_STREAM", (run?"1":"0"), fmode);
01458 */
01459 }
01460 
01461 int send_html_data(const char * devfn, const char * dmafn, int mode, int refreshPeriod, const char * onLoad, const char * javaScript) {
01462   int i;
01463   int mhtml=0;
01464   int mjs=0;
01465   int mxml=0;
01466   int fmode;
01467   int devfd;
01468   char s[256];
01469   double f;
01470   double d256=1.0/256;
01471   struct beam_params beam;
01472 /*
01473 #define HTML_SENSOR_JS   1
01474 #define HTML_SENSOR_HTML 2
01475 #define HTML_BEAM_JS     3
01476 #define HTML_BEAM_HTML   4
01477 
01478 #define HTML_STATE_JS    5
01479 #define HTML_STATE_HTML  6
01480 #define HTML_ACQUIRE     7
01481 #define HTML_RESET       8
01482 #define XML_SENSOR      10
01483 #define XML_BEAM        11
01484 #define XML_STATE       12
01485 #define XML_ACQUIRE     13
01486 #define XML_RESET       14
01487 
01488 
01489 */
01490  switch (mode) {
01491   case HTML_SENSOR_JS:
01492   case HTML_BEAM_JS:
01493   case HTML_STATE_JS:
01494     mjs=1;     // and continue - no break
01495   case HTML_SENSOR_HTML:
01496   case HTML_BEAM_HTML:
01497   case HTML_STATE_HTML:
01498   case HTML_ACQUIRE:
01499   case HTML_RESET:
01500     {mhtml=1;break;}
01501 
01502   case XML_SENSOR:
01503   case XML_BEAM:
01504   case XML_STATE:
01505 
01506   case XML_ACQUIRE:
01507   case XML_RESET:
01508     mxml=1;
01509  }
01510   fmode=(mxml)?2:(mjs?1:0);
01511 
01512   if (mhtml) {
01513     printf("Content-Type: text/html\n");
01514     printf("Pragma: no-cache\n\n"); // 2 new lines!
01515     printf("<html><head>\n");
01516     if (refreshPeriod)   printf("<meta http-equiv=\"refresh\" content=\"%d\">\n",refreshPeriod);
01517     if (javaScript)      printf("<script language=\"JavaScript\" src=\"%s\"></script>\n",javaScript);
01518     if (mjs) {
01519       printf("<script language=\"JavaScript\">\n");
01520       printf("<!--\n");
01521 
01522     } else {
01523       if (onLoad) printf("</head><body onLoad=\"%s\">\n",onLoad);
01524       else printf("</head><body>\n");
01525       printf("<table border=\"1\">\n");
01526     }
01527   } else { // if mxml
01528     printf("Content-Type: text/xml\n");
01529     printf("Pragma: no-cache\n\n"); // 2 new lines!
01530 
01531     printf("<?xml version=\"1.0\" ?>\n");
01532     printf("<camera>\n");
01533   }
01534 
01535   if ((devfd = open(devfn, O_RDONLY)) >=0) {
01536     if ((mode==HTML_STATE_JS) || (mode==HTML_STATE_HTML) || (mode==XML_STATE)) { // return acquisition state - "5" =  image got
01537 // return state here
01538       sprintf(s,"%d",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0));
01539       printDocumentLine("SENSOR_STATE", s, fmode);
01540     } else if ((mode==HTML_BEAM_JS) || (mode==HTML_BEAM_HTML) || (mode==XML_BEAM)) { // beam parameters
01541           if (ioctl(devfd, _CCCMD( CCAM_RPARS , P_BITS ), 0) != 10) \
01542              fprintf(stderr,"ccam.c ERROR: beam parameters are calculated only in 10-bit acquisition mode\n");
01543           else {
01544             if ((i=calculateBeamParams(dmafn, \
01545 
01546                                         ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0), \
01547                                         ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0), \
01548                                         &beam)) < 0) {
01549              fprintf(stderr,"ccam.c ERROR: calculateBeamParams returned %d\n",i);
01550                 } else {
01551 // acquisition parameters
01552           i= (ioctl(devfd, _CCCMD( CCAM_RPARS ,P_SENSOR)) & SENSOR_MASK);
01553           switch (i) {
01554             case SENSOR_ZR32112: {
01555             printDocumentLine("sensor", "'ZR32112'",   fmode);
01556             printDocumentLine("pixel",  "'0.0075 mm'", fmode);
01557             break;
01558            }
01559             case SENSOR_ZR32212: {
01560             printDocumentLine("sensor", "'ZR32212'",   fmode);
01561             printDocumentLine("pixel",  "'0.006 mm'",  fmode);
01562             break;
01563            }
01564            case SENSOR_KAC1310: {
01565             printDocumentLine("sensor", "'KAC-1310'",  fmode);
01566             printDocumentLine("pixel",  "'0.006 mm'",  fmode);
01567             break;
01568            }
01569           }
01570           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0));
01571           printDocumentLine("width", s, fmode);
01572           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0));
01573           printDocumentLine("height", s, fmode);
01574           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS ,P_DCM_HOR)));
01575           printDocumentLine("decimation", s, fmode);
01576           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS ,P_BIN_HOR)));
01577           printDocumentLine("binning", s, fmode);
01578 // primary sums
01579           sprintf(s,"%e",beam.SQ);   printDocumentLine("SQ",   s, fmode);
01580 
01581           sprintf(s,"%e",beam.SxQ);  printDocumentLine("SxQ",  s, fmode);
01582           sprintf(s,"%e",beam.SyQ);  printDocumentLine("SyQ",  s, fmode);
01583           sprintf(s,"%e",beam.SxxQ); printDocumentLine("SxxQ", s, fmode);
01584           sprintf(s,"%e",beam.SyyQ); printDocumentLine("SyyQ", s, fmode);
01585           sprintf(s,"%e",beam.SxyQ); printDocumentLine("SxyQ", s, fmode);
01586 //moments
01587           sprintf(s,"%e",beam.xc);   printDocumentLine("xc",   s, fmode);
01588 
01589           sprintf(s,"%e",beam.yc);   printDocumentLine("yc",   s, fmode);
01590           sprintf(s,"%e",beam.s2x);  printDocumentLine("s2x",  s, fmode);
01591           sprintf(s,"%e",beam.s2y);  printDocumentLine("s2y",  s, fmode);
01592           sprintf(s,"%e",beam.sxy);  printDocumentLine("sxy",  s, fmode);
01593 //results
01594           sprintf(s,"%e",beam.dx);   printDocumentLine("dx",   s, fmode);
01595           sprintf(s,"%e",beam.dy);   printDocumentLine("dy",   s, fmode);
01596           sprintf(s,"%e",beam.d);    printDocumentLine("d",    s, fmode);
01597           sprintf(s,"%e",beam.az);   printDocumentLine("az",   s, fmode);
01598           sprintf(s,"%e",beam.dxe);  printDocumentLine("dxe",  s, fmode);
01599           sprintf(s,"%e",beam.dye);  printDocumentLine("dye",  s, fmode);
01600           sprintf(s,"%e",beam.ar);   printDocumentLine("ar",   s, fmode);
01601                 }
01602           }
01603         } else if ((mode==HTML_SENSOR_JS) || (mode==HTML_SENSOR_HTML) || (mode==XML_SENSOR)) { // return all sensor parameters
01604 // return state first
01605           sprintf(s,"%d",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0));printDocumentLine("SENSOR_STATE", s, fmode);
01606 //          f=(1000000.0*ioctl(devfd, _CCCMD( CCAM_RPARS , P_CLK_SENSOR), 0))/ioctl(devfd, _CCCMD( CCAM_RPARS , P_PERIOD), 0);
01607           f=(0.01*ioctl(devfd, _CCCMD( CCAM_RPARS , P_FP100S), 0));
01608           sprintf(s,"%f",f);  printDocumentLine("FPS", s, fmode);
01609           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FPSLM), 0)); printDocumentLine("P_FPSLM", s, fmode);
01610           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SENSOR_WIDTH), 0)); printDocumentLine("P_SENSOR_WIDTH", s, fmode);
01611           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SENSOR_HEIGHT), 0)); printDocumentLine("P_SENSOR_HEIGHT", s, fmode);
01612           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH), 0)); printDocumentLine("P_ACTUAL_WIDTH", s, fmode);
01613           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT), 0)); printDocumentLine("P_ACTUAL_HEIGHT", s, fmode);
01614           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_VIRT_WIDTH), 0)); printDocumentLine("P_VIRT_WIDTH", s, fmode);
01615           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_VIRT_HEIGHT), 0)); printDocumentLine("P_VIRT_HEIGHT", s, fmode);
01616           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_WOI_LEFT), 0)); printDocumentLine("P_WOI_LEFT", s, fmode);
01617           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_WOI_TOP), 0)); printDocumentLine("P_WOI_TOP", s, fmode);
01618           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_WOI_WIDTH), 0)); printDocumentLine("P_WOI_WIDTH", s, fmode);
01619           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_WOI_HEIGHT), 0)); printDocumentLine("P_WOI_HEIGHT", s, fmode);
01620           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FLIP), 0)); printDocumentLine("P_FLIP", s, fmode);
01621           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_DCM_HOR), 0)); printDocumentLine("P_DCM_HOR", s, fmode);
01622           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_DCM_VERT), 0)); printDocumentLine("P_DCM_VERT", s, fmode);
01623 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_DCM_HOR), 0) >> 4); printDocumentLine("P_BIN_HOR", s, fmode);
01624 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_DCM_VERT), 0) >>4 ); printDocumentLine("P_BIN_VERT", s, fmode);
01625           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_BIN_HOR), 0)); printDocumentLine("P_BIN_HOR", s, fmode);
01626           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_BIN_VERT), 0)); printDocumentLine("P_BIN_VERT", s, fmode);
01627           
01628           sprintf(s,"%f",0.000001*ioctl(devfd, _CCCMD( CCAM_RPARS , P_CLK_FPGA), 0));  printDocumentLine("P_CLK_FPGA", s, fmode);
01629           sprintf(s,"%f",0.000001*ioctl(devfd, _CCCMD( CCAM_RPARS , P_CLK_SENSOR), 0));  printDocumentLine("P_CLK_SENSOR", s, fmode);
01630           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FRAME), 0));  printDocumentLine("P_FRAME", s, fmode);
01631           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SENSOR ), 0)); printDocumentLine("P_SENSOR", s, fmode);
01632           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_LPR), 0)); printDocumentLine("P_LPR", s, fmode);
01633           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_IMAGE_SIZE), 0)); printDocumentLine("P_IMAGE_SIZE", s, fmode);
01634           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_BAYER), 0)); printDocumentLine("P_BAYER", s, fmode);
01635           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_COLOR_SATURATION_BLUE), 0)); printDocumentLine("P_COLOR_SATURATION_BLUE", s, fmode);
01636           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_COLOR_SATURATION_RED), 0)); printDocumentLine("P_COLOR_SATURATION_RED", s, fmode);
01637           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAMMA), 0)); printDocumentLine("P_GAMMA", s, fmode);
01638           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_PIXEL_LOW), 0)); printDocumentLine("P_PIXEL_LOW", s, fmode);
01639           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_PIXEL_HIGH),0)); printDocumentLine("P_PIXEL_HIGH", s, fmode);
01640           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_TRIGGERED), 0)); printDocumentLine("P_TRIGGERED", s, fmode);
01641           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_TRIG), 0)); printDocumentLine("P_TRIG", s, fmode);
01642           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_EXPOS), 0)); printDocumentLine("P_EXPOS", s, fmode);
01643           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_PAGE_ACQ), 0)); printDocumentLine("P_PAGE_ACQ", s, fmode);
01644 
01645           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_PAGE_READ), 0)); printDocumentLine("P_PAGE_READ", s, fmode);
01646           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_BGFRAME), 0));   printDocumentLine("P_BGFRAME", s, fmode);
01647 
01648           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_OVERLAP), 0)); printDocumentLine("P_OVERLAP", s, fmode);
01649           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_VIDEO), 0)); printDocumentLine("P_VIDEO", s, fmode);
01650           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_AUXCM), 0)); printDocumentLine("P_AUXCM", s, fmode);
01651           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_COLOR), 0)); printDocumentLine("P_COLOR", s, fmode); // can be combined with test modes
01652 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_TEST), 0)); printDocumentLine("P_TEST", s, fmode);
01653           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_MCLK), 0)); printDocumentLine("P_MCLK", s, fmode);
01654 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_MCLK_DIS), 0)); printDocumentLine("P_MCLK_DIS", s, fmode);
01655           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_PF_HEIGHT), 0)); printDocumentLine("P_PF_HEIGHT", s, fmode);
01656           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FRAMESYNC_DLY), 0)); printDocumentLine("P_FRAMESYNC_DLY", s, fmode);
01657           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_BITS), 0)); printDocumentLine("P_BITS", s, fmode);
01658           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SHIFTL), 0)); printDocumentLine("P_SHIFTL", s, fmode);
01659 
01660           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FPNS), 0)); printDocumentLine("P_FPNS", s, fmode);
01661           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FPNM), 0)); printDocumentLine("P_FPNM", s, fmode);
01662           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_VEXPOS), 0)); printDocumentLine("P_VEXPOS", s, fmode);
01663 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAINR), 0)); printDocumentLine("P_GAINR", s, fmode);
01664 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAING), 0)); printDocumentLine("P_GAING", s, fmode);
01665 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAINB), 0)); printDocumentLine("P_GAINB", s, fmode);
01666 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAINGB), 0)); printDocumentLine("P_GAINGB", s, fmode);
01667 
01668           sprintf(s,"%f",d256*ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAINR), 0)); printDocumentLine("P_GAINR", s, fmode);
01669           sprintf(s,"%f",d256*ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAING), 0)); printDocumentLine("P_GAING", s, fmode);
01670           sprintf(s,"%f",d256*ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAINB), 0)); printDocumentLine("P_GAINB", s, fmode);
01671           sprintf(s,"%f",d256*ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAINGB), 0)); printDocumentLine("P_GAINGB", s, fmode);
01672           sprintf(s,"%f",d256*ioctl(devfd, _CCCMD( CCAM_RPARS , P_RSCALE), 0)); printDocumentLine("P_RSCALE", s, fmode);
01673           sprintf(s,"%f",d256*ioctl(devfd, _CCCMD( CCAM_RPARS , P_BSCALE), 0)); printDocumentLine("P_BSCALE", s, fmode);
01674 
01675 
01676           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FATZERO), 0)); printDocumentLine("P_FATZERO", s, fmode);
01677           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_VIRTTRIG), 0)); printDocumentLine("P_VIRTTRIG", s, fmode);
01678 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SPEC_KAC_GGA), 0)); printDocumentLine("P_SPEC_KAC_GGA", s, fmode);
01679 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SPEC_KAC_GGB), 0)); printDocumentLine("P_SPEC_KAC_GGB", s, fmode);
01680 //          sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_SPEC_KAC_GGM), 0)); printDocumentLine("P_SPEC_KAC_GGM", s, fmode);
01681           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_QUALITY), 0)); printDocumentLine("P_QUALITY", s, fmode);
01682           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_PERIOD), 0));  printDocumentLine("P_PERIOD", s, fmode);
01683           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_FPGA_XTRA), 0));  printDocumentLine("P_FPGA_XTRA", s, fmode);
01684 
01685           sprintf(s,"%d",ioctl(devfd, _CCCMD( CCAM_RPARS , P_JPEG_WP), 0));  printDocumentLine("P_JPEG_WP", s, fmode);
01686           
01687           printStreamerParameters(fmode);
01688 
01689           }
01690 
01691     close (devfd);
01692   }
01693   if (mhtml) {
01694     if (mjs) {
01695       printf("//->\n");
01696       if (onLoad) printf("</script></head><body onLoad=\"%s\">\n",onLoad);
01697       else printf("</script></head><body>\n");
01698     } else printf("</table>\n");
01699 
01700     printf("</body></html>\n");
01701   } else { // if mxml?
01702     printf("</camera>\n");
01703   }
01704   return 0;
01705 }
01706 
01707 
01708 int parseQuery(struct key_value * params, char * qry) {
01709   char * cp;
01710   int l=0;
01711   cp=strtok(qry,"=");
01712   while ((cp) && (l<QRY_MAXPARAMS)) {
01713     params[l].key=cp;
01714     cp=strtok(NULL,"&");
01715     params[l++].value=cp;
01716     if (cp) cp=strtok(NULL,"=");
01717   }
01718  params[l].key=NULL;
01719  return l;
01720 
01721 }
01722 
01723 char * paramValue(struct key_value * params, char * skey) { // returns pointer to parameter value, NULL if not defined
01724   int i=0;
01725   if (skey)
01726    while ((i<QRY_MAXPARAMS) && (params[i].key)) {
01727     if (strcmp(skey,params[i].key)==0) return   params[i].value;
01728 
01729     i++;
01730    }
01731   return NULL;
01732 }
01733 
01734 int optionPresent(struct key_value * params, char * skey, char c) { // returns 1 if c is in argument skey
01735 //  int i=0;
01736   char * cp;
01737   return (((cp=paramValue(params, skey))) && (strchr(cp,c)));
01738 }
01739 int processImage(struct key_value * params,
01740                  const char * ImgFileName,   // camera DMA pseudofile name (to control camera/get parameters)
01741                  const char * bufFileName,   // buffer file name (used in buffered file output only)
01742                  const char * pc_par,        // pseudocolors string
01743 // used in image mode
01744                  int iq_par,                 // JPEG image quality (negative - BMP mode)
01745                  int gd_par,                 // "digital gain" value
01746 // used in html mode only
01747                  int html_par,               // html mode (0 - image mode)
01748                  int htmlr_par,              // html refresh period (if >0)
01749                  const char * htmll_par,     // html "onLoad" value for <body> tag (or NULL)
01750                  const char * htmlj_par,     // html extarnal javaScript file to be included in <head> portion
01751 // used in vrml mode only
01752                  int vrml_par,               // VRML - output VRML instead of image
01753                  int vrmlm_par,                          // maximal pixel (full scale -= 1024, 0 - auto normalize)
01754                  int vrmld_par,              // square width/height (in pixels) to be integrated into a vertex
01755                  int vrmlb_par,              // number of separate profile blocks to build (each direction, total - squared)
01756                  int vrmli_par,              // use indentation (easier to read generated VRML code)
01757                  int vrmlf_par,              // use 1 digit after decimal point (0 - integers)
01758                  int vrmll_par,              // number of intensity levels to show isolines for
01759                  int vrmlo_par,              // options (bitmask): 1 - build flat isolines, 2 - build elevated isolines
01760                  int vrmlz_par               //- 0..9 output (gzip) compression level (0 - none, 1 - fastest, default - 6, best -9)
01761                  ) {
01762       int i;
01763       int devfd;
01764       int ImageWidth;             // actual image width - here increment by 2 to include boarders
01765           int ImageHeight;            // actual image height - same as above
01766       int Color;                  // 0 - monochrome, 1 - color
01767           int bayer;                  // bayer filter under pixel 0/0
01768       int Depth;                  // acquired picture depth (10/8/4 bits/pixel)
01769       const char * sourceFileName=ImgFileName; // where to get image from (may be both memory buffer or file)
01770       if ((devfd = open(ImgFileName, O_RDWR))<0) { // check control OK
01771         printf(error304);
01772         return -1;
01773       }
01774 // DD(ioctl(devfd, _CCCMD(CCAM_WPARS ,  62 ),     20)); // +++++just test - to be reported by driver
01775 
01776       ImageWidth =  ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0) + 2;
01777       ImageHeight = ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0) + 2;
01778           bayer =       ioctl(devfd, _CCCMD( CCAM_RPARS , P_BAYER ), 0);
01779           Color=        ioctl(devfd, _CCCMD( CCAM_RPARS , P_COLOR ), 0);
01780           Depth=        ioctl(devfd, _CCCMD( CCAM_RPARS , P_BITS ), 0);
01781       close(devfd);
01782 
01783           if (vrml_par)  i= export_vrml (sourceFileName,
01784                                         ImageWidth,ImageHeight,
01785                                         vrmlm_par,              // maximal pixel (full scale -= 1024, 0 - auto normalize)
01786                                         vrmld_par, vrmld_par,   // rectangle width/height to be combined in one vertex
01787                                         vrmlb_par, vrmlb_par,    // number of separate blocks in x/y direction
01788                                         vrmli_par,                      // VRML text indentation (0/1)
01789                                         vrmlf_par,                      // number of coordinate digits after "." - 0,1,2,3
01790 
01791                                         vrmll_par,                      // number of isolines
01792                                         vrmlo_par & 1,          // 0/1, generate flat isolines with Z=0
01793                                         (vrmlo_par & 2)>>1, // 0/1, generate elevated isolines with Z matching intensity
01794                                         pc_par,                     // string of pseudocolors, i.e "BR" or "mbcgyr" or "546231"
01795                                         vrmlz_par           //- 0..9 output (gzip) compression level (0 - none, 1 - fastest, default - 6, best -9)
01796                                         );
01797 
01798           else if (html_par>=0) i=send_html_data(ImgFileName, sourceFileName, html_par, htmlr_par, htmll_par, htmlj_par);
01799           else {
01800         if (optionPresent(params, "opt", 'b')) i=send_buf_image   (ImageWidth,ImageHeight,iq_par,gd_par,Color,bayer,Depth,pc_par,sourceFileName,bufFileName);
01801         else                                   i=send_immed_image (ImageWidth,ImageHeight,iq_par,gd_par,Color,bayer,Depth,pc_par,sourceFileName);
01802           }
01803       return i;
01804 }
01805 
01806 #define     GAMMA_START  0x400
01807 int     setCamPars(int devfd, int n_bf,   char * cp, char * vp) {
01808   int gr,gb,gg,ggb;
01809   float sens=0.0;
01810   float rscale=0.0; //=0 - not specified, -1 - auto
01811   float bscale=0.0;
01812   int wbthrsh=250;
01813   float wbPercPixels=1.0;
01814   float wbDiffGains[3];
01815 // day/night gain switching expNight/expDay > sensNight/sensDay (safely higher)
01816   float expDay=    500.0;  // 50ms
01817   float expNight=  10000.0;  // 1s
01818   float sensDay=   1.3;
01819   float sensNight= 16.0;
01820   
01821 
01822   int    i; //,j,jj;
01823   int    need_gamma=0;
01824   int    black8=-1;
01825   int    white8=-1; 
01826   int    gamma100=-1;
01827 // histogram  
01828         float gain_f=0;
01829         long int gain_i;
01830         int flag = 0;
01831   
01832 // Specify driver parameters (no validation) - driver will do it
01833 // alternate acquisition pages in "restart" mode
01834 
01835         if (optionPresent(gparams, "opt", 'm')) {
01836            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_PAGE_ACQ ),
01837 (ioctl(devfd, _CCCMD( CCAM_RPARS , P_PAGE_ACQ ), 0)&1)^1 ); // alternate pages
01838 
01839         }
01840 
01841         if ((vp=paramValue(gparams, "gam" ))){ 
01842            i=strtol (vp,&cp,10); if (i>1000) i=1000;  if (i<13) i=13;
01843            if (i!=((gamma100=ioctl(devfd, _CCCMD( CCAM_RPARS , P_GAMMA), 0)))) {
01844              gamma100=i;
01845              ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_GAMMA ),i );
01846              need_gamma=1;
01847            }
01848         }
01849         if ((vp=paramValue(gparams, "pxl" ))){
01850            i=strtol (vp,&cp,10); if (i>254) i=254;  if (i<0) i=0;
01851            if (i!=((black8=ioctl(devfd, _CCCMD( CCAM_RPARS , P_PIXEL_LOW), 0)))) {
01852              black8=i;
01853              ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_PIXEL_LOW ),i );
01854              need_gamma=1;
01855            }
01856         }
01857         if ((vp=paramValue(gparams, "pxh" ))){
01858            i=strtol (vp,&cp,10); if (i>255) i=255;
01859            if (i<=ioctl(devfd, _CCCMD( CCAM_RPARS , P_PIXEL_LOW), 0)) i=ioctl(devfd, _CCCMD( CCAM_RPARS , P_PIXEL_LOW), 0)+1;
01860            if (i!=((white8=ioctl(devfd, _CCCMD( CCAM_RPARS , P_PIXEL_HIGH), 0)))) {
01861              white8=i;
01862              ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_PIXEL_HIGH ),i );
01863              need_gamma=1;
01864            }
01865         }
01866 
01867         if ((vp=paramValue(gparams, "iq")))             ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_QUALITY),      strtol (vp,&cp,10));
01868    if ((vp=paramValue(gparams, "byr" )))      ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_BAYER),      strtol (vp,&cp,10));
01869    else ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_BAYER),      4); // use calculated
01870 
01871 // Add some kodak-specific gain parameters here... - obsolete
01872 
01873         if ((vp=paramValue(gparams, "fpns" )))          ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_FPNS ),      strtol (vp,&cp,10));
01874         if ((vp=paramValue(gparams, "fpnm" )))          ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_FPNM ),      strtol (vp,&cp,10));
01875 
01876 //      if ((vp=paramValue(gparams, "dmasz" ))) ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_DMA_SZ ),     strtol (vp,&cp,10));
01877         if ((vp=paramValue(gparams, "e" )))             ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_EXPOS ),      strtol (vp,&cp,10));
01878         if ((vp=paramValue(gparams, "ve" )))    ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_VEXPOS ),      strtol (vp,&cp,10));
01879 
01880         if ((vp=paramValue(gparams, "vw")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_VIRT_WIDTH ),  strtol (vp,&cp,10));
01881         if ((vp=paramValue(gparams, "vh")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_VIRT_HEIGHT ), strtol (vp,&cp,10));
01882 
01883         if ((vp=paramValue(gparams, "wl")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_WOI_LEFT ),    strtol (vp,&cp,10));
01884 
01885         if ((vp=paramValue(gparams, "wt")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_WOI_TOP ),     strtol (vp,&cp,10));
01886         if ((vp=paramValue(gparams, "ww")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_WOI_WIDTH ),   strtol (vp,&cp,10));
01887 
01888         if ((vp=paramValue(gparams, "wh")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_WOI_HEIGHT ),  strtol (vp,&cp,10));
01889    
01890 //      if ((vp=paramValue(gparams, "pfh")))            ioctl(devfd, _CCCMD(CCAM_WPARS , P_PF_HEIGHT),  strtol (vp,&cp,10));
01891    i=-1;
01892    if ((vp=paramValue(gparams, "pfh")))  i= (strtol (vp,&cp,10) & 0xffff);
01893    if ((vp=paramValue(gparams, "ts"))) {
01894      if (i<0) i=0;
01895      i |= (strtol (vp,&cp,10) << 16);
01896    }
01897    if (i>=0) ioctl(devfd, _CCCMD(CCAM_WPARS , P_PF_HEIGHT),  i); 
01898    
01899    
01900    if ((vp=paramValue(gparams, "fsd")))      ioctl(devfd, _CCCMD(CCAM_WPARS , P_FRAMESYNC_DLY),  strtol (vp,&cp,10));
01901         
01902         
01903    if ((vp=paramValue(gparams, "dh")))          ioctl(devfd, _CCCMD(CCAM_WPARS , P_DCM_HOR ),     strtol (vp,&cp,10));
01904         if ((vp=paramValue(gparams, "dv")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_DCM_VERT ),    strtol (vp,&cp,10));
01905         
01906    if ((vp=paramValue(gparams, "bh")))          ioctl(devfd, _CCCMD(CCAM_WPARS , P_BIN_HOR ),     strtol (vp,&cp,10));
01907         if ((vp=paramValue(gparams, "bv")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_BIN_VERT ),    strtol (vp,&cp,10));
01908         if ((vp=paramValue(gparams, "clk")))            ioctl(devfd, _CCCMD(CCAM_WPARS , P_MCLK ),        strtol (vp,&cp,10));
01909         if ((vp=paramValue(gparams, "bit")))            ioctl(devfd, _CCCMD(CCAM_WPARS , P_BITS ),        strtol (vp,&cp,10));
01910         if ((vp=paramValue(gparams, "shl")))            ioctl(devfd, _CCCMD(CCAM_WPARS , P_SHIFTL ),      strtol (vp,&cp,10));
01911 
01912 /*      if ((vp=paramValue(gparams, "gr")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAINR ),      strtol (vp,&cp,10));
01913         if ((vp=paramValue(gparams, "gg")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAING ),      strtol (vp,&cp,10));
01914         if ((vp=paramValue(gparams, "gb")))             ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAINB ),      strtol (vp,&cp,10));
01915         if ((vp=paramValue(gparams, "ggb")))            ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAINGB ),      strtol (vp,&cp,10));
01916 */
01917    if ((vp=paramValue(gparams, "gr")))   {gr =   256* strtod (vp,&cp); ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAINR ), gr );}
01918    if ((vp=paramValue(gparams, "gg")))   {gg =   256* strtod (vp,&cp); ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAING ), gg );}
01919    if ((vp=paramValue(gparams, "gb")))   {gb =   256* strtod (vp,&cp); ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAINB ), gb );}
01920    if ((vp=paramValue(gparams, "ggb")))  {ggb=   256* strtod (vp,&cp); ioctl(devfd, _CCCMD(CCAM_WPARS , P_GAINGB), ggb);}
01921 
01922    
01923 //   if (strcmp(skey,params[i].key)==0) return  params[i].value;
01924    
01925    if ((vp=paramValue(gparams, "sens")))  {
01926       if (strcmp(vp,"auto")==0) sens=-1;
01927       else                      sens = strtod(vp,&cp);
01928    }   
01929    
01930    if ((vp=paramValue(gparams, "rscale")))  {
01931       if (strcmp(vp,"auto")==0) rscale =-1;
01932       else                      rscale = strtod(vp,&cp);
01933    }   
01934    if ((vp=paramValue(gparams, "bscale")))  {
01935       if (strcmp(vp,"auto")==0) bscale=-1;
01936       else                      bscale = strtod(vp,&cp);
01937    }   
01938 #ifdef SYSLOG
01939 syslog(LOG_ALERT, "rscale == %d, bscale == %d\n", rscale * 100, bscale * 100);
01940 #endif
01941    if ((vp=paramValue(gparams, "wbth")))     wbthrsh=  strtol (vp,&cp,10);
01942    if ((vp=paramValue(gparams, "wbpc")))     wbPercPixels=  strtod (vp,&cp);
01943    if ((vp=paramValue(gparams, "wbpc")))     wbPercPixels=  strtod (vp,&cp);
01944 
01945         if((rscale < 0) || (bscale <0 ) || (sens < 0)) {
01946                 i = calcWhiteBalance(wbthrsh,   // threshold (0..255) for the "brightest color"
01947                         ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0)*
01948                         ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0)*
01949                         (wbPercPixels/100.0), // minimal number of pixels above threshold for the brightest color (threshold will be lowered to satisfy min_pixels)
01950                         wbDiffGains);
01951                 if(i >= 0) {
01952                         flag = 1;
01953                         if(rscale < 0)
01954                                 rscale = wbDiffGains[0];
01955                         if(bscale < 0)
01956                                 bscale = wbDiffGains[1];
01957                         // calculate day/night sensitivity      
01958                         if(sens < 0) { 
01959                                 if((vp = paramValue(gparams, "ed")))
01960                                         expDay = strtod(vp, &cp);
01961                                 if((vp = paramValue(gparams, "en")))
01962                                         expNight = strtod(vp,&cp);
01963                                 if((vp = paramValue(gparams, "sd")))
01964                                         sensDay = strtod(vp,&cp);
01965                                 if((vp = paramValue(gparams, "sn")))
01966                                         sensNight = strtod(vp,&cp);
01967                                 if(wbDiffGains[2] > expNight) {
01968                                         sens = sensNight;
01969                                 } else {
01970                                         if(wbDiffGains[2] < expDay)
01971                                                 sens = sensDay;
01972                                         else
01973                                                 sens = 0;
01974                                 }
01975                         }
01976                 } else { // error
01977                         if(rscale < 0)
01978                                 rscale = 0;
01979                         if(bscale < 0)
01980                                 bscale = 0;
01981                         if(gain_f < 0)
01982                                 sens = 0;
01983                 }
01984         }
01985         if(rscale > 0)   {
01986                 flag = 1;
01987                 gain_f = 256.0 * rscale;
01988                 gain_i = (unsigned long)gain_f;
01989 //      ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAINR), gain_i);
01990                 ioctl(devfd, _CCCMD(CCAM_WPARS,  P_RSCALE), gain_i);
01991 #ifdef SYSLOG
01992 syslog(LOG_ALERT, "rscale == 0x%04X\n", gain_i);
01993 #endif
01994         }
01995         if(bscale > 0)   {
01996                 flag = 1;
01997                 gain_f = 256.0 * bscale;
01998                 gain_i = (unsigned long)gain_f;
01999 //      ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAINB), gain_i);
02000                 ioctl(devfd, _CCCMD(CCAM_WPARS,  P_BSCALE), gain_i);
02001 #ifdef SYSLOG
02002 syslog(LOG_ALERT, "bscale == 0x%04X\n", gain_i);
02003 #endif
02004         }
02005         
02006 //   if ((vp=paramValue(gparams, "sens"))){
02007 //      gain_f = strtod(vp,&cp);
02008    if (sens >0) {
02009                 flag = 1;
02010                 gain_f = 256.0*sens;
02011                 gain_i = (unsigned long)gain_f;
02012 //temporary set all gains. Will remove it later to let software adjust individual gains
02013                 ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAINR),  gain_i);
02014       ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAING),  gain_i);
02015       ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAINB),  gain_i);
02016       ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAINGB), gain_i);
02017         }
02018 //      if(flag)
02019 //              ioctl(devfd, _CCCMD(CCAM_WPARS,  P_GAING), 0xFFFF);
02020       
02021 //      if ((vp=paramValue(gparams, "kga")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_SPEC_KAC_GGA ),     strtol (vp,&cp,10));
02022 //      if ((vp=paramValue(gparams, "kgb")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_SPEC_KAC_GGB ),     strtol (vp,&cp,10));
02023 //      if ((vp=paramValue(gparams, "kgm")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_SPEC_KAC_GGM ),     strtol (vp,&cp,10));
02024 
02025         if ((vp=paramValue(gparams, "csb")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_COLOR_SATURATION_BLUE ), strtol (vp,&cp,10));
02026         if ((vp=paramValue(gparams, "csr")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_COLOR_SATURATION_RED  ), strtol (vp,&cp,10));
02027 
02028         if ((vp=paramValue(gparams, "eol")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_OVERLAP ),     strtol (vp,&cp,10));
02029         if ((vp=paramValue(gparams, "vtrig")))  ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_VIRTTRIG ),    strtol (vp,&cp,10));
02030 
02031         if ((vp=paramValue(gparams, "fclk")))   ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_CLK_FPGA ),    1000000* strtod (vp,&cp));
02032         if ((vp=paramValue(gparams, "sclk")))   ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_CLK_SENSOR ),  1000000* strtod (vp,&cp));
02033         if ((vp=paramValue(gparams, "xtra")))   ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_FPGA_XTRA ),    strtol (vp,&cp,10));
02034 
02035 // only change P_FP100S if fps= and/or fpslm are present
02036    if((vp = paramValue(gparams, "fps"))) {
02037      i = 100 * strtod (vp, &cp);
02038      ioctl(devfd, _CCCMD(CCAM_WPARS, P_FP100S),  i );
02039      if ((vp = paramValue(gparams, "fpslm")))  ioctl(devfd, _CCCMD(CCAM_WPARS, P_FPSLM), strtol (vp,&cp,10));
02040      else if (i>0) ioctl(devfd, _CCCMD(CCAM_WPARS, P_FPSLM), 1); // old behavior - just upper limit, if fps !=0 
02041    } else { // no fps specified - do not change
02042      if ((vp = paramValue(gparams, "fpslm")))  ioctl(devfd, _CCCMD(CCAM_WPARS, P_FPSLM), strtol (vp,&cp,10));
02043      else ioctl(devfd, _CCCMD(CCAM_WPARS, P_FPSLM), -1); // do not change FPS limit mode
02044    }
02045 
02046 
02047     i=(ioctl(devfd, _CCCMD( CCAM_RPARS , P_TRIG), 0) & ~1); // for now - just don't touch bit 1
02048         ioctl(devfd, _CCCMD(CCAM_WPARS , P_TRIG ),   i | (optionPresent(gparams, "opt", 't')?1:0) | (optionPresent(gparams, "opt", 'a')?4:0));
02049         if ((vp=paramValue(gparams, "trig")))   ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_TRIG ),    strtol (vp,&cp,10));
02050         ioctl(devfd, _CCCMD(CCAM_WPARS , P_FLIP ),  (optionPresent(gparams, "opt", 'x')?1:0) | (optionPresent(gparams, "opt", 'y')?2:0));
02051         ioctl(devfd, _CCCMD(CCAM_WPARS , P_COLOR ),
02052         ( optionPresent(gparams, "opt", 'j')?    2:( optionPresent(gparams, "opt", 'c')?    1:0)) |
02053                   (optionPresent(gparams, "opt", 'p')? 0x100:0) |
02054                   (optionPresent(gparams, "opt", 'f')? 0x200:0)
02055                   );
02056 
02057 //      ioctl(devfd, _CCCMD(CCAM_WPARS , P_TEST ),   (optionPresent(gparams, "opt", 'p')?1:0) | (optionPresent(gparams, "opt", 'f')?2:0));
02058         ioctl(devfd, _CCCMD(CCAM_WPARS , P_BGFRAME ),  n_bf?n_bf:0); // for now driver only checks if n_bf==0, later maybe will average
02059 // Now update these parameters (at once) - will also stop data transfer
02060   if (optionPresent(gparams, "opt", 'u') && !optionPresent(gparams, "opt", '!')) ioctl(devfd, _CCCMD(CCAM_WPARS , P_UPDATE ),   3); // "on the fly"
02061   else                                    ioctl(devfd, _CCCMD(CCAM_WPARS , P_UPDATE ),   1); // 1 - at once (2 - later)
02062 
02063  return 0;      // add errors later
02064 }
02065 
02066 int set_fpga_time(int seconds, int useconds) {
02067  int fpgaio_fd;
02068    if ((fpgaio_fd = open("/dev/fpgaio", O_RDWR))>=0) { 
02069          ioctl(fpgaio_fd, _IO(FPGACONF_WRITEREG, 0x44 ), useconds);
02070          ioctl(fpgaio_fd, _IO(FPGACONF_WRITEREG, 0x45 ), seconds);
02071      close (fpgaio_fd);
02072      return 0;
02073    } else return -1;
02074 }
02075 // *********************************** WHITE BALANCE ******************************************
02076 // this function can be used for white balance. It will find percentiles ("cent" means 0x100 here) for 4 colors (both greens separate)
02077 // so that the highest value of 4 will be equal to thrsh (should be less than 255).
02078 // after compensation for non-linear "gamma" (for the values close to 255 it can be linearly approximated) these values xan be used to directly adjust color balance -
02079 // just reverse proportionally to the ratio of this result.
02080 
02081 #define HIST_LEN        256 * 4 * 4
02082 #define GAMMA_LEN       256 * 4 * 2
02083 int calcWhiteBalance(int thrsh,   // threshold (0..255) for the "brightest color"
02084                      int min_pixels, // minimal number of pixels above threshold for the brightest color (threshold will be lowered to satisfy min_pixels)
02085                      float diffGains[3] // last element - current exposure time (in 100 us)
02086                      ){
02087   float colPercentiles[4];
02088 //  int *hists;
02089 //  short *gammas;
02090   int hists[1024];
02091   short gammas[1024];
02092   int retr=10000;
02093   int autoexp_fd=-1;
02094   void *_map;
02095   int sum[4];
02096   int indx[4];
02097   int i,j,k,smax,z;
02098   int percFound=0;
02099   int rez = 0;
02100   
02101 // first - just read the histogram array  
02102   
02103   while ( (((autoexp_fd = open(AUTOEXP_DEV_NAME, O_RDONLY)))<0) && (retr>0)) retr--; // maybe now not needed after this file can be opened for reading multiple times
02104   if (autoexp_fd < 0)  return -1;
02105   z = ioctl(autoexp_fd, _IO(IOC_AUTOEXP_GET, 0x00), &autoexp);
02106   diffGains[2]=autoexp.exp;
02107   if((_map = mmap(NULL, TABLES_LEN, PROT_READ, MAP_FIXED | MAP_SHARED, autoexp_fd, 0)) == MAP_FAILED) {
02108 //  if((_map = mmap(NULL, HIST_SIZE, PROT_READ, MAP_FIXED | MAP_SHARED, autoexp_fd, 0)) == MAP_FAILED) {
02109 //  if((_map = mmap(NULL, HIST_LEN + GAMMA_LEN, PROT_READ, MAP_FIXED | MAP_SHARED, autoexp_fd, 0)) == MAP_FAILED) {
02110       close (autoexp_fd);
02111       return -1;
02112   }
02113   memcpy (hists,_map,HIST_LEN);
02114   memcpy (gammas,_map + HIST_LEN,GAMMA_LEN);
02115 //  memcpy (hists,_map,HIST_SIZE);
02116 //   _map = mmap((void *)0x10000000, GAMMA_SIZE, PROT_READ, MAP_FIXED | MAP_SHARED, autoexp_fd, 0);
02117 //  memcpy (gammas,_map,GAMMA_SIZE);
02118 //      hists = (int *)_map;
02119 //      gammas = (short *)(_map + HIST_LEN);
02120 //  close (autoexp_fd);
02121 //  for (i=0;i<255;i++) printf("<wb_gamma%d>%x_%x_%x_%x</wb_gamma%d>\n",i,gammas[i],gammas[i+256],gammas[i+512],gammas[i+768],i);
02122   
02123 //  for (j=1;j<4;j++) {sum[j]=0;indx[j]=-1;colPercentiles[j]=-1.0;}
02124   for (j=0;j<4;j++) {sum[j]=0;indx[j]=-1;colPercentiles[j]=-1.0;}
02125   for (i=255;i>=thrsh;i--) for (j=0;j<4;j++)   sum[j]+=hists[i+ (j<<8)];
02126   smax = sum[0];
02127   for (j=1;j<4;j++) if (sum[j]>smax) smax=sum[j];
02128 //  printf("<wb_smax1>%d</wb_smax1>\n",smax); //
02129   
02130 //  for (j=0;j<4;j++)  printf("<wb_sum%d>%d</wb_sum%d>\n",j,sum[j],j); //
02131   
02132   if (smax<min_pixels) {//continue by lowering threshold to match the minimal number of pixels
02133     for (i=thrsh-1;(i>0) && (smax<min_pixels); i--) { // continue down, lowering thrsh until min_pixels is met.
02134       for (j=0;j<4;j++)   sum[j]+=hists[i+ (j<<8)];
02135       for (j=0;j<4;j++) if (sum[j]>smax) {smax=sum[j];k=j;thrsh=i;}
02136     }
02137   }
02138 //  printf("<wb_smax2>%d</wb_smax2>\n",smax); //
02139 //  printf("<wb_thrsh>%d</wb_thrsh>\n",thrsh); //
02140   
02141         if(smax < min_pixels)
02142                 return -2; // could not satisfy min_pixels - wrong min_pixels?
02143 // now thrsh is modified if needed  
02144 //       printf("<wbPixels>%d</wbPixels>\n",wbPixels); //
02145 
02146   i=0;
02147   smax=0;
02148   for (j=0;j<4;j++) if (sum[j]>smax) {smax=sum[j];i=j;}
02149 //  printf("<wb_smax3>%d</wb_smax3>\n",smax); //
02150   indx[i]=thrsh; //colPercentiles[i]=thrsh;
02151   percFound |= (1<<i);
02152 //  printf("<wb_thrsh>%d</wb_thrsh>\n",thrsh); //
02153 //  printf("<wb_percFound>%d</wb_percFound>\n",percFound); //
02154   for (i=thrsh-1;(i>0) && (percFound != 0xf); i--) { // continue down, looking when other colors will get the same number of pixels (smax), then linear interpolate fractions.
02155     for (j=0;j<4;j++) if (!(percFound & (1 <<j))) {
02156       sum[j] += hists[i+ (j<<8)];
02157       if (sum[j]>=smax) {
02158         percFound |= (1<<j);
02159 //  printf("<wb_j>%d</wb_j>\n",j); //
02160 //  printf("<wb_percFound>%d</wb_percFound>\n",percFound); //
02161         indx[j]=i;
02162       }
02163     }    
02164   }
02165 //  printf("<wb_percFound>0x%x</wb_percFound>\n",percFound); //
02166   
02167         if(percFound != 0xf)
02168                 return -3; // problem with histogram
02169 // now each color got at least the number of pixels the "brightest" got over thrsh
02170 // make linear interpolation between counts
02171   for (j=0;j<4;j++) {
02172 //   printf("<wb_sum%d>%d</wb_sum%d>\n",j,sum[j],j); //
02173 //   printf("<wb_indx%d>%d</wb_indx%d>\n",j,indx[j],j); //
02174 //   printf("<wb_hist%d_%d>%d</wb_hist%d_%d>\n",j,indx[j],hists[indx[j]+ (j<<8)],j,indx[j]); //
02175     
02176     if (sum[j]==smax) colPercentiles[j]=indx[j];
02177     else colPercentiles[j]= indx[j]+(1.0*(sum[j]-smax))/hists[indx[j]+ (j<<8)];
02178 //    printf("<wb_beforegamma_%d>%f</wb_beforegamma_%d>\n",j,colPercentiles[j],j); //
02179   }
02180 //unapply gamma
02181   k=0; // to make gcc happy
02182   for (j=0;j<4;j++) {
02183     for (i=255;(i>=0) && ((k=((gammas[i+(j<<8)]>>8) & 0xff)) > indx[j]);i--);
02184     colPercentiles[j]=i+ (colPercentiles[j]-k)/ ( ((gammas[i+1+(j<<8)]>>8) & 0xff) -k);
02185 //    printf("<wb_aftergamma_%d>%f</wb_aftergamma_%d>\n",j,colPercentiles[j],j); //
02186   }
02187   diffGains[0]=(colPercentiles[1]+colPercentiles[2])/2.0/colPercentiles[0];
02188   diffGains[1]=(colPercentiles[1]+colPercentiles[2])/2.0/colPercentiles[3];
02189 //  printf("<wb_gainR2G>%f</wb_gainR2G>\n",diffGains[0]); //
02190 //  printf("<wb_gainB2G>%f</wb_gainB2G>\n",diffGains[1]); //
02191 
02192 //ret:
02193 //      munmap(_map, HIST_SIZE + GAMMA_SIZE);
02194 //      close(autoexp_fd);
02195   return rez;  
02196 }
02197 
02198 // ********************* Reading last JPEG from the buffer w/o interrupting the streamers
02199 // it copies all the frame to the buffer, so no buffer owerrun with slow connections
02200 //#define MAP_OPTIONS MAP_FILE|MAP_PRIVATE -> #define MAP_OPTIONS MAP_SHARED
02201 
02202 int sendLastFrame (int cache) {
02203  const char BuffFileName[]="/dev/circbuf";
02204  const char HeadFileName[]="/dev/jpeghead";
02205  const char ioctlFileName[]="/dev/sensorpars"; 
02206 
02207  const char trailer[] = {0xff,0xd9};
02208 
02209   int buff_fd, ioctl_fd;
02210   int sensor_state;
02211 //  int frame_number,i0,a;
02212   int jpeg_wp;
02213   int buff_size;
02214   int i, alen;
02215   unsigned long * ccam_dma_buf;           /* mmapped array */
02216   int jpeg_len,jpeg_start;
02217   int head_fd;
02218   int head_size;
02219   int jpeg_full_size;
02220   char * jpeg_copy;
02221   int l;
02222     ioctl_fd = open(ioctlFileName, O_RDWR);
02223     if (ioctl_fd<0) { // check control OK
02224        return -1;
02225     }
02227     sensor_state = ioctl(ioctl_fd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0);
02228 //    if (sensor_state !=CAMSEQ_RUN) ; // What to do here?
02232 
02234     jpeg_wp= ioctl(ioctl_fd, _CCCMD( CCAM_RPARS , P_JPEG_WP), 0);
02235 //    printf ("Write pointer was 0x%x\n",jpeg_wp);
02236     close (ioctl_fd);
02237 
02240     buff_fd = open(BuffFileName, O_RDWR);
02241     if (buff_fd<0) { // check control OK
02242        return -1;
02243     }
02245     buff_size=lseek(buff_fd,0,2);
02247    ccam_dma_buf = (unsigned long *) mmap(0, buff_size, PROT_READ, MAP_OPTIONS, buff_fd, 0);
02248    if((int)ccam_dma_buf == -1) {
02249 //     printf("Error in mmap %s\r\n",BuffFileName);
02250      close(buff_fd);
02251      return -1;
02252    }
02253    alen=jpeg_wp-9; if (alen<0) alen+= (buff_size>>2);
02254 // let's get the last frame here
02255    jpeg_len=ccam_dma_buf[alen] & 0xffffff; 
02256 //   jpeg_start=(alen & 0xfffffff8)- (((jpeg_len+7) & 0xffffffe0)>>2);
02257    jpeg_start=(alen & 0xfffffff8)- (((jpeg_len + CCAM_MMAP_META + 3) & 0xffffffe0)>>2);
02258    if (jpeg_start<0) jpeg_start+=(buff_size>>2);
02259    head_fd = open(HeadFileName, O_RDWR);
02260    if (head_fd<0) { // check control OK
02261 //      printf ("Error opening %s\n", HeadFileName);
02262       close (buff_fd);              
02263       return -1;
02264    }
02265    head_size=lseek(head_fd,0,2);
02266    jpeg_full_size=jpeg_len+head_size+2;
02267 //   printf ("JPEG header length=%d (0x%x)\n",head_size,head_size);
02268    jpeg_copy=malloc(jpeg_full_size);
02269    lseek(head_fd,0,0);
02270    read (head_fd,jpeg_copy,head_size);
02271    //i=jpeg_len;
02272    l=head_size;
02273    if (((jpeg_start<<2)+jpeg_len) > buff_size) {
02274      memcpy (&jpeg_copy[l],&ccam_dma_buf[jpeg_start],buff_size-(jpeg_start<<2));
02275      l+=buff_size-(jpeg_start<<2);
02276      memcpy (&jpeg_copy[l],&ccam_dma_buf[0],jpeg_len-(buff_size-(jpeg_start<<2)));
02277    } else {
02278      memcpy (&jpeg_copy[l],&ccam_dma_buf[jpeg_start],jpeg_len);
02279    }
02280    memcpy (&jpeg_copy[jpeg_len+head_size],trailer,2);
02281 
02282    USEHTTP10(printf("HTTP/1.0 200 OK\n"));
02283    printf("Content-Length: %d\n",jpeg_full_size);
02284    printf("Content-Type: image/jpeg\n");
02285    if (!cache)printf("Pragma: no-cache\n");
02286    printf("\n");
02287    for (i=0;i<=(jpeg_full_size-SOCKETBUF_SIZE);i+=SOCKETBUF_SIZE) fwrite (&jpeg_copy[i],1,SOCKETBUF_SIZE,stdout);
02288    if (i<jpeg_full_size)fwrite (&jpeg_copy[i],1,(jpeg_full_size-i),stdout);
02289    free(jpeg_copy);
02290    close (buff_fd);              
02291    close (head_fd);              
02292    return 0;
02293 }
02294 
02295 
02296 
02297 /*!********************************************************************************************************************
02298  *! _time=t (ms) will try to set current system time (if it was not set already. _stime - will always set)
02299  *! if any of html, htmlr, htmll or htmlj are present will genmerate html page instead of an image
02300  *! html= not present)- picture as before (or vrml)
02301  *!       0 - nothing
02302  *!       1 - all sensor parameters as javaScript
02303  *!       2 - all sensor parameters as html
02304  *!       3 - beam data as javaScript
02305  *!       4 - beam data as html
02306  *!       5 - state (5 -picture ready) as javaScript
02307  *!       6 - state (5 -picture ready) as html
02308  *!       7 - start image acquisition (option "s" or "t" should be present)
02309  *!       8 - reset waiting for trigger
02310  *!      10 - all sensor parameters as XML
02311  *!      11 - beam data as XML
02312  *!      12 - state (5 -picture ready) as XML
02313  *!      13 - start image acquisition (option "s" or "t" should be present), return XML
02314  *!      14 - reset waiting for trigger, return XML
02315 
02316  *! htmlr=n - Refresh each n seconds
02317  *! htmll=(escape) - command executed onLoad in <body> tag
02318  *! htmlj=(escape) - include *.js javaScript file
02319 
02320  *! vrmld - decimation to make a grid (>=8 for full frame) (default = 16)
02321  *! vrmlb - number of individual blocks in each x/y (default=2)
02322  *! vrmlm - maximal pixel. 1023 - full scale, less - increase contrast, 0 - automatic (default =1023)
02323 
02324  *! vrmli - indentation (default=1)
02325  *! vrmlf - format - 0 - integer, 1 - one digit after "." (default 0)
02326  *! vrmll - number of countours to build (default = 32)
02327  *! vrmlo - options for isolines - e - elevated, f - flat (default=ef)
02328  *! vrmlz - 0..9 output (gzip) compression level (0 - none, 1 - fastest, default - 6, best -9)
02329  *! fpns  - 0..3 fpga background subtraction:
02330  *!               0 - none,
02331  *!               1 (fine) - subtract 8-bit FPN from 10-bit pixel
02332  *!               2 - multiply FPN by 2 before subtracting
02333  *!               3 - multiply FPN by 4 before subtracting (full scale)
02334  *!       note:   negative result is replaced by 0, decrease FPN data before applying for "fat 0"
02335  *! fpnm  -       muliply by inverse sensitivity (sensitivity correction) mode:
02336  *!               0 - no correction
02337  *!               1 - fine (+/- 12.5%)
02338  *!               2 - medium (+/- 25%)
02339  *!               3 - maximal (+/- 50%)
02340  *! pc - pseudo color string. Applies to monochrome images and vrml
02341 
02342  *! any of vrml* specified - vrml instead of a picture/html
02343  *!
02344  *! background measurement/subtraction will (now) work only with 10-bit images
02345  *! gd = "digital gain" 0..5 (software)
02346  *! iq = 0..100 - jpeg quality, "-1" - BMP non-compressed, "-2" - BMP RLE compressed
02347  *! byr =0..3 Overwite Bayer phase shift, =4 - use calculated by driver.
02348  
02349  *! vw - virtual frame width
02350 
02351  *! vh - virtual frame height
02352 
02353  *! wl = 0..1288 - left
02354  *! wt = 0..1032 - top
02355  *! ww = 1..1288 - width
02356  *! wh = 1..1032 - height
02357  *! pfh - photofinish mode strip height (0 - normal mode, not photofinish). In this mode each frame will consist of multiple
02358          pfh-high horizontal (camera should be oriented 90 deg. to make vertical) strips, and no extra lines will be added to the frames
02359          for demosaic
02360          for now: +65536 - timestamp for normal frames, +131072 - timestamps for photo-finish mode
02361  *! ts  - time stamp mode: 0 - none, 1 - in upper-left corner, 2 - added to the right of the image (photo-finish mode)        
02362                   
02363  *! fsd - frame sync delay (in lines) from the beginning of a frame (needed in photofinish mode - 3 lines?)
02364 
02365  *! dh = 1 2 4  - decimation horizontal (both) MT9T001 dh= 1,2,3,4,5,6,7,8
02366  *! dv - decimation vertical MT9T001 dv= 1,2,3,4,5,6,7,8
02367  *! bh - binning horizontal or both (MT9T001 - 1<bh<=dh<=8, has some on-chip problems)
02368  *! bv - binning vertical (MT9T001 - 1<bh<=dh<=8, has some on-chip problems)
02369  *! bit - pixel depth (10/4/8)
02370  *! shl - shift left (FPGA in 8 and 4-bit modes) - obsolete
02371  *! clk - MCLK divisor - 80MHz/(2..129) - obsolete?
02372 
02373  *! fclk - 0-127 - fpga (compressor) clock (MHz)
02374  *! sclk - 0-127 - sensor clock (MHz) - will be limited by sensor driver
02375  *! xtra - number of pixel-cycles needed for compressor between frames - debugging only
02376 
02377  *! gr = 0..63 - analog gain red (or mono)
02378  *! gg = 0..63 - analog gain green (or green-"red" line)
02379  *! gb = 0..63 - analog gain blue
02380  *! ggb = 0..63 - analog gain green ("blue" line - ZR32212 only)
02381  *! bg  = n - calculate background 1-2-4..16 times (does not need option s/t/v)
02382  *! parameters for "instant on" quicktime
02383  *! qfr = n - number of frames to send in a quicktime clip
02384  *! qpad        = % to leave for the frame size to grow (initial size 1-st frame * (100- 1.5*qpad)/100
02385  *! qdur = frame duration in 1/600 of a second
02386  *! parameters for quicktime clips (send after shooting)
02387  *! qsz = n - clip size in KB (w/o headers) (<=0 will use "instant on") - will be obsolete
02388  *! qcmd= (mandatory for videoclip)
02389     1 - start constant compression of all acquired frames
02390     2 - stop constant compression.
02391     3 - acquire the whole buffer and stop
02392     4 - read movie from buffer
02393     6 (and 5?) - stop, then read
02394     7 - acquire buffer, then read
02395 
02396  *! qts = t - playback time/real time
02397 
02398  *! gam=gamma - gamma correction (gamma value 0.13..10)
02399  *! pxl=00  lowest pixel value (on 8-bit scale) before table to be mapped to zero output value
02400  *! pxh=255 hioghest pixel value (on 8-bit scale) before table to be mapped to 255 output value
02401  
02402  *! fps= xx.xx - desired fps (will truncate to 0.01 fps) See fpsm below
02403  *! fpslm = 0..3 - fps limit mode:
02404            0 - do not control fps
02405            1 - limit fps (not higher than)
02406            2 - limit fps - not lower than (not used)
02407            3 - maintain fps (both limits at once)
02408  *! hist=n - read frame from "history" applies only to rereading from memory after acquisition of a clip
02409         n<=0 - from the end of clip (0 - last), n>0 - from the start (1 - first)
02410 
02411  *! e = 0..60000 - exposure (1 msec step)
02412  *! csb= 0..710 - color saturation blue (%)
02413  *! csr= 0..562 - color saturation red (%)
02414  
02415  
02416  hl - histogram top  (all histogram parameters will be made even by truncating, all written derectly to FPGA - no shadows yet)
02417  ht - histogram left
02418  hw - histogram width
02419  hh - histogram height 
02420         if ((vp=paramValue(gparams, "csb")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_COLOR_SATURATION_BLUE ), strtol (vp,&cp,10));
02421         if ((vp=paramValue(gparams, "csr")))            ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_COLOR_SATURATION_RED  ), strtol (vp,&cp,10));
02422 
02423 
02424  *! opt = string of 1-character options:
02425  *!   h - use hardware compression
02426  *!   c - color mode
02427  *!   j - (overwrites color mode) - jp4/google mode
02428  *!   x - flip x
02429  *!   y - flip y
02430  *!   p - test pattern (ramp)
02431  *!   f - test pattern (ramp) fpga
02432  *!   b - buffer file
02433  *!   m - restart exposure after sending
02434  *!   if none of "st" is present - "reload mode" (all but iq and gd ignored)
02435  *!   s - software trigger
02436  *!   t - external trigger
02437  *!   v - video mode - will be obsolete soon (for now will only tell it is not "reload")
02438  *!   g - use background image  - will be obsolete
02439  *!   q - sent quicktime movie
02440  *!   u - updates (some) parameters "on the fly", returns 1x1 pix dummy image
02441  *!   * - unlock "in use"
02442  *!   +,-,!,@ - will explain later
02443  *!   ! - if "u!" do everything as real image, just send xml
02444  *!   w - wait for stop done (now only with qcmd=2)
02445  *!=============================================================================================================================*/
02446 
02447   void debug_write (char * filename, int linenum, const char * dbgstr ) {
02448     FILE *dbgfile;
02449     if ((dbgfile=fopen("/var/log/ccam.log", "a"))) {
02450       fprintf(dbgfile,"%s:%d:%s\n",filename,linenum,dbgstr);
02451       fclose (dbgfile);
02452     }
02453   }
02454 
02455 
02456 int main (int argc, char *argv[]) {
02457 //struct key_value gparams[QRY_MAXPARAMS+1];
02458   time_t new_time;
02459   double dtime=0.0;     // (read in ms)
02460   int devfd;
02461 //  FILE * logfile;
02462 //  FILE * console;
02463 //-  int mcpfd=-1;
02464   int lock_fd=-1;
02465   int i;
02466 //  int lines;  // ZR32112 datasheet "LINES"
02467   char * cp;
02468   char * vp;
02469 /* these are from cgitest.cgi */
02470   const char *method;
02471   const char *query;
02472   const char *uri;
02473   char  copyQuery [4096];
02474 
02475 prof_start();
02476 prof_next("point...1");
02477 prof_next("point...2");
02478 
02479 
02480 const char qtSourceFileName[]= "/etc/qt_source";
02481 const char lockFileName[]=   "/dev/ccam_lock";
02482 const char unlockFileName[]= "/dev/ccam_unlock";
02483 const char inUseFileName[]=  "/etc/inuse.jpeg";
02484 const char emptyFileName[]=  "/usr/html/pics/1pix.jpeg";
02485 
02486 const char headerFileName[]= "/var/qt_header";
02487 const char ImgFileName[]="/dev/ccam_img";
02488 const char FPNFileName[]="/dev/ccam_fpn";
02489 const char jpegFileName[]="/dev/ccam_dma.raw";
02490 // const char gammaFileName[]="/dev/fpga_tables";  // r/w fpga tables, 32 bits/location
02491 //#define     GAMMA_START  0x400
02492 // const char rawFileName[]="/dev/ccam_img";   // change later
02493  const char bufFileName[]="/var/tf.jpeg";
02494 //- const char MCPFileName[]="/dev/ccammcp";    // MCP control
02495 // const char correctedImageFileName[]="/var/calibration/image.raw";// - corrected image
02496  const char backgroundFileName[]="/var/calibration/black.raw";
02497 // const char wtfn[]="/var/calibration/white.raw";
02498  const char calibrationFileName[]="/var/calibration/calib.dat";
02499 
02500  int  fat_zero=5;
02501 
02502 
02503   int html_par=-1;
02504   int htmlr_par=0;
02505   char * htmll_par=NULL;
02506   char * htmlj_par=NULL;
02507 
02508   int vrml_par=0;
02509   int vrmld_par=16;
02510   int vrmlb_par=2;
02511   int vrmlm_par=1023;
02512 
02513   int vrmli_par=1;
02514   int vrmlf_par=0;
02515   int vrmll_par=32;
02516   int vrmlo_par=3;
02517   int vrmlz_par=6;
02518 
02519   char * pc_par=NULL;
02520 // * vrmli - indentation (default=1)
02521 // * vrmlf - format - 0 - integer, 1 - one digit after "." (default 0)
02522 // * vrmll - number of countours to build (default = 32)
02523 // * vrmlo - options for isolines - e - elevated, f - flat (default=ef)
02524 
02525 // * pc - pseudo color string. Applies to monochrome images and vrml
02526 
02527 
02528 
02529 
02530   int iq_par =50;
02531   int gd_par =0;
02532   int n_bf=0;
02533   int pp,j;//,jj;
02534   int   save_p_bits, save_p_fpns,save_p_fpnm;
02535 
02536  int qfr_par=100;
02537   int qpad_par=10;
02538   int qdur_par=50; //600/50 = 12 fps
02539 //  int qsz_par=1000; //1MB
02540   int qcmd_par=0; //none
02541   int qts_par=1;
02542   int hist_par=1; // 1-st
02543   int seconds,useconds;
02544   char dbgstr[1024];
02545   int comeOut=0;
02546 //  float wbPercentiles[4];
02547   float wbDiffGains[3];  
02548   float wbPercPixels=1.0;
02549   int   wbthrsh = 250;
02550   int   wbPixels;
02551   int   wb_width;
02552   int   wb_height;
02553 
02554 //  double gamma_par=0.0; //for now - 0.0 - don't update table, else - build/update one
02555 //  double gamma_v;
02556 //  int    gamma_table[257];
02557 
02558 //  int imageSent=0;
02559 // int j; // j - debug
02560 
02561   int  api_fd = -1;
02562   char api_fl[] = "/etc/api";
02563   char api[1];
02564  
02565 openlog(SLOG, LOG_CONS, LOG_USER);
02566 
02567         method = getenv("REQUEST_METHOD");
02568         query = getenv("QUERY_STRING");
02569         uri = getenv("REQUEST_URI");
02570         i= (query) ? strlen (query):0;
02571         D5(fprintf(stderr,"query length=%d\n", i));
02572 
02573         if(i > (sizeof(copyQuery) - 1))
02574                 i = sizeof(copyQuery) - 1;
02575         if(i > 0)
02576                 strncpy(copyQuery, query, i);
02577         copyQuery[i] = 0;
02578         unescape(copyQuery, sizeof(copyQuery));
02579 
02580         if(method == NULL) {
02581                 /* Not a CGI! */
02582                 printf("This program should be run as a CGI from the web server!\n");
02583                 exit(1);
02584         }
02585   
02586         parseQuery(gparams, copyQuery);
02587   
02588         /*
02589          * update time, if needed
02590          */
02591         time(&new_time);
02592         if(((long)new_time) < 100000000)
02593                 new_time = 0;   // time was never set, something like 1974
02594         dtime = 0.0;
02595         if((vp = paramValue(gparams, "_stime")))
02596                 dtime = strtod(vp, NULL);
02597         if((vp = paramValue(gparams, "_time")) && (new_time == 0))
02598                 dtime = strtod(vp, NULL);
02599         if(dtime > 0) {
02600                 new_time = (time_t)(dtime / 1000);
02601                 seconds = (int)(dtime / 1000);
02602                 useconds = 1000 * (dtime - 1000 * seconds);
02603                 set_fpga_time(seconds, useconds);
02604 //              j=stime(&new_time); // Will cause timeout during first transfer. set time AFTER the transfer is over
02605         }
02606   
02607         D5(fprintf(stderr,"1\r\n"));
02608 //      return 1 pixel image if there is no "opt" or "html" parameters - i.e. to search engines
02609         if((!paramValue(gparams, "opt")) && (!paramValue(gparams, "html")) && (!paramValue(gparams, "hist")) & (!paramValue(gparams, "wbstat"))) {
02610                 if(dtime > 0)
02611                         stime(&new_time);
02612                 if(optionPresent(gparams, "opt", '+') || optionPresent(gparams, "opt", '-')) { // send XML instead of "camera in use"
02613                         printf("Content-Type: text/xml\n");
02614                         printf("Pragma: no-cache\n\n"); // 2 new lines!
02615                         printf("<?xml version=\"1.0\" ?>\n");
02616 //                      printf("<camera>\n<SENSOR_STATE>-1</SENSOR_STATE></camera>\n"); // empty xml
02617                 } else {
02618                         send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02619                 }
02620                 return 0;  
02621         }
02622 
02623         if(dtime > 0)
02624                 stime(&new_time);
02625         D5(fprintf(stderr,"2\r\n"));
02626         api_fd = open(api_fl, O_RDONLY);
02627 //      no /etc/api - use ccam.cgi
02628         if(api_fd != -1) {
02629                 read(api_fd, api, 1);
02630                 close(api_fd);
02631                 if(api[0] != '0') { 
02632                         if((paramValue(gparams, "html")) || optionPresent(gparams, "opt", '+') || optionPresent(gparams, "opt", '-')) { // send XML instead of "camera in use"
02633                                 printf("Content-Type: text/xml\n");
02634                                 printf("Pragma: no-cache\n\n"); // 2 new lines!
02635                                 printf("<?xml version=\"1.0\" ?>\n");
02636 //                              printf("<camera>\n<SENSOR_STATE>-1</SENSOR_STATE></camera>\n"); // empty xml
02637                         } else {
02638                                 send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02639                         }
02640                         return 0;  
02641                 }
02642         }
02643         D5(fprintf(stderr,"2.1\r\n"));
02644         if((vp = paramValue(gparams, "bg"))) {
02645                 n_bf = strtol(vp, &cp, 10);
02646                 if(n_bf > 0) {
02647                         pp = 0;
02648                         if(n_bf > 1) pp = 1;
02649                         if(n_bf > 2) pp = 2;
02650                         if(n_bf > 4) pp = 3;
02651                         if(n_bf > 8) pp = 4;
02652                         n_bf = 1 << pp;
02653                 }
02654         }
02655         D5(fprintf(stderr,"2.2\r\n"));
02656         if(optionPresent(gparams, "opt", '*')) {
02657                 i = open(unlockFileName, O_RDONLY);
02658                 close(i);
02659         }
02660         D5(fprintf(stderr,"2.3\r\n"));
02661 
02662 // if there is a lock file:
02663 // if html mode - return xml with an error
02664 // else - if "+" - 1x1
02665 // else  - "in use"  
02666   if ((lock_fd=open(lockFileName, O_RDONLY))<0) {
02667 //    close(lock_fd);
02668     if(paramValue(gparams, "wbstat") || paramValue(gparams, "html") || (optionPresent(gparams, "opt", 'u') && optionPresent(gparams, "opt", '+'))) { // send XML instead of "camera in use"
02669       printf("Content-Type: text/xml\n");
02670       printf("Pragma: no-cache\n\n"); // 2 new lines!
02671       printf("<?xml version=\"1.0\" ?>\n");
02672       printf("<camera>\n<SENSOR_STATE>-1</SENSOR_STATE></camera>\n");
02673     } else {
02674       if(optionPresent(gparams, "opt", '+')) send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02675       else send_jpegfile_image (inUseFileName);
02676     }
02677     return -1;
02678   }
02679   D5(fprintf(stderr,"2.4\r\n"));
02680 
02681 //reset sensor (if it stays with count==2) 
02682 // newt open sensor file will rescan for the sensors  and reset it
02683   if (paramValue(gparams, "resetsensor")) {
02684       if ((devfd = open("/dev/fpgaio", O_RDWR))<0)  {
02685         if(paramValue(gparams, "html") || (optionPresent(gparams, "opt", 'u') && optionPresent(gparams, "opt", '+'))) { // send XML instead of "camera in use"
02686           printf("Content-Type: text/xml\n");
02687           printf("Pragma: no-cache\n\n"); // 2 new lines!
02688           printf("<?xml version=\"1.0\" ?>\n");
02689           printf("<camera>\n<SENSOR_STATE>-4</SENSOR_STATE></camera>\n");
02690         } else {
02691           if(optionPresent(gparams, "opt", '+')) send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02692           else send_jpegfile_image (inUseFileName);
02693         }
02694         return -1;
02695       }
02696       ioctl(devfd, _IO(FPGACONF_WRITEREG, 0x21 ),0); // 333
02697       ioctl(devfd, _IO(FPGACONF_WRITEREG, 0x22 ),0); // 313/323
02698       close (devfd);
02699   }
02700   D5(fprintf(stderr,"2.5\r\n"));
02701   
02702   if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02703   
02704   if(optionPresent(gparams, "opt", 'm')) n_bf=0;        // no background measurements in 'm' mode
02705 
02706  // if ((vp=paramValue(gparams, "gam")))        gamma_par = strtod (vp,&cp);
02707 
02708   if ((vp=paramValue(gparams, "vrmld")))        {vrml_par = 1; vrmld_par = strtol (vp,&cp,10);}
02709   if ((vp=paramValue(gparams, "vrmlb")))        {vrml_par = 1; vrmlb_par = strtol (vp,&cp,10);}
02710   if ((vp=paramValue(gparams, "vrmlm")))        {vrml_par = 1; vrmlm_par = strtol (vp,&cp,10);}
02711 
02712   if ((vp=paramValue(gparams, "vrmli")))        {vrml_par = 1; vrmli_par = strtol (vp,&cp,10);}
02713   if ((vp=paramValue(gparams, "vrmlf")))        {vrml_par = 1; vrmlf_par = strtol (vp,&cp,10);}
02714   if ((vp=paramValue(gparams, "vrmll")))        {vrml_par = 1; vrmll_par = strtol (vp,&cp,10);}
02715 
02716   if ((cp=paramValue(gparams, "vrmlo")))  vrmlo_par=(strchr(cp,'f')?1:0) | (strchr(cp,'e')?2:0);
02717   if ((vp=paramValue(gparams, "vrmlz")))        {vrml_par = 1;
02718      vrmlz_par = strtol (vp,&cp,10);
02719       if (vrmlz_par<0)  vrmlz_par=0;
02720       if (vrmlz_par>90) vrmlz_par=9;
02721      }
02722 
02723  D5(fprintf(stderr,"2.6\r\n"));
02724 
02725   pc_par=paramValue(gparams, "pc");
02726 
02727 // read non-sensor parameters that are needed in any case. Only "local" arguments are validated.
02728   if ((vp=paramValue(gparams, "htmlr")))        {html_par = 0; htmlr_par = strtol (vp,&cp,10);}
02729   htmll_par=paramValue(gparams, "htmll");
02730   htmlj_par=paramValue(gparams, "htmlj");
02731   if (htmll_par || htmlj_par) html_par = 0;
02732 // should be the last of html*_par
02733   if ((vp=paramValue(gparams, "html"))) html_par = strtol (vp,&cp,10); // html instead of picture, different modes
02734 
02735   if ((vp=paramValue(gparams, "iq")))   iq_par = strtol (vp,&cp,10); // image quality
02736   if (iq_par > 100) iq_par=100;
02737 //  if (iq_par < -2)   iq_par=-2;
02738   if ((vp=paramValue(gparams, "gd")))   gd_par = strtol (vp,&cp,10); // digital gain
02739   if (gd_par > 5) gd_par=5;
02740   if (gd_par < 0) gd_par=0;
02741   
02742  D5(fprintf(stderr,"2.7\r\n"));
02743   
02744   if (paramValue(gparams, "wbstat")) { // for now - just return raw percentiles as xml file
02745       
02746     if ((vp=paramValue(gparams, "wbth")))    wbthrsh=  strtol (vp,&cp,10);
02747     if ((vp=paramValue(gparams, "wbpc")))    wbPercPixels=  strtod (vp,&cp);
02748      devfd = open(ImgFileName, O_RDWR);
02749      wb_width = ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_WIDTH ), 0);
02750      wb_height= ioctl(devfd, _CCCMD( CCAM_RPARS , P_ACTUAL_HEIGHT ), 0);
02751      close (devfd);
02752      wbPixels= wb_width*wb_height*(wbPercPixels/100.0);
02753        printf("Content-Type: text/xml\n");
02754        printf("Pragma: no-cache\n\n"); // 2 new lines!
02755        printf("<?xml version=\"1.0\" ?>\n");
02756        printf("<whitebalance>\n");
02757 //       printf("<wbthrsh>%d</wbthrsh>\n",wbthrsh); //
02758 //       printf("<wbPixels>%d</wbPixels>\n",wbPixels); //
02759        i=calcWhiteBalance(wbthrsh,   // threshold (0..255) for the "brightest color"
02760                           wbPixels, // minimal number of pixels above threshold for the brightest color (threshold will be lowered to satisfy min_pixels)
02761                           wbDiffGains);
02762        
02763        
02764        printf("<WB_RESPONCE>%d</WB_RESPONCE>\n",i); //
02765        printf("<WB_DIFF_GAIN_R2G>%f</WB_DIFF_GAIN_R2G>\n",wbDiffGains[0]); //
02766        printf("<WB_DIFF_GAIN_B2G>%f</WB_DIFF_GAIN_B2G>\n",wbDiffGains[1]); //
02767        printf("</whitebalance>\n"); //
02768        close(lock_fd);
02769        if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02770        return 0;
02771   }
02772  D5(fprintf(stderr,"2.8\r\n"));
02773 // New mode - don't do anything if option "-" and continuous acquisition mode was on - return XML with SENSOR_STATE = -2
02774   devfd = open(ImgFileName, O_RDWR);
02775   if((optionPresent(gparams, "opt", '-')) && (ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0)>7)){  // new: if "-" - don't set parameters if streamer is running 
02776      if(paramValue(gparams, "html") || (optionPresent(gparams, "opt", 'u') && optionPresent(gparams, "opt", '+'))) { // send XML instead of "camera in use"
02777        printf("Content-Type: text/xml\n");
02778        printf("Pragma: no-cache\n\n"); // 2 new lines!
02779        printf("<?xml version=\"1.0\" ?>\n");
02780        printf("<camera>\n<SENSOR_STATE>-2</SENSOR_STATE></camera>\n"); // return -2 - did not do anything as streamer was running
02781      D5(fprintf(stderr,"2.81\r\n"));
02782      } else {
02783      
02784 //       if(optionPresent(gparams, "opt", '+')) send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02785 //       else 
02786        sendLastFrame (optionPresent(gparams, "opt", '.'));  // if image and no "+" - return last frame;
02787      D5(fprintf(stderr,"2.82\r\n"));
02788 
02789      }
02790      close (devfd);
02791      close(lock_fd);
02792      if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02793      D5(fprintf(stderr,"2.83\r\n"));
02794 
02795      return 0;
02796   }
02797   close (devfd);
02798 // -- end of new mode  
02799   D5(fprintf(stderr,"2.9\r\n"));
02800   
02801 // Just update parameters (will not change clock or window size and will not stop dma/sensor)?
02802   if (optionPresent(gparams, "opt", 'u') && !optionPresent(gparams, "opt", '!')) { 
02803     devfd = open(ImgFileName, O_RDWR);
02804     if (devfd<0) { // check control OK
02805       printf(error304);
02806       close(lock_fd);
02807       if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02808       return -1;
02809     }
02810     setCamPars(devfd,0,cp,vp); // set acquisition parameters
02811      if(optionPresent(gparams, "opt", '+') || paramValue(gparams, "html")) { // send XML instead of "camera in use"
02812       printf("Content-Type: text/xml\n");
02813       printf("Pragma: no-cache\n\n"); // 2 new lines!
02814       printf("<?xml version=\"1.0\" ?>\n");
02815       printf("<camera>\n<SENSOR_STATE>%d</SENSOR_STATE></camera>\n",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0));
02816     } else send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02817     close (devfd);
02818     close(lock_fd);
02819     if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02820     return 0;
02821   }
02822   D5(fprintf(stderr,"2.91\r\n"));
02823   
02824 // sent quicktime
02825 //int send_quicktime (const char * ImgFileName, const char * qtSourceFileName, const char * headerFileName,  int nrep, int safe)
02826   if (optionPresent(gparams, "opt", 'q'))
02827   {
02828     if ((vp=paramValue(gparams, "qfr")))          {qfr_par = strtol (vp,&cp,10); qcmd_par=-1;} // number of frames to send
02829     if ((vp=paramValue(gparams, "qpad")))  {qpad_par = strtol (vp,&cp,10);qcmd_par=-1;} // % of frame size to reserve for possible increase
02830     if ((vp=paramValue(gparams, "qdur")))  {qdur_par = strtol (vp,&cp,10);qcmd_par=-1;} // frame duration in 1/600 of a second
02831 
02832 //    if ((vp=paramValue(gparams, "qsz")))  qsz_par = strtol (vp,&cp,10); // clip size in KB (w/o headers), if <=0 "instant on" format
02833     if ((vp=paramValue(gparams, "qcmd")))  qcmd_par = strtol (vp,&cp,10); // clip acquisition command
02834     if ((vp=paramValue(gparams, "qts")))  qts_par = strtol (vp,&cp,10); // time scale playback time/real time
02835 
02836     devfd = open(ImgFileName, O_RDWR);
02837     if (devfd<0) { // check control OK
02838       printf(error304);
02839       close(lock_fd);
02840       if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02841       return -1;
02842     }
02843    D5(fprintf(stderr,"2.92\r\n"));
02844 
02845 // skip acquisition parameters if it is already running (or it will reset running mode)
02846    if (((i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0))!=CAMSEQ_RUN) &&
02847        ( i                                                             !=CAMSEQ_SINGLE) &&
02848        ((qcmd_par & 3) || (qcmd_par<0))) { //not just reread
02849 //       ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // stop sensor - program sensor will do that anyway
02850        ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_DONTCARE),  0);
02851        ioctl(devfd, _CCCMD(CCAM_WPARS ,  P_DONTCARE),  1); // to force programming of parameters
02852        setCamPars(devfd,0,cp,vp); // set acquisition parameters
02853 // still gamma table is not updated. Move the code to setCamPars()? - done
02854 //       ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 1);
02855        ioctl (devfd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_RESET); // reset pointers and DMA for new clip
02856    }
02857    D5(fprintf(stderr,"2.93\r\n"));
02858 
02859     close (devfd);
02860 //    if (qcmd_par > 0) send_quicktime_clip (jpegFileName, qtSourceFileName, headerFileName, qsz_par, qts_par);
02861     if (qcmd_par > 0) {
02862        if (send_quicktime_clip (jpegFileName, qtSourceFileName, headerFileName, qcmd_par, qts_par)<=0) {
02863 // again hack to return xml instead of 1x1 empty image
02864 // make stop stream actually wait it stopeed (first state goes to 9, then - 1)
02865          devfd = open(ImgFileName, O_RDWR);
02866          i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0);
02867          if (optionPresent(gparams, "opt", 'w') && (qcmd_par==2)) 
02868              while ((i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0))>7) ;
02869          close (devfd);
02870 
02871          if (optionPresent(gparams, "opt", '!') || optionPresent(gparams, "opt", '+') || optionPresent(gparams, "opt", '-')) { // send XML instead of "camera in use"
02872            printf("Content-Type: text/xml\n");
02873            printf("Pragma: no-cache\n\n"); // 2 new lines!
02874            printf("<?xml version=\"1.0\" ?>\n");
02875            printf("<camera>\n<SENSOR_STATE>%d</SENSOR_STATE></camera>\n",i);
02876 //      printf("<camera>\n<SENSOR_STATE>-1</SENSOR_STATE></camera>\n"); // empty xml
02877          } else {
02878            send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02879          }
02880 
02881 //         send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image (if not movie)`
02882     }
02883             close(lock_fd);
02884             if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02885             return 0;
02886     }
02887     else if (qcmd_par < 0) send_quicktime (jpegFileName, qtSourceFileName, headerFileName, qfr_par, qpad_par, qdur_par);
02888     // if 0 - do nothing
02889     close(lock_fd);
02890     if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02891     D5(fprintf(stderr,"2.94\r\n"));
02892 
02893     return 0;
02894   }
02895 
02896 // Is it just re-reading from memory?
02897   if((!optionPresent(gparams, "opt", 's')) &&
02898      (!optionPresent(gparams, "opt", 't')) &&
02899      (!optionPresent(gparams, "opt", 'v')) &&   // only place to preserve "v"
02900      (html_par!= HTML_RESET)  &&
02901      (html_par!= XML_RESET) &&
02902      (n_bf<1)               // may be no real image acquisition - just measure bg frame
02903       ) {
02904 // will try to subtract background image, but will never do it (impossible or already calculated)
02905 
02906 // will read the last page read before (or updated when state was returned CAMSEQ_DONE
02907 // is it hardware compression mode?
02908       D5(fprintf(stderr,"3\r\n"));
02909 
02910       if ((optionPresent(gparams, "opt", 'h')) || paramValue(gparams, "hist")) { // will ignore or VRML-related stuff
02911 // need to set compression quality and compress again
02912         devfd = open(jpegFileName, O_RDWR);
02913         if (devfd<0) { // check control OK
02914           printf(error304);
02915           close(lock_fd);
02916           if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02917           return -1;
02918         }
02919 // here state should be never>7 (running), last chance for the "update" or "stop" commands was above
02920       D5(fprintf(stderr,"4\r\n"));
02921        if (((i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0))==CAMSEQ_RUN) ||
02922             ( i                                                             ==CAMSEQ_SINGLE) ||
02923             ( i                                                             ==CAMSEQ_STOP)) {
02924            close(devfd);
02925            send_jpegfile_image (inUseFileName);
02926            close(lock_fd);
02927            if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
02928            return -1;
02929        }      
02930       D5(fprintf(stderr,"5\r\n"));
02931 
02932 // acquire new image only if jpeg quality is specified
02933         if ( (vp=paramValue(gparams, "iq")) )   {
02934           ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG_QUALITY ), strtol (vp,&cp,10));
02935           ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_CATCHUP); // will point to the latest got or being acquired (if none got ever)
02936           ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
02937           ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_GET); // start compression now.
02938           while (lseek(devfd,0,2)==0);
02939           D5(fprintf(stderr,"6\r\n"));
02940         }
02941       D5(fprintf(stderr,"7\r\n"));
02942 
02943 // skip hist_par last images (if specified), else leave read pointer where it was (an the clip start?)
02944 //        int logfile=fopen("/var/tmp/ccam_debug_out", "a");
02945 //        fprintf(logfile,"test /var/tmp/ccam_debug_out, hist_par=%d\n",hist_par);
02946         if ((vp=paramValue(gparams, "hist"))) {
02947           hist_par = strtol (vp,&cp,10);
02948 //        fprintf(logfile,"test- 1 hist_par=%d\n",hist_par);
02949 //           ioctl(devfd, _CCCMD(CCAM_WPARS ,  60),   hist_par); //*****???????????????
02950           ioctl (devfd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_SAVE_RP); // save read pointer
02951           if (hist_par<=0) {
02952             i=0;
02953 //        fprintf(logfile,"lseek(devfd,0,2)=%d\n",lseek(devfd,0,2));
02954             while ((i<CCAM_MAX_NUM_FRAMES) && (lseek(devfd,0,2)>0) ) {
02955               i++;
02956               ioctl (devfd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
02957 //        fprintf(logfile,"test- 3 i=%d\n",i);
02958             }
02959             i+=hist_par;
02960           } else i=hist_par;
02961 //        fprintf(logfile,"test- 4 i=%d\n",i);
02962           if (i>0) { // else just read pointer without frame
02963             ioctl (devfd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_RESTORE_RP); // restore read pointer
02964             while ((i--)>1) {
02965                ioctl (devfd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
02966 //               fprintf(logfile,"test- 5 i=%d\n",i);
02967             }   
02968           }
02969         }
02970 //        fclose (logfile);
02971         i=lseek(devfd,0,2);
02972         close(devfd);
02973       D5(fprintf(stderr,"8\r\n"));
02974 
02975         if (i==0) { // no image available
02976           send_jpegfile_image (emptyFileName);  // return just 1x1 pix jpeg image
02977           i=-1;
02978         } else {
02979           D5(fprintf(stderr,"9\r\n"));
02980           i=send_hardware_image (jpegFileName, optionPresent(gparams, "opt", '.')); //will not see changes in Quality settings
02981         }
02982         if (paramValue(gparams, "hist")) {
02983           devfd = open(jpegFileName, O_RDWR);
02984           ioctl (devfd,_IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_RESTORE_RP); // restore read pointer
02985           close(devfd);
02986         }
02987         D5(fprintf(stderr,"10\r\n"));
02988 
02989       } else {
02990         i=processImage(gparams,ImgFileName,
02991                      bufFileName,pc_par,iq_par,gd_par,
02992                      html_par,htmlr_par,htmll_par,htmlj_par,
02993            vrml_par,vrmlm_par,vrmld_par,vrmlb_par,vrmli_par,vrmlf_par,vrmll_par,vrmlo_par,vrmlz_par);
02994       }
02995       D5(fprintf(stderr,"11\r\n"));
02996 
02997       if (dtime>0) stime(&new_time);
02998       close(lock_fd);
02999       if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03000       return i;
03001   }
03002 
03003 // Here comes if image capture is required
03004 // delete processed file (if any)
03005 //   remove(correctedImageFileName);
03006 // Next parameters have to be transferred to driver
03007 // TODO: synchronize different requests to the same driver later
03008 
03009 // before changing parameters see if the picture is waiting in memory
03010 
03011 //    devfd = open(ImgFileName, O_RDWR);
03012 //-         lseek(mcpfd, 1<<1,0);       // address=1 (16bit) - start sequencer
03013   D5(fprintf(stderr,"12\r\n"));
03014 
03015  if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03016 
03017     devfd = open(jpegFileName, O_RDWR);
03018 
03019 // if picture is ready - just read it ignoring that parameters (and reset state)
03020 // if software trigger - do it old way
03021 // if picture nor ready (or not started) and external trigger mode  - restart and return "304"
03022 
03023     if (devfd<0) { // check control OK
03024       printf(error304);
03025       close(lock_fd);
03026       if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03027       return -1;
03028     }
03029 // DD(ioctl(devfd, _CCCMD(CCAM_WPARS ,  62 ),     1)); // +++++just test - to be reported by driver
03030     D5(fprintf(stderr,"13\r\n"));
03031 
03032 // is it just reset that is needed?
03033     if ((html_par== HTML_RESET) || (html_par== XML_RESET)) {
03034       ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // reset state
03035       close(devfd);
03036       i=processImage(gparams,ImgFileName,
03037                      bufFileName,pc_par,iq_par,gd_par,
03038                      html_par,htmlr_par,htmll_par,htmlj_par,
03039                      vrml_par,vrmlm_par,vrmld_par,vrmlb_par,vrmli_par,vrmlf_par,vrmll_par,vrmlo_par,vrmlz_par);
03040       if (dtime>0) stime(&new_time);
03041       close(lock_fd);
03042       if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03043       return i;
03044    }
03045    D5(fprintf(stderr,"14\r\n"));
03046 
03047 // is there picture in memory waiting and mode is "external" and not HTML_ACQUIRE ?
03048     if ((optionPresent(gparams, "opt", 't')) &&
03049         (html_par != HTML_ACQUIRE) &&
03050         (html_par != XML_ACQUIRE) &&
03051         (ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0)==CAMSEQ_DONE)) {
03052 
03053 // DD(ioctl(devfd, _CCCMD(CCAM_WPARS ,  62 ),     2)); // +++++just test - to be reported by driver
03054       ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // **** reset "done"
03055       close(devfd);
03056       if (optionPresent(gparams, "opt", 'h'))
03057 { // will ignore or VRML-related stuff
03058 // for now - start compression and wait done
03059     D5(fprintf(stderr,"15\r\n"));
03060 
03061     if ((vp=paramValue(gparams, "iq"))) ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG_QUALITY ), strtol (vp,&cp,10));
03062         devfd = open(jpegFileName, O_RDWR);
03063        ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_CATCHUP);    // will point to the latest got or being acquired (if none got ever)
03064        ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
03065 
03066         ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_GET); // start compression now.
03067 // wait for done here... (later will overlap)
03068 // wait for done here... (later will overlap)
03069         while (lseek(devfd,0,2)==0);
03070 
03071 // will return 0 until xfer is over
03072         close(devfd);
03073         D5(fprintf(stderr,"16\r\n"));
03074         i=send_hardware_image (jpegFileName, optionPresent(gparams, "opt", '.'));
03075       } else {
03076         D5(fprintf(stderr,"17\r\n"));
03077 
03078         i=processImage(gparams,ImgFileName,
03079                      bufFileName,pc_par,iq_par,gd_par,
03080                      html_par,htmlr_par,htmll_par,htmlj_par,
03081                                      vrml_par,vrmlm_par,vrmld_par,vrmlb_par,vrmli_par,vrmlf_par,vrmll_par,vrmlo_par,vrmlz_par);
03082       }
03083       if (dtime>0) stime(&new_time);
03084       close(lock_fd);
03085       if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03086       return i;
03087     }
03088 // DD(ioctl(devfd, _CCCMD(CCAM_WPARS ,  62 ),     3)); // +++++just test - to be reported by driver
03089     D5(fprintf(stderr,"18\r\n"));
03090 
03091 // Processing immediate restart mode...
03092     if (optionPresent(gparams, "opt", 'm') && ! optionPresent(gparams, "opt", 'h')) {
03093 // does acquisition need to be started?
03094       if (((i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0))==CAMSEQ_OFF) || (i==CAMSEQ_READY)) {
03095 // no, need to program all acquisition parameters
03096         setCamPars(devfd,n_bf,cp,vp);
03097 //      and start acquisition
03098 //-// open MCP "file"
03099 //-        mcpfd = open(MCPFileName, O_RDWR);
03100 //-// arm MCP sequencer (if any)
03101 //-        if (mcpfd>=0) {
03102 //-         lseek(mcpfd, 1<<1,0);       // address=1 (16bit) - start sequencer
03103 //-         i=0;
03104 //-         write(mcpfd,&i,1<<1);
03105 //-        }
03106 
03107 // Just start it
03108         ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 1);
03109 //-        if (mcpfd>=0) {close(mcpfd); mcpfd=-1;}
03110         i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0);
03111       } // if was not started
03112 // now wait ready (if ready will update read page)
03113       D5(fprintf(stderr,"19\r\n"));
03114 
03115       while ((i != CAMSEQ_DONE) &&
03116              (i != CAMSEQ_READY) && // these 2 lines - if somebody did reset the acquisition
03117              (i != CAMSEQ_OFF)) i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0); // just wait - forever?
03118 // image ready, page updated - restart acquisition but do not check state untill image is read out
03119         ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // reset state
03120 
03121         setCamPars(devfd,n_bf,cp,vp); // will toggle acquisition page
03122 //-        mcpfd = open(MCPFileName, O_RDWR);
03123 
03124 //-        if (mcpfd>=0) {
03125 //-         lseek(mcpfd, 1<<1,0);       // address=1 (16bit) - start sequencer
03126 //-         i=0;
03127 //-         write(mcpfd,&i,1<<1);
03128 //-        }
03129         ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 1);
03130 //-        if (mcpfd>=0) {close(mcpfd); mcpfd=-1;}
03131         close(devfd);
03132 // send the image
03133         i=processImage(gparams,ImgFileName,
03134                        bufFileName,pc_par,iq_par,gd_par,
03135                        html_par,htmlr_par,htmll_par,htmlj_par,
03136                        vrml_par,vrmlm_par,vrmld_par,vrmlb_par,vrmli_par,vrmlf_par,vrmll_par,vrmlo_par,vrmlz_par);
03137 
03138         if (dtime>0) stime(&new_time);
03139         close(lock_fd);
03140         if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03141         return 0;
03142     } // if (optionPresent(gparams, "opt", 'm'))
03143     D5(fprintf(stderr,"20\r\n"));
03144 
03145 // here comes if it was not a 'm' mode, devfd - open
03146 // if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03147 // if (optionPresent(gparams, "opt", '@')) {       
03148 //      sprintf(dbgstr,"state=%x count=%x\n",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0),
03149 //                                           ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1));
03150 //     debug_write (__FILE__,__LINE__,dbgstr);
03151 // }
03152 // here if the ccam.cgi hanged, count was <-1
03153 // program all parameters
03154         setCamPars(devfd,n_bf,cp,vp);
03155 // check if background measurement is needed
03156         if(n_bf > 0) {
03157                 // perform specified number of background measurements,
03158                 // write FPN data to SDRAM (using P_FPN value and calibration file if needed)
03159                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_BGFRAME ),  0); // for now driver only checks if n_bf==0, later maybe will average
03160                 // save_p_bits, save_p_fpn
03161                 close(devfd);   // it was jpegFileName  open
03162                 devfd = open(ImgFileName, O_RDWR);
03163                 save_p_bits = ioctl(devfd, _CCCMD(CCAM_RPARS, P_BITS), 0);      // save bit settings ad switch to 10-bit mode
03164                 save_p_fpns = ioctl(devfd, _CCCMD(CCAM_RPARS, P_FPNS), 0);
03165                 save_p_fpnm = ioctl(devfd, _CCCMD(CCAM_RPARS, P_FPNM), 0);
03166                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_BITS), 10);
03167                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_FPNS), 0);
03168                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_FPNM), 0);
03169                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_UPDATE), 1); // 1 - at once, 2 - later
03170                 pp = 0;
03171                 if(n_bf > 1) pp = 1;
03172                 if(n_bf > 2) pp = 2;
03173                 if(n_bf > 4) pp = 3;
03174                 if(n_bf > 8) pp = 4;
03175                 if(n_bf > 16) pp = 5;
03176                 if(n_bf > 32) pp = 6;
03177                 n_bf = 1 << pp;
03178                 remove(backgroundFileName);  // remove old background file (if any)
03179                 for(i = 0; i < n_bf; i++) {
03180                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE), 1);
03181                         while(((j = ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ), 0)) != CAMSEQ_DONE) &&
03182                                 (j !=CAMSEQ_READY) && // these 2 lines - if somebody did reset the acquisition
03183                                 (j != CAMSEQ_OFF)); // just wait - forever?
03184 //                      ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // reset state
03185                         if((j = accumData(devfd, backgroundFileName)) != 0) { // ImgFileName was open and should remain open, using devfd instead
03186                                 printf(error304);
03187                                 close(lock_fd);
03188                                 if(optionPresent(gparams, "opt", '@'))
03189                                         debug_write (__FILE__,__LINE__,query);
03190                                 return -1;
03191                         }
03192                 } //for (i=0;i<n_bp;i++)
03193                 frameShr(backgroundFileName, pp);
03194                 ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE), 0); // **** reset state
03195                 // program FPGA SDRAM background frame data and adjust it to P_FPNS
03196                 close(devfd);
03197                 programFPN(backgroundFileName,calibrationFileName, FPNFileName,save_p_fpns,save_p_fpnm, fat_zero);
03198                 devfd = open(jpegFileName, O_RDWR);
03199                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_BITS), save_p_bits);
03200                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_FPNS), save_p_fpns);
03201                 ioctl(devfd, _CCCMD(CCAM_WPARS , P_FPNM), save_p_fpnm);
03202                 setCamPars(devfd, 0, cp, vp);
03203         } //   if (n_bf>0)
03204 // if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03205 // if (optionPresent(gparams, "opt", '@')) {       
03206 //      sprintf(dbgstr,"state=%x count=%x\n",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0),
03207 //                                           ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1));
03208 //     debug_write (__FILE__,__LINE__,dbgstr);
03209 // }
03210 // start new picture acquisition
03211       D5(fprintf(stderr,"21\r\n"));
03212 
03213         if(!optionPresent(gparams, "opt", 'o'))
03214                 ioctl (devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // reset state first (just in case)
03215 // cheeeeeeese !
03216 //-// open MCP "file"
03217 //-    mcpfd = open(MCPFileName, O_RDWR);
03218 //-// arm MCP sequencer (if any)
03219 //-    if (mcpfd>=0) {
03220 //-         lseek(mcpfd, 1<<1,0);       // address=1 (16bit) - start sequencer
03221 //-         i=0;
03222 //-         write(mcpfd,&i,1<<1);
03223 //-    }
03224 
03225 // Just start it
03226 
03227 //            i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0);
03228 //            j=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1);
03229 //            printf ("Cam-sequencer state - %x,  count= %x\r\n",i,j);
03230 // if (optionPresent(gparams, "opt", '@'))  debug_write (__FILE__,__LINE__,query);
03231 // if (optionPresent(gparams, "opt", '@')) {       
03232 //      sprintf(dbgstr,"state=%x count=%x\n",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0),
03233 //                                           ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1));
03234 //     debug_write (__FILE__,__LINE__,dbgstr);
03235 // }
03236       D5(fprintf(stderr,"22\r\n"));
03237 
03238 // ------------
03239         // Is it just re-reading from memory?
03240         if(optionPresent(gparams, "opt", 'o')) {
03241 //syslog(LOG_ALERT, "-->");
03242 //syslog(LOG_ALERT, "--> opt o found...");
03243 //syslog(LOG_ALERT, "-->");
03244                 if(optionPresent(gparams, "opt", 'h')) {
03245                         // need to set compression quality and compress again
03246                         devfd = open(jpegFileName, O_RDWR);
03247                         // here state should be never>7 (running), last chance for the "update" or "stop" commands was above
03248                         if(((i = ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ), 0)) == CAMSEQ_RUN) ||
03249                                         (i == CAMSEQ_SINGLE) ||
03250                                         (i == CAMSEQ_STOP)) {
03251                                 close(devfd);
03252                                 send_jpegfile_image(inUseFileName);
03253                                 close(lock_fd);
03254                                 return -1;
03255                         }
03256                         // acquire new image only if jpeg quality is specified
03257 //                      if((vp = paramValue(gparams, "iq"))) {
03258 //                              ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG_QUALITY), strtol(vp, &cp, 10));
03259 //                              ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_CATCHUP);     // will point to the latest got or being acquired (if none got ever)
03260 //                              ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_FORGET);
03261 //                              ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_GET); // start compression now.
03262 //                              ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_ACQUIRE); // start compression witrh acquisition.
03263                                 while(lseek(devfd, 0, 2) == 0);
03264 //                      }
03265                         i = lseek(devfd, 0, 2);
03266                         close(devfd);
03267                         if(i == 0) { // no image available
03268                                 send_jpegfile_image(emptyFileName);  // return just 1x1 pix jpeg image
03269                                 i = -1;
03270                         } else {
03271                                 i = send_hardware_image(jpegFileName, optionPresent(gparams, "opt", '.')); //will not see changes in Quality settings
03272                         }
03273                         devfd = open(jpegFileName, O_RDWR);
03274                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE), 0); // reset state first (just in case)
03275                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_CATCHUP);     // will point to the latest got or being acquired (if none got ever)
03276                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_FORGET);
03277                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_ACQUIRE); // start compression witrh acquisition.
03278 //                      ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG), JPEG_CMD_GET); // start compression witrh acquisition.
03279 //                      while(lseek(devfd, 0, 2) == 0);
03280                         close(devfd);
03281                 }
03282                 close(lock_fd);
03283                 return i;
03284         }
03285 // ------------
03286 /*
03287         int enable;
03288         int enable_ping;
03289         long port_in;
03290         long port_out;
03291         unsigned long number;
03292         unsigned long id;
03293         long timeout;
03294 */
03295         // check trigger
03296 //      if(optionPresent(gparams, ))
03297         if((vp = paramValue(gparams, "tr_ping"))) {
03298                 int t;
03299                 trig_desc.enable = 1;
03300                 t = atol(vp);
03301                 if(t > 256)
03302                         trig_desc.port_in = t;
03303                 if((vp = paramValue(gparams, "tr_pong"))) {
03304                         trig_desc.enable_ping = 1;
03305                         t = atol(vp);
03306                         if(t > 256)
03307                                 trig_desc.port_out = t;
03308                 }
03309         }
03310 
03311         if(optionPresent(gparams, "opt", 'h')) {
03312 //syslog(LOG_ALERT, "...1\r\n");
03313                 ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_CATCHUP);    // will point to the latest got or being acquired (if none got ever)
03314                 if(!optionPresent(gparams, "opt", 'm'))
03315                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_FORGET);
03316                 if(trig_desc.enable) {
03317                         bcast_trigger();
03318                 }
03319                 // here we start CCD
03320                 ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_JPEG ), JPEG_CMD_ACQUIRE); // start compression witrh acquisition.
03321 //              if(optionPresent(gparams, "opt", '@')) {       
03322 //                      sprintf(dbgstr,"state=%x count=%x\n",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0),
03323 //                      ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1));
03324 //                      debug_write (__FILE__,__LINE__,dbgstr);
03325 //              }
03326             D5(fprintf(stderr,"23\r\n"));
03327         } else
03328                 ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE), 1);
03329 
03330         // need to wait for image to be acquired
03331 //      DD(ioctl(devfd, _CCCMD(CCAM_WPARS ,  62 ),     6)); // +++++just test - to be reported by driver
03332 
03333         // Always wait but make it possible to reset by "hello -z 0" or similar
03334         if(!optionPresent(gparams, "opt", 'h') && (html_par != HTML_ACQUIRE) && (html_par != XML_ACQUIRE)) { // do not wait for image and reset state if it was just  HTML_ACQUIRE
03335 //syslog(LOG_ALERT, "...2\r\n");
03336                 if(optionPresent(gparams, "opt", '@'))
03337                         debug_write (__FILE__,__LINE__,query);
03338                 while(((i = ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0)) != CAMSEQ_DONE) &&
03339                         (i !=CAMSEQ_READY) && // these 2 lines - if somebody did reset the acquisition
03340                         (i != CAMSEQ_OFF)); // just wait - forever?
03341 //syslog(LOG_ALERT, "...3\r\n");
03342                 if(optionPresent(gparams, "opt", '@'))
03343                         debug_write(__FILE__,__LINE__,query);
03344 //              if(mcpfd >= 0) close(mcpfd);
03345                 ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_SET_EXT_EXPOSURE ), 0); // reset state
03346                 D5(fprintf(stderr,"24\r\n"));
03347         }
03348         close(devfd);
03349 //syslog(LOG_ALERT, "...4\r\n");
03350         if(optionPresent(gparams, "opt", 'h')) {
03351                 D5(fprintf(stderr,"25\r\n"));
03352                 // will ignore or VRML-related stuff
03353                 // for now - start compression and wait done
03354                 devfd = open(jpegFileName, O_RDWR);
03355                 // wait for done here... (later will overlap)
03356 //              i=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0);
03357 //              j=ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1);
03358 //              printf ("Cam-sequencer state - %x,  count= %x\r\n",i,j);
03359 
03360                 // sometimes stucks here forever - reading image (not "opt=u") with "opt=*" will unfreeze it
03361                 if(optionPresent(gparams, "opt", '@'))
03362                         debug_write (__FILE__,__LINE__,query);
03363                 if(optionPresent(gparams, "opt", '@')) {       
03364                         sprintf(dbgstr,"state=%x count=%x\n",ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0),
03365                         ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1));
03366                         debug_write (__FILE__,__LINE__,dbgstr);
03367                 }
03368 //syslog(LOG_ALERT, "...5\r\n");
03369                 // seems that when compressor is stuck only VSYNC pulses are processed and counter goes below -1 (it should always read ffffffff)
03370                 // so we will check for that condition and return with failure
03371                 // ioctl() can not return -2! - for -1 .. -4096 i returns -1 placing the actual data to errno
03372 
03373 //              extern int errno;
03374                 errno = 0;
03375                 comeOut = 0;
03376                 D5(fprintf(stderr,"26\r\n"));
03377                 while(!comeOut) {
03378                         comeOut = (lseek(devfd, 0, 2) != 0) || (ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0) < 7);
03379                         errno = 0;
03380                         i = ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1);
03381                         if((i < -1) || ((i == -1) && (errno > 1)))
03382                                 comeOut = 1;
03383                 }
03384                 comeOut=errno;
03385 /*
03386       while ((lseek(devfd,0,2)==0) && 
03387        (ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1)>-2) &&
03388        !((ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1)==-1) && (errno < 2)) &&
03389        (ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0)>=7)); // so it will unfreeze if state was reset
03390 */
03391                 if(optionPresent(gparams, "opt", '@'))
03392                         debug_write(__FILE__,__LINE__,query);
03393                 if(optionPresent(gparams, "opt", '@')) {
03394                         sprintf(dbgstr, "state=%x count=%x errno=%x\n", ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 0),
03395 //                              ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ ), 1));
03396                                 i, comeOut);
03397                         debug_write(__FILE__, __LINE__, dbgstr);
03398                 }
03399                 D5(fprintf(stderr,"27\r\n"));
03400 
03401                 if(lseek(devfd, 0, 2) == 0) {
03402                         if(optionPresent(gparams, "opt", '@'))
03403                                 debug_write(__FILE__, __LINE__, query);
03404                         close(devfd);
03405                         if(paramValue(gparams, "html") || (optionPresent(gparams, "opt", 'u') && optionPresent(gparams, "opt", '+'))) { // send XML instead of "camera in use"
03406                                 printf("Content-Type: text/xml\n");
03407                                 printf("Pragma: no-cache\n\n"); // 2 new lines!
03408                                 printf("<?xml version=\"1.0\" ?>\n");
03409                                 printf("<camera>\n<SENSOR_STATE>-3</SENSOR_STATE></camera>\n");
03410                         } else {
03411                                 if(optionPresent(gparams, "opt", '+'))
03412                                         send_jpegfile_image(emptyFileName);  // return just 1x1 pix jpeg image
03413                                 else
03414                                         send_jpegfile_image(inUseFileName);
03415                         }
03416                         close(lock_fd);
03417                         return -1;
03418                 }
03419                 D5(fprintf(stderr,"28\r\n"));
03420 
03421                 if(optionPresent(gparams, "opt", '@'))
03422                         debug_write(__FILE__, __LINE__, query);
03423                 // will return 0 until xfer is over
03424                 if(optionPresent(gparams, "opt", 'u') && optionPresent(gparams, "opt", '!')) { // send XML with state instead of image
03425                         printf("Content-Type: text/xml\n");
03426                         printf("Pragma: no-cache\n\n"); // 2 new lines!
03427                         printf("<?xml version=\"1.0\" ?>\n");
03428                         printf("<camera>\n<SENSOR_STATE>%d</SENSOR_STATE></camera>\n", ioctl(devfd, _IO(CMOSCAM_IOCTYPE, IO_CCAM_MONITOR_SEQ), 0));
03429                         close (devfd);
03430                 } else {
03431                         D5(fprintf(stderr,"29\r\n"));
03432                         close(devfd);
03433                         i = send_hardware_image(jpegFileName, optionPresent(gparams, "opt", '.'));
03434                 }
03435         } else {
03436                         D5(fprintf(stderr,"30\r\n"));
03437                 i = processImage(gparams,ImgFileName,
03438                         bufFileName,pc_par,iq_par,gd_par,
03439                         html_par,htmlr_par,htmll_par,htmlj_par,
03440                         vrml_par,vrmlm_par,vrmld_par,vrmlb_par,vrmli_par,vrmlf_par,vrmll_par,vrmlo_par,vrmlz_par);
03441         }
03442 
03443         if(dtime > 0)
03444                 stime(&new_time);
03445         close(lock_fd);
03446         if(optionPresent(gparams, "opt", '@'))
03447                 debug_write(__FILE__, __LINE__, query);
03448 
03449         closelog();
03450         D5(fprintf(stderr,"31\r\n"));
03451 
03452 prof_next("point...3");
03453         return 0; // usually returns from here whan image is requested
03454 }

Generated on Thu Aug 7 16:18:59 2008 for elphel by  doxygen 1.5.1