558 case 1: // text flag |
569 case 1: // text flag |
559 case 13: // image flag |
570 case 13: // image flag |
560 default: |
571 default: |
561 $atom_structure['data'] = substr($boxdata, 8); |
572 $atom_structure['data'] = substr($boxdata, 8); |
562 if ($atomname == 'covr') { |
573 if ($atomname == 'covr') { |
563 // not a foolproof check, but better than nothing |
574 if (!empty($atom_structure['data'])) { |
564 if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) { |
575 $atom_structure['image_mime'] = 'image/unknown'; // provide default MIME type to ensure array keys exist |
565 $atom_structure['image_mime'] = 'image/jpeg'; |
576 if (function_exists('getimagesizefromstring') && ($getimagesize = getimagesizefromstring($atom_structure['data'])) && !empty($getimagesize['mime'])) { |
566 } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) { |
577 $atom_structure['image_mime'] = $getimagesize['mime']; |
567 $atom_structure['image_mime'] = 'image/png'; |
578 } else { |
568 } elseif (preg_match('#^GIF#', $atom_structure['data'])) { |
579 // if getimagesizefromstring is not available, or fails for some reason, fall back to simple detection of common image formats |
569 $atom_structure['image_mime'] = 'image/gif'; |
580 $ImageFormatSignatures = array( |
|
581 'image/jpeg' => "\xFF\xD8\xFF", |
|
582 'image/png' => "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", |
|
583 'image/gif' => 'GIF', |
|
584 ); |
|
585 foreach ($ImageFormatSignatures as $mime => $image_format_signature) { |
|
586 if (substr($atom_structure['data'], 0, strlen($image_format_signature)) == $image_format_signature) { |
|
587 $atom_structure['image_mime'] = $mime; |
|
588 break; |
|
589 } |
|
590 } |
|
591 } |
|
592 $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover'); |
|
593 } else { |
|
594 $this->warning('Unknown empty "covr" image at offset '.$baseoffset); |
570 } |
595 } |
571 $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover'); |
|
572 } |
596 } |
573 break; |
597 break; |
574 |
598 |
575 } |
599 } |
576 break; |
600 break; |
906 $atom_structure['sample_description_table'][$i]['video_encoder_name_len'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 34, 1)); |
932 $atom_structure['sample_description_table'][$i]['video_encoder_name_len'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 34, 1)); |
907 $atom_structure['sample_description_table'][$i]['video_encoder_name'] = substr($atom_structure['sample_description_table'][$i]['data'], 35, $atom_structure['sample_description_table'][$i]['video_encoder_name_len']); |
933 $atom_structure['sample_description_table'][$i]['video_encoder_name'] = substr($atom_structure['sample_description_table'][$i]['data'], 35, $atom_structure['sample_description_table'][$i]['video_encoder_name_len']); |
908 $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 66, 2)); |
934 $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 66, 2)); |
909 $atom_structure['sample_description_table'][$i]['video_color_table_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 68, 2)); |
935 $atom_structure['sample_description_table'][$i]['video_color_table_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 68, 2)); |
910 |
936 |
911 $atom_structure['sample_description_table'][$i]['video_pixel_color_type'] = (($atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color'); |
937 $atom_structure['sample_description_table'][$i]['video_pixel_color_type'] = (((int) $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color'); |
912 $atom_structure['sample_description_table'][$i]['video_pixel_color_name'] = $this->QuicktimeColorNameLookup($atom_structure['sample_description_table'][$i]['video_pixel_color_depth']); |
938 $atom_structure['sample_description_table'][$i]['video_pixel_color_name'] = $this->QuicktimeColorNameLookup($atom_structure['sample_description_table'][$i]['video_pixel_color_depth']); |
913 |
939 |
914 if ($atom_structure['sample_description_table'][$i]['video_pixel_color_name'] != 'invalid') { |
940 if ($atom_structure['sample_description_table'][$i]['video_pixel_color_name'] != 'invalid') { |
915 $info['quicktime']['video']['codec_fourcc'] = $atom_structure['sample_description_table'][$i]['data_format']; |
941 $info['quicktime']['video']['codec_fourcc'] = $atom_structure['sample_description_table'][$i]['data_format']; |
916 $info['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atom_structure['sample_description_table'][$i]['data_format']); |
942 $info['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atom_structure['sample_description_table'][$i]['data_format']); |
917 $info['quicktime']['video']['codec'] = (($atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']); |
943 $info['quicktime']['video']['codec'] = (((int) $atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']); |
918 $info['quicktime']['video']['color_depth'] = $atom_structure['sample_description_table'][$i]['video_pixel_color_depth']; |
944 $info['quicktime']['video']['color_depth'] = $atom_structure['sample_description_table'][$i]['video_pixel_color_depth']; |
919 $info['quicktime']['video']['color_depth_name'] = $atom_structure['sample_description_table'][$i]['video_pixel_color_name']; |
945 $info['quicktime']['video']['color_depth_name'] = $atom_structure['sample_description_table'][$i]['video_pixel_color_name']; |
920 |
946 |
921 $info['video']['codec'] = $info['quicktime']['video']['codec']; |
947 $info['video']['codec'] = $info['quicktime']['video']['codec']; |
922 $info['video']['bits_per_sample'] = $info['quicktime']['video']['color_depth']; |
948 $info['video']['bits_per_sample'] = $info['quicktime']['video']['color_depth']; |
1596 $this->warning('QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.'); |
1622 $this->warning('QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.'); |
1597 } |
1623 } |
1598 break; |
1624 break; |
1599 |
1625 |
1600 case 'NCDT': |
1626 case 'NCDT': |
1601 // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html |
1627 // https://exiftool.org/TagNames/Nikon.html |
1602 // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100 |
1628 // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100 |
1603 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms); |
1629 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms); |
1604 break; |
1630 break; |
1605 case 'NCTH': // Nikon Camera THumbnail image |
1631 case 'NCTH': // Nikon Camera THumbnail image |
1606 case 'NCVW': // Nikon Camera preVieW image |
1632 case 'NCVW': // Nikon Camera preVieW image |
1607 // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html |
1633 case 'NCM1': // Nikon Camera preview iMage 1 |
|
1634 case 'NCM2': // Nikon Camera preview iMage 2 |
|
1635 // https://exiftool.org/TagNames/Nikon.html |
1608 if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) { |
1636 if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) { |
|
1637 $descriptions = array( |
|
1638 'NCTH' => 'Nikon Camera Thumbnail Image', |
|
1639 'NCVW' => 'Nikon Camera Preview Image', |
|
1640 'NCM1' => 'Nikon Camera Preview Image 1', |
|
1641 'NCM2' => 'Nikon Camera Preview Image 2', |
|
1642 ); |
1609 $atom_structure['data'] = $atom_data; |
1643 $atom_structure['data'] = $atom_data; |
1610 $atom_structure['image_mime'] = 'image/jpeg'; |
1644 $atom_structure['image_mime'] = 'image/jpeg'; |
1611 $atom_structure['description'] = (($atomname == 'NCTH') ? 'Nikon Camera Thumbnail Image' : (($atomname == 'NCVW') ? 'Nikon Camera Preview Image' : 'Nikon preview image')); |
1645 $atom_structure['description'] = isset($descriptions[$atomname]) ? $descriptions[$atomname] : 'Nikon preview image'; |
1612 $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_data, 'description'=>$atom_structure['description']); |
1646 $info['quicktime']['comments']['picture'][] = array( |
1613 } |
1647 'image_mime' => $atom_structure['image_mime'], |
1614 break; |
1648 'data' => $atom_data, |
1615 case 'NCTG': // Nikon - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG |
1649 'description' => $atom_structure['description'] |
1616 $atom_structure['data'] = $this->QuicktimeParseNikonNCTG($atom_data); |
1650 ); |
1617 break; |
1651 } |
1618 case 'NCHD': // Nikon:MakerNoteVersion - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html |
1652 break; |
1619 case 'NCDB': // Nikon - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html |
1653 case 'NCTG': // Nikon - https://exiftool.org/TagNames/Nikon.html#NCTG |
1620 case 'CNCV': // Canon:CompressorVersion - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html |
1654 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.nikon-nctg.php', __FILE__, true); |
|
1655 $nikonNCTG = new getid3_tag_nikon_nctg($this->getid3); |
|
1656 |
|
1657 $atom_structure['data'] = $nikonNCTG->parse($atom_data); |
|
1658 break; |
|
1659 case 'NCHD': // Nikon:MakerNoteVersion - https://exiftool.org/TagNames/Nikon.html |
|
1660 $makerNoteVersion = ''; |
|
1661 for ($i = 0, $iMax = strlen($atom_data); $i < $iMax; ++$i) { |
|
1662 if (ord($atom_data[$i]) >= 0x00 && ord($atom_data[$i]) <= 0x1F) { |
|
1663 $makerNoteVersion .= ' '.ord($atom_data[$i]); |
|
1664 } else { |
|
1665 $makerNoteVersion .= $atom_data[$i]; |
|
1666 } |
|
1667 } |
|
1668 $makerNoteVersion = rtrim($makerNoteVersion, "\x00"); |
|
1669 $atom_structure['data'] = array( |
|
1670 'MakerNoteVersion' => $makerNoteVersion |
|
1671 ); |
|
1672 break; |
|
1673 case 'NCDB': // Nikon - https://exiftool.org/TagNames/Nikon.html |
|
1674 case 'CNCV': // Canon:CompressorVersion - https://exiftool.org/TagNames/Canon.html |
1621 $atom_structure['data'] = $atom_data; |
1675 $atom_structure['data'] = $atom_data; |
1622 break; |
1676 break; |
1623 |
1677 |
1624 case "\x00\x00\x00\x00": |
1678 case "\x00\x00\x00\x00": |
1625 // some kind of metacontainer, may contain a big data dump such as: |
1679 // some kind of metacontainer, may contain a big data dump such as: |
1626 // mdta keys \005 mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst \01D \001 \015data \001DE\010Apple 0 \002 (data \001DE\0102011-05-11T17:54:04+0200 2 \003 *data \001DE\010+52.4936+013.3897+040.247/ \01D \004 \015data \001DE\0104.3.1 \005 \018data \001DE\010iPhone 4 |
1680 // mdta keys \005 mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst \01D \001 \015data \001DE\010Apple 0 \002 (data \001DE\0102011-05-11T17:54:04+0200 2 \003 *data \001DE\010+52.4936+013.3897+040.247/ \01D \004 \015data \001DE\0104.3.1 \005 \018data \001DE\010iPhone 4 |
1627 // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt |
1681 // https://xhelmboyx.tripod.com/formats/qti-layout.txt |
1628 |
1682 |
1629 $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); |
1683 $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); |
1630 $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); |
1684 $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); |
1631 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); |
1685 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); |
1632 //$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); |
1686 //$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); |
2602 $QuicktimeStoreFrontCodeLookup[143459] = 'Switzerland'; |
2663 $QuicktimeStoreFrontCodeLookup[143459] = 'Switzerland'; |
2603 $QuicktimeStoreFrontCodeLookup[143444] = 'United Kingdom'; |
2664 $QuicktimeStoreFrontCodeLookup[143444] = 'United Kingdom'; |
2604 $QuicktimeStoreFrontCodeLookup[143441] = 'United States'; |
2665 $QuicktimeStoreFrontCodeLookup[143441] = 'United States'; |
2605 } |
2666 } |
2606 return (isset($QuicktimeStoreFrontCodeLookup[$sfid]) ? $QuicktimeStoreFrontCodeLookup[$sfid] : 'invalid'); |
2667 return (isset($QuicktimeStoreFrontCodeLookup[$sfid]) ? $QuicktimeStoreFrontCodeLookup[$sfid] : 'invalid'); |
2607 } |
|
2608 |
|
2609 /** |
|
2610 * @param string $atom_data |
|
2611 * |
|
2612 * @return array |
|
2613 */ |
|
2614 public function QuicktimeParseNikonNCTG($atom_data) { |
|
2615 // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG |
|
2616 // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100 |
|
2617 // Data is stored as records of: |
|
2618 // * 4 bytes record type |
|
2619 // * 2 bytes size of data field type: |
|
2620 // 0x0001 = flag (size field *= 1-byte) |
|
2621 // 0x0002 = char (size field *= 1-byte) |
|
2622 // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB |
|
2623 // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD |
|
2624 // 0x0005 = float (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together |
|
2625 // 0x0007 = bytes (size field *= 1-byte), values are stored as ?????? |
|
2626 // 0x0008 = ????? (size field *= 2-byte), values are stored as ?????? |
|
2627 // * 2 bytes data size field |
|
2628 // * ? bytes data (string data may be null-padded; datestamp fields are in the format "2011:05:25 20:24:15") |
|
2629 // all integers are stored BigEndian |
|
2630 |
|
2631 $NCTGtagName = array( |
|
2632 0x00000001 => 'Make', |
|
2633 0x00000002 => 'Model', |
|
2634 0x00000003 => 'Software', |
|
2635 0x00000011 => 'CreateDate', |
|
2636 0x00000012 => 'DateTimeOriginal', |
|
2637 0x00000013 => 'FrameCount', |
|
2638 0x00000016 => 'FrameRate', |
|
2639 0x00000022 => 'FrameWidth', |
|
2640 0x00000023 => 'FrameHeight', |
|
2641 0x00000032 => 'AudioChannels', |
|
2642 0x00000033 => 'AudioBitsPerSample', |
|
2643 0x00000034 => 'AudioSampleRate', |
|
2644 0x02000001 => 'MakerNoteVersion', |
|
2645 0x02000005 => 'WhiteBalance', |
|
2646 0x0200000b => 'WhiteBalanceFineTune', |
|
2647 0x0200001e => 'ColorSpace', |
|
2648 0x02000023 => 'PictureControlData', |
|
2649 0x02000024 => 'WorldTime', |
|
2650 0x02000032 => 'UnknownInfo', |
|
2651 0x02000083 => 'LensType', |
|
2652 0x02000084 => 'Lens', |
|
2653 ); |
|
2654 |
|
2655 $offset = 0; |
|
2656 $data = null; |
|
2657 $datalength = strlen($atom_data); |
|
2658 $parsed = array(); |
|
2659 while ($offset < $datalength) { |
|
2660 $record_type = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4)); $offset += 4; |
|
2661 $data_size_type = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2)); $offset += 2; |
|
2662 $data_size = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2)); $offset += 2; |
|
2663 switch ($data_size_type) { |
|
2664 case 0x0001: // 0x0001 = flag (size field *= 1-byte) |
|
2665 $data = getid3_lib::BigEndian2Int(substr($atom_data, $offset, $data_size * 1)); |
|
2666 $offset += ($data_size * 1); |
|
2667 break; |
|
2668 case 0x0002: // 0x0002 = char (size field *= 1-byte) |
|
2669 $data = substr($atom_data, $offset, $data_size * 1); |
|
2670 $offset += ($data_size * 1); |
|
2671 $data = rtrim($data, "\x00"); |
|
2672 break; |
|
2673 case 0x0003: // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB |
|
2674 $data = ''; |
|
2675 for ($i = $data_size - 1; $i >= 0; $i--) { |
|
2676 $data .= substr($atom_data, $offset + ($i * 2), 2); |
|
2677 } |
|
2678 $data = getid3_lib::BigEndian2Int($data); |
|
2679 $offset += ($data_size * 2); |
|
2680 break; |
|
2681 case 0x0004: // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD |
|
2682 $data = ''; |
|
2683 for ($i = $data_size - 1; $i >= 0; $i--) { |
|
2684 $data .= substr($atom_data, $offset + ($i * 4), 4); |
|
2685 } |
|
2686 $data = getid3_lib::BigEndian2Int($data); |
|
2687 $offset += ($data_size * 4); |
|
2688 break; |
|
2689 case 0x0005: // 0x0005 = float (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together |
|
2690 $data = array(); |
|
2691 for ($i = 0; $i < $data_size; $i++) { |
|
2692 $numerator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 0, 4)); |
|
2693 $denomninator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 4, 4)); |
|
2694 if ($denomninator == 0) { |
|
2695 $data[$i] = false; |
|
2696 } else { |
|
2697 $data[$i] = (double) $numerator / $denomninator; |
|
2698 } |
|
2699 } |
|
2700 $offset += (8 * $data_size); |
|
2701 if (count($data) == 1) { |
|
2702 $data = $data[0]; |
|
2703 } |
|
2704 break; |
|
2705 case 0x0007: // 0x0007 = bytes (size field *= 1-byte), values are stored as ?????? |
|
2706 $data = substr($atom_data, $offset, $data_size * 1); |
|
2707 $offset += ($data_size * 1); |
|
2708 break; |
|
2709 case 0x0008: // 0x0008 = ????? (size field *= 2-byte), values are stored as ?????? |
|
2710 $data = substr($atom_data, $offset, $data_size * 2); |
|
2711 $offset += ($data_size * 2); |
|
2712 break; |
|
2713 default: |
|
2714 echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br>'; |
|
2715 break 2; |
|
2716 } |
|
2717 |
|
2718 switch ($record_type) { |
|
2719 case 0x00000011: // CreateDate |
|
2720 case 0x00000012: // DateTimeOriginal |
|
2721 $data = strtotime($data); |
|
2722 break; |
|
2723 case 0x0200001e: // ColorSpace |
|
2724 switch ($data) { |
|
2725 case 1: |
|
2726 $data = 'sRGB'; |
|
2727 break; |
|
2728 case 2: |
|
2729 $data = 'Adobe RGB'; |
|
2730 break; |
|
2731 } |
|
2732 break; |
|
2733 case 0x02000023: // PictureControlData |
|
2734 $PictureControlAdjust = array(0=>'default', 1=>'quick', 2=>'full'); |
|
2735 $FilterEffect = array(0x80=>'off', 0x81=>'yellow', 0x82=>'orange', 0x83=>'red', 0x84=>'green', 0xff=>'n/a'); |
|
2736 $ToningEffect = array(0x80=>'b&w', 0x81=>'sepia', 0x82=>'cyanotype', 0x83=>'red', 0x84=>'yellow', 0x85=>'green', 0x86=>'blue-green', 0x87=>'blue', 0x88=>'purple-blue', 0x89=>'red-purple', 0xff=>'n/a'); |
|
2737 $data = array( |
|
2738 'PictureControlVersion' => substr($data, 0, 4), |
|
2739 'PictureControlName' => rtrim(substr($data, 4, 20), "\x00"), |
|
2740 'PictureControlBase' => rtrim(substr($data, 24, 20), "\x00"), |
|
2741 //'?' => substr($data, 44, 4), |
|
2742 'PictureControlAdjust' => $PictureControlAdjust[ord(substr($data, 48, 1))], |
|
2743 'PictureControlQuickAdjust' => ord(substr($data, 49, 1)), |
|
2744 'Sharpness' => ord(substr($data, 50, 1)), |
|
2745 'Contrast' => ord(substr($data, 51, 1)), |
|
2746 'Brightness' => ord(substr($data, 52, 1)), |
|
2747 'Saturation' => ord(substr($data, 53, 1)), |
|
2748 'HueAdjustment' => ord(substr($data, 54, 1)), |
|
2749 'FilterEffect' => $FilterEffect[ord(substr($data, 55, 1))], |
|
2750 'ToningEffect' => $ToningEffect[ord(substr($data, 56, 1))], |
|
2751 'ToningSaturation' => ord(substr($data, 57, 1)), |
|
2752 ); |
|
2753 break; |
|
2754 case 0x02000024: // WorldTime |
|
2755 // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#WorldTime |
|
2756 // timezone is stored as offset from GMT in minutes |
|
2757 $timezone = getid3_lib::BigEndian2Int(substr($data, 0, 2)); |
|
2758 if ($timezone & 0x8000) { |
|
2759 $timezone = 0 - (0x10000 - $timezone); |
|
2760 } |
|
2761 $timezone /= 60; |
|
2762 |
|
2763 $dst = (bool) getid3_lib::BigEndian2Int(substr($data, 2, 1)); |
|
2764 switch (getid3_lib::BigEndian2Int(substr($data, 3, 1))) { |
|
2765 case 2: |
|
2766 $datedisplayformat = 'D/M/Y'; break; |
|
2767 case 1: |
|
2768 $datedisplayformat = 'M/D/Y'; break; |
|
2769 case 0: |
|
2770 default: |
|
2771 $datedisplayformat = 'Y/M/D'; break; |
|
2772 } |
|
2773 |
|
2774 $data = array('timezone'=>floatval($timezone), 'dst'=>$dst, 'display'=>$datedisplayformat); |
|
2775 break; |
|
2776 case 0x02000083: // LensType |
|
2777 $data = array( |
|
2778 //'_' => $data, |
|
2779 'mf' => (bool) ($data & 0x01), |
|
2780 'd' => (bool) ($data & 0x02), |
|
2781 'g' => (bool) ($data & 0x04), |
|
2782 'vr' => (bool) ($data & 0x08), |
|
2783 ); |
|
2784 break; |
|
2785 } |
|
2786 $tag_name = (isset($NCTGtagName[$record_type]) ? $NCTGtagName[$record_type] : '0x'.str_pad(dechex($record_type), 8, '0', STR_PAD_LEFT)); |
|
2787 $parsed[$tag_name] = $data; |
|
2788 } |
|
2789 return $parsed; |
|
2790 } |
2668 } |
2791 |
2669 |
2792 /** |
2670 /** |
2793 * @param string $keyname |
2671 * @param string $keyname |
2794 * @param string|array $data |
2672 * @param string|array $data |