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 #ifdef HAVE_CONFIG_H
00080 #include "config.h"
00081 #endif
00082
00083 #include <sys/mman.h>
00084 #include <sys/ioctl.h>
00085 #include <fcntl.h>
00086 #include <asm/byteorder.h>
00087 #include <errno.h>
00088
00089 #include "php.h"
00090 #include "php_ini.h"
00091 #include "elphel_php.h"
00093
00094
00095 ZEND_DECLARE_MODULE_GLOBALS(elphel)
00096 static function_entry elphel_functions[] = {
00097 PHP_FE(elph_hello, NULL)
00098 PHP_FE(elphel_get_P_value, NULL)
00099 PHP_FE(elphel_set_P_value, NULL)
00100 PHP_FE(elphel_get_P_arr, NULL)
00101 PHP_FE(elphel_get_P_warr, NULL)
00102 PHP_FE(elphel_set_P_arr, NULL)
00103 PHP_FE(elphel_get_state, NULL)
00104 PHP_FE(elphel_program_sensor, NULL)
00105 PHP_FE(elphel_compressor_cmd, NULL)
00106 PHP_FE(elphel_compressor_reset, NULL)
00107 PHP_FE(elphel_compressor_run, NULL)
00108 PHP_FE(elphel_compressor_stop, NULL)
00109 PHP_FE(elphel_compressor_frame, NULL)
00110 PHP_FE(elphel_is_compressor_idle, NULL)
00111 PHP_FE(elphel_reset_sensor, NULL)
00112 PHP_FE(elphel_set_fpga_time, NULL)
00113 PHP_FE(elphel_get_fpga_time, NULL)
00114 PHP_FE(elphel_white_balance, NULL)
00115 PHP_FE(elphel_autoexposure_set, NULL)
00116 PHP_FE(elphel_autoexposure_get, NULL)
00117 PHP_FE(elphel_wait_frame, NULL)
00118 PHP_FE(elphel_fpga_read, NULL)
00119 PHP_FE(elphel_fpga_write, NULL)
00120 PHP_FE(elphel_trigger, NULL)
00121 PHP_FE(elphel_flush_cache, NULL)
00122 PHP_FE(elphel_gamma, NULL)
00123 PHP_FE(elphel_histogram, NULL)
00124 PHP_FE(elphel_get_gamma, NULL)
00125 PHP_FE(elphel_get_histogram, NULL)
00126 PHP_FE(elphel_get_exif_field, NULL)
00127 PHP_FE(elphel_set_exif_field, NULL)
00128 PHP_FE(elphel_get_exif_elphel, NULL)
00129 PHP_FE(elphel_update_exif, NULL)
00130 PHP_FE(elphel_get_circbuf_pointers, NULL)
00131 {NULL, NULL, NULL}
00132 };
00133
00134 zend_module_entry elphel_module_entry = {
00135 #if ZEND_MODULE_API_NO >= 20010901
00136 STANDARD_MODULE_HEADER,
00137 #endif
00138 PHP_ELPHEL_EXTNAME,
00139 elphel_functions,
00140 PHP_MINIT(elphel),
00141 PHP_MSHUTDOWN(elphel),
00142 PHP_RINIT(elphel),
00143 NULL,
00144 PHP_MINFO(elphel),
00145 #if ZEND_MODULE_API_NO >= 20010901
00146 PHP_ELPHEL_VERSION,
00147 #endif
00148 STANDARD_MODULE_PROPERTIES
00149 };
00150
00151 #ifdef COMPILE_DL_ELPHEL
00152 ZEND_GET_MODULE(elphel)
00153 #endif
00154
00155
00156 PHP_INI_BEGIN()
00158 PHP_INI_END()
00159
00160
00162 static void init_sens() {
00163 if ((((long *) ELPHEL_G(imageParamsR)) [P_SENSOR])==0) lseek((int) ELPHEL_G( fd_sens), LSEEK_INIT_SENSOR , SEEK_END );
00164 }
00165
00166 PHP_FUNCTION(elphel_flush_cache)
00167 {
00168 lseek((int)ELPHEL_G(fd_sens),LSEEK_FLUSH_CACHE, SEEK_END);
00169 RETURN_NULL();
00170 }
00171
00172 long createExifDirectory (int rebuild) {
00173 int indx;
00174 long numfields=0;
00175 struct exif_dir_table_t dir_table_entry;
00177 int exif_this_size=lseek((int) ELPHEL_G(fd_exifdir),1,SEEK_END);
00178
00179 if ((ELPHEL_G(exif_size) == exif_this_size) && !rebuild) return 0;
00180 ELPHEL_G(exif_size) = exif_this_size;
00181
00182 for (indx=0; indx<ExifKmlNumber; indx++) ELPHEL_G(exif_dir)[indx].ltag=0;
00183 while (read((int) ELPHEL_G(fd_exifdir), &dir_table_entry, sizeof(dir_table_entry))>0) {
00184 switch (dir_table_entry.ltag) {
00185 case Exif_Image_ImageDescription: indx= Exif_Image_ImageDescription_Index; break;
00186 case Exif_Image_FrameNumber: indx= Exif_Image_FrameNumber_Index; break;
00187 case Exif_Photo_DateTimeOriginal: indx= Exif_Photo_DateTimeOriginal_Index; break;
00188 case Exif_Photo_SubSecTimeOriginal: indx= Exif_Photo_SubSecTimeOriginal_Index; break;
00189 case Exif_Photo_ExposureTime: indx= Exif_Photo_ExposureTime_Index; break;
00190 case Exif_GPSInfo_GPSLatitudeRef: indx= Exif_GPSInfo_GPSLatitudeRef_Index; break;
00191 case Exif_GPSInfo_GPSLatitude: indx= Exif_GPSInfo_GPSLatitude_Index ; break;
00192 case Exif_GPSInfo_GPSLongitudeRef: indx= Exif_GPSInfo_GPSLongitudeRef_Index ; break;
00193 case Exif_GPSInfo_GPSLongitude: indx= Exif_GPSInfo_GPSLongitude_Index; break;
00194 case Exif_GPSInfo_GPSAltitudeRef: indx= Exif_GPSInfo_GPSAltitudeRef_Index; break;
00195 case Exif_GPSInfo_GPSAltitude: indx= Exif_GPSInfo_GPSAltitude_Index; break;
00196 case Exif_GPSInfo_GPSTimeStamp: indx= Exif_GPSInfo_GPSTimeStamp_Index; break;
00197 case Exif_GPSInfo_GPSDateStamp: indx= Exif_GPSInfo_GPSDateStamp_Index; break;
00198 case Exif_GPSInfo_GPSMeasureMode: indx= Exif_GPSInfo_GPSMeasureMode_Index; break;
00199 case Exif_GPSInfo_CompassDirectionRef: indx= Exif_GPSInfo_CompassDirectionRef_Index; break;
00200 case Exif_GPSInfo_CompassDirection: indx= Exif_GPSInfo_CompassDirection_Index; break;
00201 case Exif_GPSInfo_CompassPitchRef: indx= Exif_GPSInfo_CompassPitchRef_Index; break;
00202 case Exif_GPSInfo_CompassPitch: indx= Exif_GPSInfo_CompassPitch_Index; break;
00203 case Exif_GPSInfo_CompassRollRef: indx= Exif_GPSInfo_CompassRollRef_Index; break;
00204 case Exif_GPSInfo_CompassRoll: indx= Exif_GPSInfo_CompassRoll_Index; break;
00205 default: indx=-1;
00206 }
00207 if (indx>=0) {
00208 memcpy(&(ELPHEL_G(exif_dir)[indx]),&dir_table_entry,sizeof(dir_table_entry));
00209 numfields++;
00210 }
00211 }
00212 return numfields;
00213 }
00214
00215
00216
00217
00218
00219 PHP_FUNCTION(elphel_get_circbuf_pointers) {
00220 char * ccam_dma_buf_char= (char *) ELPHEL_G( ccam_dma_buf);
00221 long second=0;
00222 long p,frameParamPointer;
00223 long buff_size=lseek(ELPHEL_G( fd_circ),0,SEEK_END);
00224
00225 zval *image_pointers;
00226 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &second) == FAILURE) {
00227 RETURN_NULL();
00228 }
00229 p=lseek((int) ELPHEL_G( fd_circ), second? CIRCLSEEK_SCND: CIRCLSEEK_FIRST, SEEK_END );
00230 if (p<0) RETURN_NULL();
00231 array_init(return_value);
00232 while (p>=0) {
00233 frameParamPointer=p-32;
00234 if (frameParamPointer<0) frameParamPointer+=buff_size;
00235 ALLOC_INIT_ZVAL(image_pointers);
00236 array_init(image_pointers);
00237 add_assoc_long(image_pointers, "circbuf_pointer", p);
00238 add_assoc_long(image_pointers, "exif_pointer", ((struct frame_params_t *) &ccam_dma_buf_char[frameParamPointer])->meta_index);
00239 add_next_index_zval(return_value, image_pointers);
00241 p=lseek((int) ELPHEL_G( fd_circ), CIRCLSEEK_NEXT, SEEK_END );
00242 p=lseek((int) ELPHEL_G( fd_circ), CIRCLSEEK_READY, SEEK_END );
00243
00244 }
00245 }
00246
00247
00248 #define saferead255(f,d,l) read(f,d,((l)<256)?(l):255)
00249 PHP_FUNCTION(elphel_get_exif_elphel)
00250 {
00251 long rational3[6];
00252 long exif_page_start;
00253 char *key;
00254 long indx;
00255 char val[256];
00256 long exif_page=0;
00257 int hours=0, minutes=0;
00258 double seconds=0.0;
00259 double longitude=0.0, latitude=0.0, altitude=0.0, heading=0.0, roll=0.0, pitch=0.0, exposure=0.0;
00260 val[255]='\0';
00261 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &exif_page) == FAILURE) {
00262 RETURN_NULL();
00263 }
00264
00265 createExifDirectory(0);
00266 if (exif_page) exif_page_start=lseek ((int) ELPHEL_G(fd_exif), exif_page, SEEK_END);
00267 else exif_page_start=lseek ((int) ELPHEL_G(fd_exif), 0, SEEK_SET);
00268 if (exif_page_start<0) RETURN_NULL();
00269 array_init(return_value);
00270
00271
00273
00274 if (ELPHEL_G(exif_dir)[Exif_Image_ImageDescription_Index].ltag==Exif_Image_ImageDescription) {
00275 lseek (ELPHEL_G(fd_exif),
00276 exif_page_start+ELPHEL_G(exif_dir)[Exif_Image_ImageDescription_Index].dst,
00277 SEEK_SET);
00278 saferead255(ELPHEL_G(fd_exif), val, ELPHEL_G(exif_dir)[Exif_Image_ImageDescription_Index].len);
00279 add_assoc_string(return_value, "ImageDescription", val, 1);
00280 }
00282 if (ELPHEL_G(exif_dir)[Exif_Image_FrameNumber_Index].ltag==Exif_Image_FrameNumber) {
00283 lseek (ELPHEL_G(fd_exif),
00284 exif_page_start+ELPHEL_G(exif_dir)[Exif_Image_FrameNumber_Index].dst,
00285 SEEK_SET);
00286 read(ELPHEL_G(fd_exif), rational3, 4);
00287 sprintf (val,"%ld", (long) __cpu_to_be32( rational3[0]));
00288 add_assoc_string(return_value, "FrameNumber", val, 1);
00289 }
00290
00292 if (ELPHEL_G(exif_dir)[Exif_Photo_DateTimeOriginal_Index].ltag==Exif_Photo_DateTimeOriginal) {
00293 lseek (ELPHEL_G(fd_exif),
00294 exif_page_start+ELPHEL_G(exif_dir)[Exif_Photo_DateTimeOriginal_Index].dst,
00295 SEEK_SET);
00296 read(ELPHEL_G(fd_exif), val, 19);
00297 val[19]='\0';
00298 if (ELPHEL_G(exif_dir)[Exif_Photo_SubSecTimeOriginal_Index].ltag==Exif_Photo_SubSecTimeOriginal) {
00299 val[19]='.';
00300 lseek (ELPHEL_G(fd_exif),
00301 exif_page_start+ELPHEL_G(exif_dir)[Exif_Photo_SubSecTimeOriginal_Index].dst,
00302 SEEK_SET);
00303 read(ELPHEL_G(fd_exif), &val[20], 7);
00304 val[27]='\0';
00305 }
00306 add_assoc_string(return_value, "DateTimeOriginal", val, 1);
00307 }
00308
00310 if (ELPHEL_G(exif_dir)[Exif_Photo_ExposureTime_Index].ltag==Exif_Photo_ExposureTime) {
00311 lseek (ELPHEL_G(fd_exif),
00312 exif_page_start+ELPHEL_G(exif_dir)[Exif_Photo_ExposureTime_Index].dst,
00313 SEEK_SET);
00314 read(ELPHEL_G(fd_exif), rational3, 8);
00315 exposure=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
00316 sprintf (val,"%f",exposure);
00317 add_assoc_string(return_value, "ExposureTime", val, 1);
00318 }
00319
00320
00322 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSMeasureMode_Index].ltag==Exif_GPSInfo_GPSMeasureMode) {
00323 lseek (ELPHEL_G(fd_exif),
00324 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSMeasureMode_Index].dst,
00325 SEEK_SET);
00326 read(ELPHEL_G(fd_exif), val, 1);
00327 add_assoc_stringl(return_value, "GPSMeasureMode", val, 1, 1);
00328 }
00329
00331 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSDateStamp_Index].ltag==Exif_GPSInfo_GPSDateStamp) {
00332 lseek (ELPHEL_G(fd_exif),
00333 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSDateStamp_Index].dst,
00334 SEEK_SET);
00335 read(ELPHEL_G(fd_exif), val, 10);
00336 val[10]='\0';
00337 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSTimeStamp_Index].ltag==Exif_GPSInfo_GPSTimeStamp) {
00338 lseek (ELPHEL_G(fd_exif),
00339 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSTimeStamp_Index].dst,
00340 SEEK_SET);
00341 read(ELPHEL_G(fd_exif), rational3, 24);
00342 hours= __cpu_to_be32( rational3[0]);
00343 minutes= __cpu_to_be32( rational3[2]);
00344 seconds= (1.0*(__cpu_to_be32( rational3[4])+1))/__cpu_to_be32( rational3[5]);
00345 sprintf (&val[10]," %02d:%02d:%05.2f",hours,minutes,seconds);
00346 }
00347 add_assoc_string(return_value, "GPSDateTime", val, 1);
00348 }
00349
00352 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitude_Index].ltag==Exif_GPSInfo_GPSLongitude) {
00353 lseek (ELPHEL_G(fd_exif),
00354 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitude_Index].dst,
00355 SEEK_SET);
00356 read(ELPHEL_G(fd_exif), rational3, 24);
00357 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]));
00358 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitudeRef_Index].ltag==Exif_GPSInfo_GPSLongitudeRef) {
00359 lseek (ELPHEL_G(fd_exif),
00360 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLongitudeRef_Index].dst,
00361 SEEK_SET);
00362 read(ELPHEL_G(fd_exif), val, 1);
00363 if (val[0]!= 'E') longitude=-longitude;
00364 }
00365 sprintf (val,"%f",longitude);
00366 add_assoc_string(return_value, "GPSLongitude", val, 1);
00367 }
00369 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitude_Index].ltag==Exif_GPSInfo_GPSLatitude) {
00370 lseek (ELPHEL_G(fd_exif),
00371 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitude_Index].dst,
00372 SEEK_SET);
00373 read(ELPHEL_G(fd_exif), rational3, 24);
00374 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]));
00375 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitudeRef_Index].ltag==Exif_GPSInfo_GPSLatitudeRef) {
00376 lseek (ELPHEL_G(fd_exif),
00377 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSLatitudeRef_Index].dst,
00378 SEEK_SET);
00379 read(ELPHEL_G(fd_exif), val, 1);
00380 if (val[0] != 'N') latitude=-latitude;
00381 }
00382 sprintf (val,"%f",latitude);
00383 add_assoc_string(return_value, "GPSLatitude", val, 1);
00384 }
00386 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitude_Index].ltag==Exif_GPSInfo_GPSAltitude) {
00387 lseek (ELPHEL_G(fd_exif),
00388 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitude_Index].dst,
00389 SEEK_SET);
00390 read(ELPHEL_G(fd_exif), rational3, 8);
00391 altitude=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
00392
00393 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitudeRef_Index].ltag==Exif_GPSInfo_GPSAltitudeRef) {
00394 lseek (ELPHEL_G(fd_exif),
00395 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_GPSAltitudeRef_Index].dst,
00396 SEEK_SET);
00397 read(ELPHEL_G(fd_exif), val, 1);
00398 if (val[0] != '\0') altitude=-altitude;
00399 }
00400 sprintf (val,"%f",altitude);
00401 add_assoc_string(return_value, "GPSAltitude", val, 1);
00402 }
00404 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassDirection_Index].ltag==Exif_GPSInfo_CompassDirection) {
00405 lseek (ELPHEL_G(fd_exif),
00406 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassDirection_Index].dst,
00407 SEEK_SET);
00408 read(ELPHEL_G(fd_exif), rational3, 8);
00409 heading=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
00410 sprintf (val,"%f",heading);
00411 add_assoc_string(return_value, "CompassDirection", val, 1);
00412 }
00415 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRoll_Index].ltag==Exif_GPSInfo_CompassRoll) {
00416 lseek (ELPHEL_G(fd_exif),
00417 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRoll_Index].dst,
00418 SEEK_SET);
00419 read(ELPHEL_G(fd_exif), rational3, 8);
00420 roll=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
00421
00422 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRollRef_Index].ltag==Exif_GPSInfo_CompassRollRef) {
00423 lseek (ELPHEL_G(fd_exif),
00424 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassRollRef_Index].dst,
00425 SEEK_SET);
00426 read(ELPHEL_G(fd_exif), val, 1);
00427 if (val[0] != EXIF_COMPASS_ROLL_ASCII[0]) roll=-roll;
00428 }
00429 sprintf (val,"%f",roll);
00430 add_assoc_string(return_value, "CompassRoll", val, 1);
00431 }
00432
00434 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitch_Index].ltag==Exif_GPSInfo_CompassPitch) {
00435 lseek (ELPHEL_G(fd_exif),
00436 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitch_Index].dst,
00437 SEEK_SET);
00438 read(ELPHEL_G(fd_exif), rational3, 8);
00439 pitch=(1.0*__cpu_to_be32( rational3[0]))/__cpu_to_be32( rational3[1]);
00440
00441 if (ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitchRef_Index].ltag==Exif_GPSInfo_CompassPitchRef) {
00442 lseek (ELPHEL_G(fd_exif),
00443 exif_page_start+ELPHEL_G(exif_dir)[Exif_GPSInfo_CompassPitchRef_Index].dst,
00444 SEEK_SET);
00445 read(ELPHEL_G(fd_exif), val, 1);
00446 if (val[0] != EXIF_COMPASS_PITCH_ASCII[0]) pitch=-pitch;
00447 }
00448 sprintf (val,"%f",pitch);
00449 add_assoc_string(return_value, "CompassPitch", val, 1);
00450 }
00451
00452 }
00453
00454
00455 PHP_FUNCTION(elphel_update_exif) {
00456 RETURN_LONG(createExifDirectory(1));
00457 }
00458
00459
00460 PHP_FUNCTION(elphel_get_exif_field)
00461 {
00462 long exif_page=0;
00463 long ltag;
00464 struct exif_dir_table_t dir_table_entry;
00465 char * rslt;
00466 int found=0;
00467
00468 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", <ag, &exif_page) == FAILURE) {
00469 RETURN_NULL();
00470 }
00471
00472 lseek ((int) ELPHEL_G(fd_exifdir), 0, SEEK_SET);
00473 while (read((int) ELPHEL_G(fd_exifdir), &dir_table_entry, sizeof(dir_table_entry))>0) {
00474 if (dir_table_entry.ltag==ltag) {
00475 found=1;
00476 break;
00477 }
00478 }
00479 if (!found) RETURN_NULL();
00480
00481 if (exif_page) found= lseek ((int) ELPHEL_G(fd_exif), exif_page, SEEK_END);
00482 else found= lseek ((int) ELPHEL_G(fd_exif), 0, SEEK_SET);
00483 if (found<0) RETURN_NULL();
00484
00485 lseek ((int) ELPHEL_G(fd_exif), dir_table_entry.dst, SEEK_CUR);
00486 rslt=emalloc(dir_table_entry.len);
00487 read((int) ELPHEL_G(fd_exif), rslt, dir_table_entry.len);
00488 RETURN_STRINGL(rslt,dir_table_entry.len,0);
00489 }
00490
00491
00492
00493 PHP_FUNCTION(elphel_set_exif_field)
00494 {
00495
00496 long ltag;
00497 struct exif_dir_table_t dir_table_entry;
00498 char * value;
00499 int value_length;
00500 int found=0;
00501
00502 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", <ag, &value,&value_length) == FAILURE) {
00503 RETURN_NULL();
00504 }
00505
00506 lseek ((int) ELPHEL_G(fd_exifdir), 0, SEEK_SET);
00507 while (read((int) ELPHEL_G(fd_exifdir), &dir_table_entry, sizeof(dir_table_entry))>0) {
00508 if (dir_table_entry.ltag==ltag) {
00509 found=1;
00510 break;
00511 }
00512 }
00513 if (!found) RETURN_NULL();
00514 lseek ((int) ELPHEL_G(fd_exifmeta), dir_table_entry.src, SEEK_SET);
00515 if (value_length>dir_table_entry.len) value_length = dir_table_entry.len;
00517
00518 long rslt=write(ELPHEL_G(fd_exifmeta), value, value_length);
00519 if (rslt<0) rslt =-errno;
00520 RETURN_LONG(rslt);
00521 }
00522
00523
00525 PHP_FUNCTION(elph_hello)
00526 {
00528 DEFINE_P_NAMES(pname_arr);
00529 int i;
00530
00531 array_init(return_value);
00532 for (i=0;i< (sizeof(pname_arr)/sizeof(pname_arr[0])); i++) {
00533
00534 add_assoc_long(return_value, pname_arr[i].name, ((long *) ELPHEL_G(imageParamsR))[pname_arr[i].value]);
00535 }
00536 }
00538 PHP_FUNCTION(elphel_wait_frame)
00539 {
00540 lseek((int) ELPHEL_G( fd_circ), CIRCLSEEK_TOWP, SEEK_END );
00541 lseek((int) ELPHEL_G( fd_circ), CIRCLSEEK_WAIT, SEEK_END );
00542 RETURN_NULL();
00543 }
00544
00546 PHP_FUNCTION(elphel_autoexposure_set)
00547 {
00548 lseek((int) ELPHEL_G( fd_sens), LSEEK_AUTOEXP_SET, SEEK_END );
00549 RETURN_NULL();
00550 }
00551
00553 PHP_FUNCTION(elphel_autoexposure_get)
00554 {
00555 lseek((int) ELPHEL_G( fd_sens), LSEEK_AUTOEXP_GET, SEEK_END );
00556 RETURN_NULL();
00557 }
00558
00559
00560 #define HIST_LEN 256 * 4 * 4
00561 #define GAMMA_LEN 256 * 4 * 2
00562
00563
00564
00565
00566 PHP_FUNCTION(elphel_get_histogram)
00567 {
00568 long addr;
00569
00570 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
00571 RETURN_NULL();
00572 }
00573 if ((addr > 1023) || (addr <0)) {
00574 RETURN_NULL();
00575 }
00576 RETURN_LONG( ((long *) ELPHEL_G(hist_gamma_mmap))[addr]);
00577 }
00578 PHP_FUNCTION(elphel_get_gamma)
00579 {
00580 long addr;
00581
00582 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
00583 RETURN_NULL();
00584 }
00585 if ((addr > 1023) || (addr <0)) {
00586 RETURN_NULL();
00587 }
00588 RETURN_LONG( ((unsigned short *) ELPHEL_G(hist_gamma_mmap))[addr+(HIST_LEN>>1)]);
00589 }
00590
00591
00596 PHP_FUNCTION(elphel_gamma)
00597 {
00598 unsigned short gamma[256];
00599 long channel;
00600 double indat,outdat;
00601 int indx;
00602 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld", &channel, &indat ) == FAILURE) {
00603 RETURN_LONG (-1);
00604 }
00605 if ((channel <0) || (channel > 3)) RETURN_LONG (-1);
00606
00607
00608 memcpy (gamma,ELPHEL_G(hist_gamma_mmap) + HIST_LEN + ((GAMMA_LEN>>2)*channel), (GAMMA_LEN>>2));
00609 indat*=255.0;
00610 indx=indat;
00611 if (indx < 0) outdat=0.0;
00612 else if (indx >=255) outdat=1.0;
00613 else outdat=(gamma[indx]+ (gamma[indx+1]-gamma[indx])*(indat-indx))*(1.0/65535);
00614 RETURN_DOUBLE (outdat);
00615 }
00616
00617 PHP_FUNCTION(elphel_histogram)
00618 {
00619 unsigned long histogram[256];
00620 long channel;
00621 double indat,outdat;
00622 int i,d;
00623 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ld", &channel, &indat ) == FAILURE) {
00624 RETURN_LONG (-1);
00625 }
00626 if ((channel <0) || (channel > 3)) RETURN_LONG (-1);
00627
00628 memcpy (histogram,ELPHEL_G(hist_gamma_mmap) + ((HIST_LEN>>2)*channel), (HIST_LEN>>2));
00629 if (indat <= 0.0) outdat=0.0;
00630 else if (indat>=1.0) outdat=1.0;
00631 else {
00632 for (i=1;i<256;i++) histogram[i]+=histogram[i-1];
00633 indat*=histogram[255];
00634 d=indat;
00635 for (i=0; histogram[i] <= d; i++);
00636 if (i==0) outdat= ((1.0/255.0)*d)/histogram[0];
00637 else outdat= (1.0/255.0)*((i-1)+ (1.0*(d-histogram[i-1])/(histogram[i]-histogram[i-1])));
00638 }
00639 RETURN_DOUBLE (outdat);
00640 }
00641
00650
00651
00652
00653 int calcWhiteBalance(int thrsh,
00654 int min_pixels,
00655 double diffGains[3],
00656 long use_green2
00657 ){
00658 double colPercentiles[4];
00659 int hists[1024];
00660 unsigned short gammas[1024];
00661
00662 int sum[4];
00663 int indx[4];
00664 int i,j,k,smax;
00665 int percFound=0;
00667 memcpy (hists, ELPHEL_G(hist_gamma_mmap), HIST_LEN);
00668 memcpy (gammas,ELPHEL_G(hist_gamma_mmap) + HIST_LEN, GAMMA_LEN);
00669
00670 #ifdef HISTDBG
00671 php_printf ("thrsh=%d, min_pixels=%d\n",thrsh, min_pixels);
00672 for (k=0; k<4; k++) {
00673 php_printf ("k=%d\n",k);
00674 for (j=0; j<256; j+=16) {
00675 php_printf ( "%03x: ",j);
00676 for (i=j; i<j+16; i++) {
00677 php_printf ( " %08x: ",hists[256*k+i]);
00678 }
00679 php_printf ("\n");
00680 }
00681 }
00682
00683 for (k=0; k<4; k++) {
00684 php_printf ("k=%d\n",k);
00685 for (j=0; j<256; j+=16) {
00686 php_printf ( "%03x: ",j);
00687 for (i=j; i<j+16; i++) {
00688 php_printf ( " %04x: ", (int) gammas[256*k+i]);
00689 }
00690 php_printf ("\n");
00691 }
00692 }
00693 #endif
00694
00695
00696 for (j=0;j<4;j++) {sum[j]=0;indx[j]=-1;colPercentiles[j]=-1.0;}
00697 for (i=255;i>=thrsh;i--) for (j=0;j<4;j++) sum[j]+=hists[i+ (j<<8)];
00698 #ifdef HISTDBG
00699 php_printf ("sum[0]=%d, sum[1]=%d, sum[2]=%d, sum[3]=%d\n", sum[0], sum[1], sum[2], sum[3]);
00700 #endif
00701 smax = sum[0];
00702 for (j=1;j<4;j++) if (sum[j]>smax) smax=sum[j];
00703 if (smax<min_pixels) {
00704 for (i=thrsh-1;(i>0) && (smax<min_pixels); i--) {
00705 for (j=0;j<4;j++) sum[j]+=hists[i+ (j<<8)];
00706 for (j=0;j<4;j++) {
00707 if (((j!=2) || use_green2) && (sum[j]>smax)) {smax=sum[j];k=j;thrsh=i;}
00708 }
00709 }
00710 }
00711 #ifdef HISTDBG
00712 php_printf ("thrsh=%d\n",thrsh);
00713 php_printf ("smax=%d, sum[0]=%d, sum[1]=%d, sum[2]=%d, sum[3]=%d\n",smax, sum[0], sum[1], sum[2], sum[3]);
00714 #endif
00715
00716 if(smax < min_pixels) return -2;
00717 i=0;
00718 smax=0;
00719 for (j=0;j<4;j++) if (((j!=2) || use_green2) && (sum[j]>smax)) {smax=sum[j];i=j;}
00720 indx[i]=thrsh;
00721 percFound |= (1<<i);
00722 for (i=thrsh-1;(i>0) && (percFound != 0xf); i--) {
00723 for (j=0;j<4;j++) if (((j!=2) || use_green2) && !(percFound & (1 <<j))) {
00724 sum[j] += hists[i+ (j<<8)];
00725 if (sum[j]>=smax) {
00726 percFound |= (1<<j);
00727 indx[j]=i;
00728 }
00729 }
00730 }
00731 #ifdef HISTDBG
00732 php_printf ("sum[0]=%d, sum[1]=%d, sum[2]=%d, sum[3]=%d\n", sum[0], sum[1], sum[2], sum[3]);
00733 php_printf ("indx[0]=%d, indx[1]=%d, indx[2]=%d, indx[3]=%d\n", indx[0], indx[1], indx[2], indx[3]);
00734 #endif
00735 if (!use_green2) percFound |= 0x4;
00736
00737 if(percFound != 0xf) return -3;
00738 for (j=0;j<4;j++) if ((j!=2) || use_green2) {
00739 if (sum[j]==smax) colPercentiles[j]=indx[j];
00740 else colPercentiles[j]= indx[j]+(1.0*(sum[j]-smax))/hists[indx[j]+ (j<<8)];
00741 }
00743
00744 k=0;
00745 for (j=0;j<4;j++) if ((j!=2) || use_green2) {
00746 for (i=255;(i>=0) && ((k=((gammas[i+(j<<8)]>>8) & 0xff)) > indx[j]);i--);
00747 colPercentiles[j]=i+ (colPercentiles[j]-k)/ ( ((gammas[i+1+(j<<8)]>>8) & 0xff) -k);
00748 }
00749
00750
00751
00752
00753 diffGains[0]=colPercentiles[1]/colPercentiles[0];
00754 diffGains[1]=colPercentiles[1]/colPercentiles[3];
00755 if ((j!=2) || use_green2) diffGains[2]=colPercentiles[1]/colPercentiles[2];
00756
00757 #ifdef HISTDBG
00758 for (k=0; k<4; k++) php_printf ("colPercentiles[%d]=%f\n",k,colPercentiles[k]);
00759 for (k=0; k<3; k++) php_printf ("diffGains[%d]=%f\n",k,diffGains[k]);
00760 #endif
00761 return 0;
00762 }
00769 PHP_FUNCTION(elphel_white_balance)
00770 {
00771 double thrsh= 0.98;
00772 double minfrac =0.01;
00773 double rscale= 1.0;
00774 double bscale= 1.0;
00775 double corr_factor=1.0;
00776 int ithrsh, minpix;
00777 double wbDiffGains[3];
00778 long corr_green=0;
00779 int rslt=-1;
00780 int d,s;
00781 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ddddl", &thrsh, &minfrac, &rscale, &bscale, &corr_factor, &corr_green) == FAILURE) {
00782 RETURN_LONG (-1);
00783 }
00784 ithrsh=(255*thrsh)+0.5;
00785 minpix= ((long *) ELPHEL_G(imageParamsR))[P_ACTUAL_WIDTH] *
00786 ((long *) ELPHEL_G(imageParamsR))[P_ACTUAL_HEIGHT] *
00787 minfrac;
00788 rslt = calcWhiteBalance( ithrsh,
00789 minpix,
00790 wbDiffGains,
00791 corr_green);
00792 if (rslt) RETURN_LONG (rslt) ;
00793
00794 wbDiffGains[0]*=rscale;
00795 wbDiffGains[1]*=bscale;
00798 ((long *) ELPHEL_G(imageParamsR))[P_RSCALE+P_NUMBER]=256.0*wbDiffGains[0];
00799 ((long *) ELPHEL_G(imageParamsR))[P_BSCALE+P_NUMBER]=256.0*wbDiffGains[1];
00800 if (corr_green) ((long *) ELPHEL_G(imageParamsR))[P_GSCALE+P_NUMBER]=256.0*wbDiffGains[2];
00801 if (corr_factor < 1.0) {
00802 d=((long *) ELPHEL_G(imageParamsR))[P_RSCALE+P_NUMBER]-((long *) ELPHEL_G(imageParamsR))[P_RSCALE];
00803 s=1;
00804 if (d<0) {d=-d;s=-s;};
00805 if (d) {
00806 d *= corr_factor;
00807 if (d<1) d=1;
00808 ((long *) ELPHEL_G(imageParamsR))[P_RSCALE+P_NUMBER]=((long *) ELPHEL_G(imageParamsR))[P_RSCALE]+s*d;
00809 }
00810 d=((long *) ELPHEL_G(imageParamsR))[P_BSCALE+P_NUMBER]-((long *) ELPHEL_G(imageParamsR))[P_BSCALE];
00811 s=1;
00812 if (d<0) {d=-d;s=-s;};
00813 if (d) {
00814 d *= corr_factor;
00815 if (d<1) d=1;
00816 ((long *) ELPHEL_G(imageParamsR))[P_BSCALE+P_NUMBER]=((long *) ELPHEL_G(imageParamsR))[P_BSCALE]+s*d;
00817 }
00818 }
00819 RETURN_LONG (0);
00820 }
00821
00822
00823
00828 PHP_FUNCTION(elphel_get_P_arr)
00829 {
00830 char full_constant_name[256];
00831 zval *arr, **data;
00832 HashTable *arr_hash;
00833 HashPosition pointer;
00834 char *key;
00835 int key_len;
00836 long index;
00837 zval const_value;
00838 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
00839 RETURN_NULL();
00840 }
00841 init_sens();
00842 array_init(return_value);
00843 arr_hash = Z_ARRVAL_P(arr);
00844 for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
00845 zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS;
00846 zend_hash_move_forward_ex(arr_hash, &pointer)) {
00847 if (zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) {
00848 sprintf (full_constant_name,"ELPHEL_%s",key);
00849 if (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC)) {
00850 add_assoc_long(return_value, key, ((long *) ELPHEL_G(imageParamsR))[ Z_LVAL(const_value)]);
00851 zval_dtor(&const_value);
00852 }
00853 }
00854 }
00855 }
00857 PHP_FUNCTION(elphel_get_P_warr)
00858 {
00859 char full_constant_name[256];
00860 zval *arr, **data;
00861 HashTable *arr_hash;
00862 HashPosition pointer;
00863 char *key;
00864 int key_len;
00865 long index;
00866 zval const_value;
00867 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
00868 RETURN_NULL();
00869 }
00870 init_sens();
00871 array_init(return_value);
00872 arr_hash = Z_ARRVAL_P(arr);
00873 for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
00874 zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS;
00875 zend_hash_move_forward_ex(arr_hash, &pointer)) {
00876 if (zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) {
00877 sprintf (full_constant_name,"ELPHEL_%s",key);
00878 if (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC)) {
00879 add_assoc_long(return_value, key, ((long *) ELPHEL_G(imageParamsR))[P_NUMBER + Z_LVAL(const_value)]);
00880 zval_dtor(&const_value);
00881 }
00882 }
00883 }
00884 }
00885
00886
00891 PHP_FUNCTION(elphel_set_P_arr)
00892 {
00893 char full_constant_name[256];
00894 zval *arr, **data;
00895 HashTable *arr_hash;
00896 HashPosition pointer;
00897 char *key;
00898 int key_len;
00899 long index;
00900 zval const_value;
00901 int num_written=0;
00902 int reg_addr, reg_data;
00903 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) {
00904 RETURN_LONG(num_written);
00905 }
00906 init_sens();
00907 arr_hash = Z_ARRVAL_P(arr);
00908 for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
00909 zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS;
00910 zend_hash_move_forward_ex(arr_hash, &pointer)) {
00911 if ((zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) &&
00912 (Z_TYPE_PP(data) == IS_LONG)) {
00913 reg_data=Z_LVAL_PP(data);
00914 sprintf (full_constant_name,"ELPHEL_%s",key);
00915 if (zend_get_constant(full_constant_name, strlen(full_constant_name), &const_value TSRMLS_CC)) {
00916 reg_addr=Z_LVAL(const_value);
00917 zval_dtor(&const_value);
00918 if ((reg_addr>=0) && (reg_addr<P_NUMBER)) {
00919 ((long *) ELPHEL_G(imageParamsR))[reg_addr+P_NUMBER]=reg_data;
00920 num_written++;
00921 }
00922 }
00923 }
00924 }
00925 RETURN_LONG(num_written);
00926 }
00927
00929 PHP_FUNCTION(elphel_fpga_read)
00930 {
00931 long addr,data,res;
00932 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
00933 RETURN_NULL();
00934 }
00935 int fd=open("/dev/fpgaio", O_RDONLY);
00936 if (fd<0) {
00937 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/fpgaio");
00938 return ;
00939 }
00940 lseek (fd, addr,SEEK_SET) ;
00941 res=read(fd,&data,4);
00942 close (fd);
00943 if (res<4) {
00944 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not read file %s","/dev/fpgaio");
00945 return ;
00946 }
00947 RETURN_LONG(data);
00948 }
00949
00950 PHP_FUNCTION(elphel_fpga_write)
00951 {
00952 long addr,data,res;
00953 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &addr,&data) == FAILURE) {
00954 RETURN_NULL();
00955 }
00956 int fd=open("/dev/fpgaio", O_RDWR);
00957 if (fd<0) {
00958 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/fpgaio");
00959 return ;
00960 }
00961 lseek (fd, addr,SEEK_SET) ;
00962 res=write(fd,&data,4);
00963 close (fd);
00964 if (res<4) {
00965 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not write to file %s","/dev/fpgaio");
00966 return ;
00967 }
00968 RETURN_NULL();
00969 }
00970
00971
00972
00975 PHP_FUNCTION(elphel_get_P_value)
00976 {
00977 long addr;
00978
00979 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &addr) == FAILURE) {
00980 RETURN_NULL();
00981 }
00982 if ((addr<0) ||(addr>= (P_NUMBER * 4))) {
00983 RETURN_NULL();
00984 }
00985 init_sens();
00986 RETURN_LONG( ((long *) ELPHEL_G(imageParamsR))[addr]);
00987 }
00989 PHP_FUNCTION(elphel_set_P_value)
00990 {
00991 long addr;
00992 long data;
00993
00994 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &addr,&data) == FAILURE) {
00995 RETURN_NULL();
00996 }
00997 if ((addr<0) ||(addr>= (P_NUMBER * 2))) {
00998 RETURN_NULL();
00999 }
01000 if (addr>=P_NUMBER) addr-=P_NUMBER;
01001 else addr+=P_NUMBER;
01002 init_sens();
01003 ((long *) ELPHEL_G(imageParamsR))[addr]=data;
01004 RETURN_NULL();
01005 }
01006
01008 PHP_FUNCTION(elphel_get_state)
01009 {
01010 RETURN_LONG(lseek((int) ELPHEL_G( fd_sens), LSEEK_CAMSEQSTATE, SEEK_END ));
01011 }
01012
01014 PHP_FUNCTION(elphel_program_sensor)
01015 {
01016 long nonstop;
01017
01018 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &nonstop) == FAILURE) {
01019 RETURN_NULL();
01020 }
01021 init_sens();
01022 if (nonstop) lseek((int) ELPHEL_G( fd_sens), PROGRAM_SENSOR_1, SEEK_END );
01023 else lseek((int) ELPHEL_G( fd_sens), PROGRAM_SENSOR_0, SEEK_END );
01024 RETURN_NULL();
01025 }
01026
01028 PHP_FUNCTION(elphel_compressor_cmd)
01029 {
01030 long cmd;
01031 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &cmd) == FAILURE) {
01032 RETURN_NULL();
01033 }
01034 lseek((int) ELPHEL_G( fd_sens), cmd, SEEK_END );
01035 RETURN_NULL();
01036 }
01038 PHP_FUNCTION(elphel_compressor_reset)
01039 {
01040 lseek((int) ELPHEL_G( fd_sens), JPEG_CMD_RESET0, SEEK_END );
01041 RETURN_NULL();
01042 }
01043
01045 PHP_FUNCTION(elphel_compressor_run)
01046 {
01047 lseek((int) ELPHEL_G( fd_sens), JPEG_CMD_START, SEEK_END );
01048 RETURN_NULL();
01049 }
01050
01052
01053 PHP_FUNCTION(elphel_compressor_stop)
01054 {
01055 lseek((int) ELPHEL_G( fd_sens), JPEG_CMD_JUST_STOP, SEEK_END );
01056 RETURN_NULL();
01057 }
01059 PHP_FUNCTION(elphel_compressor_frame)
01060 {
01061 lseek((int) ELPHEL_G( fd_sens), JPEG_CMD_ACQUIRE, SEEK_END );
01062 RETURN_NULL();
01063 }
01064
01066 PHP_FUNCTION(elphel_is_compressor_idle)
01067 {
01068 int state= lseek((int) ELPHEL_G( fd_sens), LSEEK_CAMSEQSTATE, SEEK_END );
01069 if (state == 7) {RETURN_LONG (((((long *) ELPHEL_G(imageParamsR)) [P_COMPRESSOR_CMD])==0)?1:0);}
01070 else if (state > 7) {RETURN_LONG (0);}
01071 else {RETURN_LONG (1);}
01072 }
01073
01075 PHP_FUNCTION(elphel_reset_sensor) {
01076 lseek((int) ELPHEL_G( fd_sens), JPEG_CMD_RESET, SEEK_END );
01077 lseek((int) ELPHEL_G( fd_sens), LSEEK_RESET_SENSOR , SEEK_END );
01078 init_sens();
01079 RETURN_NULL();
01080 }
01081
01085 PHP_FUNCTION(elphel_set_fpga_time) {
01086 double dtime;
01087 long ltime_sec,ltime_usec;
01088 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &dtime) == FAILURE) {
01089 RETURN_NULL();
01090 }
01091 ltime_sec=dtime;
01092 ltime_usec=(dtime-ltime_sec)*1000000;
01093 ((long *) ELPHEL_G(imageParamsR)) [P_SECONDS+P_NUMBER] = ltime_sec;
01094 ((long *) ELPHEL_G(imageParamsR)) [P_MICROSECONDS+P_NUMBER] = ltime_usec;
01095 lseek((int) ELPHEL_G( fd_sens), LSEEK_SET_FPGA_TIME, SEEK_END );
01096 dtime=ltime_usec;
01097 dtime=ltime_sec+0.000001*dtime;
01098 RETURN_DOUBLE(dtime);
01099 }
01100
01102 PHP_FUNCTION(elphel_get_fpga_time) {
01103 double dtime;
01104 long ltime_sec,ltime_usec;
01105 lseek((int) ELPHEL_G( fd_sens), LSEEK_GET_FPGA_TIME, SEEK_END );
01106 dtime=((long *) ELPHEL_G(imageParamsR)) [P_MICROSECONDS];
01107 dtime=(((long *) ELPHEL_G(imageParamsR)) [P_SECONDS]) + 0.000001*dtime;
01108 RETURN_DOUBLE(dtime);
01109 }
01110
01112 PHP_FUNCTION(elphel_trigger)
01113 {
01114 lseek((int) ELPHEL_G( fd_sens), LSEEK_TRIGGER_PGM, SEEK_END );
01115 RETURN_NULL();
01116 }
01117
01118
01119 static void php_elphel_init_globals(zend_elphel_globals *elphel_globals)
01120 {
01122 elphel_globals->imageParamsR = NULL;
01123 elphel_globals->fd_sens= open("/dev/sensorpars", O_RDWR);
01124 if (elphel_globals->fd_sens <0) {
01125 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/sensorpars");
01126 return ;
01127 }
01129 elphel_globals->imageParamsR = (unsigned long *) mmap(0, P_NUMBER*4 *4 , PROT_READ | PROT_WRITE, MAP_SHARED, elphel_globals->fd_sens, 0);
01130 if((int)elphel_globals->imageParamsR == -1) {
01131 elphel_globals->imageParamsR=NULL;
01132
01133
01134 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap /dev/sensorpars");
01135 close (elphel_globals->fd_sens);
01136 elphel_globals->fd_sens = -1;
01137 return ;
01138 }
01140 elphel_globals->ccam_dma_buf = NULL;
01141 elphel_globals->fd_circ= open("/dev/circbuf", O_RDWR);
01142 if (elphel_globals->fd_circ <0) {
01143 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s","/dev/circbuf");
01144 return ;
01145 }
01146 elphel_globals->ccam_dma_buf_len=lseek(elphel_globals->fd_circ,0,SEEK_END);
01147
01149 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);
01150 if((int)elphel_globals->ccam_dma_buf == -1) {
01151 elphel_globals->ccam_dma_buf=NULL;
01152 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap /dev/circbuf");
01153 close (elphel_globals->fd_circ);
01154 elphel_globals->fd_circ = -1;
01155 return ;
01156 }
01157
01158
01159
01160
01162 elphel_globals->hist_gamma_mmap = NULL;
01163 elphel_globals->fd_autoexp = open(AUTOEXP_DEV_NAME, O_RDONLY);
01164 if (elphel_globals->fd_autoexp <0) {
01165 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",AUTOEXP_DEV_NAME);
01166 return ;
01167 }
01168 elphel_globals->hist_gamma_mmap = (void *) mmap(NULL, TABLES_LEN, PROT_READ, MAP_FIXED | MAP_SHARED, elphel_globals->fd_autoexp, 0);
01169 if(elphel_globals->hist_gamma_mmap == MAP_FAILED) {
01170 elphel_globals->hist_gamma_mmap=NULL;
01171 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error in mmap %s",AUTOEXP_DEV_NAME);
01172 close (elphel_globals->fd_autoexp);
01173 elphel_globals->fd_autoexp = -1;
01174 return ;
01175 }
01176 elphel_globals->fd_exif = open(EXIF_DEV_NAME, O_RDONLY);
01177 if (elphel_globals->fd_exif <0) {
01178 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",EXIF_DEV_NAME);
01179 return ;
01180 }
01181 elphel_globals->fd_exifdir = open(EXIFDIR_DEV_NAME, O_RDONLY);
01182 if (elphel_globals->fd_exifdir <0) {
01183 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",EXIFDIR_DEV_NAME);
01184 return ;
01185 }
01186 elphel_globals->fd_exifmeta = open(EXIFMETA_DEV_NAME, O_RDWR);
01187 if (elphel_globals->fd_exifmeta <0) {
01188 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Can not open file %s",EXIFMETA_DEV_NAME);
01189 return ;
01190 }
01191 elphel_globals->exif_size=0;
01192
01193
01194
01195
01196 }
01197
01198 PHP_RINIT_FUNCTION(elphel)
01199 {
01200
01201
01202 return SUCCESS;
01203 }
01204
01205 PHP_MINIT_FUNCTION(elphel)
01206 {
01207 ZEND_INIT_MODULE_GLOBALS(elphel, php_elphel_init_globals, NULL);
01208
01209 DEFINE_P_NAMES(pname_arr);
01210 int i;
01211 char full_constant_name[256];
01213 REGISTER_INI_ENTRIES();
01214 for (i=0;i< (sizeof(pname_arr)/sizeof(pname_arr[0])); i++) {
01215 sprintf (full_constant_name,"ELPHEL_%s",pname_arr[i].name);
01216 zend_register_long_constant(full_constant_name, strlen(full_constant_name)+1, pname_arr[i].value, (CONST_CS | CONST_PERSISTENT), module_number TSRMLS_CC);
01217 }
01218 return SUCCESS;
01219
01220 }
01221
01222 PHP_MSHUTDOWN_FUNCTION(elphel)
01223 {
01224 UNREGISTER_INI_ENTRIES();
01225 if (ELPHEL_G(imageParamsR)) ;
01226 if (ELPHEL_G(fd_sens)>=0) close (ELPHEL_G(fd_sens));
01227 if (ELPHEL_G(ccam_dma_buf)) ;
01228 if (ELPHEL_G(fd_circ)>=0) close (ELPHEL_G(fd_circ));
01229 if (ELPHEL_G(hist_gamma_mmap)) ;
01230 if (ELPHEL_G(fd_autoexp)>=0) close (ELPHEL_G(fd_autoexp));
01231 if (ELPHEL_G(fd_exif)>=0) close (ELPHEL_G(fd_exif));
01232 if (ELPHEL_G(fd_exifdir)>=0) close (ELPHEL_G(fd_exifdir));
01233 if (ELPHEL_G(fd_exifmeta)>=0) close (ELPHEL_G(fd_exifmeta));
01234 return SUCCESS;
01235 }
01236
01237 PHP_MINFO_FUNCTION(elphel)
01238 {
01239 php_info_print_table_start();
01240 php_info_print_table_row(2, "Elphel support", "Enabled");
01241 php_info_print_table_row(2, "Elphel API Version", PHP_ELPHEL_VERSION);
01242 php_info_print_table_end();
01243 }
01244