00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 #ifdef HAVE_CONFIG_H
00164 #include "config.h"
00165 #endif
00166
00167
00168 #include <sys/mman.h>
00169 #include <sys/ioctl.h>
00170 #include <fcntl.h>
00171 #include <asm/byteorder.h>
00172 #include <errno.h>
00173 #include "php.h"
00174 #include "php_ini.h"
00175 #include "elphel_php.h"
00176
00177
00178 ZEND_DECLARE_MODULE_GLOBALS(elphel)
00179 static function_entry elphel_functions[] = {
00180 PHP_FE(elphel_get_frame, NULL)
00181 PHP_FE(elphel_skip_frames, NULL)
00182 PHP_FE(elphel_wait_frame_abs, NULL)
00183 PHP_FE(elphel_framepars_get_raw, NULL)
00184 PHP_FE(elphel_parse_P_name, NULL)
00185 PHP_FE(elphel_is_global_par, NULL)
00186 PHP_FE(elphel_is_frame_par, NULL)
00187 PHP_FE(elphel_get_P_value, NULL)
00188 PHP_FE(elphel_set_P_value, NULL)
00189 PHP_FE(elphel_get_P_arr, NULL)
00190 PHP_FE(elphel_set_P_arr, NULL)
00191 PHP_FE(elphel_gamma_add, NULL)
00192 PHP_FE(elphel_gamma_add_custom, NULL)
00193 PHP_FE(elphel_gamma_get, NULL)
00194 PHP_FE(elphel_gamma_get_index, NULL)
00195 PHP_FE(elphel_gamma_get_raw, NULL)
00196 PHP_FE(elphel_histogram_get_raw, NULL)
00197 PHP_FE(elphel_histogram_get, NULL)
00198 PHP_FE(elphel_get_state, NULL)
00199
00200 PHP_FE(elphel_compressor_reset, NULL)
00201 PHP_FE(elphel_compressor_run, NULL)
00202 PHP_FE(elphel_compressor_stop, NULL)
00203 PHP_FE(elphel_compressor_frame, NULL)
00204 PHP_FE(elphel_reset_sensor, NULL)
00205 PHP_FE(elphel_set_fpga_time, NULL)
00206 PHP_FE(elphel_get_fpga_time, NULL)
00207 PHP_FE(elphel_wait_frame, NULL)
00208 PHP_FE(elphel_fpga_read, NULL)
00209 PHP_FE(elphel_fpga_write, NULL)
00210 PHP_FE(elphel_gamma, NULL)
00211 PHP_FE(elphel_reverse_gamma, NULL)
00212 PHP_FE(elphel_histogram, NULL)
00213 PHP_FE(elphel_reverse_histogram, NULL)
00214 PHP_FE(elphel_get_exif_field, NULL)
00215 PHP_FE(elphel_set_exif_field, NULL)
00216 PHP_FE(elphel_get_interframe_meta, NULL)
00217 PHP_FE(elphel_get_exif_elphel, NULL)
00218 PHP_FE(elphel_update_exif, NULL)
00219 PHP_FE(elphel_get_circbuf_pointers, NULL)
00220 {NULL, NULL, NULL}
00221 };
00222
00223 zend_module_entry elphel_module_entry = {
00224 #if ZEND_MODULE_API_NO >= 20010901
00225 STANDARD_MODULE_HEADER,
00226 #endif
00227 PHP_ELPHEL_EXTNAME,
00228 elphel_functions,
00229 PHP_MINIT(elphel),
00230 PHP_MSHUTDOWN(elphel),
00231 PHP_RINIT(elphel),
00232 NULL,
00233 PHP_MINFO(elphel),
00234 #if ZEND_MODULE_API_NO >= 20010901
00235 PHP_ELPHEL_VERSION,
00236 #endif
00237 STANDARD_MODULE_PROPERTIES
00238 };
00239
00240 #ifdef COMPILE_DL_ELPHEL
00241 ZEND_GET_MODULE(elphel)
00242 #endif
00243
00244
00245 PHP_INI_BEGIN()
00247 PHP_INI_END()
00248
00249
00251 static void init_sens() {
00252 }
00253
00262 int splitConstantName(char * name) {
00263 int len= strlen(name);
00264 int nIndex;
00265 int d=0;
00266 int dp=1;
00267 int bfields;
00268 int success=0;
00269 if ((len>6) && (name[len-6]=='_') && (name[len-5]=='_')) {
00270
00271 d= FRAMEPAIR_FRAME_BITS(((name[len-3] - '0') + ((name[len-4] - '0') * 10)), ((name[len-1] - '0') + ((name[len-2] - '0') * 10)));
00272 name[len-6]='\0';
00273 len-=6;
00274 success=1;
00275 }
00276 nIndex= len-1;
00277 while ((nIndex>0) && (name[nIndex]>='0') && (name[nIndex] <='9')){
00278 d+=dp*(name[nIndex]-'0');
00279 dp*=10;
00280 nIndex--;
00281 success=1;
00282 }
00283 nIndex++;
00284 if (success) {
00285 name[nIndex]='\0';
00286 return d;
00287 } else return -1;
00288 }
00289
00291 PHP_FUNCTION(elphel_get_frame)
00292 {
00293 RETURN_LONG( ELPHEL_GLOBALPARS(G_THIS_FRAME));
00294 }
00295
00296 PHP_FUNCTION(elphel_skip_frames)
00297 {
00298 long skip=1;
00299 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &skip) == FAILURE) {
00300 RETURN_NULL();
00301 }
00302 long target_frame=lseek((int) ELPHEL_G( fd_fparmsall), 0, SEEK_CUR )+skip;
00303 if ((target_frame<0) || (target_frame > 0x7ffffdff)) RETURN_NULL();
00304 RETURN_LONG(lseek((int) ELPHEL_G( fd_fparmsall), target_frame + LSEEK_FRAME_WAIT_ABS, SEEK_END ));
00305 }
00306
00307 PHP_FUNCTION(elphel_wait_frame_abs)
00308 {
00309 long target_frame;
00310 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &target_frame) == FAILURE) {
00311 RETURN_NULL();
00312 }
00313 if ((target_frame<0) || (target_frame > 0x7ffffdff)) RETURN_NULL();
00314 RETURN_LONG(lseek((int) ELPHEL_G( fd_fparmsall), target_frame + LSEEK_FRAME_WAIT_ABS, SEEK_END ));
00315 }
00316
00322 PHP_FUNCTION(elphel_parse_P_name)
00323 {
00324 char full_constant_name[256];
00325 char *name;
00326 int name_len;
00327 long full_addr =-1;
00328 zval const_value;
00329 long constAddNumber;
00330 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
00331 RETURN_NULL();
00332 }
00333 if (strlen(name)>(sizeof(full_constant_name)-8)) RETURN_NULL();
00334 sprintf (full_constant_name,"ELPHEL_%s",name);
00335 if (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC)) {
00336 full_addr= Z_LVAL(const_value);
00337 } else {
00338 constAddNumber=splitConstantName(full_constant_name);
00339 if ((constAddNumber>=0) && (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC))) {
00340 full_addr= (Z_LVAL(const_value) & ~FRAMEPAIR_MASK_BYTES)+constAddNumber;
00341 }
00342 }
00343 if (full_addr!=-1) {
00344 RETURN_LONG (full_addr);
00345 zval_dtor(&const_value);
00346 }
00347 RETURN_NULL();
00348 }
00349
00355 PHP_FUNCTION(elphel_is_global_par)
00356 {
00357 long addr;
00358 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
00359 RETURN_NULL();
00360 }
00361 addr &= 0xffff;
00362 if ((addr >= FRAMEPAR_GLOBALS) && (addr < (FRAMEPAR_GLOBALS+P_MAX_GPAR))) RETURN_TRUE;
00363 RETURN_FALSE;
00364 }
00365
00371 PHP_FUNCTION(elphel_is_frame_par)
00372 {
00373 long addr;
00374 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
00375 RETURN_NULL();
00376 }
00377 addr &= 0xffff;
00378 if (addr < (sizeof (struct framepars_t) >>2)) RETURN_TRUE;
00379 RETURN_FALSE;
00380 }
00381
00384 PHP_FUNCTION(elphel_get_P_value)
00385 {
00386 long addr, full_addr;
00387 long frame=-1;
00388 long frame_index=-1;
00389 int frame_stored;
00390 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &full_addr,&frame) == FAILURE) {
00391 RETURN_NULL();
00392 }
00393 if (frame <0) {
00394 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME);
00395 }
00396 addr = full_addr & 0xffff;
00397
00398 if (addr >= FRAMEPAR_GLOBALS) {
00399 if (addr >= (FRAMEPAR_GLOBALS+P_MAX_GPAR)) {
00400 RETURN_NULL();
00401 }
00402 if (full_addr & FRAMEPAIR_MASK_BYTES) {
00403 RETURN_LONG(FRAMEPAIR_FRAME_FIELD(full_addr,ELPHEL_GLOBALPARS(addr)));
00404 } else {
00405 RETURN_LONG(ELPHEL_GLOBALPARS(addr));
00406 }
00407 }
00409 if ((addr<0) ||(addr>= (sizeof (struct framepars_t) >>2))) {
00410 RETURN_NULL();
00411 }
00412 if (frame <0) {
00413
00414 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME);
00415 }
00416
00418 frame_index = frame & PARS_FRAMES_MASK;
00419 frame_stored= ((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[P_FRAME];
00420 if (frame_stored == frame) {
00421 RETURN_LONG( ((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[addr]);
00422 }
00423 if (frame_stored <frame) {
00424 RETURN_NULL();
00425 }
00427 frame_index = frame & PASTPARS_SAVE_ENTRIES_MASK;
00428 frame_stored= ((struct framepars_past_t *) ELPHEL_G(pastPars))[frame_index].past_pars[P_FRAME-PARS_SAVE_FROM];
00429 if (frame_stored == frame) {
00430 addr-=PARS_SAVE_FROM;
00431 if ((addr<0) ||(addr>= (sizeof (struct framepars_past_t) >>2))) {
00432 RETURN_NULL();
00433 }
00434 RETURN_LONG( ((struct framepars_past_t *) ELPHEL_G(pastPars))[frame_index].past_pars[addr]);
00435 }
00437 RETURN_NULL();
00438 }
00439
00443 PHP_FUNCTION(elphel_get_state)
00444 {
00445 long frame8=ELPHEL_GLOBALPARS(G_THIS_FRAME) & PARS_FRAMES_MASK;
00446 long compressor_state= ((struct framepars_t *) ELPHEL_G(framePars))[frame8].pars[P_COMPRESSOR_RUN];
00447 long sensor_state= ((struct framepars_t *) ELPHEL_G(framePars))[frame8].pars[P_SENSOR_RUN];
00448 long result=(compressor_state==COMPRESSOR_RUN_CONT)?0x8:
00449 ((compressor_state==COMPRESSOR_RUN_SINGLE)?0xa:
00450 ((sensor_state==SENSOR_RUN_CONT)?0x7:0));
00451 RETURN_LONG(result);
00452 }
00453
00461 PHP_FUNCTION(elphel_framepars_get_raw)
00462 {
00463 char * packed_framepars_structure;
00464 long index=0;
00465 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &index) == FAILURE) {
00466 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong index");
00467 RETURN_NULL ();
00468 }
00469 packed_framepars_structure= (char*) emalloc (sizeof (struct framepars_t));
00470 if (packed_framepars_structure) {
00472 if (index>=0) {
00473 memcpy(packed_framepars_structure, &(((struct framepars_t *) ELPHEL_G(framePars))[index & PARS_FRAMES_MASK]),sizeof(struct framepars_t));
00474 } else if (index == -1) {
00475 memcpy(packed_framepars_structure, ((struct framepars_t *) ELPHEL_G(funcs2call)),sizeof(struct framepars_t));
00476 } else if (index == -2) {
00477 memcpy(packed_framepars_structure, ((struct framepars_t *) ELPHEL_G(globalPars)),sizeof(struct framepars_t));
00478 } else RETURN_NULL ();
00479 RETURN_STRINGL (packed_framepars_structure, sizeof(struct framepars_t), 0);
00480 }
00481 php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc error");
00482 RETURN_NULL ();
00483 }
00484
00485
00486
00487
00488
00496 PHP_FUNCTION(elphel_get_P_arr)
00497 {
00498 long frame=-1;
00499 long frame_index=-1;
00500 int future=1;
00501 int frame_stored;
00502 long addr,full_addr,val;
00503 char full_constant_name[256];
00504 zval *arr, **data;
00505 HashTable *arr_hash;
00506 HashPosition pointer;
00507 char *key;
00508 int key_len;
00509 long index;
00510 long constAddNumber;
00511 zval const_value;
00512 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &arr, &frame) == FAILURE) {
00513 RETURN_NULL();
00514 }
00515
00517 if (frame < 0) {
00518 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME);
00519 }
00521 frame_index = frame & PARS_FRAMES_MASK;
00522 frame_stored= ((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[P_FRAME];
00523 if (frame_stored <frame) {
00524 future=-1 ;
00525 }
00526 if (frame_stored > frame) {
00527 frame_index = frame & PASTPARS_SAVE_ENTRIES_MASK;
00528 frame_stored= ((struct framepars_past_t *) ELPHEL_G(pastPars))[frame_index].past_pars[P_FRAME-PARS_SAVE_FROM];
00529 if (frame_stored != frame) {
00530 future=-1 ;
00531 } else future=0;
00532 }
00533
00534 array_init(return_value);
00535 arr_hash = Z_ARRVAL_P(arr);
00536 for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
00537 zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS;
00538 zend_hash_move_forward_ex(arr_hash, &pointer)) {
00539 if (zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) {
00540 if (strlen(key)>(sizeof(full_constant_name)-8)) RETURN_NULL();
00541 sprintf (full_constant_name,"ELPHEL_%s",key);
00542 full_addr =-1;
00543 if (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC)) {
00544 full_addr= Z_LVAL(const_value);
00545 } else {
00546 constAddNumber=splitConstantName(full_constant_name);
00547
00548 if ((constAddNumber>=0) && (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC))) {
00549 full_addr= (Z_LVAL(const_value) & ~FRAMEPAIR_MASK_BYTES)+constAddNumber;
00550 }
00551 }
00552 if (full_addr!=-1) {
00553 addr=full_addr & 0xffff;
00555 if (addr >= FRAMEPAR_GLOBALS) {
00556 if (addr < (FRAMEPAR_GLOBALS+P_MAX_GPAR)) {
00557 if (full_addr & FRAMEPAIR_MASK_BYTES) {
00558 add_assoc_long(return_value, key, FRAMEPAIR_FRAME_FIELD(full_addr,ELPHEL_GLOBALPARS(addr)));
00559 } else {
00560 add_assoc_long(return_value, key, ELPHEL_GLOBALPARS(addr));
00561 }
00562 }
00564 } else if (future>0) {
00565 if ((addr >=0) && (addr < (sizeof (struct framepars_t) >>2))) {
00566 if (full_addr & FRAMEPAIR_MASK_BYTES) {
00567 add_assoc_long(return_value, key, FRAMEPAIR_FRAME_FIELD(full_addr,((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[addr]));
00568 } else {
00569 add_assoc_long(return_value, key, ((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[addr]);
00570 }
00571 }
00573 } else if (future==0){
00574 addr-=PARS_SAVE_FROM;
00575 if ((addr >=0) && (addr <(sizeof (struct framepars_past_t) >>2))) {
00576 if (full_addr & FRAMEPAIR_MASK_BYTES) {
00577 add_assoc_long(return_value, key, FRAMEPAIR_FRAME_FIELD(full_addr,((struct framepars_past_t *) ELPHEL_G(pastPars))[frame_index].past_pars[addr]));
00578 } else {
00579 add_assoc_long(return_value, key, ((struct framepars_past_t *) ELPHEL_G(pastPars))[frame_index].past_pars[addr]);
00580 }
00581 }
00582 }
00583 zval_dtor(&const_value);
00584 }
00585 }
00586 }
00587 }
00588
00598 long elphel_set_P_value_common(long addr, long data, long frame, long flags) {
00599 unsigned long write_data[4];
00600 long maddr;
00602 maddr=addr & 0xffff;
00603 if (( (addr & 0xff00) != 0xff00 ) && (maddr >= FRAMEPAR_GLOBALS)) {
00604 if (maddr >= (FRAMEPAR_GLOBALS+P_MAX_GPAR)) {
00605 return -1;
00606 }
00607 ELPHEL_GLOBALPARS(maddr)=data;
00608 return 0;
00609 }
00610 if (frame <0) {
00611 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME) + FRAME_DEAFAULT_AHEAD;
00612 }
00613 flags |= (flags << 16);
00614 flags &=0xffff0000;
00615 if ((addr<0) ||((maddr >= (sizeof (struct framepars_t) >>2)) && ( (addr & 0xff00) != 0xff00 ) )) {
00616 return -1;
00617 }
00618 write_data[0]=FRAMEPARS_SETFRAME;
00619 write_data[1]=frame;
00620 write_data[2]= addr | flags;
00621 write_data[3]= data;
00622 long rslt=write(ELPHEL_G(fd_fparmsall), write_data, sizeof(write_data));
00623
00624 if (rslt<0) return -errno;
00625 if (rslt == sizeof( write_data )) return frame;
00626 return -1;
00627 }
00628
00629
00633
00634 PHP_FUNCTION(elphel_set_P_value)
00635 {
00636 long addr;
00637 long data;
00638 long frame=-1;
00639 unsigned long flags=0;
00640 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|ll", &addr,&data,&frame,&flags) == FAILURE) {
00641 RETURN_NULL();
00642 }
00643 if (((frame=elphel_set_P_value_common (addr, data, frame, flags))) <0) {
00644 RETURN_NULL();
00645 }
00646 RETURN_LONG(frame);
00647 }
00648
00650 PHP_FUNCTION(elphel_compressor_reset)
00651 {
00652 long frame=-1;
00653 unsigned long flags=-1;
00654 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &frame,&flags) == FAILURE) {
00655 RETURN_NULL();
00656 }
00657 if (flags<0) flags=FRAMEPAIR_FORCE_NEWPROC;
00658 if (((frame=elphel_set_P_value_common (P_COMPRESSOR_RUN, COMPRESSOR_RUN_STOP, frame, flags)))<0) {
00659 RETURN_NULL();
00660 }
00661 RETURN_LONG(frame);
00662 }
00663
00665 PHP_FUNCTION(elphel_compressor_run)
00666 {
00667 long frame=-1;
00668 unsigned long flags=-1;
00669 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &frame,&flags) == FAILURE) {
00670 RETURN_NULL();
00671 }
00672 if (flags<0) flags=FRAMEPAIR_FORCE_NEWPROC;
00673 if (((frame=elphel_set_P_value_common (P_COMPRESSOR_RUN, COMPRESSOR_RUN_CONT, frame, flags)))<0) {
00674 RETURN_NULL();
00675 }
00676 RETURN_LONG(frame);
00677 }
00678
00680
00681 PHP_FUNCTION(elphel_compressor_stop)
00682 {
00683 long frame=-1;
00684 unsigned long flags=-1;
00685 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &frame,&flags) == FAILURE) {
00686 RETURN_NULL();
00687 }
00688 if (flags<0) flags=FRAMEPAIR_FORCE_NEWPROC;
00689 if (((frame=elphel_set_P_value_common (P_COMPRESSOR_RUN, COMPRESSOR_RUN_STOP, frame, flags)))<0) {
00690 RETURN_NULL();
00691 }
00692 RETURN_LONG(frame);
00693 }
00694
00696 PHP_FUNCTION(elphel_compressor_frame)
00697 {
00698 long frame=-1;
00699 unsigned long flags=-1;
00700 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &frame,&flags) == FAILURE) {
00701 RETURN_NULL();
00702 }
00703 if (flags<0) flags=FRAMEPAIR_JUST_THIS;
00704 if (((frame=elphel_set_P_value_common (P_COMPRESSOR_RUN, COMPRESSOR_RUN_SINGLE, frame, flags)))<0) {
00705 RETURN_NULL();
00706 }
00707 RETURN_LONG(frame);
00708 }
00710 PHP_FUNCTION(elphel_reset_sensor) {
00711 lseek((int) ELPHEL_G(fd_fparmsall), LSEEK_FRAMEPARS_INIT, SEEK_END );
00712 elphel_set_P_value_common (P_SENSOR, 0, 0, -1);
00713 RETURN_NULL();
00714 }
00715
00721 PHP_FUNCTION(elphel_set_P_arr)
00722 {
00723 char full_constant_name[256];
00724 zval *arr, **data;
00725 HashTable *arr_hash;
00726 HashPosition pointer;
00727 char *key;
00728 int key_len;
00729 long index;
00730 zval const_value;
00731 int array_count;
00732 unsigned long * write_data=NULL;
00733 long frame=-1;
00734 long flags=0;
00735 int num_written=0;
00736 int num_mmap_written=0;
00737 int reg_addr, reg_data, constAddNumber;
00738 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|ll", &arr,&frame,&flags) == FAILURE) {
00739 RETURN_LONG(num_written);
00740 }
00741 if (frame <0) {
00742 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME) + FRAME_DEAFAULT_AHEAD;
00743 }
00744 flags |= (flags << 16);
00745 flags &=0xffff0000;
00746 init_sens();
00747 arr_hash = Z_ARRVAL_P(arr);
00748 array_count = zend_hash_num_elements(arr_hash);
00750 write_data=(unsigned long *) emalloc ((array_count+1)<<3);
00751 if (!write_data) RETURN_NULL();
00752
00753 write_data[0]=FRAMEPARS_SETFRAME;
00754 write_data[1]=frame;
00755 for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
00756 zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS;
00757 zend_hash_move_forward_ex(arr_hash, &pointer)) {
00758 if ((zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) &&
00759 (Z_TYPE_PP(data) == IS_LONG)) {
00760 reg_data=Z_LVAL_PP(data);
00761 if (strlen(key)>(sizeof(full_constant_name)-8)) RETURN_NULL();
00762 sprintf (full_constant_name,"ELPHEL_%s",key);
00763
00764 reg_addr =-1;
00765 if (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC)) {
00766 reg_addr= Z_LVAL(const_value);
00767 } else {
00768 constAddNumber=splitConstantName(full_constant_name);
00769 if ((constAddNumber>=0) && (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC))) {
00770 reg_addr= (Z_LVAL(const_value) & ~FRAMEPAIR_MASK_BYTES)+constAddNumber;
00771 }
00772 }
00773
00774 if (reg_addr>=0) {
00776 zval_dtor(&const_value);
00777 if (((reg_addr & 0xff00) != 0xff00 ) && ((reg_addr & 0xffff) >= FRAMEPAR_GLOBALS)) {
00778 if ((reg_addr & 0xffff) < (FRAMEPAR_GLOBALS+P_MAX_GPAR)) {
00779 if ((reg_addr & FRAMEPAIR_MASK_BYTES) ==0) {
00780 ELPHEL_GLOBALPARS(reg_addr & 0xffff)=reg_data;
00781 num_mmap_written++;
00782 } else {
00783 write_data[(num_written<<1) + 2]= reg_addr | flags;
00784 write_data[(num_written<<1) + 3]= reg_data;
00785 num_written++;
00786 }
00787 }
00788 } else if ((reg_addr>=0) && (((reg_addr & 0xffff) < (sizeof (struct framepars_t) >>2)) || ( (reg_addr & 0xff00) == 0xff00 ) )) {
00789 write_data[(num_written<<1) + 2]= reg_addr | flags;
00790 write_data[(num_written<<1) + 3]= reg_data;
00791 num_written++;
00792 }
00793 }
00794 }
00795 }
00796 if (num_written) {
00797 long rslt=write(ELPHEL_G(fd_fparmsall), write_data, (num_written+1)<<3);
00798 efree(write_data);
00799 if (rslt<0) RETURN_LONG(-errno);
00800 num_written=(rslt>>3) -1 ;
00801 }
00803 RETURN_LONG(frame);
00804 }
00805
00814 int gamma_calc (double gamma, double black, unsigned short * gtable) {
00815 int i;
00816 double x, black256,k;
00817 int ig;
00818 black256=black*256.0;
00819 if (k>=1.0) k= k/256.0 ;
00820 if (k>0.99) k=0.99;
00821 k=1.0/(256.0-black256);
00822 if (!gtable) return -1;
00824 if (gamma < 0.13) gamma=0.13;
00825 if (gamma >10.0) gamma=10.0;
00826 for (i=0; i<257; i++) {
00827 x=k*(i-black256);
00828 if (x < 0.0 ) x=0.0;
00829 ig= 0.5+65535.0*pow(x,gamma);
00830 if (ig > 0xffff) ig=0xffff;
00831 gtable[i]=ig;
00832 }
00833 return 0;
00834 }
00835
00844 PHP_FUNCTION(elphel_gamma_add)
00845 {
00846 unsigned short data_to_write[260];
00847 double gamma,black;
00848 int igamma, iblack, hash16;
00849 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &gamma, &black ) == FAILURE) {
00850 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong arguments");
00851 RETURN_NULL ();
00852 }
00853 igamma=100*gamma+0.5;
00854 if (igamma < 0) igamma= 0;
00855 if (igamma > 255) igamma=255;
00856 gamma=0.01*igamma;
00857 iblack= (black>=1.0)?black:(256*black+0.5);
00858 if (iblack < 0) iblack= 0;
00859 if (iblack > 254) iblack=254;
00860 black= (1.0/256.0) * iblack;
00861 hash16= igamma | (iblack<<8);
00862 data_to_write[0]= GAMMA_SCLALE_1;
00863 data_to_write[1]= hash16;
00866 data_to_write[2]=0;
00867 gamma_calc (gamma, black, &data_to_write[3]);
00868 long rslt=write(ELPHEL_G(fd_gamma_cache), data_to_write, sizeof(data_to_write));
00869 if (rslt<0) {
00870 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Write to fd_gamma_cache returned errno=%d",errno);
00871 RETURN_LONG(-errno);
00872 }
00873 RETURN_LONG (hash16);
00874 }
00875
00889 PHP_FUNCTION(elphel_gamma_add_custom)
00890 {
00891 unsigned short data_to_write[260];
00892 long hash16;
00893 int i,d;
00894 zval *arr, **data;
00895 HashTable *arr_hash;
00896 long array_count;
00897
00898 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la", &hash16, &arr ) == FAILURE) {
00899 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong arguments");
00900 RETURN_LONG (-998);
00901 }
00902 arr_hash = Z_ARRVAL_P(arr);
00903 array_count = zend_hash_num_elements(arr_hash);
00904 if (array_count != 257) {
00905 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong array length (should be 257) - %d",array_count);
00906 RETURN_LONG (-999);
00907 }
00908 hash16 &= 0xffff;
00909 data_to_write[0]= GAMMA_SCLALE_1;
00910 data_to_write[1]= hash16;
00913 data_to_write[2]=0;
00915 for (i=0; i<257; i++) {
00916 if (zend_hash_index_find(arr_hash, i, (void**)&data) == FAILURE) {
00917 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Missing array element [%d]",i);
00918 RETURN_LONG(-i-1000);
00919 }
00920 switch (Z_TYPE_PP(data)) {
00921 case IS_DOUBLE:
00922 d=Z_DVAL_PP(data);
00923 break;
00924 case IS_LONG:
00925 d=(1.0/255)* Z_LVAL_PP(data);
00926 default:
00927 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Non-numeric array element [%d]",i);
00928 RETURN_LONG(-i-2000);
00929 }
00930 if (d<0) d=0.0;
00931 if (d>1.0) d=1.0;
00932 data_to_write[i+3]=d*65535.0;
00933 }
00934 long rslt=write(ELPHEL_G(fd_gamma_cache), data_to_write, sizeof(data_to_write));
00935 if (rslt<0) {
00936 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Write to fd_gamma_cache returned errno=%d",errno);
00937 RETURN_LONG(-errno);
00938 }
00939 RETURN_LONG (hash16);
00940 }
00941
00955 PHP_FUNCTION(elphel_gamma_get)
00956 {
00957
00958 unsigned short gtable[257];
00959 unsigned short data_to_write[3];
00960 long hash16;
00961 long raw=0;
00962 zval *zscale=NULL;
00963 int iscale=GAMMA_SCLALE_1;
00964 int gamma_cache_index;
00965 int i;
00966 double gk=1.0/65535.0;
00967 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|zl", &hash16, &zscale,&raw) == FAILURE) {
00968 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong arguments");
00969 RETURN_LONG (-998);
00970 }
00971 if (zscale) {
00972 switch (Z_TYPE_P(zscale)) {
00973 case IS_DOUBLE:
00974 iscale=(GAMMA_SCLALE_1 * Z_DVAL_P(zscale) +0.5);
00975 break;
00976 case IS_LONG:
00977 iscale = Z_LVAL_P(zscale);
00978 break;
00979 default:
00980 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong scale type");
00981 }
00982 }
00983 if (iscale < 0) iscale=0;
00984 if (iscale > 0xffff) iscale=0xffff;
00986 data_to_write[0]= iscale;
00987 data_to_write[1]= hash16;
00990 data_to_write[2]=0;
00991 long rslt=write(ELPHEL_G(fd_gamma_cache), data_to_write, sizeof(data_to_write));
00992 if (rslt<0) {
00993
00994 RETURN_LONG(-errno);
00995 }
00996 gamma_cache_index= lseek(ELPHEL_G(fd_gamma_cache), 0, SEEK_CUR);
00997 if (!gamma_cache_index) {
00998 RETURN_LONG (-997);
00999 }
01001 memcpy(gtable, &(((struct gamma_stuct_t *) ELPHEL_G(gamma_cache))[gamma_cache_index].direct[0]),sizeof(gtable));
01002 if (lseek(ELPHEL_G(fd_gamma_cache), LSEEK_GAMMA_ISCURRENT, SEEK_END)<=0) {
01003 RETURN_LONG (-996);
01004 }
01006 array_init(return_value);
01007 if (raw) for (i=0;i<257;i++) add_next_index_long (return_value, gtable[i]);
01008 else for (i=0;i<257;i++) add_next_index_double(return_value, gk*gtable[i]);
01010 }
01011
01023 PHP_FUNCTION(elphel_gamma_get_index)
01024 {
01025 unsigned short data_to_write[3];
01026 long hash16;
01027 zval *zscale=NULL;
01028 int iscale=GAMMA_SCLALE_1;
01029 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &hash16, &zscale) == FAILURE) {
01030 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong arguments");
01031 RETURN_LONG (-998);
01032 }
01033 if (zscale) {
01034 switch (Z_TYPE_P(zscale)) {
01035 case IS_DOUBLE:
01036 iscale=(GAMMA_SCLALE_1 * Z_DVAL_P(zscale) +0.5);
01037 break;
01038 case IS_LONG:
01039 iscale = Z_LVAL_P(zscale);
01040 break;
01041 default:
01042 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong scale type");
01043 }
01044 }
01045 if (iscale < 0) iscale=0;
01046 if (iscale > 0xffff) iscale=0xffff;
01048 data_to_write[0]= iscale;
01049 data_to_write[1]= hash16;
01052 data_to_write[2]=0;
01053 long rslt=write(ELPHEL_G(fd_gamma_cache), data_to_write, sizeof(data_to_write));
01054 if (rslt<0) {
01055
01056 RETURN_LONG(-errno);
01057 }
01058 RETURN_LONG (lseek(ELPHEL_G(fd_gamma_cache), 0, SEEK_CUR));
01059 }
01060
01061
01062
01063
01071 PHP_FUNCTION(elphel_gamma_get_raw)
01072 {
01073 char * packed_gamma_structure;
01074 long index;
01075 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
01076 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong index");
01077 RETURN_NULL ();
01078 }
01079 if (index >= GAMMA_CACHE_NUMBER) {
01080 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong index (%d >= %d)",index, (int) GAMMA_CACHE_NUMBER);
01081 RETURN_NULL ();
01082 }
01083 packed_gamma_structure= (char*) emalloc (sizeof(struct gamma_stuct_t));
01084 if (packed_gamma_structure) {
01086 memcpy(packed_gamma_structure, &(((struct gamma_stuct_t *) ELPHEL_G(gamma_cache))[index]),sizeof(struct gamma_stuct_t));
01087 if (index==0) {
01088 packed_gamma_structure[sizeof(struct gamma_stuct_t)-1]=0xff;
01089 }
01090 RETURN_STRINGL (packed_gamma_structure, sizeof(struct gamma_stuct_t), 0);
01091 }
01092 php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc error");
01093 RETURN_NULL ();
01094 }
01095
01098
01106 PHP_FUNCTION(elphel_histogram_get_raw)
01107 {
01108 char * packed_histogram_structure;
01109 long frame=-1;
01110 long needed=0xfff;
01111 long index;
01112 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &needed,&frame) == FAILURE) {
01113 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong index");
01114 RETURN_NULL ();
01115 }
01116 if (frame<0) frame=lseek((int) ELPHEL_G( fd_fparmsall), 0, SEEK_CUR );
01117 needed &= 0xfff;
01118 lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_WAIT_C, SEEK_END);
01119 lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_NEEDED + (needed & 0xff0), SEEK_END);
01120 index=lseek(ELPHEL_G(fd_histogram_cache), frame, SEEK_SET);
01121 if (index <0) {
01122 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Requested histograms are not available (frame=%d, needed=0x%x)",frame,needed);
01123 RETURN_NULL ();
01124 }
01125 if (index >= HISTOGRAM_CACHE_NUMBER) {
01126 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: frame=%d, index=%d",frame, index);
01127 RETURN_NULL ();
01128 }
01129
01130 packed_histogram_structure= (char*) emalloc (sizeof(struct histogram_stuct_t));
01131 if (!packed_histogram_structure) {
01132 php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc error");
01133 RETURN_NULL ();
01134 }
01136 memcpy(packed_histogram_structure, &(((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[index]),sizeof(struct histogram_stuct_t));
01137 RETURN_STRINGL (packed_histogram_structure, sizeof(struct histogram_stuct_t), 0);
01138 }
01139
01153 PHP_FUNCTION(elphel_histogram_get)
01154 {
01155 struct histogram_stuct_t * frame_histogram_structure;
01156 long frame=-1;
01157 long needed=0xfff;
01158 long index;
01159 int i;
01160 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &needed, &frame) == FAILURE) {
01161 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong index");
01162 RETURN_NULL ();
01163 }
01164 needed &= 0xfff;
01165 lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_WAIT_C, SEEK_END);
01166 lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_NEEDED + (needed & 0xff0), SEEK_END);
01167 index=lseek(ELPHEL_G(fd_histogram_cache), frame, SEEK_SET);
01168 if (index <0) {
01169 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Requested histograms are not available (frame=%d, needed=0x%x)",frame,needed);
01170 RETURN_NULL ();
01171 }
01172 if (index >= HISTOGRAM_CACHE_NUMBER) {
01173 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: frame=%d, index=%d",frame, index);
01174 RETURN_NULL ();
01175 }
01176
01177 frame_histogram_structure= (struct histogram_stuct_t *) emalloc (sizeof(struct histogram_stuct_t));
01178 if (!frame_histogram_structure) {
01179 php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc error");
01180 RETURN_NULL ();
01181 }
01183 memcpy((void *) frame_histogram_structure, &(((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[index]),sizeof(struct histogram_stuct_t));
01185 if (frame != ((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[index].frame ) {
01186 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Frame changed while retrieving histograms (frame requested=%d, current=%d)",
01187 frame, (int)((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[index].frame);
01188 RETURN_NULL ();
01189 efree (frame_histogram_structure);
01190 }
01192 if ((needed & frame_histogram_structure->valid ) != needed) {
01193 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not all the requested tables are available (frame=%d needed=0x%x, valid=0x%x)",
01194 frame, needed, frame_histogram_structure->valid);
01195 RETURN_NULL ();
01196 efree (frame_histogram_structure);
01197 }
01199
01200 array_init(return_value);
01201 if (needed & 0x001) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->hist_r[i]);
01202 if (needed & 0x002) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->hist_g[i]);
01203 if (needed & 0x004) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->hist_gb[i]);
01204 if (needed & 0x008) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->hist_b[i]);
01205
01206 if (needed & 0x010) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->cumul_hist_r[i]);
01207 if (needed & 0x020) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->cumul_hist_g[i]);
01208 if (needed & 0x040) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->cumul_hist_gb[i]);
01209 if (needed & 0x080) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->cumul_hist_b[i]);
01210
01211 if (needed & 0x100) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->percentile_r[i]);
01212 if (needed & 0x200) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->percentile_g[i]);
01213 if (needed & 0x400) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->percentile_gb[i]);
01214 if (needed & 0x800) for (i=0;i<256;i++) add_next_index_long (return_value, frame_histogram_structure->percentile_b[i]);
01215
01216 efree (frame_histogram_structure);
01218 }
01219
01220
01222 long createExifDirectory (int rebuild) {
01223 int indx;
01224 long numfields=0;
01225 struct exif_dir_table_t dir_table_entry;
01227 int exif_this_size=lseek((int) ELPHEL_G(fd_exifdir),1,SEEK_END);
01228
01229 if ((ELPHEL_G(exif_size) == exif_this_size) && !rebuild) return 0;
01230 ELPHEL_G(exif_size) = exif_this_size;
01231
01232 for (indx=0; indx<ExifKmlNumber; indx++) ELPHEL_G(exif_dir)[indx].ltag=0;
01233 while (read((int) ELPHEL_G(fd_exifdir), &dir_table_entry, sizeof(dir_table_entry))>0) {
01234 switch (dir_table_entry.ltag) {
01235 case Exif_Image_ImageDescription: indx= Exif_Image_ImageDescription_Index; break;
01236 case Exif_Image_FrameNumber: indx= Exif_Image_FrameNumber_Index; break;
01237 case Exif_Photo_DateTimeOriginal: indx= Exif_Photo_DateTimeOriginal_Index; break;
01238 case Exif_Photo_SubSecTimeOriginal: indx= Exif_Photo_SubSecTimeOriginal_Index; break;
01239 case Exif_Photo_ExposureTime: indx= Exif_Photo_ExposureTime_Index; break;
01240 case Exif_GPSInfo_GPSLatitudeRef: indx= Exif_GPSInfo_GPSLatitudeRef_Index; break;
01241 case Exif_GPSInfo_GPSLatitude: indx= Exif_GPSInfo_GPSLatitude_Index ; break;
01242 case Exif_GPSInfo_GPSLongitudeRef: indx= Exif_GPSInfo_GPSLongitudeRef_Index ; break;
01243 case Exif_GPSInfo_GPSLongitude: indx= Exif_GPSInfo_GPSLongitude_Index; break;
01244 case Exif_GPSInfo_GPSAltitudeRef: indx= Exif_GPSInfo_GPSAltitudeRef_Index; break;
01245 case Exif_GPSInfo_GPSAltitude: indx= Exif_GPSInfo_GPSAltitude_Index; break;
01246 case Exif_GPSInfo_GPSTimeStamp: indx= Exif_GPSInfo_GPSTimeStamp_Index; break;
01247 case Exif_GPSInfo_GPSDateStamp: indx= Exif_GPSInfo_GPSDateStamp_Index; break;
01248 case Exif_GPSInfo_GPSMeasureMode: indx= Exif_GPSInfo_GPSMeasureMode_Index; break;
01249 case Exif_GPSInfo_CompassDirectionRef: indx= Exif_GPSInfo_CompassDirectionRef_Index; break;
01250 case Exif_GPSInfo_CompassDirection: indx= Exif_GPSInfo_CompassDirection_Index; break;
01251 case Exif_GPSInfo_CompassPitchRef: indx= Exif_GPSInfo_CompassPitchRef_Index; break;
01252 case Exif_GPSInfo_CompassPitch: indx= Exif_GPSInfo_CompassPitch_Index; break;
01253 case Exif_GPSInfo_CompassRollRef: indx= Exif_GPSInfo_CompassRollRef_Index; break;
01254 case Exif_GPSInfo_CompassRoll: indx= Exif_GPSInfo_CompassRoll_Index; break;
01255 default: indx=-1;
01256 }
01257 if (indx>=0) {
01258 memcpy(&(ELPHEL_G(exif_dir)[indx]),&dir_table_entry,sizeof(dir_table_entry));
01259 numfields++;
01260 }
01261 }
01262 return numfields;
01263 }
01264
01265
01267 PHP_FUNCTION(elphel_get_circbuf_pointers) {
01268 char * ccam_dma_buf_char= (char *) ELPHEL_G( ccam_dma_buf);
01269 long second=0;
01270 long p,frameParamPointer;
01271 long buff_size=lseek(ELPHEL_G( fd_circ),0,SEEK_END);
01272 long meta_index,displacementInPage,exifPageStart,frame_be;
01273
01274 zval *image_pointers;
01275 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &second) == FAILURE) {
01276 RETURN_NULL();
01277 }
01279 createExifDirectory(0);
01280 if (ELPHEL_G(exif_dir)[Exif_Image_FrameNumber_Index].ltag==Exif_Image_FrameNumber)
01281 displacementInPage=ELPHEL_G(exif_dir)[Exif_Image_FrameNumber_Index].dst;
01282 else
01283 displacementInPage=-1;
01284 p=lseek((int) ELPHEL_G( fd_circ), second? LSEEK_CIRC_SCND: LSEEK_CIRC_FIRST, SEEK_END );
01285 if (p<0) RETURN_NULL();
01286 array_init(return_value);
01287 while (p>=0) {
01288 frameParamPointer=p-32;
01289 if (frameParamPointer<0) frameParamPointer+=buff_size;
01290 ALLOC_INIT_ZVAL(image_pointers);
01291 array_init(image_pointers);
01292 add_assoc_long(image_pointers, "circbuf_pointer", p);
01293
01294 meta_index=((struct interframe_params_t *) &ccam_dma_buf_char[frameParamPointer])->meta_index;
01295 add_assoc_long(image_pointers, "exif_pointer", meta_index);
01297 if (displacementInPage>=0){
01298 exifPageStart=lseek ((int) ELPHEL_G(fd_exif), meta_index, SEEK_END);
01299 lseek (ELPHEL_G(fd_exif), exifPageStart+displacementInPage, SEEK_SET);
01300 read(ELPHEL_G(fd_exif), &frame_be, 4);
01302 add_assoc_long(image_pointers, "frame", (long) __cpu_to_be32(frame_be));
01303 }
01304 add_next_index_zval(return_value, image_pointers);
01306 p=lseek((int) ELPHEL_G( fd_circ), LSEEK_CIRC_NEXT, SEEK_END );
01307 p=lseek((int) ELPHEL_G( fd_circ), LSEEK_CIRC_READY, SEEK_END );
01308
01309 }
01310 }
01311
01312
01313 PHP_FUNCTION(elphel_get_interframe_meta)
01314 {
01315 char * ccam_dma_buf_char= (char *) ELPHEL_G( ccam_dma_buf);
01316 struct interframe_params_t frame_params;
01317 long circbuf_pointer=-1;
01318 long frameParamPointer,jpeg_len,timestamp_start;
01319
01320 long circbuf_size=ELPHEL_G(ccam_dma_buf_len);
01321 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &circbuf_pointer) == FAILURE) {
01322 RETURN_NULL();
01323 }
01324 frameParamPointer=circbuf_pointer-32;
01325 if (frameParamPointer < 0) frameParamPointer+=circbuf_size;
01326 memcpy (&frame_params, &ccam_dma_buf_char[frameParamPointer],32);
01327 jpeg_len=frame_params.frame_length;
01329 timestamp_start=circbuf_pointer+((jpeg_len+CCAM_MMAP_META+3) & (~0x1f)) + 32 - CCAM_MMAP_META_SEC;
01330 if (timestamp_start >= circbuf_size) timestamp_start-=circbuf_size;
01331 memcpy (&(frame_params.timestamp_sec), &ccam_dma_buf_char[timestamp_start],8);
01332 if (frame_params.signffff !=0xffff) {
01333 RETURN_NULL();
01334 }
01335 array_init(return_value);
01337 add_assoc_long(return_value, "hash32_r", frame_params.hash32_r);
01338 add_assoc_long(return_value, "hash32_g", frame_params.hash32_g);
01339 add_assoc_long(return_value, "hash32_gb", frame_params.hash32_gb);
01340 add_assoc_long(return_value, "hash32_b", frame_params.hash32_b);
01345 add_assoc_long(return_value, "quality2", frame_params.quality2);
01346 add_assoc_long(return_value, "color", frame_params.color);
01347 add_assoc_long(return_value, "byrshift", frame_params.byrshift);
01348 add_assoc_long(return_value, "width", frame_params.width);
01349 add_assoc_long(return_value, "height", frame_params.height);
01350 add_assoc_long(return_value, "meta_index", frame_params.meta_index);
01351 add_assoc_long(return_value, "timestamp_sec", frame_params.timestamp_sec);
01352 add_assoc_long(return_value, "timestamp_usec",frame_params.timestamp_usec);
01353 }
01354
01355
01356 #define saferead255(f,d,l) read(f,d,((l)<256)?(l):255)
01357 PHP_FUNCTION(elphel_get_exif_elphel)
01358 {
01359 long rational3[6];
01360 long exif_page_start;
01361 char *key;
01362 long indx;
01363 char val[256];
01364 long exif_page=0;
01365 int hours=0, minutes=0;
01366 double seconds=0.0;
01367 double longitude=0.0, latitude=0.0, altitude=0.0, heading=0.0, roll=0.0, pitch=0.0, exposure=0.0;
01368 val[255]='\0';
01369 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &exif_page) == FAILURE) {
01370 RETURN_NULL();
01371 }
01372
01373 createExifDirectory(0);
01374 if (exif_page) exif_page_start=lseek ((int) ELPHEL_G(fd_exif), exif_page, SEEK_END);
01375 else exif_page_start=lseek ((int) ELPHEL_G(fd_exif), 0, SEEK_SET);
01376 if (exif_page_start<0) RETURN_NULL();
01377 array_init(return_value);
01378
01379
01381
01382 if (ELPHEL_G(exif_dir)[Exif_Image_ImageDescription_Index].ltag==Exif_Image_ImageDescription) {
01383 lseek (ELPHEL_G(fd_exif),
01384 exif_page_start+ELPHEL_G(exif_dir)[Exif_Image_ImageDescription_Index].dst,
01385 SEEK_SET);
01386 saferead255(ELPHEL_G(fd_exif), val, ELPHEL_G(exif_dir)[Exif_Image_ImageDescription_Index].len);
01387 add_assoc_string(return_value, "ImageDescription", val, 1);
01388 }
01390 if (ELPHEL_G(exif_dir)[Exif_Image_FrameNumber_Index].ltag==Exif_Image_FrameNumber) {
01391 lseek (ELPHEL_G(fd_exif),
01392 exif_page_start+ELPHEL_G(exif_dir)[Exif_Image_FrameNumber_Index].dst,
01393 SEEK_SET);
01394 read(ELPHEL_G(fd_exif), rational3, 4);
01395 sprintf (val,"%ld", (long) __cpu_to_be32( rational3[0]));
01396 add_assoc_string(return_value, "FrameNumber", val, 1);
01397 }
01398
01400 if (ELPHEL_G(exif_dir)[Exif_Photo_DateTimeOriginal_Index].ltag==Exif_Photo_DateTimeOriginal) {
01401 lseek (ELPHEL_G(fd_exif),
01402 exif_page_start+ELPHEL_G(exif_dir)[Exif_Photo_DateTimeOriginal_Index].dst,
01403 SEEK_SET);
01404 read(ELPHEL_G(fd_exif), val, 19);
01405 val[19]='\0';
01406 if (ELPHEL_G(exif_dir)[Exif_Photo_SubSecTimeOriginal_Index].ltag==Exif_Photo_SubSecTimeOriginal) {
01407 val[19]='.';
01408 lseek (ELPHEL_G(fd_exif),
01409 exif_page_start+ELPHEL_G(exif_dir)[Exif_Photo_SubSecTimeOriginal_Index].dst,
01410 SEEK_SET);
01411 read(ELPHEL_G(fd_exif), &val[20], 7);
01412 val[27]='\0';
01413 }
01414 add_assoc_string(return_value, "DateTimeOriginal", val, 1);
01415 }
01416
01418 if (ELPHEL_G(exif_dir)[Exif_Photo_ExposureTime_Index].ltag==Exif_Photo_ExposureTime) {
01419 lseek (ELPHEL_G(fd_exif),
01420 exif_page_start+ELPHEL_G(exif_dir)[Exif_Photo_ExposureTime_Index].dst,
01421 SEEK_SET);
01422 read(ELPHEL_G(fd_exif), rational3, 8);
01423 exposure=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
01424 sprintf (val,"%f",exposure);
01425 add_assoc_string(return_value, "ExposureTime", val, 1);
01426 }
01427
01428
01430 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSMeasureMode_Index].ltag==Exif_GPSInfo_GPSMeasureMode) {
01431 lseek (ELPHEL_G(fd_exif),
01432 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSMeasureMode_Index].dst,
01433 SEEK_SET);
01434 read(ELPHEL_G(fd_exif), val, 1);
01435 add_assoc_stringl(return_value, "GPSMeasureMode", val, 1, 1);
01436 }
01437
01439 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSDateStamp_Index].ltag==Exif_GPSInfo_GPSDateStamp) {
01440 lseek (ELPHEL_G(fd_exif),
01441 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSDateStamp_Index].dst,
01442 SEEK_SET);
01443 read(ELPHEL_G(fd_exif), val, 10);
01444 val[10]='\0';
01445 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSTimeStamp_Index].ltag==Exif_GPSInfo_GPSTimeStamp) {
01446 lseek (ELPHEL_G(fd_exif),
01447 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSTimeStamp_Index].dst,
01448 SEEK_SET);
01449 read(ELPHEL_G(fd_exif), rational3, 24);
01450 hours= __cpu_to_be32( rational3[0]);
01451 minutes= __cpu_to_be32( rational3[2]);
01452 seconds= (1.0*(__cpu_to_be32( rational3[4])+1))/__cpu_to_be32( rational3[5]);
01453 sprintf (&val[10]," %02d:%02d:%05.2f",hours,minutes,seconds);
01454 }
01455 add_assoc_string(return_value, "GPSDateTime", val, 1);
01456 }
01457
01460 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitude_Index].ltag==Exif_GPSInfo_GPSLongitude) {
01461 lseek (ELPHEL_G(fd_exif),
01462 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitude_Index].dst,
01463 SEEK_SET);
01464 read(ELPHEL_G(fd_exif), rational3, 24);
01465 longitude=__cpu_to_be32( rational3[0])/(1.0*__cpu_to_be32( rational3[1])) + __cpu_to_be32( rational3[2])/(60.0*__cpu_to_be32( rational3[3]));
01466 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitudeRef_Index].ltag==Exif_GPSInfo_GPSLongitudeRef) {
01467 lseek (ELPHEL_G(fd_exif),
01468 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitudeRef_Index].dst,
01469 SEEK_SET);
01470 read(ELPHEL_G(fd_exif), val, 1);
01471 if (val[0]!= 'E') longitude=-longitude;
01472 }
01473 sprintf (val,"%f",longitude);
01474 add_assoc_string(return_value, "GPSLongitude", val, 1);
01475 }
01477 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitude_Index].ltag==Exif_GPSInfo_GPSLatitude) {
01478 lseek (ELPHEL_G(fd_exif),
01479 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitude_Index].dst,
01480 SEEK_SET);
01481 read(ELPHEL_G(fd_exif), rational3, 24);
01482 latitude=__cpu_to_be32( rational3[0])/(1.0*__cpu_to_be32( rational3[1])) + __cpu_to_be32( rational3[2])/(60.0*__cpu_to_be32( rational3[3]));
01483 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitudeRef_Index].ltag==Exif_GPSInfo_GPSLatitudeRef) {
01484 lseek (ELPHEL_G(fd_exif),
01485 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitudeRef_Index].dst,
01486 SEEK_SET);
01487 read(ELPHEL_G(fd_exif), val, 1);
01488 if (val[0] != 'N') latitude=-latitude;
01489 }
01490 sprintf (val,"%f",latitude);
01491 add_assoc_string(return_value, "GPSLatitude", val, 1);
01492 }
01494 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitude_Index].ltag==Exif_GPSInfo_GPSAltitude) {
01495 lseek (ELPHEL_G(fd_exif),
01496 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitude_Index].dst,
01497 SEEK_SET);
01498 read(ELPHEL_G(fd_exif), rational3, 8);
01499 altitude=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
01500
01501 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitudeRef_Index].ltag==Exif_GPSInfo_GPSAltitudeRef) {
01502 lseek (ELPHEL_G(fd_exif),
01503 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitudeRef_Index].dst,
01504 SEEK_SET);
01505 read(ELPHEL_G(fd_exif), val, 1);
01506 if (val[0] != '\0') altitude=-altitude;
01507 }
01508 sprintf (val,"%f",altitude);
01509 add_assoc_string(return_value, "GPSAltitude", val, 1);
01510 }
01512 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassDirection_Index].ltag==Exif_GPSInfo_CompassDirection) {
01513 lseek (ELPHEL_G(fd_exif),
01514 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassDirection_Index].dst,
01515 SEEK_SET);
01516 read(ELPHEL_G(fd_exif), rational3, 8);
01517 heading=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
01518 sprintf (val,"%f",heading);
01519 add_assoc_string(return_value, "CompassDirection", val, 1);
01520 }
01523 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRoll_Index].ltag==Exif_GPSInfo_CompassRoll) {
01524 lseek (ELPHEL_G(fd_exif),
01525 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRoll_Index].dst,
01526 SEEK_SET);
01527 read(ELPHEL_G(fd_exif), rational3, 8);
01528 roll=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
01529
01530 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRollRef_Index].ltag==Exif_GPSInfo_CompassRollRef) {
01531 lseek (ELPHEL_G(fd_exif),
01532 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRollRef_Index].dst,
01533 SEEK_SET);
01534 read(ELPHEL_G(fd_exif), val, 1);
01535 if (val[0] != EXIF_COMPASS_ROLL_ASCII[0]) roll=-roll;
01536 }
01537 sprintf (val,"%f",roll);
01538 add_assoc_string(return_value, "CompassRoll", val, 1);
01539 }
01540
01542 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitch_Index].ltag==Exif_GPSInfo_CompassPitch) {
01543 lseek (ELPHEL_G(fd_exif),
01544 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitch_Index].dst,
01545 SEEK_SET);
01546 read(ELPHEL_G(fd_exif), rational3, 8);
01547 pitch=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
01548
01549 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitchRef_Index].ltag==Exif_GPSInfo_CompassPitchRef) {
01550 lseek (ELPHEL_G(fd_exif),
01551 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitchRef_Index].dst,
01552 SEEK_SET);
01553 read(ELPHEL_G(fd_exif), val, 1);
01554 if (val[0] != EXIF_COMPASS_PITCH_ASCII[0]) pitch=-pitch;
01555 }
01556 sprintf (val,"%f",pitch);
01557 add_assoc_string(return_value, "CompassPitch", val, 1);
01558 }
01559
01560 }
01561
01562 PHP_FUNCTION(elphel_update_exif) {
01563 RETURN_LONG(createExifDirectory(1));
01564 }
01565
01566
01567 PHP_FUNCTION(elphel_get_exif_field)
01568 {
01569 long exif_page=0;
01570 long ltag;
01571 struct exif_dir_table_t dir_table_entry;
01572 char * rslt;
01573 int found=0;
01574
01575 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", <ag, &exif_page) == FAILURE) {
01576 RETURN_NULL();
01577 }
01578
01579 lseek ((int) ELPHEL_G(fd_exifdir), 0, SEEK_SET);
01580 while (read((int) ELPHEL_G(fd_exifdir), &dir_table_entry, sizeof(dir_table_entry))>0) {
01581 if (dir_table_entry.ltag==ltag) {
01582 found=1;
01583 break;
01584 }
01585 }
01586 if (!found) RETURN_NULL();
01587
01588 if (exif_page) found= lseek ((int) ELPHEL_G(fd_exif), exif_page, SEEK_END);
01589 else found= lseek ((int) ELPHEL_G(fd_exif), 0, SEEK_SET);
01590 if (found<0) RETURN_NULL();
01591
01592 lseek ((int) ELPHEL_G(fd_exif), dir_table_entry.dst, SEEK_CUR);
01593 rslt=emalloc(dir_table_entry.len);
01594 read((int) ELPHEL_G(fd_exif), rslt, dir_table_entry.len);
01595 RETURN_STRINGL(rslt,dir_table_entry.len,0);
01596 }
01597
01598
01599
01600 PHP_FUNCTION(elphel_set_exif_field)
01601 {
01602
01603 long ltag;
01604 struct exif_dir_table_t dir_table_entry;
01605 char * value;
01606 int value_length;
01607 int found=0;
01608
01609 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", <ag, &value,&value_length) == FAILURE) {
01610 RETURN_NULL();
01611 }
01612
01613 lseek ((int) ELPHEL_G(fd_exifdir), 0, SEEK_SET);
01614 while (read((int) ELPHEL_G(fd_exifdir), &dir_table_entry, sizeof(dir_table_entry))>0) {
01615 if (dir_table_entry.ltag==ltag) {
01616 found=1;
01617 break;
01618 }
01619 }
01620 if (!found) RETURN_NULL();
01621 lseek ((int) ELPHEL_G(fd_exifmeta), dir_table_entry.src, SEEK_SET);
01622 if (value_length>dir_table_entry.len) value_length = dir_table_entry.len;
01624
01625 long rslt=write(ELPHEL_G(fd_exifmeta), value, value_length);
01626 if (rslt<0) rslt =-errno;
01627 RETURN_LONG(rslt);
01628 }
01629
01630
01632 PHP_FUNCTION(elphel_wait_frame)
01633 {
01634 lseek((int) ELPHEL_G( fd_circ), LSEEK_CIRC_TOWP, SEEK_END );
01635 lseek((int) ELPHEL_G( fd_circ), LSEEK_CIRC_WAIT, SEEK_END );
01636 RETURN_NULL();
01637 }
01638
01648 PHP_FUNCTION(elphel_gamma)
01649 {
01650 long color;
01651 long frame =-1;
01652 double sensorLevel;
01653 int indx,gamma_index;
01654 unsigned long hash32;
01655 unsigned long write_data[2];
01656 int rslt;
01657 unsigned short * gamma_direct;
01658 long lsensorLevel;
01659 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld|l", &color, &sensorLevel, &frame ) == FAILURE) {
01660 RETURN_LONG (-1);
01661 }
01662 if ((color <0) || (color > 3)) RETURN_LONG (-1);
01663 if (frame <0) {
01664 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME)-1;
01665 }
01666
01667 hash32=get_imageParamsThat (P_GTAB_R+color, frame);
01668
01669 if (hash32 == 0xffffffff) RETURN_LONG (-1);
01671 write_data[0]=hash32;
01672 write_data[1]=0;
01673 rslt=write(ELPHEL_G(fd_gamma_cache), write_data, 6);
01674
01675
01676 if (rslt<= 0) {
01677 RETURN_LONG (-1);
01678 }
01679 gamma_index=lseek(ELPHEL_G(fd_gamma_cache), 0, SEEK_CUR);
01680
01681
01682 if (gamma_index <= 0) {
01683 RETURN_LONG (-2);
01684 }
01685 gamma_direct= &(((struct gamma_stuct_t *) ELPHEL_G(gamma_cache))[gamma_index].direct[0]);
01686
01687 lsensorLevel=0x10000*sensorLevel;
01688
01689
01690 if (lsensorLevel <0) RETURN_LONG (-1);
01691 if (lsensorLevel >0xffff) lsensorLevel=0xffff;
01692
01693
01694
01695 RETURN_DOUBLE ((1.0/(1<<24))* ((((long) gamma_direct[lsensorLevel>>8])<<8) +
01696 (((long) gamma_direct[(lsensorLevel>>8)+1] - ((long) gamma_direct[lsensorLevel>>8]))*(lsensorLevel & 0xff))));
01697 }
01698
01708 PHP_FUNCTION(elphel_reverse_gamma)
01709 {
01710 long color;
01711 long frame=-1;
01712 double gammaLevel;
01713 int indx,gamma_index;
01714 unsigned long hash32;
01715 unsigned long write_data[2];
01716 int rslt;
01717 unsigned short * gamma_direct;
01718 unsigned char * gamma_reverse;
01719 long lgammaLevel, sensor_high8,delta, sensor_full;
01720
01721 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld|l", &color, &gammaLevel, &frame ) == FAILURE) {
01722 RETURN_LONG (-1);
01723 }
01724 if ((color <0) || (color > 3)) RETURN_LONG (-1);
01725 if (frame <0) {
01726 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME)-1;
01727 }
01728 hash32=get_imageParamsThat (P_GTAB_R+color, frame);
01729 if (hash32 == 0xffffffff) RETURN_LONG (-1);
01731 write_data[0]=hash32;
01732 write_data[1]= GAMMA_MODE_NEED_REVERSE;
01733 rslt=write(ELPHEL_G(fd_gamma_cache), write_data, 6);
01734 if (rslt<= 0) {
01735 RETURN_LONG (-1);
01736 }
01737 gamma_index=lseek(ELPHEL_G(fd_gamma_cache), 0, SEEK_CUR);
01738 if (gamma_index <= 0) {
01739 RETURN_LONG (-2);
01740 }
01741 gamma_direct= &(((struct gamma_stuct_t *) ELPHEL_G(gamma_cache))[gamma_index].direct[0]);
01742
01743 gamma_reverse=&(((struct gamma_stuct_t *) ELPHEL_G(gamma_cache))[gamma_index].reverse[0]);
01744
01745 lgammaLevel=0x10000*gammaLevel;
01746 if (lgammaLevel <0) RETURN_LONG (-1);
01747 if (lgammaLevel >0xffff) lgammaLevel=0xffff;
01748 sensor_high8=gamma_reverse[lgammaLevel >> 8];
01749 if (sensor_high8>0) sensor_high8--;
01750 while ((sensor_high8>0) && (gamma_direct[sensor_high8] > lgammaLevel)) sensor_high8--;
01751 sensor_high8++;
01752 while ((sensor_high8<255) && (gamma_direct[sensor_high8] <= lgammaLevel)) sensor_high8++;
01753 sensor_high8--;
01754 delta=gamma_direct[sensor_high8+1] - gamma_direct[sensor_high8];
01755 if (delta) {
01756 sensor_full=((lgammaLevel-gamma_direct[sensor_high8]) << 8)/delta;
01757 } else sensor_full=0;
01758 sensor_full += sensor_high8 << 8;
01760 if (sensor_full < 0) sensor_full=0;
01761 else if (sensor_full > 0xffff) sensor_full=0xffff;
01762 RETURN_DOUBLE ((1.0/(1<<16))* sensor_full);
01763 }
01764
01772 int get_histogram_index (long color,long frame, long needreverse) {
01773 long hist_index;
01774 if ((color<0) || (color>4)) return -1;
01775 if (color == COLOR_Y_NUMBER) lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_WAIT_Y, SEEK_END);
01776 else lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_WAIT_C, SEEK_END);
01777 lseek(ELPHEL_G(fd_histogram_cache), LSEEK_HIST_NEEDED + ((1 << color) << (needreverse? 8:4)), SEEK_END);
01778 return lseek(ELPHEL_G(fd_histogram_cache), frame, SEEK_SET);
01779 }
01780
01787 unsigned long get_imageParamsThat (int indx, unsigned long frame) {
01788 int frame_index= frame & PARS_FRAMES_MASK;
01789 int past_index= frame & PASTPARS_SAVE_ENTRIES_MASK;
01790 unsigned long value;
01792 if (((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[P_FRAME] != frame) {
01794 if ((indx < PARS_SAVE_FROM) || (indx >= (PARS_SAVE_FROM+PARS_SAVE_NUM))) return 0xffffffff ;
01795 value=((struct framepars_past_t *) ELPHEL_G(pastPars))[past_index].past_pars[indx-PARS_SAVE_FROM];
01796 if (((struct framepars_past_t *) ELPHEL_G(pastPars))[frame_index].past_pars[P_FRAME-PARS_SAVE_FROM] != frame) {
01797 return 0xffffffff;
01798 }
01799 } else {
01800 value=((struct framepars_t *) ELPHEL_G(framePars))[frame_index].pars[indx];
01801 }
01802 return value;
01803 }
01804
01813 PHP_FUNCTION(elphel_histogram)
01814 {
01815 long frame=-1;
01816 long hist_index;
01817 double dlevel;
01818 long llevel,total_pixels;
01819 unsigned long * hist_cumul;
01820 long hist,color;
01821
01822 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld|l", &color, &dlevel, &frame ) == FAILURE) {
01823 RETURN_LONG (-1);
01824 }
01825 if ((color <0) || (color > 3)) RETURN_LONG (-1);
01826 if (frame <0) {
01827 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME)-1;
01828 }
01829 if (((hist_index=get_histogram_index (color, frame, 0)))<0) RETURN_LONG (-1);
01830 llevel=0x10000*dlevel;
01831 if (llevel< -0.5) RETURN_LONG(-1) ;
01832 if (llevel<0) llevel=0;
01833 else if (llevel>0xffff) llevel=0xffff;
01835 hist_cumul= &(((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[hist_index].cumul_hist[color<<8]);
01836 total_pixels= hist_cumul[255];
01837 hist= (llevel>>8)?hist_cumul[(llevel>>8)-1]:0;
01838 hist +=((hist_cumul[llevel>>8]-hist)*(llevel & 0xff))>>8;
01839 RETURN_DOUBLE(((double) hist)/total_pixels);
01840 }
01841
01851 PHP_FUNCTION(elphel_reverse_histogram)
01852 {
01853 long frame=-1;
01854 long hist_index;
01855 double fraction;
01856 long frac_pixels,total_pixels, frac_256, delta;
01857 unsigned long * hist_cumul;
01858 unsigned char * hist_percentile;
01859
01860 long perc,perc_frac,color;
01861
01862 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld|l", &color, &fraction, &frame ) == FAILURE) {
01863 RETURN_LONG (-1);
01864 }
01865 if ((color <0) || (color > 3)) RETURN_LONG (-1);
01866 if (frame <0) {
01867 frame=ELPHEL_GLOBALPARS(G_THIS_FRAME)-1;
01868 }
01869 if (((hist_index=get_histogram_index (color, frame, 1)))<0) RETURN_LONG (-1);
01871 hist_cumul= &(((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[hist_index].cumul_hist[color<<8]);
01872 hist_percentile=&(((struct histogram_stuct_t *) ELPHEL_G(histogram_cache))[hist_index].percentile[color<<8]);
01873 total_pixels= hist_cumul[255];
01874 frac_pixels=total_pixels*fraction;
01875 if (fraction < -0.5) RETURN_LONG(-1) ;
01876 if (frac_pixels<0) frac_pixels=0;
01877 else if (frac_pixels>=total_pixels) frac_pixels=total_pixels-1;
01878 frac_256=(1.0/256)*fraction;
01879 if (frac_256 > 255) frac_256=255;
01880 perc=hist_percentile[frac_256];
01881 if (perc>0) perc--;
01882 while ((perc>0) && (hist_cumul[perc] > frac_pixels)) perc--;
01883 perc++;
01884 while ((perc<255) && (hist_cumul[perc] <= frac_pixels)) perc++;
01885 perc--;
01886 delta=hist_cumul[perc+1] - hist_cumul[perc];
01887 if (delta) {
01888 perc_frac=((frac_pixels-hist_cumul[perc]) << 8)/delta;
01889 } else perc_frac=0;
01890 perc_frac += perc << 8;
01891 RETURN_DOUBLE((1.0/(1<<16)) * ((double) perc_frac));
01892 }
01893
01894
01895
01897 PHP_FUNCTION(elphel_fpga_read)
01898 {
01899 long addr,data,res;
01900 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
01901 RETURN_NULL();
01902 }
01903 int fd=open("/dev/fpgaio", O_RDONLY);
01904 if (fd<0) {
01905 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/fpgaio");
01906 return ;
01907 }
01908 lseek (fd, addr,SEEK_SET) ;
01909 res=read(fd,&data,4);
01910 close (fd);
01911 if (res<4) {
01912 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not read file %s","/dev/fpgaio");
01913 return ;
01914 }
01915 RETURN_LONG(data);
01916 }
01917
01918 PHP_FUNCTION(elphel_fpga_write)
01919 {
01920 long addr,data,res;
01921 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &addr,&data) == FAILURE) {
01922 RETURN_NULL();
01923 }
01924 int fd=open("/dev/fpgaio", O_RDWR);
01925 if (fd<0) {
01926 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/fpgaio");
01927 return ;
01928 }
01929 lseek (fd, addr,SEEK_SET) ;
01930 res=write(fd,&data,4);
01931 close (fd);
01932 if (res<4) {
01933 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not write to file %s","/dev/fpgaio");
01934 return ;
01935 }
01936 RETURN_NULL();
01937 }
01938
01939
01940
01944 PHP_FUNCTION(elphel_set_fpga_time) {
01945 unsigned long write_data[8]= {FRAMEPARS_SETFRAME, 0,
01946 G_SECONDS, 0,
01947 G_MICROSECONDS, 0,
01948 FRAMEPARS_SETFPGATIME, 0};
01949 double dtime;
01950 long ltime_sec,ltime_usec;
01951 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dtime) == FAILURE) {
01952 RETURN_NULL();
01953 }
01954 ltime_sec=dtime;
01955 ltime_usec=(dtime-ltime_sec)*1000000;
01956 write_data[3]=ltime_sec;
01957 write_data[5]=ltime_usec;
01958
01959 long rslt=write(ELPHEL_G(fd_fparmsall), write_data, sizeof(write_data));
01960 if (rslt<0) RETURN_LONG(-errno);
01961 dtime=ltime_usec;
01962 dtime=ltime_sec+0.000001*dtime;
01963 RETURN_DOUBLE(dtime);
01964 }
01965
01967 PHP_FUNCTION(elphel_get_fpga_time) {
01968 double dtime;
01969 long ltime_sec,ltime_usec;
01970 lseek((int) ELPHEL_G( fd_fparmsall), LSEEK_GET_FPGA_TIME, SEEK_END );
01971 dtime= ELPHEL_GLOBALPARS(G_MICROSECONDS);
01972 dtime= ELPHEL_GLOBALPARS(G_SECONDS) + 0.000001*dtime;
01973 RETURN_DOUBLE(dtime);
01974 }
01975
01976
01977 static void php_elphel_init_globals(zend_elphel_globals *elphel_globals)
01978 {
01980 elphel_globals->frameParsAll = NULL;
01981 elphel_globals->framePars = NULL;
01982 elphel_globals->pastPars = NULL;
01983 elphel_globals->funcs2call= NULL;
01984 elphel_globals->fd_fparmsall= open("/dev/frameparsall", O_RDWR);
01985 if (elphel_globals->fd_fparmsall <0) {
01986 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/frameparsall");
01987 return ;
01988 }
01990 elphel_globals->frameParsAll = (struct framepars_all_t *) mmap(0, sizeof (struct framepars_all_t) , PROT_READ | PROT_WRITE, MAP_SHARED, elphel_globals->fd_fparmsall, 0);
01991 if((int)elphel_globals->frameParsAll == -1) {
01992 elphel_globals->frameParsAll=NULL;
01993 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap /dev/frameparsall");
01994 close (elphel_globals->fd_fparmsall);
01995 elphel_globals->fd_fparmsall = -1;
01996 return ;
01997 }
01999 elphel_globals->framePars = elphel_globals->frameParsAll->framePars;
02000 elphel_globals->pastPars = elphel_globals->frameParsAll->pastPars;
02001 elphel_globals->funcs2call= elphel_globals->frameParsAll->func2call.pars;
02002 elphel_globals->globalPars = elphel_globals->frameParsAll->globalPars;
02003
02004
02006
02007 elphel_globals->gamma_cache = NULL;
02008 elphel_globals->fd_gamma_cache= open("/dev/gamma_cache", O_RDWR);
02009 if (elphel_globals->fd_gamma_cache <0) {
02010 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/gamma_cache");
02011 return ;
02012 }
02014 elphel_globals->gamma_cache = (struct gamma_stuct_t *) mmap(0, sizeof (struct gamma_stuct_t) * GAMMA_CACHE_NUMBER , PROT_READ, MAP_SHARED, elphel_globals->fd_gamma_cache, 0);
02015 if((int)elphel_globals->gamma_cache == -1) {
02016 elphel_globals->gamma_cache=NULL;
02017 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap /dev/gamma_cache");
02018 close (elphel_globals->fd_gamma_cache);
02019 elphel_globals->fd_gamma_cache = -1;
02020 return ;
02021 }
02024 elphel_globals->histogram_cache = NULL;
02025 elphel_globals->fd_histogram_cache= open("/dev/histogram_cache", O_RDWR);
02026 if (elphel_globals->fd_histogram_cache <0) {
02027 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/histogram_cache");
02028 return ;
02029 }
02031 elphel_globals->histogram_cache = (struct histogram_stuct_t *) mmap(0, sizeof (struct histogram_stuct_t) * HISTOGRAM_CACHE_NUMBER , PROT_READ, MAP_SHARED, elphel_globals->fd_histogram_cache, 0);
02032 if((int)elphel_globals->histogram_cache == -1) {
02033 elphel_globals->histogram_cache=NULL;
02034 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap /dev/histogram_cache");
02035 close (elphel_globals->fd_histogram_cache);
02036 elphel_globals->fd_histogram_cache = -1;
02037 return ;
02038 }
02039
02041 elphel_globals->ccam_dma_buf = NULL;
02042 elphel_globals->fd_circ= open("/dev/circbuf", O_RDWR);
02043 if (elphel_globals->fd_circ <0) {
02044 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/circbuf");
02045 return ;
02046 }
02047 elphel_globals->ccam_dma_buf_len=lseek(elphel_globals->fd_circ,0,SEEK_END);
02048
02050 elphel_globals->ccam_dma_buf = (unsigned long *) mmap(0, elphel_globals->ccam_dma_buf_len , PROT_READ | PROT_WRITE, MAP_SHARED, elphel_globals->fd_circ, 0);
02051 if((int)elphel_globals->ccam_dma_buf == -1) {
02052 elphel_globals->ccam_dma_buf=NULL;
02053 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap /dev/circbuf");
02054 close (elphel_globals->fd_circ);
02055 elphel_globals->fd_circ = -1;
02056 return ;
02057 }
02058
02059
02060 elphel_globals->fd_exif = open(EXIF_DEV_NAME, O_RDONLY);
02061 if (elphel_globals->fd_exif <0) {
02062 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",EXIF_DEV_NAME);
02063 return ;
02064 }
02065 elphel_globals->fd_exifdir = open(EXIFDIR_DEV_NAME, O_RDONLY);
02066 if (elphel_globals->fd_exifdir <0) {
02067 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",EXIFDIR_DEV_NAME);
02068 return ;
02069 }
02070 elphel_globals->fd_exifmeta = open(EXIFMETA_DEV_NAME, O_RDWR);
02071 if (elphel_globals->fd_exifmeta <0) {
02072 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",EXIFMETA_DEV_NAME);
02073 return ;
02074 }
02075 elphel_globals->exif_size=0;
02076 }
02077
02078 PHP_RINIT_FUNCTION(elphel)
02079 {
02080
02081
02082 return SUCCESS;
02083 }
02085 PHP_MINIT_FUNCTION(elphel)
02086 {
02087 ZEND_INIT_MODULE_GLOBALS(elphel, php_elphel_init_globals, NULL);
02088
02089 DEFINE_P_NAMES(pname_arr);
02090
02091 DEFINE_ONCHANGE_NAMES(onchange_arr);
02092
02093 DEFINE_LSEEK_NAMES(lseek_arr);
02094
02095 DEFINE_CONST_NAMES(const_arr);
02096
02097 int i,j;
02098 char full_constant_name[256];
02099
02101 REGISTER_INI_ENTRIES();
02102 for (i=0;i< (sizeof(pname_arr)/sizeof(pname_arr[0])); i++) {
02103 if (strlen(pname_arr[i].name)>(sizeof(full_constant_name)-8)) return FAILURE;
02104 sprintf (full_constant_name,"ELPHEL_%s",pname_arr[i].name);
02105 zend_register_long_constant(full_constant_name, strlen(full_constant_name)+1, pname_arr[i].value, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
02106 }
02107
02108 for (i=0;i< (sizeof(onchange_arr)/sizeof(onchange_arr[0])); i++) {
02109 if (strlen(onchange_arr[i].name)>(sizeof(full_constant_name)-17)) return FAILURE;
02110 sprintf (full_constant_name,"ELPHEL_ONCHANGE_%s",onchange_arr[i].name);
02111 for (j=0; j<strlen(full_constant_name);j++) full_constant_name[j]=toupper(full_constant_name[j]);
02112 zend_register_long_constant(full_constant_name, strlen(full_constant_name)+1, onchange_arr[i].value, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
02113 }
02114
02115 for (i=0;i< (sizeof(lseek_arr)/sizeof(lseek_arr[0])); i++) {
02116 if (strlen(lseek_arr[i].name)>(sizeof(full_constant_name)-14)) return FAILURE;
02117 sprintf (full_constant_name,"ELPHEL_LSEEK_%s",lseek_arr[i].name);
02118 zend_register_long_constant(full_constant_name, strlen(full_constant_name)+1, lseek_arr[i].value, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
02119 }
02120 for (i=0;i< (sizeof(const_arr)/sizeof(const_arr[0])); i++) {
02121 if (strlen(const_arr[i].name)>(sizeof(full_constant_name)-14)) return FAILURE;
02122 sprintf (full_constant_name,"ELPHEL_CONST_%s",const_arr[i].name);
02123 zend_register_long_constant(full_constant_name, strlen(full_constant_name)+1, const_arr[i].value, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
02124 }
02125 return SUCCESS;
02126 }
02127
02128 PHP_MSHUTDOWN_FUNCTION(elphel)
02129 {
02130 UNREGISTER_INI_ENTRIES();
02131 if (ELPHEL_G(fd_fparmsall)>=0) close (ELPHEL_G(fd_fparmsall));
02132 if (ELPHEL_G(fd_gamma_cache)>=0) close (ELPHEL_G(fd_gamma_cache));
02133 if (ELPHEL_G(fd_histogram_cache)>=0) close (ELPHEL_G(fd_histogram_cache));
02134 if (ELPHEL_G(fd_circ)>=0) close (ELPHEL_G(fd_circ));
02135 if (ELPHEL_G(fd_exif)>=0) close (ELPHEL_G(fd_exif));
02136 if (ELPHEL_G(fd_exifdir)>=0) close (ELPHEL_G(fd_exifdir));
02137 if (ELPHEL_G(fd_exifmeta)>=0) close (ELPHEL_G(fd_exifmeta));
02138 return SUCCESS;
02139 }
02140
02141 PHP_MINFO_FUNCTION(elphel)
02142 {
02143 php_info_print_table_start();
02144 php_info_print_table_row(2, "Elphel support", "Enabled");
02145 php_info_print_table_row(2, "Elphel API Version", PHP_ELPHEL_VERSION);
02146 php_info_print_table_end();
02147 }
02148