Blame src/asfvideo.cpp

Packit Service 21b5d1
// ***************************************************************** -*- C++ -*-
Packit Service 21b5d1
/*
Packit Service 21b5d1
 * Copyright (C) 2004-2018 Exiv2 authors
Packit Service 21b5d1
 * This program is part of the Exiv2 distribution.
Packit Service 21b5d1
 *
Packit Service 21b5d1
 * This program is free software; you can redistribute it and/or
Packit Service 21b5d1
 * modify it under the terms of the GNU General Public License
Packit Service 21b5d1
 * as published by the Free Software Foundation; either version 2
Packit Service 21b5d1
 * of the License, or (at your option) any later version.
Packit Service 21b5d1
 *
Packit Service 21b5d1
 * This program is distributed in the hope that it will be useful,
Packit Service 21b5d1
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 21b5d1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 21b5d1
 * GNU General Public License for more details.
Packit Service 21b5d1
 *
Packit Service 21b5d1
 * You should have received a copy of the GNU General Public License
Packit Service 21b5d1
 * along with this program; if not, write to the Free Software
Packit Service 21b5d1
 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
Packit Service 21b5d1
 */
Packit Service 21b5d1
/*
Packit Service 21b5d1
  File:      asfvideo.cpp
Packit Service 21b5d1
  Author(s): Abhinav Badola for GSoC 2012 (AB) <mail.abu.to@gmail.com>
Packit Service 21b5d1
  History:   08-Aug-12, AB: created
Packit Service 21b5d1
  Credits:   See header file
Packit Service 21b5d1
 */
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// included header files
Packit Service 21b5d1
#include "config.h"
Packit Service 21b5d1
Packit Service 21b5d1
#ifdef EXV_ENABLE_VIDEO
Packit Service 21b5d1
#include "error.hpp"
Packit Service 21b5d1
#include "tags.hpp"
Packit Service 21b5d1
#include "tags_int.hpp"
Packit Service 21b5d1
#include "asfvideo.hpp"
Packit Service 21b5d1
#include "futils.hpp"
Packit Service 21b5d1
#include "basicio.hpp"
Packit Service 21b5d1
#include "types.hpp"
Packit Service 21b5d1
#include "riffvideo.hpp"
Packit Service 21b5d1
#include "convert.hpp"
Packit Service 21b5d1
Packit Service 21b5d1
// + standard includes
Packit Service 21b5d1
#include <cmath>
Packit Service 21b5d1
#include <cstring>
Packit Service 21b5d1
#include <ctype.h>
Packit Service 21b5d1
#include <cassert>
Packit Service 21b5d1
Packit Service 21b5d1
// *****************************************************************************
Packit Service 21b5d1
// class member definitions
Packit Service 21b5d1
namespace Exiv2 {
Packit Service 21b5d1
    namespace Internal {
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      Tag Look-up list for ASF Type Video Files
Packit Service 21b5d1
      Associates the GUID of a Tag with its Tag Name(i.e. Human Readable Form)
Packit Service 21b5d1
      Tags have been diferentiated into Various Categories.
Packit Service 21b5d1
      The categories have been listed above the Tag Groups
Packit Service 21b5d1
Packit Service 21b5d1
     */
Packit Service 21b5d1
    extern const TagVocabulary GUIDReferenceTags[] =  {
Packit Service 21b5d1
        /// Top-level ASF object GUIDS
Packit Service 21b5d1
        {   "75B22630-668E-11CF-A6D9-00AA0062CE6C", "Header" },
Packit Service 21b5d1
        {   "75B22636-668E-11CF-A6D9-00AA0062CE6C", "Data" },
Packit Service 21b5d1
        {   "33000890-E5B1-11CF-89F4-00A0C90349CB", "Simple_Index" },
Packit Service 21b5d1
        {   "D6E229D3-35DA-11D1-9034-00A0C90349BE", "Index" },
Packit Service 21b5d1
        {   "FEB103F8-12AD-4C64-840F-2A1D2F7AD48C", "Media_Index" },
Packit Service 21b5d1
        {   "3CB73FD0-0C4A-4803-953D-EDF7B6228F0C", "Timecode_Index" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Header Object GUIDs
Packit Service 21b5d1
        {   "8CABDCA1-A947-11CF-8EE4-00C00C205365", "File_Properties" },
Packit Service 21b5d1
        {   "B7DC0791-A9B7-11CF-8EE6-00C00C205365", "Stream_Properties" },
Packit Service 21b5d1
        {   "5FBF03B5-A92E-11CF-8EE3-00C00C205365", "Header_Extension" },
Packit Service 21b5d1
        {   "86D15240-311D-11D0-A3A4-00A0C90348F6", "Codec_List" },
Packit Service 21b5d1
        {   "1EFB1A30-0B62-11D0-A39B-00A0C90348F6", "Script_Command" },
Packit Service 21b5d1
        {   "F487CD01-A951-11CF-8EE6-00C00C205365", "Marker" },
Packit Service 21b5d1
        {   "D6E229DC-35DA-11D1-9034-00A0C90349BE", "Bitrate_Mutual_Exclusion" },
Packit Service 21b5d1
        {   "75B22635-668E-11CF-A6D9-00AA0062CE6C", "Error_Correction" },
Packit Service 21b5d1
        {   "75B22633-668E-11CF-A6D9-00AA0062CE6C", "Content_Description" },
Packit Service 21b5d1
        {   "D2D0A440-E307-11D2-97F0-00A0C95EA850", "Extended_Content_Description" },
Packit Service 21b5d1
        {   "2211B3FA-BD23-11D2-B4B7-00A0C955FC6E", "Content_Branding" },
Packit Service 21b5d1
        {   "7BF875CE-468D-11D1-8D82-006097C9A2B2", "Stream_Bitrate_Properties" },
Packit Service 21b5d1
        {   "2211B3FB-BD23-11D2-B4B7-00A0C955FC6E", "Content_Encryption" },
Packit Service 21b5d1
        {   "298AE614-2622-4C17-B935-DAE07EE9289C", "Extended_Content_Encryption" },
Packit Service 21b5d1
        {   "2211B3FC-BD23-11D2-B4B7-00A0C955FC6E", "Digital_Signature" },
Packit Service 21b5d1
        {   "1806D474-CADF-4509-A4BA-9AABCB96AAE8", "Padding" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Header Extension Object GUIDs
Packit Service 21b5d1
        {   "14E6A5CB-C672-4332-8399-A96952065B5A", "Extended_Stream_Properties" },
Packit Service 21b5d1
        {   "A08649CF-4775-4670-8A16-6E35357566CD", "Advanced_Mutual_Exclusion" },
Packit Service 21b5d1
        {   "D1465A40-5A79-4338-B71B-E36B8FD6C249", "Group_Mutual_Exclusion" },
Packit Service 21b5d1
        {   "D4FED15B-88D3-454F-81F0-ED5C45999E24", "Stream_Prioritization" },
Packit Service 21b5d1
        {   "A69609E6-517B-11D2-B6AF-00C04FD908E9", "Bandwidth_Sharing" },
Packit Service 21b5d1
        {   "7C4346A9-EFE0-4BFC-B229-393EDE415C85", "Language_List" },
Packit Service 21b5d1
        {   "C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA", "Metadata" },
Packit Service 21b5d1
        {   "44231C94-9498-49D1-A141-1D134E457054", "Metadata_Library" },
Packit Service 21b5d1
        {   "D6E229DF-35DA-11D1-9034-00A0C90349BE", "Index_Parameters" },
Packit Service 21b5d1
        {   "6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7", "Media_Index_Parameters" },
Packit Service 21b5d1
        {   "F55E496D-9797-4B5D-8C8B-604DFE9BFB24", "Timecode_Index_Parameters" },
Packit Service 21b5d1
        {   "26F18B5D-4584-47EC-9F5F-0E651F0452C9", "Compatibility" },
Packit Service 21b5d1
        {   "43058533-6981-49E6-9B74-AD12CB86D58C", "Advanced_Content_Encryption" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Stream Properties Object Stream Type GUIDs
Packit Service 21b5d1
        {   "F8699E40-5B4D-11CF-A8FD-00805F5C442B", "Audio_Media" },
Packit Service 21b5d1
        {   "BC19EFC0-5B4D-11CF-A8FD-00805F5C442B", "Video_Media" },
Packit Service 21b5d1
        {   "59DACFC0-59E6-11D0-A3AC-00A0C90348F6", "Command_Media" },
Packit Service 21b5d1
        {   "B61BE100-5B4E-11CF-A8FD-00805F5C442B", "JFIF_Media" },
Packit Service 21b5d1
        {   "35907DE0-E415-11CF-A917-00805F5C442B", "Degradable_JPEG_Media" },
Packit Service 21b5d1
        {   "91BD222C-F21C-497A-8B6D-5AA86BFC0185", "File_Transfer_Media" },
Packit Service 21b5d1
        {   "3AFB65E2-47EF-40F2-AC2C-70A90D71D343", "Binary_Media" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Web stream Type-Specific Data GUIDs
Packit Service 21b5d1
        {   "776257D4-C627-41CB-8F81-7AC7FF1C40CC", "Web_Stream_Media_Subtype" },
Packit Service 21b5d1
        {   "DA1E6B13-8359-4050-B398-388E965BF00C", "Web_Stream_Format" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Stream Properties Object Error Correction Type GUIDs
Packit Service 21b5d1
        {   "20FB5700-5B55-11CF-A8FD-00805F5C442B", "No_Error_Correction" },
Packit Service 21b5d1
        {   "BFC3CD50-618F-11CF-8BB2-00AA00B4E220", "Audio_Spread" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Header Extension Object GUIDs
Packit Service 21b5d1
        {   "ABD3D211-A9BA-11cf-8EE6-00C00C205365", "Reserved_1" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Advanced Content Encryption Object System ID GUIDs
Packit Service 21b5d1
        {   "7A079BB6-DAA4-4e12-A5CA-91D38DC11A8D", "Content_Encryption_System_Windows_Media_DRM_Network_Devices" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Codec List Object GUIDs
Packit Service 21b5d1
        {   "86D15241-311D-11D0-A3A4-00A0C90348F6", "Reserved_2" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Script Command Object GUIDs
Packit Service 21b5d1
        {   "4B1ACBE3-100B-11D0-A39B-00A0C90348F6", "Reserved_3" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Marker Object GUIDs
Packit Service 21b5d1
        {   "4CFEDB20-75F6-11CF-9C0F-00A0C90349CB", "Reserved_4" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Mutual Exclusion Object Exclusion Type GUIDs
Packit Service 21b5d1
        {   "D6E22A00-35DA-11D1-9034-00A0C90349BE", "Mutex_Language" },
Packit Service 21b5d1
        {   "D6E22A01-35DA-11D1-9034-00A0C90349BE", "Mutex_Bitrate" },
Packit Service 21b5d1
        {   "D6E22A02-35DA-11D1-9034-00A0C90349BE", "Mutex_Unknown" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Bandwidth Sharing Object GUIDs
Packit Service 21b5d1
        {   "AF6060AA-5197-11D2-B6AF-00C04FD908E9", "Bandwidth_Sharing_Exclusive" },
Packit Service 21b5d1
        {   "AF6060AB-5197-11D2-B6AF-00C04FD908E9", "Bandwidth_Sharing_Partial" },
Packit Service 21b5d1
Packit Service 21b5d1
        /// Standard Payload Extension System GUIDs
Packit Service 21b5d1
        {   "399595EC-8667-4E2D-8FDB-98814CE76C1E", "Payload_Extension_System_Timecode" },
Packit Service 21b5d1
        {   "E165EC0E-19ED-45D7-B4A7-25CBD1E28E9B", "Payload_Extension_System_File_Name" },
Packit Service 21b5d1
        {   "D590DC20-07BC-436C-9CF7-F3BBFBF1A4DC", "Payload_Extension_System_Content_Type" },
Packit Service 21b5d1
        {   "1B1EE554-F9EA-4BC8-821A-376B74E4C4B8", "Payload_Extension_System_Pixel_Aspect_Ratio" },
Packit Service 21b5d1
        {   "C6BD9450-867F-4907-83A3-C77921B733AD", "Payload_Extension_System_Sample_Duration" },
Packit Service 21b5d1
        {   "6698B84E-0AFA-4330-AEB2-1C0A98D7A44D", "Payload_Extension_System_Encryption_Sample_ID" },
Packit Service 21b5d1
        {   "00E1AF06-7BEC-11D1-A582-00C04FC29CFB", "Payload_Extension_System_Degradable_JPEG" }
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    //! Audio codec type-specific data in ASF
Packit Service 21b5d1
    extern const TagDetails audioCodec[] =  {
Packit Service 21b5d1
        {    0x161, "Windows Media Audio (7, 8, and 9 Series)" },
Packit Service 21b5d1
        {    0x162, "Windows Media Audio 9 Professional" },
Packit Service 21b5d1
        {    0x163, "Windows Media Audio 9 Lossless" },
Packit Service 21b5d1
        {   0x7A21, "GSM-AMR (CBR, no SID)" },
Packit Service 21b5d1
        {   0x7A22, "GSM-AMR (VBR including SID)" }
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    extern const TagDetails filePropertiesTags[] =  {
Packit Service 21b5d1
        {    7, "Xmp.video.FileLength" },
Packit Service 21b5d1
        {    6, "Xmp.video.CreationDate" },
Packit Service 21b5d1
        {    5, "Xmp.video.DataPackets" },
Packit Service 21b5d1
        {    4, "Xmp.video.Duration" },
Packit Service 21b5d1
        {    3, "Xmp.video.SendDuration" },
Packit Service 21b5d1
        {    2, "Xmp.video.Preroll" },
Packit Service 21b5d1
        {    1, "Xmp.video.MaxBitRate" }
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    extern const TagDetails contentDescriptionTags[] =  {
Packit Service 21b5d1
        {    0, "Xmp.video.Title" },
Packit Service 21b5d1
        {    1, "Xmp.video.Author" },
Packit Service 21b5d1
        {    2, "Xmp.video.Copyright" },
Packit Service 21b5d1
        {    3, "Xmp.video.Description" },
Packit Service 21b5d1
        {    4, "Xmp.video.Rating" }
Packit Service 21b5d1
    };
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Function used to read data from data buffer, reads 16-bit character
Packit Service 21b5d1
          array and stores it in std::string object.
Packit Service 21b5d1
      @param buf Exiv2 data buffer, which stores the information
Packit Service 21b5d1
      @return Returns std::string object .
Packit Service 21b5d1
     */
Packit Service 21b5d1
    std::string toString16(Exiv2::DataBuf& buf)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        std::ostringstream os; char t;
Packit Service 21b5d1
Packit Service 21b5d1
        for(int i = 0; i <= buf.size_; i += 2 ) {
Packit Service 21b5d1
            t = buf.pData_[i] + 16 * buf.pData_[i + 1];
Packit Service 21b5d1
            if(t == 0) {
Packit Service 21b5d1
                if(i)
Packit Service 21b5d1
                    os << '\0';
Packit Service 21b5d1
                break;
Packit Service 21b5d1
            }
Packit Service 21b5d1
            os<< t;
Packit Service 21b5d1
        }
Packit Service 21b5d1
        return os.str();
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Function used to check equality of two Tags (ignores case).
Packit Service 21b5d1
      @param str1 char* Pointer to First Tag
Packit Service 21b5d1
      @param str2 char* Pointer to Second Tag
Packit Service 21b5d1
      @return Returns true if both are equal.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    bool compareTag(const char* str1, const char* str2) {
Packit Service 21b5d1
        if ( strlen(str1) != strlen(str2))
Packit Service 21b5d1
            return false;
Packit Service 21b5d1
Packit Service 21b5d1
        for ( uint64_t i = 0 ; i < strlen(str1); ++i )
Packit Service 21b5d1
            if (tolower(str1[i]) != tolower(str2[i]))
Packit Service 21b5d1
                return false;
Packit Service 21b5d1
Packit Service 21b5d1
        return true;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Function used to convert a decimal number to its Hexadecimal
Packit Service 21b5d1
          equivalent, then parsed into a character
Packit Service 21b5d1
      @param n Integer which is to be parsed as Hexadecimal character
Packit Service 21b5d1
      @return Return a Hexadecimal number, in character
Packit Service 21b5d1
     */
Packit Service 21b5d1
    char returnHEX(int n) {
Packit Service 21b5d1
        if(n >= 0 && n <= 9)
Packit Service 21b5d1
            return (char)(n + 48);
Packit Service 21b5d1
        else
Packit Service 21b5d1
            return (char)(n + 55);
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Function used to calculate GUID, Tags comprises of 16 bytes.
Packit Service 21b5d1
          The Buffer contains the Tag in Binary Form. The information is then
Packit Service 21b5d1
          parsed into a character array GUID.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    void getGUID (byte buf[], char GUID[]) {
Packit Service 21b5d1
        int i;
Packit Service 21b5d1
        for (i = 0; i < 4; ++i) {
Packit Service 21b5d1
            GUID[(3 - i) * 2]      = returnHEX(buf[i] / 0x10);
Packit Service 21b5d1
            GUID[(3 - i) * 2 + 1]  = returnHEX(buf[i] % 0x10);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        for (i = 4; i < 6; ++i) {
Packit Service 21b5d1
            GUID[(9 - i) * 2 + 1]  = returnHEX(buf[i] / 0x10);
Packit Service 21b5d1
            GUID[(9 - i) * 2 + 2]  = returnHEX(buf[i] % 0x10);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        for (i = 6; i < 8; ++i) {
Packit Service 21b5d1
            GUID[(14 - i) * 2]     = returnHEX(buf[i] / 0x10);
Packit Service 21b5d1
            GUID[(14 - i) * 2 + 1] = returnHEX(buf[i] % 0x10);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        for (i = 8; i < 10; ++i) {
Packit Service 21b5d1
            GUID[ i * 2 + 3]       = returnHEX(buf[i] / 0x10);
Packit Service 21b5d1
            GUID[ i * 2 + 4]       = returnHEX(buf[i] % 0x10);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        for (i = 10; i < 16; ++i) {
Packit Service 21b5d1
            GUID[ i * 2 + 4]       = returnHEX(buf[i] / 0x10);
Packit Service 21b5d1
            GUID[ i * 2 + 5]       = returnHEX(buf[i] % 0x10);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        GUID[36] = '\0'; GUID[8] = GUID[13] = GUID[18] = GUID[23] = '-';
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    /*!
Packit Service 21b5d1
      @brief Function used to check if data stored in buf is equivalent to
Packit Service 21b5d1
          ASF Header Tag's GUID.
Packit Service 21b5d1
      @param buf Exiv2 byte buffer
Packit Service 21b5d1
      @return Returns true if the buffer data is equivalent to Header GUID.
Packit Service 21b5d1
     */
Packit Service 21b5d1
    bool isASFType (byte buf[]) {
Packit Service 21b5d1
Packit Service 21b5d1
        if(buf[0]  == 0x30   && buf[1]  == 0x26   && buf[2]  == 0xb2   && buf[3]  == 0x75 &&
Packit Service 21b5d1
           buf[4]  == 0x8e   && buf[5]  == 0x66   && buf[6]  == 0xcf   && buf[7]  == 0x11 &&
Packit Service 21b5d1
           buf[8]  == 0xa6   && buf[9]  == 0xd9   && buf[10] == 0x00   && buf[11] == 0xaa &&
Packit Service 21b5d1
           buf[12] == 0x00   && buf[13] == 0x62   && buf[14] == 0xce   && buf[15] == 0x6c )
Packit Service 21b5d1
                return true;
Packit Service 21b5d1
Packit Service 21b5d1
        return false;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    //! Function used to convert buffer data into 64-bit Integer, information stored in littleEndian format
Packit Service 21b5d1
    uint64_t getUint64_t(Exiv2::DataBuf& buf) {
Packit Service 21b5d1
        uint64_t temp = 0;
Packit Service 21b5d1
Packit Service 21b5d1
        for(int i = 0; i < 8; ++i){
Packit Service 21b5d1
            temp = temp + static_cast<uint64_t>(buf.pData_[i]*(pow(static_cast<float>(256), i)));
Packit Service 21b5d1
        }
Packit Service 21b5d1
        return temp;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
}}                                      // namespace Internal, Exiv2
Packit Service 21b5d1
Packit Service 21b5d1
namespace Exiv2 {
Packit Service 21b5d1
Packit Service 21b5d1
    using namespace Exiv2::Internal;
Packit Service 21b5d1
Packit Service 21b5d1
    AsfVideo::AsfVideo(BasicIo::AutoPtr io)
Packit Service 21b5d1
        : Image(ImageType::asf, mdNone, io)
Packit Service 21b5d1
    {
Packit Service 21b5d1
    } // AsfVideo::AsfVideo
Packit Service 21b5d1
Packit Service 21b5d1
    std::string AsfVideo::mimeType() const
Packit Service 21b5d1
    {
Packit Service 21b5d1
        return "video/asf";
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::writeMetadata()
Packit Service 21b5d1
    {
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::readMetadata()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError());
Packit Service 21b5d1
Packit Service 21b5d1
        // Ensure that this is the correct image type
Packit Service 21b5d1
        if (!isAsfType(*io_, false)) {
Packit Service 21b5d1
            if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
Packit Service 21b5d1
            throw Error(kerNotAnImage, "ASF");
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        IoCloser closer(*io_);
Packit Service 21b5d1
        clearMetadata();
Packit Service 21b5d1
        continueTraversing_ = true;
Packit Service 21b5d1
        io_->seek(0, BasicIo::beg);
Packit Service 21b5d1
        height_ = width_ = 1;
Packit Service 21b5d1
Packit Service 21b5d1
        xmpData_["Xmp.video.FileSize"] = (double)io_->size()/(double)1048576;
Packit Service 21b5d1
        xmpData_["Xmp.video.FileName"] = io_->path();
Packit Service 21b5d1
        xmpData_["Xmp.video.MimeType"] = mimeType();
Packit Service 21b5d1
Packit Service 21b5d1
        while (continueTraversing_) decodeBlock();
Packit Service 21b5d1
Packit Service 21b5d1
        aspectRatio();
Packit Service 21b5d1
    } // AsfVideo::readMetadata
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::decodeBlock()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        const long bufMinSize = 9;
Packit Service 21b5d1
        DataBuf buf(bufMinSize);
Packit Service 21b5d1
        uint64_t size = 0;
Packit Service 21b5d1
        buf.pData_[8] = '\0' ;
Packit Service 21b5d1
        const TagVocabulary* tv;
Packit Service 21b5d1
        uint64_t cur_pos = io_->tell();
Packit Service 21b5d1
Packit Service 21b5d1
        byte guidBuf[16];
Packit Service 21b5d1
        io_->read(guidBuf, 16);
Packit Service 21b5d1
Packit Service 21b5d1
        if(io_->eof()) {
Packit Service 21b5d1
            continueTraversing_ = false;
Packit Service 21b5d1
            return;
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        char GUID[37] = ""; //the getGUID function write the GUID[36],
Packit Service 21b5d1
Packit Service 21b5d1
        getGUID(guidBuf, GUID);
Packit Service 21b5d1
        tv = find( GUIDReferenceTags, GUID);
Packit Service 21b5d1
Packit Service 21b5d1
        std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
        io_->read(buf.pData_, 8);
Packit Service 21b5d1
        size = getUint64_t(buf);
Packit Service 21b5d1
Packit Service 21b5d1
        if(tv) {
Packit Service 21b5d1
            tagDecoder(tv,size-24);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        else
Packit Service 21b5d1
            io_->seek(cur_pos + size, BasicIo::beg);
Packit Service 21b5d1
Packit Service 21b5d1
        localPosition_ = io_->tell();
Packit Service 21b5d1
    } // AsfVideo::decodeBlock
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::tagDecoder(const TagVocabulary *tv, uint64_t size)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        uint64_t cur_pos = io_->tell();
Packit Service 21b5d1
        DataBuf buf(1000);
Packit Service 21b5d1
        unsigned long count = 0, tempLength = 0;
Packit Service 21b5d1
        buf.pData_[4] = '\0' ;
Packit Service 21b5d1
        Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpSeq);
Packit Service 21b5d1
Packit Service 21b5d1
        if(compareTag( exvGettext(tv->label_), "Header")) {
Packit Service 21b5d1
            localPosition_ = 0;
Packit Service 21b5d1
            io_->read(buf.pData_, 4);
Packit Service 21b5d1
            io_->read(buf.pData_, 2);
Packit Service 21b5d1
Packit Service 21b5d1
            while(localPosition_ < cur_pos + size) decodeBlock();
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "File_Properties"))
Packit Service 21b5d1
            fileProperties();
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Stream_Properties"))
Packit Service 21b5d1
            streamProperties();
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Metadata"))
Packit Service 21b5d1
            metadataHandler(1);
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Extended_Content_Description"))
Packit Service 21b5d1
            metadataHandler(2);
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Metadata_Library"))
Packit Service 21b5d1
            metadataHandler(3);
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Codec_List"))
Packit Service 21b5d1
            codecList();
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Content_Description"))
Packit Service 21b5d1
            contentDescription(size);
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Extended_Stream_Properties"))
Packit Service 21b5d1
            extendedStreamProperties(size);
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Header_Extension")) {
Packit Service 21b5d1
            localPosition_ = 0;
Packit Service 21b5d1
            headerExtension(size);
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Language_List")) {
Packit Service 21b5d1
            std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
            io_->read(buf.pData_, 2);
Packit Service 21b5d1
            count = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
            while(count--) {
Packit Service 21b5d1
                std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
                io_->read(buf.pData_, 1);   tempLength = (int)buf.pData_[0];
Packit Service 21b5d1
Packit Service 21b5d1
                io_->read(buf.pData_, tempLength);
Packit Service 21b5d1
                v->read(toString16(buf));
Packit Service 21b5d1
            }
Packit Service 21b5d1
            xmpData_.add(Exiv2::XmpKey("Xmp.video.TrackLang"), v.get());
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        io_->seek(cur_pos + size, BasicIo::beg);
Packit Service 21b5d1
        localPosition_ = io_->tell();
Packit Service 21b5d1
    } // AsfVideo::tagDecoder
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::extendedStreamProperties(uint64_t size)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        uint64_t cur_pos = io_->tell(), avgTimePerFrame = 0;
Packit Service 21b5d1
        DataBuf buf(8);
Packit Service 21b5d1
        static int previousStream;
Packit Service 21b5d1
        io_->seek(cur_pos + 48, BasicIo::beg);
Packit Service 21b5d1
Packit Service 21b5d1
        std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
        io_->read(buf.pData_, 2);
Packit Service 21b5d1
        streamNumber_ = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
        io_->read(buf.pData_, 2);
Packit Service 21b5d1
        io_->read(buf.pData_, 8);
Packit Service 21b5d1
        avgTimePerFrame = getUint64_t(buf);
Packit Service 21b5d1
Packit Service 21b5d1
        if(previousStream < streamNumber_  &&  avgTimePerFrame != 0)
Packit Service 21b5d1
            xmpData_["Xmp.video.FrameRate"] = (double)10000000/(double)avgTimePerFrame;
Packit Service 21b5d1
Packit Service 21b5d1
        previousStream = streamNumber_;
Packit Service 21b5d1
        io_->seek(cur_pos + size, BasicIo::beg);
Packit Service 21b5d1
    } // AsfVideo::extendedStreamProperties
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::contentDescription(uint64_t size)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        const long pos = io_->tell();
Packit Service 21b5d1
        if (pos == -1) throw Error(kerFailedToReadImageData);
Packit Service 21b5d1
        long length[5];
Packit Service 21b5d1
        for (int i = 0 ; i < 5 ; ++i) {
Packit Service 21b5d1
            byte buf[2];
Packit Service 21b5d1
            io_->read(buf, 2);
Packit Service 21b5d1
            if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
Packit Service 21b5d1
            length[i] = getUShort(buf, littleEndian);
Packit Service 21b5d1
        }
Packit Service 21b5d1
        for (int i = 0 ; i < 5 ; ++i) {
Packit Service 21b5d1
            DataBuf buf(length[i]);
Packit Service 21b5d1
            std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
            io_->read(buf.pData_, length[i]);
Packit Service 21b5d1
            if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
Packit Service 21b5d1
            const TagDetails* td = find(contentDescriptionTags, i);
Packit Service 21b5d1
            assert(td);
Packit Service 21b5d1
            std::string str((const char*)buf.pData_, length[i]);
Packit Service 21b5d1
            if (convertStringCharset(str, "UCS-2LE", "UTF-8")) {
Packit Service 21b5d1
                xmpData_[td->label_] = str;
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else {
Packit Service 21b5d1
                xmpData_[td->label_] = toString16(buf);
Packit Service 21b5d1
            }
Packit Service 21b5d1
        }
Packit Service 21b5d1
        if (io_->seek(pos + size, BasicIo::beg)) throw Error(kerFailedToReadImageData);
Packit Service 21b5d1
    } // AsfVideo::contentDescription
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::streamProperties()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        DataBuf buf(20);
Packit Service 21b5d1
        buf.pData_[8] = '\0' ;
Packit Service 21b5d1
        byte guidBuf[16]; int stream = 0;
Packit Service 21b5d1
        io_->read(guidBuf, 16);
Packit Service 21b5d1
        char streamType[37] = "";
Packit Service 21b5d1
        Exiv2::RiffVideo *test = NULL;
Packit Service 21b5d1
Packit Service 21b5d1
        getGUID(guidBuf, streamType);
Packit Service 21b5d1
        const TagVocabulary* tv;
Packit Service 21b5d1
        tv = find( GUIDReferenceTags, streamType);
Packit Service 21b5d1
        io_->read(guidBuf, 16);
Packit Service 21b5d1
Packit Service 21b5d1
        if(compareTag( exvGettext(tv->label_), "Audio_Media"))
Packit Service 21b5d1
            stream = 1;
Packit Service 21b5d1
        else if(compareTag( exvGettext(tv->label_), "Video_Media"))
Packit Service 21b5d1
            stream = 2;
Packit Service 21b5d1
Packit Service 21b5d1
        io_->read(buf.pData_, 8);
Packit Service 21b5d1
        if(stream == 2)
Packit Service 21b5d1
            xmpData_["Xmp.video.TimeOffset"] = getUint64_t(buf);
Packit Service 21b5d1
        else if(stream == 1)
Packit Service 21b5d1
            xmpData_["Xmp.audio.TimeOffset"] = getUint64_t(buf);
Packit Service 21b5d1
Packit Service 21b5d1
        io_->read(buf.pData_, 8);
Packit Service 21b5d1
        std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
        io_->read(buf.pData_, 1);
Packit Service 21b5d1
        streamNumber_ = (int)buf.pData_[0] & 127;
Packit Service 21b5d1
Packit Service 21b5d1
        io_->read(buf.pData_, 5);
Packit Service 21b5d1
        std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
        io_->read(buf.pData_, 2);
Packit Service 21b5d1
        long temp = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
        if(stream == 2) {
Packit Service 21b5d1
            xmpData_["Xmp.video.Width"] = temp;
Packit Service 21b5d1
            width_ = temp;
Packit Service 21b5d1
        }
Packit Service 21b5d1
        else if(stream == 1) {
Packit Service 21b5d1
            xmpData_["Xmp.audio.Codec"] = test->printAudioEncoding(temp);
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        io_->read(buf.pData_, 2);
Packit Service 21b5d1
        temp = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
        if(stream == 1)
Packit Service 21b5d1
            xmpData_["Xmp.audio.ChannelType"] = temp;
Packit Service 21b5d1
Packit Service 21b5d1
        io_->read(buf.pData_, 4);
Packit Service 21b5d1
        temp = Exiv2::getULong(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
        if(stream == 2) {
Packit Service 21b5d1
            xmpData_["Xmp.video.Height"] = temp;
Packit Service 21b5d1
            height_ = temp;
Packit Service 21b5d1
        }
Packit Service 21b5d1
        else if(stream == 1) {
Packit Service 21b5d1
            xmpData_["Xmp.audio.SampleRate"] = temp;
Packit Service 21b5d1
        }
Packit Service 21b5d1
    } // AsfVideo::streamProperties
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::codecList()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        DataBuf buf(200);
Packit Service 21b5d1
        io_->read(buf.pData_, 16);
Packit Service 21b5d1
        std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
        io_->read(buf.pData_, 4);
Packit Service 21b5d1
        int codecCount = Exiv2::getULong(buf.pData_, littleEndian), descLength = 0, codecType = 0;
Packit Service 21b5d1
Packit Service 21b5d1
        while(codecCount--) {
Packit Service 21b5d1
            std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
            io_->read(buf.pData_, 2);
Packit Service 21b5d1
            codecType = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
            io_->read(buf.pData_, 2);
Packit Service 21b5d1
            descLength = Exiv2::getUShort(buf.pData_, littleEndian) * 2;
Packit Service 21b5d1
Packit Service 21b5d1
            if (descLength < 0) {
Packit Service 21b5d1
            #ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                    EXV_ERROR   << " Description found in this ASF file is not of valid size ."
Packit Service 21b5d1
                                << " Entries considered invalid. Not Processed.\n";
Packit Service 21b5d1
            #endif
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else {
Packit Service 21b5d1
                io_->read(buf.pData_, descLength);
Packit Service 21b5d1
                if(codecType == 1)
Packit Service 21b5d1
                    xmpData_["Xmp.video.Codec"] = toString16(buf);
Packit Service 21b5d1
                else if(codecType == 2)
Packit Service 21b5d1
                    xmpData_["Xmp.audio.Compressor"] = toString16(buf);
Packit Service 21b5d1
            }
Packit Service 21b5d1
Packit Service 21b5d1
            std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
            io_->read(buf.pData_, 2);
Packit Service 21b5d1
            descLength = Exiv2::getUShort(buf.pData_, littleEndian) * 2;
Packit Service 21b5d1
Packit Service 21b5d1
            if (descLength < 0) {
Packit Service 21b5d1
            #ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                    EXV_ERROR   << " Description found in this ASF file is not of valid size ."
Packit Service 21b5d1
                                << " Entries considered invalid. Not Processed.\n";
Packit Service 21b5d1
            #endif
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else {
Packit Service 21b5d1
                io_->read(buf.pData_, descLength);
Packit Service 21b5d1
Packit Service 21b5d1
                if(codecType == 1)
Packit Service 21b5d1
                    xmpData_["Xmp.video.CodecDescription"] = toString16(buf);
Packit Service 21b5d1
                else if(codecType == 2)
Packit Service 21b5d1
                    xmpData_["Xmp.audio.CodecDescription"] = toString16(buf);
Packit Service 21b5d1
            }
Packit Service 21b5d1
Packit Service 21b5d1
            std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
            io_->read(buf.pData_, 2);
Packit Service 21b5d1
            descLength = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
            if (descLength < 0) {
Packit Service 21b5d1
            #ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                    EXV_ERROR   << " Description found in this ASF file is not of valid size ."
Packit Service 21b5d1
                                << " Entries considered invalid. Not Processed.\n";
Packit Service 21b5d1
            #endif
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else {
Packit Service 21b5d1
                io_->read(buf.pData_, descLength);
Packit Service 21b5d1
            }
Packit Service 21b5d1
        }
Packit Service 21b5d1
    } // AsfVideo::codecList
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::headerExtension(uint64_t size)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        uint64_t cur_pos = io_->tell();
Packit Service 21b5d1
        DataBuf buf(20);
Packit Service 21b5d1
        io_->read(buf.pData_, 18);
Packit Service 21b5d1
        buf.pData_[4] = '\0' ;
Packit Service 21b5d1
        io_->read(buf.pData_, 4);
Packit Service 21b5d1
Packit Service 21b5d1
        while(localPosition_ < cur_pos + size) decodeBlock();
Packit Service 21b5d1
Packit Service 21b5d1
        io_->seek(cur_pos + size, BasicIo::beg);
Packit Service 21b5d1
    } // AsfVideo::headerExtension
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::metadataHandler(int meta)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        DataBuf buf(5000);
Packit Service 21b5d1
        io_->read(buf.pData_, 2);
Packit Service 21b5d1
        int recordCount = Exiv2::getUShort(buf.pData_, littleEndian), nameLength = 0, dataLength = 0, dataType = 0;
Packit Service 21b5d1
        Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpSeq);
Packit Service 21b5d1
        byte guidBuf[16];   char fileID[37] = "";
Packit Service 21b5d1
Packit Service 21b5d1
        while(recordCount--) {
Packit Service 21b5d1
            std::memset(buf.pData_, 0x0, buf.size_);
Packit Service 21b5d1
Packit Service 21b5d1
            if(meta == 1 || meta == 3) {
Packit Service 21b5d1
                io_->read(buf.pData_, 4);
Packit Service 21b5d1
                io_->read(buf.pData_, 2);
Packit Service 21b5d1
                nameLength = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
                io_->read(buf.pData_, 2);
Packit Service 21b5d1
                dataType = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
                io_->read(buf.pData_, 4);
Packit Service 21b5d1
                dataLength = Exiv2::getULong(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
                if (nameLength > 5000) {
Packit Service 21b5d1
#ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                    EXV_ERROR << "Xmp.video.Metadata nameLength was found to be larger than 5000 "
Packit Service 21b5d1
                              << " entries considered invalid; not read.\n";
Packit Service 21b5d1
#endif
Packit Service 21b5d1
                    io_->seek(io_->tell() + nameLength, BasicIo::beg);
Packit Service 21b5d1
                } else {
Packit Service 21b5d1
                    io_->read(buf.pData_, nameLength);
Packit Service 21b5d1
                }
Packit Service 21b5d1
Packit Service 21b5d1
                v->read(toString16(buf));
Packit Service 21b5d1
                if(dataType == 6) {
Packit Service 21b5d1
                    io_->read(guidBuf, 16);
Packit Service 21b5d1
                    getGUID(guidBuf, fileID);
Packit Service 21b5d1
                }
Packit Service 21b5d1
                else
Packit Service 21b5d1
                    // Sanity check with an "unreasonably" large number
Packit Service 21b5d1
                    if (dataLength > 5000) {
Packit Service 21b5d1
#ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                        EXV_ERROR << "Xmp.video.Metadata dataLength was found to be larger than 5000 "
Packit Service 21b5d1
                                  << " entries considered invalid; not read.\n";
Packit Service 21b5d1
#endif
Packit Service 21b5d1
                        io_->seek(io_->tell() + dataLength, BasicIo::beg);
Packit Service 21b5d1
                    }
Packit Service 21b5d1
                else
Packit Service 21b5d1
                        io_->read(buf.pData_, dataLength);
Packit Service 21b5d1
            }
Packit Service 21b5d1
Packit Service 21b5d1
            else if(meta == 2) {
Packit Service 21b5d1
                io_->read(buf.pData_, 2);
Packit Service 21b5d1
                nameLength = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
                if (nameLength > 5000) {
Packit Service 21b5d1
#ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                    EXV_ERROR << "Xmp.video.Metadata nameLength was found to be larger than 5000 "
Packit Service 21b5d1
                              << " entries considered invalid; not read.\n";
Packit Service 21b5d1
#endif
Packit Service 21b5d1
                    io_->seek(io_->tell() + nameLength, BasicIo::beg);
Packit Service 21b5d1
                } else {
Packit Service 21b5d1
                    io_->read(buf.pData_, nameLength);
Packit Service 21b5d1
                }
Packit Service 21b5d1
Packit Service 21b5d1
                v->read(toString16(buf));
Packit Service 21b5d1
Packit Service 21b5d1
                io_->read(buf.pData_, 2);
Packit Service 21b5d1
                dataType = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
                io_->read(buf.pData_, 2);
Packit Service 21b5d1
                dataLength = Exiv2::getUShort(buf.pData_, littleEndian);
Packit Service 21b5d1
Packit Service 21b5d1
                // Sanity check with an "unreasonably" large number
Packit Service 21b5d1
                if (dataLength > 5000) {
Packit Service 21b5d1
#ifndef SUPPRESS_WARNINGS
Packit Service 21b5d1
                    EXV_ERROR << "Xmp.video.Metadata dataLength was found to be larger than 5000 "
Packit Service 21b5d1
                              << " entries considered invalid; not read.\n";
Packit Service 21b5d1
#endif
Packit Service 21b5d1
                    io_->seek(io_->tell() + dataLength, BasicIo::beg);
Packit Service 21b5d1
                }
Packit Service 21b5d1
            else
Packit Service 21b5d1
                io_->read(buf.pData_, dataLength);
Packit Service 21b5d1
            }
Packit Service 21b5d1
Packit Service 21b5d1
            if(dataType == 0) {                       // Unicode String
Packit Service 21b5d1
                v->read(toString16(buf));
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else if(dataType == 2 || dataType == 5) { // 16-bit Unsigned Integer
Packit Service 21b5d1
                v->read( Exiv2::toString( Exiv2::getUShort(buf.pData_, littleEndian)));
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else if(dataType == 3) {                  // 32-bit Unsigned Integer
Packit Service 21b5d1
                v->read( Exiv2::toString( Exiv2::getULong( buf.pData_, littleEndian)));
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else if(dataType == 4) {                  // 64-bit Unsigned Integer
Packit Service 21b5d1
                v->read(Exiv2::toString(getUint64_t(buf)));
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else if(dataType == 6) {                  // 128-bit GUID
Packit Service 21b5d1
                v->read(Exiv2::toString(fileID));
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else {                                    // Byte array
Packit Service 21b5d1
                v->read( Exiv2::toString(buf.pData_));
Packit Service 21b5d1
            }
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        if(meta == 1) {
Packit Service 21b5d1
            xmpData_.add(Exiv2::XmpKey("Xmp.video.Metadata"), v.get());
Packit Service 21b5d1
        }
Packit Service 21b5d1
        else if(meta == 2) {
Packit Service 21b5d1
            xmpData_.add(Exiv2::XmpKey("Xmp.video.ExtendedContentDescription"), v.get());
Packit Service 21b5d1
        }
Packit Service 21b5d1
        else {
Packit Service 21b5d1
            xmpData_.add(Exiv2::XmpKey("Xmp.video.MetadataLibrary"), v.get());
Packit Service 21b5d1
        }
Packit Service 21b5d1
    } // AsfVideo::metadataHandler
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::fileProperties()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        DataBuf buf(9);
Packit Service 21b5d1
        buf.pData_[8] = '\0' ;
Packit Service 21b5d1
Packit Service 21b5d1
        byte guidBuf[16];
Packit Service 21b5d1
        io_->read(guidBuf, 16);
Packit Service 21b5d1
        char fileID[37] = ""; int count = 7;
Packit Service 21b5d1
        getGUID(guidBuf, fileID);
Packit Service 21b5d1
        xmpData_["Xmp.video.FileID"] = fileID;
Packit Service 21b5d1
Packit Service 21b5d1
        const TagDetails* td;
Packit Service 21b5d1
Packit Service 21b5d1
        while(count--) {
Packit Service 21b5d1
            td = find(filePropertiesTags , (count + 1));
Packit Service 21b5d1
            io_->read(buf.pData_, 8);
Packit Service 21b5d1
Packit Service 21b5d1
            if(count == 0) {
Packit Service 21b5d1
                buf.pData_[4] = '\0' ;
Packit Service 21b5d1
                io_->read(buf.pData_, 4); io_->read(buf.pData_, 4);
Packit Service 21b5d1
            }
Packit Service 21b5d1
Packit Service 21b5d1
            if(count == 3 || count == 2) {
Packit Service 21b5d1
                xmpData_[exvGettext(td->label_)] = getUint64_t(buf) / 10000;
Packit Service 21b5d1
            }
Packit Service 21b5d1
            else {
Packit Service 21b5d1
                xmpData_[exvGettext(td->label_)] = getUint64_t(buf);
Packit Service 21b5d1
            }
Packit Service 21b5d1
        }
Packit Service 21b5d1
    } // AsfVideo::fileProperties
Packit Service 21b5d1
Packit Service 21b5d1
    void AsfVideo::aspectRatio()
Packit Service 21b5d1
    {
Packit Service 21b5d1
        //TODO - Make a better unified method to handle all cases of Aspect Ratio
Packit Service 21b5d1
Packit Service 21b5d1
        double aspectRatio = (double)width_ / (double)height_;
Packit Service 21b5d1
        aspectRatio = floor(aspectRatio*10) / 10;
Packit Service 21b5d1
        xmpData_["Xmp.video.AspectRatio"] = aspectRatio;
Packit Service 21b5d1
Packit Service 21b5d1
        int aR = (int) ((aspectRatio*10.0)+0.1);
Packit Service 21b5d1
Packit Service 21b5d1
        switch  (aR) {
Packit Service 21b5d1
            case 13 : xmpData_["Xmp.video.AspectRatio"] = "4:3"     ; break;
Packit Service 21b5d1
            case 17 : xmpData_["Xmp.video.AspectRatio"] = "16:9"    ; break;
Packit Service 21b5d1
            case 10 : xmpData_["Xmp.video.AspectRatio"] = "1:1"     ; break;
Packit Service 21b5d1
            case 16 : xmpData_["Xmp.video.AspectRatio"] = "16:10"   ; break;
Packit Service 21b5d1
            case 22 : xmpData_["Xmp.video.AspectRatio"] = "2.21:1"  ; break;
Packit Service 21b5d1
            case 23 : xmpData_["Xmp.video.AspectRatio"] = "2.35:1"  ; break;
Packit Service 21b5d1
            case 12 : xmpData_["Xmp.video.AspectRatio"] = "5:4"     ; break;
Packit Service 21b5d1
            default : xmpData_["Xmp.video.AspectRatio"] = aspectRatio;break;
Packit Service 21b5d1
        }
Packit Service 21b5d1
    } // AsfVideo::aspectRatio
Packit Service 21b5d1
Packit Service 21b5d1
Packit Service 21b5d1
    Image::AutoPtr newAsfInstance(BasicIo::AutoPtr io, bool /*create*/)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        Image::AutoPtr image(new AsfVideo(io));
Packit Service 21b5d1
        if (!image->good()) {
Packit Service 21b5d1
            image.reset();
Packit Service 21b5d1
        }
Packit Service 21b5d1
        return image;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
    bool isAsfType(BasicIo& iIo, bool advance)
Packit Service 21b5d1
    {
Packit Service 21b5d1
        const int32_t len = 16;
Packit Service 21b5d1
        byte buf[len];
Packit Service 21b5d1
        iIo.read(buf, len);
Packit Service 21b5d1
Packit Service 21b5d1
        if (iIo.error() || iIo.eof()) {
Packit Service 21b5d1
            return false;
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        bool matched = isASFType(buf);
Packit Service 21b5d1
        if (!advance || !matched) {
Packit Service 21b5d1
            iIo.seek(0, BasicIo::beg);
Packit Service 21b5d1
        }
Packit Service 21b5d1
Packit Service 21b5d1
        return matched;
Packit Service 21b5d1
    }
Packit Service 21b5d1
Packit Service 21b5d1
}                                       // namespace Exiv2
Packit Service 21b5d1
#endif // EXV_ENABLE_VIDEO