Exemplo n.º 1
0
function parseOlympus($block, &$result, $seek, $globalOffset)
{
    if ($result['Endien'] == "Intel") {
        $intel = 1;
    } else {
        $intel = 0;
    }
    $model = $result['IFD0']['Model'];
    $place = 8;
    //current place
    $offset = 8;
    //Get number of tags (2 bytes)
    $num = bin2hex(substr($block, $place, 2));
    $place += 2;
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
    //loop thru all tags  Each field is 12 bytes
    for ($i = 0; $i < hexdec($num); $i++) {
        //2 byte tag
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $tag = intel2Moto($tag);
        }
        $tag_name = lookup_Olympus_tag($tag);
        //2 byte type
        $type = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $type = intel2Moto($type);
        }
        lookup_type($type, $size);
        //4 byte count of number of data units
        $count = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $count = intel2Moto($count);
        }
        $bytesofdata = $size * hexdec($count);
        //4 byte value of data or pointer to data
        $value = substr($block, $place, 4);
        $place += 4;
        if ($bytesofdata <= 4) {
            $data = $value;
        } else {
            $value = bin2hex($value);
            if ($intel == 1) {
                $value = intel2Moto($value);
            }
            $v = fseek($seek, $globalOffset + hexdec($value));
            //offsets are from TIFF header which is 12 bytes from the start of the file
            if ($v == 0) {
                $data = fread($seek, $bytesofdata);
            } else {
                if ($v == -1) {
                    $result['Errors'] = $result['Errors']++;
                }
            }
        }
        $formated_data = formatOlympusData($type, $tag, $intel, $data);
        if ($result['VerboseOutput'] == 1) {
            $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            if ($type == "URATIONAL" || $type == "SRATIONAL" || $type == "USHORT" || $type == "SSHORT" || $type == "ULONG" || $type == "SLONG" || $type == "FLOAT" || $type == "DOUBLE") {
                $data = bin2hex($data);
                if ($intel == 1) {
                    $data = intel2Moto($data);
                }
            }
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
        } else {
            $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
        }
    }
}
Exemplo n.º 2
0
Arquivo: exif.php Projeto: anqh/core
function read_exif_data_raw($path, $verbose)
{
    if ($path == '' || $path == 'none') {
        return;
    }
    $in = @fopen($path, 'rb');
    // the b is for windows machines to open in binary mode
    $seek = @fopen($path, 'rb');
    // There may be an elegant way to do this with one file handle.
    $globalOffset = 0;
    if (!isset($verbose)) {
        $verbose = 0;
    }
    $result['VerboseOutput'] = $verbose;
    $result['Errors'] = 0;
    if (!$in || !$seek) {
        // if the path was invalid, this error will catch it
        $result['Errors'] = 1;
        $result['Error'][$result['Errors']] = gettext('The file could not be found.');
        return $result;
    }
    $GLOBALS['exiferFileSize'] = filesize($path);
    // First 2 bytes of JPEG are 0xFFD8
    $data = bin2hex(fread($in, 2));
    if ($data == 'ffd8') {
        $result['ValidJpeg'] = 1;
    } else {
        $result['ValidJpeg'] = 0;
        fseek($in, 0);
    }
    $result['ValidIPTCData'] = 0;
    $result['ValidJFIFData'] = 0;
    $result['ValidEXIFData'] = 0;
    $result['ValidAPP2Data'] = 0;
    $result['ValidCOMData'] = 0;
    if ($result['ValidJpeg'] == 1) {
        // Next 2 bytes are MARKER tag (0xFFE#)
        $data = bin2hex(fread($in, 2));
        $size = bin2hex(fread($in, 2));
        // LOOP THROUGH MARKERS TILL YOU GET TO FFE1  (exif marker)
        $abortCount = 0;
        while (!feof($in) && $data != 'ffe1' && $data != 'ffc0' && $data != 'ffd9' && ++$abortCount < 200) {
            if ($data == 'ffe0') {
                // JFIF Marker
                $result['ValidJFIFData'] = 1;
                $result['JFIF']['Size'] = hexdec($size);
                if (hexdec($size) - 2 > 0) {
                    $data = fread($in, hexdec($size) - 2);
                    $result['JFIF']['Data'] = $data;
                }
                $result['JFIF']['Identifier'] = substr($data, 0, 5);
                $result['JFIF']['ExtensionCode'] = bin2hex(substr($data, 6, 1));
                $globalOffset += hexdec($size) + 2;
            } else {
                if ($data == 'ffed') {
                    // IPTC Marker
                    $result['ValidIPTCData'] = 1;
                    $result['IPTC']['Size'] = hexdec($size);
                    if (hexdec($size) - 2 > 0) {
                        $data = fread($in, hexdec($size) - 2);
                        $result['IPTC']['Data'] = $data;
                    }
                    $globalOffset += hexdec($size) + 2;
                } else {
                    if ($data == 'ffe2') {
                        // EXIF extension Marker
                        $result['ValidAPP2Data'] = 1;
                        $result['APP2']['Size'] = hexdec($size);
                        if (hexdec($size) - 2 > 0) {
                            $data = fread($in, hexdec($size) - 2);
                            $result['APP2']['Data'] = $data;
                        }
                        $globalOffset += hexdec($size) + 2;
                    } else {
                        if ($data == 'fffe') {
                            // COM extension Marker
                            $result['ValidCOMData'] = 1;
                            $result['COM']['Size'] = hexdec($size);
                            if (hexdec($size) - 2 > 0) {
                                $data = fread($in, hexdec($size) - 2);
                                $result['COM']['Data'] = $data;
                            }
                            $globalOffset += hexdec($size) + 2;
                        } else {
                            if ($data == 'ffe1') {
                                $result['ValidEXIFData'] = 1;
                            }
                        }
                    }
                }
            }
            $data = bin2hex(fread($in, 2));
            $size = bin2hex(fread($in, 2));
        }
        // END MARKER LOOP
        if ($data == 'ffe1') {
            $result['ValidEXIFData'] = 1;
        } else {
            fclose($in);
            fclose($seek);
            return $result;
        }
        // Size of APP1
        $result['APP1Size'] = hexdec($size);
        // Start of APP1 block starts with 'Exif' header (6 bytes)
        $header = fread($in, 6);
    }
    // END IF ValidJpeg
    // Then theres a TIFF header with 2 bytes of endieness (II or MM)
    $header = fread($in, 2);
    if ($header === 'II') {
        $intel = 1;
        $result['Endien'] = 'Intel';
    } else {
        if ($header === 'MM') {
            $intel = 0;
            $result['Endien'] = 'Motorola';
        } else {
            $intel = 1;
            // not sure what the default should be, but this seems reasonable
            $result['Endien'] = 'Unknown';
        }
    }
    // 2 bytes of 0x002a
    $tag = bin2hex(fread($in, 2));
    // Then 4 bytes of offset to IFD0 (usually 8 which includes all 8 bytes of TIFF header)
    $offset = bin2hex(fread($in, 4));
    if ($intel == 1) {
        $offset = intel2Moto($offset);
    }
    // Check for extremely large values here
    if (hexdec($offset) > 100000) {
        $result['ValidEXIFData'] = 0;
        fclose($in);
        fclose($seek);
        return $result;
    }
    if (hexdec($offset) > 8) {
        $unknown = fread($in, hexdec($offset) - 8);
    }
    // fixed this bug in 1.3
    // add 12 to the offset to account for TIFF header
    if ($result['ValidJpeg'] == 1) {
        $globalOffset += 12;
    }
    //===========================================================
    // Start of IFD0
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['IFD0NumTags'] = $num;
    if ($num < 1000) {
        // 1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, 'IFD0', $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = 'Illegal size for IFD0';
    }
    // store offset to IFD1
    $offset = bin2hex(fread($in, 4));
    if ($intel == 1) {
        $offset = intel2Moto($offset);
    }
    $result['IFD1Offset'] = hexdec($offset);
    // Check for SubIFD
    if (!isset($result['IFD0']['ExifOffset']) || $result['IFD0']['ExifOffset'] == 0) {
        fclose($in);
        fclose($seek);
        return $result;
    }
    // seek to SubIFD (Value of ExifOffset tag) above.
    $ExitOffset = $result['IFD0']['ExifOffset'];
    $v = fseek($in, $globalOffset + $ExitOffset);
    if ($v == -1) {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = gettext('Could not Find SubIFD');
    }
    //===========================================================
    // Start of SubIFD
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['SubIFDNumTags'] = $num;
    if ($num < 1000) {
        // 1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, 'SubIFD', $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = gettext('Illegal size for SubIFD');
    }
    // Add the 35mm equivalent focal length:
    if (isset($result['IFD0']['FocalLengthIn35mmFilm']) && !isset($result['SubIFD']['FocalLengthIn35mmFilm'])) {
        // found in the wrong place
        $result['SubIFD']['FocalLengthIn35mmFilm'] = $result['IFD0']['FocalLengthIn35mmFilm'];
    }
    if (!isset($result['SubIFD']['FocalLengthIn35mmFilm'])) {
        $result['SubIFD']['FocalLengthIn35mmFilm'] = get35mmEquivFocalLength($result);
    }
    // Check for IFD1
    if (!isset($result['IFD1Offset']) || $result['IFD1Offset'] == 0) {
        fclose($in);
        fclose($seek);
        return $result;
    }
    // seek to IFD1
    $v = fseek($in, $globalOffset + $result['IFD1Offset']);
    if ($v == -1) {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = gettext('Could not Find IFD1');
    }
    //===========================================================
    // Start of IFD1
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['IFD1NumTags'] = $num;
    if ($num < 1000) {
        // 1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, 'IFD1', $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = gettext('Illegal size for IFD1');
    }
    // If verbose output is on, include the thumbnail raw data...
    if ($result['VerboseOutput'] == 1 && $result['IFD1']['JpegIFOffset'] > 0 && $result['IFD1']['JpegIFByteCount'] > 0) {
        $v = fseek($seek, $globalOffset + $result['IFD1']['JpegIFOffset']);
        if ($v == 0) {
            $data = fread($seek, $result['IFD1']['JpegIFByteCount']);
        } else {
            if ($v == -1) {
                $result['Errors'] = $result['Errors'] + 1;
            }
        }
        $result['IFD1']['ThumbnailData'] = $data;
    }
    // Check for Interoperability IFD
    if (!isset($result['SubIFD']['ExifInteroperabilityOffset']) || $result['SubIFD']['ExifInteroperabilityOffset'] == 0) {
        fclose($in);
        fclose($seek);
        return $result;
    }
    // Seek to InteroperabilityIFD
    $v = fseek($in, $globalOffset + $result['SubIFD']['ExifInteroperabilityOffset']);
    if ($v == -1) {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = gettext('Could not Find InteroperabilityIFD');
    }
    //===========================================================
    // Start of InteroperabilityIFD
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['InteroperabilityIFDNumTags'] = $num;
    if ($num < 1000) {
        // 1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, 'InteroperabilityIFD', $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = gettext('Illegal size for InteroperabilityIFD');
    }
    fclose($in);
    fclose($seek);
    return $result;
}
Exemplo n.º 3
0
function parseFujifilm($block, &$result)
{
    //if($result['Endien']=="Intel") $intel=1;
    //else $intel=0;
    $intel = 1;
    $model = $result['IFD0']['Model'];
    $place = 8;
    //current place
    $offset = 8;
    $num = bin2hex(substr($block, $place, 4));
    $place += 4;
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $result['SubIFD']['MakerNote']['Offset'] = hexdec($num);
    //Get number of tags (2 bytes)
    $num = bin2hex(substr($block, $place, 2));
    $place += 2;
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
    //loop thru all tags  Each field is 12 bytes
    for ($i = 0; $i < hexdec($num); $i++) {
        //2 byte tag
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $tag = intel2Moto($tag);
        }
        $tag_name = lookup_Fujifilm_tag($tag);
        //2 byte type
        $type = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $type = intel2Moto($type);
        }
        lookup_type($type, $size);
        //4 byte count of number of data units
        $count = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $count = intel2Moto($count);
        }
        $bytesofdata = $size * hexdec($count);
        //4 byte value of data or pointer to data
        $value = substr($block, $place, 4);
        $place += 4;
        if ($bytesofdata <= 4) {
            $data = $value;
        } else {
            $value = bin2hex($value);
            if ($intel == 1) {
                $value = intel2Moto($value);
            }
            $data = substr($block, hexdec($value) - $offset, $bytesofdata * 2);
        }
        $formated_data = formatFujifilmData($type, $tag, $intel, $data);
        if ($result['VerboseOutput'] == 1) {
            $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            if ($type == "URATIONAL" || $type == "SRATIONAL" || $type == "USHORT" || $type == "SSHORT" || $type == "ULONG" || $type == "SLONG" || $type == "FLOAT" || $type == "DOUBLE") {
                $data = bin2hex($data);
                if ($intel == 1) {
                    $data = intel2Moto($data);
                }
            }
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
        } else {
            $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
        }
    }
}
Exemplo n.º 4
0
function parseGPS($block, &$result, $offset, $seek, $globalOffset)
{
    if ($result['Endien'] == "Intel") {
        $intel = 1;
    } else {
        $intel = 0;
    }
    $v = fseek($seek, $globalOffset + $offset);
    //offsets are from TIFF header which is 12 bytes from the start of the file
    if ($v == -1) {
        $result['Errors'] = $result['Errors']++;
    }
    $num = bin2hex(fread($seek, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['GPS']['NumTags'] = $num;
    if ($num == 0) {
        return;
    }
    $block = fread($seek, $num * 12);
    $place = 0;
    //loop thru all tags  Each field is 12 bytes
    for ($i = 0; $i < $num; $i++) {
        //2 byte tag
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $tag = intel2Moto($tag);
        }
        $tag_name = lookup_GPS_tag($tag);
        //2 byte datatype
        $type = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $type = intel2Moto($type);
        }
        lookup_type($type, $size);
        //4 byte number of elements
        $count = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $count = intel2Moto($count);
        }
        $bytesofdata = $size * hexdec($count);
        //4 byte value or pointer to value if larger than 4 bytes
        $value = substr($block, $place, 4);
        $place += 4;
        if ($bytesofdata <= 4) {
            $data = $value;
        } else {
            if (strpos('unknown', $tag_name) !== false || $bytesofdata > 1024) {
                $result['Errors'] = $result['Errors']++;
                $data = '';
                $type = 'ASCII';
            } else {
                $value = bin2hex($value);
                if ($intel == 1) {
                    $value = intel2Moto($value);
                }
                $v = fseek($seek, $globalOffset + hexdec($value));
                //offsets are from TIFF header which is 12 bytes from the start of the file
                if ($v == 0) {
                    $data = fread($seek, $bytesofdata);
                } else {
                    $result['Errors'] = $result['Errors']++;
                    $data = '';
                    $type = 'ASCII';
                }
            }
        }
        if ($result['VerboseOutput'] == 1) {
            $result['GPS'][$tag_name] = formatGPSData($type, $tag, $intel, $data);
            $result['GPS'][$tag_name . "_Verbose"]['RawData'] = bin2hex($data);
            $result['GPS'][$tag_name . "_Verbose"]['Type'] = $type;
            $result['GPS'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
        } else {
            $result['GPS'][$tag_name] = formatGPSData($type, $tag, $intel, $data);
        }
    }
}
Exemplo n.º 5
0
Arquivo: canon.php Projeto: anqh/core
function parseCanon($block, &$result, $seek, $globalOffset)
{
    $place = 0;
    //current place
    if ($result['Endien'] == "Intel") {
        $intel = 1;
    } else {
        $intel = 0;
    }
    $model = $result['IFD0']['Model'];
    //Get number of tags (2 bytes)
    $num = bin2hex(substr($block, $place, 2));
    $place += 2;
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
    //loop thru all tags  Each field is 12 bytes
    for ($i = 0; $i < hexdec($num); $i++) {
        //2 byte tag
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $tag = intel2Moto($tag);
        }
        $tag_name = lookup_Canon_tag($tag);
        //2 byte type
        $type = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $type = intel2Moto($type);
        }
        lookup_type($type, $size);
        //4 byte count of number of data units
        $count = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $count = intel2Moto($count);
        }
        $bytesofdata = $size * hexdec($count);
        if ($bytesofdata <= 0) {
            return;
            //if this value is 0 or less then we have read all the tags we can
        }
        //4 byte value of data or pointer to data
        $value = substr($block, $place, 4);
        $place += 4;
        if ($bytesofdata <= 4) {
            $data = $value;
        } else {
            $value = bin2hex($value);
            if ($intel == 1) {
                $value = intel2Moto($value);
            }
            $v = fseek($seek, $globalOffset + hexdec($value));
            //offsets are from TIFF header which is 12 bytes from the start of the file
            if (isset($GLOBALS['exiferFileSize'])) {
                $exiferFileSize = $GLOBALS['exiferFileSize'];
            } else {
                $exiferFileSize = 0;
            }
            if ($v == 0 && $bytesofdata < $exiferFileSize) {
                $data = fread($seek, $bytesofdata);
            } else {
                if ($v == -1) {
                    $result['Errors'] = $result['Errors']++;
                    $data = '';
                } else {
                    $data = '';
                }
            }
        }
        $result['SubIFD']['MakerNote'][$tag_name] = '';
        // insure the index exists
        $formated_data = formatCanonData($type, $tag, $intel, $data, $result, $result['SubIFD']['MakerNote'][$tag_name]);
        if ($result['VerboseOutput'] == 1) {
            //$result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            if ($type == "URATIONAL" || $type == "SRATIONAL" || $type == "USHORT" || $type == "SSHORT" || $type == "ULONG" || $type == "SLONG" || $type == "FLOAT" || $type == "DOUBLE") {
                $data = bin2hex($data);
                if ($intel == 1) {
                    $data = intel2Moto($data);
                }
            }
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
        } else {
            //$result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
        }
    }
}
Exemplo n.º 6
0
function parseNikon($block, &$result)
{
    if ($result['Endien'] == "Intel") {
        $intel = 1;
    } else {
        $intel = 0;
    }
    $model = $result['IFD0']['Model'];
    //these 6 models start with "Nikon".  Other models dont.
    if ($model == "E700" || $model == "E800" || $model == "E900" || $model == "E900S" || $model == "E910" || $model == "E950") {
        $place = 8;
        //current place
        $model = 0;
        //Get number of tags (2 bytes)
        $num = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $num = intel2Moto($num);
        }
        $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
        //loop thru all tags  Each field is 12 bytes
        for ($i = 0; $i < hexdec($num); $i++) {
            //2 byte tag
            $tag = bin2hex(substr($block, $place, 2));
            $place += 2;
            if ($intel == 1) {
                $tag = intel2Moto($tag);
            }
            $tag_name = lookup_Nikon_tag($tag, $model);
            //2 byte type
            $type = bin2hex(substr($block, $place, 2));
            $place += 2;
            if ($intel == 1) {
                $type = intel2Moto($type);
            }
            lookup_type($type, $size);
            //4 byte count of number of data units
            $count = bin2hex(substr($block, $place, 4));
            $place += 4;
            if ($intel == 1) {
                $count = intel2Moto($count);
            }
            $bytesofdata = $size * hexdec($count);
            //4 byte value of data or pointer to data
            $value = substr($block, $place, 4);
            $place += 4;
            //if tag is 0002 then its the ASCII value which we know is at 140 so calc offset
            //THIS HACK ONLY WORKS WITH EARLY NIKON MODELS
            if ($tag == "0002") {
                $offset = hexdec($value) - 140;
            }
            if ($bytesofdata <= 4) {
                $data = $value;
            } else {
                $value = bin2hex($value);
                if ($intel == 1) {
                    $value = intel2Moto($value);
                }
                $data = substr($block, hexdec($value) - $offset, $bytesofdata * 2);
            }
            $formated_data = formatNikonData($type, $tag, $intel, $model, $data);
            if ($result['VerboseOutput'] == 1) {
                $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
                $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
                $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
                $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
            } else {
                $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            }
        }
    } else {
        $place = 0;
        //current place
        $model = 1;
        $nikon = substr($block, $place, 8);
        $place += 8;
        $endien = substr($block, $place, 4);
        $place += 4;
        //2 bytes of 0x002a
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        //Then 4 bytes of offset to IFD0 (usually 8 which includes all 8 bytes of TIFF header)
        $offset = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $offset = intel2Moto($offset);
        }
        if (hexdec($offset) > 8) {
            $place += $offset - 8;
        }
        //Get number of tags (2 bytes)
        $num = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $num = intel2Moto($num);
        }
        //loop thru all tags  Each field is 12 bytes
        for ($i = 0; $i < hexdec($num); $i++) {
            //2 byte tag
            $tag = bin2hex(substr($block, $place, 2));
            $place += 2;
            if ($intel == 1) {
                $tag = intel2Moto($tag);
            }
            $tag_name = lookup_Nikon_tag($tag, $model);
            //2 byte type
            $type = bin2hex(substr($block, $place, 2));
            $place += 2;
            if ($intel == 1) {
                $type = intel2Moto($type);
            }
            lookup_type($type, $size);
            //4 byte count of number of data units
            $count = bin2hex(substr($block, $place, 4));
            $place += 4;
            if ($intel == 1) {
                $count = intel2Moto($count);
            }
            $bytesofdata = $size * hexdec($count);
            //4 byte value of data or pointer to data
            $value = substr($block, $place, 4);
            $place += 4;
            if ($bytesofdata <= 4) {
                $data = $value;
            } else {
                $value = bin2hex($value);
                if ($intel == 1) {
                    $value = intel2Moto($value);
                }
                $data = substr($block, hexdec($value) + hexdec($offset) + 2, $bytesofdata);
            }
            $formated_data = formatNikonData($type, $tag, $intel, $model, $data);
            if ($result['VerboseOutput'] == 1) {
                $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
                if ($type == "URATIONAL" || $type == "SRATIONAL" || $type == "USHORT" || $type == "SSHORT" || $type == "ULONG" || $type == "SLONG" || $type == "FLOAT" || $type == "DOUBLE") {
                    $data = bin2hex($data);
                    if ($intel == 1) {
                        $data = intel2Moto($data);
                    }
                }
                $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
                $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
                $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
            } else {
                $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            }
        }
    }
}
Exemplo n.º 7
0
function parseOlympus($block, &$result, $seek, $globalOffset)
{
    if ($result['Endien'] == "Intel") {
        $intel = 1;
    } else {
        $intel = 0;
    }
    $model = $result['IFD0']['Model'];
    // New header for new DSLRs - Check for it because the
    // number of bytes that count the IFD fields differ in each case.
    // Fixed by Zenphoto 2/24/08
    $new = false;
    if (substr($block, 0, 8) == "OLYMPUS") {
        $new = true;
    } else {
        if (substr($block, 0, 7) == "OLYMP" || substr($block, 0, 7) == "OLYMP") {
            $new = false;
        } else {
            // Header does not match known Olympus headers.
            // This is not a valid OLYMPUS Makernote.
            return false;
        }
    }
    // Offset of IFD entry after Olympus header.
    $place = 8;
    $offset = 8;
    // Get number of tags (1 or 2 bytes, depending on New or Old makernote)
    $countfieldbits = $new ? 1 : 2;
    // New makernote repeats 1-byte value twice, so increment $place by 2 in either case.
    $num = bin2hex(substr($block, $place, $countfieldbits));
    $place += 2;
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $ntags = hexdec($num);
    $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = $ntags;
    //loop thru all tags  Each field is 12 bytes
    for ($i = 0; $i < $ntags; $i++) {
        //2 byte tag
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $tag = intel2Moto($tag);
        }
        $tag_name = lookup_Olympus_tag($tag);
        //2 byte type
        $type = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $type = intel2Moto($type);
        }
        lookup_type($type, $size);
        //4 byte count of number of data units
        $count = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $count = intel2Moto($count);
        }
        $bytesofdata = $size * hexdec($count);
        //4 byte value of data or pointer to data
        $value = substr($block, $place, 4);
        $place += 4;
        if ($bytesofdata <= 4) {
            $data = $value;
        } else {
            $value = bin2hex($value);
            if ($intel == 1) {
                $value = intel2Moto($value);
            }
            $v = fseek($seek, $globalOffset + hexdec($value));
            //offsets are from TIFF header which is 12 bytes from the start of the file
            if (isset($GLOBALS['exiferFileSize']) && $v == 0 && $bytesofdata < $GLOBALS['exiferFileSize']) {
                $data = fread($seek, $bytesofdata);
            } else {
                $result['Errors'] = $result['Errors']++;
                $data = '';
            }
        }
        $formated_data = formatOlympusData($type, $tag, $intel, $data);
        if ($result['VerboseOutput'] == 1) {
            $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            if ($type == "URATIONAL" || $type == "SRATIONAL" || $type == "USHORT" || $type == "SSHORT" || $type == "ULONG" || $type == "SLONG" || $type == "FLOAT" || $type == "DOUBLE") {
                $data = bin2hex($data);
                if ($intel == 1) {
                    $data = intel2Moto($data);
                }
            }
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
        } else {
            $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
        }
    }
}
Exemplo n.º 8
0
function read_exif_data_raw($path, $verbose)
{
    if ($path == '' || $path == 'none') {
        return;
    }
    $in = @fopen($path, "rb");
    //the b is for windows machines to open in binary mode
    $seek = @fopen($path, "rb");
    //There may be an elegant way to do this with one file handle.
    $globalOffset = 0;
    if (!isset($verbose)) {
        $verbose = 0;
    }
    $result['VerboseOutput'] = $verbose;
    $result['Errors'] = 0;
    if (!$in || !$seek) {
        //if the path was invalid, this error will catch it
        $result['Errors'] = 1;
        $result['Error'][$result['Errors']] = "The file could not be found.";
        return $result;
    }
    //First 2 bytes of JPEG are 0xFFD8
    $data = bin2hex(fread($in, 2));
    if ($data == "ffd8") {
        $result['ValidJpeg'] = 1;
    } else {
        $result['ValidJpeg'] = 0;
        fclose($in);
        fclose($seek);
        return $result;
    }
    $result['ValidIPTCData'] = 0;
    $result['ValidJFIFData'] = 0;
    $result['ValidEXIFData'] = 0;
    $result['ValidAPP2Data'] = 0;
    $result['ValidCOMData'] = 0;
    //Next 2 bytes are MARKER tag (0xFFE#)
    $data = bin2hex(fread($in, 2));
    $size = bin2hex(fread($in, 2));
    //LOOP THROUGH MARKERS TILL YOU GET TO FFE1	(exif marker)
    while (!feof($in) && $data != "ffe1" && $data != "ffc0" && $data != "ffd9") {
        if ($data == "ffe0") {
            //JFIF Marker
            $result['ValidJFIFData'] = 1;
            $result['JFIF']['Size'] = hexdec($size);
            if (hexdec($size) - 2 > 0) {
                $data = fread($in, hexdec($size) - 2);
                $result['JFIF']['Data'] = $data;
            }
            $result['JFIF']['Identifier'] = substr($data, 0, 5);
            $result['JFIF']['ExtensionCode'] = bin2hex(substr($data, 6, 1));
            $globalOffset += hexdec($size) + 2;
        } else {
            if ($data == "ffed") {
                //IPTC Marker
                $result['ValidIPTCData'] = 1;
                $result['IPTC']['Size'] = hexdec($size);
                if (hexdec($size) - 2 > 0) {
                    $data = fread($in, hexdec($size) - 2);
                    $result['IPTC']['Data'] = $data;
                }
                $globalOffset += hexdec($size) + 2;
            } else {
                if ($data == "ffe2") {
                    //EXIF extension Marker
                    $result['ValidAPP2Data'] = 1;
                    $result['APP2']['Size'] = hexdec($size);
                    if (hexdec($size) - 2 > 0) {
                        $data = fread($in, hexdec($size) - 2);
                        $result['APP2']['Data'] = $data;
                    }
                    $globalOffset += hexdec($size) + 2;
                } else {
                    if ($data == "fffe") {
                        //COM extension Marker
                        $result['ValidCOMData'] = 1;
                        $result['COM']['Size'] = hexdec($size);
                        if (hexdec($size) - 2 > 0) {
                            $data = fread($in, hexdec($size) - 2);
                            $result['COM']['Data'] = $data;
                        }
                        $globalOffset += hexdec($size) + 2;
                    } else {
                        if ($data == "ffe1") {
                            $result['ValidEXIFData'] = 1;
                        }
                    }
                }
            }
        }
        $data = bin2hex(fread($in, 2));
        $size = bin2hex(fread($in, 2));
    }
    //END MARKER LOOP
    if ($data == "ffe1") {
        $result['ValidEXIFData'] = 1;
    } else {
        fclose($in);
        fclose($seek);
        return $result;
    }
    //Size of APP1
    $result['APP1Size'] = hexdec($size);
    //Start of APP1 block starts with "Exif" header (6 bytes)
    $header = fread($in, 6);
    //Then theres a TIFF header with 2 bytes of endieness (II or MM)
    $header = fread($in, 2);
    if ($header === "II") {
        $intel = 1;
        $result['Endien'] = "Intel";
    } else {
        if ($header === "MM") {
            $intel = 0;
            $result['Endien'] = "Motorola";
        } else {
            $intel = 1;
            //not sure what the default should be, but this seems reasonable
            $result['Endien'] = "Unknown";
        }
    }
    //2 bytes of 0x002a
    $tag = bin2hex(fread($in, 2));
    //Then 4 bytes of offset to IFD0 (usually 8 which includes all 8 bytes of TIFF header)
    $offset = bin2hex(fread($in, 4));
    if ($intel == 1) {
        $offset = intel2Moto($offset);
    }
    // Check for extremely large values here
    if (hexdec($offset) > 100000) {
        $result['ValidEXIFData'] = 0;
        fclose($in);
        fclose($seek);
        return $result;
    }
    if (hexdec($offset) > 8) {
        $unknown = fread($in, hexdec($offset) - 8);
    }
    //fixed this bug in 1.3
    //add 12 to the offset to account for TIFF header
    $globalOffset += 12;
    //===========================================================Start of IFD0
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['IFD0NumTags'] = $num;
    if ($num < 1000) {
        //1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, "IFD0", $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Illegal size for IFD0";
    }
    //store offset to IFD1
    $offset = bin2hex(fread($in, 4));
    if ($intel == 1) {
        $offset = intel2Moto($offset);
    }
    $result['IFD1Offset'] = hexdec($offset);
    //Check for SubIFD
    if (!isset($result['IFD0']['ExifOffset']) || $result['IFD0']['ExifOffset'] == 0) {
        fclose($in);
        fclose($seek);
        return $result;
    }
    //seek to SubIFD (Value of ExifOffset tag) above.
    $ExitOffset = $result['IFD0']['ExifOffset'];
    $v = fseek($in, $globalOffset + $ExitOffset);
    if ($v == -1) {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Couldnt Find SubIFD";
    }
    //===========================================================Start of SubIFD
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['SubIFDNumTags'] = $num;
    if ($num < 1000) {
        //1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, "SubIFD", $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Illegal size for SubIFD";
    }
    //Check for IFD1
    if (!isset($result['IFD1Offset']) || $result['IFD1Offset'] == 0) {
        fclose($in);
        fclose($seek);
        return $result;
    }
    //seek to IFD1
    $v = fseek($in, $globalOffset + $result['IFD1Offset']);
    if ($v == -1) {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Couldnt Find IFD1";
    }
    //===========================================================Start of IFD1
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['IFD1NumTags'] = $num;
    if ($num < 1000) {
        //1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, "IFD1", $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Illegal size for IFD1";
    }
    //if verbose output is on, stick in the thumbnail raw data
    if ($result['VerboseOutput'] == 1 && $result['IFD1']['JpegIFOffset'] > 0 && $result['IFD1']['JpegIFByteCount'] > 0) {
        $v = fseek($seek, $globalOffset + $result['IFD1']['JpegIFOffset']);
        if ($v == 0) {
            $data = fread($seek, $result['IFD1']['JpegIFByteCount']);
        } else {
            if ($v == -1) {
                $result['Errors'] = $result['Errors'] + 1;
            }
        }
        $result['IFD1']["ThumbnailData"] = $data;
    }
    //Check for Interoperability IFD
    if (!isset($result['SubIFD']['ExifInteroperabilityOffset']) || $result['SubIFD']['ExifInteroperabilityOffset'] == 0) {
        fclose($in);
        fclose($seek);
        return $result;
    }
    //seek to InteroperabilityIFD
    $v = fseek($in, $globalOffset + $result['SubIFD']['ExifInteroperabilityOffset']);
    if ($v == -1) {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Couldnt Find InteroperabilityIFD";
    }
    //===========================================================Start of InteroperabilityIFD
    $num = bin2hex(fread($in, 2));
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $num = hexdec($num);
    $result['InteroperabilityIFDNumTags'] = $num;
    if ($num < 1000) {
        //1000 entries is too much and is probably an error.
        for ($i = 0; $i < $num; $i++) {
            read_entry($result, $in, $seek, $intel, "InteroperabilityIFD", $globalOffset);
        }
    } else {
        $result['Errors'] = $result['Errors'] + 1;
        $result['Error'][$result['Errors']] = "Illegal size for InteroperabilityIFD";
    }
    fclose($in);
    fclose($seek);
    return $result;
}
Exemplo n.º 9
0
function parseCanon($block, &$result, $seek, $globalOffset)
{
    global $exiferFileSize;
    //Manuel: this makes canon maker notes work
    $place = 0;
    //current place
    if ($result['Endien'] == "Intel") {
        $intel = 1;
    } else {
        $intel = 0;
    }
    /* Manuel: start determine a possible makernote offset given in the makernote trailer */
    $offsetDelta = 0;
    //currentOffset of MakerNote starting after TIFF header
    $blockLenBytes = strlen(bin2hex($block)) / 2;
    $currentOffset = ftell($seek) - $blockLenBytes - $globalOffset;
    //get potential trailer 8bytes from end of MakerNote
    //first 4 bytes are trailer signature corresponding to TIFF header
    $trailerId = bin2hex(substr($block, -8, 4));
    if ($intel) {
        $tiffHeader = bin2hex('II');
        //Intel
        // 2 bytes of 0x002a
        $tiffHeader .= intel2Moto('002a');
    } else {
        $tiffHeader = bin2hex('MM');
        //Motorola
        $tiffHeader .= '002a';
    }
    if ($trailerId == $tiffHeader) {
        //is it the trailer?
        //next 4 bytes contain offset value
        $mnOffset = bin2hex(substr($block, -4));
        if ($intel == 1) {
            $mnOffset = intel2Moto($mnOffset);
        }
        //calculate the delta
        $offsetDelta = $currentOffset - hexdec($mnOffset);
    }
    /* Manuel: end determine makernote offset */
    $model = $result['IFD0']['Model'];
    //Get number of tags (2 bytes)
    $num = bin2hex(substr($block, $place, 2));
    $place += 2;
    if ($intel == 1) {
        $num = intel2Moto($num);
    }
    $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
    //loop thru all tags  Each field is 12 bytes
    for ($i = 0; $i < hexdec($num); $i++) {
        //2 byte tag
        $tag = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $tag = intel2Moto($tag);
        }
        $tag_name = lookup_Canon_tag($tag);
        //2 byte type
        $type = bin2hex(substr($block, $place, 2));
        $place += 2;
        if ($intel == 1) {
            $type = intel2Moto($type);
        }
        lookup_type($type, $size);
        //4 byte count of number of data units
        $count = bin2hex(substr($block, $place, 4));
        $place += 4;
        if ($intel == 1) {
            $count = intel2Moto($count);
        }
        $bytesofdata = $size * hexdec($count);
        if ($bytesofdata <= 0) {
            return;
            //if this value is 0 or less then we have read all the tags we can
        }
        //4 byte value of data or pointer to data
        $value = substr($block, $place, 4);
        $place += 4;
        if ($bytesofdata <= 4) {
            $data = $value;
        } else {
            $value = bin2hex($value);
            if ($intel == 1) {
                $value = intel2Moto($value);
            }
            //offsets are from TIFF header which is 12 bytes from the start of the file
            //Manuel: also account for $offsetDelta given by the makernote offset in TIFF trailer
            $v = fseek($seek, $globalOffset + hexdec($value) + $offsetDelta);
            if ($v == 0 && $bytesofdata < $exiferFileSize) {
                //Manuel: this makes canon maker notes work
                $data = fread($seek, $bytesofdata);
            } else {
                if ($v == -1) {
                    $result['Errors'] = $result['Errors']++;
                }
            }
        }
        $formated_data = formatCanonData($type, $tag, $intel, $data, $result, $result['SubIFD']['MakerNote'][$tag_name]);
        if ($result['VerboseOutput'] == 1) {
            //$result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
            if ($type == "URATIONAL" || $type == "SRATIONAL" || $type == "USHORT" || $type == "SSHORT" || $type == "ULONG" || $type == "SLONG" || $type == "FLOAT" || $type == "DOUBLE") {
                $data = bin2hex($data);
                if ($intel == 1) {
                    $data = intel2Moto($data);
                }
            }
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['RawData'] = $data;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Type'] = $type;
            $result['SubIFD']['MakerNote'][$tag_name . "_Verbose"]['Bytes'] = $bytesofdata;
        } else {
            //$result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
        }
    }
}