Import FFMPEG LZW code and CMS header from Broadcom/Zyxel source-code
authorTJ <hacker@iam.tj>
Fri, 8 Apr 2016 19:52:11 +0000 (20:52 +0100)
committerTJ <hacker@iam.tj>
Fri, 8 Apr 2016 19:52:11 +0000 (20:52 +0100)
cms.h [new file with mode: 0644]
cms_lzw.h [new file with mode: 0644]
lzw_decode.c [new file with mode: 0644]
lzw_encode.c [new file with mode: 0644]

diff --git a/cms.h b/cms.h
new file mode 100644 (file)
index 0000000..d650c46
--- /dev/null
+++ b/cms.h
@@ -0,0 +1,532 @@
+/***********************************************************************
+ *
+ *  Copyright (c) 2006-2007  Broadcom Corporation
+ *  All Rights Reserved
+ *
+ * <:label-BRCM:2011:DUAL/GPL:standard
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as published by
+ * the Free Software Foundation (the "GPL").
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * 
+ * A copy of the GPL is available at http://www.broadcom.com/licenses/GPLv2.php, or by
+ * writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * 
+:>
+ *
+ ************************************************************************/
+
+#ifndef __CMS_H__
+#define __CMS_H__
+
+/*!\file cms.h
+ * \brief Header file containing common and constant definitions for
+ *        the CPE Management System (CMS).  Parameters which may change
+ *        depending on vendor preference or board configuration are located
+ *        in cms_params.h (which is included by this file at the bottom.)
+ */
+
+#include "os_defs.h"
+#include "cms_version.h"
+
+
+
+/*!\enum CmsRet
+ * \brief Return codes for all external functions, and some internal functions too.
+ *
+ * Codes from 9000-9799 are reserved for TR69C return values.
+ * All Broadcom return codes should start at 9800.
+ */
+typedef enum
+{
+   CMSRET_SUCCESS              = 0,     /**<Success. */
+   CMSRET_METHOD_NOT_SUPPORTED = 9000,  /**<Method not supported. */
+   CMSRET_REQUEST_DENIED       = 9001,  /**< Request denied (no reason specified). */
+   CMSRET_INTERNAL_ERROR       = 9002,  /**< Internal error. */
+   CMSRET_INVALID_ARGUMENTS    = 9003,  /**< Invalid arguments. */
+   CMSRET_RESOURCE_EXCEEDED    = 9004,  /**< Resource exceeded.
+                                        *  (when used in association with
+                                        *  setParameterValues, this MUST not be
+                                        *  used to indicate parameters in error)
+                                        */
+   CMSRET_INVALID_PARAM_NAME   = 9005,  /**< Invalid parameter name.
+                                        *  (associated with set/getParameterValues,
+                                        *  getParameterNames,set/getParameterAtrributes)
+                                        */
+   CMSRET_INVALID_PARAM_TYPE   = 9006,  /**< Invalid parameter type.
+                                        *  (associated with set/getParameterValues)
+                                        */
+   CMSRET_INVALID_PARAM_VALUE  = 9007,  /**< Invalid parameter value.
+                                        *  (associated with set/getParameterValues)
+                                        */
+   CMSRET_SET_NON_WRITABLE_PARAM = 9008,/**< Attempt to set a non-writable parameter.
+                                        *  (associated with setParameterValues)
+                                        */
+   CMSRET_NOTIFICATION_REQ_REJECTED = 9009, /**< Notification request rejected.
+                                            *  (associated with setParameterAttributes)
+                                            */
+   CMSRET_DOWNLOAD_FAILURE     = 9010,  /**< Download failure.
+                                         *  (associated with download or transferComplete)
+                                         */
+   CMSRET_UPLOAD_FAILURE       = 9011,  /**< Upload failure.
+                                        *  (associated with upload or transferComplete)
+                                        */
+   CMSRET_FILE_TRANSFER_AUTH_FAILURE = 9012,  /**< File transfer server authentication
+                                              *  failure.
+                                              *  (associated with upload, download
+                                              *  or transferComplete)
+                                              */
+   CMSRET_UNSUPPORTED_FILE_TRANSFER_PROTOCOL = 9013,/**< Unsupported protocol for file
+                                                    *  transfer.
+                                                    *  (associated with upload or
+                                                    *  download)
+                                                    */
+   CMSRET_FILE_TRANSFER_UNABLE_JOIN_MULTICAST = 9014,/**< File transfer failure,
+                                                    *  unable to join multicast
+                                                    *  group.
+                                                    */
+   CMSRET_FILE_TRANSFER_UNABLE_CONTACT_FILE_SERVER = 9015,/**< File transfer failure,
+                                                    *  unable to contact file server.
+                                                    */
+   CMSRET_FILE_TRANSFER_UNABLE_ACCESS_FILE = 9016,/**< File transfer failure,
+                                                    *  unable to access file.
+                                                    */
+   CMSRET_FILE_TRANSFER_UNABLE_COMPLETE = 9017,/**< File transfer failure,
+                                                    *  unable to complete download.
+                                                    */
+   CMSRET_FILE_TRANSFER_FILE_CORRUPTED = 9018,/**< File transfer failure,
+                                                    *  file corrupted.
+                                                    */
+   CMSRET_FILE_TRANSFER_FILE_AUTHENTICATION_ERROR = 9019,/**< File transfer failure,
+                                                    *  file authentication error.
+                                                    */
+   CMSRET_FILE_TRANSFER_FILE_TIMEOUT = 9020,/**< File transfer failure,
+                                                    *  download timeout.
+                                                    */
+   CMSRET_FILE_TRANSFER_FILE_CANCELLATION_NOT_ALLOW = 9021,/**< File transfer failure,
+                                                    *  cancellation not permitted.
+                                                    */
+   CMSRET_INVALID_UUID_FORMAT = 9022,/**< Invalid UUID Format
+                                                    * (associated with ChangeDUState)
+                                                    */
+   CMSRET_UNKNOWN_EE = 9023,/**< Unknown Execution Environment
+                                                    * (associated with ChangeDUState)
+                                                    */
+
+   CMSRET_EE_DISABLED = 9024,/**< Execution Environment disabled
+                                                    * (associated with ChangeDUState)
+                                                    */
+   CMSRET_DU_EE_MISMATCH = 9025,/**< Execution Environment and Deployment Unit mismatch
+                                                    * (associated with ChangeDUState:install/update)
+                                                    */
+   CMSRET_DU_DUPLICATE = 9026,/**< Duplicate Deployment Unit
+                                                    * (associated with ChangeDUState:install/update)
+                                                    */
+   CMSRET_SW_MODULE_SYSTEM_RESOURCE_EXCEEDED = 9027,/**< System resources exceeded
+                                                    * (associated with ChangeDUState:install/update)
+                                                    */
+   CMSRET_DU_UNKNOWN = 9028,/**< Unknown Deployment Unit
+                                                    * (associated with ChangeDUState:update/uninstall)
+                                                    */
+   CMSRET_DU_STATE_INVALID = 9029,/**< Invalid Deployment Unit State
+                                                    * (associated with ChangeDUState:update)
+                                                    */
+   CMSRET_DU_UPDATE_DOWNGRADE_NOT_ALLOWED = 9030,/**< Invalid Deployment Unit Update, downgrade not permitted
+                                                    * (associated with ChangeDUState:update)
+                                                    */
+   CMSRET_DU_UPDATE_VERSION_NOT_SPECIFIED = 9031,/**< Invalid Deployment Unit Update, version not specified
+                                                    * (associated with ChangeDUState:update)
+                                                    */
+
+   CMSRET_DU_UPDATE_VERSION_EXISTED= 9032,/**< Invalid Deployment Unit Update, version already exists
+                                                    * (associated with ChangeDUState:update)
+                                                    */
+#if 1 // __MSTC__, Nick Tseng, Login Privilege
+   CMSRET_FAIL_USER_NAME_FORMAT = 9101,/**<User name format error. */
+   CMSRET_FAIL_USER_NAME_LENGTH = 9102,/**<User name length error. */
+   CMSRET_FAIL_USER_NAME_DUPLICATE = 9103,/**<User name duplicate. */
+   CMSRET_FAIL_PASSWORD_FORMAT = 9104,/**<Password format error. */
+   CMSRET_FAIL_PASSWORD_LENGTH = 9105,/**<Password length error. */
+   CMSRET_FAIL_PASSWORD_DUPLICATE = 9106,/**<Password duplicate with 3 previous passowrd. */
+#endif
+#if 1 //__MSTC__, Richard Huang,                                               
+   CMSRET_FAIL_RULE_NAME_DUPLICATE = 9107, /**<Rule name duplicate. */
+   CMSRET_FAIL_RULE_IS_USED = 9108, /**<Rule is used. */
+   CMSRET_SKIP_CURR_ACTION = 9813,
+#endif
+   CMSRET_SUCCESS_REBOOT_REQUIRED = 9800, /**< Config successful, but requires reboot to take effect. */
+   CMSRET_SUCCESS_UNRECOGNIZED_DATA_IGNORED = 9801,  /**<Success, but some unrecognized data was ignored. */
+   CMSRET_SUCCESS_OBJECT_UNCHANGED = 9802,  /**<Success, furthermore object has not changed, returned by STL handler functions. */
+   CMSRET_FAIL_REBOOT_REQUIRED = 9803,  /**<Config failed, and now system is in a bad state requiring reboot. */
+   CMSRET_NO_MORE_INSTANCES = 9804,     /**<getnext operation cannot find any more instances to return. */
+   CMSRET_MDM_TREE_ERROR = 9805,         /**<Error during MDM tree traversal */
+   CMSRET_WOULD_DEADLOCK = 9806, /**< Caller is requesting a lock while holding the same lock or a different one. */
+   CMSRET_LOCK_REQUIRED = 9807,  /**< The MDM lock is required for this operation. */
+   CMSRET_OP_INTR = 9808,      /**<Operation was interrupted, most likely by a Linux signal. */
+   CMSRET_TIMED_OUT = 9809,     /**<Operation timed out. */
+   CMSRET_DISCONNECTED = 9810,  /**< Communications link is disconnected. */
+   CMSRET_MSG_BOUNCED = 9811,   /**< Msg was sent to a process not running, and the
+                                 *   bounceIfNotRunning flag was set on the header.  */
+   CMSRET_OP_ABORTED_BY_USER = 9812,  /**< Operation was aborted/discontinued by the user */
+   CMSRET_RECURSION_ERROR = 9817,     /**< too many levels of recursion */
+   CMSRET_OPEN_FILE_ERROR = 9818,     /**< open file error */
+   CMSRET_EAGAIN_ERROR = 9820,        /**< socket write EAGAIN error */
+   CMSRET_SOCKET_ERROR = 9821,        /**< socket error */
+   CMSRET_KEY_GENERATION_ERROR = 9830,     /** certificate key generation error */
+   CMSRET_INVALID_CERT_REQ = 9831,     /** requested certificate does not match with issued certificate */
+   CMSRET_INVALID_CERT_SUBJECT = 9832,     /** certificate has invalid subject information */
+   CMSRET_OBJECT_NOT_FOUND = 9840,     /** failed to find object */
+
+   CMSRET_INVALID_FILENAME = 9850,  /**< filename was not given for download */
+   CMSRET_INVALID_IMAGE = 9851,     /**< bad image was given for download */
+   CMSRET_INVALID_CONFIG_FILE = 9852,  /**< invalid config file was detected */
+   CMSRET_CONFIG_PSI = 9853,         /**< old PSI/3.x config file was detected */
+   CMSRET_IMAGE_FLASH_FAILED = 9854, /**< could not write the image to flash */
+   CMSRET_RESOURCE_NOT_CONFIGURED = 9855, /**< requested resource is not configured/found */
+#if 1 //__MSTC__, TengChang, for firmwareUpgrade.html
+   CMSRET_INVALID_MODELID = 9856,
+   CMSRET_INVALID_BOOTROMSIZE = 9857,
+#endif //__MSTC__, TengChang, for firmwareUpgrade.html
+} CmsRet;
+
+
+#if 1 //__MSTC__, Amy
+typedef enum
+{
+   LSRET_PASS     = 0,
+   LSRET_LOGINFAIL= 1,
+   LSRET_SHOWINFO = 2,    
+   LSRET_EXPIRED  = 3,
+   LSRET_USED     = 4,
+   LSRET_SAMENAME = 5,
+   LSRET_FORMAT   = 6,
+   LSRET_LENGTH   = 7,
+   LSRET_FAIL     = 9,
+   LSRET_NULL     = 10,
+   LSRET_ID_LENGTH = 11,
+   LSRET_ID_FORMAT = 12,
+} LoginStatusRet;
+#endif
+
+
+/** Check if the CmsRet code is either SUCCESS or SUCCESS_REBOOT_REQUIRED.
+ * CMSRET_SUCCESS_REBOOT is returned in two scenarios:
+ * 1. During a set, the RCL handler function has accepted the new value but
+ *    is unable to change the system configuration at run-time, so a reboot
+ *    is needed before the change can take effect.
+ * 2. During a AddObject or DeleteObject.  The MDM object tree has been
+ *    successfully updated, but the RCL handler function is unable to change
+ *    the system configuration at run-time, so a reboot is needed before the
+ *    change can take effect.
+ * Be very careful if you add any other return codes to this macro.
+ * Make sure you understand what you are doing.  Specifically,
+ * do not add CMSRET_SUCCESS_UNRECOGNIZED_DATA_IGNORED or
+ * CMSRET_SUCCESS_OBJECT_UNCHANGED to this macro.  These return codes are
+ * used in different contexts.
+ */
+#define IS_CMSRET_A_SUCCESS_VARIANT(r) (((r) == CMSRET_SUCCESS) || \
+                                        ((r) == CMSRET_SUCCESS_REBOOT_REQUIRED))
+
+/** Check if the CmsRet code is a TR69c recognized value.
+ */
+#define IS_CMSRET_A_TR69C_VARIANT(r) (((r) == CMSRET_SUCCESS) ||        \
+                                      (((r) >= 9000) && ((r) < 9800)))
+
+
+
+#ifndef TRUE
+/** TRUE = 1
+ */
+#define TRUE  1
+#endif
+
+#ifndef FALSE
+/** FALSE = 0
+ */
+#define FALSE 0
+#endif
+
+/** Maximum value for a UINT64 */
+#define MAX_UINT64 18446744073709551615ULL
+
+/** Maximum value for a SINT64 */
+#define MAX_SINT64 9223372036854775807LL
+
+/** Minimum value for a SINT64 */
+#define MIN_SINT64 (-1 * MAX_SINT64 - 1)
+
+/** Maximum value for a UINT32 */
+#define MAX_UINT32 4294967295U
+
+/** Maximum value for a SINT32 */
+#define MAX_SINT32 2147483647
+
+/** Minimum value for a SINT32 */
+#define MIN_SINT32 (-2147483648)
+
+/** Maximum value for a UINT16 */
+#define MAX_UINT16  65535
+
+/** Maximum value for a SINT16 */
+#define MAX_SINT16  32767
+
+/** Minimum value for a SINT16 */
+#define MIN_SINT16  (-32768)
+
+
+/**
+ * This is common used string length types.
+ */
+#define BUFLEN_4        4     //!< buffer length 4
+#define BUFLEN_8        8     //!< buffer length 8
+#define BUFLEN_16       16    //!< buffer length 16
+#define BUFLEN_18       18    //!< buffer length 18 -- for ppp session id
+#define BUFLEN_24       24    //!< buffer length 24 -- mostly for password
+#define BUFLEN_32       32    //!< buffer length 32
+#define BUFLEN_40       40    //!< buffer length 40
+#define BUFLEN_48       48    //!< buffer length 48
+#define BUFLEN_64       64    //!< buffer length 64
+#define BUFLEN_80       80    //!< buffer length 80
+#define BUFLEN_128      128   //!< buffer length 128
+#define BUFLEN_256      256   //!< buffer length 256
+#define BUFLEN_264      264   //!< buffer length 264
+#define BUFLEN_512      512   //!< buffer length 512
+#define BUFLEN_1024     1024  //!< buffer length 1024
+#define BUFLEN_4096     4096  //!< buffer length 4096
+
+#if 1 //__MSTC__, Dennis, 3 group privilege size
+#define PRIVILEGE_BUFLEN  (512 * 3)
+#endif
+
+#define IIDSTACK_BUF_LEN  40  //!< good length to use for mdm_dumpIidStack
+#define MAC_ADDR_LEN    6     //!< Mac address len in an array of 6 bytes
+#define MAC_STR_LEN     17    //!< Mac String len with ":". eg: xx:xx:xx:xx:xx:xx
+#define VPI_MIN         0     //!< VPI min 
+#define VPI_MAX         255   //!< VPI max 
+#define VCI_MIN         32    //!< VCI min 
+#define VCI_MAX         65535 //!< VCI max 
+
+#define PPP_CONNECT_ERROR_REASON_LEN 48
+
+#define CMS_IFNAME_LENGTH  BUFLEN_32   //!< broadcom interface name length
+#define CMS_MAX_ACS_URL_LENGTH   260   //!< max acs url from dhcp server, specified in TR-181 as max length 256
+#define CMS_MAX_ACS_PROVISIONING_CODE_LENGTH 68  //!< max acs provisioning code, TR-181 max length is 64
+
+#define CMS_AFTR_NAME_LENGTH   256     //!< max aftr name from dhcpv6 server
+
+#ifdef DMP_X_5067F0_IPV6_1    /* aka SUPPORT_IPV6 */
+#define CMS_IPADDR_LENGTH  46          //!< IP address length to hold IPv6 in CIDR notation (match INET6_ADDRSTRLEN)
+#else
+#define CMS_IPADDR_LENGTH  BUFLEN_16   //!< IP address length to hold IPv4 in ASCII
+#endif /* DMP_X_5067F0_IPV6_1 */
+#
+#define CMS_MAX_DEFAULT_GATEWAY     8  //!< max default gateways allowed in L3 X_5067F0_DefaultConnectionServices
+#define CMS_MAX_DNSIFNAME           8  //!< max dns wan interface names in X_BROADCOM_Networking.DNSIfName
+#define CMS_MAX_ACTIVE_DNS_IP       4  //!< max active dns ip (in resolv.conf)
+
+#ifdef DMP_X_5067F0_GPONRG_OMCI_LIGHT_1
+#define CMS_MAX_GPONWAN_INTF        4  //!< max gpon wan layer 2 interfaces for light omci GponRg
+#else
+#ifdef DMP_X_5067F0_GPONRG_OMCI_FULL_1
+#define CMS_MAX_GPONWAN_INTF        1  //!< max gpon wan layer 2 interfaces for full omci GponRg
+#else
+#define CMS_MAX_GPONWAN_INTF        0  //!< No gpon at all, so no GPONWAN intf
+#endif
+#endif
+
+/**
+ * Values for network protocol
+ */
+#define PROTO_PPPOE        0  //!< PPPoE protocol
+#define PROTO_PPPOA        1  //!< PPPoA protocol
+#define PROTO_MER          2  //!< MER protocol
+#define PROTO_BRIDGE       3  //!< bridge protocol
+#define PROTO_PPPOE_RELA   4  //!< PPPoE relay protocol
+#define PROTO_IPOA         5  //!< ip over atm protocol
+#define PROTO_IPOWAN       6  //!< ip over wan protocol
+#define PROTO_NONE         10 //!< invalid protocol
+
+#define IFC_WAN_MAX        16  //!< Max WAN Connection in the system.
+#define IFC_VLAN_MAX       8  //!< Max VLAN on single PVC
+#define ATM_QUEUE_MAX      8  //!< Max ATM queues
+
+/*!\enum WanIfcType
+ * \brief Enumerated values of WAN interface types.
+ */
+typedef enum {
+   WAN_IFC_ATM=0,       /**< ATM */
+   WAN_IFC_PPPOA=1,     /**< PPPoA */
+   WAN_IFC_IPOA=2,      /**< IPoA */
+   WAN_IFC_ETH=3,       /**< Eth */
+   WAN_IFC_PTM=4,       /**< Ptm */
+   WAN_IFC_NONE=10      /**< undefined/invalid */
+} WanIfcType;
+
+#ifdef NOT_USED_AND_USE_CMSWANCONNECTIONTYPE_BELOW
+/******************* NOTE:  DO NOT USE WanProtocal. USE CmsWanConnetctionType Below !!!!! ***********
+ * !\enum WanProtocol
+ * \brief Enumerated values of WAN connection protocols.
+ * This should be used to replace the same set of defines in cms.h
+ */
+typedef enum {
+   WAN_PROTO_PPPOE=0,   /**< PPPoE */
+   WAN_PROTO_PPPOA=1,   /** < PPPoA */
+   WAN_PROTO_MER=2,     /**< static or dynamic mer */
+   WAN_PROTO_BRIDGE=3,  /**< bridge */
+   WAN_PROTO_PPPOE_RELAY=4,  /**< pppoe relay */
+   WAN_PROTO_IPOA=5,     /**< IPoA */
+   WAN_PROTO_IPOWAN=6,   /**< IP over Wan only when SUPPORT ETHWAN */
+   WAN_PROTO_NONE=10     /**< no proto found/defined/invalid */
+} WanProtocol;
+#endif 
+
+/* try to match with the above old defines  PROTO_PPPOE=0 PPPOA=1, MER=2, BRIDGE=3 thing 
+ * so that no html changes need  */
+typedef enum 
+
+{
+   CMS_WAN_TYPE_PPPOE               = 0,
+   CMS_WAN_TYPE_PPPOA               = 1,
+   CMS_WAN_TYPE_DYNAMIC_IPOE        = 2,
+   CMS_WAN_TYPE_BRIDGE              = 3,
+   CMS_WAN_TYPE_PPPOE_RELAY         = 4,
+   CMS_WAN_TYPE_IPOA                = 5,
+   CMS_WAN_TYPE_STATIC_IPOE         = 6,   
+   
+   CMS_WAN_TYPE_STATIC_ETHERNET_IP  = 10,
+   CMS_WAN_TYPE_DYNAMIC_ETHERNET_IP = 11,
+   CMS_WAN_TYPE_ETHERNET_PPPOE      = 12,
+   CMS_WAN_TYPE_ETHERNET_BRIDGE     = 13,
+   CMS_WAN_TYPE_UNDEFINED           = 99
+} CmsWanConnectionType;
+
+
+
+#define BRIDGE_PROTO_STR      "Bridge"
+#define IPOA_PROTO_STR        "IPoA"
+#define IPOE_PROTO_STR        "IPoE"
+#define PPPOE_PROTO_STR       "PPPoE"
+#define PPPOA_PROTO_STR       "PPPoA"
+#define IPOW_PROTO_STR        "IPoW"
+#ifdef DMP_X_5067F0_MSTC_WWAN_1 // __MSTC__, Richard Huang,
+#define PPP_PROTO_STR         "PPP"
+#endif
+
+#define ETH_IFC_STR           "eth"
+#define USB_IFC_STR           "usb"
+#define WLAN_IFC_STR          "wl"
+#define MOCA_IFC_STR          "moca"
+#define GPON_IFC_STR          "veip"
+#define EPON_IFC_STR          "epon"
+#define ATM_IFC_STR           "atm"
+#define PTM_IFC_STR           "ptm"
+#define BRIDGE_IFC_STR        "br"
+#define IPOA_IFC_STR          "ipoa"
+#define IPOE_IFC_STR          "ipoe"
+#define PPP_IFC_STR           "ppp"
+#define PPPOE_IFC_STR         "pppoe"
+#define PPPOA_IFC_STR         "pppoa"
+#define IPA_IFC_STR           "ipa"
+#define BRIDGE_SMUX_STR       "bridge"
+#ifdef DMP_X_5067F0_MSTC_WWAN_1 // __MSTC__, Richard Huang, For Telefonica 3G WAN backup, __TELEFONICA__, MitraStar Chehuai, 20110617 */
+#define PPPO3G_IFC_STR        "pppo3G"
+#endif
+
+/* for interface group with routed pvc */
+#define RT_TABLES_BASE 200
+
+typedef enum
+{
+   ATM=0,          /**< WanDev is used for DSL ATM  */               
+   PTM=1,          /**< WanDev is used for DSL PTM  */     
+   Ethernet=2      /**< WanDev is used for Ethernet  */
+}WanLinkType;
+
+
+typedef enum
+{
+   CMS_CONNECTION_MODE_DEFAULT=0,      /**< Default connection mdoe - single wan service over 1 connection */          
+   CMS_CONNECTION_MODE_VLANMUX=1,      /**< Vlan mux connection mdoe - multiple vlan service over 1 connection */          
+   CMS_CONNECTION_MODE_MSC=2,          /**< MSC connection mdoe - multiple wan service over 1 connection */           
+} ConnectionModeType;
+   
+
+typedef enum
+{
+   ATM_EOA=0,        /**< WanDev is used for DSL ATM  */               
+   ATM_IPOA=1,       /**< WanDev is used for DSL ATM IPOA */
+   ATM_PPPOA=2,      /**< WanDev is used for DSL ATM PPPoA */
+   PTM_EOA=3         /**< WanDev is used for DSL PTM  */     
+   
+}Layer2IfNameType;
+
+
+typedef enum
+{
+   ENBL_IPV4_ONLY=0,     /**< Wan Connection is IPv4 only  */               
+   ENBL_IPV4_IPV6=1,     /**< Wan Connection is dual stack */     
+   ENBL_IPV6_ONLY=2      /**< Wan Connection is IPv6 only  */
+}WanConnL3Type;
+
+
+/* RAM size defines */
+#define SZ_8MB          0x800000
+#define SZ_16MB         0x1000000
+
+/*filter*/
+#define CFG_FILTER_CMD_SIZE 256
+
+#define MAX_PERSISTENT_WAN_PORT     39       /**< Max Ethernet ports can be configured as WAN ports */
+#define MAX_GMAC_ETH_PORT           5        /**< Max GMAC Ethernet ports in the system */
+
+#define DNSINFO_CONF  "/var/dnsinfo.conf"   /**< This file is created by cms when there is a WAN connection status change and is used
+                                               * by dnsproxy and can be used by other applications for the finding the WAN dns info. 
+                                               * and has the following fields,  WAN Interface; Subnet/Mask; dns1, dns2..; app1, app2.. :
+                                                    * eg. atm1;172.0.0.1/32;10.7.2.8,20.1.2.5;tr69c    -- WAN service for TR69
+                                                    * 1). WAN interface name. eg. ppp0, atm0, etc.
+                                               * 2)  subnet/mask in cidr format (bind to this WAN)
+                                                    * 3) dns list for this WAN
+                                                    * 4) process name list uses this WAN
+                                                    */
+
+/* include cms_params.h after we have defined all other constants. */
+#include "cms_params.h"
+
+/* for Gpon */
+typedef enum
+{
+    OMCI_FLOW_NONE = 0,
+    OMCI_FLOW_UPSTREAM,
+    OMCI_FLOW_DOWNSTREAM,
+    OMCI_FLOW_BOTH,
+} OmciFLowDirection;
+
+
+typedef enum
+{
+   LOGIN_INVALID=0,     /**< This is for httpd login */
+   LOGIN_USER=1,        /**< user login */     
+   LOGIN_SUPPORT=2,     /**< support login  */
+   LOGIN_ADMIN=10,      /**< admin login  */       
+} HttpLoginType;
+
+#if 1 //__MSTC__, DingRuei, Run time chage Web UI
+/*Web UI Style Type*/
+#define WEBUI_BRICK 1
+#define WEBUI_BRCM 2
+#define WEBUI_BRICK_ODM 3
+#define UNKNOWN_TYPE 1025
+#endif //__MSTC__, DingRuei, Run time chage Web UI
+
+#ifdef SUPPORT_MSTC_WEB_REDIRECT // __MSTC__, for web redirect
+#define WAN_REDIRECT_STATUS_FILE       "/var/redirect_status"
+#endif
+
+#endif /* __CMS_H__ */
diff --git a/cms_lzw.h b/cms_lzw.h
new file mode 100644 (file)
index 0000000..9dd8d4d
--- /dev/null
+++ b/cms_lzw.h
@@ -0,0 +1,179 @@
+/*
+ * LZW decoder
+ * Copyright (c) 2003 Fabrice Bellard.
+ * Copyright (c) 2006 Konstantin Shishkov.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CMS_LZW_H__
+#define __CMS_LZW_H__
+
+/*!\file cms_lzw.h
+ * \brief Header file for LZW Encoder/Decoder functions.
+ * 
+ * These functions were taken from the ffmpeg library.
+ */
+
+
+#define LZW_MAXBITS        12
+#define LZW_SIZTABLE       (1<<LZW_MAXBITS)
+#define LZW_HASH_SIZE      16411
+#define LZW_HASH_SHIFT     6
+
+#define LZW_PREFIX_EMPTY   -1
+#define LZW_PREFIX_FREE    -2
+
+
+/** fixed length header in front of compressed config file */
+#define COMPRESSED_CONFIG_HEADER_LENGTH 40
+
+/** start of compressed config file */
+#define COMPRESSED_CONFIG_HEADER        "<compressed alg=lzw len="
+
+
+/** One code in hash table */
+typedef struct Code{
+    /// Hash code of prefix, LZW_PREFIX_EMPTY if empty prefix, or LZW_PREFIX_FREE if no code
+    int hash_prefix;
+    int code;               ///< LZW code
+    uint8_t suffix;         ///< Last character in code block
+}Code;
+
+
+typedef struct PutBitContext {
+    uint32_t bit_buf;
+    int bit_left;
+    uint8_t *buf, *buf_ptr, *buf_end;
+} PutBitContext;
+
+
+/** LZW encode state */
+typedef struct {
+    int clear_code;          ///< Value of clear code
+    int end_code;            ///< Value of end code
+    Code tab[LZW_HASH_SIZE]; ///< Hash table
+    int tabsize;             ///< Number of values in hash table
+    int bits;                ///< Actual bits code
+    int bufsize;             ///< Size of output buffer
+    PutBitContext pb;        ///< Put bit context for output
+    int maxbits;             ///< Max bits code
+    int maxcode;             ///< Max value of code
+    int output_bytes;        ///< Number of written bytes
+    int last_code;           ///< Value of last output code or LZW_PREFIX_EMPTY
+}LZWEncoderState;
+
+
+/** LZW decoder state structure */
+typedef struct {
+    uint8_t *pbuf, *ebuf;
+    int bbits;
+    unsigned int bbuf;
+
+    int mode;                   ///< Decoder mode
+    int cursize;                ///< The current code size
+    int curmask;
+    int codesize;
+    int clear_code;
+    int end_code;
+    int newcodes;               ///< First available code
+    int top_slot;               ///< Highest code for current size
+    int extra_slot;
+    int slot;                   ///< Last read code
+    int fc, oc;
+    uint8_t *sp;
+    uint8_t stack[LZW_SIZTABLE];
+    uint8_t suffix[LZW_SIZTABLE];
+    uint16_t prefix[LZW_SIZTABLE];
+    int bs;                     ///< current buffer size for GIF
+} LZWDecoderState;
+
+
+/** Create and Initialize a LZW encoder.
+ *
+ * @param s       (IN/OUT) LZW encoder state structure allocated by this function.
+ * @param outbuf  (IN)  Output buffer, caller is responsible for allocating the buffer.
+ * @param outsize (IN)  Size of output buffer
+ *
+ * @return CmsRet enum
+ */
+CmsRet cmsLzw_initEncoder(LZWEncoderState **s, UINT8 *outbuf, UINT32 outsize);
+
+
+/** LZW main encode/compress function
+ *
+ * @param s      (IN) LZW encoder state
+ * @param inbuf  (IN) Input buffer, contains data to be compressed
+ * @param insize (IN) Size of input buffer
+ * @return Number of bytes written or -1 on error
+ */
+SINT32 cmsLzw_encode(LZWEncoderState *s, const UINT8 *inbuf, UINT32 insize);
+
+
+/** Write end code and flush bitstream
+ *
+ * @param s (IN) LZW encoder state
+ * @return Number of bytes written or -1 on error.  Note the count here should
+ *         be added to the count returned by cmsLzw_encode for the total number
+ *         of encoded/compressed bytes.
+ */
+SINT32 cmsLzw_flushEncoder(LZWEncoderState *s);
+
+
+/** Destroy the LZW encoder.
+ *  Note the output buffer that was passed into the cmsLzw_initEncoder
+ *  is not freed.  That buffer is the responsibility of the caller.
+ *
+ * @param s      (IN) LZW encoder state
+ */
+void cmsLzw_cleanupEncoder(LZWEncoderState **s);
+
+
+/** Create and Initialize a LZW decoder
+ *
+ * @param s          (IN/OUT) LZW decoder context
+ * @param inbuf      (IN) input compressed data
+ * @param inbuf_size (IN) input data size
+ *
+ * @return CmsRet enum
+ */
+CmsRet cmsLzw_initDecoder(LZWDecoderState **s, UINT8 *inbuf, UINT32 inbuf_size);
+
+
+/** Decode given number of bytes
+ *
+ * @param s       (IN) LZW decoder context
+ * @param outbuf  (IN) output buffer, caller is responsible for allocating this buffer
+ * @param outlen  (IN) number of bytes to decode, or the length of the output buffer.
+ *                  The decompressor/decoder will stop if the end of the encoded
+ *                  data is reached or if the end of the output buffer is reached.
+ *
+ * @return number of bytes decoded, or -1 on error.
+ */
+SINT32 cmsLzw_decode(LZWDecoderState *s, UINT8 *outbuf, UINT32 outlen);
+
+
+/** Destroy the LZW Decoder.
+ *
+ * Note the input buffer that was passed into cmsLzw_initDecoder is not freed.
+ * That buffer is the responsibility of the caller.
+ */
+void cmsLzw_cleanupDecoder(LZWDecoderState **s);
+
+
+
+#endif /* __CMS_LZW_H__ */
diff --git a/lzw_decode.c b/lzw_decode.c
new file mode 100644 (file)
index 0000000..e331560
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * LZW decoder
+ * Copyright (c) 2003 Fabrice Bellard.
+ * Copyright (c) 2006 Konstantin Shishkov.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifdef COMPRESSED_CONFIG_FILE
+
+#include "cms_lzw.h"
+
+
+
+static const uint16_t mask[17] =
+{
+    0x0000, 0x0001, 0x0003, 0x0007,
+    0x000F, 0x001F, 0x003F, 0x007F,
+    0x00FF, 0x01FF, 0x03FF, 0x07FF,
+    0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
+};
+
+
+enum FF_LZW_MODES{
+    FF_LZW_GIF,
+    FF_LZW_TIFF
+};
+
+
+/* get one code from stream */
+static int lzw_get_code(LZWDecoderState *s)
+{
+    int c;
+
+    /* always use TIFF mode */
+
+    while (s->bbits < s->cursize) {
+        s->bbuf = (s->bbuf << 8) | (*s->pbuf++);
+        s->bbits += 8;
+    }
+    //    printf("TIFF: bbuf=0x%08x bbits=%d cursize=%d\n", s->bbuf, s->bbits, s->cursize);
+    c = s->bbuf >> (s->bbits - s->cursize);
+
+    s->bbits -= s->cursize;
+
+    //    printf("bbits=%d c=0x%08x curmask=0x%08x\n", s->bbits, c, s->curmask);
+    return c & s->curmask;
+}
+
+
+void ff_lzw_decode_tail(LZWDecoderState *s)
+{
+    /* always use TIFF mode */
+    s->pbuf= s->ebuf;
+}
+
+
+CmsRet cmsLzw_initDecoder(LZWDecoderState **p, UINT8 *inbuf, UINT32 inbuf_size)
+{
+    LZWDecoderState *s;
+    int mode = FF_LZW_TIFF;  /* always use TIFF mode */
+    int csize = 8;  /* the encoder side has this hardcoded, so hardcode here too */
+
+    *p = (LZWDecoderState *) cmsMem_alloc(sizeof(LZWDecoderState), ALLOC_ZEROIZE);
+    if (*p == NULL)
+    {
+       cmsLog_error("could not allocate %d bytes for decoder state", sizeof(LZWDecoderState));
+       return CMSRET_RESOURCE_EXCEEDED;
+    }
+    else
+    {
+       cmsLog_debug("%d bytes allocated for decoder state", sizeof(LZWDecoderState));
+    }
+
+    s = *p;
+
+    /* read buffer */
+    s->pbuf = inbuf;
+    s->ebuf = s->pbuf + inbuf_size;
+    s->bbuf = 0;
+    s->bbits = 0;
+    s->bs = 0;
+
+    /* decoder */
+    s->codesize = csize;
+    s->cursize = s->codesize + 1;
+    s->curmask = mask[s->cursize];
+    s->top_slot = 1 << s->cursize;
+    s->clear_code = 1 << s->codesize;
+    s->end_code = s->clear_code + 1;
+    s->slot = s->newcodes = s->clear_code + 2;
+    s->oc = s->fc = -1;
+    s->sp = s->stack;
+
+    s->mode = mode;
+    s->extra_slot = (s->mode == FF_LZW_TIFF);
+
+    return CMSRET_SUCCESS;
+}
+
+
+SINT32 cmsLzw_decode(LZWDecoderState *s, UINT8 *outbuf, UINT32 outlen)
+{
+    UINT32 l;
+    int c, code, oc, fc;
+    uint8_t *sp;
+
+    if (s->end_code < 0)
+        return -1;
+
+    l = outlen;
+    sp = s->sp;
+    oc = s->oc;
+    fc = s->fc;
+
+    for (;;) {
+
+        while (sp > s->stack) {
+           //           printf("transfer stack to buf, sp=0x%02x buf=%p\n", *sp, outbuf);
+            *outbuf++ = *(--sp);
+            if ((--l) == 0)
+                goto the_end;
+        }
+
+        c = lzw_get_code(s);
+        if (c == s->end_code) {
+            cmsLog_debug("got end code %d", c);
+            break;
+        } else if (c == s->clear_code) {
+            cmsLog_debug("got clear code %d", c);
+            s->cursize = s->codesize + 1;
+            s->curmask = mask[s->cursize];
+            s->slot = s->newcodes;
+            s->top_slot = 1 << s->cursize;
+            fc= oc= -1;
+        } else {
+            code = c;
+            //            printf("got valid code %d (0x%02x)\n", c, c);
+
+            if (code == s->slot && fc>=0) {
+                *sp++ = fc;
+                code = oc;
+            }else if(code >= s->slot) {
+                cmsLog_error("code %d greater than slot %d", code, s->slot);
+                break;
+            }
+
+            while (code >= s->newcodes) {
+               //               printf("transfer suffix to to sp \n");
+                *sp++ = s->suffix[code];
+                code = s->prefix[code];
+            }
+
+            //            printf("sp=%p gets code %d\n", sp, code);
+            *sp++ = code;
+
+
+            if (s->slot < s->top_slot && oc>=0) {
+               //                printf("suffix[%d]=%d prefix[%d]=%d\n", s->slot, code, s->slot, oc);
+                s->suffix[s->slot] = code;
+                s->prefix[s->slot++] = oc;
+            }
+            fc = code;
+            oc = c;
+
+            if (s->slot >= s->top_slot - s->extra_slot) {
+                if (s->cursize < LZW_MAXBITS) {
+                    s->top_slot <<= 1;
+                    s->curmask = mask[++s->cursize];
+                    //                    printf("new top_slot=0x%x curmask=0x%x\n", s->top_slot, s->curmask);
+                }
+            }
+        }
+    }  // end of for loop
+
+
+    s->end_code = -1;
+  the_end:
+    s->sp = sp;
+    s->oc = oc;
+    s->fc = fc;
+
+    cmsLog_debug("about to return, outlen=%d l=%d\n", outlen, l);
+    return outlen - l;
+}
+
+
+
+void cmsLzw_cleanupDecoder(LZWDecoderState **s)
+{
+   cmsMem_free(*s);
+   *s = NULL;
+}
+
+
+
+#endif /* COMPRESSED_CONFIG_FILE */
diff --git a/lzw_encode.c b/lzw_encode.c
new file mode 100644 (file)
index 0000000..714e70f
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * LZW encoder
+ * Copyright (c) 2007 Bartlomiej Wolowiec
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef COMPRESSED_CONFIG_FILE
+
+#include "cms_lzw.h"
+
+
+#ifdef DESKTOP_LINUX
+
+/*
+ * We are on Intel.  Intel is LE.
+ */
+#define be2me_16(x) ntohs(x)
+#define be2me_32(x) ntohl(x)
+
+#else
+
+/*
+ * We are on the MIPS.  MIPS is in BE mode.
+ */
+#define be2me_16(x) (x)
+#define be2me_32(x) (x)
+
+#define UNALIGNED_STORES_ARE_BAD
+#endif
+
+
+#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
+#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
+
+
+/**
+ * Hash function adding character
+ * @param head LZW code for prefix
+ * @param add Character to add
+ * @return New hash value
+ */
+static inline int hash(int head, const int add)
+{
+    head ^= (add << LZW_HASH_SHIFT);
+    if (head >= LZW_HASH_SIZE)
+        head -= LZW_HASH_SIZE;
+    cmsAst_assert(head >= 0 && head < LZW_HASH_SIZE);
+    return head;
+}
+
+/**
+ * Hash function calculates next hash value
+ * @param head Actual hash code
+ * @param offset Offset calculated by hashOffset
+ * @return New hash value
+ */
+static inline int hashNext(int head, const int offset)
+{
+    head -= offset;
+    if(head < 0)
+        head += LZW_HASH_SIZE;
+    return head;
+}
+
+/**
+ * Hash function calculates hash offset
+ * @param head Actual hash code
+ * @return Hash offset
+ */
+static inline int hashOffset(const int head)
+{
+    return head ? LZW_HASH_SIZE - head : 1;
+}
+
+
+static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
+{
+    if(buffer_size < 0) {
+        buffer_size = 0;
+        buffer = NULL;
+    }
+
+    s->buf = buffer;
+    s->buf_end = s->buf + buffer_size;
+
+    s->buf_ptr = s->buf;
+    s->bit_left=32;
+    s->bit_buf=0;
+}
+
+
+void put_bits(PutBitContext *s, int n, unsigned int value)
+{
+    unsigned int bit_buf;
+    int bit_left;
+
+    //    printf("put_bits=%d %c (0x%x)\n", n, value, value);
+    cmsAst_assert(n == 32 || value < (1U << n));
+
+    bit_buf = s->bit_buf;
+    bit_left = s->bit_left;
+
+    //    printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
+    /* XXX: optimize */
+    if (n < bit_left) {
+        bit_buf = (bit_buf<<n) | value;
+        bit_left-=n;
+    } else {
+        bit_buf<<=bit_left;
+        bit_buf |= value >> (n - bit_left);
+#ifdef UNALIGNED_STORES_ARE_BAD
+        if (3 & (intptr_t) s->buf_ptr) {
+            s->buf_ptr[0] = bit_buf >> 24;
+            s->buf_ptr[1] = bit_buf >> 16;
+            s->buf_ptr[2] = bit_buf >>  8;
+            s->buf_ptr[3] = bit_buf      ;
+        } else
+#endif
+        *(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
+        //        printf("STORING: buf=%p be bitbuf = %08x me=%08x (bit_left=%d)\n",
+        //               s->buf_ptr, bit_buf, *(uint32_t *)s->buf_ptr, bit_left);
+        s->buf_ptr+=4;
+        bit_left+=32 - n;
+        bit_buf = value;
+    }
+
+    s->bit_buf = bit_buf;
+    s->bit_left = bit_left;
+}
+
+/* pad the end of the output stream with zeros */
+static inline void flush_put_bits(PutBitContext *s)
+{
+    s->bit_buf<<= s->bit_left;
+    while (s->bit_left < 32) {
+        /* XXX: should test end of buffer */
+        *s->buf_ptr++=s->bit_buf >> 24;
+        s->bit_buf<<=8;
+        s->bit_left+=8;
+    }
+    s->bit_left=32;
+    s->bit_buf=0;
+}
+
+
+/* return the number of bits output */
+static inline int put_bits_count(PutBitContext *s)
+{
+    return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
+}
+
+
+
+/**
+ * Write one code to stream
+ * @param s LZW state
+ * @param c code to write
+ */
+static inline void writeCode(LZWEncoderState * s, int c)
+{
+    cmsAst_assert(0 <= c && c < 1 << s->bits);
+    put_bits(&s->pb, s->bits, c);
+}
+
+
+/**
+ * Find LZW code for block
+ * @param s LZW state
+ * @param c Last character in block
+ * @param hash_prefix LZW code for prefix
+ * @return LZW code for block or -1 if not found in table
+ */
+static inline int findCode(LZWEncoderState * s, uint8_t c, int hash_prefix)
+{
+    int h = hash(FFMAX(hash_prefix, 0), c);
+    int hash_offset = hashOffset(h);
+
+    while (s->tab[h].hash_prefix != LZW_PREFIX_FREE) {
+        if ((s->tab[h].suffix == c)
+            && (s->tab[h].hash_prefix == hash_prefix))
+            return h;
+        h = hashNext(h, hash_offset);
+    }
+
+    return h;
+}
+
+/**
+ * Add block to LZW code table
+ * @param s LZW state
+ * @param c Last character in block
+ * @param hash_prefix LZW code for prefix
+ * @param hash_code LZW code for bytes block
+ */
+static inline void addCode(LZWEncoderState * s, uint8_t c, int hash_prefix, int hash_code)
+{
+    s->tab[hash_code].code = s->tabsize;
+    s->tab[hash_code].suffix = c;
+    s->tab[hash_code].hash_prefix = hash_prefix;
+
+    s->tabsize++;
+
+    if (s->tabsize >= 1 << s->bits)
+        s->bits++;
+}
+
+/**
+ * Clear LZW code table
+ * @param s LZW state
+ */
+static void clearTable(LZWEncoderState * s)
+{
+    int i, h;
+    //    printf("clearTable called\n");
+    writeCode(s, s->clear_code);
+    s->bits = 9;
+    for (i = 0; i < LZW_HASH_SIZE; i++) {
+        s->tab[i].hash_prefix = LZW_PREFIX_FREE;
+    }
+    for (i = 0; i < 256; i++) {
+        h = hash(0, i);
+        s->tab[h].code = i;
+        s->tab[h].suffix = i;
+        s->tab[h].hash_prefix = LZW_PREFIX_EMPTY;
+    }
+    s->tabsize = 258;
+}
+
+/**
+ * Calculate number of bytes written
+ * @param s LZW encode state
+ * @return Number of bytes written
+ */
+static SINT32 writtenBytes(LZWEncoderState *s){
+    int ret = put_bits_count(&s->pb) >> 3;
+    ret -= s->output_bytes;
+    s->output_bytes += ret;
+    return ret;
+}
+
+
+CmsRet cmsLzw_initEncoder(LZWEncoderState **p, UINT8 *outbuf, UINT32 outsize)
+{
+   LZWEncoderState *s;
+
+    *p = (LZWEncoderState *) cmsMem_alloc(sizeof(LZWEncoderState), ALLOC_ZEROIZE);
+    if (*p == NULL)
+    {
+       cmsLog_error("could not allocate %d bytes for encoder state", sizeof(LZWEncoderState));
+       return CMSRET_RESOURCE_EXCEEDED;
+    }
+    else
+    {
+       cmsLog_debug("%d bytes allocated for encoder state", sizeof(LZWEncoderState));
+    }
+
+    s = *p;
+
+    s->clear_code = 256;
+    s->end_code = 257;
+    s->maxbits = LZW_MAXBITS;
+    init_put_bits(&s->pb, outbuf, outsize);
+    s->bufsize = outsize;
+    cmsAst_assert(9 <= s->maxbits && s->maxbits <= s->maxbits);
+    s->maxcode = 1 << s->maxbits;
+    s->output_bytes = 0;
+    s->last_code = LZW_PREFIX_EMPTY;
+    s->bits = 9;
+
+    return CMSRET_SUCCESS;
+}
+
+
+int cmsLzw_encode(LZWEncoderState *s, const UINT8 *inbuf, UINT32 insize)
+{
+    UINT32 i;
+    UINT32 round_error=5;
+
+    //    printf("size check, insize*3=%d outbuf*2=%d\n", insize * 3, s->bufsize * 2);
+    if(insize * 3 > (UINT32) (s->bufsize - s->output_bytes) * 2 + round_error){
+        cmsLog_error("size check failed, insize=%d (*3) outsize=%d (*2)", insize, (s->bufsize - s->output_bytes));
+        return -1;
+    }
+
+    if (s->last_code == LZW_PREFIX_EMPTY)
+        clearTable(s);
+
+    for (i = 0; i < insize; i++) {
+        uint8_t c = *inbuf++;
+        int code = findCode(s, c, s->last_code);
+
+        //        printf("\n\n[%d] c=%c code=%d\n", i, c, code);        
+        if (s->tab[code].hash_prefix == LZW_PREFIX_FREE) {
+            writeCode(s, s->last_code);
+            addCode(s, c, s->last_code, code);
+            code= hash(0, c);
+        }
+        s->last_code = s->tab[code].code;
+        if (s->tabsize >= s->maxcode - 1) {
+            clearTable(s);
+        }
+    }
+
+    return writtenBytes(s);
+}
+
+
+SINT32 cmsLzw_flushEncoder(LZWEncoderState * s)
+{
+    if (s->last_code != -1)
+        writeCode(s, s->last_code);
+
+    writeCode(s, s->end_code);
+    flush_put_bits(&s->pb);
+    s->last_code = -1;
+
+    return writtenBytes(s);
+}
+
+
+void cmsLzw_cleanupEncoder(LZWEncoderState **s)
+{
+   cmsMem_free(*s);
+   *s = NULL;
+}
+
+
+#endif /* COMPRESSED_CONFIG_FILE */
+