File: /var/www/html/digisferach.sumar.com.py/wp-content/plugins/peepso/classes/exif.php
<?php
class PeepSoExif
{
private $_filename = NULL;
private $_fh = NULL;
private $_msg = NULL;
/*
* http://sylvana.net/jpegcrop/jpegexiforient.c
* 1 2 3 4 5 6 7 8
*
* 888888 888888 88 88 8888888888 88 88 8888888888
* 88 88 88 88 88 88 88 88 88 88 88 88
* 8888 8888 8888 8888 88 8888888888 8888888888 88
* 88 88 88 88
* 88 88 888888 888888
*/
public function __construct($file)
{
if (file_exists($file))
$this->_filename = $file;
}
/**
* Finds the image orientation value
* @return mixed FALSE on error or non-JPG type images, otherwise the image orientation value (see above) 0=normal, 3=rotate 180, 6=rotate 270, 8=rotate 90
*/
public function get_orientation()
{
if (NULL === $this->_filename)
return ($this->_set_error('no file given' . ' (' . var_export($this->_filename, TRUE) . ')'));
$this->_fh = fopen($this->_filename, 'r');
if (FALSE === $this->_fh)
return ($this->_set_error('unable to open file'));
$exif_date = array();
// read file head, check for JPEG SOI + Exif APP1
for ($i = 0; $i < 4; $i++)
$exif_data[$i] = ord($this->_read1());
// check for valid JPEG headers
if (0xFF != $exif_data[0] ||
0xD8 != $exif_data[1] ||
0xFF != $exif_data[2] ||
0xE1 != $exif_data[3])
return ($this->_set_error('JPG header not found'));
// get the marker parameter length count
$length = $this->_read2();
// length includes itself, so must be at least 2
// following Exif data length must be at least 6
if ($length < 8)
return (0);
$length -= 8;
//echo 'length: ', $length, PHP_EOL;
// read Exif head, check for "Exif"
for ($i = 0; $i < 6; $i++)
$exif_data[$i] = ord($this->_read1());
if (0x45 != $exif_data[0] ||
0x78 != $exif_data[1] ||
0x69 != $exif_data[2] ||
0x66 != $exif_data[3] ||
0 != $exif_data[4] ||
0 != $exif_data[5])
return ($this->_set_error('Exif data not found ' . var_export($exif_data, TRUE)));
// read Exif body
for ($i = 0; $i < $length; $i++)
$exif_data[$i] = ord($this->_read1());
if ($length < 12)
return ($this->_set_error('bad IFD entry length')); // length of an IFD entry
// determine byte order
if (0x49 == $exif_data[0] && 0x49 == $exif_data[1])
$is_motorola = 0;
else if (0x4D == $exif_data[0] && 0x4D == $exif_data[1])
$is_motorola = 1;
else
return ($this->_set_error('unable to determine byte order'));
// check Tag mark
if ($is_motorola) {
if (0 != $exif_data[2])
return ($this->_set_error('invalid tag mark'));
if (0x2A != $exif_data[3])
return ($this->_set_error('unrecognized Tag mark: 0x' . dechex($exif_data[3])));
} else {
if (0 != $exif_data[3])
return ($this->_set_error('invalid tag mark'));
if (0x2A != $exif_data[2])
return ($this->_set_error('unrecognized Tag mark: 0x' . dechex($exif_data[3])));
}
//echo 'found proper tag mark', PHP_EOL;
// get first IFD offset (offset to IFD0)
if ($is_motorola) {
if (0 != $exif_data[4])
return ($this->_set_error('invalid IFD offset'));
if (0 != $exif_data[5])
return ($this->_set_error('invalid IFD offset'));
//echo '0x', dechex($exif_data[6]), ' 0x', dechex($exif_data[7]), PHP_EOL;
$offset = $exif_data[6];
$offset <<= 8;
$offset += $exif_data[7];
} else {
if (0 != $exif_data[7])
return ($this->_set_error('invalid IFD offset'));
if (0 != $exif_data[6])
return ($this->_set_error('invalid IFD offset'));
$offset = $exif_data[5];
$offset <<= 8;
$offset += $exif_data[4];
}
// check end of data segment
if ($offset > $length - 2)
return ($this->_set_error('invalid offset'));
//echo 'offset: ', $offset, PHP_EOL;
// get the number of directory entries contained in this IFD
if ($is_motorola) {
$number_of_tags = $exif_data[$offset];
$number_of_tags <<= 8;
$number_of_tags += $exif_data[$offset + 1];
} else {
$number_of_tags = $exif_data[$offset + 1];
$number_of_tags <<= 8;
$number_of_tags += $exif_data[$offset];
}
if (0 === $number_of_tags)
return ($this->_set_error ('invalid number of tags: ' . $number_of_tags));
//echo 'number of tags: ', $number_of_tags, PHP_EOL;
$offset += 2;
// search for Orientation Tag in IFD0
for (;;) {
// check end of data segment
if ($offset > $length - 12)
return ($this->_set_error('exceeded end of data segment'));
// get Tag number
if ($is_motorola) {
$tagnum = $exif_data[$offset];
$tagnum <<= 8;
$tagnum += $exif_data[$offset + 1];
} else {
$tagnum = $exif_data[$offset + 1];
$tagnum <<= 8;
$tagnum += $exif_data[$offset];
}
//echo 'tagnum: ', $tagnum, PHP_EOL;
if (0x0112 == $tagnum)
break; // found Orientation Tag
if (0 == --$number_of_tags)
return ($this->_set_error('number of bytes is zero'));
$offset += 12;
}
// get the Orientation value
if ($is_motorola) {
if (0 != $exif_data[$offset + 8])
return ($this->_set_error('orientation value is 0'));
$set_flag = $exif_data[$offset + 9];
} else {
if (0 != $exif_data[$offset + 9])
return ($this->_set_error('orientagion value is 0'));
$set_flag = $exif_data[$offset + 8];
}
//echo 'set_flag: ', $set_flag, PHP_EOL;
if ($set_flag > 8)
return ($this->_set_error('invalid orientation tag:' . $set_flag));
return ($set_flag);
}
/**
* Reads a single byte from the input file
* @return string The character read or FALSE at EOF
*/
private function _read1()
{
$ch = fread($this->_fh, 1);
if (FALSE === $ch)
return ($this->_set_error('premature EOF'));
return ($ch);
}
/**
* Reads two bytes from the input file
* @return string The characters read or FALSE at EOF
*/
private function _read2()
{
$ch1 = fread($this->_fh, 1);
$ch2 = fread($this->_fh, 1);
if (FALSE === $ch1 || FALSE === $ch2)
return ($this->_set_error('premature eof'));
$a1 = ord($ch1);
$a2 = ord($ch2);
$ret = ($a1 << 8) + $a2;
return ($ret);
}
/**
* Sets the error that the class instance will "remember"
* @param string $msg Error message to remember
* @return boolean Always returns FALSE to indicate an error
*/
private function _set_error($msg)
{
$this->_msg = $msg;
return (FALSE);
}
/**
* Gets the last error message
* @return string Returns the last error message that the instance "remembered" or NULL if no errors were stored
*/
public function get_error()
{
return ($this->_msg);
}
}
// EOF