Overview

Packages

  • admin
  • classes
    • media
  • CodeIgniter
    • Libraries
  • core
  • functions
  • JSMin
  • None
  • OpenID
  • PHP
  • PHPMailer
  • plugins
    • admin
    • development
    • feed
    • mail
    • media
    • misc
    • seo
    • spam
    • uploader
    • users
    • zenpage
    • zenphoto
      • news
  • Services
    • JSON

Classes

  • _zp_captcha
  • _zp_HTML_cache
  • admin_approval
  • Album
  • AlbumBase
  • AlbumZip
  • AMFReader
  • AMFStream
  • AnyFile
  • AnyFile_Options
  • Auth_OpenID
  • Auth_OpenID_AlreadySigned
  • Auth_OpenID_AssociateRequest
  • Auth_OpenID_Association
  • Auth_OpenID_AuthRequest
  • Auth_OpenID_AX
  • Auth_OpenID_AX_AttrInfo
  • Auth_OpenID_AX_Error
  • Auth_OpenID_AX_FetchRequest
  • Auth_OpenID_AX_FetchResponse
  • Auth_OpenID_AX_KeyValueMessage
  • Auth_OpenID_AX_Message
  • Auth_OpenID_AX_StoreRequest
  • Auth_OpenID_AX_StoreResponse
  • Auth_OpenID_BcMathWrapper
  • Auth_OpenID_CancelResponse
  • Auth_OpenID_CheckAuthRequest
  • Auth_OpenID_CheckIDRequest
  • Auth_OpenID_Consumer
  • Auth_OpenID_ConsumerResponse
  • Auth_OpenID_CryptUtil
  • Auth_OpenID_DatabaseConnection
  • Auth_OpenID_Decoder
  • Auth_OpenID_DiffieHellman
  • Auth_OpenID_DiffieHellmanSHA1ConsumerSession
  • Auth_OpenID_DiffieHellmanSHA1ServerSession
  • Auth_OpenID_DiffieHellmanSHA256ConsumerSession
  • Auth_OpenID_DiffieHellmanSHA256ServerSession
  • Auth_OpenID_DumbStore
  • Auth_OpenID_Encoder
  • Auth_OpenID_EncodingError
  • Auth_OpenID_Extension
  • Auth_OpenID_FailureResponse
  • Auth_OpenID_FileStore
  • Auth_OpenID_GenericConsumer
  • Auth_OpenID_GmpMathWrapper
  • Auth_OpenID_KVForm
  • Auth_OpenID_MalformedReturnURL
  • Auth_OpenID_MalformedTrustRoot
  • Auth_OpenID_Mapping
  • Auth_OpenID_MathLibrary
  • Auth_OpenID_MDB2Store
  • Auth_OpenID_MemcachedStore
  • Auth_OpenID_Message
  • Auth_OpenID_MySQLStore
  • Auth_OpenID_NamespaceMap
  • Auth_OpenID_NoReturnToError
  • Auth_OpenID_OpenIDStore
  • Auth_OpenID_PAPE_Request
  • Auth_OpenID_PAPE_Response
  • Auth_OpenID_Parse
  • Auth_OpenID_PlainTextConsumerSession
  • Auth_OpenID_PlainTextServerSession
  • Auth_OpenID_PostgreSQLStore
  • Auth_OpenID_Request
  • Auth_OpenID_Server
  • Auth_OpenID_ServerError
  • Auth_OpenID_ServerErrorContainer
  • Auth_OpenID_ServerRequest
  • Auth_OpenID_ServerResponse
  • Auth_OpenID_ServiceEndpoint
  • Auth_OpenID_ServiceEndpointLoader
  • Auth_OpenID_SessionNegotiator
  • Auth_OpenID_SetupNeededResponse
  • Auth_OpenID_Signatory
  • Auth_OpenID_SigningEncoder
  • Auth_OpenID_SQLiteStore
  • Auth_OpenID_SQLStore
  • Auth_OpenID_SRegBase
  • Auth_OpenID_SRegRequest
  • Auth_OpenID_SRegResponse
  • Auth_OpenID_SuccessResponse
  • Auth_OpenID_TrustRoot
  • Auth_OpenID_TypeURIMismatch
  • Auth_OpenID_UntrustedReturnURL
  • Auth_OpenID_WebResponse
  • Auth_Yadis_Discovery
  • Auth_Yadis_DiscoveryResult
  • Auth_Yadis_dom
  • Auth_Yadis_domxml
  • Auth_Yadis_HTTPFetcher
  • Auth_Yadis_HTTPResponse
  • Auth_Yadis_Manager
  • Auth_Yadis_ManagerLoader
  • Auth_Yadis_ParanoidHTTPFetcher
  • Auth_Yadis_ParseHTML
  • Auth_Yadis_PHPSession
  • Auth_Yadis_PlainHTTPFetcher
  • Auth_Yadis_ProxyResolver
  • Auth_Yadis_Service
  • Auth_Yadis_SessionLoader
  • Auth_Yadis_XMLParser
  • Auth_Yadis_XRDS
  • Auth_Yadis_Yadis
  • auto_backup
  • AVCSequenceParameterSetReader
  • bxslider
  • cacheManager
  • cacheManagerFeed
  • CI_jsmin
  • CI_load
  • cloneZenphoto
  • codeIgniter_kludge
  • colorbox
  • Comment
  • comment_form
  • contactformOptions
  • crop_image
  • cycle
  • defaultCodeblocks
  • deprecated_functions
  • DownloadList
  • dynamic_locale
  • dynamicAlbum
  • elFinder_options
  • email_new_user
  • exampleMacros
  • external_auth
  • ExternalFeed
  • externalFeed_options
  • favorites
  • favoritesOptions
  • federated_logon
  • feed
  • fieldExtender
  • flag_thumbnail
  • Gallery
  • galleryArticles
  • getID3
  • getid3_aac
  • getid3_apetag
  • getid3_flv
  • getid3_handler
  • getid3_id3v1
  • getid3_id3v2
  • getid3_lib
  • getid3_lyrics3
  • getid3_mp3
  • getid3_mpeg
  • getid3_quicktime
  • getid3_swf
  • GoogleMap
  • Googlemaps
  • googleVerifyOptions
  • hitcounter
  • HTML
  • htmlmetatags
  • http_auth
  • Image
  • image_effects
  • internal_deprecations
  • ipBlocker
  • jcarousel
  • jPlayer
  • jplayer_options
  • jquery_rating
  • JSMin
  • lib_GD_Options
  • lib_Imagick_Options
  • lib_NoGraphics
  • MediaObject
  • menu_manager
  • MergedRSS
  • MergedRSSOptions
  • mobile
  • Mobile_Detect
  • mobileTheme
  • multipleLayoutOptions
  • null_seo
  • OAuthConsumer
  • OAuthDataStore
  • OAuthRequest
  • OAuthServer
  • OAuthSignatureMethod
  • OAuthSignatureMethod_HMAC_SHA1
  • OAuthSignatureMethod_PLAINTEXT
  • OAuthSignatureMethod_RSA_SHA1
  • OAuthToken
  • OAuthUtil
  • pagedThumbsNav
  • pagedthumbsOptions
  • PclZip
  • PersistentObject
  • PHPMailer
  • PlainText
  • POP3
  • print_album_menu
  • pseudoPlayer
  • publishContent
  • quota_manager
  • reCaptcha
  • ReCaptchaResponse
  • register_user
  • rewriteRules
  • rewriteTokens
  • RSS
  • RSS_internal_deprecations
  • rss_options
  • search_statistics
  • SearchEngine
  • security_logger
  • seo_locale
  • Services_JSON
  • Services_JSON_Error
  • setupexternalFeed
  • setupRSS
  • show_not_loggedin
  • sitemap
  • slideshow
  • SMTP
  • static_html_cache
  • tagsuggest
  • TextObject
  • TextObject_internal_deprecations
  • TextObject_Options
  • ThemeObject
  • themeSwitcher
  • tinymce4Options
  • tinyURL
  • Transientimage
  • tweet
  • TwitterOAuth
  • UploadHandler
  • user_expiry
  • user_groups
  • user_logout_options
  • userAddressFields
  • utf8
  • Video
  • Video_internal_deprecations
  • VideoObject_Options
  • viewer_size_image_options
  • WEBdocs
  • WEBdocs_Options
  • xmpMetadata
  • Zenpage
  • Zenpage_internal_deprecations
  • ZenpageCategory
  • zenpagecms
  • ZenpageItems
  • ZenpageNews
  • ZenpagePage
  • ZenpageRoot
  • Zenphoto_Administrator
  • Zenphoto_Authority
  • zenphoto_org_news
  • zenphoto_seo
  • zenphotoDonate
  • ZipStream
  • zp_PHPMailer
  • zpCaptcha
  • zpFunctions
  • zpLegacySpam
  • zpMutex
  • zpSimpleSpam
  • zpTrivialSpam

Exceptions

  • BadFunctionCallException
  • BadMethodCallException
  • Exception
  • getid3_exception
  • JSMin_UnterminatedCommentException
  • JSMin_UnterminatedRegExpException
  • JSMin_UnterminatedStringException
  • LogicException
  • OAuthExcept
  • phpmailerException

Functions

  • __autoload
  • _escape_xref
  • _recaptcha_aes_encrypt
  • _recaptcha_aes_pad
  • _recaptcha_http_post
  • _recaptcha_mailhide_email_parts
  • _recaptcha_mailhide_urlbase64
  • _recaptcha_qsencode
  • accessAllAlbums
  • add_context
  • addalbumsToDatabase
  • addCategoriesToDatabase
  • addGeoCoord
  • addItem
  • addPagesToDatabase
  • addPluginScript
  • addPluginType
  • addSubalbumMenus
  • admin_album_list
  • admin_securityChecks
  • admin_showupdate
  • adminPageNav
  • adminToolbox
  • albumNumber
  • applyMacros
  • Auth_OpenID_arrangeByType
  • Auth_OpenID_AX_checkAlias
  • Auth_OpenID_AX_toTypeURIs
  • Auth_OpenID_bestMatchingService
  • Auth_OpenID_checkFieldName
  • Auth_OpenID_checkSessionType
  • Auth_OpenID_checkTimestamp
  • Auth_OpenID_detectMathLibrary
  • Auth_OpenID_discover
  • Auth_OpenID_discoverURI
  • Auth_OpenID_discoverWithoutYadis
  • Auth_OpenID_discoverWithYadis
  • Auth_OpenID_discoverXRI
  • Auth_OpenID_extractReturnURL
  • Auth_OpenID_findOPLocalIdentifier
  • Auth_OpenID_getAllAssociationTypes
  • Auth_OpenID_getAllowedReturnURLs
  • Auth_OpenID_getAuthorityPattern
  • Auth_OpenID_getAvailableSessionTypes
  • Auth_OpenID_getDefaultAssociationOrder
  • Auth_OpenID_getDefaultGen
  • Auth_OpenID_getDefaultMod
  • Auth_OpenID_getDefaultNegotiator
  • Auth_OpenID_getEncodedPattern
  • Auth_OpenID_getEncryptedNegotiator
  • Auth_OpenID_getEscapeRE
  • Auth_OpenID_getMathLib
  • Auth_OpenID_getOnlyEncryptedOrder
  • Auth_OpenID_getOpenIDConsumerTypeURIs
  • Auth_OpenID_getOpenIDTypeName
  • Auth_OpenID_getOpenIDTypeURIs
  • Auth_OpenID_getOPOrUserServices
  • Auth_OpenID_getSecretSize
  • Auth_OpenID_getSessionTypes
  • Auth_OpenID_getSupportedAssociationTypes
  • Auth_OpenID_getUnreserved
  • Auth_OpenID_getURIPattern
  • Auth_OpenID_getURLIllegalCharRE
  • Auth_OpenID_HMACSHA1
  • Auth_OpenID_HMACSHA256
  • Auth_OpenID_include_init
  • Auth_OpenID_isError
  • Auth_OpenID_isOpenID1
  • Auth_OpenID_legacy_discover
  • Auth_OpenID_makeOpenIDEndpoints
  • Auth_OpenID_math_extensions
  • Auth_OpenID_mkNonce
  • Auth_OpenID_noMathSupport
  • Auth_OpenID_pct_encoded_replace
  • Auth_OpenID_pct_encoded_replace_unreserved
  • Auth_OpenID_registerNamespaceAlias
  • Auth_OpenID_remove_dot_segments
  • Auth_OpenID_removeNamespaceAlias
  • Auth_OpenID_returnToMatches
  • Auth_OpenID_setNoMathSupport
  • Auth_OpenID_SHA1
  • Auth_OpenID_SHA256
  • Auth_OpenID_splitNonce
  • Auth_OpenID_supportsSReg
  • Auth_OpenID_urinorm
  • Auth_OpenID_verifyReturnTo
  • Auth_Yadis_array_scramble
  • Auth_Yadis_escapeForIRI
  • Auth_Yadis_getCanonicalID
  • Auth_Yadis_getDefaultProxy
  • Auth_Yadis_getEscapeRE
  • Auth_Yadis_getIPrivateChars
  • Auth_Yadis_getNSMap
  • Auth_Yadis_getServiceEndpoints
  • Auth_Yadis_getSupportedExtensions
  • Auth_Yadis_getUCSChars
  • Auth_Yadis_getXMLParser
  • Auth_Yadis_getXRDExpiration
  • Auth_Yadis_getXrefRE
  • Auth_Yadis_getXRIAuthorities
  • Auth_Yadis_identifierScheme
  • Auth_Yadis_iriToURI
  • Auth_Yadis_pct_escape_unicode
  • Auth_Yadis_providerIsAuthoritative
  • Auth_Yadis_rootAuthority
  • Auth_Yadis_setDefaultParser
  • Auth_Yadis_startswith
  • Auth_Yadis_toIRINormal
  • Auth_Yadis_toURINormal
  • Auth_Yadis_XRI
  • Auth_Yadis_XRIAppendArgs
  • authorSelector
  • build_query
  • build_url
  • bulkActionRedirect
  • bulkTags
  • byteConvert
  • cacheImage
  • checkAccess
  • checkAlbumimagesort
  • checkAlbumParentid
  • checkAlbumPassword
  • checkChosenItemStatus
  • checkChosenMenuset
  • checked
  • checkFolder
  • checkForEmptyTitle
  • checkForGuest
  • checkForPage
  • checkForPassword
  • checkForUpdate
  • checkHitcounterDisplay
  • checkIfChecked
  • checkIfLockedNews
  • checkIfLockedPage
  • checkIfNew
  • checkInstall
  • checkLayoutUseForImages
  • checkNewsAccess
  • checkNewsCategoryPassword
  • checkObjectsThumb
  • checkPagePassword
  • checkPageValidity
  • checkParentLayouts
  • checkPublishDates
  • checkRequiredField
  • checkSelectedAlbum
  • checkSignature
  • cleanAlbum
  • cleanHTML
  • clearSitemapCache
  • clonedFrom
  • codeblocktabsJS
  • comment_form_addComment
  • comment_form_handle_comment
  • comment_form_PaginationJS
  • comment_form_postcomment
  • comment_form_print10Most
  • comment_form_visualEditor
  • commentFormUseCaptcha
  • commentReply
  • commentsAllowed
  • consolidatedEditMessages
  • copyLayoutSelection
  • copyThemeDirectory
  • countArticles
  • countCombiNews
  • createMenuIfNotExists
  • createRelatedItemsResultArray
  • cron_starter
  • currentRelativeURL
  • customOptions
  • dateDiff
  • datepickerJS
  • dateTimeConvert
  • db_affected_rows
  • db_close
  • db_collation
  • db_connect
  • db_count
  • db_create
  • db_create_table
  • db_error
  • db_fetch_assoc
  • db_fetch_row
  • db_free_result
  • db_getSQLmode
  • db_insert_id
  • db_LIKE_escape
  • db_list_fields
  • db_name
  • db_num_rows
  • db_permissions
  • db_quote
  • db_setSQLmode
  • db_show
  • db_software
  • db_table_update
  • db_truncate_table
  • debug404
  • debugLog
  • debugLogBacktrace
  • debugLogVar
  • defaultCodeblocks_codebox
  • deleteArticle
  • deleteCategory
  • deleteItem
  • deleteLayoutSelection
  • deletePage
  • deleteThemeDirectory
  • detect_fetcher
  • detect_math
  • detect_query_corruption
  • detect_random
  • detect_stores
  • detect_xml
  • dircopy
  • displayError
  • doIncludes
  • elFinder_admin_tabs
  • elFinder_tinymce
  • enableExtension
  • escape
  • executeRSS
  • exitZP
  • exposeZenPhotoInformations
  • extensionEnabled
  • fetchComments
  • filesystemToInternal
  • filter_extractReturnURL
  • filter_MatchesAnyOpenIDConsumerType
  • filter_MatchesAnyOpenIDType
  • filterImageQuery
  • fix_path_redirect
  • formatList
  • fullText
  • galleryAlbumsPerPage
  • genAlbumList
  • generateCaptcha
  • generateLanguageList
  • generateListFromArray
  • generateListFromFiles
  • generateRadiobuttonsFromArray
  • generateSitemapCacheFile
  • generateSitemapIndexCacheFile
  • generateUnorderedListFromArray
  • get_AnyFile_suffixes
  • get_context
  • get_filterScript
  • get_instance
  • get_language_string
  • getAdminThumb
  • getAlbumArray
  • getAlbumBreadcrumb
  • getAlbumBreadcrumbAdmin
  • getAlbumCustomData
  • getAlbumData
  • getAlbumDate
  • getAlbumDesc
  • getAlbumFolder
  • getAlbumGeodata
  • getAlbumId
  • getAlbumInherited
  • getAlbumLinkURL
  • getAlbumLocation
  • getAlbumPage
  • getAlbumPlace
  • getAlbumStatistic
  • getAlbumThumb
  • getAlbumTitle
  • getAlbumURL
  • getAllAccessibleAlbums
  • getAllAlbums
  • getAllArticleDates
  • getAllCategories
  • getAllDates
  • getAllowedTags
  • getAllSubAlbumIDs
  • getAllSubalbums
  • getAllTagsCount
  • getAllTagsFromAlbum
  • getAllTagsFromAlbum_multi_unique
  • getAllTagsFromZenpage
  • getAllTagsUnique
  • getAllTranslations
  • getAnnotatedAlbumTitle
  • getAnnotatedImageTitle
  • getArticles
  • getAuthor
  • getBare
  • getBareAlbumDesc
  • getBareAlbumTitle
  • getBareGalleryDesc
  • getBareGalleryTitle
  • getBareImageDesc
  • getBareImageTitle
  • getBareNewsAlbumTitle
  • getBareNewsTitle
  • getBarePageTitle
  • getCategory
  • getCategoryID
  • getCategoryLink
  • getCategoryParentID
  • getCategorySortOrder
  • getCategoryTitle
  • getCheckboxState
  • getCodeblock
  • getCombiNews
  • getCommentAddress
  • getCommentAuthorEmail
  • getCommentAuthorLink
  • getCommentAuthorName
  • getCommentAuthorSite
  • getCommentBody
  • getCommentCount
  • getCommentDate
  • getCommentDateTime
  • getCommentErrors
  • getCommentsAllowed
  • getCommentStored
  • getCommentTime
  • getConsumer
  • getContentShorten
  • getCurrentMenuItem
  • getCurrentNewsArchive
  • getCurrentNewsCategory
  • getCurrentNewsCategoryID
  • getCurrentNewsCategoryParentID
  • getCurrentNewsPage
  • getCurrentPage
  • getCurrentTheme
  • getCustomAlbumThumb
  • getCustomAlbumThumbMaxSpace
  • getCustomImageURL
  • getCustomPageURL
  • getCustomSizedImageMaxSpace
  • getCustomSizedImageThumbMaxSpace
  • getDefaultHeight
  • getDefaultSizedImage
  • getDefaultWidth
  • getDownloadLink
  • getdownloadList
  • getDownloadURL
  • getE
  • getEnabledPlugins
  • getExpiryDatePost
  • getFavoritesURL
  • getField
  • getFirstImageURL
  • getFullHeight
  • getFullImageURL
  • getFullNewsImage
  • getFullWidth
  • getGalleryDesc
  • getGalleryIndexURL
  • getGalleryTitle
  • getGeoCoord
  • getHeadTitle
  • getHitcounter
  • getImageArgs
  • getImageCacheFilename
  • getImageCachePostfix
  • getImageCity
  • getImageCountry
  • getImageCustomData
  • getImageData
  • getImageDate
  • getImageDesc
  • getImageEXIFData
  • getImageGeodata
  • getImageID
  • getImageLinkURL
  • getImageLocation
  • getImageMetaData
  • getImageParameters
  • getImageProcessorURI
  • getImageProcessorURIFromCacheName
  • getImageRotation
  • getImageSortOrder
  • getImageState
  • getImageStatistic
  • getImageThumb
  • getImageTitle
  • getImageURI
  • getImageURL
  • getItem
  • getItemByID
  • getItemTitleAndURL
  • getjPlayerSkinCSS
  • getjPlayerSkins
  • getLanguageArray
  • getLanguageFlag
  • getLastImageURL
  • getLatestComments
  • getLatestNews
  • getLatestZenpageComments
  • getLayout
  • getLayoutSelector
  • getLink
  • getLinkHTML
  • getLogTabs
  • getMacros
  • getMainSiteName
  • getMainSiteURL
  • getManagedAlbumList
  • getMaxSpaceContainer
  • getMenuFromLink
  • getMenuItemChilds
  • getMenuItems
  • getMenumanagerPredicessor
  • getMenumanagerSuccessor
  • getMenuSetSelector
  • getMenuVisibility
  • getMimeString
  • getNestedAlbumList
  • getNewsAdminOption
  • getNewsAdminOptionPath
  • getNewsAlbumName
  • getNewsAlbumTitle
  • getNewsAlbumURL
  • getNewsArchivePath
  • getNewsArchiveURL
  • getNewsAuthor
  • getNewsCategories
  • getNewsCategoryCustomData
  • getNewsCategoryDesc
  • getNewsCategoryPath
  • getNewsCategoryURL
  • getNewsContent
  • getNewsContentShorten
  • getNewsCustomData
  • getNewsDate
  • getNewsExtraContent
  • getNewsID
  • getNewsImageTags
  • getNewsIndexURL
  • getNewsLink
  • getNewsPagesStatistic
  • getNewsPathNav
  • getNewsReadMore
  • getNewsTitle
  • getNewsTitleLink
  • getNewsTitlePath
  • getNewsType
  • getNewsURL
  • getNewsVideoContent
  • getNextAlbum
  • getNextAlbumURL
  • getNextImageThumb
  • getNextImageURL
  • getNextNewsPageURL
  • getNextNewsURL
  • getNextPageURL
  • getNextPrevNews
  • getNotViewableAlbums
  • getNotViewableImages
  • getNumAlbums
  • getNumAllSubalbums
  • getNumImages
  • getNumNews
  • getNumPages
  • getNumSubalbums
  • getOpenIDURL
  • getOption
  • getOptionFromDB
  • getOptionList
  • getPageAuthor
  • getPageContent
  • getPageCustomData
  • getPageDate
  • getPageExtraContent
  • getPageID
  • getPageLastChangeDate
  • getPageLinkPath
  • getPageLinkURL
  • getPageNavList
  • getPageNumURL
  • getPageParentID
  • getPageRedirect
  • getPages
  • getPageSelector
  • getPageSortorder
  • getPageTitle
  • getPageTitleLink
  • getPageURL
  • getParentAlbums
  • getParentAlbumsAdmin
  • getParentBreadcrumb
  • getParentItems
  • getParentMenuItems
  • getParentNewsCategories
  • getParentPages
  • getPasswordProtectImage
  • getPHPFiles
  • getPlugin
  • getPluginFiles
  • getPluginTabs
  • getPrevAlbum
  • getPrevAlbumURL
  • getPrevImageThumb
  • getPrevImageURL
  • getPrevNewsPageURL
  • getPrevNewsURL
  • getPrevPageURL
  • getProtectedImageURL
  • getRandomImages
  • getRandomImagesAlbum
  • getRating
  • getRelatedItems
  • getRequestURI
  • getReturnTo
  • getRSSHeaderLink
  • getRSSLink
  • getScheme
  • getSearchDate
  • getSearchURL
  • getSearchWords
  • getSelectedLayout
  • getSerializedArray
  • getSetClause
  • getSiteHomeURL
  • getSitemapAlbumList
  • getSitemapAlbums
  • getSitemapGoogleImageVideoExtras
  • getSitemapGoogleLoopIndex
  • getSitemapImages
  • getSitemapIndexLinks
  • getSitemapZenpageNewsArticles
  • getSitemapZenpageNewsCategories
  • getSitemapZenpageNewsIndex
  • getSitemapZenpagePages
  • getSizeCustomImage
  • getSizeDefaultImage
  • getSizeDefaultThumb
  • getSizedImageURL
  • getSizeFullImage
  • getStore
  • getSubCategories
  • getSubtabs
  • getSuffix
  • getTagCountByAccess
  • getTagOrder
  • getTags
  • gettext_pl
  • gettext_th
  • getTheme
  • getThemeFiles
  • getThemeOption
  • getTimezones
  • getTinyMCE4ConfigFiles
  • getTitle
  • getTotalArticles
  • getTotalImagesIn
  • getTotalNewsPages
  • getTotalPages
  • getTrustRoot
  • getUnprotectedImageURL
  • getUrAlbum
  • getURL
  • getUserIP
  • getUserLocale
  • getVersion
  • getViewerImageSize
  • getWatermarkParam
  • getWatermarkPath
  • getWatermarks
  • getWhereClause
  • getXSRFToken
  • getZenpageHitcounter
  • getZenpageRSSHeaderLink
  • getZenpageRSSLink
  • getZenpageStatistic
  • googleVerifyHead
  • handleSearchParms
  • hasDynamicAlbumSuffix
  • hasNextImage
  • hasNextPage
  • hasPrevImage
  • hasPrevPage
  • hitcounter
  • html_decode
  • html_encode
  • html_encodeTagged
  • httpsRedirect
  • httpUploadHandler
  • httpUploadHandler_admin_tabs
  • i18nSetLocale
  • imageBlurGD
  • imageDebug
  • imageError
  • imageNumber
  • imgSrcURI
  • in_context
  • inNewsCategory
  • inProtectedNewsCategory
  • installSignature
  • instrument
  • inSubNewsCategoryOf
  • internalToFilesystem
  • inventMenuItem
  • iptc_make_tag
  • is_AdminEditPage
  • is_connected
  • is_GalleryNewsType
  • is_News
  • is_NewsArchive
  • is_NewsArticle
  • is_NewsCategory
  • is_NewsPage
  • is_NewsType
  • is_Pages
  • is_valid_email_zp
  • is_valid_image
  • is_valid_other_type
  • is_zip
  • isAlbumClass
  • isAlbumPage
  • isArchive
  • isHandledAlbum
  • isImageClass
  • isImagePage
  • isImagePhoto
  • isImageVideo
  • isLandscape
  • isMyAlbum
  • isMyNews
  • isMyPage
  • isolate
  • isProtectedAlbum
  • isProtectedNewsCategory
  • isProtectedPage
  • isSubNewsCategoryOf
  • isValidURL
  • jQueryUpload_head
  • jQueryUpload_headers
  • jQueryUploadHandler
  • jQueryUploadHandler_admin_tabs
  • js_encode
  • json_decode
  • json_encode
  • kses
  • kses_array_lc
  • kses_attr
  • kses_bad_protocol
  • kses_bad_protocol_once
  • kses_bad_protocol_once2
  • kses_check_attr_val
  • kses_decode_entities
  • kses_hair
  • kses_hook
  • kses_html_error
  • kses_js_entities
  • kses_no_null
  • kses_normalize_entities
  • kses_normalize_entities2
  • kses_split
  • kses_split2
  • kses_stripslashes
  • kses_version
  • ksesProcess
  • layoutSelector
  • layoutSelector_album
  • listDBUses
  • listDirectoryFiles
  • listUses
  • load_zenpage_news
  • load_zenpage_pages
  • loadLocalOptions
  • log_message
  • lookupSortKey
  • macro_admin_tabs
  • macroList_show
  • makeAlbumCurrent
  • makeImageCurrent
  • makeSpecialImageName
  • markRelease_button
  • mb_strlen
  • mb_strpos
  • mb_strrpos
  • mb_strtolower
  • mb_strtoupper
  • mb_substr
  • mb_substr_count
  • menu_admin_toolbox_global
  • menu_tabs
  • minDiff
  • mkdir_recursive
  • my_truncate_string
  • myts_date
  • newAlbum
  • newImage
  • next_album
  • next_comment
  • next_image
  • next_news
  • next_page
  • ngettext_pl
  • ngettext_th
  • normalizeColumns
  • omsAdditions
  • openedForComments
  • parse_query
  • parse_size
  • parseAllowedTags
  • parseHttpAcceptLanguage
  • passAlbums
  • passImages
  • pathurlencode
  • PclZipUtilCopyBlock
  • PclZipUtilOptionText
  • PclZipUtilPathInclusion
  • PclZipUtilPathReduction
  • PclZipUtilRename
  • PclZipUtilTranslateWinPath
  • PHPMailerAutoload
  • populateManagedObjectsList
  • postAlbumSort
  • postIndexDecode
  • postIndexEncode
  • prefix
  • prepareAlbumPage
  • prepareCustomPage
  • prepareImagePage
  • prepareIndexPage
  • print404status
  • print_language_string_list
  • printAddToFavorites
  • printAdminFooter
  • printAdminHeader
  • printAdminRightsTable
  • printAdminToolbox
  • printAlbumBreadcrumb
  • printAlbumButtons
  • printAlbumCustomData
  • printAlbumData
  • printAlbumDate
  • printAlbumDesc
  • printAlbumEditForm
  • printAlbumEditRow
  • printAlbumLegend
  • printAlbumLink
  • printAlbumLocation
  • printAlbumMap
  • printAlbumMenu
  • printAlbumMenuJump
  • printAlbumMenuList
  • printAlbumMenuListAlbum
  • printAlbumPlace
  • printAlbumRating
  • printAlbumsSelector
  • printAlbumStatistic
  • printAlbumStatisticItem
  • printAlbumThumbImage
  • printAlbumTitle
  • printAlbumURL
  • printAlbumZip
  • printAllDates
  • printAllNewsCategories
  • printAllTags
  • printAllTagsAs
  • printAllTagsFromAlbum
  • printAllTagsFromZenpage
  • printAnnotatedAlbumTitle
  • printAnnotatedImageTitle
  • printArticleCategories
  • printArticleDatesDropdown
  • printArticlesPerPageDropdown
  • printBareAlbumDesc
  • printBareAlbumTitle
  • printBareGalleryDesc
  • printBareGalleryTitle
  • printBareImageDesc
  • printBareImageTitle
  • printBareNewsTitle
  • printBarePageTitle
  • printBulkActions
  • printCaptcha
  • printCategoriesStatistic
  • printCategoryCheckboxListEntry
  • printCategoryDropdown
  • printCategoryListSortableTable
  • printCategorySelection
  • printCodeblock
  • printCodeblockEdit
  • printCommentAuthorLink
  • printCommentErrors
  • printCommentForm
  • printContactForm
  • printCurrentNewsArchive
  • printCurrentNewsCategory
  • printCustomAlbumThumbImage
  • printCustomAlbumThumbMaxSpace
  • printCustomMenu
  • printCustomPageSelector
  • printCustomPageURL
  • printCustomSizedImage
  • printCustomSizedImageMaxHeight
  • printCustomSizedImageMaxSpace
  • printCustomSizedImageThumbMaxSpace
  • printDefaultSizedImage
  • printDownloadAlbumZipURL
  • printDownloadLink
  • printDownloadLinkAlbumZip
  • printdownloadList
  • printDownloadURL
  • printEditable
  • printEditCommentLink
  • printEditDropdown
  • printExpired
  • printFavoritesLink
  • printFavoritesURL
  • printField
  • printGalleryDesc
  • printGalleryIndexURL
  • printGalleryTitle
  • printGoogleMap
  • printHeadTitle
  • printHomeLink
  • printImageCustomData
  • printImageData
  • printImageDate
  • printImageDesc
  • printImageDiv
  • printImageEXIFData
  • printImageID
  • printImageLink
  • printImageMap
  • printImageMetadata
  • printImageRating
  • printImageSortOrder
  • printImageStatistic
  • printImageThumb
  • printImageTitle
  • printImageURL
  • printItemEditLink
  • printItemsList
  • printItemsListTable
  • printItemStatusDropdown
  • printjCarouselThumbNav
  • printjPlayerPlaylist
  • printLanguageSelector
  • printLatestAlbums
  • printLatestComments
  • printLatestImages
  • printLatestImagesByDate
  • printLatestImagesByMtime
  • printLatestNews
  • printLatestUpdatedAlbums
  • printLatestZenpageComments
  • printLink
  • printLinkHTML
  • printLogoAndLinks
  • printManagedObjects
  • printMenuemanagerPageList
  • printMenuemanagerPageListWithNav
  • printMenumanagerBreadcrumb
  • printMenumanagerNextLink
  • printMenumanagerPrevLink
  • printMostPopularItems
  • printMostRatedAlbums
  • printMostRatedImages
  • printMostRatedItems
  • printNestedAlbumsList
  • printNestedItemsList
  • printNestedMenu
  • printNews
  • printNewsArchive
  • printNewsAuthor
  • printNewsCategories
  • printNewsCategoryCustomData
  • printNewsCategoryDesc
  • printNewsCategoryURL
  • printNewsContent
  • printNewsCustomData
  • printNewsDate
  • printNewsExtraContent
  • printNewsImageTags
  • printNewsIndexURL
  • printNewsLink
  • printNewsPageList
  • printNewsPageListWithNav
  • printNewsReadMoreLink
  • printNewsStatistic
  • printNewsTitle
  • printNewsTitleLink
  • printNewsURL
  • printNextNewsLink
  • printNextNewsPageLink
  • printNextPageLink
  • printNextPageURL
  • printPageArticleTags
  • printPageAuthor
  • printPageContent
  • printPageCustomData
  • printPageDate
  • printPagedThumbsNav
  • printPageExtraContent
  • printPageID
  • printPageLastChangeDate
  • printPageLinkURL
  • printPageList
  • printPageListWithNav
  • printPageMenu
  • printPageNav
  • printPageSelector
  • printPagesListTable
  • printPagesStatistic
  • printPageTitle
  • printPageTitleLink
  • printPageURL
  • printParentBreadcrumb
  • printParentPagesBreadcrumb
  • printPasswordForm
  • printPopularAlbums
  • printPopularImages
  • printPreloadScript
  • printPrevNewsLink
  • printPrevNewsPageLink
  • printPrevPageLink
  • printPrevPageURL
  • printPublished
  • printPublishIconLink
  • printRandomImages
  • printRating
  • printRegisterURL
  • printRegistrationForm
  • printRelatedItems
  • printRSSHeaderLink
  • printRSSLink
  • printSearchBreadcrumb
  • printSearchForm
  • printSiteHomeURL
  • printSizedImageLink
  • printSizedImageURL
  • printSlideShow
  • printSlideShowJS
  • printSlideShowLink
  • printSortableHead
  • printSortOrderDropdown
  • printSubPagesExcerpts
  • printSubtabs
  • printTabs
  • printTags
  • printThumbNav
  • printTopRatedAlbums
  • printTopRatedImages
  • printTopRatedItems
  • printUnpublishedDropdown
  • printUserLogin_out
  • printUserSizeImage
  • printUserSizeSelector
  • printVersion
  • printZenJavascripts
  • printZenpageIconLegend
  • printZenpageItemsBreadcrumb
  • printZenpageNewsCategorySelector
  • printZenpagePagesSelector
  • printZenpageRSSHeaderLink
  • printZenpageRSSLink
  • printZenpageStatistic
  • printZenphotoLink
  • process_language_string_save
  • processAlbumBulkActions
  • processAlbumEdit
  • processCodeblockSave
  • processCommentBulkActions
  • processCredentials
  • processCustomOptionSave
  • processEditSelection
  • processExpired
  • processImageBulkActions
  • processImageEdit
  • processManagedObjects
  • processMenuBulkActions
  • processOrder
  • processRights
  • processTags
  • processZenpageBulkActions
  • propSizes
  • publishItem
  • purgeOption
  • query
  • query_full_array
  • query_single_row
  • rc4
  • read_exif_data_protected
  • readTags
  • recaptcha_check_answer
  • recaptcha_get_html
  • recaptcha_get_signup_url
  • recaptcha_mailhide_html
  • recaptcha_mailhide_url
  • reconfigureAction
  • reconfigureCS
  • reconfigurePage
  • recordMissing
  • rem_context
  • removeParentAlbumNames
  • resetCurrentAlbum
  • restore_context
  • reveal
  • rewrite_get_album_image
  • rewrite_path
  • rewrite_path_zenpage
  • RSS_Channel
  • RSS_Retrieve
  • RSS_Tags
  • rulesList
  • run
  • safe_fnmatch
  • safe_glob
  • sanitize
  • sanitize_numeric
  • sanitize_path
  • sanitize_script
  • sanitize_string
  • sanitizeRedirect
  • save_context
  • saveLayoutSelection
  • saveZenphotoLayoutSelection
  • search_quote
  • secureServer
  • seo_cleanup_button
  • seoFriendly
  • seoFriendlyJS
  • set_context
  • setAlbumCustomData
  • setAlbumSubtabs
  • setImageCustomData
  • setMainDomain
  • setOption
  • setOptionDefault
  • setPluginDomain
  • setThemeColumns
  • setThemeDomain
  • setThemeOption
  • setThemeOptionDefault
  • setupAllowedMaps
  • setupCurrentLocale
  • setupDomain
  • setupTheme
  • shortenContent
  • showOrNotShowField
  • shuffle_assoc
  • signatureChange
  • site_upgrade_button
  • site_upgrade_status
  • sitemap_echonl
  • sitemap_getChangefreq
  • sitemap_getDateformat
  • sitemap_getDBLimit
  • sitemap_getISO8601Date
  • skipScheduledPublishing
  • sortByKey
  • sortByMultilingual
  • sortMultiArray
  • standardScripts
  • standardThemeOptions
  • stickyNews
  • storeConfig
  • storeTags
  • stripSuffix
  • submenuOf
  • switchLog
  • tagSelector
  • tagSuggestJS
  • tagSuggestJS_admin
  • tagSuggestJS_frontend
  • themeIsEditable
  • themeSetup
  • timezoneDiff
  • tinymce4ConfigJS
  • truncate_string
  • unpublishedZenphotoItemCheck
  • unpublishSubalbums
  • unQuote
  • unzip
  • updateArticle
  • updateCacheName
  • updateCategory
  • updateConfigItem
  • updateItemSortorder
  • updateItemsSortorder
  • updateMenuItem
  • updatePage
  • upload_extra
  • upload_form
  • upload_head
  • user_mailing_list_button
  • validateLocale
  • wordpress_import_button
  • wp_prefix
  • wp_query_full_array
  • wpimport_TryAgainError
  • XSRFdefender
  • XSRFToken
  • zenJavascript
  • zenpageAlbumImage
  • zenpageBulkActionMessage
  • zenpageHitcounter
  • zenpageJSCSS
  • zenpageOpenedForComments
  • zenpagePublish
  • zenphoto_PHPMailer
  • zenphoto_sendmail
  • zenPhotoTheme
  • zp_apply_filter
  • zp_clearCookie
  • zp_colorAllocate
  • zp_cookieEncode
  • zp_copyCanvas
  • zp_createImage
  • zp_drawRectangle
  • zp_error
  • zp_filter_slot
  • zp_filter_unique_id
  • zp_getCookie
  • zp_getFonts
  • zp_graphicsLibInfo
  • zp_handle_password
  • zp_handle_password_single
  • zp_has_filter
  • zp_image_types
  • zp_imageCanRotate
  • zp_imageColorTransparent
  • zp_imageDims
  • zp_imageFill
  • zp_imageFontHeight
  • zp_imageFontWidth
  • zp_imageFromString
  • zp_imageGet
  • zp_imageGray
  • zp_imageHeight
  • zp_imageIPTC
  • zp_imageKill
  • zp_imageLoadFont
  • zp_imageMerge
  • zp_imageOutput
  • zp_imageResizeAlpha
  • zp_imageUnsharpMask
  • zp_imageWidth
  • zp_load_album
  • zp_load_gallery
  • zp_load_image
  • zp_load_page
  • zp_load_request
  • zp_load_search
  • zp_loggedin
  • zp_mail
  • zp_register_filter
  • zp_remove_filter
  • zp_resampleImage
  • zp_rotateImage
  • zp_session_start
  • zp_setCookie
  • zp_writeString
  • zpErrorHandler
  • zpFormattedDate
  • zpRewriteURL
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
   1: <?php
   2: /////////////////////////////////////////////////////////////////
   3: /// getID3() by James Heinrich <info@getid3.org>               //
   4: //  available at http://getid3.sourceforge.net                 //
   5: //            or http://www.getid3.org                         //
   6: //          also https://github.com/JamesHeinrich/getID3       //
   7: /////////////////////////////////////////////////////////////////
   8: // See readme.txt for more details                             //
   9: /////////////////////////////////////////////////////////////////
  10: //                                                             //
  11: // module.audio-video.quicktime.php                            //
  12: // module for analyzing Quicktime and MP3-in-MP4 files         //
  13: // dependencies: module.audio.mp3.php                          //
  14: // dependencies: module.tag.id3v2.php                          //
  15: //                                                            ///
  16: /////////////////////////////////////////////////////////////////
  17: 
  18: getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
  19: getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); // needed for ISO 639-2 language code lookup
  20: 
  21: class getid3_quicktime extends getid3_handler
  22: {
  23: 
  24:     public $ReturnAtomData        = true;
  25:     public $ParseAllPossibleAtoms = false;
  26: 
  27:     public function Analyze() {
  28:         $info = &$this->getid3->info;
  29: 
  30:         $info['fileformat'] = 'quicktime';
  31:         $info['quicktime']['hinting']    = false;
  32:         $info['quicktime']['controller'] = 'standard'; // may be overridden if 'ctyp' atom is present
  33: 
  34:         $this->fseek($info['avdataoffset']);
  35: 
  36:         $offset      = 0;
  37:         $atomcounter = 0;
  38:         $atom_data_read_buffer_size = ($info['php_memory_limit'] ? round($info['php_memory_limit'] / 2) : $this->getid3->option_fread_buffer_size * 1024); // allow [default: 32MB] if PHP configured with no memory_limit
  39:         while ($offset < $info['avdataend']) {
  40:             if (!getid3_lib::intValueSupported($offset)) {
  41:                 $info['error'][] = 'Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
  42:                 break;
  43:             }
  44:             $this->fseek($offset);
  45:             $AtomHeader = $this->fread(8);
  46: 
  47:             $atomsize = getid3_lib::BigEndian2Int(substr($AtomHeader, 0, 4));
  48:             $atomname = substr($AtomHeader, 4, 4);
  49: 
  50:             // 64-bit MOV patch by jlegateØktnc*com
  51:             if ($atomsize == 1) {
  52:                 $atomsize = getid3_lib::BigEndian2Int($this->fread(8));
  53:             }
  54: 
  55:             $info['quicktime'][$atomname]['name']   = $atomname;
  56:             $info['quicktime'][$atomname]['size']   = $atomsize;
  57:             $info['quicktime'][$atomname]['offset'] = $offset;
  58: 
  59:             if (($offset + $atomsize) > $info['avdataend']) {
  60:                 $info['error'][] = 'Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)';
  61:                 return false;
  62:             }
  63: 
  64:             if ($atomsize == 0) {
  65:                 // Furthermore, for historical reasons the list of atoms is optionally
  66:                 // terminated by a 32-bit integer set to 0. If you are writing a program
  67:                 // to read user data atoms, you should allow for the terminating 0.
  68:                 break;
  69:             }
  70:             $atomHierarchy = array();
  71:             $info['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, $atom_data_read_buffer_size)), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms);
  72: 
  73:             $offset += $atomsize;
  74:             $atomcounter++;
  75:         }
  76: 
  77:         if (!empty($info['avdataend_tmp'])) {
  78:             // this value is assigned to a temp value and then erased because
  79:             // otherwise any atoms beyond the 'mdat' atom would not get parsed
  80:             $info['avdataend'] = $info['avdataend_tmp'];
  81:             unset($info['avdataend_tmp']);
  82:         }
  83: 
  84:         if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) {
  85:             $info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
  86:         }
  87:         if (isset($info['bitrate']) && !isset($info['audio']['bitrate']) && !isset($info['quicktime']['video'])) {
  88:             $info['audio']['bitrate'] = $info['bitrate'];
  89:         }
  90:         if (!empty($info['playtime_seconds']) && !isset($info['video']['frame_rate']) && !empty($info['quicktime']['stts_framecount'])) {
  91:             foreach ($info['quicktime']['stts_framecount'] as $key => $samples_count) {
  92:                 $samples_per_second = $samples_count / $info['playtime_seconds'];
  93:                 if ($samples_per_second > 240) {
  94:                     // has to be audio samples
  95:                 } else {
  96:                     $info['video']['frame_rate'] = $samples_per_second;
  97:                     break;
  98:                 }
  99:             }
 100:         }
 101:         if (($info['audio']['dataformat'] == 'mp4') && empty($info['video']['resolution_x'])) {
 102:             $info['fileformat'] = 'mp4';
 103:             $info['mime_type']  = 'audio/mp4';
 104:             unset($info['video']['dataformat']);
 105:         }
 106: 
 107:         if (!$this->ReturnAtomData) {
 108:             unset($info['quicktime']['moov']);
 109:         }
 110: 
 111:         if (empty($info['audio']['dataformat']) && !empty($info['quicktime']['audio'])) {
 112:             $info['audio']['dataformat'] = 'quicktime';
 113:         }
 114:         if (empty($info['video']['dataformat']) && !empty($info['quicktime']['video'])) {
 115:             $info['video']['dataformat'] = 'quicktime';
 116:         }
 117: 
 118:         return true;
 119:     }
 120: 
 121:     public function QuicktimeParseAtom($atomname, $atomsize, $atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
 122:         // http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm
 123:         // https://code.google.com/p/mp4v2/wiki/iTunesMetadata
 124: 
 125:         $info = &$this->getid3->info;
 126: 
 127:         $atom_parent = end($atomHierarchy); // not array_pop($atomHierarchy); see http://www.getid3.org/phpBB3/viewtopic.php?t=1717
 128:         array_push($atomHierarchy, $atomname);
 129:         $atom_structure['hierarchy'] = implode(' ', $atomHierarchy);
 130:         $atom_structure['name']      = $atomname;
 131:         $atom_structure['size']      = $atomsize;
 132:         $atom_structure['offset']    = $baseoffset;
 133:         switch ($atomname) {
 134:             case 'moov': // MOVie container atom
 135:             case 'trak': // TRAcK container atom
 136:             case 'clip': // CLIPping container atom
 137:             case 'matt': // track MATTe container atom
 138:             case 'edts': // EDiTS container atom
 139:             case 'tref': // Track REFerence container atom
 140:             case 'mdia': // MeDIA container atom
 141:             case 'minf': // Media INFormation container atom
 142:             case 'dinf': // Data INFormation container atom
 143:             case 'udta': // User DaTA container atom
 144:             case 'cmov': // Compressed MOVie container atom
 145:             case 'rmra': // Reference Movie Record Atom
 146:             case 'rmda': // Reference Movie Descriptor Atom
 147:             case 'gmhd': // Generic Media info HeaDer atom (seen on QTVR)
 148:                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
 149:                 break;
 150: 
 151:             case 'ilst': // Item LiST container atom
 152:                 if ($atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms)) {
 153:                     // some "ilst" atoms contain data atoms that have a numeric name, and the data is far more accessible if the returned array is compacted
 154:                     $allnumericnames = true;
 155:                     foreach ($atom_structure['subatoms'] as $subatomarray) {
 156:                         if (!is_integer($subatomarray['name']) || (count($subatomarray['subatoms']) != 1)) {
 157:                             $allnumericnames = false;
 158:                             break;
 159:                         }
 160:                     }
 161:                     if ($allnumericnames) {
 162:                         $newData = array();
 163:                         foreach ($atom_structure['subatoms'] as $subatomarray) {
 164:                             foreach ($subatomarray['subatoms'] as $newData_subatomarray) {
 165:                                 unset($newData_subatomarray['hierarchy'], $newData_subatomarray['name']);
 166:                                 $newData[$subatomarray['name']] = $newData_subatomarray;
 167:                                 break;
 168:                             }
 169:                         }
 170:                         $atom_structure['data'] = $newData;
 171:                         unset($atom_structure['subatoms']);
 172:                     }
 173:                 }
 174:                 break;
 175: 
 176:             case "\x00\x00\x00\x01":
 177:             case "\x00\x00\x00\x02":
 178:             case "\x00\x00\x00\x03":
 179:             case "\x00\x00\x00\x04":
 180:             case "\x00\x00\x00\x05":
 181:                 $atomname = getid3_lib::BigEndian2Int($atomname);
 182:                 $atom_structure['name'] = $atomname;
 183:                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
 184:                 break;
 185: 
 186:             case 'stbl': // Sample TaBLe container atom
 187:                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
 188:                 $isVideo = false;
 189:                 $framerate  = 0;
 190:                 $framecount = 0;
 191:                 foreach ($atom_structure['subatoms'] as $key => $value_array) {
 192:                     if (isset($value_array['sample_description_table'])) {
 193:                         foreach ($value_array['sample_description_table'] as $key2 => $value_array2) {
 194:                             if (isset($value_array2['data_format'])) {
 195:                                 switch ($value_array2['data_format']) {
 196:                                     case 'avc1':
 197:                                     case 'mp4v':
 198:                                         // video data
 199:                                         $isVideo = true;
 200:                                         break;
 201:                                     case 'mp4a':
 202:                                         // audio data
 203:                                         break;
 204:                                 }
 205:                             }
 206:                         }
 207:                     } elseif (isset($value_array['time_to_sample_table'])) {
 208:                         foreach ($value_array['time_to_sample_table'] as $key2 => $value_array2) {
 209:                             if (isset($value_array2['sample_count']) && isset($value_array2['sample_duration']) && ($value_array2['sample_duration'] > 0)) {
 210:                                 $framerate  = round($info['quicktime']['time_scale'] / $value_array2['sample_duration'], 3);
 211:                                 $framecount = $value_array2['sample_count'];
 212:                             }
 213:                         }
 214:                     }
 215:                 }
 216:                 if ($isVideo && $framerate) {
 217:                     $info['quicktime']['video']['frame_rate'] = $framerate;
 218:                     $info['video']['frame_rate'] = $info['quicktime']['video']['frame_rate'];
 219:                 }
 220:                 if ($isVideo && $framecount) {
 221:                     $info['quicktime']['video']['frame_count'] = $framecount;
 222:                 }
 223:                 break;
 224: 
 225: 
 226:             case "\xA9".'alb': // ALBum
 227:             case "\xA9".'ART': //
 228:             case "\xA9".'art': // ARTist
 229:             case "\xA9".'aut': //
 230:             case "\xA9".'cmt': // CoMmenT
 231:             case "\xA9".'com': // COMposer
 232:             case "\xA9".'cpy': //
 233:             case "\xA9".'day': // content created year
 234:             case "\xA9".'dir': //
 235:             case "\xA9".'ed1': //
 236:             case "\xA9".'ed2': //
 237:             case "\xA9".'ed3': //
 238:             case "\xA9".'ed4': //
 239:             case "\xA9".'ed5': //
 240:             case "\xA9".'ed6': //
 241:             case "\xA9".'ed7': //
 242:             case "\xA9".'ed8': //
 243:             case "\xA9".'ed9': //
 244:             case "\xA9".'enc': //
 245:             case "\xA9".'fmt': //
 246:             case "\xA9".'gen': // GENre
 247:             case "\xA9".'grp': // GRouPing
 248:             case "\xA9".'hst': //
 249:             case "\xA9".'inf': //
 250:             case "\xA9".'lyr': // LYRics
 251:             case "\xA9".'mak': //
 252:             case "\xA9".'mod': //
 253:             case "\xA9".'nam': // full NAMe
 254:             case "\xA9".'ope': //
 255:             case "\xA9".'PRD': //
 256:             case "\xA9".'prf': //
 257:             case "\xA9".'req': //
 258:             case "\xA9".'src': //
 259:             case "\xA9".'swr': //
 260:             case "\xA9".'too': // encoder
 261:             case "\xA9".'trk': // TRacK
 262:             case "\xA9".'url': //
 263:             case "\xA9".'wrn': //
 264:             case "\xA9".'wrt': // WRiTer
 265:             case '----': // itunes specific
 266:             case 'aART': // Album ARTist
 267:             case 'akID': // iTunes store account type
 268:             case 'apID': // Purchase Account
 269:             case 'atID': //
 270:             case 'catg': // CaTeGory
 271:             case 'cmID': //
 272:             case 'cnID': //
 273:             case 'covr': // COVeR artwork
 274:             case 'cpil': // ComPILation
 275:             case 'cprt': // CoPyRighT
 276:             case 'desc': // DESCription
 277:             case 'disk': // DISK number
 278:             case 'egid': // Episode Global ID
 279:             case 'geID': //
 280:             case 'gnre': // GeNRE
 281:             case 'hdvd': // HD ViDeo
 282:             case 'keyw': // KEYWord
 283:             case 'ldes': // Long DEScription
 284:             case 'pcst': // PodCaST
 285:             case 'pgap': // GAPless Playback
 286:             case 'plID': //
 287:             case 'purd': // PURchase Date
 288:             case 'purl': // Podcast URL
 289:             case 'rati': //
 290:             case 'rndu': //
 291:             case 'rpdu': //
 292:             case 'rtng': // RaTiNG
 293:             case 'sfID': // iTunes store country
 294:             case 'soaa': // SOrt Album Artist
 295:             case 'soal': // SOrt ALbum
 296:             case 'soar': // SOrt ARtist
 297:             case 'soco': // SOrt COmposer
 298:             case 'sonm': // SOrt NaMe
 299:             case 'sosn': // SOrt Show Name
 300:             case 'stik': //
 301:             case 'tmpo': // TeMPO (BPM)
 302:             case 'trkn': // TRacK Number
 303:             case 'tven': // tvEpisodeID
 304:             case 'tves': // TV EpiSode
 305:             case 'tvnn': // TV Network Name
 306:             case 'tvsh': // TV SHow Name
 307:             case 'tvsn': // TV SeasoN
 308:                 if ($atom_parent == 'udta') {
 309:                     // User data atom handler
 310:                     $atom_structure['data_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2));
 311:                     $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2));
 312:                     $atom_structure['data']        =                           substr($atom_data, 4);
 313: 
 314:                     $atom_structure['language']    = $this->QuicktimeLanguageLookup($atom_structure['language_id']);
 315:                     if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) {
 316:                         $info['comments']['language'][] = $atom_structure['language'];
 317:                     }
 318:                 } else {
 319:                     // Apple item list box atom handler
 320:                     $atomoffset = 0;
 321:                     if (substr($atom_data, 2, 2) == "\x10\xB5") {
 322:                         // not sure what it means, but observed on iPhone4 data.
 323:                         // Each $atom_data has 2 bytes of datasize, plus 0x10B5, then data
 324:                         while ($atomoffset < strlen($atom_data)) {
 325:                             $boxsmallsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset,     2));
 326:                             $boxsmalltype =                           substr($atom_data, $atomoffset + 2, 2);
 327:                             $boxsmalldata =                           substr($atom_data, $atomoffset + 4, $boxsmallsize);
 328:                             if ($boxsmallsize <= 1) {
 329:                                 $info['warning'][] = 'Invalid QuickTime atom smallbox size "'.$boxsmallsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset);
 330:                                 $atom_structure['data'] = null;
 331:                                 $atomoffset = strlen($atom_data);
 332:                                 break;
 333:                             }
 334:                             switch ($boxsmalltype) {
 335:                                 case "\x10\xB5":
 336:                                     $atom_structure['data'] = $boxsmalldata;
 337:                                     break;
 338:                                 default:
 339:                                     $info['warning'][] = 'Unknown QuickTime smallbox type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxsmalltype).'" ('.trim(getid3_lib::PrintHexBytes($boxsmalltype)).') at offset '.$baseoffset;
 340:                                     $atom_structure['data'] = $atom_data;
 341:                                     break;
 342:                             }
 343:                             $atomoffset += (4 + $boxsmallsize);
 344:                         }
 345:                     } else {
 346:                         while ($atomoffset < strlen($atom_data)) {
 347:                             $boxsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset, 4));
 348:                             $boxtype =                           substr($atom_data, $atomoffset + 4, 4);
 349:                             $boxdata =                           substr($atom_data, $atomoffset + 8, $boxsize - 8);
 350:                             if ($boxsize <= 1) {
 351:                                 $info['warning'][] = 'Invalid QuickTime atom box size "'.$boxsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset);
 352:                                 $atom_structure['data'] = null;
 353:                                 $atomoffset = strlen($atom_data);
 354:                                 break;
 355:                             }
 356:                             $atomoffset += $boxsize;
 357: 
 358:                             switch ($boxtype) {
 359:                                 case 'mean':
 360:                                 case 'name':
 361:                                     $atom_structure[$boxtype] = substr($boxdata, 4);
 362:                                     break;
 363: 
 364:                                 case 'data':
 365:                                     $atom_structure['version']   = getid3_lib::BigEndian2Int(substr($boxdata,  0, 1));
 366:                                     $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($boxdata,  1, 3));
 367:                                     switch ($atom_structure['flags_raw']) {
 368:                                         case  0: // data flag
 369:                                         case 21: // tmpo/cpil flag
 370:                                             switch ($atomname) {
 371:                                                 case 'cpil':
 372:                                                 case 'hdvd':
 373:                                                 case 'pcst':
 374:                                                 case 'pgap':
 375:                                                     // 8-bit integer (boolean)
 376:                                                     $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
 377:                                                     break;
 378: 
 379:                                                 case 'tmpo':
 380:                                                     // 16-bit integer
 381:                                                     $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 2));
 382:                                                     break;
 383: 
 384:                                                 case 'disk':
 385:                                                 case 'trkn':
 386:                                                     // binary
 387:                                                     $num       = getid3_lib::BigEndian2Int(substr($boxdata, 10, 2));
 388:                                                     $num_total = getid3_lib::BigEndian2Int(substr($boxdata, 12, 2));
 389:                                                     $atom_structure['data']  = empty($num) ? '' : $num;
 390:                                                     $atom_structure['data'] .= empty($num_total) ? '' : '/'.$num_total;
 391:                                                     break;
 392: 
 393:                                                 case 'gnre':
 394:                                                     // enum
 395:                                                     $GenreID = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
 396:                                                     $atom_structure['data']    = getid3_id3v1::LookupGenreName($GenreID - 1);
 397:                                                     break;
 398: 
 399:                                                 case 'rtng':
 400:                                                     // 8-bit integer
 401:                                                     $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
 402:                                                     $atom_structure['data']    = $this->QuicktimeContentRatingLookup($atom_structure[$atomname]);
 403:                                                     break;
 404: 
 405:                                                 case 'stik':
 406:                                                     // 8-bit integer (enum)
 407:                                                     $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
 408:                                                     $atom_structure['data']    = $this->QuicktimeSTIKLookup($atom_structure[$atomname]);
 409:                                                     break;
 410: 
 411:                                                 case 'sfID':
 412:                                                     // 32-bit integer
 413:                                                     $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
 414:                                                     $atom_structure['data']    = $this->QuicktimeStoreFrontCodeLookup($atom_structure[$atomname]);
 415:                                                     break;
 416: 
 417:                                                 case 'egid':
 418:                                                 case 'purl':
 419:                                                     $atom_structure['data'] = substr($boxdata, 8);
 420:                                                     break;
 421: 
 422:                                                 case 'plID':
 423:                                                     // 64-bit integer
 424:                                                     $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 8));
 425:                                                     break;
 426: 
 427:                                                 case 'atID':
 428:                                                 case 'cnID':
 429:                                                 case 'geID':
 430:                                                 case 'tves':
 431:                                                 case 'tvsn':
 432:                                                 default:
 433:                                                     // 32-bit integer
 434:                                                     $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
 435:                                             }
 436:                                             break;
 437: 
 438:                                         case  1: // text flag
 439:                                         case 13: // image flag
 440:                                         default:
 441:                                             $atom_structure['data'] = substr($boxdata, 8);
 442:                                             if ($atomname == 'covr') {
 443:                                                 // not a foolproof check, but better than nothing
 444:                                                 if (preg_match('#^\xFF\xD8\xFF#', $atom_structure['data'])) {
 445:                                                     $atom_structure['image_mime'] = 'image/jpeg';
 446:                                                 } elseif (preg_match('#^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A#', $atom_structure['data'])) {
 447:                                                     $atom_structure['image_mime'] = 'image/png';
 448:                                                 } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
 449:                                                     $atom_structure['image_mime'] = 'image/gif';
 450:                                                 }
 451:                                             }
 452:                                             break;
 453: 
 454:                                     }
 455:                                     break;
 456: 
 457:                                 default:
 458:                                     $info['warning'][] = 'Unknown QuickTime box type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxtype).'" ('.trim(getid3_lib::PrintHexBytes($boxtype)).') at offset '.$baseoffset;
 459:                                     $atom_structure['data'] = $atom_data;
 460: 
 461:                             }
 462:                         }
 463:                     }
 464:                 }
 465:                 $this->CopyToAppropriateCommentsSection($atomname, $atom_structure['data'], $atom_structure['name']);
 466:                 break;
 467: 
 468: 
 469:             case 'play': // auto-PLAY atom
 470:                 $atom_structure['autoplay'] = (bool) getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 471: 
 472:                 $info['quicktime']['autoplay'] = $atom_structure['autoplay'];
 473:                 break;
 474: 
 475: 
 476:             case 'WLOC': // Window LOCation atom
 477:                 $atom_structure['location_x']  = getid3_lib::BigEndian2Int(substr($atom_data,  0, 2));
 478:                 $atom_structure['location_y']  = getid3_lib::BigEndian2Int(substr($atom_data,  2, 2));
 479:                 break;
 480: 
 481: 
 482:             case 'LOOP': // LOOPing atom
 483:             case 'SelO': // play SELection Only atom
 484:             case 'AllF': // play ALL Frames atom
 485:                 $atom_structure['data'] = getid3_lib::BigEndian2Int($atom_data);
 486:                 break;
 487: 
 488: 
 489:             case 'name': //
 490:             case 'MCPS': // Media Cleaner PRo
 491:             case '@PRM': // adobe PReMiere version
 492:             case '@PRQ': // adobe PRemiere Quicktime version
 493:                 $atom_structure['data'] = $atom_data;
 494:                 break;
 495: 
 496: 
 497:             case 'cmvd': // Compressed MooV Data atom
 498:                 // Code by ubergeekØubergeek*tv based on information from
 499:                 // http://developer.apple.com/quicktime/icefloe/dispatch012.html
 500:                 $atom_structure['unCompressedSize'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4));
 501: 
 502:                 $CompressedFileData = substr($atom_data, 4);
 503:                 if ($UncompressedHeader = @gzuncompress($CompressedFileData)) {
 504:                     $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($UncompressedHeader, 0, $atomHierarchy, $ParseAllPossibleAtoms);
 505:                 } else {
 506:                     $info['warning'][] = 'Error decompressing compressed MOV atom at offset '.$atom_structure['offset'];
 507:                 }
 508:                 break;
 509: 
 510: 
 511:             case 'dcom': // Data COMpression atom
 512:                 $atom_structure['compression_id']   = $atom_data;
 513:                 $atom_structure['compression_text'] = $this->QuicktimeDCOMLookup($atom_data);
 514:                 break;
 515: 
 516: 
 517:             case 'rdrf': // Reference movie Data ReFerence atom
 518:                 $atom_structure['version']                = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 519:                 $atom_structure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3));
 520:                 $atom_structure['flags']['internal_data'] = (bool) ($atom_structure['flags_raw'] & 0x000001);
 521: 
 522:                 $atom_structure['reference_type_name']    =                           substr($atom_data,  4, 4);
 523:                 $atom_structure['reference_length']       = getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
 524:                 switch ($atom_structure['reference_type_name']) {
 525:                     case 'url ':
 526:                         $atom_structure['url']            =       $this->NoNullString(substr($atom_data, 12));
 527:                         break;
 528: 
 529:                     case 'alis':
 530:                         $atom_structure['file_alias']     =                           substr($atom_data, 12);
 531:                         break;
 532: 
 533:                     case 'rsrc':
 534:                         $atom_structure['resource_alias'] =                           substr($atom_data, 12);
 535:                         break;
 536: 
 537:                     default:
 538:                         $atom_structure['data']           =                           substr($atom_data, 12);
 539:                         break;
 540:                 }
 541:                 break;
 542: 
 543: 
 544:             case 'rmqu': // Reference Movie QUality atom
 545:                 $atom_structure['movie_quality'] = getid3_lib::BigEndian2Int($atom_data);
 546:                 break;
 547: 
 548: 
 549:             case 'rmcs': // Reference Movie Cpu Speed atom
 550:                 $atom_structure['version']          = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 551:                 $atom_structure['flags_raw']        = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 552:                 $atom_structure['cpu_speed_rating'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2));
 553:                 break;
 554: 
 555: 
 556:             case 'rmvc': // Reference Movie Version Check atom
 557:                 $atom_structure['version']            = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 558:                 $atom_structure['flags_raw']          = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 559:                 $atom_structure['gestalt_selector']   =                           substr($atom_data,  4, 4);
 560:                 $atom_structure['gestalt_value_mask'] = getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
 561:                 $atom_structure['gestalt_value']      = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4));
 562:                 $atom_structure['gestalt_check_type'] = getid3_lib::BigEndian2Int(substr($atom_data, 14, 2));
 563:                 break;
 564: 
 565: 
 566:             case 'rmcd': // Reference Movie Component check atom
 567:                 $atom_structure['version']                = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 568:                 $atom_structure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 569:                 $atom_structure['component_type']         =                           substr($atom_data,  4, 4);
 570:                 $atom_structure['component_subtype']      =                           substr($atom_data,  8, 4);
 571:                 $atom_structure['component_manufacturer'] =                           substr($atom_data, 12, 4);
 572:                 $atom_structure['component_flags_raw']    = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4));
 573:                 $atom_structure['component_flags_mask']   = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4));
 574:                 $atom_structure['component_min_version']  = getid3_lib::BigEndian2Int(substr($atom_data, 24, 4));
 575:                 break;
 576: 
 577: 
 578:             case 'rmdr': // Reference Movie Data Rate atom
 579:                 $atom_structure['version']       = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 580:                 $atom_structure['flags_raw']     = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 581:                 $atom_structure['data_rate']     = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 582: 
 583:                 $atom_structure['data_rate_bps'] = $atom_structure['data_rate'] * 10;
 584:                 break;
 585: 
 586: 
 587:             case 'rmla': // Reference Movie Language Atom
 588:                 $atom_structure['version']     = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 589:                 $atom_structure['flags_raw']   = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 590:                 $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2));
 591: 
 592:                 $atom_structure['language']    = $this->QuicktimeLanguageLookup($atom_structure['language_id']);
 593:                 if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) {
 594:                     $info['comments']['language'][] = $atom_structure['language'];
 595:                 }
 596:                 break;
 597: 
 598: 
 599:             case 'rmla': // Reference Movie Language Atom
 600:                 $atom_structure['version']   = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 601:                 $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 602:                 $atom_structure['track_id']  = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2));
 603:                 break;
 604: 
 605: 
 606:             case 'ptv ': // Print To Video - defines a movie's full screen mode
 607:                 // http://developer.apple.com/documentation/QuickTime/APIREF/SOURCESIV/at_ptv-_pg.htm
 608:                 $atom_structure['display_size_raw']  = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2));
 609:                 $atom_structure['reserved_1']        = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2)); // hardcoded: 0x0000
 610:                 $atom_structure['reserved_2']        = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); // hardcoded: 0x0000
 611:                 $atom_structure['slide_show_flag']   = getid3_lib::BigEndian2Int(substr($atom_data, 6, 1));
 612:                 $atom_structure['play_on_open_flag'] = getid3_lib::BigEndian2Int(substr($atom_data, 7, 1));
 613: 
 614:                 $atom_structure['flags']['play_on_open'] = (bool) $atom_structure['play_on_open_flag'];
 615:                 $atom_structure['flags']['slide_show']   = (bool) $atom_structure['slide_show_flag'];
 616: 
 617:                 $ptv_lookup[0] = 'normal';
 618:                 $ptv_lookup[1] = 'double';
 619:                 $ptv_lookup[2] = 'half';
 620:                 $ptv_lookup[3] = 'full';
 621:                 $ptv_lookup[4] = 'current';
 622:                 if (isset($ptv_lookup[$atom_structure['display_size_raw']])) {
 623:                     $atom_structure['display_size'] = $ptv_lookup[$atom_structure['display_size_raw']];
 624:                 } else {
 625:                     $info['warning'][] = 'unknown "ptv " display constant ('.$atom_structure['display_size_raw'].')';
 626:                 }
 627:                 break;
 628: 
 629: 
 630:             case 'stsd': // Sample Table Sample Description atom
 631:                 $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 632:                 $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 633:                 $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 634:                 $stsdEntriesDataOffset = 8;
 635:                 for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 636:                     $atom_structure['sample_description_table'][$i]['size']             = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 4));
 637:                     $stsdEntriesDataOffset += 4;
 638:                     $atom_structure['sample_description_table'][$i]['data_format']      =                           substr($atom_data, $stsdEntriesDataOffset, 4);
 639:                     $stsdEntriesDataOffset += 4;
 640:                     $atom_structure['sample_description_table'][$i]['reserved']         = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 6));
 641:                     $stsdEntriesDataOffset += 6;
 642:                     $atom_structure['sample_description_table'][$i]['reference_index']  = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 2));
 643:                     $stsdEntriesDataOffset += 2;
 644:                     $atom_structure['sample_description_table'][$i]['data']             =                           substr($atom_data, $stsdEntriesDataOffset, ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2));
 645:                     $stsdEntriesDataOffset += ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2);
 646: 
 647:                     $atom_structure['sample_description_table'][$i]['encoder_version']  = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  0, 2));
 648:                     $atom_structure['sample_description_table'][$i]['encoder_revision'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  2, 2));
 649:                     $atom_structure['sample_description_table'][$i]['encoder_vendor']   =                           substr($atom_structure['sample_description_table'][$i]['data'],  4, 4);
 650: 
 651:                     switch ($atom_structure['sample_description_table'][$i]['encoder_vendor']) {
 652: 
 653:                         case "\x00\x00\x00\x00":
 654:                             // audio tracks
 655:                             $atom_structure['sample_description_table'][$i]['audio_channels']       =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  8,  2));
 656:                             $atom_structure['sample_description_table'][$i]['audio_bit_depth']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 10,  2));
 657:                             $atom_structure['sample_description_table'][$i]['audio_compression_id'] =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12,  2));
 658:                             $atom_structure['sample_description_table'][$i]['audio_packet_size']    =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 14,  2));
 659:                             $atom_structure['sample_description_table'][$i]['audio_sample_rate']    = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 16,  4));
 660: 
 661:                             // video tracks
 662:                             // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
 663:                             $atom_structure['sample_description_table'][$i]['temporal_quality'] =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  8,  4));
 664:                             $atom_structure['sample_description_table'][$i]['spatial_quality']  =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12,  4));
 665:                             $atom_structure['sample_description_table'][$i]['width']            =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 16,  2));
 666:                             $atom_structure['sample_description_table'][$i]['height']           =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 18,  2));
 667:                             $atom_structure['sample_description_table'][$i]['resolution_x']     = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24,  4));
 668:                             $atom_structure['sample_description_table'][$i]['resolution_y']     = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 28,  4));
 669:                             $atom_structure['sample_description_table'][$i]['data_size']        =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 32,  4));
 670:                             $atom_structure['sample_description_table'][$i]['frame_count']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 36,  2));
 671:                             $atom_structure['sample_description_table'][$i]['compressor_name']  =                             substr($atom_structure['sample_description_table'][$i]['data'], 38,  4);
 672:                             $atom_structure['sample_description_table'][$i]['pixel_depth']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 42,  2));
 673:                             $atom_structure['sample_description_table'][$i]['color_table_id']   =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 44,  2));
 674: 
 675:                             switch ($atom_structure['sample_description_table'][$i]['data_format']) {
 676:                                 case '2vuY':
 677:                                 case 'avc1':
 678:                                 case 'cvid':
 679:                                 case 'dvc ':
 680:                                 case 'dvcp':
 681:                                 case 'gif ':
 682:                                 case 'h263':
 683:                                 case 'jpeg':
 684:                                 case 'kpcd':
 685:                                 case 'mjpa':
 686:                                 case 'mjpb':
 687:                                 case 'mp4v':
 688:                                 case 'png ':
 689:                                 case 'raw ':
 690:                                 case 'rle ':
 691:                                 case 'rpza':
 692:                                 case 'smc ':
 693:                                 case 'SVQ1':
 694:                                 case 'SVQ3':
 695:                                 case 'tiff':
 696:                                 case 'v210':
 697:                                 case 'v216':
 698:                                 case 'v308':
 699:                                 case 'v408':
 700:                                 case 'v410':
 701:                                 case 'yuv2':
 702:                                     $info['fileformat'] = 'mp4';
 703:                                     $info['video']['fourcc'] = $atom_structure['sample_description_table'][$i]['data_format'];
 704: // http://www.getid3.org/phpBB3/viewtopic.php?t=1550
 705: //if ((!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($atom_structure['sample_description_table'][$i]['width'])) && (empty($info['video']['resolution_x']) || empty($info['video']['resolution_y']) || (number_format($info['video']['resolution_x'], 6) != number_format(round($info['video']['resolution_x']), 6)) || (number_format($info['video']['resolution_y'], 6) != number_format(round($info['video']['resolution_y']), 6)))) { // ugly check for floating point numbers
 706: if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($atom_structure['sample_description_table'][$i]['height'])) {
 707:     // assume that values stored here are more important than values stored in [tkhd] atom
 708:     $info['video']['resolution_x'] = $atom_structure['sample_description_table'][$i]['width'];
 709:     $info['video']['resolution_y'] = $atom_structure['sample_description_table'][$i]['height'];
 710:     $info['quicktime']['video']['resolution_x'] = $info['video']['resolution_x'];
 711:     $info['quicktime']['video']['resolution_y'] = $info['video']['resolution_y'];
 712: }
 713:                                     break;
 714: 
 715:                                 case 'qtvr':
 716:                                     $info['video']['dataformat'] = 'quicktimevr';
 717:                                     break;
 718: 
 719:                                 case 'mp4a':
 720:                                 default:
 721:                                     $info['quicktime']['audio']['codec']       = $this->QuicktimeAudioCodecLookup($atom_structure['sample_description_table'][$i]['data_format']);
 722:                                     $info['quicktime']['audio']['sample_rate'] = $atom_structure['sample_description_table'][$i]['audio_sample_rate'];
 723:                                     $info['quicktime']['audio']['channels']    = $atom_structure['sample_description_table'][$i]['audio_channels'];
 724:                                     $info['quicktime']['audio']['bit_depth']   = $atom_structure['sample_description_table'][$i]['audio_bit_depth'];
 725:                                     $info['audio']['codec']                    = $info['quicktime']['audio']['codec'];
 726:                                     $info['audio']['sample_rate']              = $info['quicktime']['audio']['sample_rate'];
 727:                                     $info['audio']['channels']                 = $info['quicktime']['audio']['channels'];
 728:                                     $info['audio']['bits_per_sample']          = $info['quicktime']['audio']['bit_depth'];
 729:                                     switch ($atom_structure['sample_description_table'][$i]['data_format']) {
 730:                                         case 'raw ': // PCM
 731:                                         case 'alac': // Apple Lossless Audio Codec
 732:                                             $info['audio']['lossless'] = true;
 733:                                             break;
 734:                                         default:
 735:                                             $info['audio']['lossless'] = false;
 736:                                             break;
 737:                                     }
 738:                                     break;
 739:                             }
 740:                             break;
 741: 
 742:                         default:
 743:                             switch ($atom_structure['sample_description_table'][$i]['data_format']) {
 744:                                 case 'mp4s':
 745:                                     $info['fileformat'] = 'mp4';
 746:                                     break;
 747: 
 748:                                 default:
 749:                                     // video atom
 750:                                     $atom_structure['sample_description_table'][$i]['video_temporal_quality']  =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  8,  4));
 751:                                     $atom_structure['sample_description_table'][$i]['video_spatial_quality']   =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12,  4));
 752:                                     $atom_structure['sample_description_table'][$i]['video_frame_width']       =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 16,  2));
 753:                                     $atom_structure['sample_description_table'][$i]['video_frame_height']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 18,  2));
 754:                                     $atom_structure['sample_description_table'][$i]['video_resolution_x']      = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 20,  4));
 755:                                     $atom_structure['sample_description_table'][$i]['video_resolution_y']      = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24,  4));
 756:                                     $atom_structure['sample_description_table'][$i]['video_data_size']         =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 28,  4));
 757:                                     $atom_structure['sample_description_table'][$i]['video_frame_count']       =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 32,  2));
 758:                                     $atom_structure['sample_description_table'][$i]['video_encoder_name_len']  =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 34,  1));
 759:                                     $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']);
 760:                                     $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 66,  2));
 761:                                     $atom_structure['sample_description_table'][$i]['video_color_table_id']    =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 68,  2));
 762: 
 763:                                     $atom_structure['sample_description_table'][$i]['video_pixel_color_type']  = (($atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color');
 764:                                     $atom_structure['sample_description_table'][$i]['video_pixel_color_name']  = $this->QuicktimeColorNameLookup($atom_structure['sample_description_table'][$i]['video_pixel_color_depth']);
 765: 
 766:                                     if ($atom_structure['sample_description_table'][$i]['video_pixel_color_name'] != 'invalid') {
 767:                                         $info['quicktime']['video']['codec_fourcc']        = $atom_structure['sample_description_table'][$i]['data_format'];
 768:                                         $info['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atom_structure['sample_description_table'][$i]['data_format']);
 769:                                         $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']);
 770:                                         $info['quicktime']['video']['color_depth']         = $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'];
 771:                                         $info['quicktime']['video']['color_depth_name']    = $atom_structure['sample_description_table'][$i]['video_pixel_color_name'];
 772: 
 773:                                         $info['video']['codec']           = $info['quicktime']['video']['codec'];
 774:                                         $info['video']['bits_per_sample'] = $info['quicktime']['video']['color_depth'];
 775:                                     }
 776:                                     $info['video']['lossless']           = false;
 777:                                     $info['video']['pixel_aspect_ratio'] = (float) 1;
 778:                                     break;
 779:                             }
 780:                             break;
 781:                     }
 782:                     switch (strtolower($atom_structure['sample_description_table'][$i]['data_format'])) {
 783:                         case 'mp4a':
 784:                             $info['audio']['dataformat']         = 'mp4';
 785:                             $info['quicktime']['audio']['codec'] = 'mp4';
 786:                             break;
 787: 
 788:                         case '3ivx':
 789:                         case '3iv1':
 790:                         case '3iv2':
 791:                             $info['video']['dataformat'] = '3ivx';
 792:                             break;
 793: 
 794:                         case 'xvid':
 795:                             $info['video']['dataformat'] = 'xvid';
 796:                             break;
 797: 
 798:                         case 'mp4v':
 799:                             $info['video']['dataformat'] = 'mpeg4';
 800:                             break;
 801: 
 802:                         case 'divx':
 803:                         case 'div1':
 804:                         case 'div2':
 805:                         case 'div3':
 806:                         case 'div4':
 807:                         case 'div5':
 808:                         case 'div6':
 809:                             $info['video']['dataformat'] = 'divx';
 810:                             break;
 811: 
 812:                         default:
 813:                             // do nothing
 814:                             break;
 815:                     }
 816:                     unset($atom_structure['sample_description_table'][$i]['data']);
 817:                 }
 818:                 break;
 819: 
 820: 
 821:             case 'stts': // Sample Table Time-to-Sample atom
 822:                 $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 823:                 $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 824:                 $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 825:                 $sttsEntriesDataOffset = 8;
 826:                 //$FrameRateCalculatorArray = array();
 827:                 $frames_count = 0;
 828: 
 829:                 $max_stts_entries_to_scan = ($info['php_memory_limit'] ? min(floor($this->getid3->memory_limit / 10000), $atom_structure['number_entries']) : $atom_structure['number_entries']);
 830:                 if ($max_stts_entries_to_scan < $atom_structure['number_entries']) {
 831:                     $info['warning'][] = 'QuickTime atom "stts" has '.$atom_structure['number_entries'].' but only scanning the first '.$max_stts_entries_to_scan.' entries due to limited PHP memory available ('.floor($atom_structure['number_entries'] / 1048576).'MB).';
 832:                 }
 833:                 for ($i = 0; $i < $max_stts_entries_to_scan; $i++) {
 834:                     $atom_structure['time_to_sample_table'][$i]['sample_count']    = getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4));
 835:                     $sttsEntriesDataOffset += 4;
 836:                     $atom_structure['time_to_sample_table'][$i]['sample_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4));
 837:                     $sttsEntriesDataOffset += 4;
 838: 
 839:                     $frames_count += $atom_structure['time_to_sample_table'][$i]['sample_count'];
 840: 
 841:                     // THIS SECTION REPLACED WITH CODE IN "stbl" ATOM
 842:                     //if (!empty($info['quicktime']['time_scale']) && ($atom_structure['time_to_sample_table'][$i]['sample_duration'] > 0)) {
 843:                     //  $stts_new_framerate = $info['quicktime']['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration'];
 844:                     //  if ($stts_new_framerate <= 60) {
 845:                     //      // some atoms have durations of "1" giving a very large framerate, which probably is not right
 846:                     //      $info['video']['frame_rate'] = max($info['video']['frame_rate'], $stts_new_framerate);
 847:                     //  }
 848:                     //}
 849:                     //
 850:                     //$FrameRateCalculatorArray[($info['quicktime']['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration'])] += $atom_structure['time_to_sample_table'][$i]['sample_count'];
 851:                 }
 852:                 $info['quicktime']['stts_framecount'][] = $frames_count;
 853:                 //$sttsFramesTotal  = 0;
 854:                 //$sttsSecondsTotal = 0;
 855:                 //foreach ($FrameRateCalculatorArray as $frames_per_second => $frame_count) {
 856:                 //  if (($frames_per_second > 60) || ($frames_per_second < 1)) {
 857:                 //      // not video FPS information, probably audio information
 858:                 //      $sttsFramesTotal  = 0;
 859:                 //      $sttsSecondsTotal = 0;
 860:                 //      break;
 861:                 //  }
 862:                 //  $sttsFramesTotal  += $frame_count;
 863:                 //  $sttsSecondsTotal += $frame_count / $frames_per_second;
 864:                 //}
 865:                 //if (($sttsFramesTotal > 0) && ($sttsSecondsTotal > 0)) {
 866:                 //  if (($sttsFramesTotal / $sttsSecondsTotal) > $info['video']['frame_rate']) {
 867:                 //      $info['video']['frame_rate'] = $sttsFramesTotal / $sttsSecondsTotal;
 868:                 //  }
 869:                 //}
 870:                 break;
 871: 
 872: 
 873:             case 'stss': // Sample Table Sync Sample (key frames) atom
 874:                 if ($ParseAllPossibleAtoms) {
 875:                     $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 876:                     $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 877:                     $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 878:                     $stssEntriesDataOffset = 8;
 879:                     for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 880:                         $atom_structure['time_to_sample_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stssEntriesDataOffset, 4));
 881:                         $stssEntriesDataOffset += 4;
 882:                     }
 883:                 }
 884:                 break;
 885: 
 886: 
 887:             case 'stsc': // Sample Table Sample-to-Chunk atom
 888:                 if ($ParseAllPossibleAtoms) {
 889:                     $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 890:                     $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 891:                     $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 892:                     $stscEntriesDataOffset = 8;
 893:                     for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 894:                         $atom_structure['sample_to_chunk_table'][$i]['first_chunk']        = getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4));
 895:                         $stscEntriesDataOffset += 4;
 896:                         $atom_structure['sample_to_chunk_table'][$i]['samples_per_chunk']  = getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4));
 897:                         $stscEntriesDataOffset += 4;
 898:                         $atom_structure['sample_to_chunk_table'][$i]['sample_description'] = getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4));
 899:                         $stscEntriesDataOffset += 4;
 900:                     }
 901:                 }
 902:                 break;
 903: 
 904: 
 905:             case 'stsz': // Sample Table SiZe atom
 906:                 if ($ParseAllPossibleAtoms) {
 907:                     $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 908:                     $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 909:                     $atom_structure['sample_size']    = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 910:                     $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
 911:                     $stszEntriesDataOffset = 12;
 912:                     if ($atom_structure['sample_size'] == 0) {
 913:                         for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 914:                             $atom_structure['sample_size_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stszEntriesDataOffset, 4));
 915:                             $stszEntriesDataOffset += 4;
 916:                         }
 917:                     }
 918:                 }
 919:                 break;
 920: 
 921: 
 922:             case 'stco': // Sample Table Chunk Offset atom
 923:                 if ($ParseAllPossibleAtoms) {
 924:                     $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 925:                     $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 926:                     $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 927:                     $stcoEntriesDataOffset = 8;
 928:                     for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 929:                         $atom_structure['chunk_offset_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stcoEntriesDataOffset, 4));
 930:                         $stcoEntriesDataOffset += 4;
 931:                     }
 932:                 }
 933:                 break;
 934: 
 935: 
 936:             case 'co64': // Chunk Offset 64-bit (version of "stco" that supports > 2GB files)
 937:                 if ($ParseAllPossibleAtoms) {
 938:                     $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 939:                     $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 940:                     $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 941:                     $stcoEntriesDataOffset = 8;
 942:                     for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 943:                         $atom_structure['chunk_offset_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stcoEntriesDataOffset, 8));
 944:                         $stcoEntriesDataOffset += 8;
 945:                     }
 946:                 }
 947:                 break;
 948: 
 949: 
 950:             case 'dref': // Data REFerence atom
 951:                 $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 952:                 $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 953:                 $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
 954:                 $drefDataOffset = 8;
 955:                 for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
 956:                     $atom_structure['data_references'][$i]['size']                    = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 4));
 957:                     $drefDataOffset += 4;
 958:                     $atom_structure['data_references'][$i]['type']                    =                           substr($atom_data, $drefDataOffset, 4);
 959:                     $drefDataOffset += 4;
 960:                     $atom_structure['data_references'][$i]['version']                 = getid3_lib::BigEndian2Int(substr($atom_data,  $drefDataOffset, 1));
 961:                     $drefDataOffset += 1;
 962:                     $atom_structure['data_references'][$i]['flags_raw']               = getid3_lib::BigEndian2Int(substr($atom_data,  $drefDataOffset, 3)); // hardcoded: 0x0000
 963:                     $drefDataOffset += 3;
 964:                     $atom_structure['data_references'][$i]['data']                    =                           substr($atom_data, $drefDataOffset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
 965:                     $drefDataOffset += ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3);
 966: 
 967:                     $atom_structure['data_references'][$i]['flags']['self_reference'] = (bool) ($atom_structure['data_references'][$i]['flags_raw'] & 0x001);
 968:                 }
 969:                 break;
 970: 
 971: 
 972:             case 'gmin': // base Media INformation atom
 973:                 $atom_structure['version']                = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 974:                 $atom_structure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 975:                 $atom_structure['graphics_mode']          = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2));
 976:                 $atom_structure['opcolor_red']            = getid3_lib::BigEndian2Int(substr($atom_data,  6, 2));
 977:                 $atom_structure['opcolor_green']          = getid3_lib::BigEndian2Int(substr($atom_data,  8, 2));
 978:                 $atom_structure['opcolor_blue']           = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2));
 979:                 $atom_structure['balance']                = getid3_lib::BigEndian2Int(substr($atom_data, 12, 2));
 980:                 $atom_structure['reserved']               = getid3_lib::BigEndian2Int(substr($atom_data, 14, 2));
 981:                 break;
 982: 
 983: 
 984:             case 'smhd': // Sound Media information HeaDer atom
 985:                 $atom_structure['version']                = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 986:                 $atom_structure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
 987:                 $atom_structure['balance']                = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2));
 988:                 $atom_structure['reserved']               = getid3_lib::BigEndian2Int(substr($atom_data,  6, 2));
 989:                 break;
 990: 
 991: 
 992:             case 'vmhd': // Video Media information HeaDer atom
 993:                 $atom_structure['version']                = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
 994:                 $atom_structure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3));
 995:                 $atom_structure['graphics_mode']          = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2));
 996:                 $atom_structure['opcolor_red']            = getid3_lib::BigEndian2Int(substr($atom_data,  6, 2));
 997:                 $atom_structure['opcolor_green']          = getid3_lib::BigEndian2Int(substr($atom_data,  8, 2));
 998:                 $atom_structure['opcolor_blue']           = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2));
 999: 
1000:                 $atom_structure['flags']['no_lean_ahead'] = (bool) ($atom_structure['flags_raw'] & 0x001);
1001:                 break;
1002: 
1003: 
1004:             case 'hdlr': // HanDLeR reference atom
1005:                 $atom_structure['version']                = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
1006:                 $atom_structure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
1007:                 $atom_structure['component_type']         =                           substr($atom_data,  4, 4);
1008:                 $atom_structure['component_subtype']      =                           substr($atom_data,  8, 4);
1009:                 $atom_structure['component_manufacturer'] =                           substr($atom_data, 12, 4);
1010:                 $atom_structure['component_flags_raw']    = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4));
1011:                 $atom_structure['component_flags_mask']   = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4));
1012:                 $atom_structure['component_name']         =      $this->Pascal2String(substr($atom_data, 24));
1013: 
1014:                 if (($atom_structure['component_subtype'] == 'STpn') && ($atom_structure['component_manufacturer'] == 'zzzz')) {
1015:                     $info['video']['dataformat'] = 'quicktimevr';
1016:                 }
1017:                 break;
1018: 
1019: 
1020:             case 'mdhd': // MeDia HeaDer atom
1021:                 $atom_structure['version']               = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
1022:                 $atom_structure['flags_raw']             = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
1023:                 $atom_structure['creation_time']         = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
1024:                 $atom_structure['modify_time']           = getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
1025:                 $atom_structure['time_scale']            = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4));
1026:                 $atom_structure['duration']              = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4));
1027:                 $atom_structure['language_id']           = getid3_lib::BigEndian2Int(substr($atom_data, 20, 2));
1028:                 $atom_structure['quality']               = getid3_lib::BigEndian2Int(substr($atom_data, 22, 2));
1029: 
1030:                 if ($atom_structure['time_scale'] == 0) {
1031:                     $info['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero';
1032:                     return false;
1033:                 }
1034:                 $info['quicktime']['time_scale'] = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
1035: 
1036:                 $atom_structure['creation_time_unix']    = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
1037:                 $atom_structure['modify_time_unix']      = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
1038:                 $atom_structure['playtime_seconds']      = $atom_structure['duration'] / $atom_structure['time_scale'];
1039:                 $atom_structure['language']              = $this->QuicktimeLanguageLookup($atom_structure['language_id']);
1040:                 if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) {
1041:                     $info['comments']['language'][] = $atom_structure['language'];
1042:                 }
1043:                 break;
1044: 
1045: 
1046:             case 'pnot': // Preview atom
1047:                 $atom_structure['modification_date']      = getid3_lib::BigEndian2Int(substr($atom_data,  0, 4)); // "standard Macintosh format"
1048:                 $atom_structure['version_number']         = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2)); // hardcoded: 0x00
1049:                 $atom_structure['atom_type']              =                           substr($atom_data,  6, 4);        // usually: 'PICT'
1050:                 $atom_structure['atom_index']             = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2)); // usually: 0x01
1051: 
1052:                 $atom_structure['modification_date_unix'] = getid3_lib::DateMac2Unix($atom_structure['modification_date']);
1053:                 break;
1054: 
1055: 
1056:             case 'crgn': // Clipping ReGioN atom
1057:                 $atom_structure['region_size']   = getid3_lib::BigEndian2Int(substr($atom_data,  0, 2)); // The Region size, Region boundary box,
1058:                 $atom_structure['boundary_box']  = getid3_lib::BigEndian2Int(substr($atom_data,  2, 8)); // and Clipping region data fields
1059:                 $atom_structure['clipping_data'] =                           substr($atom_data, 10);           // constitute a QuickDraw region.
1060:                 break;
1061: 
1062: 
1063:             case 'load': // track LOAD settings atom
1064:                 $atom_structure['preload_start_time'] = getid3_lib::BigEndian2Int(substr($atom_data,  0, 4));
1065:                 $atom_structure['preload_duration']   = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
1066:                 $atom_structure['preload_flags_raw']  = getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
1067:                 $atom_structure['default_hints_raw']  = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4));
1068: 
1069:                 $atom_structure['default_hints']['double_buffer'] = (bool) ($atom_structure['default_hints_raw'] & 0x0020);
1070:                 $atom_structure['default_hints']['high_quality']  = (bool) ($atom_structure['default_hints_raw'] & 0x0100);
1071:                 break;
1072: 
1073: 
1074:             case 'tmcd': // TiMe CoDe atom
1075:             case 'chap': // CHAPter list atom
1076:             case 'sync': // SYNChronization atom
1077:             case 'scpt': // tranSCriPT atom
1078:             case 'ssrc': // non-primary SouRCe atom
1079:                 for ($i = 0; $i < strlen($atom_data); $i += 4) {
1080:                     @$atom_structure['track_id'][] = getid3_lib::BigEndian2Int(substr($atom_data, $i, 4));
1081:                 }
1082:                 break;
1083: 
1084: 
1085:             case 'elst': // Edit LiST atom
1086:                 $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
1087:                 $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
1088:                 $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
1089:                 for ($i = 0; $i < $atom_structure['number_entries']; $i++ ) {
1090:                     $atom_structure['edit_list'][$i]['track_duration'] =   getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 0, 4));
1091:                     $atom_structure['edit_list'][$i]['media_time']     =   getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 4, 4));
1092:                     $atom_structure['edit_list'][$i]['media_rate']     = getid3_lib::FixedPoint16_16(substr($atom_data, 8 + ($i * 12) + 8, 4));
1093:                 }
1094:                 break;
1095: 
1096: 
1097:             case 'kmat': // compressed MATte atom
1098:                 $atom_structure['version']        = getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
1099:                 $atom_structure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atom_data,  1, 3)); // hardcoded: 0x0000
1100:                 $atom_structure['matte_data_raw'] =               substr($atom_data,  4);
1101:                 break;
1102: 
1103: 
1104:             case 'ctab': // Color TABle atom
1105:                 $atom_structure['color_table_seed']   = getid3_lib::BigEndian2Int(substr($atom_data,  0, 4)); // hardcoded: 0x00000000
1106:                 $atom_structure['color_table_flags']  = getid3_lib::BigEndian2Int(substr($atom_data,  4, 2)); // hardcoded: 0x8000
1107:                 $atom_structure['color_table_size']   = getid3_lib::BigEndian2Int(substr($atom_data,  6, 2)) + 1;
1108:                 for ($colortableentry = 0; $colortableentry < $atom_structure['color_table_size']; $colortableentry++) {
1109:                     $atom_structure['color_table'][$colortableentry]['alpha'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 0, 2));
1110:                     $atom_structure['color_table'][$colortableentry]['red']   = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 2, 2));
1111:                     $atom_structure['color_table'][$colortableentry]['green'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 4, 2));
1112:                     $atom_structure['color_table'][$colortableentry]['blue']  = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 6, 2));
1113:                 }
1114:                 break;
1115: 
1116: 
1117:             case 'mvhd': // MoVie HeaDer atom
1118:                 $atom_structure['version']            =   getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
1119:                 $atom_structure['flags_raw']          =   getid3_lib::BigEndian2Int(substr($atom_data,  1, 3));
1120:                 $atom_structure['creation_time']      =   getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
1121:                 $atom_structure['modify_time']        =   getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
1122:                 $atom_structure['time_scale']         =   getid3_lib::BigEndian2Int(substr($atom_data, 12, 4));
1123:                 $atom_structure['duration']           =   getid3_lib::BigEndian2Int(substr($atom_data, 16, 4));
1124:                 $atom_structure['preferred_rate']     = getid3_lib::FixedPoint16_16(substr($atom_data, 20, 4));
1125:                 $atom_structure['preferred_volume']   =   getid3_lib::FixedPoint8_8(substr($atom_data, 24, 2));
1126:                 $atom_structure['reserved']           =                             substr($atom_data, 26, 10);
1127:                 $atom_structure['matrix_a']           = getid3_lib::FixedPoint16_16(substr($atom_data, 36, 4));
1128:                 $atom_structure['matrix_b']           = getid3_lib::FixedPoint16_16(substr($atom_data, 40, 4));
1129:                 $atom_structure['matrix_u']           =  getid3_lib::FixedPoint2_30(substr($atom_data, 44, 4));
1130:                 $atom_structure['matrix_c']           = getid3_lib::FixedPoint16_16(substr($atom_data, 48, 4));
1131:                 $atom_structure['matrix_d']           = getid3_lib::FixedPoint16_16(substr($atom_data, 52, 4));
1132:                 $atom_structure['matrix_v']           =  getid3_lib::FixedPoint2_30(substr($atom_data, 56, 4));
1133:                 $atom_structure['matrix_x']           = getid3_lib::FixedPoint16_16(substr($atom_data, 60, 4));
1134:                 $atom_structure['matrix_y']           = getid3_lib::FixedPoint16_16(substr($atom_data, 64, 4));
1135:                 $atom_structure['matrix_w']           =  getid3_lib::FixedPoint2_30(substr($atom_data, 68, 4));
1136:                 $atom_structure['preview_time']       =   getid3_lib::BigEndian2Int(substr($atom_data, 72, 4));
1137:                 $atom_structure['preview_duration']   =   getid3_lib::BigEndian2Int(substr($atom_data, 76, 4));
1138:                 $atom_structure['poster_time']        =   getid3_lib::BigEndian2Int(substr($atom_data, 80, 4));
1139:                 $atom_structure['selection_time']     =   getid3_lib::BigEndian2Int(substr($atom_data, 84, 4));
1140:                 $atom_structure['selection_duration'] =   getid3_lib::BigEndian2Int(substr($atom_data, 88, 4));
1141:                 $atom_structure['current_time']       =   getid3_lib::BigEndian2Int(substr($atom_data, 92, 4));
1142:                 $atom_structure['next_track_id']      =   getid3_lib::BigEndian2Int(substr($atom_data, 96, 4));
1143: 
1144:                 if ($atom_structure['time_scale'] == 0) {
1145:                     $info['error'][] = 'Corrupt Quicktime file: mvhd.time_scale == zero';
1146:                     return false;
1147:                 }
1148:                 $atom_structure['creation_time_unix']        = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
1149:                 $atom_structure['modify_time_unix']          = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
1150:                 $info['quicktime']['time_scale']    = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
1151:                 $info['quicktime']['display_scale'] = $atom_structure['matrix_a'];
1152:                 $info['playtime_seconds']           = $atom_structure['duration'] / $atom_structure['time_scale'];
1153:                 break;
1154: 
1155: 
1156:             case 'tkhd': // TracK HeaDer atom
1157:                 $atom_structure['version']             =   getid3_lib::BigEndian2Int(substr($atom_data,  0, 1));
1158:                 $atom_structure['flags_raw']           =   getid3_lib::BigEndian2Int(substr($atom_data,  1, 3));
1159:                 $atom_structure['creation_time']       =   getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
1160:                 $atom_structure['modify_time']         =   getid3_lib::BigEndian2Int(substr($atom_data,  8, 4));
1161:                 $atom_structure['trackid']             =   getid3_lib::BigEndian2Int(substr($atom_data, 12, 4));
1162:                 $atom_structure['reserved1']           =   getid3_lib::BigEndian2Int(substr($atom_data, 16, 4));
1163:                 $atom_structure['duration']            =   getid3_lib::BigEndian2Int(substr($atom_data, 20, 4));
1164:                 $atom_structure['reserved2']           =   getid3_lib::BigEndian2Int(substr($atom_data, 24, 8));
1165:                 $atom_structure['layer']               =   getid3_lib::BigEndian2Int(substr($atom_data, 32, 2));
1166:                 $atom_structure['alternate_group']     =   getid3_lib::BigEndian2Int(substr($atom_data, 34, 2));
1167:                 $atom_structure['volume']              =   getid3_lib::FixedPoint8_8(substr($atom_data, 36, 2));
1168:                 $atom_structure['reserved3']           =   getid3_lib::BigEndian2Int(substr($atom_data, 38, 2));
1169: // http://developer.apple.com/library/mac/#documentation/QuickTime/RM/MovieBasics/MTEditing/K-Chapter/11MatrixFunctions.html
1170: // http://developer.apple.com/library/mac/#documentation/QuickTime/qtff/QTFFChap4/qtff4.html#//apple_ref/doc/uid/TP40000939-CH206-18737
1171:                 $atom_structure['matrix_a']            = getid3_lib::FixedPoint16_16(substr($atom_data, 40, 4));
1172:                 $atom_structure['matrix_b']            = getid3_lib::FixedPoint16_16(substr($atom_data, 44, 4));
1173:                 $atom_structure['matrix_u']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 48, 4));
1174:                 $atom_structure['matrix_c']            = getid3_lib::FixedPoint16_16(substr($atom_data, 52, 4));
1175:                 $atom_structure['matrix_d']            = getid3_lib::FixedPoint16_16(substr($atom_data, 56, 4));
1176:                 $atom_structure['matrix_v']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 60, 4));
1177:                 $atom_structure['matrix_x']            = getid3_lib::FixedPoint16_16(substr($atom_data, 64, 4));
1178:                 $atom_structure['matrix_y']            = getid3_lib::FixedPoint16_16(substr($atom_data, 68, 4));
1179:                 $atom_structure['matrix_w']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 72, 4));
1180:                 $atom_structure['width']               = getid3_lib::FixedPoint16_16(substr($atom_data, 76, 4));
1181:                 $atom_structure['height']              = getid3_lib::FixedPoint16_16(substr($atom_data, 80, 4));
1182:                 $atom_structure['flags']['enabled']    = (bool) ($atom_structure['flags_raw'] & 0x0001);
1183:                 $atom_structure['flags']['in_movie']   = (bool) ($atom_structure['flags_raw'] & 0x0002);
1184:                 $atom_structure['flags']['in_preview'] = (bool) ($atom_structure['flags_raw'] & 0x0004);
1185:                 $atom_structure['flags']['in_poster']  = (bool) ($atom_structure['flags_raw'] & 0x0008);
1186:                 $atom_structure['creation_time_unix']  = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
1187:                 $atom_structure['modify_time_unix']    = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
1188: 
1189:                 if ($atom_structure['flags']['enabled'] == 1) {
1190:                     if (!isset($info['video']['resolution_x']) || !isset($info['video']['resolution_y'])) {
1191:                         $info['video']['resolution_x'] = $atom_structure['width'];
1192:                         $info['video']['resolution_y'] = $atom_structure['height'];
1193:                     }
1194:                     $info['video']['resolution_x'] = max($info['video']['resolution_x'], $atom_structure['width']);
1195:                     $info['video']['resolution_y'] = max($info['video']['resolution_y'], $atom_structure['height']);
1196:                     $info['quicktime']['video']['resolution_x'] = $info['video']['resolution_x'];
1197:                     $info['quicktime']['video']['resolution_y'] = $info['video']['resolution_y'];
1198:                 } else {
1199:                     // see: http://www.getid3.org/phpBB3/viewtopic.php?t=1295
1200:                     //if (isset($info['video']['resolution_x'])) { unset($info['video']['resolution_x']); }
1201:                     //if (isset($info['video']['resolution_y'])) { unset($info['video']['resolution_y']); }
1202:                     //if (isset($info['quicktime']['video']))    { unset($info['quicktime']['video']);    }
1203:                 }
1204:                 break;
1205: 
1206: 
1207:             case 'iods': // Initial Object DeScriptor atom
1208:                 // http://www.koders.com/c/fid1FAB3E762903DC482D8A246D4A4BF9F28E049594.aspx?s=windows.h
1209:                 // http://libquicktime.sourcearchive.com/documentation/1.0.2plus-pdebian/iods_8c-source.html
1210:                 $offset = 0;
1211:                 $atom_structure['version']                =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1212:                 $offset += 1;
1213:                 $atom_structure['flags_raw']              =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 3));
1214:                 $offset += 3;
1215:                 $atom_structure['mp4_iod_tag']            =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1216:                 $offset += 1;
1217:                 $atom_structure['length']                 = $this->quicktime_read_mp4_descr_length($atom_data, $offset);
1218:                 //$offset already adjusted by quicktime_read_mp4_descr_length()
1219:                 $atom_structure['object_descriptor_id']   =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));
1220:                 $offset += 2;
1221:                 $atom_structure['od_profile_level']       =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1222:                 $offset += 1;
1223:                 $atom_structure['scene_profile_level']    =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1224:                 $offset += 1;
1225:                 $atom_structure['audio_profile_id']       =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1226:                 $offset += 1;
1227:                 $atom_structure['video_profile_id']       =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1228:                 $offset += 1;
1229:                 $atom_structure['graphics_profile_level'] =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1230:                 $offset += 1;
1231: 
1232:                 $atom_structure['num_iods_tracks'] = ($atom_structure['length'] - 7) / 6; // 6 bytes would only be right if all tracks use 1-byte length fields
1233:                 for ($i = 0; $i < $atom_structure['num_iods_tracks']; $i++) {
1234:                     $atom_structure['track'][$i]['ES_ID_IncTag'] =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1));
1235:                     $offset += 1;
1236:                     $atom_structure['track'][$i]['length']       = $this->quicktime_read_mp4_descr_length($atom_data, $offset);
1237:                     //$offset already adjusted by quicktime_read_mp4_descr_length()
1238:                     $atom_structure['track'][$i]['track_id']     =       getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4));
1239:                     $offset += 4;
1240:                 }
1241: 
1242:                 $atom_structure['audio_profile_name'] = $this->QuicktimeIODSaudioProfileName($atom_structure['audio_profile_id']);
1243:                 $atom_structure['video_profile_name'] = $this->QuicktimeIODSvideoProfileName($atom_structure['video_profile_id']);
1244:                 break;
1245: 
1246:             case 'ftyp': // FileTYPe (?) atom (for MP4 it seems)
1247:                 $atom_structure['signature'] =                           substr($atom_data,  0, 4);
1248:                 $atom_structure['unknown_1'] = getid3_lib::BigEndian2Int(substr($atom_data,  4, 4));
1249:                 $atom_structure['fourcc']    =                           substr($atom_data,  8, 4);
1250:                 break;
1251: 
1252:             case 'mdat': // Media DATa atom
1253:                 // 'mdat' contains the actual data for the audio/video, possibly also subtitles
1254: 
1255: /* due to lack of known documentation, this is a kludge implementation. If you know of documentation on how mdat is properly structed, please send it to info@getid3.org */
1256: 
1257:                 // first, skip any 'wide' padding, and second 'mdat' header (with specified size of zero?)
1258:                 $mdat_offset = 0;
1259:                 while (true) {
1260:                     if (substr($atom_data, $mdat_offset, 8) == "\x00\x00\x00\x08".'wide') {
1261:                         $mdat_offset += 8;
1262:                     } elseif (substr($atom_data, $mdat_offset, 8) == "\x00\x00\x00\x00".'mdat') {
1263:                         $mdat_offset += 8;
1264:                     } else {
1265:                         break;
1266:                     }
1267:                 }
1268: 
1269:                 // check to see if it looks like chapter titles, in the form of unterminated strings with a leading 16-bit size field
1270:                 while  (($chapter_string_length = getid3_lib::BigEndian2Int(substr($atom_data, $mdat_offset, 2)))
1271:                     && ($chapter_string_length < 1000)
1272:                     && ($chapter_string_length <= (strlen($atom_data) - $mdat_offset - 2))
1273:                     && preg_match('#^[\x20-\xFF]+$#', substr($atom_data, $mdat_offset + 2, $chapter_string_length), $chapter_matches)) {
1274:                         $mdat_offset += (2 + $chapter_string_length);
1275:                         @$info['quicktime']['comments']['chapters'][] = $chapter_matches[0];
1276:                 }
1277: 
1278: 
1279: 
1280:                 if (($atomsize > 8) && (!isset($info['avdataend_tmp']) || ($info['quicktime'][$atomname]['size'] > ($info['avdataend_tmp'] - $info['avdataoffset'])))) {
1281: 
1282:                     $info['avdataoffset'] = $atom_structure['offset'] + 8;                       // $info['quicktime'][$atomname]['offset'] + 8;
1283:                     $OldAVDataEnd         = $info['avdataend'];
1284:                     $info['avdataend']    = $atom_structure['offset'] + $atom_structure['size']; // $info['quicktime'][$atomname]['offset'] + $info['quicktime'][$atomname]['size'];
1285: 
1286:                     $getid3_temp = new getID3();
1287:                     $getid3_temp->openfile($this->getid3->filename);
1288:                     $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1289:                     $getid3_temp->info['avdataend']    = $info['avdataend'];
1290:                     $getid3_mp3 = new getid3_mp3($getid3_temp);
1291:                     if ($getid3_mp3->MPEGaudioHeaderValid($getid3_mp3->MPEGaudioHeaderDecode($this->fread(4)))) {
1292:                         $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1293:                         if (!empty($getid3_temp->info['warning'])) {
1294:                             foreach ($getid3_temp->info['warning'] as $value) {
1295:                                 $info['warning'][] = $value;
1296:                             }
1297:                         }
1298:                         if (!empty($getid3_temp->info['mpeg'])) {
1299:                             $info['mpeg'] = $getid3_temp->info['mpeg'];
1300:                             if (isset($info['mpeg']['audio'])) {
1301:                                 $info['audio']['dataformat']   = 'mp3';
1302:                                 $info['audio']['codec']        = (!empty($info['mpeg']['audio']['encoder']) ? $info['mpeg']['audio']['encoder'] : (!empty($info['mpeg']['audio']['codec']) ? $info['mpeg']['audio']['codec'] : (!empty($info['mpeg']['audio']['LAME']) ? 'LAME' :'mp3')));
1303:                                 $info['audio']['sample_rate']  = $info['mpeg']['audio']['sample_rate'];
1304:                                 $info['audio']['channels']     = $info['mpeg']['audio']['channels'];
1305:                                 $info['audio']['bitrate']      = $info['mpeg']['audio']['bitrate'];
1306:                                 $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1307:                                 $info['bitrate']               = $info['audio']['bitrate'];
1308:                             }
1309:                         }
1310:                     }
1311:                     unset($getid3_mp3, $getid3_temp);
1312:                     $info['avdataend'] = $OldAVDataEnd;
1313:                     unset($OldAVDataEnd);
1314: 
1315:                 }
1316: 
1317:                 unset($mdat_offset, $chapter_string_length, $chapter_matches);
1318:                 break;
1319: 
1320:             case 'free': // FREE space atom
1321:             case 'skip': // SKIP atom
1322:             case 'wide': // 64-bit expansion placeholder atom
1323:                 // 'free', 'skip' and 'wide' are just padding, contains no useful data at all
1324: 
1325:                 // When writing QuickTime files, it is sometimes necessary to update an atom's size.
1326:                 // It is impossible to update a 32-bit atom to a 64-bit atom since the 32-bit atom
1327:                 // is only 8 bytes in size, and the 64-bit atom requires 16 bytes. Therefore, QuickTime
1328:                 // puts an 8-byte placeholder atom before any atoms it may have to update the size of.
1329:                 // In this way, if the atom needs to be converted from a 32-bit to a 64-bit atom, the
1330:                 // placeholder atom can be overwritten to obtain the necessary 8 extra bytes.
1331:                 // The placeholder atom has a type of kWideAtomPlaceholderType ( 'wide' ).
1332:                 break;
1333: 
1334: 
1335:             case 'nsav': // NoSAVe atom
1336:                 // http://developer.apple.com/technotes/tn/tn2038.html
1337:                 $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($atom_data,  0, 4));
1338:                 break;
1339: 
1340:             case 'ctyp': // Controller TYPe atom (seen on QTVR)
1341:                 // http://homepages.slingshot.co.nz/~helmboy/quicktime/formats/qtm-layout.txt
1342:                 // some controller names are:
1343:                 //   0x00 + 'std' for linear movie
1344:                 //   'none' for no controls
1345:                 $atom_structure['ctyp'] = substr($atom_data, 0, 4);
1346:                 $info['quicktime']['controller'] = $atom_structure['ctyp'];
1347:                 switch ($atom_structure['ctyp']) {
1348:                     case 'qtvr':
1349:                         $info['video']['dataformat'] = 'quicktimevr';
1350:                         break;
1351:                 }
1352:                 break;
1353: 
1354:             case 'pano': // PANOrama track (seen on QTVR)
1355:                 $atom_structure['pano'] = getid3_lib::BigEndian2Int(substr($atom_data,  0, 4));
1356:                 break;
1357: 
1358:             case 'hint': // HINT track
1359:             case 'hinf': //
1360:             case 'hinv': //
1361:             case 'hnti': //
1362:                 $info['quicktime']['hinting'] = true;
1363:                 break;
1364: 
1365:             case 'imgt': // IMaGe Track reference (kQTVRImageTrackRefType) (seen on QTVR)
1366:                 for ($i = 0; $i < ($atom_structure['size'] - 8); $i += 4) {
1367:                     $atom_structure['imgt'][] = getid3_lib::BigEndian2Int(substr($atom_data, $i, 4));
1368:                 }
1369:                 break;
1370: 
1371: 
1372:             // Observed-but-not-handled atom types are just listed here to prevent warnings being generated
1373:             case 'FXTC': // Something to do with Adobe After Effects (?)
1374:             case 'PrmA':
1375:             case 'code':
1376:             case 'FIEL': // this is NOT "fiel" (Field Ordering) as describe here: http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html
1377:             case 'tapt': // TrackApertureModeDimensionsAID - http://developer.apple.com/documentation/QuickTime/Reference/QT7-1_Update_Reference/Constants/Constants.html
1378:                         // tapt seems to be used to compute the video size [http://www.getid3.org/phpBB3/viewtopic.php?t=838]
1379:                         // * http://lists.apple.com/archives/quicktime-api/2006/Aug/msg00014.html
1380:                         // * http://handbrake.fr/irclogs/handbrake-dev/handbrake-dev20080128_pg2.html
1381:             case 'ctts'://  STCompositionOffsetAID             - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
1382:             case 'cslg'://  STCompositionShiftLeastGreatestAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
1383:             case 'sdtp'://  STSampleDependencyAID              - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
1384:             case 'stps'://  STPartialSyncSampleAID             - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
1385:                 //$atom_structure['data'] = $atom_data;
1386:                 break;
1387: 
1388:             case "\xA9".'xyz':  // GPS latitude+longitude+altitude
1389:                 $atom_structure['data'] = $atom_data;
1390:                 if (preg_match('#([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)?/$#i', $atom_data, $matches)) {
1391:                     @list($all, $latitude, $longitude, $altitude) = $matches;
1392:                     $info['quicktime']['comments']['gps_latitude'][]  = floatval($latitude);
1393:                     $info['quicktime']['comments']['gps_longitude'][] = floatval($longitude);
1394:                     if (!empty($altitude)) {
1395:                         $info['quicktime']['comments']['gps_altitude'][] = floatval($altitude);
1396:                     }
1397:                 } else {
1398:                     $info['warning'][] = 'QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.';
1399:                 }
1400:                 break;
1401: 
1402:             case 'NCDT':
1403:                 // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
1404:                 // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
1405:                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms);
1406:                 break;
1407:             case 'NCTH': // Nikon Camera THumbnail image
1408:             case 'NCVW': // Nikon Camera preVieW image
1409:                 // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
1410:                 if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) {
1411:                     $atom_structure['data'] = $atom_data;
1412:                     $atom_structure['image_mime'] = 'image/jpeg';
1413:                     $atom_structure['description'] = (($atomname == 'NCTH') ? 'Nikon Camera Thumbnail Image' : (($atomname == 'NCVW') ? 'Nikon Camera Preview Image' : 'Nikon preview image'));
1414:                     $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_data, 'description'=>$atom_structure['description']);
1415:                 }
1416:                 break;
1417:             case 'NCTG': // Nikon - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
1418:                 $atom_structure['data'] = $this->QuicktimeParseNikonNCTG($atom_data);
1419:                 break;
1420:             case 'NCHD': // Nikon:MakerNoteVersion  - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
1421:             case 'NCDB': // Nikon                   - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
1422:             case 'CNCV': // Canon:CompressorVersion - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html
1423:                 $atom_structure['data'] = $atom_data;
1424:                 break;
1425: 
1426:             case "\x00\x00\x00\x00":
1427:             case 'meta': // METAdata atom
1428:                 // some kind of metacontainer, may contain a big data dump such as:
1429:                 // 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
1430:                 // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
1431: 
1432:                 $atom_structure['version']   =          getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
1433:                 $atom_structure['flags_raw'] =          getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
1434:                 $atom_structure['subatoms']  = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
1435:                 //$atom_structure['subatoms']  = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
1436:                 break;
1437: 
1438:             case 'data': // metaDATA atom
1439:                 // seems to be 2 bytes language code (ASCII), 2 bytes unknown (set to 0x10B5 in sample I have), remainder is useful data
1440:                 $atom_structure['language'] =                           substr($atom_data, 4 + 0, 2);
1441:                 $atom_structure['unknown']  = getid3_lib::BigEndian2Int(substr($atom_data, 4 + 2, 2));
1442:                 $atom_structure['data']     =                           substr($atom_data, 4 + 4);
1443:                 break;
1444: 
1445:             default:
1446:                 $info['warning'][] = 'Unknown QuickTime atom type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" ('.trim(getid3_lib::PrintHexBytes($atomname)).') at offset '.$baseoffset;
1447:                 $atom_structure['data'] = $atom_data;
1448:                 break;
1449:         }
1450:         array_pop($atomHierarchy);
1451:         return $atom_structure;
1452:     }
1453: 
1454:     public function QuicktimeParseContainerAtom($atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
1455: //echo 'QuicktimeParseContainerAtom('.substr($atom_data, 4, 4).') @ '.$baseoffset.'<br><br>';
1456:         $atom_structure  = false;
1457:         $subatomoffset  = 0;
1458:         $subatomcounter = 0;
1459:         if ((strlen($atom_data) == 4) && (getid3_lib::BigEndian2Int($atom_data) == 0x00000000)) {
1460:             return false;
1461:         }
1462:         while ($subatomoffset < strlen($atom_data)) {
1463:             $subatomsize = getid3_lib::BigEndian2Int(substr($atom_data, $subatomoffset + 0, 4));
1464:             $subatomname =                           substr($atom_data, $subatomoffset + 4, 4);
1465:             $subatomdata =                           substr($atom_data, $subatomoffset + 8, $subatomsize - 8);
1466:             if ($subatomsize == 0) {
1467:                 // Furthermore, for historical reasons the list of atoms is optionally
1468:                 // terminated by a 32-bit integer set to 0. If you are writing a program
1469:                 // to read user data atoms, you should allow for the terminating 0.
1470:                 return $atom_structure;
1471:             }
1472: 
1473:             $atom_structure[$subatomcounter] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms);
1474: 
1475:             $subatomoffset += $subatomsize;
1476:             $subatomcounter++;
1477:         }
1478:         return $atom_structure;
1479:     }
1480: 
1481: 
1482:     public function quicktime_read_mp4_descr_length($data, &$offset) {
1483:         // http://libquicktime.sourcearchive.com/documentation/2:1.0.2plus-pdebian-2build1/esds_8c-source.html
1484:         $num_bytes = 0;
1485:         $length    = 0;
1486:         do {
1487:             $b = ord(substr($data, $offset++, 1));
1488:             $length = ($length << 7) | ($b & 0x7F);
1489:         } while (($b & 0x80) && ($num_bytes++ < 4));
1490:         return $length;
1491:     }
1492: 
1493: 
1494:     public function QuicktimeLanguageLookup($languageid) {
1495:         // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap4/qtff4.html#//apple_ref/doc/uid/TP40000939-CH206-34353
1496:         static $QuicktimeLanguageLookup = array();
1497:         if (empty($QuicktimeLanguageLookup)) {
1498:             $QuicktimeLanguageLookup[0]     = 'English';
1499:             $QuicktimeLanguageLookup[1]     = 'French';
1500:             $QuicktimeLanguageLookup[2]     = 'German';
1501:             $QuicktimeLanguageLookup[3]     = 'Italian';
1502:             $QuicktimeLanguageLookup[4]     = 'Dutch';
1503:             $QuicktimeLanguageLookup[5]     = 'Swedish';
1504:             $QuicktimeLanguageLookup[6]     = 'Spanish';
1505:             $QuicktimeLanguageLookup[7]     = 'Danish';
1506:             $QuicktimeLanguageLookup[8]     = 'Portuguese';
1507:             $QuicktimeLanguageLookup[9]     = 'Norwegian';
1508:             $QuicktimeLanguageLookup[10]    = 'Hebrew';
1509:             $QuicktimeLanguageLookup[11]    = 'Japanese';
1510:             $QuicktimeLanguageLookup[12]    = 'Arabic';
1511:             $QuicktimeLanguageLookup[13]    = 'Finnish';
1512:             $QuicktimeLanguageLookup[14]    = 'Greek';
1513:             $QuicktimeLanguageLookup[15]    = 'Icelandic';
1514:             $QuicktimeLanguageLookup[16]    = 'Maltese';
1515:             $QuicktimeLanguageLookup[17]    = 'Turkish';
1516:             $QuicktimeLanguageLookup[18]    = 'Croatian';
1517:             $QuicktimeLanguageLookup[19]    = 'Chinese (Traditional)';
1518:             $QuicktimeLanguageLookup[20]    = 'Urdu';
1519:             $QuicktimeLanguageLookup[21]    = 'Hindi';
1520:             $QuicktimeLanguageLookup[22]    = 'Thai';
1521:             $QuicktimeLanguageLookup[23]    = 'Korean';
1522:             $QuicktimeLanguageLookup[24]    = 'Lithuanian';
1523:             $QuicktimeLanguageLookup[25]    = 'Polish';
1524:             $QuicktimeLanguageLookup[26]    = 'Hungarian';
1525:             $QuicktimeLanguageLookup[27]    = 'Estonian';
1526:             $QuicktimeLanguageLookup[28]    = 'Lettish';
1527:             $QuicktimeLanguageLookup[28]    = 'Latvian';
1528:             $QuicktimeLanguageLookup[29]    = 'Saamisk';
1529:             $QuicktimeLanguageLookup[29]    = 'Lappish';
1530:             $QuicktimeLanguageLookup[30]    = 'Faeroese';
1531:             $QuicktimeLanguageLookup[31]    = 'Farsi';
1532:             $QuicktimeLanguageLookup[31]    = 'Persian';
1533:             $QuicktimeLanguageLookup[32]    = 'Russian';
1534:             $QuicktimeLanguageLookup[33]    = 'Chinese (Simplified)';
1535:             $QuicktimeLanguageLookup[34]    = 'Flemish';
1536:             $QuicktimeLanguageLookup[35]    = 'Irish';
1537:             $QuicktimeLanguageLookup[36]    = 'Albanian';
1538:             $QuicktimeLanguageLookup[37]    = 'Romanian';
1539:             $QuicktimeLanguageLookup[38]    = 'Czech';
1540:             $QuicktimeLanguageLookup[39]    = 'Slovak';
1541:             $QuicktimeLanguageLookup[40]    = 'Slovenian';
1542:             $QuicktimeLanguageLookup[41]    = 'Yiddish';
1543:             $QuicktimeLanguageLookup[42]    = 'Serbian';
1544:             $QuicktimeLanguageLookup[43]    = 'Macedonian';
1545:             $QuicktimeLanguageLookup[44]    = 'Bulgarian';
1546:             $QuicktimeLanguageLookup[45]    = 'Ukrainian';
1547:             $QuicktimeLanguageLookup[46]    = 'Byelorussian';
1548:             $QuicktimeLanguageLookup[47]    = 'Uzbek';
1549:             $QuicktimeLanguageLookup[48]    = 'Kazakh';
1550:             $QuicktimeLanguageLookup[49]    = 'Azerbaijani';
1551:             $QuicktimeLanguageLookup[50]    = 'AzerbaijanAr';
1552:             $QuicktimeLanguageLookup[51]    = 'Armenian';
1553:             $QuicktimeLanguageLookup[52]    = 'Georgian';
1554:             $QuicktimeLanguageLookup[53]    = 'Moldavian';
1555:             $QuicktimeLanguageLookup[54]    = 'Kirghiz';
1556:             $QuicktimeLanguageLookup[55]    = 'Tajiki';
1557:             $QuicktimeLanguageLookup[56]    = 'Turkmen';
1558:             $QuicktimeLanguageLookup[57]    = 'Mongolian';
1559:             $QuicktimeLanguageLookup[58]    = 'MongolianCyr';
1560:             $QuicktimeLanguageLookup[59]    = 'Pashto';
1561:             $QuicktimeLanguageLookup[60]    = 'Kurdish';
1562:             $QuicktimeLanguageLookup[61]    = 'Kashmiri';
1563:             $QuicktimeLanguageLookup[62]    = 'Sindhi';
1564:             $QuicktimeLanguageLookup[63]    = 'Tibetan';
1565:             $QuicktimeLanguageLookup[64]    = 'Nepali';
1566:             $QuicktimeLanguageLookup[65]    = 'Sanskrit';
1567:             $QuicktimeLanguageLookup[66]    = 'Marathi';
1568:             $QuicktimeLanguageLookup[67]    = 'Bengali';
1569:             $QuicktimeLanguageLookup[68]    = 'Assamese';
1570:             $QuicktimeLanguageLookup[69]    = 'Gujarati';
1571:             $QuicktimeLanguageLookup[70]    = 'Punjabi';
1572:             $QuicktimeLanguageLookup[71]    = 'Oriya';
1573:             $QuicktimeLanguageLookup[72]    = 'Malayalam';
1574:             $QuicktimeLanguageLookup[73]    = 'Kannada';
1575:             $QuicktimeLanguageLookup[74]    = 'Tamil';
1576:             $QuicktimeLanguageLookup[75]    = 'Telugu';
1577:             $QuicktimeLanguageLookup[76]    = 'Sinhalese';
1578:             $QuicktimeLanguageLookup[77]    = 'Burmese';
1579:             $QuicktimeLanguageLookup[78]    = 'Khmer';
1580:             $QuicktimeLanguageLookup[79]    = 'Lao';
1581:             $QuicktimeLanguageLookup[80]    = 'Vietnamese';
1582:             $QuicktimeLanguageLookup[81]    = 'Indonesian';
1583:             $QuicktimeLanguageLookup[82]    = 'Tagalog';
1584:             $QuicktimeLanguageLookup[83]    = 'MalayRoman';
1585:             $QuicktimeLanguageLookup[84]    = 'MalayArabic';
1586:             $QuicktimeLanguageLookup[85]    = 'Amharic';
1587:             $QuicktimeLanguageLookup[86]    = 'Tigrinya';
1588:             $QuicktimeLanguageLookup[87]    = 'Galla';
1589:             $QuicktimeLanguageLookup[87]    = 'Oromo';
1590:             $QuicktimeLanguageLookup[88]    = 'Somali';
1591:             $QuicktimeLanguageLookup[89]    = 'Swahili';
1592:             $QuicktimeLanguageLookup[90]    = 'Ruanda';
1593:             $QuicktimeLanguageLookup[91]    = 'Rundi';
1594:             $QuicktimeLanguageLookup[92]    = 'Chewa';
1595:             $QuicktimeLanguageLookup[93]    = 'Malagasy';
1596:             $QuicktimeLanguageLookup[94]    = 'Esperanto';
1597:             $QuicktimeLanguageLookup[128]   = 'Welsh';
1598:             $QuicktimeLanguageLookup[129]   = 'Basque';
1599:             $QuicktimeLanguageLookup[130]   = 'Catalan';
1600:             $QuicktimeLanguageLookup[131]   = 'Latin';
1601:             $QuicktimeLanguageLookup[132]   = 'Quechua';
1602:             $QuicktimeLanguageLookup[133]   = 'Guarani';
1603:             $QuicktimeLanguageLookup[134]   = 'Aymara';
1604:             $QuicktimeLanguageLookup[135]   = 'Tatar';
1605:             $QuicktimeLanguageLookup[136]   = 'Uighur';
1606:             $QuicktimeLanguageLookup[137]   = 'Dzongkha';
1607:             $QuicktimeLanguageLookup[138]   = 'JavaneseRom';
1608:             $QuicktimeLanguageLookup[32767] = 'Unspecified';
1609:         }
1610:         if (($languageid > 138) && ($languageid < 32767)) {
1611:             /*
1612:             ISO Language Codes - http://www.loc.gov/standards/iso639-2/php/code_list.php
1613:             Because the language codes specified by ISO 639-2/T are three characters long, they must be packed to fit into a 16-bit field.
1614:             The packing algorithm must map each of the three characters, which are always lowercase, into a 5-bit integer and then concatenate
1615:             these integers into the least significant 15 bits of a 16-bit integer, leaving the 16-bit integer's most significant bit set to zero.
1616: 
1617:             One algorithm for performing this packing is to treat each ISO character as a 16-bit integer. Subtract 0x60 from the first character
1618:             and multiply by 2^10 (0x400), subtract 0x60 from the second character and multiply by 2^5 (0x20), subtract 0x60 from the third character,
1619:             and add the three 16-bit values. This will result in a single 16-bit value with the three codes correctly packed into the 15 least
1620:             significant bits and the most significant bit set to zero.
1621:             */
1622:             $iso_language_id  = '';
1623:             $iso_language_id .= chr((($languageid & 0x7C00) >> 10) + 0x60);
1624:             $iso_language_id .= chr((($languageid & 0x03E0) >>  5) + 0x60);
1625:             $iso_language_id .= chr((($languageid & 0x001F) >>  0) + 0x60);
1626:             $QuicktimeLanguageLookup[$languageid] = getid3_id3v2::LanguageLookup($iso_language_id);
1627:         }
1628:         return (isset($QuicktimeLanguageLookup[$languageid]) ? $QuicktimeLanguageLookup[$languageid] : 'invalid');
1629:     }
1630: 
1631:     public function QuicktimeVideoCodecLookup($codecid) {
1632:         static $QuicktimeVideoCodecLookup = array();
1633:         if (empty($QuicktimeVideoCodecLookup)) {
1634:             $QuicktimeVideoCodecLookup['.SGI'] = 'SGI';
1635:             $QuicktimeVideoCodecLookup['3IV1'] = '3ivx MPEG-4 v1';
1636:             $QuicktimeVideoCodecLookup['3IV2'] = '3ivx MPEG-4 v2';
1637:             $QuicktimeVideoCodecLookup['3IVX'] = '3ivx MPEG-4';
1638:             $QuicktimeVideoCodecLookup['8BPS'] = 'Planar RGB';
1639:             $QuicktimeVideoCodecLookup['avc1'] = 'H.264/MPEG-4 AVC';
1640:             $QuicktimeVideoCodecLookup['avr '] = 'AVR-JPEG';
1641:             $QuicktimeVideoCodecLookup['b16g'] = '16Gray';
1642:             $QuicktimeVideoCodecLookup['b32a'] = '32AlphaGray';
1643:             $QuicktimeVideoCodecLookup['b48r'] = '48RGB';
1644:             $QuicktimeVideoCodecLookup['b64a'] = '64ARGB';
1645:             $QuicktimeVideoCodecLookup['base'] = 'Base';
1646:             $QuicktimeVideoCodecLookup['clou'] = 'Cloud';
1647:             $QuicktimeVideoCodecLookup['cmyk'] = 'CMYK';
1648:             $QuicktimeVideoCodecLookup['cvid'] = 'Cinepak';
1649:             $QuicktimeVideoCodecLookup['dmb1'] = 'OpenDML JPEG';
1650:             $QuicktimeVideoCodecLookup['dvc '] = 'DVC-NTSC';
1651:             $QuicktimeVideoCodecLookup['dvcp'] = 'DVC-PAL';
1652:             $QuicktimeVideoCodecLookup['dvpn'] = 'DVCPro-NTSC';
1653:             $QuicktimeVideoCodecLookup['dvpp'] = 'DVCPro-PAL';
1654:             $QuicktimeVideoCodecLookup['fire'] = 'Fire';
1655:             $QuicktimeVideoCodecLookup['flic'] = 'FLC';
1656:             $QuicktimeVideoCodecLookup['gif '] = 'GIF';
1657:             $QuicktimeVideoCodecLookup['h261'] = 'H261';
1658:             $QuicktimeVideoCodecLookup['h263'] = 'H263';
1659:             $QuicktimeVideoCodecLookup['IV41'] = 'Indeo4';
1660:             $QuicktimeVideoCodecLookup['jpeg'] = 'JPEG';
1661:             $QuicktimeVideoCodecLookup['kpcd'] = 'PhotoCD';
1662:             $QuicktimeVideoCodecLookup['mjpa'] = 'Motion JPEG-A';
1663:             $QuicktimeVideoCodecLookup['mjpb'] = 'Motion JPEG-B';
1664:             $QuicktimeVideoCodecLookup['msvc'] = 'Microsoft Video1';
1665:             $QuicktimeVideoCodecLookup['myuv'] = 'MPEG YUV420';
1666:             $QuicktimeVideoCodecLookup['path'] = 'Vector';
1667:             $QuicktimeVideoCodecLookup['png '] = 'PNG';
1668:             $QuicktimeVideoCodecLookup['PNTG'] = 'MacPaint';
1669:             $QuicktimeVideoCodecLookup['qdgx'] = 'QuickDrawGX';
1670:             $QuicktimeVideoCodecLookup['qdrw'] = 'QuickDraw';
1671:             $QuicktimeVideoCodecLookup['raw '] = 'RAW';
1672:             $QuicktimeVideoCodecLookup['ripl'] = 'WaterRipple';
1673:             $QuicktimeVideoCodecLookup['rpza'] = 'Video';
1674:             $QuicktimeVideoCodecLookup['smc '] = 'Graphics';
1675:             $QuicktimeVideoCodecLookup['SVQ1'] = 'Sorenson Video 1';
1676:             $QuicktimeVideoCodecLookup['SVQ1'] = 'Sorenson Video 3';
1677:             $QuicktimeVideoCodecLookup['syv9'] = 'Sorenson YUV9';
1678:             $QuicktimeVideoCodecLookup['tga '] = 'Targa';
1679:             $QuicktimeVideoCodecLookup['tiff'] = 'TIFF';
1680:             $QuicktimeVideoCodecLookup['WRAW'] = 'Windows RAW';
1681:             $QuicktimeVideoCodecLookup['WRLE'] = 'BMP';
1682:             $QuicktimeVideoCodecLookup['y420'] = 'YUV420';
1683:             $QuicktimeVideoCodecLookup['yuv2'] = 'ComponentVideo';
1684:             $QuicktimeVideoCodecLookup['yuvs'] = 'ComponentVideoUnsigned';
1685:             $QuicktimeVideoCodecLookup['yuvu'] = 'ComponentVideoSigned';
1686:         }
1687:         return (isset($QuicktimeVideoCodecLookup[$codecid]) ? $QuicktimeVideoCodecLookup[$codecid] : '');
1688:     }
1689: 
1690:     public function QuicktimeAudioCodecLookup($codecid) {
1691:         static $QuicktimeAudioCodecLookup = array();
1692:         if (empty($QuicktimeAudioCodecLookup)) {
1693:             $QuicktimeAudioCodecLookup['.mp3']          = 'Fraunhofer MPEG Layer-III alias';
1694:             $QuicktimeAudioCodecLookup['aac ']          = 'ISO/IEC 14496-3 AAC';
1695:             $QuicktimeAudioCodecLookup['agsm']          = 'Apple GSM 10:1';
1696:             $QuicktimeAudioCodecLookup['alac']          = 'Apple Lossless Audio Codec';
1697:             $QuicktimeAudioCodecLookup['alaw']          = 'A-law 2:1';
1698:             $QuicktimeAudioCodecLookup['conv']          = 'Sample Format';
1699:             $QuicktimeAudioCodecLookup['dvca']          = 'DV';
1700:             $QuicktimeAudioCodecLookup['dvi ']          = 'DV 4:1';
1701:             $QuicktimeAudioCodecLookup['eqal']          = 'Frequency Equalizer';
1702:             $QuicktimeAudioCodecLookup['fl32']          = '32-bit Floating Point';
1703:             $QuicktimeAudioCodecLookup['fl64']          = '64-bit Floating Point';
1704:             $QuicktimeAudioCodecLookup['ima4']          = 'Interactive Multimedia Association 4:1';
1705:             $QuicktimeAudioCodecLookup['in24']          = '24-bit Integer';
1706:             $QuicktimeAudioCodecLookup['in32']          = '32-bit Integer';
1707:             $QuicktimeAudioCodecLookup['lpc ']          = 'LPC 23:1';
1708:             $QuicktimeAudioCodecLookup['MAC3']          = 'Macintosh Audio Compression/Expansion (MACE) 3:1';
1709:             $QuicktimeAudioCodecLookup['MAC6']          = 'Macintosh Audio Compression/Expansion (MACE) 6:1';
1710:             $QuicktimeAudioCodecLookup['mixb']          = '8-bit Mixer';
1711:             $QuicktimeAudioCodecLookup['mixw']          = '16-bit Mixer';
1712:             $QuicktimeAudioCodecLookup['mp4a']          = 'ISO/IEC 14496-3 AAC';
1713:             $QuicktimeAudioCodecLookup['MS'."\x00\x02"] = 'Microsoft ADPCM';
1714:             $QuicktimeAudioCodecLookup['MS'."\x00\x11"] = 'DV IMA';
1715:             $QuicktimeAudioCodecLookup['MS'."\x00\x55"] = 'Fraunhofer MPEG Layer III';
1716:             $QuicktimeAudioCodecLookup['NONE']          = 'No Encoding';
1717:             $QuicktimeAudioCodecLookup['Qclp']          = 'Qualcomm PureVoice';
1718:             $QuicktimeAudioCodecLookup['QDM2']          = 'QDesign Music 2';
1719:             $QuicktimeAudioCodecLookup['QDMC']          = 'QDesign Music 1';
1720:             $QuicktimeAudioCodecLookup['ratb']          = '8-bit Rate';
1721:             $QuicktimeAudioCodecLookup['ratw']          = '16-bit Rate';
1722:             $QuicktimeAudioCodecLookup['raw ']          = 'raw PCM';
1723:             $QuicktimeAudioCodecLookup['sour']          = 'Sound Source';
1724:             $QuicktimeAudioCodecLookup['sowt']          = 'signed/two\'s complement (Little Endian)';
1725:             $QuicktimeAudioCodecLookup['str1']          = 'Iomega MPEG layer II';
1726:             $QuicktimeAudioCodecLookup['str2']          = 'Iomega MPEG *layer II';
1727:             $QuicktimeAudioCodecLookup['str3']          = 'Iomega MPEG **layer II';
1728:             $QuicktimeAudioCodecLookup['str4']          = 'Iomega MPEG ***layer II';
1729:             $QuicktimeAudioCodecLookup['twos']          = 'signed/two\'s complement (Big Endian)';
1730:             $QuicktimeAudioCodecLookup['ulaw']          = 'mu-law 2:1';
1731:         }
1732:         return (isset($QuicktimeAudioCodecLookup[$codecid]) ? $QuicktimeAudioCodecLookup[$codecid] : '');
1733:     }
1734: 
1735:     public function QuicktimeDCOMLookup($compressionid) {
1736:         static $QuicktimeDCOMLookup = array();
1737:         if (empty($QuicktimeDCOMLookup)) {
1738:             $QuicktimeDCOMLookup['zlib'] = 'ZLib Deflate';
1739:             $QuicktimeDCOMLookup['adec'] = 'Apple Compression';
1740:         }
1741:         return (isset($QuicktimeDCOMLookup[$compressionid]) ? $QuicktimeDCOMLookup[$compressionid] : '');
1742:     }
1743: 
1744:     public function QuicktimeColorNameLookup($colordepthid) {
1745:         static $QuicktimeColorNameLookup = array();
1746:         if (empty($QuicktimeColorNameLookup)) {
1747:             $QuicktimeColorNameLookup[1]  = '2-color (monochrome)';
1748:             $QuicktimeColorNameLookup[2]  = '4-color';
1749:             $QuicktimeColorNameLookup[4]  = '16-color';
1750:             $QuicktimeColorNameLookup[8]  = '256-color';
1751:             $QuicktimeColorNameLookup[16] = 'thousands (16-bit color)';
1752:             $QuicktimeColorNameLookup[24] = 'millions (24-bit color)';
1753:             $QuicktimeColorNameLookup[32] = 'millions+ (32-bit color)';
1754:             $QuicktimeColorNameLookup[33] = 'black & white';
1755:             $QuicktimeColorNameLookup[34] = '4-gray';
1756:             $QuicktimeColorNameLookup[36] = '16-gray';
1757:             $QuicktimeColorNameLookup[40] = '256-gray';
1758:         }
1759:         return (isset($QuicktimeColorNameLookup[$colordepthid]) ? $QuicktimeColorNameLookup[$colordepthid] : 'invalid');
1760:     }
1761: 
1762:     public function QuicktimeSTIKLookup($stik) {
1763:         static $QuicktimeSTIKLookup = array();
1764:         if (empty($QuicktimeSTIKLookup)) {
1765:             $QuicktimeSTIKLookup[0]  = 'Movie';
1766:             $QuicktimeSTIKLookup[1]  = 'Normal';
1767:             $QuicktimeSTIKLookup[2]  = 'Audiobook';
1768:             $QuicktimeSTIKLookup[5]  = 'Whacked Bookmark';
1769:             $QuicktimeSTIKLookup[6]  = 'Music Video';
1770:             $QuicktimeSTIKLookup[9]  = 'Short Film';
1771:             $QuicktimeSTIKLookup[10] = 'TV Show';
1772:             $QuicktimeSTIKLookup[11] = 'Booklet';
1773:             $QuicktimeSTIKLookup[14] = 'Ringtone';
1774:             $QuicktimeSTIKLookup[21] = 'Podcast';
1775:         }
1776:         return (isset($QuicktimeSTIKLookup[$stik]) ? $QuicktimeSTIKLookup[$stik] : 'invalid');
1777:     }
1778: 
1779:     public function QuicktimeIODSaudioProfileName($audio_profile_id) {
1780:         static $QuicktimeIODSaudioProfileNameLookup = array();
1781:         if (empty($QuicktimeIODSaudioProfileNameLookup)) {
1782:             $QuicktimeIODSaudioProfileNameLookup = array(
1783:                 0x00 => 'ISO Reserved (0x00)',
1784:                 0x01 => 'Main Audio Profile @ Level 1',
1785:                 0x02 => 'Main Audio Profile @ Level 2',
1786:                 0x03 => 'Main Audio Profile @ Level 3',
1787:                 0x04 => 'Main Audio Profile @ Level 4',
1788:                 0x05 => 'Scalable Audio Profile @ Level 1',
1789:                 0x06 => 'Scalable Audio Profile @ Level 2',
1790:                 0x07 => 'Scalable Audio Profile @ Level 3',
1791:                 0x08 => 'Scalable Audio Profile @ Level 4',
1792:                 0x09 => 'Speech Audio Profile @ Level 1',
1793:                 0x0A => 'Speech Audio Profile @ Level 2',
1794:                 0x0B => 'Synthetic Audio Profile @ Level 1',
1795:                 0x0C => 'Synthetic Audio Profile @ Level 2',
1796:                 0x0D => 'Synthetic Audio Profile @ Level 3',
1797:                 0x0E => 'High Quality Audio Profile @ Level 1',
1798:                 0x0F => 'High Quality Audio Profile @ Level 2',
1799:                 0x10 => 'High Quality Audio Profile @ Level 3',
1800:                 0x11 => 'High Quality Audio Profile @ Level 4',
1801:                 0x12 => 'High Quality Audio Profile @ Level 5',
1802:                 0x13 => 'High Quality Audio Profile @ Level 6',
1803:                 0x14 => 'High Quality Audio Profile @ Level 7',
1804:                 0x15 => 'High Quality Audio Profile @ Level 8',
1805:                 0x16 => 'Low Delay Audio Profile @ Level 1',
1806:                 0x17 => 'Low Delay Audio Profile @ Level 2',
1807:                 0x18 => 'Low Delay Audio Profile @ Level 3',
1808:                 0x19 => 'Low Delay Audio Profile @ Level 4',
1809:                 0x1A => 'Low Delay Audio Profile @ Level 5',
1810:                 0x1B => 'Low Delay Audio Profile @ Level 6',
1811:                 0x1C => 'Low Delay Audio Profile @ Level 7',
1812:                 0x1D => 'Low Delay Audio Profile @ Level 8',
1813:                 0x1E => 'Natural Audio Profile @ Level 1',
1814:                 0x1F => 'Natural Audio Profile @ Level 2',
1815:                 0x20 => 'Natural Audio Profile @ Level 3',
1816:                 0x21 => 'Natural Audio Profile @ Level 4',
1817:                 0x22 => 'Mobile Audio Internetworking Profile @ Level 1',
1818:                 0x23 => 'Mobile Audio Internetworking Profile @ Level 2',
1819:                 0x24 => 'Mobile Audio Internetworking Profile @ Level 3',
1820:                 0x25 => 'Mobile Audio Internetworking Profile @ Level 4',
1821:                 0x26 => 'Mobile Audio Internetworking Profile @ Level 5',
1822:                 0x27 => 'Mobile Audio Internetworking Profile @ Level 6',
1823:                 0x28 => 'AAC Profile @ Level 1',
1824:                 0x29 => 'AAC Profile @ Level 2',
1825:                 0x2A => 'AAC Profile @ Level 4',
1826:                 0x2B => 'AAC Profile @ Level 5',
1827:                 0x2C => 'High Efficiency AAC Profile @ Level 2',
1828:                 0x2D => 'High Efficiency AAC Profile @ Level 3',
1829:                 0x2E => 'High Efficiency AAC Profile @ Level 4',
1830:                 0x2F => 'High Efficiency AAC Profile @ Level 5',
1831:                 0xFE => 'Not part of MPEG-4 audio profiles',
1832:                 0xFF => 'No audio capability required',
1833:             );
1834:         }
1835:         return (isset($QuicktimeIODSaudioProfileNameLookup[$audio_profile_id]) ? $QuicktimeIODSaudioProfileNameLookup[$audio_profile_id] : 'ISO Reserved / User Private');
1836:     }
1837: 
1838: 
1839:     public function QuicktimeIODSvideoProfileName($video_profile_id) {
1840:         static $QuicktimeIODSvideoProfileNameLookup = array();
1841:         if (empty($QuicktimeIODSvideoProfileNameLookup)) {
1842:             $QuicktimeIODSvideoProfileNameLookup = array(
1843:                 0x00 => 'Reserved (0x00) Profile',
1844:                 0x01 => 'Simple Profile @ Level 1',
1845:                 0x02 => 'Simple Profile @ Level 2',
1846:                 0x03 => 'Simple Profile @ Level 3',
1847:                 0x08 => 'Simple Profile @ Level 0',
1848:                 0x10 => 'Simple Scalable Profile @ Level 0',
1849:                 0x11 => 'Simple Scalable Profile @ Level 1',
1850:                 0x12 => 'Simple Scalable Profile @ Level 2',
1851:                 0x15 => 'AVC/H264 Profile',
1852:                 0x21 => 'Core Profile @ Level 1',
1853:                 0x22 => 'Core Profile @ Level 2',
1854:                 0x32 => 'Main Profile @ Level 2',
1855:                 0x33 => 'Main Profile @ Level 3',
1856:                 0x34 => 'Main Profile @ Level 4',
1857:                 0x42 => 'N-bit Profile @ Level 2',
1858:                 0x51 => 'Scalable Texture Profile @ Level 1',
1859:                 0x61 => 'Simple Face Animation Profile @ Level 1',
1860:                 0x62 => 'Simple Face Animation Profile @ Level 2',
1861:                 0x63 => 'Simple FBA Profile @ Level 1',
1862:                 0x64 => 'Simple FBA Profile @ Level 2',
1863:                 0x71 => 'Basic Animated Texture Profile @ Level 1',
1864:                 0x72 => 'Basic Animated Texture Profile @ Level 2',
1865:                 0x81 => 'Hybrid Profile @ Level 1',
1866:                 0x82 => 'Hybrid Profile @ Level 2',
1867:                 0x91 => 'Advanced Real Time Simple Profile @ Level 1',
1868:                 0x92 => 'Advanced Real Time Simple Profile @ Level 2',
1869:                 0x93 => 'Advanced Real Time Simple Profile @ Level 3',
1870:                 0x94 => 'Advanced Real Time Simple Profile @ Level 4',
1871:                 0xA1 => 'Core Scalable Profile @ Level1',
1872:                 0xA2 => 'Core Scalable Profile @ Level2',
1873:                 0xA3 => 'Core Scalable Profile @ Level3',
1874:                 0xB1 => 'Advanced Coding Efficiency Profile @ Level 1',
1875:                 0xB2 => 'Advanced Coding Efficiency Profile @ Level 2',
1876:                 0xB3 => 'Advanced Coding Efficiency Profile @ Level 3',
1877:                 0xB4 => 'Advanced Coding Efficiency Profile @ Level 4',
1878:                 0xC1 => 'Advanced Core Profile @ Level 1',
1879:                 0xC2 => 'Advanced Core Profile @ Level 2',
1880:                 0xD1 => 'Advanced Scalable Texture @ Level1',
1881:                 0xD2 => 'Advanced Scalable Texture @ Level2',
1882:                 0xE1 => 'Simple Studio Profile @ Level 1',
1883:                 0xE2 => 'Simple Studio Profile @ Level 2',
1884:                 0xE3 => 'Simple Studio Profile @ Level 3',
1885:                 0xE4 => 'Simple Studio Profile @ Level 4',
1886:                 0xE5 => 'Core Studio Profile @ Level 1',
1887:                 0xE6 => 'Core Studio Profile @ Level 2',
1888:                 0xE7 => 'Core Studio Profile @ Level 3',
1889:                 0xE8 => 'Core Studio Profile @ Level 4',
1890:                 0xF0 => 'Advanced Simple Profile @ Level 0',
1891:                 0xF1 => 'Advanced Simple Profile @ Level 1',
1892:                 0xF2 => 'Advanced Simple Profile @ Level 2',
1893:                 0xF3 => 'Advanced Simple Profile @ Level 3',
1894:                 0xF4 => 'Advanced Simple Profile @ Level 4',
1895:                 0xF5 => 'Advanced Simple Profile @ Level 5',
1896:                 0xF7 => 'Advanced Simple Profile @ Level 3b',
1897:                 0xF8 => 'Fine Granularity Scalable Profile @ Level 0',
1898:                 0xF9 => 'Fine Granularity Scalable Profile @ Level 1',
1899:                 0xFA => 'Fine Granularity Scalable Profile @ Level 2',
1900:                 0xFB => 'Fine Granularity Scalable Profile @ Level 3',
1901:                 0xFC => 'Fine Granularity Scalable Profile @ Level 4',
1902:                 0xFD => 'Fine Granularity Scalable Profile @ Level 5',
1903:                 0xFE => 'Not part of MPEG-4 Visual profiles',
1904:                 0xFF => 'No visual capability required',
1905:             );
1906:         }
1907:         return (isset($QuicktimeIODSvideoProfileNameLookup[$video_profile_id]) ? $QuicktimeIODSvideoProfileNameLookup[$video_profile_id] : 'ISO Reserved Profile');
1908:     }
1909: 
1910: 
1911:     public function QuicktimeContentRatingLookup($rtng) {
1912:         static $QuicktimeContentRatingLookup = array();
1913:         if (empty($QuicktimeContentRatingLookup)) {
1914:             $QuicktimeContentRatingLookup[0]  = 'None';
1915:             $QuicktimeContentRatingLookup[2]  = 'Clean';
1916:             $QuicktimeContentRatingLookup[4]  = 'Explicit';
1917:         }
1918:         return (isset($QuicktimeContentRatingLookup[$rtng]) ? $QuicktimeContentRatingLookup[$rtng] : 'invalid');
1919:     }
1920: 
1921:     public function QuicktimeStoreAccountTypeLookup($akid) {
1922:         static $QuicktimeStoreAccountTypeLookup = array();
1923:         if (empty($QuicktimeStoreAccountTypeLookup)) {
1924:             $QuicktimeStoreAccountTypeLookup[0] = 'iTunes';
1925:             $QuicktimeStoreAccountTypeLookup[1] = 'AOL';
1926:         }
1927:         return (isset($QuicktimeStoreAccountTypeLookup[$akid]) ? $QuicktimeStoreAccountTypeLookup[$akid] : 'invalid');
1928:     }
1929: 
1930:     public function QuicktimeStoreFrontCodeLookup($sfid) {
1931:         static $QuicktimeStoreFrontCodeLookup = array();
1932:         if (empty($QuicktimeStoreFrontCodeLookup)) {
1933:             $QuicktimeStoreFrontCodeLookup[143460] = 'Australia';
1934:             $QuicktimeStoreFrontCodeLookup[143445] = 'Austria';
1935:             $QuicktimeStoreFrontCodeLookup[143446] = 'Belgium';
1936:             $QuicktimeStoreFrontCodeLookup[143455] = 'Canada';
1937:             $QuicktimeStoreFrontCodeLookup[143458] = 'Denmark';
1938:             $QuicktimeStoreFrontCodeLookup[143447] = 'Finland';
1939:             $QuicktimeStoreFrontCodeLookup[143442] = 'France';
1940:             $QuicktimeStoreFrontCodeLookup[143443] = 'Germany';
1941:             $QuicktimeStoreFrontCodeLookup[143448] = 'Greece';
1942:             $QuicktimeStoreFrontCodeLookup[143449] = 'Ireland';
1943:             $QuicktimeStoreFrontCodeLookup[143450] = 'Italy';
1944:             $QuicktimeStoreFrontCodeLookup[143462] = 'Japan';
1945:             $QuicktimeStoreFrontCodeLookup[143451] = 'Luxembourg';
1946:             $QuicktimeStoreFrontCodeLookup[143452] = 'Netherlands';
1947:             $QuicktimeStoreFrontCodeLookup[143461] = 'New Zealand';
1948:             $QuicktimeStoreFrontCodeLookup[143457] = 'Norway';
1949:             $QuicktimeStoreFrontCodeLookup[143453] = 'Portugal';
1950:             $QuicktimeStoreFrontCodeLookup[143454] = 'Spain';
1951:             $QuicktimeStoreFrontCodeLookup[143456] = 'Sweden';
1952:             $QuicktimeStoreFrontCodeLookup[143459] = 'Switzerland';
1953:             $QuicktimeStoreFrontCodeLookup[143444] = 'United Kingdom';
1954:             $QuicktimeStoreFrontCodeLookup[143441] = 'United States';
1955:         }
1956:         return (isset($QuicktimeStoreFrontCodeLookup[$sfid]) ? $QuicktimeStoreFrontCodeLookup[$sfid] : 'invalid');
1957:     }
1958: 
1959:     public function QuicktimeParseNikonNCTG($atom_data) {
1960:         // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
1961:         // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
1962:         // Data is stored as records of:
1963:         // * 4 bytes record type
1964:         // * 2 bytes size of data field type:
1965:         //     0x0001 = flag   (size field *= 1-byte)
1966:         //     0x0002 = char   (size field *= 1-byte)
1967:         //     0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB
1968:         //     0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD
1969:         //     0x0005 = float  (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together
1970:         //     0x0007 = bytes  (size field *= 1-byte), values are stored as ??????
1971:         //     0x0008 = ?????  (size field *= 2-byte), values are stored as ??????
1972:         // * 2 bytes data size field
1973:         // * ? bytes data (string data may be null-padded; datestamp fields are in the format "2011:05:25 20:24:15")
1974:         // all integers are stored BigEndian
1975: 
1976:         $NCTGtagName = array(
1977:             0x00000001 => 'Make',
1978:             0x00000002 => 'Model',
1979:             0x00000003 => 'Software',
1980:             0x00000011 => 'CreateDate',
1981:             0x00000012 => 'DateTimeOriginal',
1982:             0x00000013 => 'FrameCount',
1983:             0x00000016 => 'FrameRate',
1984:             0x00000022 => 'FrameWidth',
1985:             0x00000023 => 'FrameHeight',
1986:             0x00000032 => 'AudioChannels',
1987:             0x00000033 => 'AudioBitsPerSample',
1988:             0x00000034 => 'AudioSampleRate',
1989:             0x02000001 => 'MakerNoteVersion',
1990:             0x02000005 => 'WhiteBalance',
1991:             0x0200000b => 'WhiteBalanceFineTune',
1992:             0x0200001e => 'ColorSpace',
1993:             0x02000023 => 'PictureControlData',
1994:             0x02000024 => 'WorldTime',
1995:             0x02000032 => 'UnknownInfo',
1996:             0x02000083 => 'LensType',
1997:             0x02000084 => 'Lens',
1998:         );
1999: 
2000:         $offset = 0;
2001:         $datalength = strlen($atom_data);
2002:         $parsed = array();
2003:         while ($offset < $datalength) {
2004: //echo getid3_lib::PrintHexBytes(substr($atom_data, $offset, 4)).'<br>';
2005:             $record_type       = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4));  $offset += 4;
2006:             $data_size_type    = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));  $offset += 2;
2007:             $data_size         = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));  $offset += 2;
2008:             switch ($data_size_type) {
2009:                 case 0x0001: // 0x0001 = flag   (size field *= 1-byte)
2010:                     $data = getid3_lib::BigEndian2Int(substr($atom_data, $offset, $data_size * 1));
2011:                     $offset += ($data_size * 1);
2012:                     break;
2013:                 case 0x0002: // 0x0002 = char   (size field *= 1-byte)
2014:                     $data = substr($atom_data, $offset, $data_size * 1);
2015:                     $offset += ($data_size * 1);
2016:                     $data = rtrim($data, "\x00");
2017:                     break;
2018:                 case 0x0003: // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB
2019:                     $data = '';
2020:                     for ($i = $data_size - 1; $i >= 0; $i--) {
2021:                         $data .= substr($atom_data, $offset + ($i * 2), 2);
2022:                     }
2023:                     $data = getid3_lib::BigEndian2Int($data);
2024:                     $offset += ($data_size * 2);
2025:                     break;
2026:                 case 0x0004: // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD
2027:                     $data = '';
2028:                     for ($i = $data_size - 1; $i >= 0; $i--) {
2029:                         $data .= substr($atom_data, $offset + ($i * 4), 4);
2030:                     }
2031:                     $data = getid3_lib::BigEndian2Int($data);
2032:                     $offset += ($data_size * 4);
2033:                     break;
2034:                 case 0x0005: // 0x0005 = float  (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together
2035:                     $data = array();
2036:                     for ($i = 0; $i < $data_size; $i++) {
2037:                         $numerator    = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 0, 4));
2038:                         $denomninator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 4, 4));
2039:                         if ($denomninator == 0) {
2040:                             $data[$i] = false;
2041:                         } else {
2042:                             $data[$i] = (double) $numerator / $denomninator;
2043:                         }
2044:                     }
2045:                     $offset += (8 * $data_size);
2046:                     if (count($data) == 1) {
2047:                         $data = $data[0];
2048:                     }
2049:                     break;
2050:                 case 0x0007: // 0x0007 = bytes  (size field *= 1-byte), values are stored as ??????
2051:                     $data = substr($atom_data, $offset, $data_size * 1);
2052:                     $offset += ($data_size * 1);
2053:                     break;
2054:                 case 0x0008: // 0x0008 = ?????  (size field *= 2-byte), values are stored as ??????
2055:                     $data = substr($atom_data, $offset, $data_size * 2);
2056:                     $offset += ($data_size * 2);
2057:                     break;
2058:                 default:
2059: echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br>';
2060:                     break 2;
2061:             }
2062: 
2063:             switch ($record_type) {
2064:                 case 0x00000011: // CreateDate
2065:                 case 0x00000012: // DateTimeOriginal
2066:                     $data = strtotime($data);
2067:                     break;
2068:                 case 0x0200001e: // ColorSpace
2069:                     switch ($data) {
2070:                         case 1:
2071:                             $data = 'sRGB';
2072:                             break;
2073:                         case 2:
2074:                             $data = 'Adobe RGB';
2075:                             break;
2076:                     }
2077:                     break;
2078:                 case 0x02000023: // PictureControlData
2079:                     $PictureControlAdjust = array(0=>'default', 1=>'quick', 2=>'full');
2080:                     $FilterEffect = array(0x80=>'off', 0x81=>'yellow', 0x82=>'orange',    0x83=>'red', 0x84=>'green',  0xff=>'n/a');
2081:                     $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');
2082:                     $data = array(
2083:                         'PictureControlVersion'     =>                           substr($data,  0,  4),
2084:                         'PictureControlName'        =>                     rtrim(substr($data,  4, 20), "\x00"),
2085:                         'PictureControlBase'        =>                     rtrim(substr($data, 24, 20), "\x00"),
2086:                         //'?'                       =>                           substr($data, 44,  4),
2087:                         'PictureControlAdjust'      => $PictureControlAdjust[ord(substr($data, 48,  1))],
2088:                         'PictureControlQuickAdjust' =>                       ord(substr($data, 49,  1)),
2089:                         'Sharpness'                 =>                       ord(substr($data, 50,  1)),
2090:                         'Contrast'                  =>                       ord(substr($data, 51,  1)),
2091:                         'Brightness'                =>                       ord(substr($data, 52,  1)),
2092:                         'Saturation'                =>                       ord(substr($data, 53,  1)),
2093:                         'HueAdjustment'             =>                       ord(substr($data, 54,  1)),
2094:                         'FilterEffect'              =>         $FilterEffect[ord(substr($data, 55,  1))],
2095:                         'ToningEffect'              =>         $ToningEffect[ord(substr($data, 56,  1))],
2096:                         'ToningSaturation'          =>                       ord(substr($data, 57,  1)),
2097:                     );
2098:                     break;
2099:                 case 0x02000024: // WorldTime
2100:                     // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#WorldTime
2101:                     // timezone is stored as offset from GMT in minutes
2102:                     $timezone = getid3_lib::BigEndian2Int(substr($data, 0, 2));
2103:                     if ($timezone & 0x8000) {
2104:                         $timezone = 0 - (0x10000 - $timezone);
2105:                     }
2106:                     $timezone /= 60;
2107: 
2108:                     $dst = (bool) getid3_lib::BigEndian2Int(substr($data, 2, 1));
2109:                     switch (getid3_lib::BigEndian2Int(substr($data, 3, 1))) {
2110:                         case 2:
2111:                             $datedisplayformat = 'D/M/Y'; break;
2112:                         case 1:
2113:                             $datedisplayformat = 'M/D/Y'; break;
2114:                         case 0:
2115:                         default:
2116:                             $datedisplayformat = 'Y/M/D'; break;
2117:                     }
2118: 
2119:                     $data = array('timezone'=>floatval($timezone), 'dst'=>$dst, 'display'=>$datedisplayformat);
2120:                     break;
2121:                 case 0x02000083: // LensType
2122:                     $data = array(
2123:                         //'_'  => $data,
2124:                         'mf' => (bool) ($data & 0x01),
2125:                         'd'  => (bool) ($data & 0x02),
2126:                         'g'  => (bool) ($data & 0x04),
2127:                         'vr' => (bool) ($data & 0x08),
2128:                     );
2129:                     break;
2130:             }
2131:             $tag_name = (isset($NCTGtagName[$record_type]) ? $NCTGtagName[$record_type] : '0x'.str_pad(dechex($record_type), 8, '0', STR_PAD_LEFT));
2132:             $parsed[$tag_name] = $data;
2133:         }
2134:         return $parsed;
2135:     }
2136: 
2137: 
2138:     public function CopyToAppropriateCommentsSection($keyname, $data, $boxname='') {
2139:         static $handyatomtranslatorarray = array();
2140:         if (empty($handyatomtranslatorarray)) {
2141:             // http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
2142:             // http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
2143:             // http://atomicparsley.sourceforge.net/mpeg-4files.html
2144:             // https://code.google.com/p/mp4v2/wiki/iTunesMetadata
2145:             $handyatomtranslatorarray["\xA9".'alb'] = 'album';               // iTunes 4.0
2146:             $handyatomtranslatorarray["\xA9".'ART'] = 'artist';
2147:             $handyatomtranslatorarray["\xA9".'art'] = 'artist';              // iTunes 4.0
2148:             $handyatomtranslatorarray["\xA9".'aut'] = 'author';
2149:             $handyatomtranslatorarray["\xA9".'cmt'] = 'comment';             // iTunes 4.0
2150:             $handyatomtranslatorarray["\xA9".'com'] = 'comment';
2151:             $handyatomtranslatorarray["\xA9".'cpy'] = 'copyright';
2152:             $handyatomtranslatorarray["\xA9".'day'] = 'creation_date';       // iTunes 4.0
2153:             $handyatomtranslatorarray["\xA9".'dir'] = 'director';
2154:             $handyatomtranslatorarray["\xA9".'ed1'] = 'edit1';
2155:             $handyatomtranslatorarray["\xA9".'ed2'] = 'edit2';
2156:             $handyatomtranslatorarray["\xA9".'ed3'] = 'edit3';
2157:             $handyatomtranslatorarray["\xA9".'ed4'] = 'edit4';
2158:             $handyatomtranslatorarray["\xA9".'ed5'] = 'edit5';
2159:             $handyatomtranslatorarray["\xA9".'ed6'] = 'edit6';
2160:             $handyatomtranslatorarray["\xA9".'ed7'] = 'edit7';
2161:             $handyatomtranslatorarray["\xA9".'ed8'] = 'edit8';
2162:             $handyatomtranslatorarray["\xA9".'ed9'] = 'edit9';
2163:             $handyatomtranslatorarray["\xA9".'enc'] = 'encoded_by';
2164:             $handyatomtranslatorarray["\xA9".'fmt'] = 'format';
2165:             $handyatomtranslatorarray["\xA9".'gen'] = 'genre';               // iTunes 4.0
2166:             $handyatomtranslatorarray["\xA9".'grp'] = 'grouping';            // iTunes 4.2
2167:             $handyatomtranslatorarray["\xA9".'hst'] = 'host_computer';
2168:             $handyatomtranslatorarray["\xA9".'inf'] = 'information';
2169:             $handyatomtranslatorarray["\xA9".'lyr'] = 'lyrics';              // iTunes 5.0
2170:             $handyatomtranslatorarray["\xA9".'mak'] = 'make';
2171:             $handyatomtranslatorarray["\xA9".'mod'] = 'model';
2172:             $handyatomtranslatorarray["\xA9".'nam'] = 'title';               // iTunes 4.0
2173:             $handyatomtranslatorarray["\xA9".'ope'] = 'composer';
2174:             $handyatomtranslatorarray["\xA9".'prd'] = 'producer';
2175:             $handyatomtranslatorarray["\xA9".'PRD'] = 'product';
2176:             $handyatomtranslatorarray["\xA9".'prf'] = 'performers';
2177:             $handyatomtranslatorarray["\xA9".'req'] = 'system_requirements';
2178:             $handyatomtranslatorarray["\xA9".'src'] = 'source_credit';
2179:             $handyatomtranslatorarray["\xA9".'swr'] = 'software';
2180:             $handyatomtranslatorarray["\xA9".'too'] = 'encoding_tool';       // iTunes 4.0
2181:             $handyatomtranslatorarray["\xA9".'trk'] = 'track';
2182:             $handyatomtranslatorarray["\xA9".'url'] = 'url';
2183:             $handyatomtranslatorarray["\xA9".'wrn'] = 'warning';
2184:             $handyatomtranslatorarray["\xA9".'wrt'] = 'composer';
2185:             $handyatomtranslatorarray['aART'] = 'album_artist';
2186:             $handyatomtranslatorarray['apID'] = 'purchase_account';
2187:             $handyatomtranslatorarray['catg'] = 'category';            // iTunes 4.9
2188:             $handyatomtranslatorarray['covr'] = 'picture';             // iTunes 4.0
2189:             $handyatomtranslatorarray['cpil'] = 'compilation';         // iTunes 4.0
2190:             $handyatomtranslatorarray['cprt'] = 'copyright';           // iTunes 4.0?
2191:             $handyatomtranslatorarray['desc'] = 'description';         // iTunes 5.0
2192:             $handyatomtranslatorarray['disk'] = 'disc_number';         // iTunes 4.0
2193:             $handyatomtranslatorarray['egid'] = 'episode_guid';        // iTunes 4.9
2194:             $handyatomtranslatorarray['gnre'] = 'genre';               // iTunes 4.0
2195:             $handyatomtranslatorarray['hdvd'] = 'hd_video';            // iTunes 4.0
2196:             $handyatomtranslatorarray['ldes'] = 'description_long';    //
2197:             $handyatomtranslatorarray['keyw'] = 'keyword';             // iTunes 4.9
2198:             $handyatomtranslatorarray['pcst'] = 'podcast';             // iTunes 4.9
2199:             $handyatomtranslatorarray['pgap'] = 'gapless_playback';    // iTunes 7.0
2200:             $handyatomtranslatorarray['purd'] = 'purchase_date';       // iTunes 6.0.2
2201:             $handyatomtranslatorarray['purl'] = 'podcast_url';         // iTunes 4.9
2202:             $handyatomtranslatorarray['rtng'] = 'rating';              // iTunes 4.0
2203:             $handyatomtranslatorarray['soaa'] = 'sort_album_artist';   //
2204:             $handyatomtranslatorarray['soal'] = 'sort_album';          //
2205:             $handyatomtranslatorarray['soar'] = 'sort_artist';         //
2206:             $handyatomtranslatorarray['soco'] = 'sort_composer';       //
2207:             $handyatomtranslatorarray['sonm'] = 'sort_title';          //
2208:             $handyatomtranslatorarray['sosn'] = 'sort_show';           //
2209:             $handyatomtranslatorarray['stik'] = 'stik';                // iTunes 4.9
2210:             $handyatomtranslatorarray['tmpo'] = 'bpm';                 // iTunes 4.0
2211:             $handyatomtranslatorarray['trkn'] = 'track_number';        // iTunes 4.0
2212:             $handyatomtranslatorarray['tven'] = 'tv_episode_id';       //
2213:             $handyatomtranslatorarray['tves'] = 'tv_episode';          // iTunes 6.0
2214:             $handyatomtranslatorarray['tvnn'] = 'tv_network_name';     // iTunes 6.0
2215:             $handyatomtranslatorarray['tvsh'] = 'tv_show_name';        // iTunes 6.0
2216:             $handyatomtranslatorarray['tvsn'] = 'tv_season';           // iTunes 6.0
2217: 
2218:             // boxnames:
2219:             /*
2220:             $handyatomtranslatorarray['iTunSMPB']                    = 'iTunSMPB';
2221:             $handyatomtranslatorarray['iTunNORM']                    = 'iTunNORM';
2222:             $handyatomtranslatorarray['Encoding Params']             = 'Encoding Params';
2223:             $handyatomtranslatorarray['replaygain_track_gain']       = 'replaygain_track_gain';
2224:             $handyatomtranslatorarray['replaygain_track_peak']       = 'replaygain_track_peak';
2225:             $handyatomtranslatorarray['replaygain_track_minmax']     = 'replaygain_track_minmax';
2226:             $handyatomtranslatorarray['MusicIP PUID']                = 'MusicIP PUID';
2227:             $handyatomtranslatorarray['MusicBrainz Artist Id']       = 'MusicBrainz Artist Id';
2228:             $handyatomtranslatorarray['MusicBrainz Album Id']        = 'MusicBrainz Album Id';
2229:             $handyatomtranslatorarray['MusicBrainz Album Artist Id'] = 'MusicBrainz Album Artist Id';
2230:             $handyatomtranslatorarray['MusicBrainz Track Id']        = 'MusicBrainz Track Id';
2231:             $handyatomtranslatorarray['MusicBrainz Disc Id']         = 'MusicBrainz Disc Id';
2232: 
2233:             // http://age.hobba.nl/audio/tag_frame_reference.html
2234:             $handyatomtranslatorarray['PLAY_COUNTER']                = 'play_counter'; // Foobar2000 - http://www.getid3.org/phpBB3/viewtopic.php?t=1355
2235:             $handyatomtranslatorarray['MEDIATYPE']                   = 'mediatype';    // Foobar2000 - http://www.getid3.org/phpBB3/viewtopic.php?t=1355
2236:             */
2237:         }
2238:         $info = &$this->getid3->info;
2239:         $comment_key = '';
2240:         if ($boxname && ($boxname != $keyname)) {
2241:             $comment_key = (isset($handyatomtranslatorarray[$boxname]) ? $handyatomtranslatorarray[$boxname] : $boxname);
2242:         } elseif (isset($handyatomtranslatorarray[$keyname])) {
2243:             $comment_key = $handyatomtranslatorarray[$keyname];
2244:         }
2245:         if ($comment_key) {
2246:             if ($comment_key == 'picture') {
2247:                 if (!is_array($data)) {
2248:                     $image_mime = '';
2249:                     if (preg_match('#^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A#', $data)) {
2250:                         $image_mime = 'image/png';
2251:                     } elseif (preg_match('#^\xFF\xD8\xFF#', $data)) {
2252:                         $image_mime = 'image/jpeg';
2253:                     } elseif (preg_match('#^GIF#', $data)) {
2254:                         $image_mime = 'image/gif';
2255:                     } elseif (preg_match('#^BM#', $data)) {
2256:                         $image_mime = 'image/bmp';
2257:                     }
2258:                     $data = array('data'=>$data, 'image_mime'=>$image_mime);
2259:                 }
2260:             }
2261:             $gooddata = array($data);
2262:             if ($comment_key == 'genre') {
2263:                 // some other taggers separate multiple genres with semicolon, e.g. "Heavy Metal;Thrash Metal;Metal"
2264:                 $gooddata = explode(';', $data);
2265:             }
2266:             foreach ($gooddata as $data) {
2267:                 $info['quicktime']['comments'][$comment_key][] = $data;
2268:             }
2269:         }
2270:         return true;
2271:     }
2272: 
2273:     public function NoNullString($nullterminatedstring) {
2274:         // remove the single null terminator on null terminated strings
2275:         if (substr($nullterminatedstring, strlen($nullterminatedstring) - 1, 1) === "\x00") {
2276:             return substr($nullterminatedstring, 0, strlen($nullterminatedstring) - 1);
2277:         }
2278:         return $nullterminatedstring;
2279:     }
2280: 
2281:     public function Pascal2String($pascalstring) {
2282:         // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string
2283:         return substr($pascalstring, 1);
2284:     }
2285: 
2286: }
2287: 
Zenphoto doc API documentation generated by ApiGen