apps/web/imgsrv/exif.php

Go to the documentation of this file.
00001 #!/usr/local/sbin/php -q
00002 <?php
00077 //TODO: Decide with the start sequence, more data is availble after the sensor is initialized.
00078 // Or leave it to imgsrv (it still needs sensor to start first), just put placeholders
00079 // use http://www.exiv2.org/tags.html  for reference of the Exif fields if you need to add modify
00080 // the data below
00081 
00082 $ExifDeviceTemplateFilename="/dev/exif_template";
00083 $ExifDeviceMetadirFilename= "/dev/exif_metadir";
00084 $ExifDeviceExifFilename=    "/dev/exif_exif";
00085 $ExifDeviceMetaFilename=    "/dev/exif_meta";
00086 
00087 
00090 
00091 $ExifXMLName="/etc/Exif_template.xml";
00092 $init=false;
00093 if ($_SERVER['REQUEST_METHOD']=="GET") {
00094   if ($_GET["init"]!==NULL) {
00095     if ($_GET["init"]) $ExifXMLName=$_GET["init"];
00096     $init=true; // in any case - filename specified or not
00097     $noGPS=     ($_GET["noGPS"]!==NULL);
00098     $nocompass= ($_GET["nocompass"]!==NULL);
00099   }
00100 } else {
00101   foreach ($_SERVER['argv'] as $param) if (substr($param,0,4)=="init") {
00102     $param=substr($param,5);
00103     if (strlen($param)>0) $ExifXMLName=$param;
00104     $init=true; //
00105     break;
00106   }
00107   if ($init) {
00108     $noGPS=     in_array  ('noGPS'    , $_SERVER['argv']);
00109     $nocompass= in_array  ('nocompass', $_SERVER['argv']);
00110   } else {
00111     echo <<<USAGE
00112 
00113 Usage: {$_SERVER['argv'][0]} [init[=filename.xml] [noGPS] [nocompass]]
00114 
00115 
00116 USAGE;
00117     exit (0);
00118   }
00119 }
00120 
00121 define("EXIF_BYTE",      1);
00122 define("EXIF_ASCII",     2);
00123 define("EXIF_SHORT",     3);
00124 define("EXIF_LONG",      4);
00125 define("EXIF_RATIONAL",  5);
00126 define("EXIF_SBYTE",     6);
00127 define("EXIF_UNDEFINED", 7);
00128 define("EXIF_SSHORT",    8); //obsolete?
00129 define("EXIF_SLONG",     9);
00130 define("EXIF_SRATIONAL",10);
00131 
00132 define("EXIF_LSEEK_ENABLE", 2); // rebuild buffer
00133 
00135  if ($init) { // configure Exif data
00136    $exif_head= array (
00137           0xff, 0xe1, // APP1 marker
00138 // offset=2 - start of Exif header
00139           0x00, 0x00, // - length of the Exif header (including this length bytes) - we'll fill it later, we do not know it yet
00140           0x45,0x78,0x69,0x66,0x00,0x00); // Exif header
00141    $Exif_length_offset= 2; // put total length here (big endian, 2 bytes)
00142 
00143    $exif_data= array (// start of TIFF Header, data offsets will match indexes in this array
00144           0x4d,0x4d, // (MM) Big endian, MSB goes first in multi-byte data
00145           0x00,0x2a,  // Tag Mark
00146           0x00,0x00,0x00,0x08); //offset to first IDF (from the beginning of the TIFF header, so 8 is minimum)
00147    $xml_exif = simplexml_load_file($ExifXMLName);
00148    if ($xml_exif->GPSInfo) {
00150      if ($nocompass) {
00151         $tounset=array();
00152         foreach ($xml_exif->GPSInfo->children() as $entry) if (strpos  ($entry->getName()  , "Compass" )!==false) $tounset[]=$entry->getName();
00153         foreach ($tounset as $entry) unset ($xml_exif->GPSInfo->{$entry});
00154      }
00155      if ($noGPS) {
00156        unset($xml_exif->GPSInfo);
00157        unset($xml_exif->Image->GPSTag);
00158      }
00159    }
00160 
00161    $IFD_offset=      count($exif_data);
00162    $SUB_IFD_offset=  12*count($xml_exif->Image->children())+2+4+$IFD_offset;
00163    $GPSInfo_offset=  12*count($xml_exif->Photo->children())+2+4+$SUB_IFD_offset;
00164    $data_offset=     $GPSInfo_offset+(($xml_exif->GPSInfo)?(12*count($xml_exif->GPSInfo->children())+2+4):0); //$GPSInfo is optional
00165    if ($_SERVER['REQUEST_METHOD']) {
00166       echo "<pre>";
00167       printf ("IFD_offset=0x%x\n",$IFD_offset);
00168       printf ("SUB_IFD_offset=0x%x\n",$SUB_IFD_offset);
00169       printf ("GPSInfo_offset=0x%x\n",$GPSInfo_offset);
00170       printf ("data_offset=0x%x\n",$data_offset);
00171    }
00172 
00174    foreach ($xml_exif->Image->children()   as $entry) substitute_value($entry);
00175    foreach ($xml_exif->Photo->children()   as $entry) substitute_value($entry);
00176    if ($xml_exif->GPSInfo) {
00177      foreach ($xml_exif->GPSInfo->children() as $entry) substitute_value($entry);
00178    }
00179    $ifd_pointer=$IFD_offset;
00180    $data_pointer=$data_offset;
00181    start_ifd(count($xml_exif->Image->children()));
00182    foreach ($xml_exif->Image->children() as $entry) process_ifd_entry($entry,0);
00183    finish_ifd();
00184 
00185    $ifd_pointer=$SUB_IFD_offset;
00186    start_ifd(count($xml_exif->Photo->children()));
00187    foreach ($xml_exif->Photo->children() as $entry) process_ifd_entry($entry,1);
00188    finish_ifd();
00189 
00190    if ($xml_exif->GPSInfo) {
00191      $ifd_pointer=$GPSInfo_offset;
00192      start_ifd(count($xml_exif->GPSInfo->children()));
00193      foreach ($xml_exif->GPSInfo->children() as $entry) process_ifd_entry($entry,2);
00194      finish_ifd();
00195    }
00196    $exif_len=count($exif_head)+count($exif_data)-$Exif_length_offset;
00197    $exif_head[$Exif_length_offset]=  ($exif_len >> 8) & 0xff;
00198    $exif_head[$Exif_length_offset+1]= $exif_len       & 0xff;
00199 
00200    $Exif_str="";
00201    for ($i=0; $i<count($exif_head);$i++) $Exif_str.= chr ($exif_head[$i]);
00202    for ($i=0; $i<count($exif_data);$i++) $Exif_str.= chr ($exif_data[$i]);
00203 
00204    $Exif_file  = fopen($ExifDeviceTemplateFilename, 'w');
00205    fwrite ($Exif_file,$Exif_str); 
00206    fclose($Exif_file);
00207 
00209    $dir_sequence=array();
00210    $dir_entries=array();
00211 
00212    foreach ($xml_exif->Image->children()   as $entry) addDirEntry($entry);
00213    foreach ($xml_exif->Photo->children()   as $entry) addDirEntry($entry);
00214    if ($xml_exif->GPSInfo) {
00215      foreach ($xml_exif->GPSInfo->children() as $entry) addDirEntry($entry);
00216    }
00217    array_multisort($dir_sequence,$dir_entries);
00218 
00219    $frame_meta_size=0;
00220    for ($i=0;$i<count($dir_entries);$i++) {
00221      $dir_entries[$i]["src"]=$frame_meta_size;
00222      $frame_meta_size+=$dir_entries[$i]["len"];
00223    }
00224 
00225    $Exif_str="";
00226    foreach ($dir_entries as $entry) $Exif_str.=pack("V*",$entry["ltag"],$entry["len"],$entry["src"],$entry["dst"]);
00227    $Exif_meta_file  = fopen($ExifDeviceMetadirFilename, 'w');
00228    fwrite ($Exif_meta_file,$Exif_str); 
00229    fclose($Exif_meta_file);
00230 
00232 
00233    $Exif_file  = fopen($ExifDeviceTemplateFilename, 'w');
00234    fseek ($Exif_file, EXIF_LSEEK_ENABLE, SEEK_END) ;
00235    fclose($Exif_file);
00236 
00237    if ($_SERVER['REQUEST_METHOD']) {
00238      echo "</pre>";
00239    }
00240    if ($_SERVER['REQUEST_METHOD']) {
00241      echo "<hr/>\n";
00242      test_print_header();
00243      echo "<hr/>\n";
00244      test_print_directory();
00245    }
00246  } //if ($init) // configure Exif data
00249     if ($_GET["description"]!==NULL) {
00250 
00252 
00253       $Exif_file  = fopen($ExifDeviceMetadirFilename, 'r');
00254       fseek ($Exif_file, 0, SEEK_END) ;
00255       fseek ($Exif_file, 0, SEEK_SET) ;
00256       $metadir=fread ($Exif_file, 4096);
00257       fclose($Exif_file);
00258       $dir_entries=array();
00259       for ($i=0; $i<strlen($metadir);$i+=16) {
00260         $dir_entries[]=unpack("V*",substr($metadir,$i,16));
00261       }
00262       foreach ($dir_entries as $entry) 
00263         if ($entry[1]==0x010e) {
00264            $descr=$_GET["description"];
00265            $Exif_file  = fopen($ExifDeviceMetaFilename, 'w+');
00266            fseek ($Exif_file, $entry[3], SEEK_SET) ;
00267            $descr_was=fread ($Exif_file, $entry[2]);
00268            $zero=strpos($descr_was,chr(0));
00269            if ($zero!==false) $descr_was=substr($descr_was,0, $zero);
00270            if ($descr) {
00271              $descr= str_pad($descr, $entry[2], chr(0));
00272              fseek ($Exif_file, $entry[3], SEEK_SET) ;
00273              fwrite($Exif_file, $descr,$entry[2]);
00274            }
00275            fclose($Exif_file);
00276            var_dump($descr_was); echo "<br/>\n";
00277            break;
00278         }
00279     }
00281     if ($_GET["template"]!==NULL) {
00282       $Exif_file  = fopen($ExifDeviceTemplateFilename, 'r');
00283       fseek ($Exif_file, 0, SEEK_END) ;
00284       echo "<hr/>\n";
00285       echo "ftell()=".ftell($Exif_file).", ";
00286       fseek ($Exif_file, 0, SEEK_SET) ;
00287       $template=fread ($Exif_file, 4096);
00288       fclose($Exif_file);
00289       echo "read ".strlen($template)." bytes<br/>\n";
00290       hexdump($template);
00291     }
00293     if ($_GET["metadir"]!==NULL) {
00294       $Exif_file  = fopen($ExifDeviceMetadirFilename, 'r');
00295       fseek ($Exif_file, 0, SEEK_END) ;
00296       echo "<hr/>\n";
00297       echo "ftell()=".ftell($Exif_file).", ";
00298       fseek ($Exif_file, 0, SEEK_SET) ;
00299       $metadir=fread ($Exif_file, 4096);
00300       fclose($Exif_file);
00301       echo "read ".strlen($metadir)." bytes<br/>\n";
00302       $dir_entries=array();
00303       for ($i=0; $i<strlen($metadir);$i+=16) {
00304         $dir_entries[]=unpack("V*",substr($metadir,$i,16));
00305       }
00306       print_directory($dir_entries);
00307     }
00309     if ($_GET["exif"]!==NULL) {
00310       $frame=$_GET["exif"]+0;
00311       echo "<hr/>\n";
00312       printf ("Reading frame %d, ",$frame);
00313       $Exif_file  = fopen($ExifDeviceExifFilename, 'r');
00314       fseek ($Exif_file, 1, SEEK_END) ;
00315       $exif_size=ftell($Exif_file);
00316       if ($frame) fseek ($Exif_file, $frame, SEEK_END) ;
00317       else        fseek ($Exif_file, 0, SEEK_SET) ;
00318       echo "ftell()=".ftell($Exif_file).", ";
00319       $exif_data=fread ($Exif_file, $exif_size);
00320       fclose($Exif_file);
00321       echo "read ".strlen($exif_data)." bytes<br/>\n";
00322       hexdump($exif_data);
00323     }
00324  exit(0);
00326 function hexdump($data) {
00327  global $exif_head, $exif_data;
00328    $l=strlen($data);
00329    printf ("<h2>Exif size=%d bytes</h2>\n",$l);
00330    printf ("<table border=\"0\">\n");
00331     for ($i=0; $i<$l;$i=$i+16) {
00332       printf("<tr><td>%03x</td><td>|</td>\n",$i);
00333       for ($j=$i; $j<$i+16;$j++) {
00334         printf("<td>");
00335         if ($j<$l) {
00336           $d=ord($data[$j]);
00337           printf(" %02x",$d);
00338         } else printf ("   ");
00339         printf("</td>");
00340       }
00341       printf("<td>|</td>");
00342       for ($j=$i; $j< ($i+16);$j++) {
00343         printf("<td>");
00344         if ($j<$l) {
00345           $d=ord($data[$j]);
00346           if ($d<32 or $d>126) printf(".");
00347           else printf ("%c",$d);
00348         } else printf (" ");
00349         printf("</td>");
00350 
00351       }
00352       printf("</tr>\n");
00353     }
00354    printf ("</table>");
00355 }
00356 
00357 function print_directory($dir_entries) {
00358    $meta_size=0;
00359    foreach ($dir_entries as $entry)  if (($entry[3]+$entry[2])>$meta_size) $meta_size=$entry[3]+$entry[2];
00360    printf ("<h2>Frame meta data size=%d bytes</h2>\n",$meta_size);
00361    printf ("<table border=\"1\">\n");
00362    printf ("<tr><td>ltag</td><td>meta offset</td><td>Exif offset</td><td>length</td></tr>\n");
00363    foreach ($dir_entries as $entry) {
00364      printf ("<tr><td>0x%x</td><td>0x%x</td><td>0x%x</td><td>0x%x</td></tr>\n",$entry[1],$entry[3],$entry[4],$entry[2]);
00365    }
00366    printf ("</table>");
00367 }
00368 
00369 function test_print_header() {
00370  global $exif_head, $exif_data;
00371     $lh=count($exif_head);
00372     $ld=count($exif_data);
00373    printf ("<h2>Exif size=%d bytes (head=%d, data=%d)</h2>\n",$lh+$ld,$lh,$ld);
00374    printf ("<table border=\"0\">\n");
00375     for ($i=0; $i<$lh+$ld;$i=$i+16) {
00376       printf("<tr><td>%03x</td><td>|</td>\n",$i);
00377       for ($j=$i; $j<$i+16;$j++) {
00378         printf("<td>");
00379         if ($j<($lh+$ld)) {
00380           $d=($j<$lh)?$exif_head[$j]:$exif_data[$j-$lh];
00381           printf(" %02x",$d);
00382         } else printf ("   ");
00383         printf("</td>");
00384       }
00385       printf("<td>|</td>");
00386       for ($j=$i; $j< ($i+16);$j++) {
00387         printf("<td>");
00388         if ($j<($lh+$ld)) {
00389           $d=($j<$lh)?$exif_head[$j]:$exif_data[$j-$lh];
00390           if ($d<32 or $d>126) printf(".");
00391           else printf ("%c",$d);
00392         } else printf (" ");
00393         printf("</td>");
00394 
00395       }
00396       printf("</tr>\n");
00397     }
00398    printf ("</table>");
00399 }
00400 
00401 function test_print_directory() {
00402   global $dir_entries,$frame_meta_size;
00403    printf ("<h2>Frame meta data size=%d bytes</h2>\n",$frame_meta_size);
00404    printf ("<table border=\"1\">\n");
00405    printf ("<tr><td>ltag</td><td>meta offset</td><td>Exif offset</td><td>length</td></tr>\n");
00406    foreach ($dir_entries as $entry)
00407      printf ("<tr><td>0x%x</td><td>0x%x</td><td>0x%x</td><td>0x%x</td></tr>\n",$entry["ltag"],$entry["src"],$entry["dst"],$entry["len"]);
00408    printf ("</table>");
00409 }
00410 
00411 
00412 
00413 
00414 function start_ifd($count) {
00415  global $exif_data, $ifd_pointer;
00416 // printf("start_ifd: ifd_pointer=0x%04x \n", $ifd_pointer);
00417  $exif_data[$ifd_pointer++]= ($count >> 8) & 0xff;
00418  $exif_data[$ifd_pointer++]= $count & 0xff; // may apply & 0xff in the end to all elements
00419 }
00420 function finish_ifd() { // we do not have additional IFDs
00421  global $exif_data, $ifd_pointer;
00422 // printf("finish_ifd: ifd_pointer=0x%04x \n", $ifd_pointer);
00423    $exif_data[$ifd_pointer++]=0;
00424    $exif_data[$ifd_pointer++]=0;
00425    $exif_data[$ifd_pointer++]=0;
00426    $exif_data[$ifd_pointer++]=0;
00427 }
00428 
00429 
00430 //pass2 - building map from frame meta to Exif template
00431 function addDirEntry($ifd_entry) {
00432   global $dir_sequence,$dir_entries,$exif_head;
00433   $lh=count($exif_head);
00434 
00435   $attrs = $ifd_entry->attributes();
00436 //  var_dump($attrs);
00437 //  if  (array_key_exists  ( "seq"  , $attrs  )) {
00438   if  ($attrs["seq"]) {
00439 //     echo $attrs["seq"].;
00440      $dir_sequence[]=((string) $attrs["seq"])+0;
00441      $len= (integer) $ifd_entry->value_length;
00442      $offs=$lh+(integer) $ifd_entry->value_offest;
00443 //     if (array_key_exists  ( "dlen"  , $attrs  )) 
00444      if  ($attrs["dlen"])  $len=min($len,((string) $attrs["dlen"])+0);
00445      $dir_entries[]=array("ltag"=>((integer)$ifd_entry->ltag),"dst"=>$offs,"len"=>$len);
00446   }
00447 }
00448 
00449 function substitute_value($ifd_entry) {
00450  global $SUB_IFD_offset,$GPSInfo_offset;
00451  $attrs = $ifd_entry->attributes();
00452  switch ($attrs["function"]) {
00453    case "BRAND":
00454       $ifd_entry->addChild ('value',exec("bootblocktool -x BRAND"));
00455      break;
00456    case "MODEL":
00457       $ifd_entry->addChild ('value',exec("bootblocktool -x MODEL").exec("bootblocktool -x REVISION"));
00458      break;
00459    case "SOFTWARE":
00460       $ifd_entry->addChild ('value',exec("ls /usr/html/docs/")); // filter
00461      break;
00462    case "SERIAL":
00463       $s=exec("bootblocktool -x SERNO");
00464       $ifd_entry->addChild ('value',substr($s,0,2).":".substr($s,2,2).":".substr($s,4,2).":".substr($s,6,2).":".substr($s,8,2).":".substr($s,10,2));
00465      break;
00466    case "EXIFTAG":
00467       $ifd_entry->addChild ('value',$SUB_IFD_offset);
00468      break;
00469    case "GPSTAG":
00470       $ifd_entry->addChild ('value',$GPSInfo_offset);
00471     break;
00472  }
00473 }
00474 
00475 
00476 function process_ifd_entry($ifd_entry, $group) {
00477  global $exif_data, $ifd_pointer, $data_pointer,$SUB_IFD_offset,$GPSInfo_offset;
00478  $attrs = $ifd_entry->attributes();
00479  $ifd_tag=   ((string) $attrs["tag"])+0;
00480  $ifd_format=constant("EXIF_".$attrs["format"]);
00481  $ifd_count= $attrs["count"];
00482 // echo "\nifd_tag=$ifd_tag, entry=";print_r($ifd_entry);
00483 // echo "\nifd_count=$ifd_count";
00484 // echo "\nifd_bytes:";var_dump($ifd_bytes);
00485  if (!$ifd_count) {
00486    if($ifd_format==EXIF_ASCII) $ifd_count=strlen($ifd_entry->value)+1;
00487    else $ifd_count=1 ; 
00488  }
00489 //echo "\nifd_count=$ifd_count";
00490  $exif_data[$ifd_pointer++]= ($ifd_tag    >>  8)  & 0xff;
00491  $exif_data[$ifd_pointer++]=  $ifd_tag            & 0xff;
00492  $exif_data[$ifd_pointer++]= ($ifd_format >>  8 ) & 0xff;
00493  $exif_data[$ifd_pointer++]=  $ifd_format         & 0xff;
00494  $exif_data[$ifd_pointer++]= ($ifd_count >> 24)  & 0xff;
00495  $exif_data[$ifd_pointer++]= ($ifd_count >> 16)  & 0xff;
00496  $exif_data[$ifd_pointer++]= ($ifd_count >>  8)   & 0xff;
00497  $exif_data[$ifd_pointer++]=  $ifd_count          & 0xff;
00498 
00499  $ifd_bytes=0;
00500  switch ($ifd_format) {
00501   case EXIF_SHORT:
00502   case EXIF_SSHORT:    $ifd_bytes=2; break;
00503   case EXIF_LONG:
00504   case EXIF_SLONG:     $ifd_bytes=4; break;
00505   case EXIF_RATIONAL:
00506   case EXIF_SRATIONAL: $ifd_bytes=8; break;
00507   default: $ifd_bytes=1; //1,2,6,7
00508  }
00509  $ifd_bytes=$ifd_bytes*$ifd_count;
00510 // now prepare ifd_data - array of bytes
00511  switch ($ifd_format) {
00512   case EXIF_BYTE:
00513   case EXIF_SBYTE:
00514           $ifd_data= array ();
00515           foreach ($ifd_entry->value as $a) $ifd_data[]= $a & 0xff;
00516           break;
00517   case EXIF_ASCII:
00518           $ifd_data= str_split($ifd_entry->value);
00519           foreach($ifd_data as &$d) $d=ord($d);
00520           break;
00521   case EXIF_SHORT:
00522   case EXIF_SSHORT:
00523           $ifd_data= array ();
00524           foreach ($ifd_entry->value as $a) $ifd_data=array_merge($ifd_data,array(($a >> 8) & 0xff, $a & 0xff));
00525           break;
00526   case EXIF_LONG:
00527   case EXIF_SLONG:
00528           $ifd_data= array ();
00529           foreach ($ifd_entry->value as $a) $ifd_data=array_merge($ifd_data,array(($a >> 24) & 0xff,($a >> 16) & 0xff,($a >> 8) & 0xff, $a & 0xff));
00530           break;
00531   case EXIF_RATIONAL:
00532   case EXIF_SRATIONAL:
00533           $nom= array ();
00534           foreach ($ifd_entry->nominator as $a)   $nom[]=  array(($a >> 24) & 0xff,($a >> 16) & 0xff,($a >> 8) & 0xff, $a & 0xff);
00535           $denom= array ();
00536           foreach ($ifd_entry->denominator as $a) $denom[]=array(($a >> 24) & 0xff,($a >> 16) & 0xff,($a >> 8) & 0xff, $a & 0xff);
00537           $ifd_data= array ();
00538 /*
00539 var_dump($nom);
00540 echo "\n";
00541 var_dump($denom);
00542 echo "\n";
00543 //exit(0);
00544 */
00545           for ($i=0;$i<count($nom);$i++) {
00546 //            echo "i=$i\n";
00547   //          echo "\nnom=";var_dump($nom[$i]);
00548     //        echo "\ndenom=";var_dump($denom[$i]);
00549             $ifd_data=array_merge($ifd_data,$nom[$i],$denom[$i]);
00550           }
00551           break; // rational, (un)signed
00552 
00553   case EXIF_UNDEFINED: // undefined
00554        $ifd_data= array_fill(0,$ifd_bytes,0); // will just fill with "0"-s
00555        break; 
00556  }
00557 // echo "\nifd_tag=$ifd_tag, entry=";print_r($i=$ifd_entry->value);
00558 // echo "\nifd_data:";var_dump($ifd_data);
00559 // echo "\nifd_bytes:";var_dump($ifd_bytes);
00560 
00561  $ifd_data=array_pad($ifd_data,$ifd_bytes,0); 
00562 
00563  $ifd_entry->addChild ('value_length',count($ifd_data));
00564 // if  (array_key_exists  ( "ltag"  , $attrs  )) $ltag= ((string) $attrs["ltag"])+0;
00565  if  ($attr["ltag"]) $ltag= ((string) $attrs["ltag"])+0;
00566  else  $ltag= $ifd_tag+($group<<16) ;
00567  $ifd_entry->addChild ("ltag",$ltag );
00568  if (count($ifd_data) <=4) {
00569      $ifd_entry->addChild ('value_offest',$ifd_pointer);
00570      $ifd_data= array_pad($ifd_data,-4,0); // add leading zeroes if <4 bytes
00571      for ($i=0;$i<4;$i++)   $exif_data[$ifd_pointer++]=$ifd_data[$i];
00572  } else { //pointer, not data
00573      $ifd_entry->addChild ('value_offest',$data_pointer);
00574      $exif_data[$ifd_pointer++]= ($data_pointer >> 24)  & 0xff;
00575      $exif_data[$ifd_pointer++]= ($data_pointer >> 16)  & 0xff;
00576      $exif_data[$ifd_pointer++]= ($data_pointer >>  8)  & 0xff;
00577      $exif_data[$ifd_pointer++]=  $data_pointer         & 0xff;
00578      for ($i=0;$i<count($ifd_data);$i++)  {
00579        $exif_data[$data_pointer++]=$ifd_data[$i];
00580      }
00581  }
00582 }
00583 
00584 ?> 

Generated on Fri Nov 28 00:06:23 2008 for elphel by  doxygen 1.5.1