Overview

Namespaces

  • Composer
    • Autoload
  • Geekwright
    • RegDom
  • League
    • OAuth2
      • Client
        • Provider
  • None
  • Xmf
    • Database
    • Jwt
    • Key
    • Module
      • Helper

Classes

  • ArtObject
  • ArtObjectHandler
  • BloggerApi
  • CGIF
  • CGIFCOLORTABLE
  • CGIFFILEHEADER
  • CGIFIMAGE
  • CGIFIMAGEHEADER
  • CGIFLZW
  • Composer\Autoload\ClassLoader
  • Composer\Autoload\ComposerStaticInit274e5fff219a4f27a346e611b0580d6a
  • ComposerAutoloaderInit274e5fff219a4f27a346e611b0580d6a
  • Config_File
  • Cookie
  • Criteria
  • CriteriaCompo
  • CriteriaElement
  • Database
  • Db_manager
  • ErrorHandler
  • FormDhtmlTextArea
  • FormTextArea
  • Geekwright\RegDom\PublicSuffixList
  • Geekwright\RegDom\RegisteredDomain
  • HTMLPurifier
  • League\OAuth2\Client\Provider\Google
  • MetaWeblogApi
  • ModuleAdmin
  • MovableTypeApi
  • MyTextSanitizer
  • MyTextSanitizerExtended
  • MyTextSanitizerExtension
  • MytsCensor
  • MytsFlash
  • MytsIframe
  • MytsImage
  • MytsLi
  • MytsMms
  • MytsMp3
  • MytsRtsp
  • MytsSoundcloud
  • MytsSyntaxhighlight
  • MytsTextfilter
  • MytsUl
  • MytsWiki
  • MytsWmp
  • MytsYoutube
  • PathStuffController
  • PHPMailer
  • PHPMailerOAuth
  • PHPMailerOAuthGoogle
  • phpthumb
  • phpthumb_bmp
  • phpthumb_filters
  • phpthumb_functions
  • phpthumb_ico
  • phpUnsharpMask
  • PmCorePreload
  • PmMessage
  • PmMessageHandler
  • PmSystemPreload
  • POP3
  • ProfileCategory
  • ProfileCategoryHandler
  • ProfileCorePreload
  • ProfileField
  • ProfileFieldHandler
  • ProfileProfile
  • ProfileProfileHandler
  • ProfileRegstep
  • ProfileRegstepHandler
  • ProfileVisibility
  • ProfileVisibilityHandler
  • Protector
  • Protector_bruteforce_overrun_message
  • Protector_crawler_overrun_message
  • Protector_f5attack_overrun_message
  • Protector_postcommon_post_deny_by_httpbl
  • Protector_postcommon_post_deny_by_rbl
  • Protector_postcommon_post_htmlpurify4everyone
  • Protector_postcommon_post_htmlpurify4guest
  • Protector_postcommon_post_language_match
  • Protector_postcommon_post_need_multibyte
  • Protector_postcommon_post_register_moratorium
  • Protector_postcommon_post_stopforumspam
  • Protector_postcommon_register_insert_js_check
  • Protector_postcommon_register_stopforumspam
  • Protector_precommon_badip_errorlog
  • Protector_precommon_badip_message
  • Protector_precommon_badip_redirection
  • Protector_precommon_bwlimit_errorlog
  • Protector_precommon_bwlimit_message
  • Protector_prepurge_exit_message
  • Protector_spamcheck_overrun_message
  • ProtectorCorePreload
  • ProtectorFilterAbstract
  • ProtectorFilterHandler
  • ProtectorMySQLDatabase
  • ProtectorRegistry
  • ReCaptchaResponse
  • RpcArrayHandler
  • RpcBase64Handler
  • RpcBooleanHandler
  • RpcDateTimeHandler
  • RpcDoubleHandler
  • RpcIntHandler
  • RpcMemberHandler
  • RpcMethodNameHandler
  • RpcNameHandler
  • RpcStringHandler
  • RpcStructHandler
  • RpcValueHandler
  • RssAuthorHandler
  • RssCategoryHandler
  • RssChannelHandler
  • RssCommentsHandler
  • RssCopyrightHandler
  • RssDescriptionHandler
  • RssDocsHandler
  • RssGeneratorHandler
  • RssGuidHandler
  • RssHeightHandler
  • RssImageHandler
  • RssItemHandler
  • RssLanguageHandler
  • RssLastBuildDateHandler
  • RssLinkHandler
  • RssManagingEditorHandler
  • RssNameHandler
  • RssPubDateHandler
  • RssSourceHandler
  • RssTextInputHandler
  • RssTitleHandler
  • RssTtlHandler
  • RssUrlHandler
  • RssWebMasterHandler
  • RssWidthHandler
  • SaxParser
  • Smarty
  • Smarty_Compiler
  • SMTP
  • Snoopy
  • SqlUtility
  • SystemAvatar
  • SystemAvatarHandler
  • SystemBanner
  • SystemBannerclient
  • SystemBannerclientHandler
  • SystemBannerFinish
  • SystemBannerfinishHandler
  • SystemBannerHandler
  • SystemBlock
  • SystemBlockHandler
  • SystemBlockLinkModule
  • SystemBlockLinkModuleHandler
  • SystemBreadcrumb
  • SystemCorePreload
  • SystemFineAvatarUploadHandler
  • SystemFineImUploadHandler
  • SystemFineUploadHandler
  • SystemGroup
  • SystemGroupHandler
  • SystemMaintenance
  • SystemMenuHandler
  • SystemSmilies
  • SystemsmiliesHandler
  • SystemUserrank
  • SystemuserrankHandler
  • SystemUsers
  • SystemUsersHandler
  • Tar
  • ThemeSetAuthorHandler
  • ThemeSetDateCreatedHandler
  • ThemeSetDescriptionHandler
  • ThemeSetEmailHandler
  • ThemeSetFileTypeHandler
  • ThemeSetGeneratorHandler
  • ThemeSetImageHandler
  • ThemeSetLinkHandler
  • ThemeSetModuleHandler
  • ThemeSetNameHandler
  • ThemeSetTagHandler
  • ThemeSetTemplateHandler
  • TinyMCE
  • Xmf\Assert
  • Xmf\Database\Migrate
  • Xmf\Database\TableLoad
  • Xmf\Database\Tables
  • Xmf\Debug
  • Xmf\FilterInput
  • Xmf\Highlighter
  • Xmf\IPAddress
  • Xmf\Jwt\JsonWebToken
  • Xmf\Jwt\KeyFactory
  • Xmf\Jwt\TokenFactory
  • Xmf\Jwt\TokenReader
  • Xmf\Key\ArrayStorage
  • Xmf\Key\Basic
  • Xmf\Key\FileStorage
  • Xmf\Key\KeyAbstract
  • Xmf\Language
  • Xmf\Metagen
  • Xmf\Module\Admin
  • Xmf\Module\Helper
  • Xmf\Module\Helper\AbstractHelper
  • Xmf\Module\Helper\Cache
  • Xmf\Module\Helper\GenericHelper
  • Xmf\Module\Helper\Permission
  • Xmf\Module\Helper\Session
  • Xmf\Random
  • Xmf\Request
  • Xmf\StopWords
  • Xmf\Yaml
  • XmlTagHandler
  • XoopsApi
  • xoopsart
  • XoopsAuth
  • XoopsAuthAds
  • XoopsAuthFactory
  • XoopsAuthLdap
  • XoopsAuthProvisionning
  • XoopsAuthXoops
  • XoopsAvatar
  • XoopsAvatarHandler
  • XoopsBlock
  • XoopsBlockHandler
  • XoopsBlockInstance
  • XoopsBlockInstanceHandler
  • XoopsCache
  • XoopsCacheApc
  • XoopsCacheEngine
  • XoopsCacheFile
  • XoopsCacheMemcache
  • XoopsCacheModel
  • XoopsCacheModelHandler
  • XoopsCacheModelObject
  • XoopsCacheXcache
  • XoopsCaptcha
  • XoopsCaptchaImage
  • XoopsCaptchaImageHandler
  • XoopsCaptchaMethod
  • XoopsCaptchaRecaptcha
  • XoopsCaptchaRecaptcha2
  • XoopsCaptchaText
  • XoopsComment
  • XoopsCommentHandler
  • XoopsCommentRenderer
  • XoopsComments
  • XoopsConfigCategory
  • XoopsConfigCategoryHandler
  • XoopsConfigHandler
  • XoopsConfigItem
  • XoopsConfigItemHandler
  • XoopsConfigOption
  • XoopsConfigOptionHandler
  • XoopsDatabase
  • XoopsDatabaseFactory
  • XoopsDownloader
  • XoopsEditor
  • XoopsEditorHandler
  • XoopsErrorHandler
  • XoopsFile
  • XoopsFileHandler
  • XoopsFilterInput
  • XoopsFolderHandler
  • XoopsForm
  • XoopsFormButton
  • XoopsFormButtonTray
  • XoopsFormCaptcha
  • XoopsFormCheckBox
  • XoopsFormColorPicker
  • XoopsFormDateTime
  • XoopsFormDhtmlTextArea
  • XoopsFormEditor
  • XoopsFormElement
  • XoopsFormElementTray
  • XoopsFormFile
  • XoopsFormHidden
  • XoopsFormHiddenToken
  • XoopsFormLabel
  • XoopsFormPassword
  • XoopsFormRadio
  • XoopsFormRadioYN
  • XoopsFormRenderer
  • XoopsFormRendererBootstrap3
  • XoopsFormRendererLegacy
  • XoopsFormSelect
  • XoopsFormSelectCheckGroup
  • XoopsFormSelectCountry
  • XoopsFormSelectEditor
  • XoopsFormSelectGroup
  • XoopsFormSelectLang
  • XoopsFormSelectMatchOption
  • XoopsFormSelectTheme
  • XoopsFormSelectTimezone
  • XoopsFormSelectUser
  • XoopsFormText
  • XoopsFormTextArea
  • XoopsFormTextDateSelect
  • XoopsFormTinymce
  • XoopsGroup
  • XoopsGroupFormCheckBox
  • XoopsGroupHandler
  • XoopsGroupPerm
  • XoopsGroupPermForm
  • XoopsGroupPermHandler
  • XoopsGTicket
  • XoopsGuestUser
  • XoopsGuiDefault
  • XoopsGuiThadmin
  • XoopsGuiTransition
  • XoopsGuiZetadigme
  • XoopsHandlerRegistry
  • XoopsImage
  • XoopsImagecategory
  • XoopsImagecategoryHandler
  • XoopsImageHandler
  • XoopsImageSet
  • XoopsImagesetHandler
  • XoopsImagesetimg
  • XoopsImagesetimgHandler
  • XoopsInstallWizard
  • XoopsLists
  • XoopsLoad
  • XoopsLocal
  • XoopsLocalAbstract
  • XoopsLocalWrapper
  • XoopsLogger
  • XoopsMailer
  • XoopsMailerLocal
  • XoopsMediaUploader
  • XoopsMemberHandler
  • XoopsMembership
  • XoopsMembershipHandler
  • XoopsModelAbstract
  • XoopsModelFactory
  • XoopsModelJoint
  • XoopsModelRead
  • XoopsModelStats
  • XoopsModelSync
  • XoopsModelWrite
  • XoopsModule
  • XoopsModuleHandler
  • XoopsMultiMailer
  • XoopsMySQLDatabase
  • XoopsMySQLDatabaseProxy
  • XoopsMySQLDatabaseSafe
  • XoopsNotification
  • XoopsNotificationHandler
  • XoopsObject
  • XoopsObjectHandler
  • XoopsObjectTree
  • XoopsOnlineHandler
  • XoopsPageNav
  • XoopsPersistableObjectHandler
  • XoopsPreload
  • XoopsPreloadItem
  • XoopsPrivmessage
  • XoopsPrivmessageHandler
  • XoopsRank
  • XoopsRankHandler
  • XoopsRequest
  • XoopsSecurity
  • XoopsSessionHandler
  • XoopsSimpleForm
  • XoopsStory
  • XoopsSystemCpanel
  • XoopsSystemGui
  • XoopsTableForm
  • XoopsTarDownloader
  • XoopsThemeForm
  • XoopsThemeSetParser
  • XoopsTopic
  • XoopsTpl
  • XoopsTplfile
  • XoopsTplfileHandler
  • XoopsTplset
  • XoopsTplsetHandler
  • XoopsTree
  • XoopsUser
  • XoopsUserHandler
  • XoopsUserUtility
  • XoopsUtility
  • XoopsXmlRpcApi
  • XoopsXmlRpcArray
  • XoopsXmlRpcBase64
  • XoopsXmlRpcBoolean
  • XoopsXmlRpcDatetime
  • XoopsXmlRpcDocument
  • XoopsXmlRpcDouble
  • XoopsXmlRpcFault
  • XoopsXmlRpcInt
  • XoopsXmlRpcParser
  • XoopsXmlRpcRequest
  • XoopsXmlRpcResponse
  • XoopsXmlRpcString
  • XoopsXmlRpcStruct
  • XoopsXmlRpcTag
  • XoopsXmlRss2Parser
  • XoopsZipDownloader
  • xos_kernel_Xoops2
  • xos_logos_PageBuilder
  • xos_opal_AdminThemeFactory
  • xos_opal_Theme
  • xos_opal_ThemeFactory
  • XoUser
  • XoUserHandler
  • Zipfile

Interfaces

  • Xmf\Key\StorageInterface
  • XoopsFormRendererInterface

Exceptions

  • phpmailerException

Functions

  • __autoload
  • _recaptcha_aes_encrypt
  • _recaptcha_aes_pad
  • _recaptcha_http_post
  • _recaptcha_mailhide_email_parts
  • _recaptcha_mailhide_urlbase64
  • _recaptcha_qsencode
  • _smarty_regex_replace_check
  • _smarty_sort_length
  • admin_refcheck
  • b_system_comments_edit
  • b_system_comments_show
  • b_system_info_edit
  • b_system_info_show
  • b_system_login_show
  • b_system_main_show
  • b_system_newmembers_edit
  • b_system_newmembers_show
  • b_system_notification_show
  • b_system_online_show
  • b_system_search_show
  • b_system_themes_edit
  • b_system_themes_show
  • b_system_topposters_edit
  • b_system_topposters_show
  • b_system_user_show
  • b_system_waiting_show
  • bannerstats
  • change_banner_url_by_client
  • checkEmail
  • clickbanner
  • clientlogin
  • closeTable
  • closeThread
  • CloseWaitBox
  • Composer\Autoload\includeFile
  • composerRequire274e5fff219a4f27a346e611b0580d6a
  • createConfigform
  • createThemeform
  • doConditionalGet
  • emailStats
  • exit404BadReq
  • fatalPhpErrorHandler
  • file_get_contents
  • file_put_contents
  • findSharp
  • form_user
  • formatTimestamp
  • formatURL
  • gd_info
  • genPathCheckHtml
  • get_request_method
  • get_writeoks_from_protector
  • getcss
  • getDbCharsets
  • getDbCollations
  • getDirList
  • getMailer
  • getTheme
  • gif_getSize
  • gif_loadFile
  • gif_loadFileToGDimageResource
  • gif_outputAsBmp
  • gif_outputAsJpeg
  • gif_outputAsPng
  • HTMLPurifier
  • imagealphablending
  • imageBrowser
  • imageCreateCorners
  • imageFilenameCheck
  • imagesavealpha
  • install_acceptUser
  • install_finalize
  • is_executable
  • kses
  • langDropdown
  • load_functions
  • load_object
  • load_objectHandler
  • loadModuleAdminMenu
  • make_cblock
  • make_data
  • make_groups
  • make_sidebar
  • mod_clearCacheFile
  • mod_clearConfg
  • mod_clearConfig
  • mod_clearFile
  • mod_clearSmartyCache
  • mod_constant
  • mod_createCacheFile
  • mod_createCacheFile_byGroup
  • mod_createFile
  • mod_DB_prefix
  • mod_fetchConfg
  • mod_fetchConfig
  • mod_generateCacheId
  • mod_generateCacheId_byGroup
  • mod_getDirname
  • mod_getIP
  • mod_getMysqlVersion
  • mod_getUnameFromId
  • mod_getUnameFromIds
  • mod_isModuleAction
  • mod_loadCacheFile
  • mod_loadCacheFile_byGroup
  • mod_loadConfg
  • mod_loadConfig
  • mod_loadFile
  • mod_loadFunctions
  • mod_loadRenderer
  • mod_message
  • modify_chmod
  • myTextForm
  • notificationCategoryInfo
  • notificationCommentCategoryInfo
  • notificationEnabled
  • notificationEventEnabled
  • notificationEventInfo
  • notificationEvents
  • notificationGenerateConfig
  • notificationSubscribableCategoryInfo
  • openTable
  • openThread
  • OpenWaitBox
  • PHPMailerAutoload
  • phpThumbURL
  • preg_quote
  • profile_getFieldForm
  • profile_getRegisterForm
  • profile_getStepForm
  • profile_getUserForm
  • profile_install_addCategory
  • profile_install_addField
  • profile_install_addStep
  • profile_install_initializeProfiles
  • profile_install_setPermissions
  • protector_message_append_oninstall
  • protector_message_append_onuninstall
  • protector_message_append_onupdate
  • protector_notify_base
  • protector_oninstall_base
  • protector_onuninstall_base
  • protector_onupdate_base
  • protector_postcommon
  • protector_prepare
  • recaptcha_check_answer
  • recaptcha_get_html
  • recaptcha_get_signup_url
  • recaptcha_mailhide_html
  • recaptcha_mailhide_url
  • redirect_header
  • RedirectToCachedFile
  • SendSaveAsFileHeaderIfNeeded
  • showbanner
  • showThread
  • smarty_block_textformat
  • smarty_compiler_assign
  • smarty_compiler_foreachq
  • smarty_compiler_includeq
  • smarty_compiler_xoAdminIcons
  • smarty_compiler_xoAdminNav
  • smarty_compiler_xoAppUrl
  • smarty_compiler_xoImgUrl
  • smarty_compiler_xoModuleIcons16
  • smarty_compiler_xoModuleIcons32
  • smarty_compiler_xoModuleIconsBookmarks
  • smarty_core_assemble_plugin_filepath
  • smarty_core_assign_smarty_interface
  • smarty_core_create_dir_structure
  • smarty_core_display_debug_console
  • smarty_core_get_include_path
  • smarty_core_get_microtime
  • smarty_core_get_php_resource
  • smarty_core_is_secure
  • smarty_core_is_trusted
  • smarty_core_load_plugins
  • smarty_core_load_resource_plugin
  • smarty_core_process_cached_inserts
  • smarty_core_process_compiled_include
  • smarty_core_read_cache_file
  • smarty_core_rm_auto
  • smarty_core_rmdir
  • smarty_core_run_insert_handler
  • smarty_core_smarty_include_php
  • smarty_core_write_cache_file
  • smarty_core_write_compiled_include
  • smarty_core_write_compiled_resource
  • smarty_core_write_file
  • smarty_function_assign_debug_info
  • smarty_function_block
  • smarty_function_config_load
  • smarty_function_counter
  • smarty_function_cycle
  • smarty_function_debug
  • smarty_function_escape_special_chars
  • smarty_function_eval
  • smarty_function_fetch
  • smarty_function_html_checkboxes
  • smarty_function_html_checkboxes_output
  • smarty_function_html_image
  • smarty_function_html_options
  • smarty_function_html_options_optgroup
  • smarty_function_html_options_optoutput
  • smarty_function_html_radios
  • smarty_function_html_radios_output
  • smarty_function_html_select_date
  • smarty_function_html_select_time
  • smarty_function_html_table
  • smarty_function_html_table_cycle
  • smarty_function_mailto
  • smarty_function_math
  • smarty_function_popup
  • smarty_function_popup_init
  • smarty_function_securityToken
  • smarty_function_xoInboxCount
  • smarty_function_xoMemberInfo
  • smarty_function_xoops_link
  • smarty_function_xoPageNav
  • smarty_make_timestamp
  • smarty_modifier_capitalize
  • smarty_modifier_capitalize_ucfirst
  • smarty_modifier_cat
  • smarty_modifier_count_characters
  • smarty_modifier_count_paragraphs
  • smarty_modifier_count_sentences
  • smarty_modifier_count_words
  • smarty_modifier_date_format
  • smarty_modifier_debug_print_var
  • smarty_modifier_default
  • smarty_modifier_escape
  • smarty_modifier_indent
  • smarty_modifier_lower
  • smarty_modifier_nl2br
  • smarty_modifier_regex_replace
  • smarty_modifier_replace
  • smarty_modifier_spacify
  • smarty_modifier_string_format
  • smarty_modifier_strip
  • smarty_modifier_strip_tags
  • smarty_modifier_truncate
  • smarty_modifier_upper
  • smarty_modifier_wordwrap
  • smarty_outputfilter_trimwhitespace
  • smarty_outputfilter_trimwhitespace_replace
  • smarty_resource_db_secure
  • smarty_resource_db_source
  • smarty_resource_db_timestamp
  • smarty_resource_db_tplinfo
  • smarty_resource_db_trusted
  • synchronize
  • system_AdminIcons
  • system_adminVersion
  • system_CleanVars
  • system_loadLanguage
  • system_loadTemplate
  • themecenterposts
  • update_system_v211
  • userCheck
  • userTimeToServerTime
  • validateDbCharset
  • writeLicenseKey
  • xoBuildLicenceKey
  • xoDiag
  • xoDiagBoolSetting
  • xoDiagIfWritable
  • xoFormBlockCollation
  • xoFormField
  • xoFormFieldCharset
  • xoFormFieldCollation
  • xoFormSelect
  • xoops_aw_decode
  • xoops_aw_encode
  • xoops_bin2hex
  • xoops_comment_count
  • xoops_comment_delete
  • xoops_confirm
  • xoops_convert_decode
  • xoops_convert_encode
  • xoops_convert_encoding
  • xoops_cp_footer
  • xoops_cp_header
  • xoops_error
  • xoops_footer
  • xoops_getActiveModules
  • xoops_getbanner
  • xoops_getBaseDomain
  • xoops_getConfigOption
  • xoops_getcss
  • xoops_getenv
  • xoops_getHandler
  • xoops_getLinkedUnameFromId
  • xoops_getMailer
  • xoops_getModuleHandler
  • xoops_getModuleOption
  • xoops_getOption
  • xoops_getrank
  • xoops_getUrlDomain
  • xoops_getUserTimestamp
  • xoops_groupperm_deletebymoditem
  • xoops_header
  • xoops_hex2bin
  • xoops_isActiveModule
  • xoops_ishexstr
  • xoops_load
  • xoops_load_lang_file
  • xoops_loadLanguage
  • xoops_local
  • xoops_makepass
  • xoops_message
  • xoops_module_activate
  • xoops_module_change
  • xoops_module_deactivate
  • xoops_module_delayed_clean_cache
  • xoops_module_get_admin_menu
  • xoops_module_gettemplate
  • xoops_module_install
  • xoops_module_install_pm
  • xoops_module_install_profile
  • xoops_module_log_header
  • xoops_module_uninstall
  • xoops_module_update
  • xoops_module_update_pm
  • xoops_module_update_profile
  • xoops_module_update_system
  • xoops_module_write_admin_menu
  • xoops_notification_deletebyitem
  • xoops_notification_deletebymodule
  • xoops_notification_deletebyuser
  • xoops_refcheck
  • xoops_result
  • xoops_setActiveModules
  • xoops_setConfigOption
  • xoops_substr
  • xoops_template_clear_module_cache
  • xoops_template_touch
  • xoops_trim
  • xoops_utf8_encode
  • xoops_write_index_file
  • xoopsCodeTarea
  • xoopseditor_get_rootpath
  • XoopsErrorHandler_HandleError
  • xoopsfwrite
  • xoopsSmilies
  • xoPassField
  • xoPhpVersion
  • xoPutLicenseKey
  • xoStripeKey
  • Overview
  • Namespace
  • Class
  • Tree
   1: <?php
   2: //////////////////////////////////////////////////////////////
   3: //   phpThumb() by James Heinrich <info@silisoftware.com>   //
   4: //        available at http://phpthumb.sourceforge.net      //
   5: //         and/or https://github.com/JamesHeinrich/phpThumb //
   6: //////////////////////////////////////////////////////////////
   7: ///                                                         //
   8: // phpthumb.filters.php - image processing filter functions //
   9: //                                                         ///
  10: //////////////////////////////////////////////////////////////
  11: 
  12: class phpthumb_filters {
  13: 
  14:     /**
  15:     * @var phpthumb
  16:     */
  17: 
  18:     var $phpThumbObject = null;
  19: 
  20: 
  21:     function DebugMessage($message, $file='', $line='') {
  22:         if (is_object($this->phpThumbObject)) {
  23:             return $this->phpThumbObject->DebugMessage($message, $file, $line);
  24:         }
  25:         return false;
  26:     }
  27: 
  28: 
  29:     public function ApplyMask(&$gdimg_mask, &$gdimg_image) {
  30:         if (phpthumb_functions::gd_version() < 2) {
  31:             $this->DebugMessage('Skipping ApplyMask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
  32:             return false;
  33:         }
  34:         if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) {
  35: 
  36:             $this->DebugMessage('Using alpha ApplyMask() technique', __FILE__, __LINE__);
  37:             if ($gdimg_mask_resized = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_image), imagesy($gdimg_image))) {
  38: 
  39:                 imagecopyresampled($gdimg_mask_resized, $gdimg_mask, 0, 0, 0, 0, imagesx($gdimg_image), imagesy($gdimg_image), imagesx($gdimg_mask), imagesy($gdimg_mask));
  40:                 if ($gdimg_mask_blendtemp = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_image), imagesy($gdimg_image))) {
  41: 
  42:                     $color_background = imagecolorallocate($gdimg_mask_blendtemp, 0, 0, 0);
  43:                     imagefilledrectangle($gdimg_mask_blendtemp, 0, 0, imagesx($gdimg_mask_blendtemp), imagesy($gdimg_mask_blendtemp), $color_background);
  44:                     imagealphablending($gdimg_mask_blendtemp, false);
  45:                     imagesavealpha($gdimg_mask_blendtemp, true);
  46:                     for ($x = 0; $x < imagesx($gdimg_image); $x++) {
  47:                         for ($y = 0; $y < imagesy($gdimg_image); $y++) {
  48:                             //$RealPixel = phpthumb_functions::GetPixelColor($gdimg_mask_blendtemp, $x, $y);
  49:                             $RealPixel = phpthumb_functions::GetPixelColor($gdimg_image, $x, $y);
  50:                             $MaskPixel = phpthumb_functions::GrayscalePixel(phpthumb_functions::GetPixelColor($gdimg_mask_resized, $x, $y));
  51:                             $MaskAlpha = 127 - (floor($MaskPixel['red'] / 2) * (1 - ($RealPixel['alpha'] / 127)));
  52:                             $newcolor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_mask_blendtemp, $RealPixel['red'], $RealPixel['green'], $RealPixel['blue'], $MaskAlpha);
  53:                             imagesetpixel($gdimg_mask_blendtemp, $x, $y, $newcolor);
  54:                         }
  55:                     }
  56:                     imagealphablending($gdimg_image, false);
  57:                     imagesavealpha($gdimg_image, true);
  58:                     imagecopy($gdimg_image, $gdimg_mask_blendtemp, 0, 0, 0, 0, imagesx($gdimg_mask_blendtemp), imagesy($gdimg_mask_blendtemp));
  59:                     imagedestroy($gdimg_mask_blendtemp);
  60: 
  61:                 } else {
  62:                     $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
  63:                 }
  64:                 imagedestroy($gdimg_mask_resized);
  65: 
  66:             } else {
  67:                 $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
  68:             }
  69: 
  70:         } else {
  71:             // alpha merging requires PHP v4.3.2+
  72:             $this->DebugMessage('Skipping ApplyMask() technique because PHP is v"'.phpversion().'"', __FILE__, __LINE__);
  73:         }
  74:         return true;
  75:     }
  76: 
  77: 
  78:     function Bevel(&$gdimg, $width, $hexcolor1, $hexcolor2) {
  79:         $width     = ($width     ? $width     : 5);
  80:         $hexcolor1 = ($hexcolor1 ? $hexcolor1 : 'FFFFFF');
  81:         $hexcolor2 = ($hexcolor2 ? $hexcolor2 : '000000');
  82: 
  83:         imagealphablending($gdimg, true);
  84:         for ($i = 0; $i < $width; $i++) {
  85:             $alpha = round(($i / $width) * 127);
  86:             $color1 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1, false, $alpha);
  87:             $color2 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2, false, $alpha);
  88: 
  89:             imageline($gdimg,                   $i,                   $i + 1,                   $i, imagesy($gdimg) - $i - 1, $color1); // left
  90:             imageline($gdimg,                   $i,                   $i    , imagesx($gdimg) - $i,                   $i    , $color1); // top
  91:             imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i - 1, imagesx($gdimg) - $i,                   $i + 1, $color2); // right
  92:             imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i    ,                   $i, imagesy($gdimg) - $i    , $color2); // bottom
  93:         }
  94:         return true;
  95:     }
  96: 
  97: 
  98:     public function Blur(&$gdimg, $radius=0.5) {
  99:         //
 100: 
 101:         $radius = round(max(0, min($radius, 50)) * 2);
 102:         if (!$radius) {
 103:             return false;
 104:         }
 105: 
 106:         $w = imagesx($gdimg);
 107:         $h = imagesy($gdimg);
 108:         if ($imgBlur = imagecreatetruecolor($w, $h)) {
 109:             // Gaussian blur matrix:
 110:             //  1   2   1
 111:             //  2   4   2
 112:             //  1   2   1
 113: 
 114:             // Move copies of the image around one pixel at the time and merge them with weight
 115:             // according to the matrix. The same matrix is simply repeated for higher radii.
 116:             for ($i = 0; $i < $radius; $i++)    {
 117:                 imagecopy     ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1);            // up left
 118:                 imagecopymerge($imgBlur, $gdimg, 1, 1, 0, 0, $w,     $h,     50.00000);  // down right
 119:                 imagecopymerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h,     33.33333);  // down left
 120:                 imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 1, $w,     $h - 1, 25.00000);  // up right
 121:                 imagecopymerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h,     33.33333);  // left
 122:                 imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 0, $w,     $h,     25.00000);  // right
 123:                 imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 1, $w,     $h - 1, 20.00000);  // up
 124:                 imagecopymerge($imgBlur, $gdimg, 0, 1, 0, 0, $w,     $h,     16.666667); // down
 125:                 imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 0, $w,     $h,     50.000000); // center
 126:                 imagecopy     ($gdimg, $imgBlur, 0, 0, 0, 0, $w,     $h);
 127:             }
 128:             return true;
 129:         }
 130:         return false;
 131:     }
 132: 
 133: 
 134:     public function BlurGaussian(&$gdimg) {
 135:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 136:             if (imagefilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)) {
 137:                 return true;
 138:             }
 139:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)', __FILE__, __LINE__);
 140:             // fall through and try it the hard way
 141:         }
 142:         $this->DebugMessage('FAILED: phpthumb_filters::BlurGaussian($gdimg) [using phpthumb_filters::Blur() instead]', __FILE__, __LINE__);
 143:         return phpthumb_filters::Blur($gdimg, 0.5);
 144:     }
 145: 
 146: 
 147:     public function BlurSelective(&$gdimg) {
 148:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 149:             if (imagefilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)) {
 150:                 return true;
 151:             }
 152:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)', __FILE__, __LINE__);
 153:             // fall through and try it the hard way
 154:         }
 155:         // currently not implemented "the hard way"
 156:         $this->DebugMessage('FAILED: phpthumb_filters::BlurSelective($gdimg) [function not implemented]', __FILE__, __LINE__);
 157:         return false;
 158:     }
 159: 
 160: 
 161:     public function Brightness(&$gdimg, $amount=0) {
 162:         if ($amount == 0) {
 163:             return true;
 164:         }
 165:         $amount = max(-255, min(255, $amount));
 166: 
 167:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 168:             if (imagefilter($gdimg, IMG_FILTER_BRIGHTNESS, $amount)) {
 169:                 return true;
 170:             }
 171:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_BRIGHTNESS, '.$amount.')', __FILE__, __LINE__);
 172:             // fall through and try it the hard way
 173:         }
 174: 
 175:         $scaling = (255 - abs($amount)) / 255;
 176:         $baseamount = (($amount > 0) ? $amount : 0);
 177:         for ($x = 0; $x < imagesx($gdimg); $x++) {
 178:             for ($y = 0; $y < imagesy($gdimg); $y++) {
 179:                 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 180:                 $NewPixel = array();
 181:                 foreach ($OriginalPixel as $key => $value) {
 182:                     $NewPixel[$key] = round($baseamount + ($OriginalPixel[$key] * $scaling));
 183:                 }
 184:                 $newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
 185:                 imagesetpixel($gdimg, $x, $y, $newColor);
 186:             }
 187:         }
 188:         return true;
 189:     }
 190: 
 191: 
 192:     public function Contrast(&$gdimg, $amount=0) {
 193:         if ($amount == 0) {
 194:             return true;
 195:         }
 196:         $amount = max(-255, min(255, $amount));
 197: 
 198:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 199:             // imagefilter(IMG_FILTER_CONTRAST) has range +100 to -100 (positive numbers make it darker!)
 200:             $amount = ($amount / 255) * -100;
 201:             if (imagefilter($gdimg, IMG_FILTER_CONTRAST, $amount)) {
 202:                 return true;
 203:             }
 204:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_CONTRAST, '.$amount.')', __FILE__, __LINE__);
 205:             // fall through and try it the hard way
 206:         }
 207: 
 208:         if ($amount > 0) {
 209:             $scaling = 1 + ($amount / 255);
 210:         } else {
 211:             $scaling = (255 - abs($amount)) / 255;
 212:         }
 213:         for ($x = 0; $x < imagesx($gdimg); $x++) {
 214:             for ($y = 0; $y < imagesy($gdimg); $y++) {
 215:                 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 216:                 $NewPixel = array();
 217:                 foreach ($OriginalPixel as $key => $value) {
 218:                     $NewPixel[$key] = min(255, max(0, round($OriginalPixel[$key] * $scaling)));
 219:                 }
 220:                 $newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
 221:                 imagesetpixel($gdimg, $x, $y, $newColor);
 222:             }
 223:         }
 224:         return true;
 225:     }
 226: 
 227: 
 228:     public function Colorize(&$gdimg, $amount, $targetColor) {
 229:         $amount      = (is_numeric($amount)                          ? $amount      : 25);
 230:         $amountPct   = $amount / 100;
 231:         $targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'gray');
 232: 
 233:         if ($amount == 0) {
 234:             return true;
 235:         }
 236: 
 237:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 238:             if ($targetColor == 'gray') {
 239:                 $targetColor = '808080';
 240:             }
 241:             $r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
 242:             $g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
 243:             $b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
 244:             if (imagefilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
 245:                 return true;
 246:             }
 247:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
 248:             // fall through and try it the hard way
 249:         }
 250: 
 251:         // overridden below for grayscale
 252:         $TargetPixel = array();
 253:         if ($targetColor != 'gray') {
 254:             $TargetPixel['red']   = hexdec(substr($targetColor, 0, 2));
 255:             $TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
 256:             $TargetPixel['blue']  = hexdec(substr($targetColor, 4, 2));
 257:         }
 258: 
 259:         for ($x = 0; $x < imagesx($gdimg); $x++) {
 260:             for ($y = 0; $y < imagesy($gdimg); $y++) {
 261:                 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 262:                 if ($targetColor == 'gray') {
 263:                     $TargetPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
 264:                 }
 265:                 $NewPixel = array();
 266:                 foreach ($TargetPixel as $key => $value) {
 267:                     $NewPixel[$key] = round(max(0, min(255, ($OriginalPixel[$key] * ((100 - $amount) / 100)) + ($TargetPixel[$key] * $amountPct))));
 268:                 }
 269:                 //$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
 270:                 $newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
 271:                 imagesetpixel($gdimg, $x, $y, $newColor);
 272:             }
 273:         }
 274:         return true;
 275:     }
 276: 
 277: 
 278:     public function Crop(&$gdimg, $left=0, $right=0, $top=0, $bottom=0) {
 279:         if (!$left && !$right && !$top && !$bottom) {
 280:             return true;
 281:         }
 282:         $oldW = imagesx($gdimg);
 283:         $oldH = imagesy($gdimg);
 284:         if (($left   > 0) && ($left   < 1)) { $left   = round($left   * $oldW); }
 285:         if (($right  > 0) && ($right  < 1)) { $right  = round($right  * $oldW); }
 286:         if (($top    > 0) && ($top    < 1)) { $top    = round($top    * $oldH); }
 287:         if (($bottom > 0) && ($bottom < 1)) { $bottom = round($bottom * $oldH); }
 288:         $right  = min($oldW - $left - 1, $right);
 289:         $bottom = min($oldH - $top  - 1, $bottom);
 290:         $newW = $oldW - $left - $right;
 291:         $newH = $oldH - $top  - $bottom;
 292: 
 293:         if ($imgCropped = imagecreatetruecolor($newW, $newH)) {
 294:             imagecopy($imgCropped, $gdimg, 0, 0, $left, $top, $newW, $newH);
 295:             if ($gdimg = imagecreatetruecolor($newW, $newH)) {
 296:                 imagecopy($gdimg, $imgCropped, 0, 0, 0, 0, $newW, $newH);
 297:                 imagedestroy($imgCropped);
 298:                 return true;
 299:             }
 300:             imagedestroy($imgCropped);
 301:         }
 302:         return false;
 303:     }
 304: 
 305: 
 306:     public function Desaturate(&$gdimg, $amount, $color='') {
 307:         if ($amount == 0) {
 308:             return true;
 309:         }
 310:         return phpthumb_filters::Colorize($gdimg, $amount, (phpthumb_functions::IsHexColor($color) ? $color : 'gray'));
 311:     }
 312: 
 313: 
 314:     public function DropShadow(&$gdimg, $distance, $width, $hexcolor, $angle, $alpha) {
 315:         if (phpthumb_functions::gd_version() < 2) {
 316:             return false;
 317:         }
 318:         $distance =                 ($distance ? $distance : 10);
 319:         $width    =                 ($width    ? $width    : 10);
 320:         $hexcolor =                 ($hexcolor ? $hexcolor : '000000');
 321:         $angle    =                 ($angle    ? $angle    : 225) % 360;
 322:         $alpha    = max(0, min(100, ($alpha    ? $alpha    : 100)));
 323: 
 324:         if ($alpha <= 0) {
 325:             // invisible shadow, nothing to do
 326:             return true;
 327:         }
 328:         if ($distance <= 0) {
 329:             // shadow completely obscured by source image, nothing to do
 330:             return true;
 331:         }
 332: 
 333:         //$width_shadow  = cos(deg2rad($angle)) * ($distance + $width);
 334:         //$height_shadow = sin(deg2rad($angle)) * ($distance + $width);
 335:         //$scaling = min(imagesx($gdimg) / (imagesx($gdimg) + abs($width_shadow)), imagesy($gdimg) / (imagesy($gdimg) + abs($height_shadow)));
 336: 
 337:         $Offset = array();
 338:         for ($i = 0; $i < $width; $i++) {
 339:             $WidthAlpha[$i] = (abs(($width / 2) - $i) / $width);
 340:             $Offset['x'] = cos(deg2rad($angle)) * ($distance + $i);
 341:             $Offset['y'] = sin(deg2rad($angle)) * ($distance + $i);
 342:         }
 343: 
 344:         $tempImageWidth  = imagesx($gdimg)  + abs($Offset['x']);
 345:         $tempImageHeight = imagesy($gdimg) + abs($Offset['y']);
 346: 
 347:         if ($gdimg_dropshadow_temp = phpthumb_functions::ImageCreateFunction($tempImageWidth, $tempImageHeight)) {
 348: 
 349:             imagealphablending($gdimg_dropshadow_temp, false);
 350:             imagesavealpha($gdimg_dropshadow_temp, true);
 351:             $transparent1 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, 0, 0, 0, 127);
 352:             imagefill($gdimg_dropshadow_temp, 0, 0, $transparent1);
 353: 
 354:             $PixelMap = array();
 355:             for ($x = 0; $x < imagesx($gdimg); $x++) {
 356:                 for ($y = 0; $y < imagesy($gdimg); $y++) {
 357:                     $PixelMap[$x][$y] = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 358:                 }
 359:             }
 360:             for ($x = 0; $x < $tempImageWidth; $x++) {
 361:                 for ($y = 0; $y < $tempImageHeight; $y++) {
 362:                     //for ($i = 0; $i < $width; $i++) {
 363:                     for ($i = 0; $i < 1; $i++) {
 364:                         if (!isset($PixelMap[$x][$y]['alpha']) || ($PixelMap[$x][$y]['alpha'] > 0)) {
 365:                             if (isset($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']) && ($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha'] < 127)) {
 366:                                 $thisColor = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor, false, $PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']);
 367:                                 imagesetpixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
 368:                             }
 369:                         }
 370:                     }
 371:                 }
 372:             }
 373: 
 374:             imagealphablending($gdimg_dropshadow_temp, true);
 375:             for ($x = 0; $x < imagesx($gdimg); $x++) {
 376:                 for ($y = 0; $y < imagesy($gdimg); $y++) {
 377:                     if ($PixelMap[$x][$y]['alpha'] < 127) {
 378:                         $thisColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, $PixelMap[$x][$y]['red'], $PixelMap[$x][$y]['green'], $PixelMap[$x][$y]['blue'], $PixelMap[$x][$y]['alpha']);
 379:                         imagesetpixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
 380:                     }
 381:                 }
 382:             }
 383: 
 384:             imagesavealpha($gdimg, true);
 385:             imagealphablending($gdimg, false);
 386:             //$this->is_alpha = true;
 387:             $transparent2 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0, 0, 0, 127);
 388:             imagefilledrectangle($gdimg, 0, 0, imagesx($gdimg), imagesy($gdimg), $transparent2);
 389:             imagecopyresampled($gdimg, $gdimg_dropshadow_temp, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg), imagesx($gdimg_dropshadow_temp), imagesy($gdimg_dropshadow_temp));
 390: 
 391:             imagedestroy($gdimg_dropshadow_temp);
 392:         }
 393:         return true;
 394:     }
 395: 
 396: 
 397:     public function EdgeDetect(&$gdimg) {
 398:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 399:             if (imagefilter($gdimg, IMG_FILTER_EDGEDETECT)) {
 400:                 return true;
 401:             }
 402:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_EDGEDETECT)', __FILE__, __LINE__);
 403:             // fall through and try it the hard way
 404:         }
 405:         // currently not implemented "the hard way"
 406:         $this->DebugMessage('FAILED: phpthumb_filters::EdgeDetect($gdimg) [function not implemented]', __FILE__, __LINE__);
 407:         return false;
 408:     }
 409: 
 410: 
 411:     public function Ellipse($gdimg) {
 412:         if (phpthumb_functions::gd_version() < 2) {
 413:             return false;
 414:         }
 415:         // generate mask at twice desired resolution and downsample afterwards for easy antialiasing
 416:         if ($gdimg_ellipsemask_double = phpthumb_functions::ImageCreateFunction(imagesx($gdimg) * 2, imagesy($gdimg) * 2)) {
 417:             if ($gdimg_ellipsemask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
 418: 
 419:                 $color_transparent = imagecolorallocate($gdimg_ellipsemask_double, 255, 255, 255);
 420:                 imagefilledellipse($gdimg_ellipsemask_double, imagesx($gdimg), imagesy($gdimg), (imagesx($gdimg) - 1) * 2, (imagesy($gdimg) - 1) * 2, $color_transparent);
 421:                 imagecopyresampled($gdimg_ellipsemask, $gdimg_ellipsemask_double, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg), imagesx($gdimg) * 2, imagesy($gdimg) * 2);
 422: 
 423:                 phpthumb_filters::ApplyMask($gdimg_ellipsemask, $gdimg);
 424:                 imagedestroy($gdimg_ellipsemask);
 425:                 return true;
 426: 
 427:             } else {
 428:                 $this->DebugMessage('$gdimg_ellipsemask = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
 429:             }
 430:             imagedestroy($gdimg_ellipsemask_double);
 431:         } else {
 432:             $this->DebugMessage('$gdimg_ellipsemask_double = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
 433:         }
 434:         return false;
 435:     }
 436: 
 437: 
 438:     public function Emboss(&$gdimg) {
 439:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 440:             if (imagefilter($gdimg, IMG_FILTER_EMBOSS)) {
 441:                 return true;
 442:             }
 443:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_EMBOSS)', __FILE__, __LINE__);
 444:             // fall through and try it the hard way
 445:         }
 446:         // currently not implemented "the hard way"
 447:         $this->DebugMessage('FAILED: phpthumb_filters::Emboss($gdimg) [function not implemented]', __FILE__, __LINE__);
 448:         return false;
 449:     }
 450: 
 451: 
 452:     public function Flip(&$gdimg, $x=false, $y=false) {
 453:         if (!$x && !$y) {
 454:             return false;
 455:         }
 456:         if ($tempImage = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
 457:             if ($x) {
 458:                 imagecopy($tempImage, $gdimg, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg));
 459:                 for ($x = 0; $x < imagesx($gdimg); $x++) {
 460:                     imagecopy($gdimg, $tempImage, imagesx($gdimg) - 1 - $x, 0, $x, 0, 1, imagesy($gdimg));
 461:                 }
 462:             }
 463:             if ($y) {
 464:                 imagecopy($tempImage, $gdimg, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg));
 465:                 for ($y = 0; $y < imagesy($gdimg); $y++) {
 466:                     imagecopy($gdimg, $tempImage, 0, imagesy($gdimg) - 1 - $y, 0, $y, imagesx($gdimg), 1);
 467:                 }
 468:             }
 469:             imagedestroy($tempImage);
 470:         }
 471:         return true;
 472:     }
 473: 
 474: 
 475:     public function Frame(&$gdimg, $frame_width, $edge_width, $hexcolor_frame, $hexcolor1, $hexcolor2) {
 476:         $frame_width    = ($frame_width    ? $frame_width    : 5);
 477:         $edge_width     = ($edge_width     ? $edge_width     : 1);
 478:         $hexcolor_frame = ($hexcolor_frame ? $hexcolor_frame : 'CCCCCC');
 479:         $hexcolor1      = ($hexcolor1      ? $hexcolor1      : 'FFFFFF');
 480:         $hexcolor2      = ($hexcolor2      ? $hexcolor2      : '000000');
 481: 
 482:         $color_frame = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor_frame);
 483:         $color1      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1);
 484:         $color2      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2);
 485:         for ($i = 0; $i < $edge_width; $i++) {
 486:             // outer bevel
 487:             imageline($gdimg,                   $i,                   $i,                   $i, imagesy($gdimg) - $i, $color1); // left
 488:             imageline($gdimg,                   $i,                   $i, imagesx($gdimg) - $i,                   $i, $color1); // top
 489:             imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, imagesx($gdimg) - $i,                   $i, $color2); // right
 490:             imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i,                   $i, imagesy($gdimg) - $i, $color2); // bottom
 491:         }
 492:         for ($i = 0; $i < $frame_width; $i++) {
 493:             // actual frame
 494:             imagerectangle($gdimg, $edge_width + $i, $edge_width + $i, imagesx($gdimg) - $edge_width - $i, imagesy($gdimg) - $edge_width - $i, $color_frame);
 495:         }
 496:         for ($i = 0; $i < $edge_width; $i++) {
 497:             // inner bevel
 498:             imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color2); // left
 499:             imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color2); // top
 500:             imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color1); // right
 501:             imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color1); // bottom
 502:         }
 503:         return true;
 504:     }
 505: 
 506: 
 507:     public function Gamma(&$gdimg, $amount) {
 508:         if (number_format($amount, 4) == '1.0000') {
 509:             return true;
 510:         }
 511:         return imagegammacorrect($gdimg, 1.0, $amount);
 512:     }
 513: 
 514: 
 515:     public function Grayscale(&$gdimg) {
 516:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 517:             if (imagefilter($gdimg, IMG_FILTER_GRAYSCALE)) {
 518:                 return true;
 519:             }
 520:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
 521:             // fall through and try it the hard way
 522:         }
 523:         return phpthumb_filters::Colorize($gdimg, 100, 'gray');
 524:     }
 525: 
 526: 
 527:     public function HistogramAnalysis(&$gdimg, $calculateGray=false) {
 528:         $ImageSX = imagesx($gdimg);
 529:         $ImageSY = imagesy($gdimg);
 530:         $Analysis = array();
 531:         for ($x = 0; $x < $ImageSX; $x++) {
 532:             for ($y = 0; $y < $ImageSY; $y++) {
 533:                 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 534:                 @$Analysis['red'][$OriginalPixel['red']]++;
 535:                 @$Analysis['green'][$OriginalPixel['green']]++;
 536:                 @$Analysis['blue'][$OriginalPixel['blue']]++;
 537:                 @$Analysis['alpha'][$OriginalPixel['alpha']]++;
 538:                 if ($calculateGray) {
 539:                     $GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
 540:                     @$Analysis['gray'][$GrayPixel['red']]++;
 541:                 }
 542:             }
 543:         }
 544:         $keys = array('red', 'green', 'blue', 'alpha');
 545:         if ($calculateGray) {
 546:             $keys[] = 'gray';
 547:         }
 548:         foreach ($keys as $dummy => $key) {
 549:             ksort($Analysis[$key]);
 550:         }
 551:         return $Analysis;
 552:     }
 553: 
 554: 
 555:     public function HistogramStretch(&$gdimg, $band='*', $method=0, $threshold=0.1) {
 556:         // equivalent of "Auto Contrast" in Adobe Photoshop
 557:         // method 0 stretches according to RGB colors. Gives a more conservative stretch.
 558:         // method 1 band stretches according to grayscale which is color-biased (59% green, 30% red, 11% blue). May give a punchier / more aggressive stretch, possibly appearing over-saturated
 559:         $Analysis = phpthumb_filters::HistogramAnalysis($gdimg, true);
 560:         $keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>(($method == 0) ? 'all' : 'gray'));
 561:         $band = substr($band, 0, 1);
 562:         if (!isset($keys[$band])) {
 563:             return false;
 564:         }
 565:         $key = $keys[$band];
 566: 
 567:         // If the absolute brightest and darkest pixels are used then one random
 568:         // pixel in the image could throw off the whole system. Instead, count up/down
 569:         // from the limit and allow <threshold> (default = 0.1%) of brightest/darkest
 570:         // pixels to be clipped to min/max
 571:         $threshold = floatval($threshold) / 100;
 572:         $clip_threshold = imagesx($gdimg) * imagesx($gdimg) * $threshold;
 573: 
 574:         $countsum  = 0;
 575:         $range_min = 0;
 576:         for ($i = 0; $i <= 255; $i++) {
 577:             if ($method == 0) {
 578:                 $countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
 579:             } else {
 580:                 $countsum += @$Analysis[$key][$i];
 581:             }
 582:             if ($countsum >= $clip_threshold) {
 583:                 $range_min = $i - 1;
 584:                 break;
 585:             }
 586:         }
 587:         $range_min = max($range_min, 0);
 588: 
 589:         $countsum  =   0;
 590:         $range_max = 255;
 591:         for ($i = 255; $i >= 0; $i--) {
 592:             if ($method == 0) {
 593:                 $countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
 594:             } else {
 595:                 $countsum += @$Analysis[$key][$i];
 596:             }
 597:             if ($countsum >= $clip_threshold) {
 598:                 $range_max = $i + 1;
 599:                 break;
 600:             }
 601:         }
 602:         $range_max = min($range_max, 255);
 603: 
 604:         $range_scale = (($range_max == $range_min) ? 1 : (255 / ($range_max - $range_min)));
 605:         if (($range_min == 0) && ($range_max == 255)) {
 606:             // no adjustment neccesary - don't waste CPU time!
 607:             return true;
 608:         }
 609: 
 610:         $ImageSX = imagesx($gdimg);
 611:         $ImageSY = imagesy($gdimg);
 612:         for ($x = 0; $x < $ImageSX; $x++) {
 613:             for ($y = 0; $y < $ImageSY; $y++) {
 614:                 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 615:                 if ($band == '*') {
 616:                     $new['red']   = min(255, max(0, ($OriginalPixel['red']   - $range_min) * $range_scale));
 617:                     $new['green'] = min(255, max(0, ($OriginalPixel['green'] - $range_min) * $range_scale));
 618:                     $new['blue']  = min(255, max(0, ($OriginalPixel['blue']  - $range_min) * $range_scale));
 619:                     $new['alpha'] = min(255, max(0, ($OriginalPixel['alpha'] - $range_min) * $range_scale));
 620:                 } else {
 621:                     $new = $OriginalPixel;
 622:                     $new[$key] = min(255, max(0, ($OriginalPixel[$key] - $range_min) * $range_scale));
 623:                 }
 624:                 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $new['red'], $new['green'], $new['blue'], $new['alpha']);
 625:                 imagesetpixel($gdimg, $x, $y, $newColor);
 626:             }
 627:         }
 628: 
 629:         return true;
 630:     }
 631: 
 632: 
 633:     public function HistogramOverlay(&$gdimg, $bands='*', $colors='', $width=0.25, $height=0.25, $alignment='BR', $opacity=50, $margin_x=5, $margin_y=null) {
 634:         $margin_y = (is_null($margin_y) ? $margin_x : $margin_y);
 635: 
 636:         $Analysis = phpthumb_filters::HistogramAnalysis($gdimg, true);
 637:         $histW = round(($width > 1) ? min($width, imagesx($gdimg)) : imagesx($gdimg) * $width);
 638:         $histH = round(($width > 1) ? min($width, imagesx($gdimg)) : imagesx($gdimg) * $width);
 639:         if ($gdHist = imagecreatetruecolor($histW, $histH)) {
 640:             $color_back = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHist, 0, 0, 0, 127);
 641:             imagefilledrectangle($gdHist, 0, 0, $histW, $histH, $color_back);
 642:             imagealphablending($gdHist, false);
 643:             imagesavealpha($gdHist, true);
 644: 
 645:             $HistogramTempWidth  = 256;
 646:             $HistogramTempHeight = 100;
 647:             if ($gdHistTemp = imagecreatetruecolor($HistogramTempWidth, $HistogramTempHeight)) {
 648:                 $color_back_temp = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHistTemp, 255, 0, 255, 127);
 649:                 imagealphablending($gdHistTemp, false);
 650:                 imagesavealpha($gdHistTemp, true);
 651:                 imagefilledrectangle($gdHistTemp, 0, 0, imagesx($gdHistTemp), imagesy($gdHistTemp), $color_back_temp);
 652: 
 653:                 $DefaultColors = array('r'=>'FF0000', 'g'=>'00FF00', 'b'=>'0000FF', 'a'=>'999999', '*'=>'FFFFFF');
 654:                 $Colors = explode(';', $colors);
 655:                 $BandsToGraph = array_unique(preg_split('##', $bands));
 656:                 $keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>'gray');
 657:                 foreach ($BandsToGraph as $key => $band) {
 658:                     if (!isset($keys[$band])) {
 659:                         continue;
 660:                     }
 661:                     $PeakValue = max($Analysis[$keys[$band]]);
 662:                     $thisColor = phpthumb_functions::ImageHexColorAllocate($gdHistTemp, phpthumb_functions::IsHexColor(@$Colors[$key]) ? $Colors[$key] : $DefaultColors[$band]);
 663:                     for ($x = 0; $x < $HistogramTempWidth; $x++) {
 664:                         imageline($gdHistTemp, $x, $HistogramTempHeight - 1, $x, $HistogramTempHeight - 1 - round(@$Analysis[$keys[$band]][$x] / $PeakValue * $HistogramTempHeight), $thisColor);
 665:                     }
 666:                     imageline($gdHistTemp, 0, $HistogramTempHeight - 1, $HistogramTempWidth - 1, $HistogramTempHeight - 1, $thisColor);
 667:                     imageline($gdHistTemp, 0, $HistogramTempHeight - 2, $HistogramTempWidth - 1, $HistogramTempHeight - 2, $thisColor);
 668:                 }
 669:                 imagecopyresampled($gdHist, $gdHistTemp, 0, 0, 0, 0, imagesx($gdHist), imagesy($gdHist), imagesx($gdHistTemp), imagesy($gdHistTemp));
 670:                 imagedestroy($gdHistTemp);
 671:             } else {
 672:                 return false;
 673:             }
 674: 
 675:             phpthumb_filters::WatermarkOverlay($gdimg, $gdHist, $alignment, $opacity, $margin_x, $margin_y);
 676:             imagedestroy($gdHist);
 677:             return true;
 678:         }
 679:         return false;
 680:     }
 681: 
 682: 
 683:     public function ImageBorder(&$gdimg, $border_width, $radius_x, $radius_y, $hexcolor_border) {
 684:         $border_width = ($border_width ? $border_width : 1);
 685:         $radius_x     = ($radius_x     ? $radius_x     : 0);
 686:         $radius_y     = ($radius_y     ? $radius_y     : 0);
 687: 
 688:         $output_width  = imagesx($gdimg);
 689:         $output_height = imagesy($gdimg);
 690: 
 691:         list($new_width, $new_height) = phpthumb_functions::ProportionalResize($output_width, $output_height, $output_width - max($border_width * 2, $radius_x), $output_height - max($border_width * 2, $radius_y));
 692:         $offset_x = ($radius_x ? $output_width  - $new_width  - $radius_x : 0);
 693: 
 694:         if ($gd_border_canvas = phpthumb_functions::ImageCreateFunction($output_width, $output_height)) {
 695: 
 696:             imagesavealpha($gd_border_canvas, true);
 697:             imagealphablending($gd_border_canvas, false);
 698:             $color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gd_border_canvas, 255, 255, 255, 127);
 699:             imagefilledrectangle($gd_border_canvas, 0, 0, $output_width, $output_height, $color_background);
 700: 
 701:             $color_border = phpthumb_functions::ImageHexColorAllocate($gd_border_canvas, (phpthumb_functions::IsHexColor($hexcolor_border) ? $hexcolor_border : '000000'));
 702: 
 703:             for ($i = 0; $i < $border_width; $i++) {
 704:                 imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x,                      $i, $output_width - $radius_x - ceil($offset_x / 2),                         $i, $color_border); // top
 705:                 imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2),    $output_height - 1 - $i, $color_border); // bottom
 706:                 imageline($gd_border_canvas,                    floor($offset_x / 2) + $i,               $radius_y,                      floor($offset_x / 2) +  $i, $output_height - $radius_y, $color_border); // left
 707:                 imageline($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2),               $radius_y,    $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right
 708:             }
 709: 
 710:             if ($radius_x && $radius_y) {
 711: 
 712:                 // PHP bug: imagearc() with thicknesses > 1 give bad/undesirable/unpredicatable results
 713:                 // Solution: Draw multiple 1px arcs side-by-side.
 714: 
 715:                 // Problem: parallel arcs give strange/ugly antialiasing problems
 716:                 // Solution: draw non-parallel arcs, from one side of the line thickness at the start angle
 717:                 //   to the opposite edge of the line thickness at the terminating angle
 718:                 for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
 719:                     imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x,              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
 720:                     imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2),              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
 721:                     imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
 722:                     imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
 723:                 }
 724:                 if ($border_width > 1) {
 725:                     for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
 726:                         imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                                      $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
 727:                         imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                                      $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
 728:                         imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
 729:                         imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
 730:                     }
 731:                 }
 732: 
 733:             }
 734:             $this->phpThumbObject->ImageResizeFunction($gd_border_canvas, $gdimg, floor(($output_width - $new_width) / 2), round(($output_height - $new_height) / 2), 0, 0, $new_width, $new_height, $output_width, $output_height);
 735: 
 736:             imagedestroy($gdimg);
 737:             $gdimg = phpthumb_functions::ImageCreateFunction($output_width, $output_height);
 738:             imagesavealpha($gdimg, true);
 739:             imagealphablending($gdimg, false);
 740:             $gdimg_color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 255, 255, 255, 127);
 741:             imagefilledrectangle($gdimg, 0, 0, $output_width, $output_height, $gdimg_color_background);
 742: 
 743:             imagecopy($gdimg, $gd_border_canvas, 0, 0, 0, 0, $output_width, $output_height);
 744:             imagedestroy($gd_border_canvas);
 745:             return true;
 746: 
 747: 
 748:         } else {
 749:             $this->DebugMessage('FAILED: $gd_border_canvas = phpthumb_functions::ImageCreateFunction('.$output_width.', '.$output_height.')', __FILE__, __LINE__);
 750:         }
 751:         return false;
 752:     }
 753: 
 754: 
 755:     public static function ImprovedImageRotate(&$gdimg_source, $rotate_angle=0, $config_background_hexcolor='FFFFFF', $bg=null, &$phpThumbObject) {
 756:         while ($rotate_angle < 0) {
 757:             $rotate_angle += 360;
 758:         }
 759:         $rotate_angle = $rotate_angle % 360;
 760:         if ($rotate_angle != 0) {
 761: 
 762:             $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_source, $config_background_hexcolor);
 763: 
 764:             if ((phpthumb_functions::gd_version() >= 2) && !$bg && ($rotate_angle % 90)) {
 765: 
 766:                 //$this->DebugMessage('Using alpha rotate', __FILE__, __LINE__);
 767:                 if ($gdimg_rotate_mask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_source), imagesy($gdimg_source))) {
 768: 
 769:                     $color_mask = array();
 770:                     for ($i = 0; $i <= 255; $i++) {
 771:                         $color_mask[$i] = imagecolorallocate($gdimg_rotate_mask, $i, $i, $i);
 772:                     }
 773:                     imagefilledrectangle($gdimg_rotate_mask, 0, 0, imagesx($gdimg_rotate_mask), imagesy($gdimg_rotate_mask), $color_mask[255]);
 774:                     $imageX = imagesx($gdimg_source);
 775:                     $imageY = imagesy($gdimg_source);
 776:                     for ($x = 0; $x < $imageX; $x++) {
 777:                         for ($y = 0; $y < $imageY; $y++) {
 778:                             $pixelcolor = phpthumb_functions::GetPixelColor($gdimg_source, $x, $y);
 779:                             imagesetpixel($gdimg_rotate_mask, $x, $y, $color_mask[255 - round($pixelcolor['alpha'] * 255 / 127)]);
 780:                         }
 781:                     }
 782:                     $gdimg_rotate_mask = imagerotate($gdimg_rotate_mask, $rotate_angle, $color_mask[0]);
 783:                     $gdimg_source      = imagerotate($gdimg_source,      $rotate_angle, $background_color);
 784: 
 785:                     imagealphablending($gdimg_source, false);
 786:                     imagesavealpha($gdimg_source, true);
 787:                     //$this->is_alpha = true;
 788:                     $phpThumbFilters = new phpthumb_filters();
 789:                     //$phpThumbFilters->phpThumbObject = $this;
 790:                     $phpThumbFilters->phpThumbObject = $phpThumbObject;
 791:                     $phpThumbFilters->ApplyMask($gdimg_rotate_mask, $gdimg_source);
 792: 
 793:                     imagedestroy($gdimg_rotate_mask);
 794: 
 795:                 } else {
 796:                     //$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
 797:                 }
 798: 
 799:             } else {
 800: 
 801:                 if (phpthumb_functions::gd_version() < 2) {
 802:                     //$this->DebugMessage('Using non-alpha rotate because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
 803:                 } elseif ($bg) {
 804:                     //$this->DebugMessage('Using non-alpha rotate because $this->bg is "'.$bg.'"', __FILE__, __LINE__);
 805:                 } elseif ($rotate_angle % 90) {
 806:                     //$this->DebugMessage('Using non-alpha rotate because ($rotate_angle % 90) = "'.($rotate_angle % 90).'"', __FILE__, __LINE__);
 807:                 } else {
 808:                     //$this->DebugMessage('Using non-alpha rotate because $this->thumbnailFormat is "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
 809:                 }
 810: 
 811:                 if (imagecolortransparent($gdimg_source) >= 0) {
 812:                     // imagerotate() forgets all about an image's transparency and sets the transparent color to black
 813:                     // To compensate, flood-fill the transparent color of the source image with the specified background color first
 814:                     // then rotate and the colors should match
 815: 
 816:                     if (!function_exists('imageistruecolor') || !imageistruecolor($gdimg_source)) {
 817:                         // convert paletted image to true-color before rotating to prevent nasty aliasing artifacts
 818: 
 819:                         //$this->source_width  = imagesx($gdimg_source);
 820:                         //$this->source_height = imagesy($gdimg_source);
 821:                         $gdimg_newsrc = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_source), imagesy($gdimg_source));
 822:                         $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor);
 823:                         imagefilledrectangle($gdimg_newsrc, 0, 0, imagesx($gdimg_source), imagesy($gdimg_source), phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor));
 824:                         imagecopy($gdimg_newsrc, $gdimg_source, 0, 0, 0, 0, imagesx($gdimg_source), imagesy($gdimg_source));
 825:                         imagedestroy($gdimg_source);
 826:                         unset($gdimg_source);
 827:                         $gdimg_source = $gdimg_newsrc;
 828:                         unset($gdimg_newsrc);
 829: 
 830:                     } else {
 831: 
 832:                         imagecolorset(
 833:                             $gdimg_source,
 834:                             imagecolortransparent($gdimg_source),
 835:                             hexdec(substr($config_background_hexcolor, 0, 2)),
 836:                             hexdec(substr($config_background_hexcolor, 2, 2)),
 837:                             hexdec(substr($config_background_hexcolor, 4, 2)));
 838: 
 839:                         imagecolortransparent($gdimg_source, -1);
 840: 
 841:                     }
 842:                 }
 843: 
 844:                 $gdimg_source = imagerotate($gdimg_source, $rotate_angle, $background_color);
 845: 
 846:             }
 847:         }
 848:         return true;
 849:     }
 850: 
 851: 
 852:     public function MeanRemoval(&$gdimg) {
 853:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 854:             if (imagefilter($gdimg, IMG_FILTER_MEAN_REMOVAL)) {
 855:                 return true;
 856:             }
 857:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_MEAN_REMOVAL)', __FILE__, __LINE__);
 858:             // fall through and try it the hard way
 859:         }
 860:         // currently not implemented "the hard way"
 861:         $this->DebugMessage('FAILED: phpthumb_filters::MeanRemoval($gdimg) [function not implemented]', __FILE__, __LINE__);
 862:         return false;
 863:     }
 864: 
 865: 
 866:     public function Negative(&$gdimg) {
 867:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 868:             if (imagefilter($gdimg, IMG_FILTER_NEGATE)) {
 869:                 return true;
 870:             }
 871:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_NEGATE)', __FILE__, __LINE__);
 872:             // fall through and try it the hard way
 873:         }
 874:         $ImageSX = imagesx($gdimg);
 875:         $ImageSY = imagesy($gdimg);
 876:         for ($x = 0; $x < $ImageSX; $x++) {
 877:             for ($y = 0; $y < $ImageSY; $y++) {
 878:                 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 879:                 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, (~$currentPixel['red'] & 0xFF), (~$currentPixel['green'] & 0xFF), (~$currentPixel['blue'] & 0xFF), $currentPixel['alpha']);
 880:                 imagesetpixel($gdimg, $x, $y, $newColor);
 881:             }
 882:         }
 883:         return true;
 884:     }
 885: 
 886: 
 887:     public function RoundedImageCorners(&$gdimg, $radius_x, $radius_y) {
 888:         // generate mask at twice desired resolution and downsample afterwards for easy antialiasing
 889:         // mask is generated as a white double-size ellipse on a triple-size black background and copy-paste-resampled
 890:         // onto a correct-size mask image as 4 corners due to errors when the entire mask is resampled at once (gray edges)
 891:         if ($gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction($radius_x * 6, $radius_y * 6)) {
 892:             if ($gdimg_cornermask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
 893: 
 894:                 $color_transparent = imagecolorallocate($gdimg_cornermask_triple, 255, 255, 255);
 895:                 imagefilledellipse($gdimg_cornermask_triple, $radius_x * 3, $radius_y * 3, $radius_x * 4, $radius_y * 4, $color_transparent);
 896: 
 897:                 imagefilledrectangle($gdimg_cornermask, 0, 0, imagesx($gdimg), imagesy($gdimg), $color_transparent);
 898: 
 899:                 imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0,                           0,     $radius_x,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
 900:                 imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0, imagesy($gdimg) - $radius_y,     $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
 901:                 imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x, imagesy($gdimg) - $radius_y, $radius_x * 3, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
 902:                 imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x,                           0, $radius_x * 3,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
 903: 
 904:                 phpthumb_filters::ApplyMask($gdimg_cornermask, $gdimg);
 905:                 imagedestroy($gdimg_cornermask);
 906:                 $this->DebugMessage('RoundedImageCorners('.$radius_x.', '.$radius_y.') succeeded', __FILE__, __LINE__);
 907:                 return true;
 908: 
 909:             } else {
 910:                 $this->DebugMessage('FAILED: $gdimg_cornermask = phpthumb_functions::ImageCreateFunction('.imagesx($gdimg).', '.imagesy($gdimg).')', __FILE__, __LINE__);
 911:             }
 912:             imagedestroy($gdimg_cornermask_triple);
 913: 
 914:         } else {
 915:             $this->DebugMessage('FAILED: $gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction('.($radius_x * 6).', '.($radius_y * 6).')', __FILE__, __LINE__);
 916:         }
 917:         return false;
 918:     }
 919: 
 920: 
 921:     public function Saturation(&$gdimg, $amount, $color='') {
 922:         if ($amount == 0) {
 923:             return true;
 924:         } elseif ($amount > 0) {
 925:             $amount = 0 - $amount;
 926:         } else {
 927:             $amount = abs($amount);
 928:         }
 929:         return phpthumb_filters::Desaturate($gdimg, $amount, $color);
 930:     }
 931: 
 932: 
 933:     public function Sepia(&$gdimg, $amount, $targetColor) {
 934:         $amount      = (is_numeric($amount) ? max(0, min(100, $amount)) : 50);
 935:         $amountPct   = $amount / 100;
 936:         $targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'A28065');
 937: 
 938:         if ($amount == 0) {
 939:             return true;
 940:         }
 941: 
 942:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 943:             if (imagefilter($gdimg, IMG_FILTER_GRAYSCALE)) {
 944: 
 945:                 $r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
 946:                 $g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
 947:                 $b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
 948:                 if (imagefilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
 949:                     return true;
 950:                 }
 951:                 $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
 952:                 // fall through and try it the hard way
 953: 
 954:             } else {
 955: 
 956:                 $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
 957:                 // fall through and try it the hard way
 958: 
 959:             }
 960:         }
 961: 
 962:         $TargetPixel['red']   = hexdec(substr($targetColor, 0, 2));
 963:         $TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
 964:         $TargetPixel['blue']  = hexdec(substr($targetColor, 4, 2));
 965: 
 966:         $ImageSX = imagesx($gdimg);
 967:         $ImageSY = imagesy($gdimg);
 968:         for ($x = 0; $x < $ImageSX; $x++) {
 969:             for ($y = 0; $y < $ImageSY; $y++) {
 970:                 $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
 971:                 $GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
 972: 
 973:                 // http://www.gimpguru.org/Tutorials/SepiaToning/
 974:                 // "In the traditional sepia toning process, the tinting occurs most in
 975:                 // the mid-tones: the lighter and darker areas appear to be closer to B&W."
 976:                 $SepiaAmount = ((128 - abs($GrayPixel['red'] - 128)) / 128) * $amountPct;
 977: 
 978:                 $NewPixel = array();
 979:                 foreach ($TargetPixel as $key => $value) {
 980:                     $NewPixel[$key] = round(max(0, min(255, $GrayPixel[$key] * (1 - $SepiaAmount) + ($TargetPixel[$key] * $SepiaAmount))));
 981:                 }
 982:                 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
 983:                 imagesetpixel($gdimg, $x, $y, $newColor);
 984:             }
 985:         }
 986:         return true;
 987:     }
 988: 
 989: 
 990:     public function Smooth(&$gdimg, $amount=6) {
 991:         $amount = min(25, max(0, $amount));
 992:         if ($amount == 0) {
 993:             return true;
 994:         }
 995:         if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
 996:             if (imagefilter($gdimg, IMG_FILTER_SMOOTH, $amount)) {
 997:                 return true;
 998:             }
 999:             $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_SMOOTH, '.$amount.')', __FILE__, __LINE__);
1000:             // fall through and try it the hard way
1001:         }
1002:         // currently not implemented "the hard way"
1003:         $this->DebugMessage('FAILED: phpthumb_filters::Smooth($gdimg, '.$amount.') [function not implemented]', __FILE__, __LINE__);
1004:         return false;
1005:     }
1006: 
1007: 
1008:     public function SourceTransparentColorMask(&$gdimg, $hexcolor, $min_limit=5, $max_limit=10) {
1009:         $width  = imagesx($gdimg);
1010:         $height = imagesy($gdimg);
1011:         if ($gdimg_mask = imagecreatetruecolor($width, $height)) {
1012:             $R = hexdec(substr($hexcolor, 0, 2));
1013:             $G = hexdec(substr($hexcolor, 2, 2));
1014:             $B = hexdec(substr($hexcolor, 4, 2));
1015:             $targetPixel = array('red'=>$R, 'green'=>$G, 'blue'=>$B);
1016:             $cutoffRange = $max_limit - $min_limit;
1017:             for ($x = 0; $x < $width; $x++) {
1018:                 for ($y = 0; $y < $height; $y++) {
1019:                     $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1020:                     $colorDiff = phpthumb_functions::PixelColorDifferencePercent($currentPixel, $targetPixel);
1021:                     $grayLevel = min($cutoffRange, max(0, -$min_limit + $colorDiff)) * (255 / max(1, $cutoffRange));
1022:                     $newColor = imagecolorallocate($gdimg_mask, $grayLevel, $grayLevel, $grayLevel);
1023:                     imagesetpixel($gdimg_mask, $x, $y, $newColor);
1024:                 }
1025:             }
1026:             return $gdimg_mask;
1027:         }
1028:         return false;
1029:     }
1030: 
1031: 
1032:     public function Threshold(&$gdimg, $cutoff) {
1033:         $width  = imagesx($gdimg);
1034:         $height = imagesy($gdimg);
1035:         $cutoff = min(255, max(0, ($cutoff ? $cutoff : 128)));
1036:         for ($x = 0; $x < $width; $x++) {
1037:             for ($y = 0; $y < $height; $y++) {
1038:                 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1039:                 $grayPixel = phpthumb_functions::GrayscalePixel($currentPixel);
1040:                 if ($grayPixel['red'] < $cutoff) {
1041:                     $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0x00, 0x00, 0x00, $currentPixel['alpha']);
1042:                 } else {
1043:                     $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0xFF, 0xFF, 0xFF, $currentPixel['alpha']);
1044:                 }
1045:                 imagesetpixel($gdimg, $x, $y, $newColor);
1046:             }
1047:         }
1048:         return true;
1049:     }
1050: 
1051: 
1052:     public function ImageTrueColorToPalette2(&$image, $dither, $ncolors) {
1053:         // http://www.php.net/manual/en/function.imagetruecolortopalette.php
1054:         // zmorris at zsculpt dot com (17-Aug-2004 06:58)
1055:         $width  = imagesx($image);
1056:         $height = imagesy($image);
1057:         $image_copy = imagecreatetruecolor($width, $height);
1058:         //imagecopymerge($image_copy, $image, 0, 0, 0, 0, $width, $height, 100);
1059:         imagecopy($image_copy, $image, 0, 0, 0, 0, $width, $height);
1060:         imagetruecolortopalette($image, $dither, $ncolors);
1061:         imagecolormatch($image_copy, $image);
1062:         imagedestroy($image_copy);
1063:         return true;
1064:     }
1065: 
1066:     public function ReduceColorDepth(&$gdimg, $colors=256, $dither=true) {
1067:         $colors = max(min($colors, 256), 2);
1068:         // imagetruecolortopalette usually makes ugly colors, the replacement is a bit better
1069:         //imagetruecolortopalette($gdimg, $dither, $colors);
1070:         phpthumb_filters::ImageTrueColorToPalette2($gdimg, $dither, $colors);
1071:         return true;
1072:     }
1073: 
1074: 
1075:     public function WhiteBalance(&$gdimg, $targetColor='') {
1076:         if (phpthumb_functions::IsHexColor($targetColor)) {
1077:             $targetPixel = array(
1078:                 'red'   => hexdec(substr($targetColor, 0, 2)),
1079:                 'green' => hexdec(substr($targetColor, 2, 2)),
1080:                 'blue'  => hexdec(substr($targetColor, 4, 2))
1081:             );
1082:         } else {
1083:             $Analysis = phpthumb_filters::HistogramAnalysis($gdimg, false);
1084:             $targetPixel = array(
1085:                 'red'   => max(array_keys($Analysis['red'])),
1086:                 'green' => max(array_keys($Analysis['green'])),
1087:                 'blue'  => max(array_keys($Analysis['blue']))
1088:             );
1089:         }
1090:         $grayValue = phpthumb_functions::GrayscaleValue($targetPixel['red'], $targetPixel['green'], $targetPixel['blue']);
1091:         $scaleR = $grayValue / $targetPixel['red'];
1092:         $scaleG = $grayValue / $targetPixel['green'];
1093:         $scaleB = $grayValue / $targetPixel['blue'];
1094: 
1095:         for ($x = 0; $x < imagesx($gdimg); $x++) {
1096:             for ($y = 0; $y < imagesy($gdimg); $y++) {
1097:                 $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1098:                 $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe(
1099:                     $gdimg,
1100:                     max(0, min(255, round($currentPixel['red']   * $scaleR))),
1101:                     max(0, min(255, round($currentPixel['green'] * $scaleG))),
1102:                     max(0, min(255, round($currentPixel['blue']  * $scaleB))),
1103:                     $currentPixel['alpha']
1104:                 );
1105:                 imagesetpixel($gdimg, $x, $y, $newColor);
1106:             }
1107:         }
1108:         return true;
1109:     }
1110: 
1111: 
1112:     public function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color='000000', $ttffont='', $opacity=100, $margin=5, $angle=0, $bg_color=false, $bg_opacity=0, $fillextend='') {
1113:         // text watermark requested
1114:         if (!$text) {
1115:             return false;
1116:         }
1117:         imagealphablending($gdimg, true);
1118: 
1119:         if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)(@[LCR])?$#i', $alignment, $matches)) {
1120:             $originOffsetX = intval($matches[1]);
1121:             $originOffsetY = intval($matches[2]);
1122:             $alignment = (@$matches[4] ? $matches[4] : 'L');
1123:             $margin = 0;
1124:         } else {
1125:             $originOffsetX = 0;
1126:             $originOffsetY = 0;
1127:         }
1128: 
1129:         $metaTextArray = array(
1130:             '^Fb' =>       $this->phpThumbObject->getimagesizeinfo['filesize'],
1131:             '^Fk' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1024),
1132:             '^Fm' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1048576),
1133:             '^X'  => $this->phpThumbObject->getimagesizeinfo[0],
1134:             '^Y'  => $this->phpThumbObject->getimagesizeinfo[1],
1135:             '^x'  => imagesx($gdimg),
1136:             '^y'  => imagesy($gdimg),
1137:             '^^'  => '^',
1138:         );
1139:         $text = strtr($text, $metaTextArray);
1140: 
1141:         $text = str_replace("\r\n", "\n", $text);
1142:         $text = str_replace("\r",   "\n", $text);
1143:         $textlines = explode("\n", $text);
1144:         $this->DebugMessage('Processing '.count($textlines).' lines of text', __FILE__, __LINE__);
1145: 
1146:         if (@is_readable($ttffont) && is_file($ttffont)) {
1147: 
1148:             $opacity = 100 - intval(max(min($opacity, 100), 0));
1149:             $letter_color_text = phpthumb_functions::ImageHexColorAllocate($gdimg, $hex_color, false, $opacity * 1.27);
1150: 
1151:             $this->DebugMessage('Using TTF font "'.$ttffont.'"', __FILE__, __LINE__);
1152: 
1153:             $TTFbox = imagettfbbox($size, $angle, $ttffont, $text);
1154: 
1155:             $min_x = min($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1156:             $max_x = max($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1157:             //$text_width = round($max_x - $min_x + ($size * 0.5));
1158:             $text_width = round($max_x - $min_x);
1159: 
1160:             $min_y = min($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1161:             $max_y = max($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1162:             //$text_height = round($max_y - $min_y + ($size * 0.5));
1163:             $text_height = round($max_y - $min_y);
1164: 
1165:             $TTFboxChar = imagettfbbox($size, $angle, $ttffont, 'jH');
1166:             $char_min_y = min($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1167:             $char_max_y = max($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1168:             $char_height = round($char_max_y - $char_min_y);
1169: 
1170:             if ($alignment == '*') {
1171: 
1172:                 $text_origin_y = $char_height + $margin;
1173:                 while (($text_origin_y - $text_height) < imagesy($gdimg)) {
1174:                     $text_origin_x = $margin;
1175:                     while ($text_origin_x < imagesx($gdimg)) {
1176:                         imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1177:                         $text_origin_x += ($text_width + $margin);
1178:                     }
1179:                     $text_origin_y += ($text_height + $margin);
1180:                 }
1181: 
1182:             } else {
1183: 
1184:                 // this block for background color only
1185: 
1186:                 $text_origin_x = 0;
1187:                 $text_origin_y = 0;
1188:                 switch ($alignment) {
1189:                     case '*':
1190:                         // handled separately
1191:                         break;
1192: 
1193:                     case 'T':
1194:                         $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1195:                         $text_origin_y = $char_height + $margin + $originOffsetY;
1196:                         break;
1197: 
1198:                     case 'B':
1199:                         $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1200:                         $text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1201:                         break;
1202: 
1203:                     case 'L':
1204:                         $text_origin_x = $margin + $originOffsetX;
1205:                         $text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1206:                         break;
1207: 
1208:                     case 'R':
1209:                         $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1210:                         $text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1211:                         break;
1212: 
1213:                     case 'C':
1214:                         $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1215:                         $text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1216:                         break;
1217: 
1218:                     case 'TL':
1219:                         $text_origin_x = $margin + $originOffsetX;
1220:                         $text_origin_y = $char_height + $margin + $originOffsetY;
1221:                         break;
1222: 
1223:                     case 'TR':
1224:                         $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1225:                         $text_origin_y = $char_height + $margin + $originOffsetY;
1226:                         break;
1227: 
1228:                     case 'BL':
1229:                         $text_origin_x = $margin + $originOffsetX;
1230:                         $text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1231:                         break;
1232: 
1233:                     case 'BR':
1234:                     default:
1235:                         $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1236:                         $text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1237:                         break;
1238:                 }
1239: 
1240:                 if (phpthumb_functions::IsHexColor($bg_color)) {
1241:                     $text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1242:                     $text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, $bg_color, false, $text_background_alpha);
1243:                 } else {
1244:                     $text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, 'FFFFFF', false, 127);
1245:                 }
1246:                 $x1 = $text_origin_x + $min_x;
1247:                 $y1 = $text_origin_y + $TTFbox[1];
1248:                 $x2 = $text_origin_x + $min_x + $text_width;
1249:                 $y2 = $text_origin_y + $TTFbox[1] - $text_height;
1250:                 $x_TL = preg_match('#x#i', $fillextend) ?               0 : min($x1, $x2);
1251:                 $y_TL = preg_match('#y#i', $fillextend) ?               0 : min($y1, $y2);
1252:                 $x_BR = preg_match('#x#i', $fillextend) ? imagesx($gdimg) : max($x1, $x2);
1253:                 $y_BR = preg_match('#y#i', $fillextend) ? imagesy($gdimg) : max($y1, $y2);
1254:                 $this->DebugMessage('WatermarkText() calling imagefilledrectangle($gdimg, '.$x_TL.', '.$y_TL.', '.$x_BR.', '.$y_BR.', $text_color_background)', __FILE__, __LINE__);
1255:                 imagefilledrectangle($gdimg, $x_TL, $y_TL, $x_BR, $y_BR, $text_color_background);
1256: 
1257:                 // end block for background color only
1258: 
1259: 
1260:                 $y_offset = 0;
1261:                 foreach ($textlines as $dummy => $line) {
1262: 
1263:                     $TTFboxLine = imagettfbbox($size, $angle, $ttffont, $line);
1264:                     $min_x_line = min($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1265:                     $max_x_line = max($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1266:                     $text_width_line = round($max_x_line - $min_x_line);
1267: 
1268:                     switch ($alignment) {
1269:                         // $text_origin_y set above, just re-set $text_origin_x here as needed
1270: 
1271:                         case 'L':
1272:                         case 'TL':
1273:                         case 'BL':
1274:                             // no change neccesary
1275:                             break;
1276: 
1277:                         case 'C':
1278:                         case 'T':
1279:                         case 'B':
1280:                             $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width_line / 2) : round((imagesx($gdimg) - $text_width_line) / 2));
1281:                             break;
1282: 
1283:                         case 'R':
1284:                         case 'TR':
1285:                         case 'BR':
1286:                             $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width_line : imagesx($gdimg) - $text_width_line  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1287:                             break;
1288:                     }
1289: 
1290:                     //imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1291:                     $this->DebugMessage('WatermarkText() calling imagettftext($gdimg, '.$size.', '.$angle.', '.$text_origin_x.', '.($text_origin_y + $y_offset).', $letter_color_text, '.$ttffont.', '.$line.')', __FILE__, __LINE__);
1292:                     imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y + $y_offset, $letter_color_text, $ttffont, $line);
1293: 
1294:                     $y_offset += $char_height;
1295:                 }
1296: 
1297:             }
1298:             return true;
1299: 
1300:         } else {
1301: 
1302:             $size = min(5, max(1, $size));
1303:             $this->DebugMessage('Using built-in font (size='.$size.') for text watermark'.($ttffont ? ' because $ttffont !is_readable('.$ttffont.')' : ''), __FILE__, __LINE__);
1304: 
1305:             $text_width  = 0;
1306:             $text_height = 0;
1307:             foreach ($textlines as $dummy => $line) {
1308:                 $text_width   = max($text_width, imagefontwidth($size) * strlen($line));
1309:                 $text_height += imagefontheight($size);
1310:             }
1311:             if ($img_watermark = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1312:                 imagealphablending($img_watermark, false);
1313:                 if (phpthumb_functions::IsHexColor($bg_color)) {
1314:                     $text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1315:                     $text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, $bg_color, false, $text_background_alpha);
1316:                 } else {
1317:                     $text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, 'FFFFFF', false, 127);
1318:                 }
1319:                 $this->DebugMessage('WatermarkText() calling imagefilledrectangle($img_watermark, 0, 0, '.imagesx($img_watermark).', '.imagesy($img_watermark).', $text_color_background)', __FILE__, __LINE__);
1320:                 imagefilledrectangle($img_watermark, 0, 0, imagesx($img_watermark), imagesy($img_watermark), $text_color_background);
1321: 
1322:                 $img_watermark_mask    = false;
1323:                 $mask_color_background = false;
1324:                 $mask_color_watermark  = false;
1325:                 if ($angle && function_exists('imagerotate')) {
1326:                     // using $img_watermark_mask is pointless if imagerotate function isn't available
1327:                     if ($img_watermark_mask = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1328:                         $mask_color_background = imagecolorallocate($img_watermark_mask, 0, 0, 0);
1329:                         imagealphablending($img_watermark_mask, false);
1330:                         imagefilledrectangle($img_watermark_mask, 0, 0, imagesx($img_watermark_mask), imagesy($img_watermark_mask), $mask_color_background);
1331:                         $mask_color_watermark = imagecolorallocate($img_watermark_mask, 255, 255, 255);
1332:                     }
1333:                 }
1334: 
1335:                 $text_color_watermark = phpthumb_functions::ImageHexColorAllocate($img_watermark, $hex_color);
1336:                 $x_offset = 0;
1337:                 foreach ($textlines as $key => $line) {
1338:                     switch ($alignment) {
1339:                         case 'C':
1340:                             $x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1341:                             $originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1342:                             $originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1343:                             break;
1344: 
1345:                         case 'T':
1346:                             $x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1347:                             $originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1348:                             $originOffsetY = $margin;
1349:                             break;
1350: 
1351:                         case 'B':
1352:                             $x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1353:                             $originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1354:                             $originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1355:                             break;
1356: 
1357:                         case 'L':
1358:                             $x_offset = 0;
1359:                             $originOffsetX = $margin;
1360:                             $originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1361:                             break;
1362: 
1363:                         case 'TL':
1364:                             $x_offset = 0;
1365:                             $originOffsetX = $margin;
1366:                             $originOffsetY = $margin;
1367:                             break;
1368: 
1369:                         case 'BL':
1370:                             $x_offset = 0;
1371:                             $originOffsetX = $margin;
1372:                             $originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1373:                             break;
1374: 
1375:                         case 'R':
1376:                             $x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1377:                             $originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1378:                             $originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1379:                             break;
1380: 
1381:                         case 'TR':
1382:                             $x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1383:                             $originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1384:                             $originOffsetY = $margin;
1385:                             break;
1386: 
1387:                         case 'BR':
1388:                         default:
1389:                             if (!empty($originOffsetX) || !empty($originOffsetY)) {
1390:                                 // absolute pixel positioning
1391:                             } else {
1392:                                 $x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1393:                                 $originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1394:                                 $originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1395:                             }
1396:                             break;
1397:                     }
1398:                     $this->DebugMessage('WatermarkText() calling imagestring($img_watermark, '.$size.', '.$x_offset.', '.($key * imagefontheight($size)).', '.$line.', $text_color_watermark)', __FILE__, __LINE__);
1399:                     imagestring($img_watermark, $size, $x_offset, $key * imagefontheight($size), $line, $text_color_watermark);
1400:                     if ($angle && $img_watermark_mask) {
1401:                         $this->DebugMessage('WatermarkText() calling imagestring($img_watermark_mask, '.$size.', '.$x_offset.', '.($key * imagefontheight($size)).', '.$text.', $mask_color_watermark)', __FILE__, __LINE__);
1402:                         imagestring($img_watermark_mask, $size, $x_offset, $key * imagefontheight($size), $text, $mask_color_watermark);
1403:                     }
1404:                 }
1405:                 if ($angle && $img_watermark_mask) {
1406:                     $img_watermark      = imagerotate($img_watermark,      $angle, $text_color_background);
1407:                     $img_watermark_mask = imagerotate($img_watermark_mask, $angle, $mask_color_background);
1408:                     phpthumb_filters::ApplyMask($img_watermark_mask, $img_watermark);
1409:                 }
1410:                 //phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, $alignment, $opacity, $margin);
1411:                 $this->DebugMessage('WatermarkText() calling phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, '.($originOffsetX.'x'.$originOffsetY).', '.$opacity.', 0)', __FILE__, __LINE__);
1412:                 phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, $originOffsetX.'x'.$originOffsetY, $opacity, 0);
1413:                 imagedestroy($img_watermark);
1414:                 return true;
1415:             }
1416: 
1417:         }
1418:         return false;
1419:     }
1420: 
1421: 
1422:     public function WatermarkOverlay(&$gdimg_dest, &$img_watermark, $alignment='*', $opacity=50, $margin_x=5, $margin_y=null) {
1423: 
1424:         if (is_resource($gdimg_dest) && is_resource($img_watermark)) {
1425:             $img_source_width          = imagesx($gdimg_dest);
1426:             $img_source_height         = imagesy($gdimg_dest);
1427:             $watermark_source_width    = imagesx($img_watermark);
1428:             $watermark_source_height   = imagesy($img_watermark);
1429:             $watermark_opacity_percent = max(0, min(100, $opacity));
1430:             $margin_y = (is_null($margin_y) ? $margin_x : $margin_y);
1431:             $watermark_margin_x = ((($margin_x > 0) && ($margin_x < 1)) ? round((1 - $margin_x) * $img_source_width)  : $margin_x);
1432:             $watermark_margin_y = ((($margin_y > 0) && ($margin_y < 1)) ? round((1 - $margin_y) * $img_source_height) : $margin_y);
1433:             $watermark_destination_x = 0;
1434:             $watermark_destination_y = 0;
1435:             if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
1436:                 $watermark_destination_x = intval($matches[1]);
1437:                 $watermark_destination_y = intval($matches[2]);
1438:             } else {
1439:                 switch ($alignment) {
1440:                     case '*':
1441:                         if ($gdimg_tiledwatermark = phpthumb_functions::ImageCreateFunction($img_source_width, $img_source_height)) {
1442: 
1443:                             imagealphablending($gdimg_tiledwatermark, false);
1444:                             imagesavealpha($gdimg_tiledwatermark, true);
1445:                             $text_color_transparent = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_tiledwatermark, 255, 0, 255, 127);
1446:                             imagefill($gdimg_tiledwatermark, 0, 0, $text_color_transparent);
1447: 
1448:                             // set the tiled image transparent color to whatever the untiled image transparency index is
1449:     //                      imagecolortransparent($gdimg_tiledwatermark, imagecolortransparent($img_watermark));
1450: 
1451:                             // a "cleaner" way of doing it, but can't handle the margin feature :(
1452:     //                      imagesettile($gdimg_tiledwatermark, $img_watermark);
1453:     //                      imagefill($gdimg_tiledwatermark, 0, 0, IMG_COLOR_TILED);
1454:     //                      break;
1455: 
1456:     //                      imagefill($gdimg_tiledwatermark, 0, 0, imagecolortransparent($gdimg_tiledwatermark));
1457:                             // tile the image as many times as can fit
1458:                             for ($x = $watermark_margin_x; $x < ($img_source_width + $watermark_source_width); $x += ($watermark_source_width + $watermark_margin_x)) {
1459:                                 for ($y = $watermark_margin_y; $y < ($img_source_height + $watermark_source_height); $y += ($watermark_source_height + $watermark_margin_y)) {
1460:                                     imagecopy(
1461:                                         $gdimg_tiledwatermark,
1462:                                         $img_watermark,
1463:                                         $x,
1464:                                         $y,
1465:                                         0,
1466:                                         0,
1467:                                         min($watermark_source_width,  $img_source_width  - $x - $watermark_margin_x),
1468:                                         min($watermark_source_height, $img_source_height - $y - $watermark_margin_y)
1469:                                     );
1470:                                 }
1471:                             }
1472: 
1473:                             $watermark_source_width  = imagesx($gdimg_tiledwatermark);
1474:                             $watermark_source_height = imagesy($gdimg_tiledwatermark);
1475:                             $watermark_destination_x = 0;
1476:                             $watermark_destination_y = 0;
1477: 
1478:                             imagedestroy($img_watermark);
1479:                             $img_watermark = $gdimg_tiledwatermark;
1480:                         }
1481:                         break;
1482: 
1483:                     case 'T':
1484:                         $watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1485:                         $watermark_destination_y = $watermark_margin_y;
1486:                         break;
1487: 
1488:                     case 'B':
1489:                         $watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1490:                         $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1491:                         break;
1492: 
1493:                     case 'L':
1494:                         $watermark_destination_x = $watermark_margin_x;
1495:                         $watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1496:                         break;
1497: 
1498:                     case 'R':
1499:                         $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1500:                         $watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1501:                         break;
1502: 
1503:                     case 'C':
1504:                         $watermark_destination_x = round(($img_source_width  / 2) - ($watermark_source_width  / 2));
1505:                         $watermark_destination_y = round(($img_source_height / 2) - ($watermark_source_height / 2));
1506:                         break;
1507: 
1508:                     case 'TL':
1509:                         $watermark_destination_x = $watermark_margin_x;
1510:                         $watermark_destination_y = $watermark_margin_y;
1511:                         break;
1512: 
1513:                     case 'TR':
1514:                         $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1515:                         $watermark_destination_y = $watermark_margin_y;
1516:                         break;
1517: 
1518:                     case 'BL':
1519:                         $watermark_destination_x = $watermark_margin_x;
1520:                         $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1521:                         break;
1522: 
1523:                     case 'BR':
1524:                     default:
1525:                         $watermark_destination_x = $img_source_width  - $watermark_source_width  - $watermark_margin_x;
1526:                         $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1527:                         break;
1528:                 }
1529:             }
1530:             imagealphablending($gdimg_dest, false);
1531:             imagesavealpha($gdimg_dest, true);
1532:             imagesavealpha($img_watermark, true);
1533:             phpthumb_functions::ImageCopyRespectAlpha($gdimg_dest, $img_watermark, $watermark_destination_x, $watermark_destination_y, 0, 0, $watermark_source_width, $watermark_source_height, $watermark_opacity_percent);
1534: 
1535:             return true;
1536:         }
1537:         return false;
1538:     }
1539: 
1540: }
1541: 
API documentation generated by ApiGen