<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.elphel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dimitrios</id>
		<title>ElphelWiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.elphel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Dimitrios"/>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/wiki/Special:Contributions/Dimitrios"/>
		<updated>2026-05-12T11:03:04Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.28.0</generator>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Imgsrv&amp;diff=11270</id>
		<title>Imgsrv</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Imgsrv&amp;diff=11270"/>
				<updated>2012-02-17T01:49:40Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Updated imgsrv commands according to the imgsrv help page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/web/imgsrv/imgsrv.c?view=markup imgsrv] - Simple and fast HTTP server to provide still images and metadata acquired by the camera ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
This server was developed to increase the transfer rate of individual images acquired by the Elphel 353 series cameras as the CGI (and even fastCGI applications) connected through the universal web servers ([http://www.boa.org Boa], included with Axis SDK, currently on the default port 80 in camera and [http://www.lighttpd.net/ lighttpd] - now used in Elphel cameras together with php in fast CGI mode, port 81) failed to reach the top speed of the 100mbps network. Specialized imgsrv  is connected through a different port (currently listens to 8081) and writes GET responses directly to the socket (reading image data from the [[Circbuf|circbuf]] using zero-copy memory mapping mmap), reaching 9-10MB/sec - virtually the full bandwidth of the network. '''This server does not provide any control over the sensor or FPGA compressor operation, its only purpose is to get data acquired to the (currently 19 MB) circular buffer in the system RAM'''. It is intended to have the functionality similar to the camera video streamers that also deal with the data already being acquired to the system buffer to be used when individual images are needed rather than the continuous video stream .&lt;br /&gt;
&lt;br /&gt;
The imgsrv makes use of the new functionality of the [[Circbuf|/dev/circbuf]] driver providing it with a convenient web front end. It serves JPEG images (with Exif data attached) as well as metadata and [[Circbuf|circbuf]] status formatting output as the xml files.&lt;br /&gt;
&lt;br /&gt;
=== imgsrv usage ===&lt;br /&gt;
&lt;br /&gt;
imgsrv listens to the camera http port (currently 8081) and parses the rest of the url string as a series of commands, i.e.:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/towp/save&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/torp/wait/img/next/save&amp;lt;/nowiki&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
The above command will be interpreted as the following sequences:&lt;br /&gt;
&lt;br /&gt;
First command (needed once):&lt;br /&gt;
#set the current image pointer after the last image acquired;&lt;br /&gt;
#save the pointer to the &amp;quot;global&amp;quot; (shared by all applications that use it)  image pointer&lt;br /&gt;
&lt;br /&gt;
Second command (to be repeated for each image to be transfered):&lt;br /&gt;
#set the current image pointer to the global read pointer stored in the driver;&lt;br /&gt;
#wait for the image at that pointer to become available (it is possible that no waiting will actually take place if the image acquisition is ahead of the reading images out process. As far as the image readout process does not fall behind too far (by the size of the circbuf) it is OK.&lt;br /&gt;
#transfer compressed image to the client&lt;br /&gt;
#advance frame pointer to the next one&lt;br /&gt;
#and finally - save the new pointer to the global read pointer, so that the same url can be used over and over each time providing the next acquired image&lt;br /&gt;
&lt;br /&gt;
If issued with empty arguments (just &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/&amp;lt;/nowiki&amp;gt; ) imgsrv outputs a text file with the list of the valid commands.&lt;br /&gt;
&lt;br /&gt;
Commands are separated from the server url and from each other by the slashes (&amp;quot;/&amp;quot;), &amp;quot;?&amp;quot; and &amp;quot;&amp;amp;&amp;quot; also work. Each command is interpreted sequentially, from the left to the right. The /dev/circbuf file stays open for all the command sequence, so local image pointer stays valid from one command to the other.&lt;br /&gt;
&lt;br /&gt;
First group of the commands generates response data sent to the client, they are mutually exclusive and can appear only once in the command line (url). Each subsequent instances of such commands will be ignored. If none of the response-generating commands appear in the URL (but the url is not empty) the server will generate a minimalistic response - 1x1 pixel image. The commands of that group are the following:&lt;br /&gt;
&lt;br /&gt;
*'''img''' - send image at the current pointer (if it is the first command - use last acquired image - implied '''last''' command), if no image  is available and the current pointer server will not wait for the image to be acquired (see '''wait ''' below) but rather immediately return 1x1 GIF image to the client;&lt;br /&gt;
*'''bimg''' -same as above, but the whole image is stored in the camera outside of the circbuf before being sent to the client. It makes it safe from being overwritten by the new frames acquired by the camera. This option is useful when the camera is accessed from outside of the fast LAN over the slow network, it is safer and is recommended if the full frame rate is not required;&lt;br /&gt;
*'''simg''', '''sbimg''' - similar to img, bimg but will imemdiately suggest to save instead of opening image in the browser&lt;br /&gt;
*'''mimg[n]''' - send images as a multipart JPEG (all commands after will be ignored), possible to specify optional fps reduction i.e. mimg4 - skip 3 frames for each frame output (1/4 fps) &lt;br /&gt;
*'''bmimg[n]''' - same as above, buffered&lt;br /&gt;
*'''meta''' - send XML-formated metadata of the current frame instead of the image;&lt;br /&gt;
*'''pointers''' - send XML-formatted data about the circbuf frame pointers.&lt;br /&gt;
*'''frame''' - return current frame number as plain text&lt;br /&gt;
*'''wframe''' - wait for the next frame sync, return current frame number as plain text&lt;br /&gt;
&lt;br /&gt;
Next commands are designed on top of [[Circbuf|circbuf]] control commands:&lt;br /&gt;
*'''torp''' -  set frame pointer to the global read pointer, maintained by the camera driver. If frame at that pointer is invalid (i.e. overran by the next images), the '''scnd''' command (see below) is used instead;&lt;br /&gt;
*'''towp''' -  set frame pointer to hardware write pointer - position where next frame will be acquired;&lt;br /&gt;
*'''prev''' -  move to previous frame in buffer, nop if none are available;&lt;br /&gt;
*'''next''' -  move to the next frame in the buffer. Pointer will not go beyond write pointer that defines where the next frame will be acquired;&lt;br /&gt;
*'''last''' -  move to the most recently acquired frame, or to write pointer if there are none already acquiured. This command is automatically executed each time the imgsrv is called with a new line;&lt;br /&gt;
*'''first''' - move to the oldest frame still available in the buffer. It is not safe to rely on it if more frames are expected - data might be overwritten at any moment and the output image/meta data will be corrupted;&lt;br /&gt;
*'''second''' - move to the second oldest frame in the buffer - somewhat safer than the 'first' - there will be time for the &amp;quot;next&amp;quot; command at least before frame data (and pointer structures) will be overwritten;&lt;br /&gt;
*'''save'''   - save the current frame pointer as a global read pointer that holds it values between the server requests.  This pointer is shared between all the clients and applications that use it;&lt;br /&gt;
*'''wait'''   - Delay execution until there will be a frame at the current pointer ready.&lt;br /&gt;
&lt;br /&gt;
=== imgsrv and Exif data ===&lt;br /&gt;
&lt;br /&gt;
imgsrv supports Exif format and includes frame metadata in the image header. The Exif headers are generated in several steps.&lt;br /&gt;
*First, the Exif template (''/var/state/exif.template'') file is generated by the [[Exif_init.php|Exif_init.php]] script (during the system start up). The template generated is a binary file that is a valid Exif header itself. This script provides the &amp;quot;static&amp;quot; data (data that does not change between the frames), it also includes specific data that the script collects from various parts of the camera and camera software (like current firmware file name). Finally it provides a place holders for dynamic frame data to be replaced by the actual values by the imgsrv server;&lt;br /&gt;
*Next step happens during initialization of the imgsrv. At that time the ''/var/state/exif.template'' is read in, parsed and the pointers to the Exif data that imgsrv is aware of are stored in as internal list together with the maximal string lengths that imgsrv may use.&lt;br /&gt;
*Last step - imgsrv reads current frames meta data and uses it to fill the Exif fields at the pointers.&lt;br /&gt;
You may find documentation about Exif tags in [http://www.exiv2.org/tags.html Exif tags] or download an official [http://www.exif.org/Exif2-2.PDF Exif2-2.PDF]&lt;br /&gt;
The fields that are currently updated by imgsrv are the following (all the other fields are preserved as they are generated by the [[Exif_init.php|Exif_init.php]]):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Tag || IFD || Key || Type|| Description&lt;br /&gt;
|-&lt;br /&gt;
|0x0132||IFD0 ||DateTime||ASCII||Date/time of the image last modified. This field is likely to be modified later by image-processing software&lt;br /&gt;
|-&lt;br /&gt;
|0x9003||IFD1 ||DateTimeOriginal||ASCII||Date/time of the image acquisition. Here - start of the frame readout (or start of the exposure where applicable)&lt;br /&gt;
|-&lt;br /&gt;
|0x9291||IFD1 ||SubSecTimeOriginal||ASCII||Fractional seconds (digits after the decimal point) to be added to DateTimeOriginal field, 6 digits&lt;br /&gt;
|-&lt;br /&gt;
|0x829a||IFD1 ||ExposureTime||RATIONAL|| This field consists of 2 unsigned shorts that make exposure time (in seconds) as a rational number (the nominator divided by the denominator). With the current software denominator is a constant of 10000, imgsrv only updates the nominato&lt;br /&gt;
|-&lt;br /&gt;
|0x927c||IFD1 ||MakerNote||BYTE|| This custom field is defined in the camera as 36 bytes, they are filled with raw frame metadata - structure ''frame_params_t'' defined in [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/include/asm-cris/elphel/c313a.h?view=markup include/asm-cris/elphel/c313a.h]. Bytes go in CPU order, so the data is little-endian (the rest is big-endian)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Elphel_Software_Kit_for_Ubuntu&amp;diff=11267</id>
		<title>Elphel Software Kit for Ubuntu</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Elphel_Software_Kit_for_Ubuntu&amp;diff=11267"/>
				<updated>2012-02-11T15:25:09Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Fixed typo for ppa&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=About=&lt;br /&gt;
&lt;br /&gt;
This page is a simple howto for running Elphel software on (K)Ubuntu GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
You can download this GNU/Linux distribution freely from http://www.kubuntu.org/&lt;br /&gt;
&lt;br /&gt;
A Live ISO image with almost all the packages pre-installed (except [[Elphel_Software_Kit_for_Ubuntu#Installation_of_the_source_code_of_Elphel_camera_software|Elphel camera source]] code and [[Elphel_Software_Kit_for_Ubuntu#Installing_Xilinx_WebPack_.28to_be_moved_to_a_separate_page.2C_just_a_link_here.29|Xilinx ISE WebPack]]) is available for downloading from [http://community.elphel.com/files/live-dvd/ here].&lt;br /&gt;
&lt;br /&gt;
=If you are new to GNU / Linux=&lt;br /&gt;
Many forums and wikis are available in many languages to help you to install and use Ubuntu. Ex: http://www.google.com/search?q=forum+ubuntu (you can add &amp;quot;&amp;amp;hl=fr&amp;quot; or any language code to the URL)&lt;br /&gt;
&lt;br /&gt;
Most instructions below are commands that you need to enter in the in the terminal window. For the lines that do not end with &amp;quot;\&amp;quot; sign you just copy them one-by-one and paste in the terminal window (in KDE it is Konsole in the &amp;quot;System&amp;quot; menu). For pasting you '''can not''' use &amp;lt;cntrl-V&amp;gt; - you need to '''right-click in the terminal window and select &amp;quot;Paste&amp;quot;''' from the drop-down context menu. Alternatively you can use '''the middle mouse button''' to both copy (drag while middle mouse pressed) and paste - click it in the console window.&lt;br /&gt;
&lt;br /&gt;
Character &amp;quot;'''\'''&amp;quot; at the end of the line means continuation, so you can copy the whole block of text where each line but the very last ends with &amp;quot;\&amp;quot; and paste them together.&lt;br /&gt;
&lt;br /&gt;
Many of the commands start with &amp;quot;'''sudo'''&amp;quot; - first time system will ask you for your user password that you enter without any starts (provided you have administrative privileges).&lt;br /&gt;
&lt;br /&gt;
If you get some problems it is very useful to copy the error message that system outputs (avoiding anything specific to your particular installation - like user directories names) and paste them into the search box of you browser.&lt;br /&gt;
&lt;br /&gt;
=User software=&lt;br /&gt;
&lt;br /&gt;
Some software need to be patched and recompiled even if they exist in Ubuntu software repositories, some softwares are not yet packaged in Ubuntu, so you have to compile them from sources also. We try to push our software patches to the mainstream applications, but it take time and is not always possible. For Ubuntu users some packages can be downloaded and upgraded using our [https://launchpad.net/~elphel/+archive/ppa ppa on launchpad].&lt;br /&gt;
&lt;br /&gt;
 sudo add-apt-repository ppa:elphel/ppa&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
&lt;br /&gt;
==Mplayer - Ubuntu 9.10 or later==&lt;br /&gt;
'''Kubuntu 9.10 includes MPlayer that is working with Elphel camera &amp;quot;out of the box&amp;quot;'''&lt;br /&gt;
So for (K)Ubuntu 9.10 you just need to install&lt;br /&gt;
 sudo apt-get install mplayer-nogui mplayer gecko-mediaplayer&lt;br /&gt;
&lt;br /&gt;
===Mplayer - installation for (K)Ubuntu older than 9.10 release ===&lt;br /&gt;
&lt;br /&gt;
With the previous verions MPlayer has to be patched and recompiled, following instructions document how to do it on (K)Ubuntu or Debian based workstation.&lt;br /&gt;
&lt;br /&gt;
Install gecko-mediaplayer before compiling/installing MPlayer, if you do it later it will install non-patched version of MPlayer&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install gecko-mediaplayer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First install some compilation dependencies, mainly libraries...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- sudo apt-get install build-essential debhelper libncurses5-dev libesd0-dev liblircclient-dev libgtk2.0-dev \&lt;br /&gt;
 libvorbis-dev libsdl1.2-dev sharutils libasound2-dev liblzo-dev gawk libjpeg62-dev libaudiofile-dev \&lt;br /&gt;
 libsmbclient-dev libxv-dev libpng3-dev libgif-dev libcdparanoia0-dev libxvidcore4-dev libdv-dev \&lt;br /&gt;
 liblivemedia-dev libfreetype6-dev em8300-headers libgl1-mesa-dev libdvdread-dev libdts-dev libtheora-dev \&lt;br /&gt;
 libglu-dev libartsc0-dev libfontconfig-dev libxxf86dga-dev libxinerama-dev libxxf86vm-dev \&lt;br /&gt;
 libxvmc-dev libggi2-dev libmpcdec-dev libspeex-dev libfribidi-dev libfaac-dev  libaa1-dev libcaca-dev \&lt;br /&gt;
 libx264-dev  libpulse-dev libmad0-dev ladspa-sdk libdbus-glib-1-dev libaudio-dev liblzo2-dev libdvdnav-dev \&lt;br /&gt;
 libopenal-dev libjack-dev libtwolame-dev libsvga1-dev libenca-dev libmp3lame-dev&lt;br /&gt;
&lt;br /&gt;
'''If you are under Ubuntu 8.10 (Intrepid) replace liblame-dev at the end by libmp3lame-dev''' --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install build-essential debhelper libncurses5-dev libesd0-dev liblircclient-dev libgtk2.0-dev \&lt;br /&gt;
 libvorbis-dev libsdl1.2-dev sharutils libasound2-dev gawk libjpeg62-dev libaudiofile-dev \&lt;br /&gt;
 libsmbclient-dev libxv-dev libpng12-dev libgif-dev libcdparanoia-dev libdv4-dev \&lt;br /&gt;
 liblivemedia-dev libfreetype6-dev libgl1-mesa-dev libdvdread-dev libdts-dev libtheora-dev \&lt;br /&gt;
 libglu1-mesa-dev libfontconfig-dev libxxf86dga-dev libxinerama-dev libxxf86vm-dev \&lt;br /&gt;
 libxvmc-dev libggi2-dev libmpcdec-dev libspeex-dev libfribidi-dev libfaac-dev  libaa1-dev libcaca-dev \&lt;br /&gt;
 libx264-dev  libpulse-dev libmad0-dev ladspa-sdk libdbus-glib-1-dev libaudio-dev liblzo2-dev libdvdnav-dev \&lt;br /&gt;
 libopenal-dev libjack-dev libtwolame-dev libsvga1-dev libenca-dev libmp3lame-dev&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Get the MPlayer ubuntu source package:&lt;br /&gt;
 apt-get source mplayer&lt;br /&gt;
&lt;br /&gt;
patch the sources and compile:&lt;br /&gt;
 cd mplayer-1.0~rc2/&lt;br /&gt;
 sed s/\#define\ MAX_RTP_FRAME_SIZE\ 50000/\#define\ MAX_RTP_FRAME_SIZE\ 5000000/g \&lt;br /&gt;
 libmpdemux/demux_rtp.cpp &amp;gt; libmpdemux/demux_rtp.cpp_&lt;br /&gt;
 mv libmpdemux/demux_rtp.cpp_ libmpdemux/demux_rtp.cpp&lt;br /&gt;
 sudo dpkg-buildpackage &lt;br /&gt;
 cd ..&lt;br /&gt;
&lt;br /&gt;
install mplayer package:&lt;br /&gt;
 sudo dpkg  --install mplayer_1.0~rc2-0ubuntu*.deb&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Current MPlayer code is capable of working with full resolution video produced by Elphel cameras. That is not yet true for the MPlayer packages in Ubuntu repositories, so you'll have to obtain the source code from MPlayer recommended source - their Subversion (SVN) source. First you need to install Subversion itself:&lt;br /&gt;
 sudo apt-get install subversion&lt;br /&gt;
Now create a download directory and get MPlayer source:&lt;br /&gt;
 mkdir download; cd download&lt;br /&gt;
 svn checkout svn://svn.mplayerhq.hu/mplayer/trunk mplayer&lt;br /&gt;
Configure, compile and prepare Debian package from that source (will take some time):&lt;br /&gt;
 cd mplayer&lt;br /&gt;
 sudo dpkg-buildpackage &lt;br /&gt;
Occasionally dpkg-buildpackage fails to build, try the comon ./configure, make, make install way then.&lt;br /&gt;
&lt;br /&gt;
Now uninstall the default Ubuntu's mplayer and mencoder &amp;amp; install the created package:&lt;br /&gt;
 sudo apt-get remove mplayer mencoder mplayer-nogui&lt;br /&gt;
 cd ..&lt;br /&gt;
 sudo dpkg  --install mplayer_1.0svn*.deb&lt;br /&gt;
&lt;br /&gt;
===MPlayer - testing with Elphel camera ===&lt;br /&gt;
You should be able now to play videos with up to 5MB frames (highest quality 5MPix images are around 1 MB) as a multicast or unicast video stream. (the streamer in the camera should be ENABLED)&lt;br /&gt;
 mplayer rtsp://192.168.0.9:554 -vo x11 -fs -zoom&lt;br /&gt;
&lt;br /&gt;
''Update 10/09/2009: In (K)Ubuntu 9.10 (Karmic Koala) repository the '''50,000 bytes limit on the frame size''' is fixed, but unfortunately the [https://bugs.launchpad.net/ubuntu/+source/mplayer/+bug/296488 other one -'''frame width limit of 2048 pixels'''] (submitted to MPlayer SVN on May, 5, 2009) - is not''--[[User:Andrey.filippov|Andrey.filippov]] 19:03, 9 October 2009 (CDT)&lt;br /&gt;
&lt;br /&gt;
The first (50,000) makes you picture break after the first 50,000 bytes (only top is shown), the second (current for the 9.10) makes MPlayer to report fatal error. So you still have to use MPlayer SVN to have the full resolution from Elphel cameras.&lt;br /&gt;
&lt;br /&gt;
Additionally, to make MPlayer work inside the web page you need to specify video output as &amp;quot;x11&amp;quot; in the [http://howto.wikia.com/wiki/Howto_configure_MPlayer MPlayer config file] - add a line&lt;br /&gt;
 vo=&amp;quot;x11&amp;quot;&lt;br /&gt;
To ~/.mplayer/config file&lt;br /&gt;
&lt;br /&gt;
=For developers=&lt;br /&gt;
''Following was written for (K)Ubuntu 9.10 and earlier, it also works with 10.04, please see revision-specific notes.''&lt;br /&gt;
&lt;br /&gt;
==Adding universe and multiverse sources==&lt;br /&gt;
Please follow this howto for adding universe and multiverse sources. &lt;br /&gt;
&lt;br /&gt;
https://help.ubuntu.com/community/Repositories/Ubuntu&lt;br /&gt;
&lt;br /&gt;
or &lt;br /&gt;
&lt;br /&gt;
https://help.ubuntu.com/community/Repositories/Kubuntu&lt;br /&gt;
&lt;br /&gt;
==Install needed packages==&lt;br /&gt;
Minimal packages:&lt;br /&gt;
 sudo apt-get install cvs build-essential autoconf flex byacc bison libglib2.0-dev tcl gettext libncurses5-dev patch zlib1g-dev nfs-kernel-server bash xutils-dev&lt;br /&gt;
Suggested packages:&lt;br /&gt;
 sudo apt-get install kinfocenter minicom firefox graphviz doxygen ctags cervisia php5 php5-cli xchat ssh kompare git-core&lt;br /&gt;
&lt;br /&gt;
==Configure your NFS server==&lt;br /&gt;
&lt;br /&gt;
Let's say you want to configure an NFS server on your machine and your IP address is '''192.168.0.15'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Edit /etc/exports file with your favorite editor. Here I use nano.&lt;br /&gt;
 sudo nano -w /etc/exports&lt;br /&gt;
alternatively you may edit the same file with kate&lt;br /&gt;
 Those who know how to use nano will figure that out themselves --[[User:Andrey.filippov|Andrey.filippov]] 18:09, 23 May 2009 (CDT)&lt;br /&gt;
 --&amp;gt;&lt;br /&gt;
Modify the configuration file:&lt;br /&gt;
 kdesudo kate /etc/exports&lt;br /&gt;
Add at the end of the file:&lt;br /&gt;
 /nfs            192.168.0.0/255.255.0.0(rw,sync,no_root_squash)&lt;br /&gt;
save the file.&lt;br /&gt;
&lt;br /&gt;
If it does not yet exist make /nfs directory and make it world writable to make it possible to write logs from the camera.&lt;br /&gt;
 sudo mkdir /nfs&lt;br /&gt;
 sudo chmod 777 -R /nfs&lt;br /&gt;
&lt;br /&gt;
And finally export the filesystem.&lt;br /&gt;
 sudo exportfs -a&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation of GCC Compiler kit for Axis ETRAX processor ==&lt;br /&gt;
=== Automatic Installation ((K)Ubuntu 11.04 Natty Narwhal)===&lt;br /&gt;
1. &lt;br /&gt;
 sudo add-apt-repository ppa:elphel/ppa&lt;br /&gt;
 &lt;br /&gt;
 (The line above is equivalent to adding the following lines to your sources.list ('''sudo kate /etc/apt/sources.list''')):&lt;br /&gt;
 deb http://ppa.launchpad.net/elphel/ppa/ubuntu natty main &lt;br /&gt;
 deb-src http://ppa.launchpad.net/elphel/ppa/ubuntu natty main &lt;br /&gt;
&lt;br /&gt;
2.&lt;br /&gt;
 sudo apt-get update&lt;br /&gt;
 sudo apt-get install cris-dist&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Manual Installation ===&lt;br /&gt;
====Downloading and unpacking  gcc-cris====&lt;br /&gt;
Download and install Cris-GCC compiler. It is needed to compile C and C++ programs for the CPU used in Elphel cameras - [http://en.wikipedia.org/wiki/ETRAX_CRIS Axis ETRAX FS] :&lt;br /&gt;
 mkdir -p ~/Downloads/axis ; cd ~/Downloads/axis&lt;br /&gt;
 wget http://www.axis.com/ftp/pub/axis/tools/cris/compiler-kit/cris-dist-linux-headers-1.64.tar.gz   &lt;br /&gt;
 wget http://www.axis.com/ftp/pub/axis/tools/cris/compiler-kit/cris-dist-linux-headersv32-1.64.tar.gz  &lt;br /&gt;
 wget http://www.axis.com/ftp/pub/axis/tools/cris/compiler-kit/cris-dist-glibc-1.64.tar.gz &lt;br /&gt;
 wget http://www.axis.com/ftp/pub/axis/tools/cris/compiler-kit/cris-dist-1.64.tar.gz&lt;br /&gt;
 wget http://www.axis.com/ftp/pub/axis/tools/cris/compiler-kit/cris-dist-1.64-1--1.64-2.patch&lt;br /&gt;
 tar zxvf cris-dist-1.64.tar.gz&lt;br /&gt;
 cd cris-dist-1.64/&lt;br /&gt;
 tar zxvf ../cris-dist-linux-headers-1.64.tar.gz                                 &lt;br /&gt;
 tar zxvf ../cris-dist-linux-headersv32-1.64.tar.gz                             &lt;br /&gt;
 tar zxvf ../cris-dist-glibc-1.64.tar.gz&lt;br /&gt;
 patch -p0 &amp;lt; ../cris-dist-1.64-1--1.64-2.patch&lt;br /&gt;
&lt;br /&gt;
==== Compiling gcc-cris ====&lt;br /&gt;
Now you may proceed with compiling gcc-cris (takes some time):&lt;br /&gt;
                                         &lt;br /&gt;
 sudo ./install-cris-tools&lt;br /&gt;
answer by default (enter, enter, ...)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Don't forget to export the path to the cris-compiler - the defaul location is /usr/local/cris, as example&lt;br /&gt;
&lt;br /&gt;
 tobias@MoonbaseAlphaOne:~$ export PATH=$PATH:/usr/local/cris/bin&lt;br /&gt;
&lt;br /&gt;
If everything worked out well, you can check the compiler version with&lt;br /&gt;
&lt;br /&gt;
 gcc-cris --version&lt;br /&gt;
&lt;br /&gt;
Which should result in an output like this one (example, might vary with version)&lt;br /&gt;
&lt;br /&gt;
 cris-axis-elf-gcc (GCC) 3.2.1 Axis release R64/1.64&lt;br /&gt;
 Copyright (C) 2002 Free Software Foundation, Inc.&lt;br /&gt;
 This is free software; see the source for copying conditions.  There is NO&lt;br /&gt;
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Build Elphel Software==&lt;br /&gt;
Get the [http://sourceforge.net/projects/elphel/files/elphel353-8/install-8.0-fromcvs/elphel353_80_install_from_cvs.sh.tar.gz/download script]. Unpack &amp;amp; Launch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation of Kdevelop 3.5 ==&lt;br /&gt;
''note: Newer KDevelop 4 does not work with Elphel software''&lt;br /&gt;
==== pre (K)Ubuntu 9.10 ====&lt;br /&gt;
 sudo apt-get install kdevelop&lt;br /&gt;
&lt;br /&gt;
==== (K)Ubuntu 9.10 (Karmic), 10.4 (Lucid) ====&lt;br /&gt;
 see [[KDevelop#Installation_of_KDevelop_3.5_on_.28K.29Ubuntu_9.10|Installation of KDevelop 3.5 on (K)Ubuntu 9.10]]&lt;br /&gt;
&lt;br /&gt;
== Install Icarus Verilog and GTKWave ==&lt;br /&gt;
(If you plan to develop FPGA code or at least look how it works)&lt;br /&gt;
&lt;br /&gt;
GTKWave is OK from repository:&lt;br /&gt;
 sudo apt-get install gtkwave&lt;br /&gt;
&lt;br /&gt;
But unfortunately Icarus Verilog (package verilog) is compiled without needed support for compressed output format, so you'll have to compile it&lt;br /&gt;
 cd ~/Downloads&lt;br /&gt;
 wget &amp;quot;ftp://ftp.icarus.com/pub/eda/verilog/v0.9/verilog-0.9.3.tar.gz&amp;quot;&lt;br /&gt;
 tar zxvf verilog-0.9.3.tar.gz&lt;br /&gt;
 cd verilog-0.9.3/&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
== Installing Xilinx WebPack (to be moved to a separate page, just a link here)==&lt;br /&gt;
If you plan to compile the FPGA code from the source code you will need to install appropriate software from the FPGA manufacturer web site. This is proprietary (and non-free) software provided by [http://www.xilinx.com Xilinx] free of charge. This software is called the [http://www.xilinx.com/tools/webpack.htm ISE WebPACK] and you may download it (currently some 2.2GB) after registering at Xilinx web site. Currently tested version is 10.1.03, we'll try to update our code when Xilinx will release the new version of their software.&lt;br /&gt;
&lt;br /&gt;
You will also need that software if you would like to simulate the FPGA functionality. Elphel camera FPGA code (written in Verilog HDL) is  licensed under GNU GPLv3, simulator and waveform viewer (see below) are also Free Software, but there are a few Verilog models of some primitives of Xilinx FPGA that are not and can be only obtained from Xilinx as a part of their unisims library. For simulation we use small subset of the unisims library components and only for functional simulation so it will probably make sense to re-write those primitives models so the 2.2 GB distribution will not be needed to extract just few kilobytes of required source code.&lt;br /&gt;
&lt;br /&gt;
Such independent re-implementation will help us to solve another problem - we have to patch the Xilinx library components to make them work correctly with our code and the simulator we use and currently each Xilinx library update breaks our patches.&lt;br /&gt;
&lt;br /&gt;
When you will build Elphel software (as described later) the installation script will try to locate Xilinx software on your computer and patch a copy of unisims library. If you'll install Xilinx WebPack after building the camera software - you'll need to navigate to ''fpga'' subdirectory of the source tree and execute&lt;br /&gt;
 make clean ; make&lt;br /&gt;
It is described in file ''README.simulation'' in that subdirectory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are additional steps required for the Xilinx WebPACK installation if you have a 64-bit GNU/Linux operation system. The next command line detects if you are running on 64 bit version of GNU/Linux and conditionally installs '''ia64-libs'''. That library is needed if you'll install Xilinx WebPack software (Xilinx does not allow to use 64-bit programs in their free for download software and the provided installation script does not install 32-bit version on its own). There is [http://ubuntuforums.org/showthread.php?t=203459 another trick] you'll need to be aware of if you are using 32-bit Xilinx WebPack on a 64-bit GNU/Linux system.&lt;br /&gt;
 if [ `uname -m` = &amp;quot;x86_64&amp;quot; ] ; then sudo apt-get install ia32-libs ; fi&lt;br /&gt;
&lt;br /&gt;
==Installation of the source code of Elphel camera software==&lt;br /&gt;
&lt;br /&gt;
You may install Elphel source code by either of the two methods. Either from the CVS (the most current code) and form the tarball files. &lt;br /&gt;
===Installation from the CVS===&lt;br /&gt;
&lt;br /&gt;
Get [http://downloads.sourceforge.net/elphel/elphel353_80_install_from_cvs.sh.tar.gz elphel353_80_install_from_cvs.sh] open archive that contains the shell script and execute it. It is recommended that you create subdirectory in your home directory, i.e. &amp;quot;elphel_projects&amp;quot;, move and execute elphel353_80_install_from_cvs.sh script there. Directory &amp;quot;distfiles&amp;quot; will be created there and used as a cache for software archives that will be downloaded during installation.&lt;br /&gt;
&lt;br /&gt;
 mkdir -p ~/elphel_projects; cd ~/elphel_projects&lt;br /&gt;
 wget &amp;quot;http://downloads.sourceforge.net/elphel/elphel353_80_install_from_cvs.sh.tar.gz&amp;quot;&lt;br /&gt;
 tar zxvf elphel353_80_install_from_cvs.sh.tar.gz&lt;br /&gt;
 ./elphel353_80_install_from_cvs.sh&lt;br /&gt;
&lt;br /&gt;
===Installation from the tarball (release file)===&lt;br /&gt;
http://sourceforge.net/projects/elphel&lt;br /&gt;
&lt;br /&gt;
* get one of the elphel353-8.0.* releases&lt;br /&gt;
* decompress the archive&lt;br /&gt;
* execute the ./install_elphel script&lt;br /&gt;
 ./install_elphel&lt;br /&gt;
&lt;br /&gt;
There will be created a file build.log in the top installation directory. If you get any installation problems you can compress that file and email it to Elphel support.&lt;br /&gt;
&lt;br /&gt;
At the end of installation the script will generate a list of all the files in the target (camera) file system that are to be installed and compares it against the contents of the file ''target.list'' that is included in the distribution. If there are any differences -- they will be reported (there should be none). If there are some missing files it is likely that something failed to install correctly.&lt;br /&gt;
&lt;br /&gt;
After the installation will be completed successfully you may want to execute the following command in the top installation directory (the one that has apps, configure-files, ... subdirectories)&lt;br /&gt;
 ./prep_kdevelop.php&lt;br /&gt;
&lt;br /&gt;
That will create ''elphel353.kdevelop'' - a project file for KDevelop IDE  (version 3.5.x), you can use it as described here - [[KDevelop]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== ImageJ and Elphel plugins for imageJ ==&lt;br /&gt;
ImageJ is a powerful open source image processing package, written in Java. There are plugins to work with Elphel cameras, the most universal one allows opening JP46 files (stored on a file system or downloaded directly from the camera). This plugin reads meta data from the image and un-applies in-camera non-linear conversion resulting in the linearized image, where each pixel is represented by a floating point value proportional to the number of photons that were detected in that pixel.&lt;br /&gt;
&lt;br /&gt;
It is a very useful tool to do quantitative analysis of the camera images.&lt;br /&gt;
&lt;br /&gt;
===ImageJ installation ===&lt;br /&gt;
You may download ImageJ bundled with Java from the [http://rsbweb.nih.gov/ij/download.html download page]:&lt;br /&gt;
==== With 32-bit Java ==== &lt;br /&gt;
cd ~/Download; wget &amp;quot;http://rsbweb.nih.gov/ij/download/linux/ij143-x86.tar.gz&amp;quot; ; tar zxvf ij143-x86.tar.gz&lt;br /&gt;
==== With 64-bit Java ====&lt;br /&gt;
cd ~/Download; wget &amp;quot;http://rsbweb.nih.gov/ij/download/linux/ij143-linux64.tar.gz&amp;quot; ; tar zxvf ij143-linux64.tar.gz&lt;br /&gt;
 http://rsbweb.nih.gov/ij/download/linux/ij143-linux64.tar.gz - 64-bit Java version&lt;br /&gt;
===Running ImageJ ===&lt;br /&gt;
There is &amp;quot;run&amp;quot; command the newly crated directory. You may start ImageJ with the following command:&lt;br /&gt;
 /Downloads/ImageJ/run&lt;br /&gt;
That command allows Java to use 512M of system memory. If you need more you can change &amp;quot;512&amp;quot; to say &amp;quot;1024&amp;quot; in a single-line &amp;quot;run&amp;quot; script. If the run command is started from the command prompt, you'll be able to see some debug output - either from existent plugins or from your own ones. It is also very useful to see any error diagnostic output.&lt;br /&gt;
&lt;br /&gt;
=== Installation of Elphel plugins for ImageJ ===&lt;br /&gt;
Elphel plugins are available in Elphel project page Git repository. To use it you first need to install git (if it was not already done):&lt;br /&gt;
 sudo apt-get install git-core&lt;br /&gt;
&lt;br /&gt;
Then clone the repository - directly to the ImageJ plugins directory. Provided you used the same directory for ImageJ as written above:&lt;br /&gt;
 cd  ~/Downloads/ImageJ/plugins&lt;br /&gt;
 git clone git://elphel.git.sourceforge.net/gitroot/elphel/ImageJ-Elphel&lt;br /&gt;
&lt;br /&gt;
=== Updating Elphel plugins for ImageJ ===&lt;br /&gt;
Later, when you'll need to update your files from the repository you will need another command:&lt;br /&gt;
 cd  ~/Downloads/ImageJ/plugins/ImageJ-Elphel&lt;br /&gt;
 git pull&lt;br /&gt;
=== Running Elphel plugin for ImageJ ===&lt;br /&gt;
When you just install Elphel plugins you need to select&lt;br /&gt;
 ~/Downloads/ImageJ/plugins/ImageJ-Elphel/JP46_Reader_camera.java&lt;br /&gt;
That command will do exactly as it is named - first compile that source file to the Java bytecode, then execute it. Next time after you close and re-start ImageJ there will be a submenu in Plugins: Plugins-&amp;gt;ImageJ-Elphel and JP46_Reader_camera command there,&lt;br /&gt;
&lt;br /&gt;
When you'll update the source files, you 'll need to re-run &amp;quot;Compile and run...&amp;quot;. meanwhile just use the item in Plugins-&amp;gt;ImageJ-Elphel menu.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Imgsrv&amp;diff=11266</id>
		<title>Imgsrv</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Imgsrv&amp;diff=11266"/>
				<updated>2012-02-11T01:13:11Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/web/imgsrv/imgsrv.c?view=markup imgsrv] - Simple and fast HTTP server to provide still images and metadata acquired by the camera ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
This server was developed to increase the transfer rate of individual images acquired by the Elphel 353 series cameras as the CGI (and even fastCGI applications) connected through the universal web servers ([http://www.boa.org Boa], included with Axis SDK, currently on the default port 80 in camera and [http://www.lighttpd.net/ lighttpd] - now used in Elphel cameras together with php in fast CGI mode, port 81) failed to reach the top speed of the 100mbps network. Specialized imgsrv  is connected through a different port (currently listens to 8081) and writes GET responses directly to the socket (reading image data from the [[Circbuf|circbuf]] using zero-copy memory mapping mmap), reaching 9-10MB/sec - virtually the full bandwidth of the network. '''This server does not provide any control over the sensor or FPGA compressor operation, its only purpose is to get data acquired to the (currently 19 MB) circular buffer in the system RAM'''. It is intended to have the functionality similar to the camera video streamers that also deal with the data already being acquired to the system buffer to be used when individual images are needed rather than the continuous video stream .&lt;br /&gt;
&lt;br /&gt;
The imgsrv makes use of the new functionality of the [[Circbuf|/dev/circbuf]] driver providing it with a convenient web front end. It serves JPEG images (with Exif data attached) as well as metadata and [[Circbuf|circbuf]] status formatting output as the xml files.&lt;br /&gt;
&lt;br /&gt;
=== imgsrv usage ===&lt;br /&gt;
&lt;br /&gt;
imgsrv listens to the camera http port (currently 8081) and parses the rest of the url string as a series of commands, i.e.:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/towp/save&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/torp/wait/img/next/save&amp;lt;/nowiki&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
The above command will be interpreted as the following sequences:&lt;br /&gt;
&lt;br /&gt;
First command (needed once):&lt;br /&gt;
#set the current image pointer after the last image acquired;&lt;br /&gt;
#save the pointer to the &amp;quot;global&amp;quot; (shared by all applications that use it)  image pointer&lt;br /&gt;
&lt;br /&gt;
Second command (to be repeated for each image to be transfered):&lt;br /&gt;
#set the current image pointer to the global read pointer stored in the driver;&lt;br /&gt;
#wait for the image at that pointer to become available (it is possible that no waiting will actually take place if the image acquisition is ahead of the reading images out process. As far as the image readout process does not fall behind too far (by the size of the circbuf) it is OK.&lt;br /&gt;
#transfer compressed image to the client&lt;br /&gt;
#advance frame pointer to the next one&lt;br /&gt;
#and finally - save the new pointer to the global read pointer, so that the same url can be used over and over each time providing the next acquired image&lt;br /&gt;
&lt;br /&gt;
If issued with empty arguments (just &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/&amp;lt;/nowiki&amp;gt; ) imgsrv outputs a text file with the list of the valid commands.&lt;br /&gt;
&lt;br /&gt;
Commands are separated from the server url and from each other by the slashes (&amp;quot;/&amp;quot;), &amp;quot;?&amp;quot; and &amp;quot;&amp;amp;&amp;quot; also work. Each command is interpreted sequentially, from the left to the right. The /dev/circbuf file stays open for all the command sequence, so local image pointer stays valid from one command to the other.&lt;br /&gt;
&lt;br /&gt;
First group of the commands generates response data sent to the client, they are mutually exclusive and can appear only once in the command line (url). Each subsequent instances of such commands will be ignored. If none of the response-generating commands appear in the URL (but the url is not empty) the server will generate a minimalistic response - 1x1 pixel image. The commands of that group are the following:&lt;br /&gt;
&lt;br /&gt;
*'''img''' - send image at the current pointer (if it is the first command - use last acquired image - implied '''last''' command), if no image  is available and the current pointer server will not wait for the image to be acquired (see '''wait ''' below) but rather immediately return 1x1 GIF image to the client;&lt;br /&gt;
*'''bimg''' -same as above, but the whole image is stored in the camera outside of the circbuf before being sent to the client. It makes it safe from being overwritten by the new frames acquired by the camera. This option is useful when the camera is accessed from outside of the fast LAN over the slow network, it is safer and is recommended if the full frame rate is not required;&lt;br /&gt;
*'''mimg''' - send a stream of images at the current pointer as MJPEG (HTTP header, ''Content-type: multipart/x-mixed-replace''); like '''img''' but for an MJPEG stream.&lt;br /&gt;
*'''mbimg''' - same as above, but the images are stored in the camera outside of the circbuf before being sent to the client.&lt;br /&gt;
*'''meta''' - send XML-formated metadata of the current frame instead of the image;&lt;br /&gt;
*'''pointers''' - send XML-formatted data about the circbuf frame pointers.&lt;br /&gt;
&lt;br /&gt;
Next commands are designed on top of [[Circbuf|circbuf]] control commands:&lt;br /&gt;
*'''torp''' -  set frame pointer to the global read pointer, maintained by the camera driver. If frame at that pointer is invalid (i.e. overran by the next images), the '''scnd''' command (see below) is used instead;&lt;br /&gt;
*'''towp''' -  set frame pointer to hardware write pointer - position where next frame will be acquired;&lt;br /&gt;
*'''prev''' -  move to previous frame in buffer, nop if none are available;&lt;br /&gt;
*'''next''' -  move to the next frame in the buffer. Pointer will not go beyond write pointer that defines where the next frame will be acquired;&lt;br /&gt;
*'''last''' -  move to the most recently acquired frame, or to write pointer if there are none already acquiured. This command is automatically executed each time the imgsrv is called with a new line;&lt;br /&gt;
*'''first''' - move to the oldest frame still available in the buffer. It is not safe to rely on it if more frames are expected - data might be overwritten at any moment and the output image/meta data will be corrupted;&lt;br /&gt;
*'''second''' - move to the second oldest frame in the buffer - somewhat safer than the 'first' - there will be time for the &amp;quot;next&amp;quot; command at least before frame data (and pointer structures) will be overwritten;&lt;br /&gt;
*'''save'''   - save the current frame pointer as a global read pointer that holds it values between the server requests.  This pointer is shared between all the clients and applications that use it;&lt;br /&gt;
*'''wait'''   - Delay execution until there will be a frame at the current pointer ready.&lt;br /&gt;
&lt;br /&gt;
=== imgsrv and Exif data ===&lt;br /&gt;
&lt;br /&gt;
imgsrv supports Exif format and includes frame metadata in the image header. The Exif headers are generated in several steps.&lt;br /&gt;
*First, the Exif template (''/var/state/exif.template'') file is generated by the [[Exif_init.php|Exif_init.php]] script (during the system start up). The template generated is a binary file that is a valid Exif header itself. This script provides the &amp;quot;static&amp;quot; data (data that does not change between the frames), it also includes specific data that the script collects from various parts of the camera and camera software (like current firmware file name). Finally it provides a place holders for dynamic frame data to be replaced by the actual values by the imgsrv server;&lt;br /&gt;
*Next step happens during initialization of the imgsrv. At that time the ''/var/state/exif.template'' is read in, parsed and the pointers to the Exif data that imgsrv is aware of are stored in as internal list together with the maximal string lengths that imgsrv may use.&lt;br /&gt;
*Last step - imgsrv reads current frames meta data and uses it to fill the Exif fields at the pointers.&lt;br /&gt;
You may find documentation about Exif tags in [http://www.exiv2.org/tags.html Exif tags] or download an official [http://www.exif.org/Exif2-2.PDF Exif2-2.PDF]&lt;br /&gt;
The fields that are currently updated by imgsrv are the following (all the other fields are preserved as they are generated by the [[Exif_init.php|Exif_init.php]]):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Tag || IFD || Key || Type|| Description&lt;br /&gt;
|-&lt;br /&gt;
|0x0132||IFD0 ||DateTime||ASCII||Date/time of the image last modified. This field is likely to be modified later by image-processing software&lt;br /&gt;
|-&lt;br /&gt;
|0x9003||IFD1 ||DateTimeOriginal||ASCII||Date/time of the image acquisition. Here - start of the frame readout (or start of the exposure where applicable)&lt;br /&gt;
|-&lt;br /&gt;
|0x9291||IFD1 ||SubSecTimeOriginal||ASCII||Fractional seconds (digits after the decimal point) to be added to DateTimeOriginal field, 6 digits&lt;br /&gt;
|-&lt;br /&gt;
|0x829a||IFD1 ||ExposureTime||RATIONAL|| This field consists of 2 unsigned shorts that make exposure time (in seconds) as a rational number (the nominator divided by the denominator). With the current software denominator is a constant of 10000, imgsrv only updates the nominato&lt;br /&gt;
|-&lt;br /&gt;
|0x927c||IFD1 ||MakerNote||BYTE|| This custom field is defined in the camera as 36 bytes, they are filled with raw frame metadata - structure ''frame_params_t'' defined in [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/include/asm-cris/elphel/c313a.h?view=markup include/asm-cris/elphel/c313a.h]. Bytes go in CPU order, so the data is little-endian (the rest is big-endian)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Imgsrv&amp;diff=11265</id>
		<title>Imgsrv</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Imgsrv&amp;diff=11265"/>
				<updated>2012-02-11T01:10:33Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Added undocummented commands mimg and mbimg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/web/imgsrv/imgsrv.c?view=markup imgsrv] - Simple and fast HTTP server to provide still images and metadata acquired by the camera ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
This server was developed to increase the transfer rate of individual images acquired by the Elphel 353 series cameras as the CGI (and even fastCGI applications) connected through the universal web servers ([http://www.boa.org Boa], included with Axis SDK, currently on the default port 80 in camera and [http://www.lighttpd.net/ lighttpd] - now used in Elphel cameras together with php in fast CGI mode, port 81) failed to reach the top speed of the 100mbps network. Specialized imgsrv  is connected through a different port (currently listens to 8081) and writes GET responses directly to the socket (reading image data from the [[Circbuf|circbuf]] using zero-copy memory mapping mmap), reaching 9-10MB/sec - virtually the full bandwidth of the network. '''This server does not provide any control over the sensor or FPGA compressor operation, its only purpose is to get data acquired to the (currently 19 MB) circular buffer in the system RAM'''. It is intended to have the functionality similar to the camera video streamers that also deal with the data already being acquired to the system buffer to be used when individual images are needed rather than the continuous video stream .&lt;br /&gt;
&lt;br /&gt;
The imgsrv makes use of the new functionality of the [[Circbuf|/dev/circbuf]] driver providing it with a convenient web front end. It serves JPEG images (with Exif data attached) as well as metadata and [[Circbuf|circbuf]] status formatting output as the xml files.&lt;br /&gt;
&lt;br /&gt;
=== imgsrv usage ===&lt;br /&gt;
&lt;br /&gt;
imgsrv listens to the camera http port (currently 8081) and parses the rest of the url string as a series of commands, i.e.:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/towp/save&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/torp/wait/img/next/save&amp;lt;/nowiki&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
The above command will be interpreted as the following sequences:&lt;br /&gt;
&lt;br /&gt;
First command (needed once):&lt;br /&gt;
#set the current image pointer after the last image acquired;&lt;br /&gt;
#save the pointer to the &amp;quot;global&amp;quot; (shared by all applications that use it)  image pointer&lt;br /&gt;
&lt;br /&gt;
Second command (to be repeated for each image to be transfered):&lt;br /&gt;
#set the current image pointer to the global read pointer stored in the driver;&lt;br /&gt;
#wait for the image at that pointer to become available (it is possible that no waiting will actually take place if the image acquisition is ahead of the reading images out process. As far as the image readout process does not fall behind too far (by the size of the circbuf) it is OK.&lt;br /&gt;
#transfer compressed image to the client&lt;br /&gt;
#advance frame pointer to the next one&lt;br /&gt;
#and finally - save the new pointer to the global read pointer, so that the same url can be used over and over each time providing the next acquired image&lt;br /&gt;
&lt;br /&gt;
If issued with empty arguments (just &amp;lt;nowiki&amp;gt;http://&amp;lt;camera_ip&amp;gt;:8081/&amp;lt;/nowiki&amp;gt; ) imgsrv outputs a text file with the list of the valid commands.&lt;br /&gt;
&lt;br /&gt;
Commands are separated from the server url and from each other by the slashes (&amp;quot;/&amp;quot;), &amp;quot;?&amp;quot; and &amp;quot;&amp;amp;&amp;quot; also work. Each command is interpreted sequentially, from the left to the right. The /dev/circbuf file stays open for all the command sequence, so local image pointer stays valid from one command to the other.&lt;br /&gt;
&lt;br /&gt;
First group of the commands generates response data sent to the client, they are mutually exclusive and can appear only once in the command line (url). Each subsequent instances of such commands will be ignored. If none of the response-generating commands appear in the URL (but the url is not empty) the server will generate a minimalistic response - 1x1 pixel image. The commands of that group are the following:&lt;br /&gt;
&lt;br /&gt;
*'''img''' - send image at the current pointer (if it is the first command - use last acquired image - implied '''last''' command), if no image  is available and the current pointer server will not wait for the image to be acquired (see '''wait ''' below) but rather immediately return 1x1 GIF image to the client;&lt;br /&gt;
*'''bimg''' -same as above, but the whole image is stored in the camera outside of the circbuf before being sent to the client. It makes it safe from being overwritten by the new frames acquired by the camera. This option is useful when the camera is accessed from outside of the fast LAN over the slow network, it is safer and is recommended if the full frame rate is not required;&lt;br /&gt;
*'''mimg''' - send a stream of images at the current pointer as MJPEG ('''Content-type: multipart/x-mixed-replace'''); like '''img''' but for an MJPEG stream.&lt;br /&gt;
*'''mbimg''' - same as above, but the images are stored in the camera outside of the circbuf before being sent to the client. *'''meta''' - send XML-formated metadata of the current frame instead of the image;&lt;br /&gt;
*'''pointers''' - send XML-formatted data about the circbuf frame pointers.&lt;br /&gt;
&lt;br /&gt;
Next commands are designed on top of [[Circbuf|circbuf]] control commands:&lt;br /&gt;
*'''torp''' -  set frame pointer to the global read pointer, maintained by the camera driver. If frame at that pointer is invalid (i.e. overran by the next images), the '''scnd''' command (see below) is used instead;&lt;br /&gt;
*'''towp''' -  set frame pointer to hardware write pointer - position where next frame will be acquired;&lt;br /&gt;
*'''prev''' -  move to previous frame in buffer, nop if none are available;&lt;br /&gt;
*'''next''' -  move to the next frame in the buffer. Pointer will not go beyond write pointer that defines where the next frame will be acquired;&lt;br /&gt;
*'''last''' -  move to the most recently acquired frame, or to write pointer if there are none already acquiured. This command is automatically executed each time the imgsrv is called with a new line;&lt;br /&gt;
*'''first''' - move to the oldest frame still available in the buffer. It is not safe to rely on it if more frames are expected - data might be overwritten at any moment and the output image/meta data will be corrupted;&lt;br /&gt;
*'''second''' - move to the second oldest frame in the buffer - somewhat safer than the 'first' - there will be time for the &amp;quot;next&amp;quot; command at least before frame data (and pointer structures) will be overwritten;&lt;br /&gt;
*'''save'''   - save the current frame pointer as a global read pointer that holds it values between the server requests.  This pointer is shared between all the clients and applications that use it;&lt;br /&gt;
*'''wait'''   - Delay execution until there will be a frame at the current pointer ready.&lt;br /&gt;
&lt;br /&gt;
=== imgsrv and Exif data ===&lt;br /&gt;
&lt;br /&gt;
imgsrv supports Exif format and includes frame metadata in the image header. The Exif headers are generated in several steps.&lt;br /&gt;
*First, the Exif template (''/var/state/exif.template'') file is generated by the [[Exif_init.php|Exif_init.php]] script (during the system start up). The template generated is a binary file that is a valid Exif header itself. This script provides the &amp;quot;static&amp;quot; data (data that does not change between the frames), it also includes specific data that the script collects from various parts of the camera and camera software (like current firmware file name). Finally it provides a place holders for dynamic frame data to be replaced by the actual values by the imgsrv server;&lt;br /&gt;
*Next step happens during initialization of the imgsrv. At that time the ''/var/state/exif.template'' is read in, parsed and the pointers to the Exif data that imgsrv is aware of are stored in as internal list together with the maximal string lengths that imgsrv may use.&lt;br /&gt;
*Last step - imgsrv reads current frames meta data and uses it to fill the Exif fields at the pointers.&lt;br /&gt;
You may find documentation about Exif tags in [http://www.exiv2.org/tags.html Exif tags] or download an official [http://www.exif.org/Exif2-2.PDF Exif2-2.PDF]&lt;br /&gt;
The fields that are currently updated by imgsrv are the following (all the other fields are preserved as they are generated by the [[Exif_init.php|Exif_init.php]]):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Tag || IFD || Key || Type|| Description&lt;br /&gt;
|-&lt;br /&gt;
|0x0132||IFD0 ||DateTime||ASCII||Date/time of the image last modified. This field is likely to be modified later by image-processing software&lt;br /&gt;
|-&lt;br /&gt;
|0x9003||IFD1 ||DateTimeOriginal||ASCII||Date/time of the image acquisition. Here - start of the frame readout (or start of the exposure where applicable)&lt;br /&gt;
|-&lt;br /&gt;
|0x9291||IFD1 ||SubSecTimeOriginal||ASCII||Fractional seconds (digits after the decimal point) to be added to DateTimeOriginal field, 6 digits&lt;br /&gt;
|-&lt;br /&gt;
|0x829a||IFD1 ||ExposureTime||RATIONAL|| This field consists of 2 unsigned shorts that make exposure time (in seconds) as a rational number (the nominator divided by the denominator). With the current software denominator is a constant of 10000, imgsrv only updates the nominato&lt;br /&gt;
|-&lt;br /&gt;
|0x927c||IFD1 ||MakerNote||BYTE|| This custom field is defined in the camera as 36 bytes, they are filled with raw frame metadata - structure ''frame_params_t'' defined in [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/include/asm-cris/elphel/c313a.h?view=markup include/asm-cris/elphel/c313a.h]. Bytes go in CPU order, so the data is little-endian (the rest is big-endian)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11261</id>
		<title>PHP and Gamma values</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11261"/>
				<updated>2012-02-09T01:08:36Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Fixed an error in frames ahead&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=How to change Gamma values in an Elphel camera=&lt;br /&gt;
&lt;br /&gt;
Changing Gamma and BlackLevel values at present requires some special treatment. Here is a short PHP script that does it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
 // Set default frame ahead&lt;br /&gt;
 if (!array_key_exists(&amp;quot;ahead&amp;quot;,$_GET))&lt;br /&gt;
 	$ahead=3;&lt;br /&gt;
 &lt;br /&gt;
 // Special treatment for the gamma values and blacklevel.&lt;br /&gt;
 // Get exising gamma values  if a gamma parameter is requested&lt;br /&gt;
 if (array_key_exists(&amp;quot;gamma&amp;quot;,$_GET) || array_key_exists(&amp;quot;black&amp;quot;,$_GET)) {&lt;br /&gt;
 	$gammas=array(&lt;br /&gt;
 		&amp;quot;GTAB_R__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_R__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;&lt;br /&gt;
 		);&lt;br /&gt;
 	// get existing gamma values&lt;br /&gt;
 	$gammas= elphel_get_P_arr($gammas);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 foreach($_GET as $key=&amp;gt;$value) {&lt;br /&gt;
 	&lt;br /&gt;
 	if(strtolower(substr($s, 0, 2))==&amp;quot;0x&amp;quot;)&lt;br /&gt;
 		$value= hexdec($value);&lt;br /&gt;
 	switch ($key) {&lt;br /&gt;
 		case &amp;quot;gamma&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_R__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_G__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_GB__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_B__0816&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case &amp;quot;black&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_R__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_G__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_GB__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_B__0824&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	// If any gamma value was set, set all gamma values in the camera.&lt;br /&gt;
 	// Was postponed earlier&lt;br /&gt;
 	if ($gammas != NULL) {&lt;br /&gt;
  		// values are taken from the green color&lt;br /&gt;
  		elphel_gamma_add($gammas[&amp;quot;GTAB_G__0816&amp;quot;]/100, $gammas[&amp;quot;GTAB_G__0824&amp;quot;]);&lt;br /&gt;
 		// Apply the values at the frame ahead&lt;br /&gt;
 		elphel_set_P_arr($gammas, elphel_get_frame() + $ahead);&lt;br /&gt;
 	}&lt;br /&gt;
 	//&lt;br /&gt;
 	// Add code to form the output here&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code looks for HTTP query parameters ''black'' (level of black) and ''gamma'' and sets them at the same time. &lt;br /&gt;
&lt;br /&gt;
The parameters should be integers: ''1 &amp;lt; gamma &amp;lt;= 100'' and ''0 &amp;lt;= black &amp;lt;= 50''.&lt;br /&gt;
&lt;br /&gt;
The undocumented function '''elphel_gamma_add(int gamma, int black)''' is used, where the value of ''gamma'' for this function must be a float ''0.1 &amp;lt; gamma &amp;lt;= 1.0''. Without it the gamma values are not effected. Relative code can be found in the file ''camvc.php'' in ''/mnt/flash/html'' in the camera.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11257</id>
		<title>PHP and Gamma values</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11257"/>
				<updated>2012-02-08T19:51:48Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=How to change Gamma values in an Elphel camera=&lt;br /&gt;
&lt;br /&gt;
Changing Gamma and BlackLevel values at present requires some special treatment. Here is a short PHP script that does it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
 // Set default frame ahead&lt;br /&gt;
 if (!array_key_exists(&amp;quot;ahead&amp;quot;,$_GET))&lt;br /&gt;
 	$ahead=3;&lt;br /&gt;
 &lt;br /&gt;
 // Special treatment for the gamma values and blacklevel.&lt;br /&gt;
 // Get exising gamma values  if a gamma parameter is requested&lt;br /&gt;
 if (array_key_exists(&amp;quot;gamma&amp;quot;,$_GET) || array_key_exists(&amp;quot;black&amp;quot;,$_GET)) {&lt;br /&gt;
 	$gammas=array(&lt;br /&gt;
 		&amp;quot;GTAB_R__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_R__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;&lt;br /&gt;
 		);&lt;br /&gt;
 	// get existing gamma values&lt;br /&gt;
 	$gammas= elphel_get_P_arr($gammas);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 foreach($_GET as $key=&amp;gt;$value) {&lt;br /&gt;
 	&lt;br /&gt;
 	if(strtolower(substr($s, 0, 2))==&amp;quot;0x&amp;quot;)&lt;br /&gt;
 		$value= hexdec($value);&lt;br /&gt;
 	switch ($key) {&lt;br /&gt;
 		case &amp;quot;gamma&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_R__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_G__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_GB__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_B__0816&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case &amp;quot;black&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_R__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_G__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_GB__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_B__0824&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	// If any gamma value was set, set all gamma values in the camera.&lt;br /&gt;
 	// Was postponed earlier&lt;br /&gt;
 	if ($gammas != NULL) {&lt;br /&gt;
  		// values are taken from the green color&lt;br /&gt;
  		elphel_gamma_add($gammas[&amp;quot;GTAB_G__0816&amp;quot;]/100, $gammas[&amp;quot;GTAB_G__0824&amp;quot;]);&lt;br /&gt;
 		// Apply the values at the frame ahead&lt;br /&gt;
 		elphel_set_P_arr($gammas,$ahead);&lt;br /&gt;
 	}&lt;br /&gt;
 	//&lt;br /&gt;
 	// Add code to form the output here&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code looks for HTTP query parameters ''black'' (level of black) and ''gamma'' and sets them at the same time. &lt;br /&gt;
&lt;br /&gt;
The parameters should be integers: ''1 &amp;lt; gamma &amp;lt;= 100'' and ''0 &amp;lt;= black &amp;lt;= 50''.&lt;br /&gt;
&lt;br /&gt;
The undocumented function '''elphel_gamma_add(int gamma, int black)''' is used, where the value of ''gamma'' for this function must be a float ''0.1 &amp;lt; gamma &amp;lt;= 1.0''. Without it the gamma values are not effected. Relative code can be found in the file ''camvc.php'' in ''/mnt/flash/html'' in the camera.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11256</id>
		<title>PHP and Gamma values</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11256"/>
				<updated>2012-02-08T19:28:48Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=How to change Gamma values in an Elphel camera=&lt;br /&gt;
&lt;br /&gt;
Changing Gamma and BlackLevel values at present requires some special treatment. Here is a short PHP script that does it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
 // Set default frame ahead&lt;br /&gt;
 if (!array_key_exists(&amp;quot;ahead&amp;quot;,$_GET))&lt;br /&gt;
 	$ahead=3;&lt;br /&gt;
 &lt;br /&gt;
 // Special treatment for the gamma values and blacklevel.&lt;br /&gt;
 // Get exising gamma values  if a gamma parameter is requested&lt;br /&gt;
 if (array_key_exists(&amp;quot;gamma&amp;quot;,$_GET) || array_key_exists(&amp;quot;black&amp;quot;,$_GET)) {&lt;br /&gt;
 	$gammas=array(&lt;br /&gt;
 		&amp;quot;GTAB_R__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_R__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;&lt;br /&gt;
 		);&lt;br /&gt;
 	// get existing gamma values&lt;br /&gt;
 	$gammas= elphel_get_P_arr($gammas);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 foreach($_GET as $key=&amp;gt;$value) {&lt;br /&gt;
 	&lt;br /&gt;
 	if(strtolower(substr($s, 0, 2))==&amp;quot;0x&amp;quot;)&lt;br /&gt;
 		$value= hexdec($value);&lt;br /&gt;
 	switch ($key) {&lt;br /&gt;
 		case &amp;quot;gamma&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_R__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_G__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_GB__0816&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_B__0816&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case &amp;quot;black&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_R__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_G__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_GB__0824&amp;quot;]=$value;&lt;br /&gt;
 			$gammas[&amp;quot;GTAB_B__0824&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	// If any gamma value was set, set all gamma values in the camera.&lt;br /&gt;
 	// Was postponed earlier&lt;br /&gt;
 	if ($gammas != NULL) {&lt;br /&gt;
  		// values are taken from the green color&lt;br /&gt;
  		elphel_gamma_add($gammas[&amp;quot;GTAB_G__0816&amp;quot;]/100, $gammas[&amp;quot;GTAB_G__0824&amp;quot;]);&lt;br /&gt;
 		// Apply the values at the frame ahead&lt;br /&gt;
 		elphel_set_P_arr($gammas,$ahead);&lt;br /&gt;
 	}&lt;br /&gt;
 	//&lt;br /&gt;
 	// Add code to form the output here&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code looks for HTTP query parameters ''black'' (level of black) and ''gamma'' and sets them at the same time. &lt;br /&gt;
&lt;br /&gt;
The parameters should be integers: ''1 &amp;lt; gamma &amp;lt;= 100'' and ''0 &amp;lt;= black &amp;lt;= 50''.&lt;br /&gt;
&lt;br /&gt;
The undocumented function '''elphel_gamma_add(int gamma, int black)''' is used, where the value of ''gamma'' for this function must be a float ''0.1 &amp;lt; gamma &amp;lt;= 1.0''. Without it the gamma values are not effected. More can be found in the file ''camvc.php'' in ''/mnt/flash/html''.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11255</id>
		<title>PHP and Gamma values</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11255"/>
				<updated>2012-02-08T19:12:08Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=How to change Gamma values in an Elphel camera=&lt;br /&gt;
&lt;br /&gt;
Changing Gamma and BlackLevel values at present requires some special treatment. Here is a short PHP script that does it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
 // Set default frame ahead&lt;br /&gt;
 if (!array_key_exists(&amp;quot;ahead&amp;quot;,$_GET))&lt;br /&gt;
 	$ahead=3;&lt;br /&gt;
 &lt;br /&gt;
 // Special treatment for the gamma values and blacklevel.&lt;br /&gt;
 // Get exising gamma values  if a gamma parameter is requested&lt;br /&gt;
 if (array_key_exists(&amp;quot;gamma&amp;quot;,$_GET) || array_key_exists(&amp;quot;black&amp;quot;,$_GET)) {&lt;br /&gt;
 	$gammas=array(&lt;br /&gt;
 		&amp;quot;GTAB_R__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_R__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;&lt;br /&gt;
 		);&lt;br /&gt;
 	// get existing gamma values&lt;br /&gt;
 	$gammas= elphel_get_P_arr($gammas);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 foreach($_GET as $key=&amp;gt;$value) {&lt;br /&gt;
 	&lt;br /&gt;
 	if(strtolower(substr($s, 0, 2))==&amp;quot;0x&amp;quot;)&lt;br /&gt;
 		$value= hexdec($value);&lt;br /&gt;
 	switch ($key) {&lt;br /&gt;
 		case &amp;quot;gamma&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
			$gammas[&amp;quot;GTAB_R__0816&amp;quot;]=$value;&lt;br /&gt;
			$gammas[&amp;quot;GTAB_G__0816&amp;quot;]=$value;&lt;br /&gt;
			$gammas[&amp;quot;GTAB_GB__0816&amp;quot;]=$value;&lt;br /&gt;
			$gammas[&amp;quot;GTAB_B__0816&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case &amp;quot;black&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
			$gammas[&amp;quot;GTAB_R__0824&amp;quot;]=$value;&lt;br /&gt;
			$gammas[&amp;quot;GTAB_G__0824&amp;quot;]=$value;&lt;br /&gt;
			$gammas[&amp;quot;GTAB_GB__0824&amp;quot;]=$value;&lt;br /&gt;
			$gammas[&amp;quot;GTAB_B__0824&amp;quot;]=$value;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	// If any gamma value was set, set all gamma values in the camera.&lt;br /&gt;
 	// Was postponed earlier&lt;br /&gt;
 	if ($gammas != NULL) {&lt;br /&gt;
  		// values are taken from the green color&lt;br /&gt;
  		elphel_gamma_add($gammas[&amp;quot;GTAB_G__0816&amp;quot;]/100, $gammas[&amp;quot;GTAB_G__0824&amp;quot;]);&lt;br /&gt;
 		// Apply the values at the frame ahead&lt;br /&gt;
 		elphel_set_P_arr($gammas,$ahead);&lt;br /&gt;
 	}&lt;br /&gt;
 	//&lt;br /&gt;
 	// Add code to form the output here&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code looks for HTTP query parameters ''black'' (level of black) and ''gamma'' and sets them at the same time. &lt;br /&gt;
&lt;br /&gt;
The parameters should be integers: ''1 &amp;lt; gamma &amp;lt;= 100'' and ''0 &amp;lt;= black &amp;lt;= 50''.&lt;br /&gt;
&lt;br /&gt;
The undocumented function '''elphel_gamma_add(int gamma, int black)''' is used, where the value of ''gamma'' for this function must be a float ''0.1 &amp;lt; gamma &amp;lt;= 1.0''. Without it the gamma values are not effected. More can be found in the file ''camvc.php'' in ''/mnt/flash/html''.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11254</id>
		<title>PHP and Gamma values</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11254"/>
				<updated>2012-02-08T18:58:04Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=How to change Gamma values in an Elphel camera=&lt;br /&gt;
&lt;br /&gt;
Changing Gamma and BlackLevel values at present requires some special treatment. Here is a short PHP script that does it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
 // Set default frame ahead&lt;br /&gt;
 if (!array_key_exists(&amp;quot;ahead&amp;quot;,$_GET))&lt;br /&gt;
 	$ahead=3;&lt;br /&gt;
 &lt;br /&gt;
 // Special treatment for the gamma values and blacklevel.&lt;br /&gt;
 // Get exising gamma values  if a gamma parameter is requested&lt;br /&gt;
 if (array_key_exists(&amp;quot;gamma&amp;quot;,$_GET) || array_key_exists(&amp;quot;black&amp;quot;,$_GET)) {&lt;br /&gt;
 	$gammas=array(&lt;br /&gt;
 		&amp;quot;GTAB_R__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_R__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;&lt;br /&gt;
 		);&lt;br /&gt;
 	// get existing gamma values&lt;br /&gt;
 	$gammas= elphel_get_P_arr($gammas);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 foreach($_GET as $key=&amp;gt;$value) {&lt;br /&gt;
 	&lt;br /&gt;
 	if(strtolower(substr($s, 0, 2))==&amp;quot;0x&amp;quot;)&lt;br /&gt;
 		$value= hexdec($value);&lt;br /&gt;
 	switch ($key) {&lt;br /&gt;
 		case &amp;quot;gamma&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			foreach (array(&lt;br /&gt;
 				&amp;quot;GTAB_R__0816&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_G__0816&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_GB__0816&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_B__0816&amp;quot;&lt;br /&gt;
 			) as $key)&lt;br /&gt;
 				$gammas[$key] = $value;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case &amp;quot;black&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			foreach (array(&lt;br /&gt;
 				&amp;quot;GTAB_R__0824&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_G__0824&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_GB__0824&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_B__0824&amp;quot;&lt;br /&gt;
 			) as $key)&lt;br /&gt;
 				$gammas[$key] = $value;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	// If any gamma value was set, set all gamma values in the camera.&lt;br /&gt;
 	// Was postponed earlier&lt;br /&gt;
 	if ($gammas != NULL) {&lt;br /&gt;
  		elphel_gamma_add($gammas[&amp;quot;GTAB_G__0816&amp;quot;]/100, $gammas[&amp;quot;GTAB_G__0824&amp;quot;]);&lt;br /&gt;
 		// Apply the values at the frame ahead&lt;br /&gt;
 		elphel_set_P_arr($gammas,$ahead);&lt;br /&gt;
 	}&lt;br /&gt;
 	//&lt;br /&gt;
 	// Add code to form the output here&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code looks for HTTP query parameters ''black'' (level of black) and ''gamma'' and sets them at the same time. &lt;br /&gt;
&lt;br /&gt;
The parameters should be integers: ''1 &amp;lt; gamma &amp;lt;= 100'' and ''0 &amp;lt;= black &amp;lt;= 50''.&lt;br /&gt;
&lt;br /&gt;
The undocumented function '''elphel_gamma_add(int gamma, int black)''' is used, where the value of ''gamma'' for this function must be a float ''0.1 &amp;lt; gamma &amp;lt;= 1.0''. Without it the gamma values are not effected. More can be found in the file ''camvc.php'' in ''/mnt/flash/html''.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11253</id>
		<title>PHP and Gamma values</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_and_Gamma_values&amp;diff=11253"/>
				<updated>2012-02-08T18:56:31Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Code to change gamma values in PHP&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=How to change Gamma values in an Elphel camera=&lt;br /&gt;
&lt;br /&gt;
Changing Gamma and BlackLevel values at present requires some special treatment. Here is a short PHP script that does it:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 &lt;br /&gt;
 // Set default frame ahead&lt;br /&gt;
 if (!array_key_exists(&amp;quot;ahead&amp;quot;,$_GET))&lt;br /&gt;
 	$ahead=3;&lt;br /&gt;
 &lt;br /&gt;
 // Special treatment for the gamma values and blacklevel.&lt;br /&gt;
 // Get exising gamma values  if a gamma parameter is requested&lt;br /&gt;
 if (array_key_exists(&amp;quot;gamma&amp;quot;,$_GET) || array_key_exists(&amp;quot;black&amp;quot;,$_GET)) {&lt;br /&gt;
 	$gammas=array(&lt;br /&gt;
 		&amp;quot;GTAB_R__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0816&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_R__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_G__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_GB__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;,&lt;br /&gt;
 		&amp;quot;GTAB_B__0824&amp;quot;=&amp;gt;&amp;quot;&amp;quot;&lt;br /&gt;
 		);&lt;br /&gt;
 	// get existing gamma values&lt;br /&gt;
 	$gammas= elphel_get_P_arr($gammas);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 foreach($_GET as $key=&amp;gt;$value) {&lt;br /&gt;
 	&lt;br /&gt;
 	if(strtolower(substr($s, 0, 2))==&amp;quot;0x&amp;quot;)&lt;br /&gt;
 		$value= hexdec($value);&lt;br /&gt;
 	switch ($key) {&lt;br /&gt;
 		case &amp;quot;gamma&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			foreach (array(&lt;br /&gt;
 				&amp;quot;GTAB_R__0816&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_G__0816&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_GB__0816&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_B__0816&amp;quot;&lt;br /&gt;
 			) as $key)&lt;br /&gt;
 				$gammas[$key] = $value;&lt;br /&gt;
 			break;&lt;br /&gt;
 		case &amp;quot;black&amp;quot;:&lt;br /&gt;
 			// set gammas array and postpone setting values in the camera&lt;br /&gt;
 			$value = intval($value);&lt;br /&gt;
 			foreach (array(&lt;br /&gt;
 				&amp;quot;GTAB_R__0824&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_G__0824&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_GB__0824&amp;quot;,&lt;br /&gt;
 				&amp;quot;GTAB_B__0824&amp;quot;&lt;br /&gt;
 			) as $key)&lt;br /&gt;
 				$gammas[$key] = $value;&lt;br /&gt;
 			break;&lt;br /&gt;
 	}&lt;br /&gt;
 	// If any gamma value was set, set all gamma values in the camera.&lt;br /&gt;
 	// Was postponed earlier&lt;br /&gt;
 	if ($gammas != NULL) {&lt;br /&gt;
  		elphel_gamma_add($gammas[&amp;quot;GTAB_G__0816&amp;quot;]/100, $gammas[&amp;quot;GTAB_G__0824&amp;quot;]);&lt;br /&gt;
 		// Apply the values at the frame ahead&lt;br /&gt;
 		elphel_set_P_arr($gammas,$ahead);&lt;br /&gt;
 	}&lt;br /&gt;
 	//&lt;br /&gt;
 	// Add code to form the output here&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code looks for HTTP query parameters ''black'' (level of black) and ''gamma'' and sets them at the same time. The parameters should be integers: ''1 &amp;lt; gamma &amp;lt;= 100'' and ''0 &amp;lt;= black &amp;lt;= 50''.&lt;br /&gt;
The undocumented function '''elphel_gamma_add(int gamma, int black)''' is used, where the value of ''gamma'' for this function must be a float ''0.1 &amp;lt; gamma &amp;lt;= 1.0''. Without it the gamma values are not effected. More can be found in the file ''camvc.php'' in ''/mnt/flash/html''.&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_in_Elphel_cameras&amp;diff=11252</id>
		<title>PHP in Elphel cameras</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_in_Elphel_cameras&amp;diff=11252"/>
				<updated>2012-02-08T13:00:36Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Corrected parameter ELPHEL_FP100S in example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Why PHP? ==&lt;br /&gt;
One of the main objectives of Elphel products is to  make them developer-friendly. Just opening of the camera internals (including source code, FPGA code, hardware schematics) is not enough without providing means to modify the cameras easily, and here [http://www.php.net PHP] comes to the rescue. It is powerful and efficient and is well known by many developers including those who may have problems to modify FPGA code or kernel drivers. It is much easier to try your custom applications written in PHP - just transfer the files to the camera (i.e. with ftp) and open them in the web browser.&lt;br /&gt;
&lt;br /&gt;
PHP supports custom extensions written in C and we'll work (and I hope not just we at Elphel) to provide more custom function to combine flexibility and ease of use of the PHP with efficiency of native compiled code.&lt;br /&gt;
&lt;br /&gt;
== PHP in Elphel cameras (models 353/363) ==&lt;br /&gt;
Current version of PHP in Elphel cameras is 5.2.1, we will try to keep it (almost) current. PHP in the camera is working in [http://en.wikipedia.org/wiki/FastCGI Fast CGI] mode through [http://www.lighttpd.net/ Lighttpd]. Fast CGI mode does not restart applications (like traditional CGI does) for each HTTP request but rather keeps them alive to serve multiple requests. In the case of large application like PHP itself it makes a big performance difference and allows usage of the PHP scripts in the camera without the penalty of slow responses - something really undesirable for [http://www.linuxdevices.com/articles/AT5951285077.html AJAX applications].&lt;br /&gt;
&lt;br /&gt;
== How to use PHP in the camera ==&lt;br /&gt;
It is very simple. It is the same as to try your HTML/JavaScript pages.  You just need to ftp you script to one of the two locations (or their subdirectories) in the camera. Examples below assume you have the default camera IP='''192.168.0.9''':&lt;br /&gt;
* '''/var/html''' (visible as '''http://192.168.0.9/var/''' in the web browser) - recommended for experiments, if something goes wrong you can just power-cycle the camera and all your changes will be gone&lt;br /&gt;
* '''/usr/html''' (visible as ''http://192.168.0.9/''' in the web browser) - permanent (until next full firmware upgrade ) storage in the camera flash memory. This second location is more dangerous as you can change the installed files and rebooting will not restore the default behaviour. Flash memory has limited number of write cycles and can develop additional bad blocks during usage, so this location is recommended for &amp;quot;final&amp;quot; files, already tested in /var/html.&lt;br /&gt;
&lt;br /&gt;
You may also edit small text files with web-based editor. It does not allow to open non-existent file, but has an option to &amp;quot;Save As&amp;quot; - http://192.168.0.9/admin-bin/editcgi.cgi&lt;br /&gt;
So you can try opening http://192.168.0.9/admin-bin/editcgi.cgi?file=/usr/html/phpinfo.php and then (modify and) save it to /var/html/test.php . When done - just open the following URL and watch the results of the script processing by in-camera PHP:&lt;br /&gt;
&lt;br /&gt;
 '''http://192.168.0.9/var/test.php'''  - run&lt;br /&gt;
 '''http://192.168.0.9/admin-bin/editcgi.cgi?file=/var/html/test.php''' - edit&lt;br /&gt;
&lt;br /&gt;
It is also possible to execute PHP scripts without the browser - camera startup scripts already use it for various initialization of the hardware. You can (silently) execute the same program in telnet session:&lt;br /&gt;
 php /var/html/test.php &amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
== Elphel PHP extension in the camera ==&lt;br /&gt;
Since [[Release_notes|Elphel software version 7.1.6]] there is a custom extension module for PHP installed in the camera, you may also create your own extension as described [[PHP_in_Elphel_cameras#Creating_custom_PHP_extensions_for_Elphel_cameras|below]]. The existent extension exports several functions and defines constants.&lt;br /&gt;
=== Constants, defined in ''elphel'' PHP extension ===&lt;br /&gt;
see: [[Elphel_PHP_constants]]&lt;br /&gt;
===''elphel'' extension functions ===&lt;br /&gt;
&lt;br /&gt;
''Note: Currently arguments (and array values) are supposed to be numbers, not strings - you may want to use $value+0 (instead of just $value) if $value may be a string (i.e. passed from _GET[])''--[[User:Andrey.filippov|Andrey.filippov]] 19:55, 14 December 2007 (CST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_get_P_value ====&lt;br /&gt;
''long'' '''elphel_get_P_value''' (''long'' $address)&lt;br /&gt;
&lt;br /&gt;
This function returns value of one of internal camera parameters, as defined in [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/include/asm-cris/elphel/c313a.h?view=markup c313a.h] and documented in [[Elphel_PHP_constants]]. It is strongly recommended to use symbolic names as the numeric values may change in the future (as they already did multiple times). The values are maintained by the camera driver(s), usually they are updated when the driver programs the acquisition process.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_get_P_value(ELPHEL_FP1000S)/1000; // will return current camera sensor frame rate in (frames per second);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_set_P_value ====&lt;br /&gt;
''void'' '''elphel_set_P_value''' (''long'' $address, ''long'' $data)&lt;br /&gt;
&lt;br /&gt;
Set a single camera parameter.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_set_P_value(ELPHEL_QUALITY,100); // set JPEG compression quality to 100% - virtually lossless&lt;br /&gt;
The elphel_get_P_value and  elphel_set_P_value deal with different variables. Those that are read are validated to match the allowed values and may differ from those written (and they are only updated when sensor/compressor are programmed). You may read the parameters values that were written to the camera by adding ELPHEL_NUMBER to the parameter address, i.e&lt;br /&gt;
 echo elphel_get_P_value(ELPHEL_QUALITY+ELPHEL_NUMBER); // will output the compression quality as written&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_get_P_arr ====&lt;br /&gt;
''array'' '''elphel_get_P_arr''' (''array'' $template)&lt;br /&gt;
&lt;br /&gt;
Read multiple camera parameters as an associative array, according to $template. $template should have elements with the key names matching the camera parameters names, same as defined [[Elphel_PHP_constants]], but without &amp;quot;ELPHEL_&amp;quot; prefix (all the elements with the other keys will be ignored). '''elphel_get_P_arr''' returns array, where element keys are the same as in $template (after removing of any unknown ones), and values are ''long'' values read from the camera.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 $arr=array(&amp;quot;foo&amp;quot;=&amp;gt;&amp;quot;&amp;quot;, &amp;quot;WOI_LEFT&amp;quot; =&amp;gt; &amp;quot;&amp;quot;,  &amp;quot;WOI_TOP&amp;quot; =&amp;gt; &amp;quot;&amp;quot;, &amp;quot;1&amp;quot;, 3, &amp;quot;WOI_WIDTH&amp;quot; =&amp;gt; 0, &amp;quot;WOI_HEIGHT&amp;quot; =&amp;gt; 0);&lt;br /&gt;
 print_r ($arr);&lt;br /&gt;
will return (5MPix sensor, full window):&lt;br /&gt;
 Array&lt;br /&gt;
 (&lt;br /&gt;
    [WOI_LEFT] =&amp;gt; 0&lt;br /&gt;
    [WOI_TOP] =&amp;gt; 0&lt;br /&gt;
    [WOI_WIDTH] =&amp;gt; 2592&lt;br /&gt;
    [WOI_HEIGHT] =&amp;gt; 1936&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_set_P_arr ====&lt;br /&gt;
''long'' '''elphel_set_P_arr''' (''array'' $input, ''long'' $frame, ''long'' $flag) )&lt;br /&gt;
&lt;br /&gt;
Write multiple camera parameters, provided as an associative array, where keys are parameter names  same as defined [[Elphel_PHP_constants]], but without &amp;quot;ELPHEL_&amp;quot; prefix. Values should be numeric and integer, all other types are ignored.&lt;br /&gt;
&lt;br /&gt;
optional arguments:&lt;br /&gt;
  frame - frame number to write these parameters to - if not specified default framedelay (current frame + 3) is applied)&lt;br /&gt;
  flag - possible flags? &lt;br /&gt;
&lt;br /&gt;
Return value - frame number to which parameters were written &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_set_P_arr(array(&amp;quot;WOI_LEFT&amp;quot; =&amp;gt; 896,  &amp;quot;WOI_TOP&amp;quot; =&amp;gt; 672, &amp;quot;WOI_WIDTH&amp;quot; =&amp;gt; 800, &amp;quot;WOI_HEIGHT&amp;quot; =&amp;gt; 600));&lt;br /&gt;
Will set 800x600 window in the center of the 5Mpix sensor and print frame number these changes where applied to&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_get_state ====&lt;br /&gt;
''long'' '''elphel_get_state''' (''void'')&lt;br /&gt;
There are multiple states defined in the camera, some are obsolete, the following are most common (no symbolic constants in PHP yet)&lt;br /&gt;
* 0 - &amp;quot;reset&amp;quot; (i.e. no images yet acquired after power up)&lt;br /&gt;
* 7 - &amp;quot;stopped&amp;quot; - sensor is constantly acquiring images (used for autoexposure), but compressor is stopped and no frames get to the [[Circbuf|circbuf]]&lt;br /&gt;
* 8 - &amp;quot;running&amp;quot; - compressor is acquiring images to [[Circbuf|circbuf]]&lt;br /&gt;
* 9 - &amp;quot;stopping&amp;quot; - compressor is compressing the last frame (transition from &amp;quot;running&amp;quot; to &amp;quot;stopped&amp;quot;&lt;br /&gt;
*10 - &amp;quot;single_buffer&amp;quot; - compressor is acquiring full [[Circbuf|circbuf]] (plus one frame as it will notice the buffer is full after overrunning the original starting point) and then will stop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_fpga_read ====&lt;br /&gt;
''long'' '''elphel_fpga_read''' (''long $address'')&lt;br /&gt;
&lt;br /&gt;
Reads data from a certain fpga register address.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_fpga_read(4); // outputs the data at address 4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_fpga_write ====&lt;br /&gt;
''void'' '''elphel_fpga_write''' (''long $address, long $data'')&lt;br /&gt;
&lt;br /&gt;
Writes data to a certain fpga register address.&lt;br /&gt;
&lt;br /&gt;
'''for Elphel 353 cameras these values can be the following (quoted from x353.h):'''&lt;br /&gt;
  187 #define X313_WA_WCTL	    0 // write control register - 32&lt;br /&gt;
  188 #define X313_WA_DMACR	    1 // DMA control register:&lt;br /&gt;
  189                               // 17:    DMA enable&lt;br /&gt;
  190                               // 16:    0- raw, 1 - JPEG&lt;br /&gt;
  191                               // 15-10: not used&lt;br /&gt;
  192                               // 0-9:   line length in long words&lt;br /&gt;
  193 #define X313_WA_SENSFPN	    2 // Sensor/FPN control register:&lt;br /&gt;
  194                                        // [10] - testmode - if 1 generates gradient data (as Zoran chips) where pixel value = horizontal position&lt;br /&gt;
  195                                        // [9:7] - submode - subtract background (8 bits) mode (use di[7:0]):&lt;br /&gt;
  196                                        // 000 - no subtraction;&lt;br /&gt;
  197                                        // 001 - (finest) subtract 8 bit bkgnd from 12 bits pixels&lt;br /&gt;
  198                                        // 010 - shift 8bit bkgnd 1 bit  left before applying&lt;br /&gt;
  199                                        // 011 - shift 8bit bkgnd 2 bits left before applying&lt;br /&gt;
  200                                        // 100 - shift 8bit bkgnd 2 bits left before applying&lt;br /&gt;
  201                                        // 101 - shift 8bit bkgnd 2 bits left before applying&lt;br /&gt;
  202                                        // fpn data to subtract should be a little less to add a &amp;quot;fat zero&amp;quot;&lt;br /&gt;
  203                                        // [6:4] - mpymode sensitivity correction mode (use di[15:8]):&lt;br /&gt;
  204                                        // 000 - no correction&lt;br /&gt;
  205                                        // 001 - fine correction (+/-3.125%)&lt;br /&gt;
  206                                        // 010 - fine correction (+/-6.25%)&lt;br /&gt;
  207                                        // 011 - fine correction (+/-12.5%)&lt;br /&gt;
  208                                        // 100 - +/- 25%&lt;br /&gt;
  209                                        // 101 - +/- 50%&lt;br /&gt;
  210                                        // [3] - wdth - word width: 0 - 8 bit, 1 - 16 bit (5 MSB == 0)&lt;br /&gt;
  211                                        // [2:0] scaling of 11 bit FPN result to fit in 8bit output:&lt;br /&gt;
  212                                        // 00 - default - use [9:1]&lt;br /&gt;
  213                                        // 01 - use [10:2] - to protect from saturation after applying mpymode&lt;br /&gt;
  214                                        //      nominal range - 0..127&lt;br /&gt;
  215                                        // 10 - use [7:0] before saturation, &amp;quot;digital gain&amp;quot; == 4 (maximal)&lt;br /&gt;
  216                                        // 11 - use [8:1] before saturation, &amp;quot;digital gain&amp;quot; == 2&lt;br /&gt;
  217 &lt;br /&gt;
  218                               // 31-8: not used&lt;br /&gt;
  219                               //    7: 0 - normal, 1 - test mode (as Zoran)&lt;br /&gt;
  220                               //  6-5: subtract FPN mode:&lt;br /&gt;
  221                               //       0 - no subtraction&lt;br /&gt;
  222                               //       1 (fine) - subtract 8-bit FPN from 10-bit pixel&lt;br /&gt;
  223                               //       2 - multiply FPN by 2 before subtracting&lt;br /&gt;
  224                               //       3 - multiply FPN by 4 before subtracting (full scfpcfale)&lt;br /&gt;
  225                               // negative result is replaced by 0, decrease FPN data before applying for &amp;quot;fat 0&amp;quot;&lt;br /&gt;
  226                               // 4-3: muliply by inverse sensitivity (sensitivity correction) mode:&lt;br /&gt;
  227                               //       0 - no correction&lt;br /&gt;
  228                               //       1 - fine (+/- 12.5%)&lt;br /&gt;
  229                               //       2 - medium (+/- 25%)&lt;br /&gt;
  230                               //       3 - maximal (+/- 50%)&lt;br /&gt;
  231                               //   2: pixel depth:&lt;br /&gt;
  232                               //       0 - 8 bits/pixel (needed for JPEG encoding)&lt;br /&gt;
  233                               //       1 - 16 bits/pixel (only 11 LSBs are non-zero)&lt;br /&gt;
  234                               // 1-0: scale (8 bit mode only):&lt;br /&gt;
  235                               //       0 - full scale corresponds to sensor full scale if no correction was applied&lt;br /&gt;
  236                               //       1 - divide by 2. This will guarantee against saturation after sensitivity correction was&lt;br /&gt;
  237                               //           applied. Nominal output range - 0..127&lt;br /&gt;
  238                               //       2 - multiply by 4 (use 8 lower bits from sensor data)&lt;br /&gt;
  239                               //       3 - multiply by 2&lt;br /&gt;
  240                               // Result data is saturated by 255&lt;br /&gt;
  241 #define X313_WA_VIRTTRIG   3  // Virtual trigger threshold&lt;br /&gt;
  242                               //   31-22  not used&lt;br /&gt;
  243                               //   21-0  Trigger will fire if sum of pixels in a line&lt;br /&gt;
  244                               //         (after FPN processig) is more than this value.&lt;br /&gt;
  245                               //         Disabled if 0 - selected real (electrical) external trigger&lt;br /&gt;
  246 #define X313_WA_TRIG       4  // Sensor triggering&lt;br /&gt;
  247                               // 31-3: not used&lt;br /&gt;
  248                               //    2: Enable sensor (0 - abort at once)&lt;br /&gt;
  249                               //    1: External Trigger (0 - internal)&lt;br /&gt;
  250                               //    0: continuous acquisition (0 - single &amp;quot;frame&amp;quot; - actually number of lines specified)&lt;br /&gt;
  251 #define X313_WA_NLINES     5  //  number of lines to acquire (afer trigger)&lt;br /&gt;
  252                               // 31-11: not used&lt;br /&gt;
  253                               // 10-0 : number of lines to acquire (in a frame or after the external trigger)&lt;br /&gt;
  254 //#define X313_WA_IRQM       6  // Interrupt mask (1 - enable, 0 - reset all but done)&lt;br /&gt;
  255                               // 31-04: not used&lt;br /&gt;
  256                               //     3: Done. Reset by writing to X313_WA_TRIG&lt;br /&gt;
  257                               //     2: frame acquisition over&lt;br /&gt;
  258                               //     1: external trigger&lt;br /&gt;
  259                               //     0: frame sync (vacts)&lt;br /&gt;
  260 #define X313_WA_DCDC       7  // sensor DC-DC converter frequency settings&lt;br /&gt;
  261                               // 31-05: not used&lt;br /&gt;
  262                               //   4-0  0 - use internal clock (not sync)&lt;br /&gt;
  263                               //        1..31 use divided pixel clock&lt;br /&gt;
  264                               //        for 20MHz use 5'h10,&lt;br /&gt;
  265                               //        else - N= (Fpix[MHz]/1.2)-1, if Fpix=20MHz,&lt;br /&gt;
  266                               //        N= 15.7-&amp;gt;16=5'h10&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_fpga_write(4, 4); // Sets sensor triggering to an unused number and therefore disabling it -&amp;gt; acquire single frame to video buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_reset_sensor ====&lt;br /&gt;
''void'' '''elphel_reset_sensor''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Reset the sensor settings, stop compressor (if it was running) and force sensor re-initialization.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_reset_sensor();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_program_sensor ====&lt;br /&gt;
''void'' '''elphel_program_sensor''' (''long'' $nonstop)&lt;br /&gt;
&lt;br /&gt;
Applies written earlier (see [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]], [[PHP_in_Elphel_cameras#elphel_white_balance|elphel_white_balance]]) parameters to the cameras sensor and FPGA compressor. $nonstop determines if the acquisition should be restarted ($nonstop==0) or updated without stopping ($nonstop==1).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' As of version 8.x, parameters are applied as they are set.  Therefore, this function is no longer necessary.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_program_sensor(0);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_wait_frame ====&lt;br /&gt;
''void'' '''elphel_wait_frame''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Waits for the next frame to be compressed to the circular buffer - it is also the time when some other parameters (accessible with [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]]) are updated.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_wait_frame();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_wait_frame_abs ====&lt;br /&gt;
''long'' '''elphel_wait_frame''' (''long'' frame)&lt;br /&gt;
&lt;br /&gt;
wait for absolute frame number (includes those that are not compressed) &lt;br /&gt;
&lt;br /&gt;
returns: frame number&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_wait_frame_abs(200);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_skip_frames ====&lt;br /&gt;
''long'' '''elphel_skip_frames''' (''long'' frames)&lt;br /&gt;
&lt;br /&gt;
skip some frames (includes those that are not compressed) - will work even if no frames are compressed &lt;br /&gt;
&lt;br /&gt;
returns: frame number&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_skip_frames(1);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_compressor_run ====&lt;br /&gt;
''void'' '''elphel_compressor_run''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Turn the FPGA compressor on. Sensor should be already programmed ([[PHP_in_Elphel_cameras#|elphel_get_state] should return 7 (or higher) if tested prior to issuing ''elphel_compressor_run()'' command.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_compressor_run();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_compressor_stop ====&lt;br /&gt;
''void'' '''elphel_compressor_stop''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Stop camera compressor (will stop transferring more frames to the [[Circbuf|circular buffer]]. This command does not to be synchronized - compressor will finish current frame before stopping.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_compressor_stop();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_compressor_frame ====&lt;br /&gt;
''void'' '''elphel_compressor_frame''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Acquire one frame to the buffer (will apply written JPEG quality). Sensor should be already programmed - [[PHP_in_Elphel_cameras#|elphel_get_state]] should return 7 (or higher) if tested prior to issuing ''elphel_compressor_frame()'' command.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_compressor_frame();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_set_fpga_time ====&lt;br /&gt;
''double'' '''elphel_set_fpga_time''' (''double'' seconds)&lt;br /&gt;
&lt;br /&gt;
Set FPGA internal timer that is used for time-stamping images and video frames. Internal counter has a 32-bit seconds counter and 12 bit microsecond one, so you may specify epoch - seconds since 01/01/1970.&lt;br /&gt;
&lt;br /&gt;
Returns time set as a ''double'' - it should match the input parameter after rounding to microseconds (resolution of the FPGA timer).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_set_fpga_time(0x47565ad3);&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_get_fpga_time ====&lt;br /&gt;
''double'' '''elphel_get_fpga_time''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Copies current value of the FPGA timer registers to the global array (maybe read with several functions described above) and returns the the time as a ''double'' value, combining second as microseconds. The readout process guaranties that seconds and microseconds are sample simultaneously.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_get_fpga_time();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
----&lt;br /&gt;
==== elphel_flush_cache ====&lt;br /&gt;
''void'' '''elphel_flush_cache''' (''void'')&lt;br /&gt;
&lt;br /&gt;
This function is included to fight (hardware) cache coherency problems in mmap implementation for ETRAX FS processor. I'm not sure it will be really needed here - it needs some testing. If it will be proven it is needed - we'll incorporate it into appropriate functions that depend on it, if not it will just be removed.&lt;br /&gt;
&lt;br /&gt;
This function may be needed before [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] to read data updated by the driver and/or before [[PHP_in_Elphel_cameras#elphel_program_sensor|elphel_program_sensor]], [[PHP_in_Elphel_cameras#elphel_compressor_run\elphel_compressor_run]], [[PHP_in_Elphel_cameras#elphel_compressor_frame|elphel_compressor_frame]] (if any of the parameters were changed with  [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]]  after the last call to elphel_flush_cache&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_flush_cache();&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_white_balance ====&lt;br /&gt;
''int'' '''elphel_white_balance''' ([''double'' thrsh [, ''double'' minfrac [, ''double'' rscale [, ''double'' bscale]]]])&lt;br /&gt;
&lt;br /&gt;
This function is designed to perform white balancing of the camera images. It relies on histogram calculation, &amp;quot;gamma&amp;quot; tables (curves) (both implemented in the FPGA) and the auto-exposure software in the camera (not yet included in this PHP extension, it is currently controlled through the separate CGI program). White balance uses the same window as auto-exposure, only data inside the specified rectangular window is processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The goal of this function is to make the brightest areas in the image white (equal values of red, green and blue), it assumes that auto-exposure algorithm (operating after each frame acquired) already adjusted the brightness of the images so it uses all the 8-bit range and some pixel values are close to the maximal 255.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The balancing is achieved by modification of the lookup tables (&amp;quot;gamma&amp;quot; tables, &amp;quot;curves&amp;quot;) that map 12-bit (in 5MPix sensor, may be 10 or 14 bits with other devices) pixel data to the 8-bit pixel values used by the image/video compressor, the same values can be manually entered with [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] functions applied to RSCALE and BSCALE parameters. The balancing is sensor-independent and it does not change sensor analog gains (where available), but if the required correction is significant, it is recommended to adjust those gains also, leaving only fine adjustment to the white balance algorithm - that will increase the dynamic range of the images.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All function parameters are optional, but you can not skip the first one(s) if you would like to specify the next one(s), in that case default values should be explicitly entered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First parameter '''thrsh''' defines how bright should be pixels to be counted as white. Default value of '''0.98''' corresponds to 250 counts on 255 scale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Second parameter '''minfrac''' (default '''0.01''') tells how many pixels (at least) should be counted, as a fraction of the total number of the pixels in the specified window. If there are too few pixels with the brightness above the ''thrsh'', the ''thrsh'' will be lowered, to let more pixels to be counted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next two parameters - '''rscale''' and '''bscale''' (both with default values of '''1.0''') can be used to apply manual bias to the automatically calculated values of red and blue scales (relative.to green)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When this function is executed successfully it returns 0 (negative numbers indicate failure) in adjusts parameters (similar to manual [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]]), but that will propagate to the FPGA only after [[PHP_in_Elphel_cameras#elphel_program_sensor|elphel_program_sensor]] is executed. If you do not need to change any other parameters, you may use '''elphel_program_sensor(1)''' - in this case the image/video acquisition process will not be interrupted, frame timing will be preserved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As this function uses the histograms calculated from the previously acquired images, you actually need to acquire some. It is recommended you wait till the auto-exposure will adjust the brightness before executing elphel_white_balance. It also is not needed to run it as frequently as auto-exposure (for each frame), usually it is enough to call it only when the lighting conditions are changed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
 if (elphel_white_balance()&amp;gt;=0) elphel_program_sensor(1);&lt;br /&gt;
or&lt;br /&gt;
 elphel_white_balance(0.98,0.01,1.0,1.2); // set bluish tint&lt;br /&gt;
&lt;br /&gt;
[http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/packages/web/353/php_top/whitebalance.php?view=markup whitebalance.php] is an example script that uses this function. It is installed in the camera and can be called as  (provided camera has the default IP of 192.168.0.9):&lt;br /&gt;
 http://192.168.0.9/whitebalance.php&lt;br /&gt;
or&lt;br /&gt;
 http://192.168.0.9/whitebalance.php?thrsh=0.98&amp;amp;minfrac=0.01&amp;amp;rscale=1.0&amp;amp;bscale=1.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_autoexposure_set ====&lt;br /&gt;
''void'' '''elphel_autoexposure_set''' (''void'')&lt;br /&gt;
&lt;br /&gt;
This function controls auto-exposure in the camera. It is a quick modification that preserves the existent functionality (including interface) and just adds control from the PHP. This function itself does not take any parameters, it also does not return any data, It applies parameters that have to be already written by either of [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]], the current state of the auto-exposure algorithm can be read back using [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] functions.&lt;br /&gt;
&lt;br /&gt;
===== auto-exposure software in the camera =====&lt;br /&gt;
&lt;br /&gt;
====== kernel space (driver) ======&lt;br /&gt;
When the image from the sensor is acquired in the camera (even the compressor is off), software interrupt is generated and among others two things related to the auto-exposure control happen in the driver.&lt;br /&gt;
* software prepares histograms calculated in the FPGA during the previous frame acquisition to be analysed by the user space application and make them available to the userspace applications through memory-mapped arrays (mmap) and&lt;br /&gt;
* the previously calculated exposure is applied to the sensor to take effect during the next frame acquisition. Exposure time is the only parameter controlled automatically, you may also want to change analog gain(s) (sensitivity) to extend the range of the illumination levels that camera can handle. Most of this driver functionality is implemented in the [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/hist353.c?view=markup hist353.c].&lt;br /&gt;
&lt;br /&gt;
====== user space (daemon) ======&lt;br /&gt;
User space application [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/autoexp/autoexp.c?view=markup autoexp.c] (running as a daemon) processes the histograms and calculates the corrected value of the exposure, the result value is sent to the driver that applies the required correction. &lt;br /&gt;
&lt;br /&gt;
In addition the histograms (four of them - individually for each of the 4 Bayer components, including 2 sets of green pixels), driver provides applications with the lookup (&amp;quot;gamma&amp;quot;) tables that are used by the FPGA to convert sensor pixel value (12 bit for the 5MPix sensor) into the 8-bit range, usually - non-linearly, controlled by &amp;quot;gamma&amp;quot; parameter. This tables are needed when processing the histograms, as FPGA calculates them after the LUT are applied to the pixel values.&lt;br /&gt;
&lt;br /&gt;
The auto-exposure configuration (input) parameters and the current state (output) can still be accessed using the current CGI script [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/autoexp/autoexpos.cgi.c?view=markup autoexpos.cgi.c] (as used by camvc user interface), alternatively they are directly accessible through the [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]],  [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] functions.&lt;br /&gt;
&lt;br /&gt;
===== auto-exposure algorithm in the camera =====&lt;br /&gt;
&lt;br /&gt;
The goal of the auto-exposure algorithm is to use as much as possible of the sensor dynamic range in the area of interest. It tries to adjust the exposure of the sensor so the whole range of the image pixel values (up to 255) are used (small number of pixels are usually still allowed to overexpose and be return the 255 limit value). It is possible to maintain the brightest pixels (disregarding just few &amp;quot;super-bright&amp;quot;) near 255, but the it has 2 disadvantages:&lt;br /&gt;
* sometimes with the back light you want to have good reproduction of darker objects while allowing the bright background to saturate&lt;br /&gt;
* it is difficult to calculate required correction when the exposure is too  long (some areas are over-saturated), because there is no way to know how much are the pixels saturated (if the image is too dim, the required exposure increase is just the ratio of 255 and the brightest pixels in the image)&lt;br /&gt;
For these reasons a slightly different algorithm is used - the software tries to maintain specified part of the pixels in the window of interest to be below the specified level (usually high, but less than the full scale). In this case if the brightness of the scene suddenly increases (up to the ratio of the full scale pixel value to the specified threshold), the exposure correction can be calculated and applied in a single step. You may experiment with this algorithm using GUI in ''camvc'' camera web interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== parameters that control auto-exposure in the camera =====&lt;br /&gt;
The following are parameters (it is possible to both their names as array keys with functions  [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]], [[PHP_in_Elphel_cameras#elphel_get_P_warr|elphel_get_P_warr]]. There are also [[Elphel_PHP_constants|constants]] defined that use the same names with &amp;quot;ELPHEL_&amp;quot;prefix (i.e. ELPHEL_AUTOEXP_ON), these constants are useful with the functions [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]],  [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]]. All the parameter values are ''long'' (32-bit) integers, you may read them back (as written) with [[PHP_in_Elphel_cameras#elphel_get_P_warr|elphel_get_P_warr]] function call. Te value of ELPHEL_HIST_NOT_CHANGE (65536) for any of these parameters mean that values corresponding to these parameters will not be updated.&lt;br /&gt;
&lt;br /&gt;
* '''AUTOEXP_ON''' - when set to '''1''' enables automatic exposure control, when '''0''' - disables it&lt;br /&gt;
* '''AUTOEXP_RWIDTH''', '''AUTOEXP_RHEIGHT''' - relative width and height (in %) of the auto-exposure window width and height. It is used for histogram calculation in the FPGA and so controls not only auto-exposure, but also [[PHP_in_Elphel_cameras#elphel_white_balance|white balance]] and manual histogram processing&lt;br /&gt;
* '''AUTOEXP_RLEFT''', '''AUTOEXP_RTOP''' - position of the auto-exposure window center, in %, counted from the left and top respectively&lt;br /&gt;
* '''AUTOEXP_EXP_MAX''' - maximal exposure time (in 1/10000 of a second) allowed for the auto-exposure algorithm. It is recommended to set it equal to the frame period when video is streamed or recorded, otherwise in the low-light conditions the frame rate may drop to accommodate longer exposure times (frame period may never be shorter than the exposure time)&lt;br /&gt;
* '''AUTOEXP_OVEREXP_MAX''' (old algorithm) - amount of pixels (fraction of all the pixels in the auto-exposure window) that are allowed to be overexposed, measured in 1/100 or a percent. This parameter is used when both '''AUTOEXP_S_PERCENT''' and '''AUTOEXP_S_INDEX''' (see below) are 0. This algorithm can be slow to handle over-exposed images and is not recommended.&lt;br /&gt;
* '''AUTOEXP_S_PERCENT''' - amount of pixels that are controlled to have value below the specified '''AUTOEXP_S_INDEX''' (below), measured in 1/100 of a percent. Example: AUTOEXP_S_PERCENT=9400 means that 94% of pixels should have value lower than '''AUTOEXP_S_INDEX'''&lt;br /&gt;
* '''AUTOEXP_S_INDEX''' - threshold for the pixel values (on a 0..255 8-bit scale) used together with '''AUTOEXP_S_PERCENT'''&lt;br /&gt;
* '''AUTOEXP_SKIP_PMIN''' - minimal calculated exposure correction that will be applied (in 1/100 of a %). Value of 500 (default) means that exposure value will not be modified if the calculated value differs less than by 5% from the current one&lt;br /&gt;
* '''AUTOEXP_SKIP_T''' minimal absolute exposure correction (in exposure steps, currently 1 step is 1/10000 sec), default value = 2&lt;br /&gt;
* '''AUTOEXP_SKIP_PMAX''' - maximal allowed  exposure correction that algorithm is allowed to apply (in 1/200 of a %, default is 5000 - 50%). If calculated exposure correction exceeds this value, it will not be applied immediately, the algorithm will wait for the next frame to make sure it was not an instant flash (i.e from some camera)&lt;br /&gt;
* '''AEXPWND_WIDTH''', '''AEXPWND_HEIGHT''', '''AEXPWND_TOP''', '''AEXPWND_LEFT''' (when written to) behave similarly to '''AEXPWND_RWIDTH''', '''AEXPWND_RHEIGHT''', '''RAEXPWND_TOP''' and '''AEXPWND_RLEFT''', but come into effect immediately, not waiting for the [[PHP_in_Elphel_cameras#elphel_autoexposure_set|elphel_autoexposure_set()]] call. Writing to AEXPWND_RWIDTH, AEXPWND_RHEIGHT, RAEXPWND_TOP and AEXPWND_RLEFT and calling [[PHP_in_Elphel_cameras#elphel_autoexposure_set|elphel_autoexposure_set()]] updates the AEXPWND_WIDTH, AEXPWND_HEIGHT, AEXPWND_TOP, AEXPWND_LEFT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
    [AUTOEXP_EXP] =&amp;gt; 801&lt;br /&gt;
    [AUTOEXP_SKIP_PMIN] =&amp;gt; 500&lt;br /&gt;
    [AUTOEXP_SKIP_PMAX] =&amp;gt; 5000&lt;br /&gt;
    [AUTOEXP_SKIP_T] =&amp;gt; 2&lt;br /&gt;
    [AEXPWND_WIDTH] =&amp;gt; 80&lt;br /&gt;
    [AEXPWND_HEIGHT] =&amp;gt; 80&lt;br /&gt;
    [AEXPWND_TOP] =&amp;gt; 50&lt;br /&gt;
    [AEXPWND_LEFT] =&amp;gt; 50&lt;br /&gt;
&lt;br /&gt;
  [ELPHEL_AUTOEXP_ON] =&amp;gt; 76&lt;br /&gt;
    [ELPHEL_AUTOEXP_RWIDTH] =&amp;gt; 77&lt;br /&gt;
    [ELPHEL_AUTOEXP_RHEIGHT] =&amp;gt; 78&lt;br /&gt;
    [ELPHEL_AUTOEXP_RLEFT] =&amp;gt; 79&lt;br /&gt;
    [ELPHEL_AUTOEXP_RTOP] =&amp;gt; 80&lt;br /&gt;
    [ELPHEL_AUTOEXP_EXM_MAX] =&amp;gt; 81&lt;br /&gt;
    [ELPHEL_AUTOEXP_OVEREXP_MAX] =&amp;gt; 82&lt;br /&gt;
    [ELPHEL_AUTOEXP_S_PERCENT] =&amp;gt; 83&lt;br /&gt;
    [ELPHEL_AUTOEXP_S_INDEX] =&amp;gt; 84&lt;br /&gt;
    [ELPHEL_AUTOEXP_EXP] =&amp;gt; 85&lt;br /&gt;
    [ELPHEL_AUTOEXP_SKIP_PMIN] =&amp;gt; 86&lt;br /&gt;
    [ELPHEL_AUTOEXP_SKIP_PMAX] =&amp;gt; 87&lt;br /&gt;
    [ELPHEL_AUTOEXP_SKIP_T] =&amp;gt; 88&lt;br /&gt;
    [ELPHEL_AEXPWND_WIDTH] =&amp;gt; 89&lt;br /&gt;
    [ELPHEL_AEXPWND_HEIGHT] =&amp;gt; 90&lt;br /&gt;
    [ELPHEL_AEXPWND_TOP] =&amp;gt; 91&lt;br /&gt;
    [ELPHEL_AEXPWND_LEFT] =&amp;gt; 92&lt;br /&gt;
    [ELPHEL_HIST_NOT_CHANGE] =&amp;gt; 65535&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating custom PHP extensions for Elphel cameras ==&lt;br /&gt;
&lt;br /&gt;
The followings steps are needed to create a custom PHP extension to run in Elphel product:&lt;br /&gt;
&lt;br /&gt;
* Create subdirectory of this (ext) directory for the new extension&lt;br /&gt;
* Create files in this new directory - at least&lt;br /&gt;
**   config.m4&lt;br /&gt;
**   &amp;lt;your name&amp;gt;.h&lt;br /&gt;
**   &amp;lt;yourname&amp;gt;.c&lt;br /&gt;
&lt;br /&gt;
You may use ext_skel script to automate this process or follow a nice tutorial by Sara Goleman '''[http://devzone.zend.com/node/view/id/1021 Extension Writing Part I: Introduction to PHP and Zend]''' . You may also like to read her book, &amp;quot;Extending and Embedding PHP&amp;quot;.&lt;br /&gt;
=== config.m4 ===&lt;br /&gt;
&lt;br /&gt;
 PHP_ARG_ENABLE(hello, whether to enable Hello World support, [ --enable-hello   Enable Hello World support])&lt;br /&gt;
 if test &amp;quot;$PHP_HELLO&amp;quot; = &amp;quot;yes&amp;quot;; then&lt;br /&gt;
  AC_DEFINE(HAVE_HELLO, 1, [Whether you have Hello World])&lt;br /&gt;
  PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
=== php_hello.h ===&lt;br /&gt;
&lt;br /&gt;
 #ifndef PHP_HELLO_H&lt;br /&gt;
 #define PHP_HELLO_H 1&lt;br /&gt;
 #define PHP_HELLO_WORLD_VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
 #define PHP_HELLO_WORLD_EXTNAME &amp;quot;hello&amp;quot;&lt;br /&gt;
 PHP_FUNCTION(hello_world);&lt;br /&gt;
 extern zend_module_entry hello_module_entry;&lt;br /&gt;
 #define phpext_hello_ptr &amp;amp;hello_module_entry&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
=== hello.c ===&lt;br /&gt;
&lt;br /&gt;
 #ifdef HAVE_CONFIG_H&lt;br /&gt;
 #include &amp;quot;config.h&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
 #include &amp;quot;php.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;php_hello.h&amp;quot;&lt;br /&gt;
 static function_entry hello_functions[] = {&lt;br /&gt;
    PHP_FE(hello_world, NULL)&lt;br /&gt;
    {NULL, NULL, NULL}&lt;br /&gt;
 };&lt;br /&gt;
 zend_module_entry hello_module_entry = {&lt;br /&gt;
 #if ZEND_MODULE_API_NO &amp;gt;= 20010901&lt;br /&gt;
    STANDARD_MODULE_HEADER,&lt;br /&gt;
 #endif&lt;br /&gt;
    PHP_HELLO_WORLD_EXTNAME,&lt;br /&gt;
    hello_functions,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
 #if ZEND_MODULE_API_NO &amp;gt;= 20010901&lt;br /&gt;
    PHP_HELLO_WORLD_VERSION,&lt;br /&gt;
 #endif&lt;br /&gt;
    STANDARD_MODULE_PROPERTIES&lt;br /&gt;
 };&lt;br /&gt;
 #ifdef COMPILE_DL_HELLO&lt;br /&gt;
 ZEND_GET_MODULE(hello)&lt;br /&gt;
 #endif&lt;br /&gt;
 PHP_FUNCTION(hello_world)&lt;br /&gt;
 {&lt;br /&gt;
    RETURN_STRING(&amp;quot;Hello World&amp;quot;, 1);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With the 3 files created you need to cd to the extension directory and run&lt;br /&gt;
 ../../elphize&lt;br /&gt;
That will generate support files (running phpize script) so you'll just need to run&lt;br /&gt;
 make install&lt;br /&gt;
to have the new extension (as a dynamic library) installed in the target directory tree and included in the camera flash image.&lt;br /&gt;
&lt;br /&gt;
You will need to add &amp;quot;extension=&amp;lt;your_extension_name&amp;gt;&amp;quot; to the php.ini file to be activated.&lt;br /&gt;
&lt;br /&gt;
When troubleshooting extensions you may also want to try your scripts from the command line in the camera - in that case the stdout will be visible and PHP+your module will be able to complain about Segmentation faults (when invoked from the browser it you will get Error 500 at best if that happens). And you'll have to manually restart web server + PHP after module changes (remember - Fast CGI does not kill PHP after end of HTTP request?)&lt;br /&gt;
&lt;br /&gt;
== Known problems ==&lt;br /&gt;
&lt;br /&gt;
Function ''[http://us.php.net/manual/en/function.fread.php fread]'' in PHP always tries to read 8192 bytes even if the length parameter is &amp;lt;8192, that causes problems when read from devices (i.e. i2c) being too slow or causing side effects. It is considered [http://bugs.php.net/bug.php?id=21641 feature, not a bug].&lt;br /&gt;
 &lt;br /&gt;
A quick fix will be to change the driver to always read minimal (1/2/3/4 bytes depending on the nature of the data) if the count passed to device read function is 8192.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:PHP]]&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=PHP_in_Elphel_cameras&amp;diff=11079</id>
		<title>PHP in Elphel cameras</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=PHP_in_Elphel_cameras&amp;diff=11079"/>
				<updated>2012-01-05T14:52:17Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Why PHP? ==&lt;br /&gt;
One of the main objectives of Elphel products is to  make them developer-friendly. Just opening of the camera internals (including source code, FPGA code, hardware schematics) is not enough without providing means to modify the cameras easily, and here [http://www.php.net PHP] comes to the rescue. It is powerful and efficient and is well known by many developers including those who may have problems to modify FPGA code or kernel drivers. It is much easier to try your custom applications written in PHP - just transfer the files to the camera (i.e. with ftp) and open them in the web browser.&lt;br /&gt;
&lt;br /&gt;
PHP supports custom extensions written in C and we'll work (and I hope not just we at Elphel) to provide more custom function to combine flexibility and ease of use of the PHP with efficiency of native compiled code.&lt;br /&gt;
&lt;br /&gt;
== PHP in Elphel cameras (models 353/363) ==&lt;br /&gt;
Current version of PHP in Elphel cameras is 5.2.1, we will try to keep it (almost) current. PHP in the camera is working in [http://en.wikipedia.org/wiki/FastCGI Fast CGI] mode through [http://www.lighttpd.net/ Lighttpd]. Fast CGI mode does not restart applications (like traditional CGI does) for each HTTP request but rather keeps them alive to serve multiple requests. In the case of large application like PHP itself it makes a big performance difference and allows usage of the PHP scripts in the camera without the penalty of slow responses - something really undesirable for [http://www.linuxdevices.com/articles/AT5951285077.html AJAX applications].&lt;br /&gt;
&lt;br /&gt;
== How to use PHP in the camera ==&lt;br /&gt;
It is very simple. It is the same as to try your HTML/JavaScript pages.  You just need to ftp you script to one of the two locations (or their subdirectories) in the camera. Examples below assume you have the default camera IP='''192.168.0.9''':&lt;br /&gt;
* '''/var/html''' (visible as '''http://192.168.0.9/var/''' in the web browser) - recommended for experiments, if something goes wrong you can just power-cycle the camera and all your changes will be gone&lt;br /&gt;
* '''/usr/html''' (visible as ''http://192.168.0.9/''' in the web browser) - permanent (until next full firmware upgrade ) storage in the camera flash memory. This second location is more dangerous as you can change the installed files and rebooting will not restore the default behaviour. Flash memory has limited number of write cycles and can develop additional bad blocks during usage, so this location is recommended for &amp;quot;final&amp;quot; files, already tested in /var/html.&lt;br /&gt;
&lt;br /&gt;
You may also edit small text files with web-based editor. It does not allow to open non-existent file, but has an option to &amp;quot;Save As&amp;quot; - http://192.168.0.9/admin-bin/editcgi.cgi&lt;br /&gt;
So you can try opening http://192.168.0.9/admin-bin/editcgi.cgi?file=/usr/html/phpinfo.php and then (modify and) save it to /var/html/test.php . When done - just open the following URL and watch the results of the script processing by in-camera PHP:&lt;br /&gt;
&lt;br /&gt;
 '''http://192.168.0.9/var/test.php'''  - run&lt;br /&gt;
 '''http://192.168.0.9/admin-bin/editcgi.cgi?file=/var/html/test.php''' - edit&lt;br /&gt;
&lt;br /&gt;
It is also possible to execute PHP scripts without the browser - camera startup scripts already use it for various initialization of the hardware. You can (silently) execute the same program in telnet session:&lt;br /&gt;
 php /var/html/test.php &amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
== Elphel PHP extension in the camera ==&lt;br /&gt;
Since [[Release_notes|Elphel software version 7.1.6]] there is a custom extension module for PHP installed in the camera, you may also create your own extension as described [[PHP_in_Elphel_cameras#Creating_custom_PHP_extensions_for_Elphel_cameras|below]]. The existent extension exports several functions and defines constants.&lt;br /&gt;
=== Constants, defined in ''elphel'' PHP extension ===&lt;br /&gt;
see: [[Elphel_PHP_constants]]&lt;br /&gt;
===''elphel'' extension functions ===&lt;br /&gt;
&lt;br /&gt;
''Note: Currently arguments (and array values) are supposed to be numbers, not strings - you may want to use $value+0 (instead of just $value) if $value may be a string (i.e. passed from _GET[])''--[[User:Andrey.filippov|Andrey.filippov]] 19:55, 14 December 2007 (CST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_get_P_value ====&lt;br /&gt;
''long'' '''elphel_get_P_value''' (''long'' $address)&lt;br /&gt;
&lt;br /&gt;
This function returns value of one of internal camera parameters, as defined in [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/include/asm-cris/elphel/c313a.h?view=markup c313a.h] and documented in [[Elphel_PHP_constants]]. It is strongly recommended to use symbolic names as the numeric values may change in the future (as they already did multiple times). The values are maintained by the camera driver(s), usually they are updated when the driver programs the acquisition process.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_get_P_value(ELPHEL_FP100S)/100; // will return current camera sensor frame rate in (frames per second);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_set_P_value ====&lt;br /&gt;
''void'' '''elphel_set_P_value''' (''long'' $address, ''long'' $data)&lt;br /&gt;
&lt;br /&gt;
Set a single camera parameter.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_set_P_value(ELPHEL_QUALITY,100); // set JPEG compression quality to 100% - virtually lossless&lt;br /&gt;
The elphel_get_P_value and  elphel_set_P_value deal with different variables. Those that are read are validated to match the allowed values and may differ from those written (and they are only updated when sensor/compressor are programmed). You may read the parameters values that were written to the camera by adding ELPHEL_NUMBER to the parameter address, i.e&lt;br /&gt;
 echo elphel_get_P_value(ELPHEL_QUALITY+ELPHEL_NUMBER); // will output the compression quality as written&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_get_P_arr ====&lt;br /&gt;
''array'' '''elphel_get_P_arr''' (''array'' $template)&lt;br /&gt;
&lt;br /&gt;
Read multiple camera parameters as an associative array, according to $template. $template should have elements with the key names matching the camera parameters names, same as defined [[Elphel_PHP_constants]], but without &amp;quot;ELPHEL_&amp;quot; prefix (all the elements with the other keys will be ignored). '''elphel_get_P_arr''' returns array, where element keys are the same as in $template (after removing of any unknown ones), and values are ''long'' values read from the camera.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 $arr=array(&amp;quot;foo&amp;quot;=&amp;gt;&amp;quot;&amp;quot;, &amp;quot;WOI_LEFT&amp;quot; =&amp;gt; &amp;quot;&amp;quot;,  &amp;quot;WOI_TOP&amp;quot; =&amp;gt; &amp;quot;&amp;quot;, &amp;quot;1&amp;quot;, 3, &amp;quot;WOI_WIDTH&amp;quot; =&amp;gt; 0, &amp;quot;WOI_HEIGHT&amp;quot; =&amp;gt; 0);&lt;br /&gt;
 print_r ($arr);&lt;br /&gt;
will return (5MPix sensor, full window):&lt;br /&gt;
 Array&lt;br /&gt;
 (&lt;br /&gt;
    [WOI_LEFT] =&amp;gt; 0&lt;br /&gt;
    [WOI_TOP] =&amp;gt; 0&lt;br /&gt;
    [WOI_WIDTH] =&amp;gt; 2592&lt;br /&gt;
    [WOI_HEIGHT] =&amp;gt; 1936&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_set_P_arr ====&lt;br /&gt;
''long'' '''elphel_set_P_arr''' (''array'' $input, ''long'' $frame, ''long'' $flag) )&lt;br /&gt;
&lt;br /&gt;
Write multiple camera parameters, provided as an associative array, where keys are parameter names  same as defined [[Elphel_PHP_constants]], but without &amp;quot;ELPHEL_&amp;quot; prefix. Values should be numeric and integer, all other types are ignored.&lt;br /&gt;
&lt;br /&gt;
optional arguments:&lt;br /&gt;
  frame - frame number to write these parameters to - if not specified default framedelay (current frame + 3) is applied)&lt;br /&gt;
  flag - possible flags? &lt;br /&gt;
&lt;br /&gt;
Return value - frame number to which parameters were written &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_set_P_arr(array(&amp;quot;WOI_LEFT&amp;quot; =&amp;gt; 896,  &amp;quot;WOI_TOP&amp;quot; =&amp;gt; 672, &amp;quot;WOI_WIDTH&amp;quot; =&amp;gt; 800, &amp;quot;WOI_HEIGHT&amp;quot; =&amp;gt; 600));&lt;br /&gt;
Will set 800x600 window in the center of the 5Mpix sensor and print frame number these changes where applied to&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_get_state ====&lt;br /&gt;
''long'' '''elphel_get_state''' (''void'')&lt;br /&gt;
There are multiple states defined in the camera, some are obsolete, the following are most common (no symbolic constants in PHP yet)&lt;br /&gt;
* 0 - &amp;quot;reset&amp;quot; (i.e. no images yet acquired after power up)&lt;br /&gt;
* 7 - &amp;quot;stopped&amp;quot; - sensor is constantly acquiring images (used for autoexposure), but compressor is stopped and no frames get to the [[Circbuf|circbuf]]&lt;br /&gt;
* 8 - &amp;quot;running&amp;quot; - compressor is acquiring images to [[Circbuf|circbuf]]&lt;br /&gt;
* 9 - &amp;quot;stopping&amp;quot; - compressor is compressing the last frame (transition from &amp;quot;running&amp;quot; to &amp;quot;stopped&amp;quot;&lt;br /&gt;
*10 - &amp;quot;single_buffer&amp;quot; - compressor is acquiring full [[Circbuf|circbuf]] (plus one frame as it will notice the buffer is full after overrunning the original starting point) and then will stop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_fpga_read ====&lt;br /&gt;
''long'' '''elphel_fpga_read''' (''long $address'')&lt;br /&gt;
&lt;br /&gt;
Reads data from a certain fpga register address.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_fpga_read(4); // outputs the data at address 4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_fpga_write ====&lt;br /&gt;
''void'' '''elphel_fpga_write''' (''long $address, long $data'')&lt;br /&gt;
&lt;br /&gt;
Writes data to a certain fpga register address.&lt;br /&gt;
&lt;br /&gt;
'''for Elphel 353 cameras these values can be the following (quoted from x353.h):'''&lt;br /&gt;
  187 #define X313_WA_WCTL	    0 // write control register - 32&lt;br /&gt;
  188 #define X313_WA_DMACR	    1 // DMA control register:&lt;br /&gt;
  189                               // 17:    DMA enable&lt;br /&gt;
  190                               // 16:    0- raw, 1 - JPEG&lt;br /&gt;
  191                               // 15-10: not used&lt;br /&gt;
  192                               // 0-9:   line length in long words&lt;br /&gt;
  193 #define X313_WA_SENSFPN	    2 // Sensor/FPN control register:&lt;br /&gt;
  194                                        // [10] - testmode - if 1 generates gradient data (as Zoran chips) where pixel value = horizontal position&lt;br /&gt;
  195                                        // [9:7] - submode - subtract background (8 bits) mode (use di[7:0]):&lt;br /&gt;
  196                                        // 000 - no subtraction;&lt;br /&gt;
  197                                        // 001 - (finest) subtract 8 bit bkgnd from 12 bits pixels&lt;br /&gt;
  198                                        // 010 - shift 8bit bkgnd 1 bit  left before applying&lt;br /&gt;
  199                                        // 011 - shift 8bit bkgnd 2 bits left before applying&lt;br /&gt;
  200                                        // 100 - shift 8bit bkgnd 2 bits left before applying&lt;br /&gt;
  201                                        // 101 - shift 8bit bkgnd 2 bits left before applying&lt;br /&gt;
  202                                        // fpn data to subtract should be a little less to add a &amp;quot;fat zero&amp;quot;&lt;br /&gt;
  203                                        // [6:4] - mpymode sensitivity correction mode (use di[15:8]):&lt;br /&gt;
  204                                        // 000 - no correction&lt;br /&gt;
  205                                        // 001 - fine correction (+/-3.125%)&lt;br /&gt;
  206                                        // 010 - fine correction (+/-6.25%)&lt;br /&gt;
  207                                        // 011 - fine correction (+/-12.5%)&lt;br /&gt;
  208                                        // 100 - +/- 25%&lt;br /&gt;
  209                                        // 101 - +/- 50%&lt;br /&gt;
  210                                        // [3] - wdth - word width: 0 - 8 bit, 1 - 16 bit (5 MSB == 0)&lt;br /&gt;
  211                                        // [2:0] scaling of 11 bit FPN result to fit in 8bit output:&lt;br /&gt;
  212                                        // 00 - default - use [9:1]&lt;br /&gt;
  213                                        // 01 - use [10:2] - to protect from saturation after applying mpymode&lt;br /&gt;
  214                                        //      nominal range - 0..127&lt;br /&gt;
  215                                        // 10 - use [7:0] before saturation, &amp;quot;digital gain&amp;quot; == 4 (maximal)&lt;br /&gt;
  216                                        // 11 - use [8:1] before saturation, &amp;quot;digital gain&amp;quot; == 2&lt;br /&gt;
  217 &lt;br /&gt;
  218                               // 31-8: not used&lt;br /&gt;
  219                               //    7: 0 - normal, 1 - test mode (as Zoran)&lt;br /&gt;
  220                               //  6-5: subtract FPN mode:&lt;br /&gt;
  221                               //       0 - no subtraction&lt;br /&gt;
  222                               //       1 (fine) - subtract 8-bit FPN from 10-bit pixel&lt;br /&gt;
  223                               //       2 - multiply FPN by 2 before subtracting&lt;br /&gt;
  224                               //       3 - multiply FPN by 4 before subtracting (full scfpcfale)&lt;br /&gt;
  225                               // negative result is replaced by 0, decrease FPN data before applying for &amp;quot;fat 0&amp;quot;&lt;br /&gt;
  226                               // 4-3: muliply by inverse sensitivity (sensitivity correction) mode:&lt;br /&gt;
  227                               //       0 - no correction&lt;br /&gt;
  228                               //       1 - fine (+/- 12.5%)&lt;br /&gt;
  229                               //       2 - medium (+/- 25%)&lt;br /&gt;
  230                               //       3 - maximal (+/- 50%)&lt;br /&gt;
  231                               //   2: pixel depth:&lt;br /&gt;
  232                               //       0 - 8 bits/pixel (needed for JPEG encoding)&lt;br /&gt;
  233                               //       1 - 16 bits/pixel (only 11 LSBs are non-zero)&lt;br /&gt;
  234                               // 1-0: scale (8 bit mode only):&lt;br /&gt;
  235                               //       0 - full scale corresponds to sensor full scale if no correction was applied&lt;br /&gt;
  236                               //       1 - divide by 2. This will guarantee against saturation after sensitivity correction was&lt;br /&gt;
  237                               //           applied. Nominal output range - 0..127&lt;br /&gt;
  238                               //       2 - multiply by 4 (use 8 lower bits from sensor data)&lt;br /&gt;
  239                               //       3 - multiply by 2&lt;br /&gt;
  240                               // Result data is saturated by 255&lt;br /&gt;
  241 #define X313_WA_VIRTTRIG   3  // Virtual trigger threshold&lt;br /&gt;
  242                               //   31-22  not used&lt;br /&gt;
  243                               //   21-0  Trigger will fire if sum of pixels in a line&lt;br /&gt;
  244                               //         (after FPN processig) is more than this value.&lt;br /&gt;
  245                               //         Disabled if 0 - selected real (electrical) external trigger&lt;br /&gt;
  246 #define X313_WA_TRIG       4  // Sensor triggering&lt;br /&gt;
  247                               // 31-3: not used&lt;br /&gt;
  248                               //    2: Enable sensor (0 - abort at once)&lt;br /&gt;
  249                               //    1: External Trigger (0 - internal)&lt;br /&gt;
  250                               //    0: continuous acquisition (0 - single &amp;quot;frame&amp;quot; - actually number of lines specified)&lt;br /&gt;
  251 #define X313_WA_NLINES     5  //  number of lines to acquire (afer trigger)&lt;br /&gt;
  252                               // 31-11: not used&lt;br /&gt;
  253                               // 10-0 : number of lines to acquire (in a frame or after the external trigger)&lt;br /&gt;
  254 //#define X313_WA_IRQM       6  // Interrupt mask (1 - enable, 0 - reset all but done)&lt;br /&gt;
  255                               // 31-04: not used&lt;br /&gt;
  256                               //     3: Done. Reset by writing to X313_WA_TRIG&lt;br /&gt;
  257                               //     2: frame acquisition over&lt;br /&gt;
  258                               //     1: external trigger&lt;br /&gt;
  259                               //     0: frame sync (vacts)&lt;br /&gt;
  260 #define X313_WA_DCDC       7  // sensor DC-DC converter frequency settings&lt;br /&gt;
  261                               // 31-05: not used&lt;br /&gt;
  262                               //   4-0  0 - use internal clock (not sync)&lt;br /&gt;
  263                               //        1..31 use divided pixel clock&lt;br /&gt;
  264                               //        for 20MHz use 5'h10,&lt;br /&gt;
  265                               //        else - N= (Fpix[MHz]/1.2)-1, if Fpix=20MHz,&lt;br /&gt;
  266                               //        N= 15.7-&amp;gt;16=5'h10&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_fpga_write(4, 4); // Sets sensor triggering to an unused number and therefore disabling it -&amp;gt; acquire single frame to video buffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_reset_sensor ====&lt;br /&gt;
''void'' '''elphel_reset_sensor''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Reset the sensor settings, stop compressor (if it was running) and force sensor re-initialization.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_reset_sensor();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_program_sensor ====&lt;br /&gt;
''void'' '''elphel_program_sensor''' (''long'' $nonstop)&lt;br /&gt;
&lt;br /&gt;
Applies written earlier (see [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]], [[PHP_in_Elphel_cameras#elphel_white_balance|elphel_white_balance]]) parameters to the cameras sensor and FPGA compressor. $nonstop determines if the acquisition should be restarted ($nonstop==0) or updated without stopping ($nonstop==1).&lt;br /&gt;
&lt;br /&gt;
'''Note:''' As of version 8.x, parameters are applied as they are set.  Therefore, this function is no longer necessary.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_program_sensor(0);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_wait_frame ====&lt;br /&gt;
''void'' '''elphel_wait_frame''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Waits for the next frame to be compressed to the circular buffer - it is also the time when some other parameters (accessible with [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]]) are updated.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_wait_frame();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_wait_frame_abs ====&lt;br /&gt;
''long'' '''elphel_wait_frame''' (''long'' frame)&lt;br /&gt;
&lt;br /&gt;
wait for absolute frame number (includes those that are not compressed) &lt;br /&gt;
&lt;br /&gt;
returns: frame number&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_wait_frame_abs(200);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_skip_frames ====&lt;br /&gt;
''long'' '''elphel_skip_frames''' (''long'' frames)&lt;br /&gt;
&lt;br /&gt;
skip some frames (includes those that are not compressed) - will work even if no frames are compressed &lt;br /&gt;
&lt;br /&gt;
returns: frame number&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_skip_frames(1);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==== elphel_compressor_run ====&lt;br /&gt;
''void'' '''elphel_compressor_run''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Turn the FPGA compressor on. Sensor should be already programmed ([[PHP_in_Elphel_cameras#|elphel_get_state] should return 7 (or higher) if tested prior to issuing ''elphel_compressor_run()'' command.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_compressor_run();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_compressor_stop ====&lt;br /&gt;
''void'' '''elphel_compressor_stop''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Stop camera compressor (will stop transferring more frames to the [[Circbuf|circular buffer]]. This command does not to be synchronized - compressor will finish current frame before stopping.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_compressor_stop();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_compressor_frame ====&lt;br /&gt;
''void'' '''elphel_compressor_frame''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Acquire one frame to the buffer (will apply written JPEG quality). Sensor should be already programmed - [[PHP_in_Elphel_cameras#|elphel_get_state]] should return 7 (or higher) if tested prior to issuing ''elphel_compressor_frame()'' command.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_compressor_frame();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_set_fpga_time ====&lt;br /&gt;
''double'' '''elphel_set_fpga_time''' (''double'' seconds)&lt;br /&gt;
&lt;br /&gt;
Set FPGA internal timer that is used for time-stamping images and video frames. Internal counter has a 32-bit seconds counter and 12 bit microsecond one, so you may specify epoch - seconds since 01/01/1970.&lt;br /&gt;
&lt;br /&gt;
Returns time set as a ''double'' - it should match the input parameter after rounding to microseconds (resolution of the FPGA timer).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_set_fpga_time(0x47565ad3);&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_get_fpga_time ====&lt;br /&gt;
''double'' '''elphel_get_fpga_time''' (''void'')&lt;br /&gt;
&lt;br /&gt;
Copies current value of the FPGA timer registers to the global array (maybe read with several functions described above) and returns the the time as a ''double'' value, combining second as microseconds. The readout process guaranties that seconds and microseconds are sample simultaneously.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 echo elphel_get_fpga_time();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
----&lt;br /&gt;
==== elphel_flush_cache ====&lt;br /&gt;
''void'' '''elphel_flush_cache''' (''void'')&lt;br /&gt;
&lt;br /&gt;
This function is included to fight (hardware) cache coherency problems in mmap implementation for ETRAX FS processor. I'm not sure it will be really needed here - it needs some testing. If it will be proven it is needed - we'll incorporate it into appropriate functions that depend on it, if not it will just be removed.&lt;br /&gt;
&lt;br /&gt;
This function may be needed before [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] to read data updated by the driver and/or before [[PHP_in_Elphel_cameras#elphel_program_sensor|elphel_program_sensor]], [[PHP_in_Elphel_cameras#elphel_compressor_run\elphel_compressor_run]], [[PHP_in_Elphel_cameras#elphel_compressor_frame|elphel_compressor_frame]] (if any of the parameters were changed with  [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]]  after the last call to elphel_flush_cache&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 elphel_flush_cache();&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_white_balance ====&lt;br /&gt;
''int'' '''elphel_white_balance''' ([''double'' thrsh [, ''double'' minfrac [, ''double'' rscale [, ''double'' bscale]]]])&lt;br /&gt;
&lt;br /&gt;
This function is designed to perform white balancing of the camera images. It relies on histogram calculation, &amp;quot;gamma&amp;quot; tables (curves) (both implemented in the FPGA) and the auto-exposure software in the camera (not yet included in this PHP extension, it is currently controlled through the separate CGI program). White balance uses the same window as auto-exposure, only data inside the specified rectangular window is processed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The goal of this function is to make the brightest areas in the image white (equal values of red, green and blue), it assumes that auto-exposure algorithm (operating after each frame acquired) already adjusted the brightness of the images so it uses all the 8-bit range and some pixel values are close to the maximal 255.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The balancing is achieved by modification of the lookup tables (&amp;quot;gamma&amp;quot; tables, &amp;quot;curves&amp;quot;) that map 12-bit (in 5MPix sensor, may be 10 or 14 bits with other devices) pixel data to the 8-bit pixel values used by the image/video compressor, the same values can be manually entered with [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] functions applied to RSCALE and BSCALE parameters. The balancing is sensor-independent and it does not change sensor analog gains (where available), but if the required correction is significant, it is recommended to adjust those gains also, leaving only fine adjustment to the white balance algorithm - that will increase the dynamic range of the images.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
All function parameters are optional, but you can not skip the first one(s) if you would like to specify the next one(s), in that case default values should be explicitly entered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First parameter '''thrsh''' defines how bright should be pixels to be counted as white. Default value of '''0.98''' corresponds to 250 counts on 255 scale.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Second parameter '''minfrac''' (default '''0.01''') tells how many pixels (at least) should be counted, as a fraction of the total number of the pixels in the specified window. If there are too few pixels with the brightness above the ''thrsh'', the ''thrsh'' will be lowered, to let more pixels to be counted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next two parameters - '''rscale''' and '''bscale''' (both with default values of '''1.0''') can be used to apply manual bias to the automatically calculated values of red and blue scales (relative.to green)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When this function is executed successfully it returns 0 (negative numbers indicate failure) in adjusts parameters (similar to manual [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]]), but that will propagate to the FPGA only after [[PHP_in_Elphel_cameras#elphel_program_sensor|elphel_program_sensor]] is executed. If you do not need to change any other parameters, you may use '''elphel_program_sensor(1)''' - in this case the image/video acquisition process will not be interrupted, frame timing will be preserved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As this function uses the histograms calculated from the previously acquired images, you actually need to acquire some. It is recommended you wait till the auto-exposure will adjust the brightness before executing elphel_white_balance. It also is not needed to run it as frequently as auto-exposure (for each frame), usually it is enough to call it only when the lighting conditions are changed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
 if (elphel_white_balance()&amp;gt;=0) elphel_program_sensor(1);&lt;br /&gt;
or&lt;br /&gt;
 elphel_white_balance(0.98,0.01,1.0,1.2); // set bluish tint&lt;br /&gt;
&lt;br /&gt;
[http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/packages/web/353/php_top/whitebalance.php?view=markup whitebalance.php] is an example script that uses this function. It is installed in the camera and can be called as  (provided camera has the default IP of 192.168.0.9):&lt;br /&gt;
 http://192.168.0.9/whitebalance.php&lt;br /&gt;
or&lt;br /&gt;
 http://192.168.0.9/whitebalance.php?thrsh=0.98&amp;amp;minfrac=0.01&amp;amp;rscale=1.0&amp;amp;bscale=1.0&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
==== elphel_autoexposure_set ====&lt;br /&gt;
''void'' '''elphel_autoexposure_set''' (''void'')&lt;br /&gt;
&lt;br /&gt;
This function controls auto-exposure in the camera. It is a quick modification that preserves the existent functionality (including interface) and just adds control from the PHP. This function itself does not take any parameters, it also does not return any data, It applies parameters that have to be already written by either of [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]], the current state of the auto-exposure algorithm can be read back using [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] functions.&lt;br /&gt;
&lt;br /&gt;
===== auto-exposure software in the camera =====&lt;br /&gt;
&lt;br /&gt;
====== kernel space (driver) ======&lt;br /&gt;
When the image from the sensor is acquired in the camera (even the compressor is off), software interrupt is generated and among others two things related to the auto-exposure control happen in the driver.&lt;br /&gt;
* software prepares histograms calculated in the FPGA during the previous frame acquisition to be analysed by the user space application and make them available to the userspace applications through memory-mapped arrays (mmap) and&lt;br /&gt;
* the previously calculated exposure is applied to the sensor to take effect during the next frame acquisition. Exposure time is the only parameter controlled automatically, you may also want to change analog gain(s) (sensitivity) to extend the range of the illumination levels that camera can handle. Most of this driver functionality is implemented in the [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/hist353.c?view=markup hist353.c].&lt;br /&gt;
&lt;br /&gt;
====== user space (daemon) ======&lt;br /&gt;
User space application [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/autoexp/autoexp.c?view=markup autoexp.c] (running as a daemon) processes the histograms and calculates the corrected value of the exposure, the result value is sent to the driver that applies the required correction. &lt;br /&gt;
&lt;br /&gt;
In addition the histograms (four of them - individually for each of the 4 Bayer components, including 2 sets of green pixels), driver provides applications with the lookup (&amp;quot;gamma&amp;quot;) tables that are used by the FPGA to convert sensor pixel value (12 bit for the 5MPix sensor) into the 8-bit range, usually - non-linearly, controlled by &amp;quot;gamma&amp;quot; parameter. This tables are needed when processing the histograms, as FPGA calculates them after the LUT are applied to the pixel values.&lt;br /&gt;
&lt;br /&gt;
The auto-exposure configuration (input) parameters and the current state (output) can still be accessed using the current CGI script [http://elphel.cvs.sourceforge.net/elphel/elphel353-7.1/apps/autoexp/autoexpos.cgi.c?view=markup autoexpos.cgi.c] (as used by camvc user interface), alternatively they are directly accessible through the [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]], [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]],  [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]] functions.&lt;br /&gt;
&lt;br /&gt;
===== auto-exposure algorithm in the camera =====&lt;br /&gt;
&lt;br /&gt;
The goal of the auto-exposure algorithm is to use as much as possible of the sensor dynamic range in the area of interest. It tries to adjust the exposure of the sensor so the whole range of the image pixel values (up to 255) are used (small number of pixels are usually still allowed to overexpose and be return the 255 limit value). It is possible to maintain the brightest pixels (disregarding just few &amp;quot;super-bright&amp;quot;) near 255, but the it has 2 disadvantages:&lt;br /&gt;
* sometimes with the back light you want to have good reproduction of darker objects while allowing the bright background to saturate&lt;br /&gt;
* it is difficult to calculate required correction when the exposure is too  long (some areas are over-saturated), because there is no way to know how much are the pixels saturated (if the image is too dim, the required exposure increase is just the ratio of 255 and the brightest pixels in the image)&lt;br /&gt;
For these reasons a slightly different algorithm is used - the software tries to maintain specified part of the pixels in the window of interest to be below the specified level (usually high, but less than the full scale). In this case if the brightness of the scene suddenly increases (up to the ratio of the full scale pixel value to the specified threshold), the exposure correction can be calculated and applied in a single step. You may experiment with this algorithm using GUI in ''camvc'' camera web interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== parameters that control auto-exposure in the camera =====&lt;br /&gt;
The following are parameters (it is possible to both their names as array keys with functions  [[PHP_in_Elphel_cameras#elphel_set_P_arr|elphel_set_P_arr]], [[PHP_in_Elphel_cameras#elphel_get_P_arr|elphel_get_P_arr]], [[PHP_in_Elphel_cameras#elphel_get_P_warr|elphel_get_P_warr]]. There are also [[Elphel_PHP_constants|constants]] defined that use the same names with &amp;quot;ELPHEL_&amp;quot;prefix (i.e. ELPHEL_AUTOEXP_ON), these constants are useful with the functions [[PHP_in_Elphel_cameras#elphel_set_P_value|elphel_set_P_value]],  [[PHP_in_Elphel_cameras#elphel_get_P_value|elphel_get_P_value]]. All the parameter values are ''long'' (32-bit) integers, you may read them back (as written) with [[PHP_in_Elphel_cameras#elphel_get_P_warr|elphel_get_P_warr]] function call. Te value of ELPHEL_HIST_NOT_CHANGE (65536) for any of these parameters mean that values corresponding to these parameters will not be updated.&lt;br /&gt;
&lt;br /&gt;
* '''AUTOEXP_ON''' - when set to '''1''' enables automatic exposure control, when '''0''' - disables it&lt;br /&gt;
* '''AUTOEXP_RWIDTH''', '''AUTOEXP_RHEIGHT''' - relative width and height (in %) of the auto-exposure window width and height. It is used for histogram calculation in the FPGA and so controls not only auto-exposure, but also [[PHP_in_Elphel_cameras#elphel_white_balance|white balance]] and manual histogram processing&lt;br /&gt;
* '''AUTOEXP_RLEFT''', '''AUTOEXP_RTOP''' - position of the auto-exposure window center, in %, counted from the left and top respectively&lt;br /&gt;
* '''AUTOEXP_EXP_MAX''' - maximal exposure time (in 1/10000 of a second) allowed for the auto-exposure algorithm. It is recommended to set it equal to the frame period when video is streamed or recorded, otherwise in the low-light conditions the frame rate may drop to accommodate longer exposure times (frame period may never be shorter than the exposure time)&lt;br /&gt;
* '''AUTOEXP_OVEREXP_MAX''' (old algorithm) - amount of pixels (fraction of all the pixels in the auto-exposure window) that are allowed to be overexposed, measured in 1/100 or a percent. This parameter is used when both '''AUTOEXP_S_PERCENT''' and '''AUTOEXP_S_INDEX''' (see below) are 0. This algorithm can be slow to handle over-exposed images and is not recommended.&lt;br /&gt;
* '''AUTOEXP_S_PERCENT''' - amount of pixels that are controlled to have value below the specified '''AUTOEXP_S_INDEX''' (below), measured in 1/100 of a percent. Example: AUTOEXP_S_PERCENT=9400 means that 94% of pixels should have value lower than '''AUTOEXP_S_INDEX'''&lt;br /&gt;
* '''AUTOEXP_S_INDEX''' - threshold for the pixel values (on a 0..255 8-bit scale) used together with '''AUTOEXP_S_PERCENT'''&lt;br /&gt;
* '''AUTOEXP_SKIP_PMIN''' - minimal calculated exposure correction that will be applied (in 1/100 of a %). Value of 500 (default) means that exposure value will not be modified if the calculated value differs less than by 5% from the current one&lt;br /&gt;
* '''AUTOEXP_SKIP_T''' minimal absolute exposure correction (in exposure steps, currently 1 step is 1/10000 sec), default value = 2&lt;br /&gt;
* '''AUTOEXP_SKIP_PMAX''' - maximal allowed  exposure correction that algorithm is allowed to apply (in 1/200 of a %, default is 5000 - 50%). If calculated exposure correction exceeds this value, it will not be applied immediately, the algorithm will wait for the next frame to make sure it was not an instant flash (i.e from some camera)&lt;br /&gt;
* '''AEXPWND_WIDTH''', '''AEXPWND_HEIGHT''', '''AEXPWND_TOP''', '''AEXPWND_LEFT''' (when written to) behave similarly to '''AEXPWND_RWIDTH''', '''AEXPWND_RHEIGHT''', '''RAEXPWND_TOP''' and '''AEXPWND_RLEFT''', but come into effect immediately, not waiting for the [[PHP_in_Elphel_cameras#elphel_autoexposure_set|elphel_autoexposure_set()]] call. Writing to AEXPWND_RWIDTH, AEXPWND_RHEIGHT, RAEXPWND_TOP and AEXPWND_RLEFT and calling [[PHP_in_Elphel_cameras#elphel_autoexposure_set|elphel_autoexposure_set()]] updates the AEXPWND_WIDTH, AEXPWND_HEIGHT, AEXPWND_TOP, AEXPWND_LEFT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
    [AUTOEXP_EXP] =&amp;gt; 801&lt;br /&gt;
    [AUTOEXP_SKIP_PMIN] =&amp;gt; 500&lt;br /&gt;
    [AUTOEXP_SKIP_PMAX] =&amp;gt; 5000&lt;br /&gt;
    [AUTOEXP_SKIP_T] =&amp;gt; 2&lt;br /&gt;
    [AEXPWND_WIDTH] =&amp;gt; 80&lt;br /&gt;
    [AEXPWND_HEIGHT] =&amp;gt; 80&lt;br /&gt;
    [AEXPWND_TOP] =&amp;gt; 50&lt;br /&gt;
    [AEXPWND_LEFT] =&amp;gt; 50&lt;br /&gt;
&lt;br /&gt;
  [ELPHEL_AUTOEXP_ON] =&amp;gt; 76&lt;br /&gt;
    [ELPHEL_AUTOEXP_RWIDTH] =&amp;gt; 77&lt;br /&gt;
    [ELPHEL_AUTOEXP_RHEIGHT] =&amp;gt; 78&lt;br /&gt;
    [ELPHEL_AUTOEXP_RLEFT] =&amp;gt; 79&lt;br /&gt;
    [ELPHEL_AUTOEXP_RTOP] =&amp;gt; 80&lt;br /&gt;
    [ELPHEL_AUTOEXP_EXM_MAX] =&amp;gt; 81&lt;br /&gt;
    [ELPHEL_AUTOEXP_OVEREXP_MAX] =&amp;gt; 82&lt;br /&gt;
    [ELPHEL_AUTOEXP_S_PERCENT] =&amp;gt; 83&lt;br /&gt;
    [ELPHEL_AUTOEXP_S_INDEX] =&amp;gt; 84&lt;br /&gt;
    [ELPHEL_AUTOEXP_EXP] =&amp;gt; 85&lt;br /&gt;
    [ELPHEL_AUTOEXP_SKIP_PMIN] =&amp;gt; 86&lt;br /&gt;
    [ELPHEL_AUTOEXP_SKIP_PMAX] =&amp;gt; 87&lt;br /&gt;
    [ELPHEL_AUTOEXP_SKIP_T] =&amp;gt; 88&lt;br /&gt;
    [ELPHEL_AEXPWND_WIDTH] =&amp;gt; 89&lt;br /&gt;
    [ELPHEL_AEXPWND_HEIGHT] =&amp;gt; 90&lt;br /&gt;
    [ELPHEL_AEXPWND_TOP] =&amp;gt; 91&lt;br /&gt;
    [ELPHEL_AEXPWND_LEFT] =&amp;gt; 92&lt;br /&gt;
    [ELPHEL_HIST_NOT_CHANGE] =&amp;gt; 65535&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating custom PHP extensions for Elphel cameras ==&lt;br /&gt;
&lt;br /&gt;
The followings steps are needed to create a custom PHP extension to run in Elphel product:&lt;br /&gt;
&lt;br /&gt;
* Create subdirectory of this (ext) directory for the new extension&lt;br /&gt;
* Create files in this new directory - at least&lt;br /&gt;
**   config.m4&lt;br /&gt;
**   &amp;lt;your name&amp;gt;.h&lt;br /&gt;
**   &amp;lt;yourname&amp;gt;.c&lt;br /&gt;
&lt;br /&gt;
You may use ext_skel script to automate this process or follow a nice tutorial by Sara Goleman '''[http://devzone.zend.com/node/view/id/1021 Extension Writing Part I: Introduction to PHP and Zend]''' . You may also like to read her book, &amp;quot;Extending and Embedding PHP&amp;quot;.&lt;br /&gt;
=== config.m4 ===&lt;br /&gt;
&lt;br /&gt;
 PHP_ARG_ENABLE(hello, whether to enable Hello World support, [ --enable-hello   Enable Hello World support])&lt;br /&gt;
 if test &amp;quot;$PHP_HELLO&amp;quot; = &amp;quot;yes&amp;quot;; then&lt;br /&gt;
  AC_DEFINE(HAVE_HELLO, 1, [Whether you have Hello World])&lt;br /&gt;
  PHP_NEW_EXTENSION(hello, hello.c, $ext_shared)&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
=== php_hello.h ===&lt;br /&gt;
&lt;br /&gt;
 #ifndef PHP_HELLO_H&lt;br /&gt;
 #define PHP_HELLO_H 1&lt;br /&gt;
 #define PHP_HELLO_WORLD_VERSION &amp;quot;1.0&amp;quot;&lt;br /&gt;
 #define PHP_HELLO_WORLD_EXTNAME &amp;quot;hello&amp;quot;&lt;br /&gt;
 PHP_FUNCTION(hello_world);&lt;br /&gt;
 extern zend_module_entry hello_module_entry;&lt;br /&gt;
 #define phpext_hello_ptr &amp;amp;hello_module_entry&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
=== hello.c ===&lt;br /&gt;
&lt;br /&gt;
 #ifdef HAVE_CONFIG_H&lt;br /&gt;
 #include &amp;quot;config.h&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
 #include &amp;quot;php.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;php_hello.h&amp;quot;&lt;br /&gt;
 static function_entry hello_functions[] = {&lt;br /&gt;
    PHP_FE(hello_world, NULL)&lt;br /&gt;
    {NULL, NULL, NULL}&lt;br /&gt;
 };&lt;br /&gt;
 zend_module_entry hello_module_entry = {&lt;br /&gt;
 #if ZEND_MODULE_API_NO &amp;gt;= 20010901&lt;br /&gt;
    STANDARD_MODULE_HEADER,&lt;br /&gt;
 #endif&lt;br /&gt;
    PHP_HELLO_WORLD_EXTNAME,&lt;br /&gt;
    hello_functions,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
    NULL,&lt;br /&gt;
 #if ZEND_MODULE_API_NO &amp;gt;= 20010901&lt;br /&gt;
    PHP_HELLO_WORLD_VERSION,&lt;br /&gt;
 #endif&lt;br /&gt;
    STANDARD_MODULE_PROPERTIES&lt;br /&gt;
 };&lt;br /&gt;
 #ifdef COMPILE_DL_HELLO&lt;br /&gt;
 ZEND_GET_MODULE(hello)&lt;br /&gt;
 #endif&lt;br /&gt;
 PHP_FUNCTION(hello_world)&lt;br /&gt;
 {&lt;br /&gt;
    RETURN_STRING(&amp;quot;Hello World&amp;quot;, 1);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With the 3 files created you need to cd to the extension directory and run&lt;br /&gt;
 ../../elphize&lt;br /&gt;
That will generate support files (running phpize script) so you'll just need to run&lt;br /&gt;
 make install&lt;br /&gt;
to have the new extension (as a dynamic library) installed in the target directory tree and included in the camera flash image.&lt;br /&gt;
&lt;br /&gt;
You will need to add &amp;quot;extension=&amp;lt;your_extension_name&amp;gt;&amp;quot; to the php.ini file to be activated.&lt;br /&gt;
&lt;br /&gt;
When troubleshooting extensions you may also want to try your scripts from the command line in the camera - in that case the stdout will be visible and PHP+your module will be able to complain about Segmentation faults (when invoked from the browser it you will get Error 500 at best if that happens). And you'll have to manually restart web server + PHP after module changes (remember - Fast CGI does not kill PHP after end of HTTP request?)&lt;br /&gt;
&lt;br /&gt;
== Known problems ==&lt;br /&gt;
&lt;br /&gt;
Function ''[http://us.php.net/manual/en/function.fread.php fread]'' in PHP always tries to read 8192 bytes even if the length parameter is &amp;lt;8192, that causes problems when read from devices (i.e. i2c) being too slow or causing side effects. It is considered [http://bugs.php.net/bug.php?id=21641 feature, not a bug].&lt;br /&gt;
 &lt;br /&gt;
A quick fix will be to change the driver to always read minimal (1/2/3/4 bytes depending on the nature of the data) if the count passed to device read function is 8192.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:PHP]]&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=User:Dimitrios&amp;diff=11078</id>
		<title>User:Dimitrios</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=User:Dimitrios&amp;diff=11078"/>
				<updated>2012-01-05T14:51:13Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Added link to tclepeg in github&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some notes that could be useful:&lt;br /&gt;
&lt;br /&gt;
=Recording and live preview=&lt;br /&gt;
&lt;br /&gt;
Is there a way to record and, at the same time, watch a reduced resolution version in a cheap tablet or portable PC / notebook?&lt;br /&gt;
&lt;br /&gt;
'''epeg''' is a super-fast library for resizing jpegs. It offers an improvement of at least an order of magnitude over other known libraries like ImageMagick. I just compiled a command line version and these are the results:&lt;br /&gt;
&lt;br /&gt;
 $ time ./resize test.jpeg test.jpg&lt;br /&gt;
 &lt;br /&gt;
 real    0m0.063s&lt;br /&gt;
 user    0m0.060s&lt;br /&gt;
 sys     0m0.000s&lt;br /&gt;
 &lt;br /&gt;
 $ time convert -resize 426x640 test.jpeg test.jpg&lt;br /&gt;
 &lt;br /&gt;
 real    0m1.158s&lt;br /&gt;
 user    0m1.048s&lt;br /&gt;
 sys     0m0.052s&lt;br /&gt;
&lt;br /&gt;
The improvement in the above case 18 times faster.&lt;br /&gt;
'''resize''' is a little C program crafted for resizing a 2592x3888 image to a 426x640 one using the epeg library. Convert is ImageMagick's convert utility. It took resize '''63 msec''' against '''1158 msec''' for ImageMagick.&lt;br /&gt;
&lt;br /&gt;
If this functionality is included in the camera it could do jpeg resize in-memory on-the-fly and spare even more by avoiding the read/write to disk that is involved in the above test.&lt;br /&gt;
&lt;br /&gt;
'''epeg''' was a stand-alone utility that is now included in Enlightenment. The [http://maemo.gitorious.org/maemo-af/epeg Maemo] sources for epeg compile without a change in Kubuntu. There is also a [http://github.com/rsky/php-epeg PHP extension] for epeg.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''epeg''' does not decode the JPEG, it only decodes the DCT coefficients needed to reconstruct an image of the size desired.&lt;br /&gt;
&lt;br /&gt;
From the README:&lt;br /&gt;
&lt;br /&gt;
 What is Epeg?&lt;br /&gt;
 &lt;br /&gt;
 An IMMENSELY FAST JPEG thumbnailer library API.&lt;br /&gt;
 &lt;br /&gt;
 Why write this? It's a convenience library API to using libjpeg to load JPEG&lt;br /&gt;
 images destined to be turned into thumbnails of the original, saving&lt;br /&gt;
 information with these thumbnails, retrieving it and managing to load the image&lt;br /&gt;
 ready for scaling with the minimum of fuss and CPU overhead. &lt;br /&gt;
 &lt;br /&gt;
 This means it's insanely fast at loading large JPEG images and scaling them&lt;br /&gt;
 down to tiny thumbnails. It's speedup will be proportional to the size&lt;br /&gt;
 difference between the source image and the output thumbnail size as a&lt;br /&gt;
 count of their pixels.&lt;br /&gt;
 &lt;br /&gt;
 It makes use of libjpeg features of being able to load an image by only&lt;br /&gt;
 decoding the DCT coefficients needed to reconstruct an image of the size&lt;br /&gt;
 desired. This gives a massive speedup. If you do not try and access the pixels&lt;br /&gt;
 in a format other than YUV (or GRAY8 if the source is grascale) then it also&lt;br /&gt;
 avoids colorspace conversions as well.&lt;br /&gt;
 &lt;br /&gt;
In the '''libepeg''' library, there is a function epeg_memory_open() that reads a JPEG image from memory instead of a file. Then the resize can be applied and the result can be sent out instead of the original JPEG.&lt;br /&gt;
&lt;br /&gt;
The C program that does the resize is this:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stddef.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;Epeg.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   Epeg_Image *im;&lt;br /&gt;
    &lt;br /&gt;
   if (argc != 3)&lt;br /&gt;
   {&lt;br /&gt;
      printf(&amp;quot;Usage: %s input.jpg thumb.jpg\n&amp;quot;, argv[0]);&lt;br /&gt;
      exit(0);&lt;br /&gt;
   }&lt;br /&gt;
   im = epeg_file_open(argv[1]);&lt;br /&gt;
   if (!im)&lt;br /&gt;
   {&lt;br /&gt;
      printf(&amp;quot;Cannot open %s\n&amp;quot;, argv[1]);&lt;br /&gt;
      exit(-1);&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   epeg_decode_size_set           (im, 426, 640);&lt;br /&gt;
   epeg_quality_set               (im, 75);&lt;br /&gt;
   epeg_thumbnail_comments_enable (im, 1);&lt;br /&gt;
   epeg_file_output_set           (im, argv[2]);&lt;br /&gt;
   epeg_encode                    (im);&lt;br /&gt;
   epeg_close                     (im);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There is also a '''tclepeg''' package allowing the use of the epeg library from TCL, for the Linux i386 platform [http://github.com/dzach/tclepeg]&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Wishlist&amp;diff=11017</id>
		<title>Wishlist</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Wishlist&amp;diff=11017"/>
				<updated>2011-12-31T17:33:07Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As user I noticed some things I wanted to have on my camera, I hope anyone that has ideas can add them here. &lt;br /&gt;
What features are you waiting for?&lt;br /&gt;
What software components are still missing that you cannot live without?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Software==&lt;br /&gt;
If a project has been completed just add the developer that did it, or is busy on it.&lt;br /&gt;
=== Sensor ===&lt;br /&gt;
* [[Dead/Hot pixel correction]]&lt;br /&gt;
&lt;br /&gt;
=== Compass ===&lt;br /&gt;
* '''DONE''' [[Implement calibration]]&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
* [[DHCP (timeouted) and DNS-SD]]&lt;br /&gt;
* [[GigaBit ethernet]]&lt;br /&gt;
* Zeroconf (Rendezvous) for LAN device announcing&lt;br /&gt;
* [[http://opensoundcontrol.org OpenSound Control]] [[http://en.wikipedia.org/wiki/OpenSound_Control  OpenSound Control on wikipedia]], [[http://www.linuxjournal.com/content/introduction-osc introduction to OSC on linuxjournal]]&lt;br /&gt;
* CF Ethernet card support [[http://www.pocketpcfaq.com/peripherals/cfethernet.htm CF 10/100 Ethernet cards list]]&lt;br /&gt;
* CF WiFi card support [[http://www.google.ru/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.linksys.com%2Fservlet%2FSatellite%3Fchildpagename%3DUS%252FLayout%26packedargs%3Dc%253DL_Product_C2%2526cid%253D1115416826419%26pagename%3DLinksys%252FCommon%252FVisitorWrapper&amp;amp;ei=2CkjSb2pB4PG0gXtx92CAg&amp;amp;usg=AFQjCNFGaaRKL7uwQ7UNQQsxbdf9mrsoeA&amp;amp;sig2=wYBsCu8pfOyTJt57UW57EA WCF54G]]&lt;br /&gt;
* CF USB card support [[http://www.twin-paradox.com/SEPDA.html SolarExpress]] [[http://www.ratocsystems.com/english/products/CFU2U.html CFU2]]&lt;br /&gt;
* External USB Display support [http://gizmodo.com/5116061/mimo-um+750-7+inch-usb-display-lightning-review Mimo UM-750 7-inch].&lt;br /&gt;
&lt;br /&gt;
=== Fastest Boot ===&lt;br /&gt;
* [[Fast Boot]]&lt;br /&gt;
&lt;br /&gt;
=== APIs ===&lt;br /&gt;
* [[C API]]&lt;br /&gt;
* [[SOAP API]]&lt;br /&gt;
&lt;br /&gt;
=== UDMA support ===&lt;br /&gt;
* Enable [[UDMA]] in the Axis kernel. Needed to support most fast CF cards, will also boost speed on SATA.&lt;br /&gt;
&lt;br /&gt;
=== Debayer Algorithmn ===&lt;br /&gt;
* Higher image quality debayer algorithmn FPGA implementation -&amp;gt; [http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html VNG]&lt;br /&gt;
&lt;br /&gt;
==Hardware==&lt;br /&gt;
What will the next elphel camera most likely entitled '''Elphel 373''' be like?&lt;br /&gt;
&lt;br /&gt;
===Power Supply===&lt;br /&gt;
* optional 5-36V supply over additional jack [http://focus.ti.com/docs/prod/folders/print/tps5430.html DC/DC] [http://focus.ti.com/docs/prod/folders/print/tps23750.html POE] [http://www.rlocman.ru/review/article.html?di=52247 TI Article]&lt;br /&gt;
&lt;br /&gt;
===Sensor===&lt;br /&gt;
* Vignetting hardware correction&lt;br /&gt;
* Lens distortion hardware correction&lt;br /&gt;
* Fixed pattern noise (FPN) correction&lt;br /&gt;
* Flash mode for rolling shutter&lt;br /&gt;
* Make image thumbnails (binning 8x8 from DCT[0,0] data)&lt;br /&gt;
'''Position adjustment'''&lt;br /&gt;
*initial focus/pan/tilt sensor adjustment&lt;br /&gt;
*Square shaped SFE and equidistant holes for easy change of orientation&lt;br /&gt;
&lt;br /&gt;
'''Interface'''&lt;br /&gt;
*group VLDS pairs in flexible cable from sensor to board&lt;br /&gt;
*[[CCD table|CCD sensors]]&lt;br /&gt;
&lt;br /&gt;
'''Sony IMX021'''&lt;br /&gt;
*designed for DSLRs (possibly the sensor used in Nikon D300 / D90)&lt;br /&gt;
*12.4 MPix&lt;br /&gt;
*5.5 µm pixel&lt;br /&gt;
*0.18 µm technology&lt;br /&gt;
*28mm x 22.2 mm APS-C sized 1.8&amp;quot; image area (28.4 mm diagonal)&lt;br /&gt;
*12 bit column ADC&lt;br /&gt;
*10.4 fps in 12.4 MPix mode&lt;br /&gt;
*on-chip noise reduction&lt;br /&gt;
*parallel A/D for every pixel coloumn&lt;br /&gt;
&lt;br /&gt;
===CPU===&lt;br /&gt;
*USB2.0 Support&lt;br /&gt;
&lt;br /&gt;
===External data sensors support===&lt;br /&gt;
*'''DONE''' GPS&lt;br /&gt;
*'''DONE''' Compass&lt;br /&gt;
*Dry contact (simply switch event)&lt;br /&gt;
*'''DONE''' RFID&lt;br /&gt;
*Proximity&lt;br /&gt;
*Environment sensors: Temperature/Humidity/Pressure/Illuminance/Loudness/.. [http://www.catnip.co.uk/wx Open Weather], [http://www.sciproj.com/FeaturedVendorProduct.aspx?uid=1208227 EL-USB-RT], [http://www.raphnet.net/electronique/usbtenki/index_en.php USBTenki], [http://www.sparkfun.com/commerce/product_info.php?products_id=8311 USB Weather Board], [http://www.farnell.com/datasheets/129494.pdf CY3271-EXP1 (PSoC Environmental Sensing Kit)]&lt;br /&gt;
*Futaba servo captute interface (for robots)&lt;br /&gt;
&lt;br /&gt;
===External control===&lt;br /&gt;
*USB3.0 Support&lt;br /&gt;
*Futaba servo control interface (for robots) [http://www.parallax.com/Store/Accessories/MotorServoControllers/tabid/160/CategoryID/35/List/0/Level/a/ProductID/346/Default.aspx?SortField=ProductName%2CProductName PSC] [http://www.endurance-rc.com/pantilt.html Pan&amp;amp;Tilt] [http://www.openservo.com/ OpenServo] [http://www.embeddedrelated.com/usenet/embedded/show/46581-1.php Verilog solution] [http://www.sparkfun.com/commerce/product_info.php?products_id=8897 Polulu]&lt;br /&gt;
*Relay control&lt;br /&gt;
*CAN support [http://www.qprotos.com/quickcan.htm quickcan] [http://www.gridconnect.com/usbcanin.html USB CAN Adapter]&lt;br /&gt;
*DMX512 support [http://en.wikipedia.org/wiki/DMX-512 DMX512]&lt;br /&gt;
*Secure Digital support [http://www.delkin.com/products/adapters/sd-to-cf/sd-to-cf.html CF-SD]&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Wishlist&amp;diff=11016</id>
		<title>Wishlist</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Wishlist&amp;diff=11016"/>
				<updated>2011-12-31T17:29:32Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As user I noticed some things I wanted to have on my camera, I hope anyone that has ideas can add them here. &lt;br /&gt;
What features are you waiting for?&lt;br /&gt;
What software components are still missing that you cannot live without?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Software==&lt;br /&gt;
If a project has been completed just add the developer that did it, or is busy on it.&lt;br /&gt;
=== Sensor ===&lt;br /&gt;
* [[Dead/Hot pixel correction]]&lt;br /&gt;
&lt;br /&gt;
=== Compass ===&lt;br /&gt;
* '''DONE''' [[Implement calibration]]&lt;br /&gt;
&lt;br /&gt;
=== Networking ===&lt;br /&gt;
* [[DHCP (timeouted) and DNS-SD]]&lt;br /&gt;
* [[GigaBit ethernet]]&lt;br /&gt;
* Zeroconf (Rendezvous) for LAN device announcing&lt;br /&gt;
* [[http://opensoundcontrol.org OpenSound Control]] [[http://en.wikipedia.org/wiki/OpenSound_Control  OpenSound Control on wikipedia]], [[http://www.linuxjournal.com/content/introduction-osc introduction to OSC on linuxjournal]]&lt;br /&gt;
* CF Ethernet card support [[http://www.pocketpcfaq.com/peripherals/cfethernet.htm CF 10/100 Ethernet cards list]]&lt;br /&gt;
* CF WiFi card support [[http://www.google.ru/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.linksys.com%2Fservlet%2FSatellite%3Fchildpagename%3DUS%252FLayout%26packedargs%3Dc%253DL_Product_C2%2526cid%253D1115416826419%26pagename%3DLinksys%252FCommon%252FVisitorWrapper&amp;amp;ei=2CkjSb2pB4PG0gXtx92CAg&amp;amp;usg=AFQjCNFGaaRKL7uwQ7UNQQsxbdf9mrsoeA&amp;amp;sig2=wYBsCu8pfOyTJt57UW57EA WCF54G]]&lt;br /&gt;
* CF USB card support [[http://www.twin-paradox.com/SEPDA.html SolarExpress]] [[http://www.ratocsystems.com/english/products/CFU2U.html CFU2]]&lt;br /&gt;
* External USB Display support [http://gizmodo.com/5116061/mimo-um+750-7+inch-usb-display-lightning-review Mimo UM-750 7-inch].&lt;br /&gt;
&lt;br /&gt;
=== Fastest Boot ===&lt;br /&gt;
* [[Fast Boot]]&lt;br /&gt;
&lt;br /&gt;
=== APIs ===&lt;br /&gt;
* [[C API]]&lt;br /&gt;
* [[SOAP API]]&lt;br /&gt;
&lt;br /&gt;
=== UDMA support ===&lt;br /&gt;
* Enable [[UDMA]] in the Axis kernel. Needed to support most fast CF cards, will also boost speed on SATA.&lt;br /&gt;
&lt;br /&gt;
=== Debayer Algorithmn ===&lt;br /&gt;
* Higher image quality debayer algorithmn FPGA implementation -&amp;gt; [http://scien.stanford.edu/class/psych221/projects/99/tingchen/algodep/vargra.html VNG]&lt;br /&gt;
&lt;br /&gt;
==Hardware==&lt;br /&gt;
What will the next elphel camera most likely entitled '''Elphel 373''' be like?&lt;br /&gt;
&lt;br /&gt;
===Power Supply===&lt;br /&gt;
* optional 5-36V supply over additional jack [http://focus.ti.com/docs/prod/folders/print/tps5430.html DC/DC] [http://focus.ti.com/docs/prod/folders/print/tps23750.html POE] [http://www.rlocman.ru/review/article.html?di=52247 TI Article]&lt;br /&gt;
&lt;br /&gt;
===Sensor===&lt;br /&gt;
* Vignetting hardware correction&lt;br /&gt;
* Lens distortion hardware correction&lt;br /&gt;
* Fixed pattern noise (FPN) correction&lt;br /&gt;
* Flash mode for rolling shutter&lt;br /&gt;
* Make image thumbnails (binning 8x8 from DCT[0,0] data)&lt;br /&gt;
'''Position adjustment'''&lt;br /&gt;
*initial focus/pan/tilt sensor adjustment&lt;br /&gt;
*Square form for easy change of orientation&lt;br /&gt;
&lt;br /&gt;
'''Interface'''&lt;br /&gt;
*group VLDS pairs in flexible cable from sensor to board&lt;br /&gt;
*[[CCD table|CCD sensors]]&lt;br /&gt;
&lt;br /&gt;
'''Sony IMX021'''&lt;br /&gt;
*designed for DSLRs (possibly the sensor used in Nikon D300 / D90)&lt;br /&gt;
*12.4 MPix&lt;br /&gt;
*5.5 µm pixel&lt;br /&gt;
*0.18 µm technology&lt;br /&gt;
*28mm x 22.2 mm APS-C sized 1.8&amp;quot; image area (28.4 mm diagonal)&lt;br /&gt;
*12 bit column ADC&lt;br /&gt;
*10.4 fps in 12.4 MPix mode&lt;br /&gt;
*on-chip noise reduction&lt;br /&gt;
*parallel A/D for every pixel coloumn&lt;br /&gt;
&lt;br /&gt;
===CPU===&lt;br /&gt;
*USB2.0 Support&lt;br /&gt;
&lt;br /&gt;
===External data sensors support===&lt;br /&gt;
*'''DONE''' GPS&lt;br /&gt;
*'''DONE''' Compass&lt;br /&gt;
*Dry contact (simply switch event)&lt;br /&gt;
*'''DONE''' RFID&lt;br /&gt;
*Proximity&lt;br /&gt;
*Environment sensors: Temperature/Humidity/Pressure/Illuminance/Loudness/.. [http://www.catnip.co.uk/wx Open Weather], [http://www.sciproj.com/FeaturedVendorProduct.aspx?uid=1208227 EL-USB-RT], [http://www.raphnet.net/electronique/usbtenki/index_en.php USBTenki], [http://www.sparkfun.com/commerce/product_info.php?products_id=8311 USB Weather Board], [http://www.farnell.com/datasheets/129494.pdf CY3271-EXP1 (PSoC Environmental Sensing Kit)]&lt;br /&gt;
*Futaba servo captute interface (for robots)&lt;br /&gt;
&lt;br /&gt;
===External control===&lt;br /&gt;
*USB3.0 Support&lt;br /&gt;
*Futaba servo control interface (for robots) [http://www.parallax.com/Store/Accessories/MotorServoControllers/tabid/160/CategoryID/35/List/0/Level/a/ProductID/346/Default.aspx?SortField=ProductName%2CProductName PSC] [http://www.endurance-rc.com/pantilt.html Pan&amp;amp;Tilt] [http://www.openservo.com/ OpenServo] [http://www.embeddedrelated.com/usenet/embedded/show/46581-1.php Verilog solution] [http://www.sparkfun.com/commerce/product_info.php?products_id=8897 Polulu]&lt;br /&gt;
*Relay control&lt;br /&gt;
*CAN support [http://www.qprotos.com/quickcan.htm quickcan] [http://www.gridconnect.com/usbcanin.html USB CAN Adapter]&lt;br /&gt;
*DMX512 support [http://en.wikipedia.org/wiki/DMX-512 DMX512]&lt;br /&gt;
*Secure Digital support [http://www.delkin.com/products/adapters/sd-to-cf/sd-to-cf.html CF-SD]&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=User:Dimitrios&amp;diff=11000</id>
		<title>User:Dimitrios</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=User:Dimitrios&amp;diff=11000"/>
				<updated>2011-12-18T02:25:21Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Created page with &amp;quot;Some notes that could be useful:  =Recording and live preview=  Is there a way to record and, at the same time, watch a reduced resolution version in a cheap tablet or portable P...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some notes that could be useful:&lt;br /&gt;
&lt;br /&gt;
=Recording and live preview=&lt;br /&gt;
&lt;br /&gt;
Is there a way to record and, at the same time, watch a reduced resolution version in a cheap tablet or portable PC / notebook?&lt;br /&gt;
&lt;br /&gt;
'''epeg''' is a super-fast library for resizing jpegs. It offers an improvement of at least an order of magnitude over other known libraries like ImageMagick. I just compiled a command line version and these are the results:&lt;br /&gt;
&lt;br /&gt;
 $ time ./resize test.jpeg test.jpg&lt;br /&gt;
 &lt;br /&gt;
 real    0m0.063s&lt;br /&gt;
 user    0m0.060s&lt;br /&gt;
 sys     0m0.000s&lt;br /&gt;
 &lt;br /&gt;
 $ time convert -resize 426x640 test.jpeg test.jpg&lt;br /&gt;
 &lt;br /&gt;
 real    0m1.158s&lt;br /&gt;
 user    0m1.048s&lt;br /&gt;
 sys     0m0.052s&lt;br /&gt;
&lt;br /&gt;
The improvement in the above case 18 times faster.&lt;br /&gt;
'''resize''' is a little C program crafted for resizing a 2592x3888 image to a 426x640 one using the epeg library. Convert is ImageMagick's convert utility. It took resize '''63 msec''' against '''1158 msec''' for ImageMagick.&lt;br /&gt;
&lt;br /&gt;
If this functionality is included in the camera it could do jpeg resize in-memory on-the-fly and spare even more by avoiding the read/write to disk that is involved in the above test.&lt;br /&gt;
&lt;br /&gt;
'''epeg''' was a stand-alone utility that is now included in Enlightenment. The [http://maemo.gitorious.org/maemo-af/epeg Maemo] sources for epeg compile without a change in Kubuntu. There is also a [http://github.com/rsky/php-epeg PHP extension] for epeg.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''epeg''' does not decode the JPEG, it only decodes the DCT coefficients needed to reconstruct an image of the size desired.&lt;br /&gt;
&lt;br /&gt;
From the README:&lt;br /&gt;
&lt;br /&gt;
 What is Epeg?&lt;br /&gt;
 &lt;br /&gt;
 An IMMENSELY FAST JPEG thumbnailer library API.&lt;br /&gt;
 &lt;br /&gt;
 Why write this? It's a convenience library API to using libjpeg to load JPEG&lt;br /&gt;
 images destined to be turned into thumbnails of the original, saving&lt;br /&gt;
 information with these thumbnails, retrieving it and managing to load the image&lt;br /&gt;
 ready for scaling with the minimum of fuss and CPU overhead. &lt;br /&gt;
 &lt;br /&gt;
 This means it's insanely fast at loading large JPEG images and scaling them&lt;br /&gt;
 down to tiny thumbnails. It's speedup will be proportional to the size&lt;br /&gt;
 difference between the source image and the output thumbnail size as a&lt;br /&gt;
 count of their pixels.&lt;br /&gt;
 &lt;br /&gt;
 It makes use of libjpeg features of being able to load an image by only&lt;br /&gt;
 decoding the DCT coefficients needed to reconstruct an image of the size&lt;br /&gt;
 desired. This gives a massive speedup. If you do not try and access the pixels&lt;br /&gt;
 in a format other than YUV (or GRAY8 if the source is grascale) then it also&lt;br /&gt;
 avoids colorspace conversions as well.&lt;br /&gt;
 &lt;br /&gt;
In the '''libepeg''' library, there is a function epeg_memory_open() that reads a JPEG image from memory instead of a file. Then the resize can be applied and the result can be sent out instead of the original JPEG.&lt;br /&gt;
&lt;br /&gt;
The C program that does the resize is this:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stddef.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;Epeg.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 int&lt;br /&gt;
 main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   Epeg_Image *im;&lt;br /&gt;
    &lt;br /&gt;
   if (argc != 3)&lt;br /&gt;
   {&lt;br /&gt;
      printf(&amp;quot;Usage: %s input.jpg thumb.jpg\n&amp;quot;, argv[0]);&lt;br /&gt;
      exit(0);&lt;br /&gt;
   }&lt;br /&gt;
   im = epeg_file_open(argv[1]);&lt;br /&gt;
   if (!im)&lt;br /&gt;
   {&lt;br /&gt;
      printf(&amp;quot;Cannot open %s\n&amp;quot;, argv[1]);&lt;br /&gt;
      exit(-1);&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   epeg_decode_size_set           (im, 426, 640);&lt;br /&gt;
   epeg_quality_set               (im, 75);&lt;br /&gt;
   epeg_thumbnail_comments_enable (im, 1);&lt;br /&gt;
   epeg_file_output_set           (im, argv[2]);&lt;br /&gt;
   epeg_encode                    (im);&lt;br /&gt;
   epeg_close                     (im);&lt;br /&gt;
   &lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Talk:10369&amp;diff=10999</id>
		<title>Talk:10369</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Talk:10369&amp;diff=10999"/>
				<updated>2011-12-16T19:55:32Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Clicking this:&lt;br /&gt;
&lt;br /&gt;
http://192.168.0.9/i2c.php?width=8&amp;amp;bus=1&amp;amp;adr=0x5102&lt;br /&gt;
&lt;br /&gt;
returns this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;i2c&amp;gt;&lt;br /&gt;
  &amp;lt;width&amp;gt;8&amp;lt;/width&amp;gt;&lt;br /&gt;
  &amp;lt;bus&amp;gt;1&amp;lt;/bus&amp;gt;&lt;br /&gt;
  &amp;lt;slave&amp;gt;0xa2&amp;lt;/slave&amp;gt;&amp;lt;&lt;br /&gt;
  &amp;lt;adr&amp;gt;20738&amp;lt;/adr&amp;gt;&lt;br /&gt;
  &amp;lt;hex_adr&amp;gt;0x5102&amp;lt;/hex_adr&amp;gt;&lt;br /&gt;
  &amp;lt;data&amp;gt;68&amp;lt;/data&amp;gt;&lt;br /&gt;
  &amp;lt;rdata&amp;gt;68&amp;lt;/rdata&amp;gt;&lt;br /&gt;
  &amp;lt;hex_data&amp;gt;0x44&amp;lt;/hex_data&amp;gt;&lt;br /&gt;
 &amp;lt;/i2c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, seconds cannot be '68', can they? It looks like the hex_data value is the actual seconds but presented in decimal not hex. 'data' and 'rdata' jump up when hex_data changes decade.&lt;br /&gt;
----&lt;br /&gt;
When clicking this link:&lt;br /&gt;
&lt;br /&gt;
http://192.168.0.9/i2c.php?cmd=readCMOS&lt;br /&gt;
&lt;br /&gt;
I get:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;i2c&amp;gt;&lt;br /&gt;
  &amp;lt;error&amp;gt;&amp;quot;Address (adr or raw) or width are not specified or are not positive.&amp;quot;&amp;lt;/error&amp;gt;&lt;br /&gt;
  &amp;lt;usage&amp;gt;&amp;quot;open URL: i2c.php?width=www&amp;amp;bus=bbb&amp;amp;adr=aaa&amp;amp;data=ddd&amp;quot;&amp;lt;/usage&amp;gt;&lt;br /&gt;
&amp;lt;/i2c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Talk:10369&amp;diff=10998</id>
		<title>Talk:10369</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Talk:10369&amp;diff=10998"/>
				<updated>2011-12-16T19:45:47Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When clicking this link:&lt;br /&gt;
&lt;br /&gt;
http://192.168.0.9/i2c.php?cmd=readCMOS&lt;br /&gt;
&lt;br /&gt;
I get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i2c&amp;gt;&lt;br /&gt;
  &amp;lt;error&amp;gt;&amp;quot;Address (adr or raw) or width are not specified or are not positive.&amp;quot;&amp;lt;/error&amp;gt;&lt;br /&gt;
  &amp;lt;usage&amp;gt;&amp;quot;open URL: i2c.php?width=www&amp;amp;bus=bbb&amp;amp;adr=aaa&amp;amp;data=ddd&amp;quot;&amp;lt;/usage&amp;gt;&lt;br /&gt;
&amp;lt;/i2c&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	<entry>
		<id>https://wiki.elphel.com/index.php?title=Talk:10369&amp;diff=10997</id>
		<title>Talk:10369</title>
		<link rel="alternate" type="text/html" href="https://wiki.elphel.com/index.php?title=Talk:10369&amp;diff=10997"/>
				<updated>2011-12-16T19:42:51Z</updated>
		
		<summary type="html">&lt;p&gt;Dimitrios: Created page with &amp;quot;When clicking this link I get:  &amp;lt;i2c&amp;gt;   &amp;lt;error&amp;gt;&amp;quot;Address (adr or raw) or width are not specified or are not positive.&amp;quot;&amp;lt;/error&amp;gt;   &amp;lt;usage&amp;gt;&amp;quot;open URL: i2c.php?width=www&amp;amp;bus=bbb&amp;amp;adr=aa...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When clicking this link I get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i2c&amp;gt;&lt;br /&gt;
  &amp;lt;error&amp;gt;&amp;quot;Address (adr or raw) or width are not specified or are not positive.&amp;quot;&amp;lt;/error&amp;gt;&lt;br /&gt;
  &amp;lt;usage&amp;gt;&amp;quot;open URL: i2c.php?width=www&amp;amp;bus=bbb&amp;amp;adr=aaa&amp;amp;data=ddd&amp;quot;&amp;lt;/usage&amp;gt;&lt;br /&gt;
&amp;lt;/i2c&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dimitrios</name></author>	</entry>

	</feed>