Ver código fonte

add: 添加sdk初始版本

Wendal Chen 4 anos atrás
pai
commit
e66b6bd00f
100 arquivos alterados com 29606 adições e 0 exclusões
  1. 6 0
      .gitignore
  2. 21 0
      LICENSE
  3. 20 0
      Third_Party/ZBAR/include/bch15_5.h
  4. 17 0
      Third_Party/ZBAR/include/binarize.h
  5. 49 0
      Third_Party/ZBAR/include/code128.h
  6. 42 0
      Third_Party/ZBAR/include/config.h
  7. 95 0
      Third_Party/ZBAR/include/debug.h
  8. 207 0
      Third_Party/ZBAR/include/decoder.h
  9. 6 0
      Third_Party/ZBAR/include/errno.h
  10. 232 0
      Third_Party/ZBAR/include/error.h
  11. 62 0
      Third_Party/ZBAR/include/event.h
  12. 134 0
      Third_Party/ZBAR/include/image.h
  13. 38 0
      Third_Party/ZBAR/include/img_scanner.h
  14. 41 0
      Third_Party/ZBAR/include/isaac.h
  15. 160 0
      Third_Party/ZBAR/include/mutex.h
  16. 23 0
      Third_Party/ZBAR/include/qr_finder.h
  17. 66 0
      Third_Party/ZBAR/include/qrcode.h
  18. 170 0
      Third_Party/ZBAR/include/qrdec.h
  19. 84 0
      Third_Party/ZBAR/include/refcnt.h
  20. 66 0
      Third_Party/ZBAR/include/rs.h
  21. 65 0
      Third_Party/ZBAR/include/svg.h
  22. 92 0
      Third_Party/ZBAR/include/symbol.h
  23. 127 0
      Third_Party/ZBAR/include/thread.h
  24. 132 0
      Third_Party/ZBAR/include/timer.h
  25. 45 0
      Third_Party/ZBAR/include/type.h
  26. 52 0
      Third_Party/ZBAR/include/util.h
  27. 160 0
      Third_Party/ZBAR/include/video.h
  28. 148 0
      Third_Party/ZBAR/include/window.h
  29. 1344 0
      Third_Party/ZBAR/include/zbar.h
  30. 242 0
      Third_Party/ZBAR/include/zbar_config.h
  31. 184 0
      Third_Party/ZBAR/src/bch15_5.c
  32. 639 0
      Third_Party/ZBAR/src/binarize.c
  33. 516 0
      Third_Party/ZBAR/src/code128.c
  34. 148 0
      Third_Party/ZBAR/src/config.c
  35. 1139 0
      Third_Party/ZBAR/src/convert.c
  36. 402 0
      Third_Party/ZBAR/src/decoder.c
  37. 182 0
      Third_Party/ZBAR/src/error.c
  38. 308 0
      Third_Party/ZBAR/src/image.c
  39. 792 0
      Third_Party/ZBAR/src/img_scanner.c
  40. 138 0
      Third_Party/ZBAR/src/isaac.c
  41. 77 0
      Third_Party/ZBAR/src/qr_finder.c
  42. 3957 0
      Third_Party/ZBAR/src/qrdec.c
  43. 403 0
      Third_Party/ZBAR/src/qrdectxt.c
  44. 48 0
      Third_Party/ZBAR/src/refcnt.c
  45. 799 0
      Third_Party/ZBAR/src/rs.c
  46. 311 0
      Third_Party/ZBAR/src/scanner.c
  47. 244 0
      Third_Party/ZBAR/src/symbol.c
  48. 140 0
      Third_Party/ZBAR/src/util.c
  49. 380 0
      Third_Party/ZBAR/src/video.c
  50. 1760 0
      Third_Party/ZBAR/src/zbar.c
  51. 740 0
      Third_Party/cm_backtrace/cm_backtrace.c
  52. 40 0
      Third_Party/cm_backtrace/cm_backtrace.h
  53. 50 0
      Third_Party/cm_backtrace/cmb_cfg.h
  54. 368 0
      Third_Party/cm_backtrace/cmb_def.h
  55. 43 0
      Third_Party/cm_backtrace/fault_handler/gcc/cmb_fault.S
  56. 46 0
      Third_Party/cm_backtrace/fault_handler/iar/cmb_fault.S
  57. 47 0
      Third_Party/cm_backtrace/fault_handler/keil/cmb_fault.S
  58. 1603 0
      Third_Party/heap/bget.c
  59. 17 0
      Third_Party/heap/bget.h
  60. 36 0
      Third_Party/iconv/include/iconv.h
  61. 23 0
      Third_Party/iconv/include/prv_iconv.h
  62. 100 0
      Third_Party/iconv/src/iconv.c
  63. 117 0
      Third_Party/vsprintf/printf.h
  64. 24 0
      application/include/app_interface.h
  65. 141 0
      application/include/luat_conf_bsp.h
  66. 3964 0
      application/include/mbedtls/config.h
  67. 1 0
      application/include/readme.txt
  68. 53 0
      application/src/luat_adc_air105.c
  69. 257 0
      application/src/luat_base_air105.c
  70. 243 0
      application/src/luat_camera_air105.c
  71. 427 0
      application/src/luat_crypto_air105.c
  72. 24 0
      application/src/luat_dac_air105.c
  73. 154 0
      application/src/luat_fs_air105.c
  74. 105 0
      application/src/luat_gpio_air105.c
  75. 43 0
      application/src/luat_i2c_air105.c
  76. 51 0
      application/src/luat_keyboard_air105.c
  77. 41 0
      application/src/luat_log_air105.c
  78. 109 0
      application/src/luat_malloc_air105.c
  79. 25 0
      application/src/luat_mcu_air105.c
  80. 65 0
      application/src/luat_msgbus_air105.c
  81. 29 0
      application/src/luat_otp_air105.c
  82. 22 0
      application/src/luat_pin_air105.c
  83. 104 0
      application/src/luat_pwm_air105.c
  84. 45 0
      application/src/luat_rtc_air105.c
  85. 63 0
      application/src/luat_sfd_onchip_air105.c
  86. 61 0
      application/src/luat_shell_air105.c
  87. 230 0
      application/src/luat_spi_air105.c
  88. 103 0
      application/src/luat_timer_air105.c
  89. 226 0
      application/src/luat_uart_air105.c
  90. 24 0
      application/src/luat_wdt_air105.c
  91. 13 0
      application/src/readme.txt
  92. 2087 0
      bsp/air105/chip/include/air105.h
  93. 147 0
      bsp/air105/chip/include/air105_adc.h
  94. 66 0
      bsp/air105/chip/include/air105_bpk.h
  95. 114 0
      bsp/air105/chip/include/air105_cache.h
  96. 51 0
      bsp/air105/chip/include/air105_conf.h
  97. 74 0
      bsp/air105/chip/include/air105_crc.h
  98. 98 0
      bsp/air105/chip/include/air105_dac.h
  99. 360 0
      bsp/air105/chip/include/air105_dcmi.h
  100. 219 0
      bsp/air105/chip/include/air105_dma.h

+ 6 - 0
.gitignore

@@ -50,3 +50,9 @@ modules.order
 Module.symvers
 Mkfile.old
 dkms.conf
+
+build
+Makefile
+
+.xmake
+*.mk

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019-2022 openLuat
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 20 - 0
Third_Party/ZBAR/include/bch15_5.h

@@ -0,0 +1,20 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#if !defined(_bch15_5_H)
+# define _bch15_5_H (1)
+
+/*Encodes a raw 5-bit value _x into a 15-bit BCH(15,5) code.
+  This is capable of correcting up to 3 bit errors, and detecting as many as
+   5 bit errors in some cases.*/
+unsigned bch15_5_encode(unsigned _x);
+
+/*Corrects the received code *_y, if possible.
+  The original data is located in the top five bits.
+  Returns the number of errors corrected, or a negative value if decoding
+   failed due to too many bit errors, in which case *_y is left unchanged.*/
+int bch15_5_correct(unsigned *_y);
+
+#endif

+ 17 - 0
Third_Party/ZBAR/include/binarize.h

@@ -0,0 +1,17 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#if !defined(_qrcode_binarize_H)
+# define _qrcode_binarize_H (1)
+
+void qr_image_cross_masking_median_filter(unsigned char *_img,
+ int _width,int _height);
+
+void qr_wiener_filter(unsigned char *_img,int _width,int _height);
+
+/*Binarizes a grayscale image.*/
+unsigned char *qr_binarize(const unsigned char *_img,int _width,int _height);
+
+#endif

+ 49 - 0
Third_Party/ZBAR/include/code128.h

@@ -0,0 +1,49 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _CODE128_H_
+#define _CODE128_H_
+
+/* Code 128 specific decode state */
+typedef struct code128_decoder_s {
+    unsigned direction : 1;     /* scan direction: 0=fwd/space, 1=rev/bar */
+    unsigned element : 3;       /* element offset 0-5 */
+    int character : 12;         /* character position in symbol */
+    unsigned s6;                /* character width */
+
+    unsigned config;
+    int configs[NUM_CFGS];      /* int valued configurations */
+} code128_decoder_t;
+
+/* reset Code 128 specific state */
+static inline void code128_reset (code128_decoder_t *dcode128)
+{
+    dcode128->direction = 0;
+    dcode128->element = 0;
+    dcode128->character = -1;
+    dcode128->s6 = 0;
+}
+
+/* decode Code 128 symbols */
+zbar_symbol_type_t _zbar_decode_code128(zbar_decoder_t *dcode);
+
+#endif

+ 42 - 0
Third_Party/ZBAR/include/config.h

@@ -0,0 +1,42 @@
+/**************************************************************************
+ * TTPCom Software Copyright (c) 1997-2005 TTPCom Ltd
+ * Licensed to TTP_CLIENT_NAME
+ **************************************************************************
+ *   $Id: //central/releases/simcom/branch_release_16_0_4_B_simcom/tplgsm/kiinc/config.h#1 $
+ *   $Revision: #1 $
+ *   $DateTime: 2006/11/27 07:18:36 $
+ **************************************************************************
+ * File Description : Global configuration parameters
+ **************************************************************************/
+
+#if !defined (CONFIG_H)
+#define       CONFIG_H
+
+/****************************************************************************
+ *  WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ *  TTPCom do not add new items to this file unless they are system wide
+ *  and non-Application specific. They should be nothing to do with GSM,
+ *  GPRS, 3G, Bluetooth or any other application.
+ *
+ *  WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ ***************************************************************************/
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/*
+** Mechanism for conditional compiling code dependant on PC/Target
+** environment. Default is on target.
+*/
+/* Detect Borland PC compiler */
+#if !defined (ON_PC) && defined (__WIN32__)
+#   define ON_PC
+#endif
+/* Detect Microsoft PC compiler */
+#if !defined (ON_PC) && defined (WIN32)
+//#   define ON_PC
+#endif
+
+#endif
+/* END OF FILE */

+ 95 - 0
Third_Party/ZBAR/include/debug.h

@@ -0,0 +1,95 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+/* varargs variations on compile time debug spew */
+#if 1
+
+#define dprintf(...)
+#define zassert(condition, retval, format, ...) //assert(condition)
+#define assert(x) if( ( x ) == 0 ) { __disable_irq(); DBG_Trace("\r\nassert %s,%d", __FUNCTION__, __LINE__); for( ;; ); }
+#define zprintf(level, format, y...) DBG_Printf(format, ##y)
+#define CHECK()	Core_DebugMem(0, __FUNCTION__, __LINE__);
+#else
+#ifndef DEBUG_LEVEL
+
+# ifdef __GNUC__
+    /* older versions of gcc (< 2.95) require a named varargs parameter */
+#  define dprintf(args...)
+# else
+    /* unfortunately named vararg parameter is a gcc-specific extension */
+#  define dprintf(...)
+# endif
+
+#else
+
+# include <stdio.h>
+
+# ifdef __GNUC__
+#  define dprintf(level, args...) \
+    if((level) <= DEBUG_LEVEL)    \
+        fprintf(stderr, args)
+# else
+#  define dprintf(level, ...)     \
+    if((level) <= DEBUG_LEVEL)    \
+        fprintf(stderr, __VA_ARGS__)
+# endif
+
+#endif /* DEBUG_LEVEL */
+
+/* spew warnings for non-fatal assertions.
+ * returns specified error code if assertion fails.
+ * NB check/return is still performed for NDEBUG
+ * only the message is inhibited
+ * FIXME don't we need varargs hacks here?
+ */
+#ifndef NDEBUG
+
+# include <stdio.h>
+
+#if __STDC_VERSION__ < 199901L && !defined(__func__)
+# if __GNUC__ >= 2
+#  define __func__ __FUNCTION__
+# else
+#  define __func__ "<unknown>"
+# endif
+#endif
+
+# define zassert(condition, retval, format, ...) do {                   \
+        if(!(condition)) {                                              \
+            fprintf(stderr, "WARNING: %s:%d: %s:"                       \
+                    " Assertion \"%s\" failed.\n\t" format,             \
+                    __FILE__, __LINE__, __func__, #condition ,          \
+                    ##__VA_ARGS__);                                     \
+            return(retval);                                             \
+        }                                                               \
+    } while(0)
+
+#else
+
+# define zassert(condition, retval, format, ...) do {   \
+        if(!(condition))                                \
+            return(retval);                             \
+    } while(0)
+
+#endif
+#endif

+ 207 - 0
Third_Party/ZBAR/include/decoder.h

@@ -0,0 +1,207 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _DECODER_H_
+#define _DECODER_H_
+
+#include <zbar_config.h>
+//#include <stdlib.h>     /* realloc */
+
+#include <zbar.h>
+
+#define NUM_CFGS (ZBAR_CFG_MAX_LEN - ZBAR_CFG_MIN_LEN + 1)
+
+#ifdef ENABLE_EAN
+# include "ean.h"
+#endif
+#ifdef ENABLE_I25
+# include "i25.h"
+#endif
+#ifdef ENABLE_CODE39
+# include "code39.h"
+#endif
+#ifdef ENABLE_CODE128
+# include "code128.h"
+#endif
+#ifdef ENABLE_PDF417
+# include "pdf417.h"
+#endif
+#ifdef ENABLE_QRCODE
+# include "qr_finder.h"
+#endif
+
+/* size of bar width history (implementation assumes power of two) */
+#ifndef DECODE_WINDOW
+# define DECODE_WINDOW  16
+#endif
+
+/* initial data buffer allocation */
+#ifndef BUFFER_MIN
+# define BUFFER_MIN   0x20
+#endif
+
+/* maximum data buffer allocation
+ * (longer symbols are rejected)
+ */
+#ifndef BUFFER_MAX
+# define BUFFER_MAX  0x100
+#endif
+
+/* buffer allocation increment */
+#ifndef BUFFER_INCR
+# define BUFFER_INCR  0x10
+#endif
+
+#define CFG(dcode, cfg) ((dcode).configs[(cfg) - ZBAR_CFG_MIN_LEN])
+#define TEST_CFG(config, cfg) (((config) >> (cfg)) & 1)
+
+/* symbology independent decoder state */
+struct zbar_decoder_s {
+    unsigned char idx;                  /* current width index */
+    unsigned w[DECODE_WINDOW];          /* window of last N bar widths */
+    zbar_symbol_type_t type;            /* type of last decoded data */
+    zbar_symbol_type_t lock;            /* buffer lock */
+
+    /* everything above here is automatically reset */
+    unsigned buf_alloc;                 /* dynamic buffer allocation */
+    unsigned buflen;                    /* binary data length */
+    unsigned char *buf;                 /* decoded characters */
+    void *userdata;                     /* application data */
+    zbar_decoder_handler_t *handler;    /* application callback */
+
+    /* symbology specific state */
+#ifdef ENABLE_EAN
+    ean_decoder_t ean;                  /* EAN/UPC parallel decode attempts */
+#endif
+#ifdef ENABLE_I25
+    i25_decoder_t i25;                  /* Interleaved 2 of 5 decode state */
+#endif
+#ifdef ENABLE_CODE39
+    code39_decoder_t code39;            /* Code 39 decode state */
+#endif
+#ifdef ENABLE_CODE128
+    code128_decoder_t code128;          /* Code 128 decode state */
+#endif
+#ifdef ENABLE_PDF417
+    pdf417_decoder_t pdf417;            /* PDF417 decode state */
+#endif
+#ifdef ENABLE_QRCODE
+    qr_finder_t qrf;                    /* QR Code finder state */
+#endif
+};
+
+/* return current element color */
+static inline char get_color (const zbar_decoder_t *dcode)
+{
+    return(dcode->idx & 1);
+}
+
+/* retrieve i-th previous element width */
+static inline unsigned get_width (const zbar_decoder_t *dcode,
+                                  unsigned char offset)
+{
+    return(dcode->w[(dcode->idx - offset) & (DECODE_WINDOW - 1)]);
+}
+
+/* retrieve bar+space pair width starting at offset i */
+static inline unsigned pair_width (const zbar_decoder_t *dcode,
+                                   unsigned char offset)
+{
+    return(get_width(dcode, offset) + get_width(dcode, offset + 1));
+}
+
+/* calculate total character width "s"
+ *   - start of character identified by context sensitive offset
+ *     (<= DECODE_WINDOW - n)
+ *   - size of character is n elements
+ */
+static inline unsigned calc_s (const zbar_decoder_t *dcode,
+                               unsigned char offset,
+                               unsigned char n)
+{
+    /* FIXME check that this gets unrolled for constant n */
+    unsigned s = 0;
+    while(n--)
+        s += get_width(dcode, offset++);
+    return(s);
+}
+
+/* fixed character width decode assist
+ * bar+space width are compared as a fraction of the reference dimension "x"
+ *   - +/- 1/2 x tolerance
+ *   - measured total character width (s) compared to symbology baseline (n)
+ *     (n = 7 for EAN/UPC, 11 for Code 128)
+ *   - bar+space *pair width* "e" is used to factor out bad "exposures"
+ *     ("blooming" or "swelling" of dark or light areas)
+ *     => using like-edge measurements avoids these issues
+ *   - n should be > 3
+ */
+static inline int decode_e (unsigned e,
+                            unsigned s,
+                            unsigned n)
+{
+    /* result is encoded number of units - 2
+     * (for use as zero based index)
+     * or -1 if invalid
+     */
+    unsigned char E = ((e * n * 2 + 1) / s - 3) / 2;
+    return((E >= n - 3) ? -1 : E);
+}
+
+/* acquire shared state lock */
+static inline char get_lock (zbar_decoder_t *dcode,
+                             zbar_symbol_type_t req)
+{
+    if(dcode->lock)
+        return(1);
+    dcode->lock = req;
+    return(0);
+}
+
+/* ensure output buffer has sufficient allocation for request */
+static inline char size_buf (zbar_decoder_t *dcode,
+                             unsigned len)
+{
+	unsigned char *buf;
+    if(len < dcode->buf_alloc)
+        /* FIXME size reduction heuristic? */
+        return(0);
+    if(len > BUFFER_MAX)
+        return(1);
+    if(len < dcode->buf_alloc + BUFFER_INCR) {
+        len = dcode->buf_alloc + BUFFER_INCR;
+        if(len > BUFFER_MAX)
+            len = BUFFER_MAX;
+    }
+    
+	buf = realloc(dcode->buf, len);
+    if(!buf)
+        return(1);
+    dcode->buf = buf;
+    dcode->buf_alloc = len;
+    return(0);
+}
+
+extern const char *_zbar_decoder_buf_dump (unsigned char *buf,
+                                            unsigned int buflen);
+
+#endif

+ 6 - 0
Third_Party/ZBAR/include/errno.h

@@ -0,0 +1,6 @@
+extern int errno;
+
+
+#define	EINVAL 22	/* Invalid argument */
+#define	E2BIG 7		/* Arg list too long */
+

+ 232 - 0
Third_Party/ZBAR/include/error.h

@@ -0,0 +1,232 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _ERROR_H_
+#define _ERROR_H_
+
+#include <config.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+//#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+//#include <assert.h>
+#include "debug.h"
+#include <zbar.h>
+
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+#  define __func__ __FUNCTION__
+# else
+#  define __func__ "<unknown>"
+# endif
+#endif
+
+#define ERRINFO_MAGIC (0x5252457a) /* "zERR" (LE) */
+
+typedef enum errsev_e {
+    SEV_FATAL   = -2,           /* application must terminate */
+    SEV_ERROR   = -1,           /* might be able to recover and continue */
+    SEV_OK      =  0,
+    SEV_WARNING =  1,           /* unexpected condition */
+    SEV_NOTE    =  2,           /* fyi */
+} errsev_t;
+
+typedef enum errmodule_e {
+    ZBAR_MOD_PROCESSOR,
+    ZBAR_MOD_VIDEO,
+    ZBAR_MOD_WINDOW,
+    ZBAR_MOD_IMAGE_SCANNER,
+    ZBAR_MOD_UNKNOWN,
+} errmodule_t;
+
+typedef struct errinfo_s {
+    uint32_t magic;             /* just in case */
+    errmodule_t module;         /* reporting module */
+    char *buf;                  /* formatted and passed to application */
+    int errnum;                 /* errno for system errors */
+
+    errsev_t sev;
+    zbar_error_t type;
+    const char *func;           /* reporting function */
+    const char *detail;         /* description */
+    char *arg_str;              /* single string argument */
+    int arg_int;                /* single integer argument */
+} errinfo_t;
+
+extern int _zbar_verbosity;
+
+/* FIXME don't we need varargs hacks here? */
+
+#ifdef _WIN32
+# define ZFLUSH fflush(stderr);
+#else
+# define ZFLUSH
+#endif
+
+#define ZNO_MESSAGES
+
+#ifdef ZNO_MESSAGES
+
+#if 0
+# ifdef __GNUC__
+    /* older versions of gcc (< 2.95) require a named varargs parameter */
+#  define zprintf(args...)
+# else
+    /* unfortunately named vararg parameter is a gcc-specific extension */
+#  define zprintf(...)
+# endif
+
+#else
+
+# ifdef __GNUC__
+#  define zprintf(level, format, args...) do {                          \
+        if(_zbar_verbosity >= level) {                                  \
+            fprintf(stderr, "%s: " format, __func__ , ##args);          \
+            ZFLUSH                                                      \
+        }                                                               \
+    } while(0)
+# else
+#  define zprintf(level, format, ...) do {                              \
+        if(_zbar_verbosity >= level) {                                  \
+            fprintf(stderr, "%s: " format, __func__ , ##__VA_ARGS__);   \
+            ZFLUSH                                                      \
+        }                                                               \
+    } while(0)
+# endif
+
+#endif
+#endif
+static inline int err_copy (void *dst_c,
+                            void *src_c)
+{
+//    errinfo_t *dst = dst_c;
+//    errinfo_t *src = src_c;
+//    assert(dst->magic == ERRINFO_MAGIC);
+//    assert(src->magic == ERRINFO_MAGIC);
+//
+//    dst->errnum = src->errnum;
+//    dst->sev = src->sev;
+//    dst->type = src->type;
+//    dst->func = src->func;
+//    dst->detail = src->detail;
+//    dst->arg_str = src->arg_str;
+//    src->arg_str = NULL; /* unused at src, avoid double free */
+//    dst->arg_int = src->arg_int;
+    return(-1);
+}
+
+static inline int err_capture (const void *container,
+                               errsev_t sev,
+                               zbar_error_t type,
+                               const char *func,
+                               const char *detail)
+{
+//    errinfo_t *err = (errinfo_t*)container;
+//    assert(err->magic == ERRINFO_MAGIC);
+//    if(type == ZBAR_ERR_SYSTEM)
+//        err->errnum = errno;
+//#ifdef _WIN32
+//    else if(type == ZBAR_ERR_WINAPI)
+//        err->errnum = GetLastError();
+//#endif
+//    err->sev = sev;
+//    err->type = type;
+//    err->func = func;
+//    err->detail = detail;
+//    if(_zbar_verbosity >= 1)
+//        _zbar_error_spew(err, 0);
+    return(-1);
+}
+
+static inline int err_capture_str (const void *container,
+                                   errsev_t sev,
+                                   zbar_error_t type,
+                                   const char *func,
+                                   const char *detail,
+                                   const char *arg)
+{
+//    errinfo_t *err = (errinfo_t*)container;
+//    assert(err->magic == ERRINFO_MAGIC);
+//    if(err->arg_str)
+//        free(err->arg_str);
+//    err->arg_str = strdup(arg);
+//    return(err_capture(container, sev, type, func, detail));
+	return -1;
+}
+
+static inline int err_capture_int (const void *container,
+                                   errsev_t sev,
+                                   zbar_error_t type,
+                                   const char *func,
+                                   const char *detail,
+                                   int arg)
+{
+//    errinfo_t *err = (errinfo_t*)container;
+//    assert(err->magic == ERRINFO_MAGIC);
+//    err->arg_int = arg;
+//    return(err_capture(container, sev, type, func, detail));
+	return -1;
+}
+
+static inline int err_capture_num (const void *container,
+                                   errsev_t sev,
+                                   zbar_error_t type,
+                                   const char *func,
+                                   const char *detail,
+                                   int num)
+{
+//    errinfo_t *err = (errinfo_t*)container;
+//    assert(err->magic == ERRINFO_MAGIC);
+//    err->errnum = num;
+//    return(err_capture(container, sev, type, func, detail));
+	return -1;
+}
+
+static inline void err_init (errinfo_t *err,
+                             errmodule_t module)
+{
+//    err->magic = ERRINFO_MAGIC;
+//    err->module = module;
+}
+
+static inline void err_cleanup (errinfo_t *err)
+{
+//    assert(err->magic == ERRINFO_MAGIC);
+//    if(err->buf) {
+//        free(err->buf);
+//        err->buf = NULL;
+//    }
+//    if(err->arg_str) {
+//        free(err->arg_str);
+//        err->arg_str = NULL;
+//    }
+}
+
+#endif

+ 62 - 0
Third_Party/ZBAR/include/event.h

@@ -0,0 +1,62 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _ZBAR_EVENT_H_
+#define _ZBAR_EVENT_H_
+
+#include <config.h>
+#include "mutex.h"
+#include "timer.h"
+
+/* platform synchronization "event" abstraction
+ */
+
+#if defined(_WIN32)
+
+# include <windows.h>
+
+typedef HANDLE zbar_event_t;
+
+
+#else
+
+# ifdef HAVE_LIBPTHREAD
+#  include <pthread.h>
+# endif
+
+typedef struct zbar_event_s {
+    int state;
+# ifdef HAVE_LIBPTHREAD
+    pthread_cond_t cond;
+# endif
+    int pollfd;
+} zbar_event_t;
+
+#endif
+
+
+extern int _zbar_event_init(zbar_event_t*);
+extern void _zbar_event_destroy(zbar_event_t*);
+extern void _zbar_event_trigger(zbar_event_t*);
+extern int _zbar_event_wait(zbar_event_t*, zbar_mutex_t*, zbar_timer_t*);
+
+#endif

+ 134 - 0
Third_Party/ZBAR/include/image.h

@@ -0,0 +1,134 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _IMAGE_H_
+#define _IMAGE_H_
+
+#include <config.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+//#include <stdlib.h>
+//#include <assert.h>
+
+#include "error.h"
+#include "symbol.h"
+#include "refcnt.h"
+#include <zbar.h>
+
+#define PRIx32    "lx"
+
+/* adapted from v4l2 spec */
+#define fourcc(a, b, c, d)                      \
+    ((uint32_t)(a) | ((uint32_t)(b) << 8) |     \
+     ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+/* unpack size/location of component */
+#define RGB_SIZE(c)   ((c) >> 5)
+#define RGB_OFFSET(c) ((c) & 0x1f)
+
+/* coarse image format categorization.
+ * to limit conversion variations
+ */
+typedef enum zbar_format_group_e {
+    ZBAR_FMT_GRAY,
+    ZBAR_FMT_YUV_PLANAR,
+    ZBAR_FMT_YUV_PACKED,
+    ZBAR_FMT_RGB_PACKED,
+    ZBAR_FMT_YUV_NV,
+    ZBAR_FMT_JPEG,
+
+    /* enum size */
+    ZBAR_FMT_NUM
+} zbar_format_group_t;
+
+
+struct zbar_image_s {
+    uint32_t format;            /* fourcc image format code */
+    unsigned width, height;     /* image size */
+    const void *data;           /* image sample data */
+    unsigned long datalen;      /* allocated/mapped size of data */
+    void *userdata;             /* user specified data associated w/image */
+
+    /* cleanup handler */
+    zbar_image_cleanup_handler_t *cleanup;
+    refcnt_t refcnt;            /* reference count */
+    zbar_video_t *src;          /* originator */
+    int srcidx;                 /* index used by originator */
+    zbar_image_t *next;         /* internal image lists */
+
+    unsigned seq;               /* page/frame sequence number */
+    zbar_symbol_set_t *syms;    /* decoded result set */
+};
+
+/* description of an image format */
+typedef struct zbar_format_def_s {
+    uint32_t format;                    /* fourcc */
+    zbar_format_group_t group;          /* coarse categorization */
+    union {
+        uint8_t gen[4];                 /* raw bytes */
+        struct {
+            uint8_t bpp;                /* bits per pixel */
+            uint8_t red, green, blue;   /* size/location a la RGB_BITS() */
+        } rgb;
+        struct {
+            uint8_t xsub2, ysub2;       /* chroma subsampling in each axis */
+            uint8_t packorder;          /* channel ordering flags
+                                         *   bit0: 0=UV, 1=VU
+                                         *   bit1: 0=Y/chroma, 1=chroma/Y
+                                         */
+        } yuv;
+        uint32_t cmp;                   /* quick compare equivalent formats */
+    } p;
+} zbar_format_def_t;
+
+
+extern int _zbar_best_format(uint32_t, uint32_t*, const uint32_t*);
+extern const zbar_format_def_t *_zbar_format_lookup(uint32_t);
+extern void _zbar_image_free(zbar_image_t*);
+
+#ifdef DEBUG_SVG
+extern int zbar_image_write_png(const zbar_image_t*, const char*);
+#else
+# define zbar_image_write_png(...)
+#endif
+
+static inline void _zbar_image_refcnt (zbar_image_t *img,
+                                       int delta)
+{
+    if(!_zbar_refcnt(&img->refcnt, delta) && delta <= 0) {
+        if(img->cleanup)
+            img->cleanup(img);
+        if(!img->src)
+            _zbar_image_free(img);
+    }
+}
+
+static inline void _zbar_image_swap_symbols (zbar_image_t *a,
+                                             zbar_image_t *b)
+{
+    zbar_symbol_set_t *tmp = a->syms;
+    a->syms = b->syms;
+    b->syms = tmp;
+}
+
+#endif

+ 38 - 0
Third_Party/ZBAR/include/img_scanner.h

@@ -0,0 +1,38 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _IMG_SCANNER_H_
+#define _IMG_SCANNER_H_
+
+#include <zbar.h>
+
+/* internal image scanner APIs for 2D readers */
+
+extern zbar_symbol_t *_zbar_image_scanner_alloc_sym(zbar_image_scanner_t*,
+                                                    zbar_symbol_type_t,
+                                                    int);
+extern void _zbar_image_scanner_add_sym(zbar_image_scanner_t*,
+                                        zbar_symbol_t*);
+extern void _zbar_image_scanner_recycle_syms(zbar_image_scanner_t*,
+                                             zbar_symbol_t*);
+
+#endif

+ 41 - 0
Third_Party/ZBAR/include/isaac.h

@@ -0,0 +1,41 @@
+/*Written by Timothy B. Terriberry (tterribe@xiph.org) 1999-2009 public domain.
+  Based on the public domain implementation by Robert J. Jenkins Jr.*/
+#if !defined(_isaac_H)
+# define _isaac_H (1)
+
+
+
+typedef struct isaac_ctx isaac_ctx;
+
+
+
+#define ISAAC_SZ_LOG      (8)
+#define ISAAC_SZ          (1<<ISAAC_SZ_LOG)
+#define ISAAC_SEED_SZ_MAX (ISAAC_SZ<<2)
+
+
+
+/*ISAAC is the most advanced of a series of Pseudo-Random Number Generators
+   designed by Robert J. Jenkins Jr. in 1996.
+  http://www.burtleburtle.net/bob/rand/isaac.html
+  To quote:
+    No efficient method is known for deducing their internal states.
+    ISAAC requires an amortized 18.75 instructions to produce a 32-bit value.
+    There are no cycles in ISAAC shorter than 2**40 values.
+    The expected cycle length is 2**8295 values.*/
+struct isaac_ctx{
+  unsigned n;
+  unsigned r[ISAAC_SZ];
+  unsigned m[ISAAC_SZ];
+  unsigned a;
+  unsigned b;
+  unsigned c;
+};
+
+
+void isaac_init(isaac_ctx *_ctx,const void *_seed,int _nseed);
+
+unsigned isaac_next_uint32(isaac_ctx *_ctx);
+unsigned isaac_next_uint(isaac_ctx *_ctx,unsigned _n);
+
+#endif

+ 160 - 0
Third_Party/ZBAR/include/mutex.h

@@ -0,0 +1,160 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _ZBAR_MUTEX_H_
+#define _ZBAR_MUTEX_H_
+
+#include <config.h>
+
+/* simple platform mutex abstraction
+ */
+
+#if defined(_WIN32)
+
+# include <windows.h>
+
+# define DEBUG_LOCKS
+# ifdef DEBUG_LOCKS
+
+typedef struct zbar_mutex_s {
+    int count;
+    CRITICAL_SECTION mutex;
+} zbar_mutex_t;
+
+static inline int _zbar_mutex_init (zbar_mutex_t *lock)
+{
+    lock->count = 1;
+    InitializeCriticalSection(&lock->mutex);
+    return(0);
+}
+
+static inline void _zbar_mutex_destroy (zbar_mutex_t *lock)
+{
+    DeleteCriticalSection(&lock->mutex);
+}
+
+static inline int _zbar_mutex_lock (zbar_mutex_t *lock)
+{
+    EnterCriticalSection(&lock->mutex);
+    if(lock->count++ < 1)
+        assert(0);
+    return(0);
+}
+
+static inline int _zbar_mutex_unlock (zbar_mutex_t *lock)
+{
+    if(lock->count-- <= 1)
+        assert(0);
+    LeaveCriticalSection(&lock->mutex);
+    return(0);
+}
+
+# else
+
+typedef CRITICAL_SECTION zbar_mutex_t;
+
+static inline int _zbar_mutex_init (zbar_mutex_t *lock)
+{
+    InitializeCriticalSection(lock);
+    return(0);
+}
+
+static inline void _zbar_mutex_destroy (zbar_mutex_t *lock)
+{
+    DeleteCriticalSection(lock);
+}
+
+static inline int _zbar_mutex_lock (zbar_mutex_t *lock)
+{
+    EnterCriticalSection(lock);
+    return(0);
+}
+
+static inline int _zbar_mutex_unlock (zbar_mutex_t *lock)
+{
+    LeaveCriticalSection(lock);
+    return(0);
+}
+
+# endif
+
+
+#elif defined(HAVE_LIBPTHREAD)
+
+# include <pthread.h>
+
+typedef pthread_mutex_t zbar_mutex_t;
+
+static inline int _zbar_mutex_init (zbar_mutex_t *lock)
+{
+# ifdef DEBUG_LOCKS
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+    int rc = pthread_mutex_init(lock, &attr);
+    pthread_mutexattr_destroy(&attr);
+    return(rc);
+# else
+    return(pthread_mutex_init(lock, NULL));
+# endif
+}
+
+static inline void _zbar_mutex_destroy (zbar_mutex_t *lock)
+{
+    pthread_mutex_destroy(lock);
+}
+
+static inline int _zbar_mutex_lock (zbar_mutex_t *lock)
+{
+    int rc = pthread_mutex_lock(lock);
+# ifdef DEBUG_LOCKS
+    assert(!rc);
+# endif
+    /* FIXME save system code */
+    /*rc = err_capture(proc, SEV_ERROR, ZBAR_ERR_LOCKING, __func__,
+                       "unable to lock processor");*/
+    return(rc);
+}
+
+static inline int _zbar_mutex_unlock (zbar_mutex_t *lock)
+{
+    int rc = pthread_mutex_unlock(lock);
+# ifdef DEBUG_LOCKS
+    assert(!rc);
+# endif
+    /* FIXME save system code */
+    return(rc);
+}
+
+
+#else
+
+typedef int zbar_mutex_t[0];
+
+#define _zbar_mutex_init(l) -1
+#define _zbar_mutex_destroy(l)
+#define _zbar_mutex_lock(l) 0
+#define _zbar_mutex_unlock(l) 0
+
+#endif
+
+#endif

+ 23 - 0
Third_Party/ZBAR/include/qr_finder.h

@@ -0,0 +1,23 @@
+#ifndef _DECODER_QR_FINDER_H_
+#define _DECODER_QR_FINDER_H_
+
+#include "qrcode.h"
+
+/* QR Code symbol finder state */
+typedef struct qr_finder_s {
+    unsigned s5;                /* finder pattern width */
+    qr_finder_line line;        /* position info needed by decoder */
+
+    unsigned config;
+} qr_finder_t;
+
+/* reset QR finder specific state */
+static inline void qr_finder_reset (qr_finder_t *qrf)
+{
+    qrf->s5 = 0;
+}
+
+/* find QR Code symbols */
+zbar_symbol_type_t _zbar_find_qr (zbar_decoder_t *dcode);
+
+#endif

+ 66 - 0
Third_Party/ZBAR/include/qrcode.h

@@ -0,0 +1,66 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#ifndef _QRCODE_H_
+#define _QRCODE_H_
+
+#include <zbar.h>
+
+typedef struct qr_reader qr_reader;
+
+typedef int qr_point[2];
+typedef struct qr_finder_line qr_finder_line;
+
+/*The number of bits of subpel precision to store image coordinates in.
+  This helps when estimating positions in low-resolution images, which may have
+   a module pitch only a pixel or two wide, making rounding errors matter a
+   great deal.*/
+#define QR_FINDER_SUBPREC (2)
+
+/*A line crossing a finder pattern.
+  Whether the line is horizontal or vertical is determined by context.
+  The offsts to various parts of the finder pattern are as follows:
+    |*****|     |*****|*****|*****|     |*****|
+    |*****|     |*****|*****|*****|     |*****|
+       ^        ^                 ^        ^
+       |        |                 |        |
+       |        |                 |       pos[v]+len+eoffs
+       |        |                pos[v]+len
+       |       pos[v]
+      pos[v]-boffs
+  Here v is 0 for horizontal and 1 for vertical lines.*/
+struct qr_finder_line {
+  /*The location of the upper/left endpoint of the line.
+    The left/upper edge of the center section is used, since other lines must
+     cross in this region.*/
+  qr_point pos;
+  /*The length of the center section.
+    This extends to the right/bottom of the center section, since other lines
+     must cross in this region.*/
+  int      len;
+  /*The offset to the midpoint of the upper/left section (part of the outside
+     ring), or 0 if we couldn't identify the edge of the beginning section.
+    We use the midpoint instead of the edge because it can be located more
+     reliably.*/
+  int      boffs;
+  /*The offset to the midpoint of the end section (part of the outside ring),
+     or 0 if we couldn't identify the edge of the end section.
+    We use the midpoint instead of the edge because it can be located more
+     reliably.*/
+  int      eoffs;
+};
+
+qr_reader *_zbar_qr_create(void);
+void _zbar_qr_destroy(qr_reader *reader);
+void _zbar_qr_reset(qr_reader *reader);
+
+int _zbar_qr_found_line(qr_reader *reader,
+                        int direction,
+                        const qr_finder_line *line);
+int _zbar_qr_decode(qr_reader *reader,
+                    zbar_image_scanner_t *iscn,
+                    zbar_image_t *img);
+
+#endif

+ 170 - 0
Third_Party/ZBAR/include/qrdec.h

@@ -0,0 +1,170 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#if !defined(_qrdec_H)
+# define _qrdec_H (1)
+
+#include <zbar.h>
+
+#define CHAR_BIT 8
+
+typedef struct qr_code_data_entry qr_code_data_entry;
+typedef struct qr_code_data       qr_code_data;
+typedef struct qr_code_data_list  qr_code_data_list;
+
+typedef enum qr_mode{
+  /*Numeric digits ('0'...'9').*/
+  QR_MODE_NUM=1,
+  /*Alphanumeric characters ('0'...'9', 'A'...'Z', plus the punctuation
+     ' ', '$', '%', '*', '+', '-', '.', '/', ':').*/
+  QR_MODE_ALNUM,
+  /*Structured-append header.*/
+  QR_MODE_STRUCT,
+  /*Raw 8-bit bytes.*/
+  QR_MODE_BYTE,
+  /*FNC1 marker (for more info, see http://www.mecsw.com/specs/uccean128.html).
+    In the "first position" data is formatted in accordance with GS1 General
+     Specifications.*/
+  QR_MODE_FNC1_1ST,
+  /*Mode 6 reserved?*/
+  /*Extended Channel Interpretation code.*/
+  QR_MODE_ECI=7,
+  /*SJIS kanji characters.*/
+  QR_MODE_KANJI,
+  /*FNC1 marker (for more info, see http://www.mecsw.com/specs/uccean128.html).
+    In the "second position" data is formatted in accordance with an industry
+     application as specified by AIM Inc.*/
+  QR_MODE_FNC1_2ND
+}qr_mode;
+
+/*Check if a mode has a data buffer associated with it.
+  Currently this is only modes with exactly one bit set.*/
+#define QR_MODE_HAS_DATA(_mode) (!((_mode)&(_mode)-1))
+
+/*ECI may be used to signal a character encoding for the data.*/
+typedef enum qr_eci_encoding{
+  /*GLI0 is like CP437, but the encoding is reset at the beginning of each
+     structured append symbol.*/
+  QR_ECI_GLI0,
+  /*GLI1 is like ISO8859_1, but the encoding is reset at the beginning of each
+     structured append symbol.*/
+  QR_ECI_GLI1,
+  /*The remaining encodings do not reset at the start of the next structured
+     append symbol.*/
+  QR_ECI_CP437,
+  /*Western European.*/
+  QR_ECI_ISO8859_1,
+  /*Central European.*/
+  QR_ECI_ISO8859_2,
+  /*South European.*/
+  QR_ECI_ISO8859_3,
+  /*North European.*/
+  QR_ECI_ISO8859_4,
+  /*Cyrillic.*/
+  QR_ECI_ISO8859_5,
+  /*Arabic.*/
+  QR_ECI_ISO8859_6,
+  /*Greek.*/
+  QR_ECI_ISO8859_7,
+  /*Hebrew.*/
+  QR_ECI_ISO8859_8,
+  /*Turkish.*/
+  QR_ECI_ISO8859_9,
+  /*Nordic.*/
+  QR_ECI_ISO8859_10,
+  /*Thai.*/
+  QR_ECI_ISO8859_11,
+  /*There is no ISO/IEC 8859-12.*/
+  /*Baltic rim.*/
+  QR_ECI_ISO8859_13=QR_ECI_ISO8859_11+2,
+  /*Celtic.*/
+  QR_ECI_ISO8859_14,
+  /*Western European with euro.*/
+  QR_ECI_ISO8859_15,
+  /*South-Eastern European (with euro).*/
+  QR_ECI_ISO8859_16,
+  /*ECI 000019 is reserved?*/
+  /*Shift-JIS.*/
+  QR_ECI_SJIS=20
+}qr_eci_encoding;
+
+
+/*A single unit of parsed QR code data.*/
+struct qr_code_data_entry{
+  /*The mode of this data block.*/
+  qr_mode mode;
+  union{
+    /*Data buffer for modes that have one.*/
+    struct{
+      unsigned char *buf;
+      int            len;
+    }data;
+    /*Decoded "Extended Channel Interpretation" data.*/
+    unsigned eci;
+    /*Structured-append header data.*/
+    struct{
+      unsigned char sa_index;
+      unsigned char sa_size;
+      unsigned char sa_parity;
+    }sa;
+  }payload;
+};
+
+
+
+/*Low-level QR code data.*/
+struct qr_code_data{
+  /*The decoded data entries.*/
+  qr_code_data_entry *entries;
+  int                 nentries;
+  /*The code version (1...40).*/
+  unsigned char       version;
+  /*The ECC level (0...3, corresponding to 'L', 'M', 'Q', and 'H').*/
+  unsigned char       ecc_level;
+  /*Structured-append information.*/
+  /*The index of this code in the structured-append group.
+    If sa_size is zero, this is undefined.*/
+  unsigned char       sa_index;
+  /*The size of the structured-append group, or 0 if there was no S-A header.*/
+  unsigned char       sa_size;
+  /*The parity of the entire structured-append group.
+    If sa_size is zero, this is undefined.*/
+  unsigned char       sa_parity;
+  /*The parity of this code.
+    If sa_size is zero, this is undefined.*/
+  unsigned char       self_parity;
+  /*An approximate bounding box for the code.
+    Points appear in the order up-left, up-right, down-left, down-right,
+     relative to the orientation of the QR code.*/
+  qr_point            bbox[4];
+};
+
+
+struct qr_code_data_list{
+  qr_code_data *qrdata;
+  int           nqrdata;
+  int           cqrdata;
+};
+
+
+/*Extract symbol data from a list of QR codes and attach to the image.
+  All text is converted to UTF-8.
+  Any structured-append group that does not have all of its members is decoded
+   as ZBAR_PARTIAL with ZBAR_PARTIAL components for the discontinuities.
+  Note that isolated members of a structured-append group may be decoded with
+   the wrong character set, since the correct setting cannot be propagated
+   between codes.
+  Return: The number of symbols which were successfully extracted from the
+   codes; this will be at most the number of codes.*/
+int qr_code_data_list_extract_text(const qr_code_data_list *_qrlist,
+                                   zbar_image_scanner_t *iscn,
+                                   zbar_image_t *img);
+
+
+/*TODO: Parse DoCoMo standard barcode data formats.
+  See http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/function/application/
+   for details.*/
+
+#endif

+ 84 - 0
Third_Party/ZBAR/include/refcnt.h

@@ -0,0 +1,84 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _REFCNT_H_
+#define _REFCNT_H_
+
+#include <config.h>
+//#include <assert.h>
+
+#if defined(_WIN32)
+# include <windows.h>
+
+typedef volatile LONG refcnt_t;  /* FIXME where did volatile come from? */
+
+static inline int _zbar_refcnt (refcnt_t *cnt,
+                                int delta)
+{
+    int rc = -1;
+    if(delta > 0)
+        while(delta--)
+            rc = InterlockedIncrement(cnt);
+    else if(delta < 0)
+        while(delta++)
+            rc = InterlockedDecrement(cnt);
+    assert(rc >= 0);
+    return(rc);
+}
+
+
+#elif defined(HAVE_LIBPTHREAD)
+# include <pthread.h>
+
+typedef int refcnt_t;
+
+extern pthread_mutex_t _zbar_reflock;
+
+static inline int _zbar_refcnt (refcnt_t *cnt,
+                                int delta)
+{
+    pthread_mutex_lock(&_zbar_reflock);
+    int rc = (*cnt += delta);
+    pthread_mutex_unlock(&_zbar_reflock);
+    assert(rc >= 0);
+    return(rc);
+}
+
+
+#else
+
+typedef int refcnt_t;
+
+static inline int _zbar_refcnt (refcnt_t *cnt,
+                                int delta)
+{
+    int rc = (*cnt += delta);
+    assert(rc >= 0);
+    return(rc);
+}
+
+#endif
+
+
+void _zbar_refcnt_init(void);
+
+#endif

+ 66 - 0
Third_Party/ZBAR/include/rs.h

@@ -0,0 +1,66 @@
+/*Copyright (C) 1991-1995  Henry Minsky (hqm@ua.com, hqm@ai.mit.edu)
+  Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#if !defined(_qrcode_rs_H)
+# define _qrcode_rs_H (1)
+
+/*This is one of 16 irreducible primitive polynomials of degree 8:
+    x**8+x**4+x**3+x**2+1.
+  Under such a polynomial, x (i.e., 0x02) is a generator of GF(2**8).
+  The high order 1 bit is implicit.
+  From~\cite{MD88}, Ch. 5, p. 275 by Patel.
+  @BOOK{MD88,
+    author="C. Dennis Mee and Eric D. Daniel",
+    title="Video, Audio, and Instrumentation Recording",
+    series="Magnetic Recording",
+    volume=3,
+    publisher="McGraw-Hill Education",
+    address="Columbus, OH",
+    month=Jun,
+    year=1988
+  }*/
+#define QR_PPOLY (0x1D)
+
+/*The index to start the generator polynomial from (0...254).*/
+#define QR_M0 (0)
+
+typedef struct rs_gf256 rs_gf256;
+
+struct rs_gf256{
+  /*A logarithm table in GF(2**8).*/
+  unsigned char log[256];
+  /*An exponential table in GF(2**8): exp[i] contains x^i reduced modulo the
+     irreducible primitive polynomial used to define the field.
+    The extra 256 entries are used to do arithmetic mod 255, since some extra
+     table lookups are generally faster than doing the modulus.*/
+  unsigned char exp[511];
+};
+
+/*Initialize discrete logarithm tables for GF(2**8) using a given primitive
+   irreducible polynomial.*/
+void rs_gf256_init(rs_gf256 *_gf,unsigned _ppoly);
+
+/*Corrects a codeword with _ndata<256 bytes, of which the last _npar are parity
+   bytes.
+  Known locations of errors can be passed in the _erasures array.
+  Twice as many (up to _npar) errors with a known location can be corrected
+   compared to errors with an unknown location.
+  Returns the number of errors corrected if successful, or a negative number if
+   the message could not be corrected because too many errors were detected.*/
+int rs_correct(const rs_gf256 *_gf,int _m0,unsigned char *_data,int _ndata,
+ int _npar,const unsigned char *_erasures,int _nerasures);
+
+/*Create an _npar-coefficient generator polynomial for a Reed-Solomon code with
+   _npar<256 parity bytes.*/
+void rs_compute_genpoly(const rs_gf256 *_gf,int _m0,
+ unsigned char *_genpoly,int _npar);
+
+/*Adds _npar<=_ndata parity bytes to an _ndata-_npar byte message.
+  _data must contain room for _ndata<256 bytes.*/
+void rs_encode(const rs_gf256 *_gf,unsigned char *_data,int _ndata,
+ const unsigned char *_genpoly,int _npar);
+
+#endif

+ 65 - 0
Third_Party/ZBAR/include/svg.h

@@ -0,0 +1,65 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _SVG_H_
+#define _SVG_H_
+
+#ifdef DEBUG_SVG
+
+typedef enum { SVG_REL, SVG_ABS } svg_absrel_t;
+
+void svg_open(const char *name, double x, double y, double w, double h);
+void svg_close(void);
+
+void svg_commentf(const char *format, ...);
+void svg_image(const char *name, double width, double height);
+
+void svg_group_start(const char *cls, double rotate,
+                     double scalex, double scaley,
+                     double x, double y);
+void svg_group_end(void);
+
+void svg_path_start(const char *cls, double scale, double x, double y);
+void svg_path_end(void);
+void svg_path_close(void);
+void svg_path_moveto(svg_absrel_t abs, double x, double y);
+void svg_path_lineto(svg_absrel_t abs, double x, double y);
+
+#else
+
+# define svg_open(...)
+# define svg_close(...)
+
+# define svg_image(...)
+
+# define svg_group_start(...)
+# define svg_group_end(...)
+
+# define svg_path_start(...)
+# define svg_path_end(...)
+# define svg_path_moveto(...)
+# define svg_path_lineto(...)
+# define svg_path_close(...)
+
+#endif
+
+#endif

+ 92 - 0
Third_Party/ZBAR/include/symbol.h

@@ -0,0 +1,92 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _SYMBOL_H_
+#define _SYMBOL_H_
+
+//#include <stdlib.h>
+#include <zbar.h>
+#include "refcnt.h"
+
+typedef struct point_s {
+    int x, y;
+} point_t;
+
+struct zbar_symbol_set_s {
+    refcnt_t refcnt;
+    int nsyms;                  /* number of filtered symbols */
+    zbar_symbol_t *head;        /* first of decoded symbol results */
+    zbar_symbol_t *tail;        /* last of unfiltered symbol results */
+};
+
+struct zbar_symbol_s {
+    zbar_symbol_type_t type;    /* symbol type */
+    unsigned int data_alloc;    /* allocation size of data */
+    unsigned int datalen;       /* length of binary symbol data */
+    char *data;                 /* symbol data */
+
+    unsigned pts_alloc;         /* allocation size of pts */
+    unsigned npts;              /* number of points in location polygon */
+    point_t *pts;               /* list of points in location polygon */
+
+    refcnt_t refcnt;            /* reference count */
+    zbar_symbol_t *next;        /* linked list of results (or siblings) */
+    zbar_symbol_set_t *syms;    /* components of composite result */
+    unsigned long time;         /* relative symbol capture time */
+    int cache_count;            /* cache state */
+    int quality;                /* relative symbol reliability metric */
+};
+
+extern void _zbar_symbol_free(zbar_symbol_t*);
+
+extern zbar_symbol_set_t *_zbar_symbol_set_create(void);
+extern void _zbar_symbol_set_free(zbar_symbol_set_t*);
+
+static inline void sym_add_point (zbar_symbol_t *sym,
+                                  int x,
+                                  int y)
+{
+    int i = sym->npts;
+    if(++sym->npts >= sym->pts_alloc)
+        sym->pts = realloc(sym->pts, ++sym->pts_alloc * sizeof(point_t));
+    sym->pts[i].x = x;
+    sym->pts[i].y = y;
+}
+
+static inline void _zbar_symbol_refcnt (zbar_symbol_t *sym,
+                                        int delta)
+{
+    if(!_zbar_refcnt(&sym->refcnt, delta) && delta <= 0)
+        _zbar_symbol_free(sym);
+}
+
+static inline void _zbar_symbol_set_add (zbar_symbol_set_t *syms,
+                                         zbar_symbol_t *sym)
+{
+    sym->next = syms->head;
+    syms->head = sym;
+    syms->nsyms++;
+
+    _zbar_symbol_refcnt(sym, 1);
+}
+
+#endif

+ 127 - 0
Third_Party/ZBAR/include/thread.h

@@ -0,0 +1,127 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _ZBAR_THREAD_H_
+#define _ZBAR_THREAD_H_
+
+/* simple platform thread abstraction
+ */
+
+#include <config.h>
+#include "event.h"
+
+#if defined(_WIN32)
+
+# include <windows.h>
+# define HAVE_THREADS
+# define ZTHREAD DWORD WINAPI
+
+typedef ZTHREAD (zbar_thread_proc_t)(void*);
+
+typedef DWORD zbar_thread_id_t;
+
+#elif defined(HAVE_LIBPTHREAD)
+
+# include <pthread.h>
+# include <signal.h>
+# define HAVE_THREADS
+# define ZTHREAD void*
+
+typedef ZTHREAD (zbar_thread_proc_t)(void*);
+
+typedef pthread_t zbar_thread_id_t;
+
+#else
+
+# undef HAVE_THREADS
+# undef ZTHREAD
+
+typedef void zbar_thread_proc_t;
+typedef int zbar_thread_id_t;
+
+#endif
+
+
+typedef struct zbar_thread_s {
+    zbar_thread_id_t tid;
+    int started, running;
+    zbar_event_t notify, activity;
+} zbar_thread_t;
+
+
+#if defined(_WIN32)
+
+static inline void _zbar_thread_init (zbar_thread_t *thr)
+{
+    thr->running = 1;
+    _zbar_event_trigger(&thr->activity);
+}
+
+static inline zbar_thread_id_t _zbar_thread_self ()
+{
+    return(GetCurrentThreadId());
+}
+
+static inline int _zbar_thread_is_self (zbar_thread_id_t tid)
+{
+    return(tid == GetCurrentThreadId());
+}
+
+
+#elif defined(HAVE_LIBPTHREAD)
+
+static inline void _zbar_thread_init (zbar_thread_t *thr)
+{
+    sigset_t sigs;
+    sigfillset(&sigs);
+    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
+    thr->running = 1;
+    _zbar_event_trigger(&thr->activity);
+}
+
+static inline zbar_thread_id_t _zbar_thread_self (void)
+{
+    return(pthread_self());
+}
+
+static inline int _zbar_thread_is_self (zbar_thread_id_t tid)
+{
+    return(pthread_equal(tid, pthread_self()));
+}
+
+
+#else
+
+# define _zbar_thread_start(...) -1
+# define _zbar_thread_stop(...) 0
+# define _zbar_thread_self(...) 0
+# define _zbar_thread_is_self(...) 1
+
+#endif
+
+#ifdef HAVE_THREADS
+extern int _zbar_thread_start(zbar_thread_t*, zbar_thread_proc_t*,
+                              void*, zbar_mutex_t*);
+extern int _zbar_thread_stop(zbar_thread_t*, zbar_mutex_t*);
+#endif
+
+#endif

+ 132 - 0
Third_Party/ZBAR/include/timer.h

@@ -0,0 +1,132 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _ZBAR_TIMER_H_
+#define _ZBAR_TIMER_H_
+
+#include <time.h>
+//#include <sys/time.h>   /* gettimeofday */
+
+/* platform timer abstraction
+ *
+ * zbar_timer_t stores the absolute expiration of a delay from
+ * when the timer was initialized.
+ *
+ * _zbar_timer_init() initialized timer with specified ms delay.
+ *     returns timer or NULL if timeout < 0 (no/infinite timeout)
+ * _zbar_timer_check() returns ms remaining until expiration.
+ *     will be <= 0 if timer has expired
+ */
+
+#if _POSIX_TIMERS > 0
+
+typedef struct timespec zbar_timer_t;
+
+static inline zbar_timer_t *_zbar_timer_init (zbar_timer_t *timer,
+                                              int delay)
+{
+    if(delay < 0)
+        return(NULL);
+
+    clock_gettime(CLOCK_REALTIME, timer);
+    timer->tv_nsec += (delay % 1000) * 1000000;
+    timer->tv_sec += (delay / 1000) + (timer->tv_nsec / 1000000000);
+    timer->tv_nsec %= 1000000000;
+    return(timer);
+}
+
+static inline int _zbar_timer_check (zbar_timer_t *timer)
+{
+    if(!timer)
+        return(-1);
+
+    struct timespec now;
+    clock_gettime(CLOCK_REALTIME, &now);
+    int delay = ((timer->tv_sec - now.tv_sec) * 1000 +
+                 (timer->tv_nsec - now.tv_nsec) / 1000000);
+    return((delay >= 0) ? delay : 0);
+}
+
+
+#elif defined(_WIN32)
+
+# include <windows.h>
+
+typedef DWORD zbar_timer_t;
+
+static inline zbar_timer_t *_zbar_timer_init (zbar_timer_t *timer,
+                                              int delay)
+{
+    if(delay < 0)
+        return(NULL);
+
+    *timer = timeGetTime() + delay;
+    return(timer);
+}
+
+static inline int _zbar_timer_check (zbar_timer_t *timer)
+{
+    if(!timer)
+        return(INFINITE);
+
+    int delay = *timer - timeGetTime();
+    return((delay >= 0) ? delay : 0);
+}
+
+
+#else
+
+typedef struct timeval zbar_timer_t;
+
+static inline zbar_timer_t *_zbar_timer_init (zbar_timer_t *timer,
+                                              int delay)
+{
+#if 0
+    if(delay < 0)
+        return(NULL);
+
+    gettimeofday(timer, NULL);
+    timer->tv_usec += (delay % 1000) * 1000;
+    timer->tv_sec += (delay / 1000) + (timer->tv_usec / 1000000);
+    timer->tv_usec %= 1000000;
+    #endif
+    return(timer);
+}
+
+static inline int _zbar_timer_check (zbar_timer_t *timer)
+{
+#if 0
+    if(!timer)
+        return(-1);
+
+    struct timeval now;
+    gettimeofday(&now, NULL);
+    return((timer->tv_sec - now.tv_sec) * 1000 +
+           (timer->tv_usec - now.tv_usec) / 1000);
+    #else
+    return 0;
+    #endif
+}
+
+#endif
+
+#endif

+ 45 - 0
Third_Party/ZBAR/include/type.h

@@ -0,0 +1,45 @@
+
+//如果已经包含cs_types.h 则不再重复包含这个文件
+#ifdef __CS_TYPE_H__
+#define __TYPE_H__
+#endif
+
+#ifndef __TYPE_H__
+#define __TYPE_H__
+
+#ifndef NULL
+#define NULL    ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE   (0)
+#endif
+
+#ifndef TRUE
+#define TRUE    (1)
+#endif
+
+#ifndef NULL
+#define NULL (0)
+#endif
+
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned int    DWORD;
+typedef unsigned char   BOOL;
+
+typedef unsigned char u8;
+typedef signed char s8;
+typedef unsigned short u16;
+typedef signed short s16;
+typedef unsigned int u32;
+typedef signed int s32;
+typedef unsigned long long u64;
+typedef long long s64;
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER)          ((u32) &((TYPE *)0)->MEMBER)
+#endif
+
+
+#endif

+ 52 - 0
Third_Party/ZBAR/include/util.h

@@ -0,0 +1,52 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#if !defined(_qrcode_util_H)
+# define _qrcode_util_H (1)
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "bsp_common.h"
+#define QR_MAXI(_a,_b)      ((_a)-((_a)-(_b)&-((_b)>(_a))))
+#define QR_MINI(_a,_b)      ((_a)+((_b)-(_a)&-((_b)<(_a))))
+#define QR_SIGNI(_x)        (((_x)>0)-((_x)<0))
+#define QR_SIGNMASK(_x)     (-((_x)<0))
+/*Unlike copysign(), simply inverts the sign of _a if _b is negative.*/
+#define QR_FLIPSIGNI(_a,_b) ((_a)+QR_SIGNMASK(_b)^QR_SIGNMASK(_b))
+#define QR_COPYSIGNI(_a,_b) QR_FLIPSIGNI(abs(_a),_b)
+/*Divides a signed integer by a positive value with exact rounding.*/
+#define QR_DIVROUND(_x,_y)  (((_x)+QR_FLIPSIGNI(_y>>1,_x))/(_y))
+#define QR_CLAMPI(_a,_b,_c) (QR_MAXI(_a,QR_MINI(_b,_c)))
+#define QR_CLAMP255(_x)     ((unsigned char)((((_x)<0)-1)&((_x)|-((_x)>255))))
+/*Swaps two integers _a and _b if _a>_b.*/
+#define QR_SORT2I(_a,_b) \
+  do{ \
+    int t__; \
+    t__=QR_MINI(_a,_b)^(_a); \
+    (_a)^=t__; \
+    (_b)^=t__; \
+  } \
+  while(0)
+#define QR_ILOG0(_v) (!!((_v)&0x2))
+#define QR_ILOG1(_v) (((_v)&0xC)?2+QR_ILOG0((_v)>>2):QR_ILOG0(_v))
+#define QR_ILOG2(_v) (((_v)&0xF0)?4+QR_ILOG1((_v)>>4):QR_ILOG1(_v))
+#define QR_ILOG3(_v) (((_v)&0xFF00)?8+QR_ILOG2((_v)>>8):QR_ILOG2(_v))
+#define QR_ILOG4(_v) (((_v)&0xFFFF0000)?16+QR_ILOG3((_v)>>16):QR_ILOG3(_v))
+/*Computes the integer logarithm of a (positive, 32-bit) constant.*/
+#define QR_ILOG(_v) ((int)QR_ILOG4((unsigned)(_v)))
+
+/*Multiplies 32-bit numbers _a and _b, adds (possibly 64-bit) number _r, and
+   takes bits [_s,_s+31] of the result.*/
+#define QR_FIXMUL(_a,_b,_r,_s) ((int)((_a)*(long long)(_b)+(_r)>>(_s)))
+/*Multiplies 32-bit numbers _a and _b, adds (possibly 64-bit) number _r, and
+   gives all 64 bits of the result.*/
+#define QR_EXTMUL(_a,_b,_r)    ((_a)*(long long)(_b)+(_r))
+
+unsigned qr_isqrt(unsigned _val);
+unsigned qr_ihypot(int _x,int _y);
+int qr_ilog(unsigned _val);
+
+#endif

+ 160 - 0
Third_Party/ZBAR/include/video.h

@@ -0,0 +1,160 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _VIDEO_H_
+#define _VIDEO_H_
+
+#include <config.h>
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+//#include <stdlib.h>
+#include <string.h>
+//#include <assert.h>
+
+#include <zbar.h>
+
+#include "image.h"
+#include "error.h"
+#include "mutex.h"
+
+/* number of images to preallocate */
+#define ZBAR_VIDEO_IMAGES_MAX  4
+
+typedef enum video_interface_e {
+    VIDEO_INVALID = 0,          /* uninitialized */
+    VIDEO_V4L1,                 /* v4l protocol version 1 */
+    VIDEO_V4L2,                 /* v4l protocol version 2 */
+    VIDEO_VFW,                  /* video for windows */
+} video_interface_t;
+
+typedef enum video_iomode_e {
+    VIDEO_READWRITE = 1,        /* standard system calls */
+    VIDEO_MMAP,                 /* mmap interface */
+    VIDEO_USERPTR,              /* userspace buffers */
+} video_iomode_t;
+
+typedef struct video_state_s video_state_t;
+
+struct zbar_video_s {
+    errinfo_t err;              /* error reporting */
+    int fd;                     /* open camera device */
+    unsigned width, height;     /* video frame size */
+
+    video_interface_t intf;     /* input interface type */
+    video_iomode_t iomode;      /* video data transfer mode */
+    unsigned initialized : 1;   /* format selected and images mapped */
+    unsigned active      : 1;   /* current streaming state */
+
+    uint32_t format;            /* selected fourcc */
+    unsigned palette;           /* v4l1 format index corresponding to format */
+    uint32_t *formats;          /* 0 terminated list of supported formats */
+
+    unsigned long datalen;      /* size of image data for selected format */
+    unsigned long buflen;       /* total size of image data buffer */
+    void *buf;                  /* image data buffer */
+
+    unsigned frame;             /* frame count */
+
+    zbar_mutex_t qlock;         /* lock image queue */
+    int num_images;             /* number of allocated images */
+    zbar_image_t **images;      /* indexed list of images */
+    zbar_image_t *nq_image;     /* last image enqueued */
+    zbar_image_t *dq_image;     /* first image to dequeue (when ordered) */
+    zbar_image_t *shadow_image; /* special case internal double buffering */
+
+    video_state_t *state;       /* platform/interface specific state */
+
+#ifdef HAVE_LIBJPEG
+    struct jpeg_decompress_struct *jpeg; /* JPEG decompressor */
+    zbar_image_t *jpeg_img;    /* temporary image */
+#endif
+
+    /* interface dependent methods */
+    int (*init)(zbar_video_t*, uint32_t);
+    int (*cleanup)(zbar_video_t*);
+    int (*start)(zbar_video_t*);
+    int (*stop)(zbar_video_t*);
+    int (*nq)(zbar_video_t*, zbar_image_t*);
+    zbar_image_t* (*dq)(zbar_video_t*);
+};
+
+
+/* video.next_image and video.recycle_image have to be thread safe
+ * wrt/other apis
+ */
+static inline int video_lock (zbar_video_t *vdo)
+{
+    int rc = 0;
+    if((rc = _zbar_mutex_lock(&vdo->qlock))) {
+        err_capture(vdo, SEV_FATAL, ZBAR_ERR_LOCKING, __func__,
+                    "unable to acquire lock");
+        vdo->err.errnum = rc;
+        return(-1);
+    }
+    return(0);
+}
+
+static inline int video_unlock (zbar_video_t *vdo)
+{
+    int rc = 0;
+    if((rc = _zbar_mutex_unlock(&vdo->qlock))) {
+        err_capture(vdo, SEV_FATAL, ZBAR_ERR_LOCKING, __func__,
+                    "unable to release lock");
+        vdo->err.errnum = rc;
+        return(-1);
+    }
+    return(0);
+}
+
+static inline int video_nq_image (zbar_video_t *vdo,
+                                  zbar_image_t *img)
+{
+    /* maintains queued buffers in order */
+    img->next = NULL;
+    if(vdo->nq_image)
+        vdo->nq_image->next = img;
+    vdo->nq_image = img;
+    if(!vdo->dq_image)
+        vdo->dq_image = img;
+    return(video_unlock(vdo));
+}
+
+static inline zbar_image_t *video_dq_image (zbar_video_t *vdo)
+{
+    zbar_image_t *img = vdo->dq_image;
+    if(img) {
+        vdo->dq_image = img->next;
+        img->next = NULL;
+    }
+    if(video_unlock(vdo))
+        /* FIXME reclaim image */
+        return(NULL);
+    return(img);
+}
+
+
+/* PAL interface */
+extern int _zbar_video_open(zbar_video_t*, const char*);
+
+#endif

+ 148 - 0
Third_Party/ZBAR/include/window.h

@@ -0,0 +1,148 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _WINDOW_H_
+#define _WINDOW_H_
+
+#include <config.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+///#include <stdlib.h>
+
+#ifdef WIN32
+#include <stdint.h>
+#endif
+
+#include <zbar.h>
+#include "symbol.h"
+#include "error.h"
+#include "mutex.h"
+
+typedef struct window_state_s window_state_t;
+
+struct zbar_window_s {
+    errinfo_t err;              /* error reporting */
+    zbar_image_t *image;        /* last displayed image
+                                 * NB image access must be locked!
+                                 */
+    unsigned overlay;           /* user set overlay level */
+
+    uint32_t format;            /* output format */
+    unsigned width, height;     /* current output size */
+    unsigned max_width, max_height;
+
+    uint32_t src_format;        /* current input format */
+    unsigned src_width;         /* last displayed image size */
+    unsigned src_height;
+
+    unsigned dst_width;         /* conversion target */
+    unsigned dst_height;
+
+    unsigned scale_num;         /* output scaling */
+    unsigned scale_den;
+
+    point_t scaled_offset;      /* output position and size */
+    point_t scaled_size;
+
+    uint32_t *formats;          /* supported formats (zero terminated) */
+
+    zbar_mutex_t imglock;       /* lock displayed image */
+
+    void *display;
+    unsigned long xwin;
+    unsigned long time;         /* last image display in milliseconds */
+    unsigned long time_avg;     /* average of inter-frame times */
+
+    window_state_t *state;      /* platform/interface specific state */
+
+    /* interface dependent methods */
+    int (*init)(zbar_window_t*, zbar_image_t*, int);
+    int (*draw_image)(zbar_window_t*, zbar_image_t*);
+    int (*cleanup)(zbar_window_t*);
+};
+
+/* window.draw has to be thread safe wrt/other apis
+ * FIXME should be a semaphore
+ */
+static inline int window_lock (zbar_window_t *w)
+{
+    int rc = 0;
+    if((rc = _zbar_mutex_lock(&w->imglock))) {
+        err_capture(w, SEV_FATAL, ZBAR_ERR_LOCKING, __func__,
+                    "unable to acquire lock");
+        w->err.errnum = rc;
+        return(-1);
+    }
+    return(0);
+}
+
+static inline int window_unlock (zbar_window_t *w)
+{
+    int rc = 0;
+    if((rc = _zbar_mutex_unlock(&w->imglock))) {
+        err_capture(w, SEV_FATAL, ZBAR_ERR_LOCKING, __func__,
+                    "unable to release lock");
+        w->err.errnum = rc;
+        return(-1);
+    }
+    return(0);
+}
+
+static inline int _zbar_window_add_format (zbar_window_t *w,
+                                           uint32_t fmt)
+{
+    int i;
+    for(i = 0; w->formats && w->formats[i]; i++)
+        if(w->formats[i] == fmt)
+            return(i);
+
+    w->formats = realloc(w->formats, (i + 2) * sizeof(uint32_t));
+    w->formats[i] = fmt;
+    w->formats[i + 1] = 0;
+    return(i);
+}
+
+static inline point_t window_scale_pt (zbar_window_t *w,
+                                       point_t p)
+{
+    p.x = ((long)p.x * w->scale_num + w->scale_den - 1) / w->scale_den;
+    p.y = ((long)p.y * w->scale_num + w->scale_den - 1) / w->scale_den;
+    return(p);
+}
+
+
+/* PAL interface */
+extern int _zbar_window_attach(zbar_window_t*, void*, unsigned long);
+extern int _zbar_window_expose(zbar_window_t*, int, int, int, int);
+extern int _zbar_window_resize(zbar_window_t*);
+extern int _zbar_window_clear(zbar_window_t*);
+extern int _zbar_window_begin(zbar_window_t*);
+extern int _zbar_window_end(zbar_window_t*);
+extern int _zbar_window_draw_marker(zbar_window_t*, uint32_t, point_t);
+extern int _zbar_window_draw_polygon(zbar_window_t*, uint32_t, const point_t*, int);
+extern int _zbar_window_draw_text(zbar_window_t*, uint32_t,
+                                  point_t, const char*);
+extern int _zbar_window_fill_rect(zbar_window_t*, uint32_t, point_t, point_t);
+extern int _zbar_window_draw_logo(zbar_window_t*);
+
+#endif

+ 1344 - 0
Third_Party/ZBAR/include/zbar.h

@@ -0,0 +1,1344 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _ZBAR_H_
+#define _ZBAR_H_
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "zbar_config.h"
+#include "cs_types.h"
+#ifdef WIN32
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int  size_t;
+#define inline
+#define HAVE_INTTYPES_H
+#endif
+
+/** @file
+ * ZBar Barcode Reader C API definition
+ */
+
+/** @mainpage
+ *
+ * interface to the barcode reader is available at several levels.
+ * most applications will want to use the high-level interfaces:
+ *
+ * @section high-level High-Level Interfaces
+ *
+ * these interfaces wrap all library functionality into an easy-to-use
+ * package for a specific toolkit:
+ * - the "GTK+ 2.x widget" may be used with GTK GUI applications.  a
+ *   Python wrapper is included for PyGtk
+ * - the @ref zbar::QZBar "Qt4 widget" may be used with Qt GUI
+ *   applications
+ * - the Processor interface (in @ref c-processor "C" or @ref
+ *   zbar::Processor "C++") adds a scanning window to an application
+ *   with no GUI.
+ *
+ * @section mid-level Intermediate Interfaces
+ *
+ * building blocks used to construct high-level interfaces:
+ * - the ImageScanner (in @ref c-imagescanner "C" or @ref
+ *   zbar::ImageScanner "C++") looks for barcodes in a library defined
+ *   image object
+ * - the Window abstraction (in @ref c-window "C" or @ref
+ *   zbar::Window "C++") sinks library images, displaying them on the
+ *   platform display
+ * - the Video abstraction (in @ref c-video "C" or @ref zbar::Video
+ *   "C++") sources library images from a video device
+ *
+ * @section low-level Low-Level Interfaces
+ *
+ * direct interaction with barcode scanning and decoding:
+ * - the Scanner (in @ref c-scanner "C" or @ref zbar::Scanner "C++")
+ *   looks for barcodes in a linear intensity sample stream
+ * - the Decoder (in @ref c-decoder "C" or @ref zbar::Decoder "C++")
+ *   extracts barcodes from a stream of bar and space widths
+ */
+
+#define INT_MIN (-1<<30)
+
+
+#ifdef __cplusplus
+
+/** C++ namespace for library interfaces */
+namespace zbar {
+    extern "C" {
+#endif
+
+
+/** @name Global library interfaces */
+/*@{*/
+
+/** "color" of element: bar or space. */
+typedef enum zbar_color_e {
+    ZBAR_SPACE = 0,    /**< light area or space between bars */
+    ZBAR_BAR = 1,      /**< dark area or colored bar segment */
+} zbar_color_t;
+
+/** decoded symbol type. */
+typedef enum zbar_symbol_type_e {
+    ZBAR_NONE        =      0,  /**< no symbol decoded */
+    ZBAR_PARTIAL     =      1,  /**< intermediate status */
+    ZBAR_EAN8        =      8,  /**< EAN-8 */
+    ZBAR_UPCE        =      9,  /**< UPC-E */
+    ZBAR_ISBN10      =     10,  /**< ISBN-10 (from EAN-13). @since 0.4 */
+    ZBAR_UPCA        =     12,  /**< UPC-A */
+    ZBAR_EAN13       =     13,  /**< EAN-13 */
+    ZBAR_ISBN13      =     14,  /**< ISBN-13 (from EAN-13). @since 0.4 */
+    ZBAR_I25         =     25,  /**< Interleaved 2 of 5. @since 0.4 */
+    ZBAR_CODE39      =     39,  /**< Code 39. @since 0.4 */
+    ZBAR_PDF417      =     57,  /**< PDF417. @since 0.6 */
+    ZBAR_QRCODE      =     64,  /**< QR Code. @since 0.10 */
+    ZBAR_CODE128     =    128,  /**< Code 128 */
+    ZBAR_SYMBOL      = 0x00ff,  /**< mask for base symbol type */
+    ZBAR_ADDON2      = 0x0200,  /**< 2-digit add-on flag */
+    ZBAR_ADDON5      = 0x0500,  /**< 5-digit add-on flag */
+    ZBAR_ADDON       = 0x0700,  /**< add-on flag mask */
+} zbar_symbol_type_t;
+
+/** error codes. */
+typedef enum zbar_error_e {
+    ZBAR_OK = 0,                /**< no error */
+    ZBAR_ERR_NOMEM,             /**< out of memory */
+    ZBAR_ERR_INTERNAL,          /**< internal library error */
+    ZBAR_ERR_UNSUPPORTED,       /**< unsupported request */
+    ZBAR_ERR_INVALID,           /**< invalid request */
+    ZBAR_ERR_SYSTEM,            /**< system error */
+    ZBAR_ERR_LOCKING,           /**< locking error */
+    ZBAR_ERR_BUSY,              /**< all resources busy */
+    ZBAR_ERR_XDISPLAY,          /**< X11 display error */
+    ZBAR_ERR_XPROTO,            /**< X11 protocol error */
+    ZBAR_ERR_CLOSED,            /**< output window is closed */
+    ZBAR_ERR_WINAPI,            /**< windows system error */
+    ZBAR_ERR_NUM                /**< number of error codes */
+} zbar_error_t;
+
+/** decoder configuration options.
+ * @since 0.4
+ */
+typedef enum zbar_config_e {
+    ZBAR_CFG_ENABLE = 0,        /**< enable symbology/feature */
+    ZBAR_CFG_ADD_CHECK,         /**< enable check digit when optional */
+    ZBAR_CFG_EMIT_CHECK,        /**< return check digit when present */
+    ZBAR_CFG_ASCII,             /**< enable full ASCII character set */
+    ZBAR_CFG_NUM,               /**< number of boolean decoder configs */
+
+    ZBAR_CFG_MIN_LEN = 0x20,    /**< minimum data length for valid decode */
+    ZBAR_CFG_MAX_LEN,           /**< maximum data length for valid decode */
+
+    ZBAR_CFG_POSITION = 0x80,   /**< enable scanner to collect position data */
+
+    ZBAR_CFG_X_DENSITY = 0x100, /**< image scanner vertical scan density */
+    ZBAR_CFG_Y_DENSITY,         /**< image scanner horizontal scan density */
+} zbar_config_t;
+
+/** retrieve runtime library version information.
+ * @param major set to the running major version (unless NULL)
+ * @param minor set to the running minor version (unless NULL)
+ * @returns 0
+ */
+extern int zbar_version(unsigned *major,
+                        unsigned *minor);
+
+/** set global library debug level.
+ * @param verbosity desired debug level.  higher values create more spew
+ */
+extern void zbar_set_verbosity(int verbosity);
+
+/** increase global library debug level.
+ * eg, for -vvvv
+ */
+extern void zbar_increase_verbosity(void);
+
+/** retrieve string name for symbol encoding.
+ * @param sym symbol type encoding
+ * @returns the static string name for the specified symbol type,
+ * or "UNKNOWN" if the encoding is not recognized
+ */
+extern const char *zbar_get_symbol_name(zbar_symbol_type_t sym);
+
+/** retrieve string name for addon encoding.
+ * @param sym symbol type encoding
+ * @returns static string name for any addon, or the empty string
+ * if no addons were decoded
+ */
+extern const char *zbar_get_addon_name(zbar_symbol_type_t sym);
+
+/** parse a configuration string of the form "[symbology.]config[=value]".
+ * the config must match one of the recognized names.
+ * the symbology, if present, must match one of the recognized names.
+ * if symbology is unspecified, it will be set to 0.
+ * if value is unspecified it will be set to 1.
+ * @returns 0 if the config is parsed successfully, 1 otherwise
+ * @since 0.4
+ */
+extern int zbar_parse_config(const char *config_string,
+                             zbar_symbol_type_t *symbology,
+                             zbar_config_t *config,
+                             int *value);
+
+/** @internal type unsafe error API (don't use) */
+extern int _zbar_error_spew(const void *object,
+                            int verbosity);
+extern const char *_zbar_error_string(const void *object,
+                                      int verbosity);
+extern zbar_error_t _zbar_get_error_code(const void *object);
+
+/*@}*/
+
+struct zbar_symbol_s;
+typedef struct zbar_symbol_s zbar_symbol_t;
+
+struct zbar_symbol_set_s;
+typedef struct zbar_symbol_set_s zbar_symbol_set_t;
+
+
+/*------------------------------------------------------------*/
+/** @name Symbol interface
+ * decoded barcode symbol result object.  stores type, data, and image
+ * location of decoded symbol.  all memory is owned by the library
+ */
+/*@{*/
+
+/** @typedef zbar_symbol_t
+ * opaque decoded symbol object.
+ */
+
+/** symbol reference count manipulation.
+ * increment the reference count when you store a new reference to the
+ * symbol.  decrement when the reference is no longer used.  do not
+ * refer to the symbol once the count is decremented and the
+ * containing image has been recycled or destroyed.
+ * @note the containing image holds a reference to the symbol, so you
+ * only need to use this if you keep a symbol after the image has been
+ * destroyed or reused.
+ * @since 0.9
+ */
+extern void zbar_symbol_ref(const zbar_symbol_t *symbol,
+                            int refs);
+
+/** retrieve type of decoded symbol.
+ * @returns the symbol type
+ */
+extern zbar_symbol_type_t zbar_symbol_get_type(const zbar_symbol_t *symbol);
+
+/** retrieve data decoded from symbol.
+ * @returns the data string
+ */
+extern const char *zbar_symbol_get_data(const zbar_symbol_t *symbol);
+
+/** retrieve length of binary data.
+ * @returns the length of the decoded data
+ */
+extern unsigned int zbar_symbol_get_data_length(const zbar_symbol_t *symbol);
+
+/** retrieve a symbol confidence metric.
+ * @returns an unscaled, relative quantity: larger values are better
+ * than smaller values, where "large" and "small" are application
+ * dependent.
+ * @note expect the exact definition of this quantity to change as the
+ * metric is refined.  currently, only the ordered relationship
+ * between two values is defined and will remain stable in the future
+ * @since 0.9
+ */
+extern int zbar_symbol_get_quality(const zbar_symbol_t *symbol);
+
+/** retrieve current cache count.  when the cache is enabled for the
+ * image_scanner this provides inter-frame reliability and redundancy
+ * information for video streams.
+ * @returns < 0 if symbol is still uncertain.
+ * @returns 0 if symbol is newly verified.
+ * @returns > 0 for duplicate symbols
+ */
+extern int zbar_symbol_get_count(const zbar_symbol_t *symbol);
+
+/** retrieve the number of points in the location polygon.  the
+ * location polygon defines the image area that the symbol was
+ * extracted from.
+ * @returns the number of points in the location polygon
+ * @note this is currently not a polygon, but the scan locations
+ * where the symbol was decoded
+ */
+extern unsigned zbar_symbol_get_loc_size(const zbar_symbol_t *symbol);
+
+/** retrieve location polygon x-coordinates.
+ * points are specified by 0-based index.
+ * @returns the x-coordinate for a point in the location polygon.
+ * @returns -1 if index is out of range
+ */
+extern int zbar_symbol_get_loc_x(const zbar_symbol_t *symbol,
+                                 unsigned index);
+
+/** retrieve location polygon y-coordinates.
+ * points are specified by 0-based index.
+ * @returns the y-coordinate for a point in the location polygon.
+ * @returns -1 if index is out of range
+ */
+extern int zbar_symbol_get_loc_y(const zbar_symbol_t *symbol,
+                                 unsigned index);
+
+/** iterate the set to which this symbol belongs (there can be only one).
+ * @returns the next symbol in the set, or
+ * @returns NULL when no more results are available
+ */
+extern const zbar_symbol_t *zbar_symbol_next(const zbar_symbol_t *symbol);
+
+/** retrieve components of a composite result.
+ * @returns the symbol set containing the components
+ * @returns NULL if the symbol is already a physical symbol
+ * @since 0.10
+ */
+extern const zbar_symbol_set_t*
+zbar_symbol_get_components(const zbar_symbol_t *symbol);
+
+/** iterate components of a composite result.
+ * @returns the first physical component symbol of a composite result
+ * @returns NULL if the symbol is already a physical symbol
+ * @since 0.10
+ */
+extern const zbar_symbol_t*
+zbar_symbol_first_component(const zbar_symbol_t *symbol);
+
+/** print XML symbol element representation to user result buffer.
+ * @see http://zbar.sourceforge.net/2008/barcode.xsd for the schema.
+ * @param symbol is the symbol to print
+ * @param buffer is the inout result pointer, it will be reallocated
+ * with a larger size if necessary.
+ * @param buflen is inout length of the result buffer.
+ * @returns the buffer pointer
+ * @since 0.6
+ */
+extern char *zbar_symbol_xml(const zbar_symbol_t *symbol,
+                             char **buffer,
+                             unsigned *buflen);
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Symbol Set interface
+ * container for decoded result symbols associated with an image
+ * or a composite symbol.
+ * @since 0.10
+ */
+/*@{*/
+
+/** @typedef zbar_symbol_set_t
+ * opaque symbol iterator object.
+ * @since 0.10
+ */
+
+/** reference count manipulation.
+ * increment the reference count when you store a new reference.
+ * decrement when the reference is no longer used.  do not refer to
+ * the object any longer once references have been released.
+ * @since 0.10
+ */
+extern void zbar_symbol_set_ref(const zbar_symbol_set_t *symbols,
+                                int refs);
+
+/** retrieve set size.
+ * @returns the number of symbols in the set.
+ * @since 0.10
+ */
+extern int zbar_symbol_set_get_size(const zbar_symbol_set_t *symbols);
+
+/** set iterator.
+ * @returns the first decoded symbol result in a set
+ * @returns NULL if the set is empty
+ * @since 0.10
+ */
+extern const zbar_symbol_t*
+zbar_symbol_set_first_symbol(const zbar_symbol_set_t *symbols);
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Image interface
+ * stores image data samples along with associated format and size
+ * metadata
+ */
+/*@{*/
+
+struct zbar_image_s;
+/** opaque image object. */
+typedef struct zbar_image_s zbar_image_t;
+
+/** cleanup handler callback function.
+ * called to free sample data when an image is destroyed.
+ */
+typedef void (zbar_image_cleanup_handler_t)(zbar_image_t *image);
+
+/** data handler callback function.
+ * called when decoded symbol results are available for an image
+ */
+typedef void (zbar_image_data_handler_t)(zbar_image_t *image,
+                                         const void *userdata);
+
+/** new image constructor.
+ * @returns a new image object with uninitialized data and format.
+ * this image should be destroyed (using zbar_image_destroy()) as
+ * soon as the application is finished with it
+ */
+extern zbar_image_t *zbar_image_create(void);
+
+/** image destructor.  all images created by or returned to the
+ * application should be destroyed using this function.  when an image
+ * is destroyed, the associated data cleanup handler will be invoked
+ * if available
+ * @note make no assumptions about the image or the data buffer.
+ * they may not be destroyed/cleaned immediately if the library
+ * is still using them.  if necessary, use the cleanup handler hook
+ * to keep track of image data buffers
+ */
+extern void zbar_image_destroy(zbar_image_t *image);
+
+/** image reference count manipulation.
+ * increment the reference count when you store a new reference to the
+ * image.  decrement when the reference is no longer used.  do not
+ * refer to the image any longer once the count is decremented.
+ * zbar_image_ref(image, -1) is the same as zbar_image_destroy(image)
+ * @since 0.5
+ */
+extern void zbar_image_ref(zbar_image_t *image,
+                           int refs);
+
+/** image format conversion.  refer to the documentation for supported
+ * image formats
+ * @returns a @em new image with the sample data from the original image
+ * converted to the requested format.  the original image is
+ * unaffected.
+ * @note the converted image size may be rounded (up) due to format
+ * constraints
+ */
+extern zbar_image_t *zbar_image_convert(const zbar_image_t *image,
+                                        unsigned long format);
+
+/** image format conversion with crop/pad.
+ * if the requested size is larger than the image, the last row/column
+ * are duplicated to cover the difference.  if the requested size is
+ * smaller than the image, the extra rows/columns are dropped from the
+ * right/bottom.
+ * @returns a @em new image with the sample data from the original
+ * image converted to the requested format and size.
+ * @note the image is @em not scaled
+ * @see zbar_image_convert()
+ * @since 0.4
+ */
+extern zbar_image_t *zbar_image_convert_resize(const zbar_image_t *image,
+                                               unsigned long format,
+                                               unsigned width,
+                                               unsigned height);
+
+/** retrieve the image format.
+ * @returns the fourcc describing the format of the image sample data
+ */
+extern unsigned long zbar_image_get_format(const zbar_image_t *image);
+
+/** retrieve a "sequence" (page/frame) number associated with this image.
+ * @since 0.6
+ */
+extern unsigned zbar_image_get_sequence(const zbar_image_t *image);
+
+/** retrieve the width of the image.
+ * @returns the width in sample columns
+ */
+extern unsigned zbar_image_get_width(const zbar_image_t *image);
+
+/** retrieve the height of the image.
+ * @returns the height in sample rows
+ */
+extern unsigned zbar_image_get_height(const zbar_image_t *image);
+
+/** return the image sample data.  the returned data buffer is only
+ * valid until zbar_image_destroy() is called
+ */
+extern const void *zbar_image_get_data(const zbar_image_t *image);
+
+/** return the size of image data.
+ * @since 0.6
+ */
+extern unsigned long zbar_image_get_data_length(const zbar_image_t *img);
+
+/** retrieve the decoded results.
+ * @returns the (possibly empty) set of decoded symbols
+ * @returns NULL if the image has not been scanned
+ * @since 0.10
+ */
+extern const zbar_symbol_set_t*
+zbar_image_get_symbols(const zbar_image_t *image);
+
+/** associate the specified symbol set with the image, replacing any
+ * existing results.  use NULL to release the current results from the
+ * image.
+ * @see zbar_image_scanner_recycle_image()
+ * @since 0.10
+ */
+extern void zbar_image_set_symbols(zbar_image_t *image,
+                                   const zbar_symbol_set_t *symbols);
+
+/** image_scanner decode result iterator.
+ * @returns the first decoded symbol result for an image
+ * or NULL if no results are available
+ */
+extern const zbar_symbol_t*
+zbar_image_first_symbol(const zbar_image_t *image);
+
+/** specify the fourcc image format code for image sample data.
+ * refer to the documentation for supported formats.
+ * @note this does not convert the data!
+ * (see zbar_image_convert() for that)
+ */
+extern void zbar_image_set_format(zbar_image_t *image,
+                                  unsigned long format);
+
+/** associate a "sequence" (page/frame) number with this image.
+ * @since 0.6
+ */
+extern void zbar_image_set_sequence(zbar_image_t *image,
+                                    unsigned sequence_num);
+
+/** specify the pixel size of the image.
+ * @note this does not affect the data!
+ */
+extern void zbar_image_set_size(zbar_image_t *image,
+                                unsigned width,
+                                unsigned height);
+
+/** specify image sample data.  when image data is no longer needed by
+ * the library the specific data cleanup handler will be called
+ * (unless NULL)
+ * @note application image data will not be modified by the library
+ */
+extern void zbar_image_set_data(zbar_image_t *image,
+                                const void *data,
+                                unsigned long data_byte_length,
+                                zbar_image_cleanup_handler_t *cleanup_hndlr);
+
+/** built-in cleanup handler.
+ * passes the image data buffer to free()
+ */
+extern void zbar_image_free_data(zbar_image_t *image);
+
+/** associate user specified data value with an image.
+ * @since 0.5
+ */
+extern void zbar_image_set_userdata(zbar_image_t *image,
+                                    void *userdata);
+
+/** return user specified data value associated with the image.
+ * @since 0.5
+ */
+extern void *zbar_image_get_userdata(const zbar_image_t *image);
+
+/** dump raw image data to a file for debug.
+ * the data will be prefixed with a 16 byte header consisting of:
+ *   - 4 bytes uint = 0x676d697a ("zimg")
+ *   - 4 bytes format fourcc
+ *   - 2 bytes width
+ *   - 2 bytes height
+ *   - 4 bytes size of following image data in bytes
+ * this header can be dumped w/eg:
+ * @verbatim
+       od -Ax -tx1z -N16 -w4 [file]
+@endverbatim
+ * for some formats the image can be displayed/converted using
+ * ImageMagick, eg:
+ * @verbatim
+       display -size 640x480+16 [-depth ?] [-sampling-factor ?x?] \
+           {GRAY,RGB,UYVY,YUV}:[file]
+@endverbatim
+ *
+ * @param image the image object to dump
+ * @param filebase base filename, appended with ".XXXX.zimg" where
+ * XXXX is the format fourcc
+ * @returns 0 on success or a system error code on failure
+ */
+extern int zbar_image_write(const zbar_image_t *image,
+                            const char *filebase);
+
+/** read back an image in the format written by zbar_image_write()
+ * @note TBD
+ */
+extern zbar_image_t *zbar_image_read(char *filename);
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Processor interface
+ * @anchor c-processor
+ * high-level self-contained image processor.
+ * processes video and images for barcodes, optionally displaying
+ * images to a library owned output window
+ */
+/*@{*/
+
+struct zbar_processor_s;
+/** opaque standalone processor object. */
+typedef struct zbar_processor_s zbar_processor_t;
+
+/** constructor.
+ * if threaded is set and threading is available the processor
+ * will spawn threads where appropriate to avoid blocking and
+ * improve responsiveness
+ */
+extern zbar_processor_t *zbar_processor_create(int threaded);
+
+/** destructor.  cleans up all resources associated with the processor
+ */
+extern void zbar_processor_destroy(zbar_processor_t *processor);
+
+/** (re)initialization.
+ * opens a video input device and/or prepares to display output
+ */
+extern int zbar_processor_init(zbar_processor_t *processor,
+                               const char *video_device,
+                               int enable_display);
+
+/** request a preferred size for the video image from the device.
+ * the request may be adjusted or completely ignored by the driver.
+ * @note must be called before zbar_processor_init()
+ * @since 0.6
+ */
+extern int zbar_processor_request_size(zbar_processor_t *processor,
+                                       unsigned width,
+                                       unsigned height);
+
+/** request a preferred video driver interface version for
+ * debug/testing.
+ * @note must be called before zbar_processor_init()
+ * @since 0.6
+ */
+extern int zbar_processor_request_interface(zbar_processor_t *processor,
+                                            int version);
+
+/** request a preferred video I/O mode for debug/testing.  You will
+ * get errors if the driver does not support the specified mode.
+ * @verbatim
+    0 = auto-detect
+    1 = force I/O using read()
+    2 = force memory mapped I/O using mmap()
+    3 = force USERPTR I/O (v4l2 only)
+@endverbatim
+ * @note must be called before zbar_processor_init()
+ * @since 0.7
+ */
+extern int zbar_processor_request_iomode(zbar_processor_t *video,
+                                         int iomode);
+
+/** force specific input and output formats for debug/testing.
+ * @note must be called before zbar_processor_init()
+ */
+extern int zbar_processor_force_format(zbar_processor_t *processor,
+                                       unsigned long input_format,
+                                       unsigned long output_format);
+
+/** setup result handler callback.
+ * the specified function will be called by the processor whenever
+ * new results are available from the video stream or a static image.
+ * pass a NULL value to disable callbacks.
+ * @param processor the object on which to set the handler.
+ * @param handler the function to call when new results are available.
+ * @param userdata is set as with zbar_processor_set_userdata().
+ * @returns the previously registered handler
+ */
+extern zbar_image_data_handler_t*
+zbar_processor_set_data_handler(zbar_processor_t *processor,
+                                zbar_image_data_handler_t *handler,
+                                const void *userdata);
+
+/** associate user specified data value with the processor.
+ * @since 0.6
+ */
+extern void zbar_processor_set_userdata(zbar_processor_t *processor,
+                                        void *userdata);
+
+/** return user specified data value associated with the processor.
+ * @since 0.6
+ */
+extern void *zbar_processor_get_userdata(const zbar_processor_t *processor);
+
+/** set config for indicated symbology (0 for all) to specified value.
+ * @returns 0 for success, non-0 for failure (config does not apply to
+ * specified symbology, or value out of range)
+ * @see zbar_decoder_set_config()
+ * @since 0.4
+ */
+extern int zbar_processor_set_config(zbar_processor_t *processor,
+                                     zbar_symbol_type_t symbology,
+                                     zbar_config_t config,
+                                     int value);
+
+/** parse configuration string using zbar_parse_config()
+ * and apply to processor using zbar_processor_set_config().
+ * @returns 0 for success, non-0 for failure
+ * @see zbar_parse_config()
+ * @see zbar_processor_set_config()
+ * @since 0.4
+ */
+static inline int zbar_processor_parse_config (zbar_processor_t *processor,
+                                               const char *config_string)
+{
+    zbar_symbol_type_t sym;
+    zbar_config_t cfg;
+    int val;
+    return(zbar_parse_config(config_string, &sym, &cfg, &val) ||
+           zbar_processor_set_config(processor, sym, cfg, val));
+}
+
+/** retrieve the current state of the ouput window.
+ * @returns 1 if the output window is currently displayed, 0 if not.
+ * @returns -1 if an error occurs
+ */
+extern int zbar_processor_is_visible(zbar_processor_t *processor);
+
+/** show or hide the display window owned by the library.
+ * the size will be adjusted to the input size
+ */
+extern int zbar_processor_set_visible(zbar_processor_t *processor,
+                                      int visible);
+
+/** control the processor in free running video mode.
+ * only works if video input is initialized. if threading is in use,
+ * scanning will occur in the background, otherwise this is only
+ * useful wrapping calls to zbar_processor_user_wait(). if the
+ * library output window is visible, video display will be enabled.
+ */
+extern int zbar_processor_set_active(zbar_processor_t *processor,
+                                     int active);
+
+/** retrieve decode results for last scanned image/frame.
+ * @returns the symbol set result container or NULL if no results are
+ * available
+ * @note the returned symbol set has its reference count incremented;
+ * ensure that the count is decremented after use
+ * @since 0.10
+ */
+extern const zbar_symbol_set_t*
+zbar_processor_get_results(const zbar_processor_t *processor);
+
+/** wait for input to the display window from the user
+ * (via mouse or keyboard).
+ * @returns >0 when input is received, 0 if timeout ms expired
+ * with no input or -1 in case of an error
+ */
+extern int zbar_processor_user_wait(zbar_processor_t *processor,
+                                    int timeout);
+
+/** process from the video stream until a result is available,
+ * or the timeout (in milliseconds) expires.
+ * specify a timeout of -1 to scan indefinitely
+ * (zbar_processor_set_active() may still be used to abort the scan
+ * from another thread).
+ * if the library window is visible, video display will be enabled.
+ * @note that multiple results may still be returned (despite the
+ * name).
+ * @returns >0 if symbols were successfully decoded,
+ * 0 if no symbols were found (ie, the timeout expired)
+ * or -1 if an error occurs
+ */
+extern int zbar_process_one(zbar_processor_t *processor,
+                            int timeout);
+
+/** process the provided image for barcodes.
+ * if the library window is visible, the image will be displayed.
+ * @returns >0 if symbols were successfully decoded,
+ * 0 if no symbols were found or -1 if an error occurs
+ */
+extern int zbar_process_image(zbar_processor_t *processor,
+                              zbar_image_t *image);
+
+/** display detail for last processor error to stderr.
+ * @returns a non-zero value suitable for passing to exit()
+ */
+static inline int
+zbar_processor_error_spew (const zbar_processor_t *processor,
+                           int verbosity)
+{
+    return(_zbar_error_spew(processor, verbosity));
+}
+
+/** retrieve the detail string for the last processor error. */
+static inline const char*
+zbar_processor_error_string (const zbar_processor_t *processor,
+                             int verbosity)
+{
+    return(_zbar_error_string(processor, verbosity));
+}
+
+/** retrieve the type code for the last processor error. */
+static inline zbar_error_t
+zbar_processor_get_error_code (const zbar_processor_t *processor)
+{
+    return(_zbar_get_error_code(processor));
+}
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Video interface
+ * @anchor c-video
+ * mid-level video source abstraction.
+ * captures images from a video device
+ */
+/*@{*/
+
+struct zbar_video_s;
+/** opaque video object. */
+typedef struct zbar_video_s zbar_video_t;
+
+/** constructor. */
+extern zbar_video_t *zbar_video_create(void);
+
+/** destructor. */
+extern void zbar_video_destroy(zbar_video_t *video);
+
+/** open and probe a video device.
+ * the device specified by platform specific unique name
+ * (v4l device node path in *nix eg "/dev/video",
+ *  DirectShow DevicePath property in windows).
+ * @returns 0 if successful or -1 if an error occurs
+ */
+extern int zbar_video_open(zbar_video_t *video,
+                           const char *device);
+
+/** retrieve file descriptor associated with open *nix video device
+ * useful for using select()/poll() to tell when new images are
+ * available (NB v4l2 only!!).
+ * @returns the file descriptor or -1 if the video device is not open
+ * or the driver only supports v4l1
+ */
+extern int zbar_video_get_fd(const zbar_video_t *video);
+
+/** request a preferred size for the video image from the device.
+ * the request may be adjusted or completely ignored by the driver.
+ * @returns 0 if successful or -1 if the video device is already
+ * initialized
+ * @since 0.6
+ */
+extern int zbar_video_request_size(zbar_video_t *video,
+                                   unsigned width,
+                                   unsigned height);
+
+/** request a preferred driver interface version for debug/testing.
+ * @note must be called before zbar_video_open()
+ * @since 0.6
+ */
+extern int zbar_video_request_interface(zbar_video_t *video,
+                                        int version);
+
+/** request a preferred I/O mode for debug/testing.  You will get
+ * errors if the driver does not support the specified mode.
+ * @verbatim
+    0 = auto-detect
+    1 = force I/O using read()
+    2 = force memory mapped I/O using mmap()
+    3 = force USERPTR I/O (v4l2 only)
+@endverbatim
+ * @note must be called before zbar_video_open()
+ * @since 0.7
+ */
+extern int zbar_video_request_iomode(zbar_video_t *video,
+                                     int iomode);
+
+/** retrieve current output image width.
+ * @returns the width or 0 if the video device is not open
+ */
+extern int zbar_video_get_width(const zbar_video_t *video);
+
+/** retrieve current output image height.
+ * @returns the height or 0 if the video device is not open
+ */
+extern int zbar_video_get_height(const zbar_video_t *video);
+
+/** initialize video using a specific format for debug.
+ * use zbar_negotiate_format() to automatically select and initialize
+ * the best available format
+ */
+extern int zbar_video_init(zbar_video_t *video,
+                           unsigned long format);
+
+/** start/stop video capture.
+ * all buffered images are retired when capture is disabled.
+ * @returns 0 if successful or -1 if an error occurs
+ */
+extern int zbar_video_enable(zbar_video_t *video,
+                             int enable);
+
+/** retrieve next captured image.  blocks until an image is available.
+ * @returns NULL if video is not enabled or an error occurs
+ */
+extern zbar_image_t *zbar_video_next_image(zbar_video_t *video);
+
+/** display detail for last video error to stderr.
+ * @returns a non-zero value suitable for passing to exit()
+ */
+static inline int zbar_video_error_spew (const zbar_video_t *video,
+                                         int verbosity)
+{
+    return(_zbar_error_spew(video, verbosity));
+}
+
+/** retrieve the detail string for the last video error. */
+static inline const char *zbar_video_error_string (const zbar_video_t *video,
+                                                   int verbosity)
+{
+    return(_zbar_error_string(video, verbosity));
+}
+
+/** retrieve the type code for the last video error. */
+static inline zbar_error_t
+zbar_video_get_error_code (const zbar_video_t *video)
+{
+    return(_zbar_get_error_code(video));
+}
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Window interface
+ * @anchor c-window
+ * mid-level output window abstraction.
+ * displays images to user-specified platform specific output window
+ */
+/*@{*/
+
+struct zbar_window_s;
+/** opaque window object. */
+typedef struct zbar_window_s zbar_window_t;
+
+/** constructor. */
+extern zbar_window_t *zbar_window_create(void);
+
+/** destructor. */
+extern void zbar_window_destroy(zbar_window_t *window);
+
+/** associate reader with an existing platform window.
+ * This can be any "Drawable" for X Windows or a "HWND" for windows.
+ * input images will be scaled into the output window.
+ * pass NULL to detach from the resource, further input will be
+ * ignored
+ */
+extern int zbar_window_attach(zbar_window_t *window,
+                              void *x11_display_w32_hwnd,
+                              unsigned long x11_drawable);
+
+/** control content level of the reader overlay.
+ * the overlay displays graphical data for informational or debug
+ * purposes.  higher values increase the level of annotation (possibly
+ * decreasing performance). @verbatim
+    0 = disable overlay
+    1 = outline decoded symbols (default)
+    2 = also track and display input frame rate
+@endverbatim
+ */
+extern void zbar_window_set_overlay(zbar_window_t *window,
+                                    int level);
+
+/** retrieve current content level of reader overlay.
+ * @see zbar_window_set_overlay()
+ * @since 0.10
+ */
+extern int zbar_window_get_overlay(const zbar_window_t *window);
+
+/** draw a new image into the output window. */
+extern int zbar_window_draw(zbar_window_t *window,
+                            zbar_image_t *image);
+
+/** redraw the last image (exposure handler). */
+extern int zbar_window_redraw(zbar_window_t *window);
+
+/** resize the image window (reconfigure handler).
+ * this does @em not update the contents of the window
+ * @since 0.3, changed in 0.4 to not redraw window
+ */
+extern int zbar_window_resize(zbar_window_t *window,
+                              unsigned width,
+                              unsigned height);
+
+/** display detail for last window error to stderr.
+ * @returns a non-zero value suitable for passing to exit()
+ */
+static inline int zbar_window_error_spew (const zbar_window_t *window,
+                                          int verbosity)
+{
+    return(_zbar_error_spew(window, verbosity));
+}
+
+/** retrieve the detail string for the last window error. */
+static inline const char*
+zbar_window_error_string (const zbar_window_t *window,
+                          int verbosity)
+{
+    return(_zbar_error_string(window, verbosity));
+}
+
+/** retrieve the type code for the last window error. */
+static inline zbar_error_t
+zbar_window_get_error_code (const zbar_window_t *window)
+{
+    return(_zbar_get_error_code(window));
+}
+
+
+/** select a compatible format between video input and output window.
+ * the selection algorithm attempts to use a format shared by
+ * video input and window output which is also most useful for
+ * barcode scanning.  if a format conversion is necessary, it will
+ * heuristically attempt to minimize the cost of the conversion
+ */
+extern int zbar_negotiate_format(zbar_video_t *video,
+                                 zbar_window_t *window);
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Image Scanner interface
+ * @anchor c-imagescanner
+ * mid-level image scanner interface.
+ * reads barcodes from 2-D images
+ */
+/*@{*/
+
+struct zbar_image_scanner_s;
+/** opaque image scanner object. */
+typedef struct zbar_image_scanner_s zbar_image_scanner_t;
+
+/** constructor. */
+extern zbar_image_scanner_t *zbar_image_scanner_create(void);
+
+/** destructor. */
+extern void zbar_image_scanner_destroy(zbar_image_scanner_t *scanner);
+
+/** setup result handler callback.
+ * the specified function will be called by the scanner whenever
+ * new results are available from a decoded image.
+ * pass a NULL value to disable callbacks.
+ * @returns the previously registered handler
+ */
+extern zbar_image_data_handler_t*
+zbar_image_scanner_set_data_handler(zbar_image_scanner_t *scanner,
+                                    zbar_image_data_handler_t *handler,
+                                    const void *userdata);
+
+
+/** set config for indicated symbology (0 for all) to specified value.
+ * @returns 0 for success, non-0 for failure (config does not apply to
+ * specified symbology, or value out of range)
+ * @see zbar_decoder_set_config()
+ * @since 0.4
+ */
+extern int zbar_image_scanner_set_config(zbar_image_scanner_t *scanner,
+                                         zbar_symbol_type_t symbology,
+                                         zbar_config_t config,
+                                         int value);
+
+/** parse configuration string using zbar_parse_config()
+ * and apply to image scanner using zbar_image_scanner_set_config().
+ * @returns 0 for success, non-0 for failure
+ * @see zbar_parse_config()
+ * @see zbar_image_scanner_set_config()
+ * @since 0.4
+ */
+static inline int
+zbar_image_scanner_parse_config (zbar_image_scanner_t *scanner,
+                                 const char *config_string)
+{
+    zbar_symbol_type_t sym;
+    zbar_config_t cfg;
+    int val;
+    return(zbar_parse_config(config_string, &sym, &cfg, &val) ||
+           zbar_image_scanner_set_config(scanner, sym, cfg, val));
+}
+
+/** enable or disable the inter-image result cache (default disabled).
+ * mostly useful for scanning video frames, the cache filters
+ * duplicate results from consecutive images, while adding some
+ * consistency checking and hysteresis to the results.
+ * this interface also clears the cache
+ */
+extern void zbar_image_scanner_enable_cache(zbar_image_scanner_t *scanner,
+                                            int enable);
+
+/** remove any previously decoded results from the image scanner and the
+ * specified image.  somewhat more efficient version of
+ * zbar_image_set_symbols(image, NULL) which may retain memory for
+ * subsequent decodes
+ * @since 0.10
+ */
+extern void zbar_image_scanner_recycle_image(zbar_image_scanner_t *scanner,
+                                             zbar_image_t *image);
+
+/** retrieve decode results for last scanned image.
+ * @returns the symbol set result container or NULL if no results are
+ * available
+ * @note the symbol set does not have its reference count adjusted;
+ * ensure that the count is incremented if the results may be kept
+ * after the next image is scanned
+ * @since 0.10
+ */
+extern const zbar_symbol_set_t*
+zbar_image_scanner_get_results(const zbar_image_scanner_t *scanner);
+
+/** scan for symbols in provided image.  The image format must be
+ * "Y800" or "GRAY".
+ * @returns >0 if symbols were successfully decoded from the image,
+ * 0 if no symbols were found or -1 if an error occurs
+ * @see zbar_image_convert()
+ * @since 0.9 - changed to only accept grayscale images
+ */
+extern int zbar_scan_image(zbar_image_scanner_t *scanner,
+                           zbar_image_t *image);
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Decoder interface
+ * @anchor c-decoder
+ * low-level bar width stream decoder interface.
+ * identifies symbols and extracts encoded data
+ */
+/*@{*/
+
+struct zbar_decoder_s;
+/** opaque decoder object. */
+typedef struct zbar_decoder_s zbar_decoder_t;
+
+/** decoder data handler callback function.
+ * called by decoder when new data has just been decoded
+ */
+typedef void (zbar_decoder_handler_t)(zbar_decoder_t *decoder);
+
+/** constructor. */
+extern zbar_decoder_t *zbar_decoder_create(void);
+
+/** destructor. */
+extern void zbar_decoder_destroy(zbar_decoder_t *decoder);
+
+/** set config for indicated symbology (0 for all) to specified value.
+ * @returns 0 for success, non-0 for failure (config does not apply to
+ * specified symbology, or value out of range)
+ * @since 0.4
+ */
+extern int zbar_decoder_set_config(zbar_decoder_t *decoder,
+                                   zbar_symbol_type_t symbology,
+                                   zbar_config_t config,
+                                   int value);
+
+/** parse configuration string using zbar_parse_config()
+ * and apply to decoder using zbar_decoder_set_config().
+ * @returns 0 for success, non-0 for failure
+ * @see zbar_parse_config()
+ * @see zbar_decoder_set_config()
+ * @since 0.4
+ */
+static inline int zbar_decoder_parse_config (zbar_decoder_t *decoder,
+                                             const char *config_string)
+{
+    zbar_symbol_type_t sym;
+    zbar_config_t cfg;
+    int val;
+    return(zbar_parse_config(config_string, &sym, &cfg, &val) ||
+           zbar_decoder_set_config(decoder, sym, cfg, val));
+}
+
+/** clear all decoder state.
+ * any partial symbols are flushed
+ */
+extern void zbar_decoder_reset(zbar_decoder_t *decoder);
+
+/** mark start of a new scan pass.
+ * clears any intra-symbol state and resets color to ::ZBAR_SPACE.
+ * any partially decoded symbol state is retained
+ */
+extern void zbar_decoder_new_scan(zbar_decoder_t *decoder);
+
+/** process next bar/space width from input stream.
+ * the width is in arbitrary relative units.  first value of a scan
+ * is ::ZBAR_SPACE width, alternating from there.
+ * @returns appropriate symbol type if width completes
+ * decode of a symbol (data is available for retrieval)
+ * @returns ::ZBAR_PARTIAL as a hint if part of a symbol was decoded
+ * @returns ::ZBAR_NONE (0) if no new symbol data is available
+ */
+extern zbar_symbol_type_t zbar_decode_width(zbar_decoder_t *decoder,
+                                            unsigned width);
+
+/** retrieve color of @em next element passed to
+ * zbar_decode_width(). */
+extern zbar_color_t zbar_decoder_get_color(const zbar_decoder_t *decoder);
+
+/** retrieve last decoded data.
+ * @returns the data string or NULL if no new data available.
+ * the returned data buffer is owned by library, contents are only
+ * valid between non-0 return from zbar_decode_width and next library
+ * call
+ */
+extern const char *zbar_decoder_get_data(const zbar_decoder_t *decoder);
+
+/** retrieve length of binary data.
+ * @returns the length of the decoded data or 0 if no new data
+ * available.
+ */
+extern unsigned int
+zbar_decoder_get_data_length(const zbar_decoder_t *decoder);
+
+/** retrieve last decoded symbol type.
+ * @returns the type or ::ZBAR_NONE if no new data available
+ */
+extern zbar_symbol_type_t
+zbar_decoder_get_type(const zbar_decoder_t *decoder);
+
+/** setup data handler callback.
+ * the registered function will be called by the decoder
+ * just before zbar_decode_width() returns a non-zero value.
+ * pass a NULL value to disable callbacks.
+ * @returns the previously registered handler
+ */
+extern zbar_decoder_handler_t*
+zbar_decoder_set_handler(zbar_decoder_t *decoder,
+                         zbar_decoder_handler_t *handler);
+
+/** associate user specified data value with the decoder. */
+extern void zbar_decoder_set_userdata(zbar_decoder_t *decoder,
+                                      void *userdata);
+
+/** return user specified data value associated with the decoder. */
+extern void *zbar_decoder_get_userdata(const zbar_decoder_t *decoder);
+
+/*@}*/
+
+/*------------------------------------------------------------*/
+/** @name Scanner interface
+ * @anchor c-scanner
+ * low-level linear intensity sample stream scanner interface.
+ * identifies "bar" edges and measures width between them.
+ * optionally passes to bar width decoder
+ */
+/*@{*/
+
+struct zbar_scanner_s;
+/** opaque scanner object. */
+typedef struct zbar_scanner_s zbar_scanner_t;
+
+/** constructor.
+ * if decoder is non-NULL it will be attached to scanner
+ * and called automatically at each new edge
+ * current color is initialized to ::ZBAR_SPACE
+ * (so an initial BAR->SPACE transition may be discarded)
+ */
+extern zbar_scanner_t *zbar_scanner_create(zbar_decoder_t *decoder);
+
+/** destructor. */
+extern void zbar_scanner_destroy(zbar_scanner_t *scanner);
+
+/** clear all scanner state.
+ * also resets an associated decoder
+ */
+extern zbar_symbol_type_t zbar_scanner_reset(zbar_scanner_t *scanner);
+
+/** mark start of a new scan pass. resets color to ::ZBAR_SPACE.
+ * also updates an associated decoder.
+ * @returns any decode results flushed from the pipeline
+ * @note when not using callback handlers, the return value should
+ * be checked the same as zbar_scan_y()
+ * @note call zbar_scanner_flush() at least twice before calling this
+ * method to ensure no decode results are lost
+ */
+extern zbar_symbol_type_t zbar_scanner_new_scan(zbar_scanner_t *scanner);
+
+/** flush scanner processing pipeline.
+ * forces current scanner position to be a scan boundary.
+ * call multiple times (max 3) to completely flush decoder.
+ * @returns any decode/scan results flushed from the pipeline
+ * @note when not using callback handlers, the return value should
+ * be checked the same as zbar_scan_y()
+ * @since 0.9
+ */
+extern zbar_symbol_type_t zbar_scanner_flush(zbar_scanner_t *scanner);
+
+/** process next sample intensity value.
+ * intensity (y) is in arbitrary relative units.
+ * @returns result of zbar_decode_width() if a decoder is attached,
+ * otherwise @returns (::ZBAR_PARTIAL) when new edge is detected
+ * or 0 (::ZBAR_NONE) if no new edge is detected
+ */
+extern zbar_symbol_type_t zbar_scan_y(zbar_scanner_t *scanner,
+                                      int y);
+
+/** process next sample from RGB (or BGR) triple. */
+static inline zbar_symbol_type_t zbar_scan_rgb24 (zbar_scanner_t *scanner,
+                                                    unsigned char *rgb)
+{
+    return(zbar_scan_y(scanner, rgb[0] + rgb[1] + rgb[2]));
+}
+
+/** retrieve last scanned width. */
+extern unsigned zbar_scanner_get_width(const zbar_scanner_t *scanner);
+
+/** retrieve sample position of last edge.
+ * @since 0.10
+ */
+extern unsigned zbar_scanner_get_edge(const zbar_scanner_t *scn,
+                                      unsigned offset,
+                                      int prec);
+
+/** retrieve last scanned color. */
+extern zbar_color_t zbar_scanner_get_color(const zbar_scanner_t *scanner);
+
+/*@}*/
+
+#ifdef __cplusplus
+    }
+}
+
+# include "zbar/Exception.h"
+# include "zbar/Decoder.h"
+# include "zbar/Scanner.h"
+# include "zbar/Symbol.h"
+# include "zbar/Image.h"
+# include "zbar/ImageScanner.h"
+# include "zbar/Video.h"
+# include "zbar/Window.h"
+# include "zbar/Processor.h"
+#endif
+
+typedef struct
+{
+	zbar_image_scanner_t *scanner;
+	zbar_image_t *image;
+	zbar_symbol_t *symbol;
+}zbar_t;
+
+zbar_t *zbar_create(void);
+//输入灰度图像点阵,zbar解码,并设置好第一个解出来的数据信息,返回0表示没有解码出数据,其他有数据
+int zbar_run(zbar_t *zbar, int width, int height, void *src);
+//获取解出来的数据,len返回数据长度,函数返回数据内存指针
+char *zbar_get_data_ptr(zbar_t *zbar, unsigned int *len);
+//设置好下一个解出来的数据信息,返回0表示没有数据了,其他有数据
+int zbar_find_next_data(zbar_t *zbar);
+void zbar_destory(zbar_t *zbar);
+void zbar_run_demo(void);
+#endif

+ 242 - 0
Third_Party/ZBAR/include/zbar_config.h

@@ -0,0 +1,242 @@
+/* manually customized for iPhone platform */
+
+/* whether to build support for Code 128 symbology */
+//#undef ENABLE_CODE128
+#define ENABLE_CODE128 1
+
+/* whether to build support for Code 93 symbology */
+#undef ENABLE_CODE93
+//#define ENABLE_CODE93 1
+
+/* whether to build support for Code 39 symbology */
+#undef ENABLE_CODE39
+//#define ENABLE_CODE39 1
+
+/* whether to build support for Codabar symbology */
+//#undef ENABLE_CODABAR
+#define ENABLE_DATABAR 1
+
+
+/* whether to build support for DataBar symbology */
+#undef ENABLE_DATABAR
+//#define ENABLE_DATABAR 1
+
+/* whether to build support for EAN symbologies */
+#undef ENABLE_EAN
+//#define ENABLE_EAN 1
+
+/* whether to build support for Interleaved 2 of 5 symbology */
+#undef ENABLE_I25
+//#define ENABLE_I25 1
+
+/* whether to build support for PDF417 symbology */
+#undef ENABLE_PDF417
+//#define ENABLE_PDF417 1
+
+/* whether to build support for QR Code */
+#define ENABLE_QRCODE 1
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <features.h> header file. */
+#undef HAVE_FEATURES_H
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the iconv() function and it works. */
+#undef HAVE_ICONV
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <jpeglib.h> header file. */
+#undef HAVE_JPEGLIB_H
+
+/* Define to 1 if you have the `jpeg' library (-ljpeg). */
+#undef HAVE_LIBJPEG
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the <linux/videodev2.h> header file. */
+#undef HAVE_LINUX_VIDEODEV2_H
+
+/* Define to 1 if you have the <linux/videodev.h> header file. */
+#undef HAVE_LINUX_VIDEODEV_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#undef HAVE_SYS_IPC_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+#undef HAVE_SYS_SHM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <vfw.h> header file. */
+#undef HAVE_VFW_H
+
+/* Define to 1 if you have the <X11/extensions/XShm.h> header file. */
+#undef HAVE_X11_EXTENSIONS_XSHM_H
+
+/* Define to 1 if you have the <X11/extensions/Xvlib.h> header file. */
+#undef HAVE_X11_EXTENSIONS_XVLIB_H
+
+/* Define as const if the declaration of iconv() needs const. */
+#undef ICONV_CONST
+
+/* Library major version */
+#define LIB_VERSION_MAJOR 0
+
+/* Library minor version */
+#define LIB_VERSION_MINOR 2
+
+/* Library revision */
+#define LIB_VERSION_REVISION 0
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to 1 if assertions should be disabled. */
+//#undef NDEBUG
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of package */
+#define PACKAGE "zbar"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "spadix@users.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "zbar"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "zbar 0.10"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "zbar"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.10"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.10"
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#define X_DISPLAY_MISSING 1
+
+/* Program major version (before the '.') as a number */
+#define ZBAR_VERSION_MAJOR 0
+
+/* Program minor version (after '.') as a number */
+#define ZBAR_VERSION_MINOR 10
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT8_T
+
+/* Minimum Windows API version */
+#undef _WIN32_WINNT
+
+/* used only for pthread debug attributes */
+#undef __USE_UNIX98
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__INLINE__' or `__INLINE' if that's what the C compiler
+   calls it, or to nothing if 'INLINE' is not supported under any name.  */
+#define INLINE
+#define inline
+///* Define to the type of a signed integer type of width exactly 32 bits if
+//   such a type exists and the standard includes do not define it. */
+//#undef int32_t
+//
+///* Define to the type of an unsigned integer type of width exactly 32 bits if
+//   such a type exists and the standard includes do not define it. */
+//#undef uint32_t
+//
+///* Define to the type of an unsigned integer type of width exactly 8 bits if
+//   such a type exists and the standard includes do not define it. */
+//#undef uint8_t
+//
+///* Define to the type of an unsigned integer type wide enough to hold a
+//   pointer, if such a type exists, and if the system does not define it. */
+//#undef uintptr_t
+
+//#define NO_STATS
+#ifndef X_DISPLAY_MISSING
+# define HAVE_X
+#endif
+

+ 184 - 0
Third_Party/ZBAR/src/bch15_5.c

@@ -0,0 +1,184 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#include "bch15_5.h"
+
+/*A cycle in GF(2**4) generated by alpha=(x**4+x+1).
+  It is extended an extra 16 entries to avoid some expensive mod operations.*/
+static const unsigned char gf16_exp[31]={
+  1,2,4,8,3,6,12,11,5,10,7,14,15,13,9,1,2,4,8,3,6,12,11,5,10,7,14,15,13,9,1
+};
+
+/*The location of each integer 1...16 in the cycle.*/
+static const signed char gf16_log[16]={
+  -1,0,1,4,2,8,5,10,3,14,9,7,6,13,11,12
+};
+
+/*Multiplication in GF(2**4) using logarithms.*/
+static unsigned gf16_mul(unsigned _a,unsigned _b){
+  return _a==0||_b==0?0:gf16_exp[gf16_log[_a]+gf16_log[_b]];
+}
+
+/*Division in GF(2**4) using logarithms.
+  The result when dividing by zero is undefined.*/
+static unsigned gf16_div(unsigned _a,unsigned _b){
+  return _a==0?0:gf16_exp[gf16_log[_a]+15-gf16_log[_b]];
+}
+
+/*Multiplication in GF(2**4) when the second argument is known to be non-zero
+   (proven by representing it by its logarithm).*/
+static unsigned gf16_hmul(unsigned _a,unsigned _logb){
+  return _a==0?0:gf16_exp[gf16_log[_a]+_logb];
+}
+
+/*The syndrome normally has five values, S_1 ... S_5.
+  We only calculate and store the odd ones in _s, since S_2=S_1**2 and
+   S_4=S_2**2.
+  Returns zero iff all the syndrome values are zero.*/
+static int bch15_5_calc_syndrome(unsigned _s[3],unsigned _y){
+  unsigned p;
+  int      i;
+  int      j;
+  p=0;
+  for(i=0;i<15;i++)if(_y&1<<i)p^=gf16_exp[i];
+  _s[0]=p;
+  p=0;
+  for(i=0;i<3;i++)for(j=0;j<5;j++)if(_y&1<<5*i+j)p^=gf16_exp[j*3];
+  _s[1]=p;
+  p=0;
+  for(i=0;i<5;i++)for(j=0;j<3;j++)if(_y&1<<3*i+j)p^=gf16_exp[j*5];
+  _s[2]=p;
+  return _s[0]!=0||_s[1]!=0||_s[2]!=0;
+}
+
+/*Compute the coefficients of the error-locator polynomial.
+  Returns the number of errors (the degree of the polynomial).*/
+static int bch15_5_calc_omega(unsigned _o[3],unsigned _s[3]){
+  unsigned s02;
+  unsigned tt;
+  unsigned dd;
+  int      d;
+  _o[0]=_s[0];
+  s02=gf16_mul(_s[0],_s[0]);
+  dd=_s[1]^gf16_mul(_s[0],s02);
+  tt=_s[2]^gf16_mul(s02,_s[1]);
+  _o[1]=dd?gf16_div(tt,dd):0;
+  _o[2]=dd^gf16_mul(_s[0],_o[1]);
+  for(d=3;d>0&&!_o[d-1];d--);
+  return d;
+}
+
+/*Find the roots of the error polynomial.
+  Returns the number of roots found, or a negative value if the polynomial did
+   not have enough roots, indicating a decoding error.*/
+static int bch15_5_calc_epos(unsigned _epos[3],unsigned _s[3]){
+  unsigned o[3];
+  int      nerrors;
+  int      d;
+  int      i;
+  d=bch15_5_calc_omega(o,_s);
+  nerrors=0;
+  if(d==1)_epos[nerrors++]=gf16_log[o[0]];
+  else if(d>0){
+    for(i=0;i<15;i++){
+      int i2;
+      i2=gf16_log[gf16_exp[i<<1]];
+      if(!(gf16_exp[i+i2]^gf16_hmul(o[0],i2)^gf16_hmul(o[1],i)^o[2])){
+        _epos[nerrors++]=i;
+      }
+    }
+    if(nerrors<d)return -1;
+  }
+  return nerrors;
+}
+
+int bch15_5_correct(unsigned *_y){
+  unsigned s[3];
+  unsigned epos[3];
+  unsigned y;
+  int      nerrors;
+  int      i;
+  y=*_y;
+  if(!bch15_5_calc_syndrome(s,y))return 0;
+  nerrors=bch15_5_calc_epos(epos,s);
+  if(nerrors>0){
+    /*If we had a non-zero syndrome value, we should always find at least one
+       error location, or we've got a decoding error.*/
+    for(i=0;i<nerrors;i++)y^=1<<epos[i];
+    /*If there were too many errors, we may not find enough roots to reduce the
+       syndrome to zero.
+      We could recompute it to check, but it's much faster just to check that
+       we have a valid codeword.*/
+    if(bch15_5_encode(y>>10)==y){
+      /*Decoding succeeded.*/
+      *_y=y;
+      return nerrors;
+    }
+  }
+  /*Decoding failed due to too many bit errors.*/
+  return -1;
+}
+
+unsigned bch15_5_encode(unsigned _x){
+  return (-(_x&1)&0x0537)^(-(_x>>1&1)&0x0A6E)^(-(_x>>2&1)&0x11EB)^
+   (-(_x>>3&1)&0x23D6)^(-(_x>>4&1)&0x429B);
+}
+
+#if 0
+#include <stdio.h>
+
+static unsigned codes[32];
+
+static int hamming(int _a,int _b){
+  int d;
+  int n;
+  d=_a^_b;
+  for(n=0;d;n++)d&=d-1;
+  return n;
+}
+
+static int closest(int _y){
+  int min_i;
+  int min_d;
+  int i;
+  int d;
+  min_i=0;
+  min_d=hamming(_y,codes[0]);
+  for(i=1;i<32;i++){
+    d=hamming(_y,codes[i]);
+    if(d<min_d){
+      min_d=d;
+      min_i=i;
+    }
+  }
+  return codes[min_i];
+}
+
+int main(void){
+  int i;
+  /*Print a list of the valid (uncorrupt) codewords.*/
+  for(i=0;i<32;i++)codes[i]=bch15_5_encode(i);
+  for(i=0;i<32;i++)printf("0x%04X%s",codes[i],i+1<32?"  ":"\n");
+  /*Try to decode all receivable (possibly corrupt) codewords.*/
+  for(i=0;i<0x8000;i++){
+    unsigned y;
+    unsigned z;
+    int      nerrors;
+    int      j;
+    y=i;
+    nerrors=bch15_5_correct(&y);
+    z=closest(i);
+    if(nerrors<0){
+      printf("0x%04X->Failed\n",i);
+      if(hamming(i,z)<=3)printf("Error: 0x%04X should map to 0x%04X\n",i,z);
+    }
+    else{
+      printf("0x%04X->0x%04X\n",i,y);
+      if(z!=y)printf("Error: 0x%04X should map to 0x%04X\n",i,z);
+    }
+  }
+  return 0;
+}
+#endif

+ 639 - 0
Third_Party/ZBAR/src/binarize.c

@@ -0,0 +1,639 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+//#include <stdlib.h>
+//#include <math.h>
+//#include <string.h>
+#include "util.h"
+#include "image.h"
+#include "binarize.h"
+
+#if 0
+/*Binarization based on~\cite{GPP06}.
+  @ARTICLE{GPP06,
+    author="Basilios Gatos and Ioannis E. Pratikakis and Stavros J. Perantonis",
+    title="Adaptive Degraded Document Image Binarization",
+    journal="Pattern Recognition",
+    volume=39,
+    number=3,
+    pages="317-327",
+    month=Mar,
+    year=2006
+  }*/
+
+#if 0
+/*Applies a 5x5 Wiener filter to the image, in-place, emphasizing differences
+   where the local variance is small, and de-emphasizing them where it is
+   large.*/
+void qr_wiener_filter(unsigned char *_img,int _width,int _height){
+  unsigned           *m_buf[8];
+  unsigned           *sn2_buf[8];
+  unsigned char       g;
+  int                 x;
+  int                 y;
+  if(_width<=0||_height<=0)return;
+  m_buf[0]=(unsigned *)malloc((_width+4<<3)*sizeof(*m_buf));
+  sn2_buf[0]=(unsigned *)malloc((_width+4<<3)*sizeof(*sn2_buf));
+  for(y=1;y<8;y++){
+    m_buf[y]=m_buf[y-1]+_width+4;
+    sn2_buf[y]=sn2_buf[y-1]+_width+4;
+  }
+  for(y=-4;y<_height;y++){
+    unsigned *pm;
+    unsigned *psn2;
+    int       i;
+    int       j;
+    pm=m_buf[y+2&7];
+    psn2=sn2_buf[y+2&7];
+    for(x=-4;x<_width;x++){
+      unsigned m;
+      unsigned m2;
+      m=m2=0;
+      if(y>=0&&y<_height-4&&x>=0&&x<_width-4)for(i=0;i<5;i++)for(j=0;j<5;j++){
+        g=_img[(y+i)*_width+x+j];
+        m+=g;
+        m2+=g*g;
+      }
+      else for(i=0;i<5;i++)for(j=0;j<5;j++){
+        g=_img[QR_CLAMPI(0,y+i,_height-1)*_width+QR_CLAMPI(0,x+j,_width-1)];
+        m+=g;
+        m2+=g*g;
+      }
+      pm[x+4]=m;
+      psn2[x+4]=(m2*25-m*m);
+    }
+    pm=m_buf[y&7];
+    if(y>=0)for(x=0;x<_width;x++){
+      int sn2;
+      sn2=sn2_buf[y&7][x+2];
+      if(sn2){
+        int vn3;
+        int m;
+        /*Gatos et al. give the expression
+            mu+(s2-v2)*(g-mu)/s2 ,
+           which we reduce to
+            mu+(s2-v2)*g/s2-(s2-v2)*mu/s2 ,
+            g-(v2/s2)*g+(v2/s2)*mu ,
+            g+(mu-g)*(v2/s2) .
+           However, s2 is much noisier than v2, and dividing by it often gives
+            extremely large adjustments, causing speckle near edges.
+           Therefore we limit the ratio (v2/s2) to lie between 0 and 1.*/
+        vn3=0;
+        for(i=-2;i<3;i++){
+          psn2=sn2_buf[y+i&7];
+          for(j=0;j<5;j++)vn3+=psn2[x+j];
+        }
+        m=m_buf[y&7][x+2];
+        vn3=vn3+1023>>10;
+        sn2=25*sn2+1023>>10;
+        if(vn3<sn2){
+          int a;
+          g=_img[y*_width+x];
+          a=(m-25*g)*vn3;
+          sn2*=25;
+          _img[y*_width+x]=QR_CLAMP255(g+QR_DIVROUND(a,sn2));
+        }
+        else _img[y*_width+x]=(unsigned char)(((m<<1)+25)/50);
+      }
+    }
+  }
+  free(sn2_buf[0]);
+  free(m_buf[0]);
+}
+
+#else
+/*Applies a 3x3 Wiener filter to the image, in-place, emphasizing differences
+   where the local variance is small, and de-emphasizing them where it is
+   large.*/
+void qr_wiener_filter(unsigned char *_img,int _width,int _height){
+  unsigned           *m_buf[4];
+  unsigned           *sn2_buf[4];
+  unsigned char       g;
+  int                 x;
+  int                 y;
+  if(_width<=0||_height<=0)return;
+  m_buf[0]=(unsigned *)malloc((_width+2<<2)*sizeof(*m_buf));
+  sn2_buf[0]=(unsigned *)malloc((_width+2<<2)*sizeof(*sn2_buf));
+  for(y=1;y<4;y++){
+    m_buf[y]=m_buf[y-1]+_width+2;
+    sn2_buf[y]=sn2_buf[y-1]+_width+2;
+  }
+  for(y=-2;y<_height;y++){
+    unsigned *pm;
+    unsigned *psn2;
+    int       i;
+    int       j;
+    pm=m_buf[y+1&3];
+    psn2=sn2_buf[y+1&3];
+    for(x=-2;x<_width;x++){
+      unsigned m;
+      unsigned m2;
+      m=m2=0;
+      if(y>=0&&y<_height-2&&x>=0&&x<_width-2)for(i=0;i<3;i++)for(j=0;j<3;j++){
+        g=_img[(y+i)*_width+x+j];
+        m+=g;
+        m2+=g*g;
+      }
+      else for(i=0;i<3;i++)for(j=0;j<3;j++){
+        g=_img[QR_CLAMPI(0,y+i,_height-1)*_width+QR_CLAMPI(0,x+j,_width-1)];
+        m+=g;
+        m2+=g*g;
+      }
+      pm[x+2]=m;
+      psn2[x+2]=(m2*9-m*m);
+    }
+    pm=m_buf[y&3];
+    if(y>=0)for(x=0;x<_width;x++){
+      int sn2;
+      sn2=sn2_buf[y&3][x+1];
+      if(sn2){
+        int m;
+        int vn3;
+        /*Gatos et al. give the expression
+            mu+(s2-v2)*(g-mu)/s2 ,
+           which we reduce to
+            mu+(s2-v2)*g/s2-(s2-v2)*mu/s2 ,
+            g-(v2/s2)*g+(v2/s2)*mu ,
+            g+(mu-g)*(v2/s2) .
+           However, s2 is much noisier than v2, and dividing by it often gives
+            extremely large adjustments, causing speckle near edges.
+           Therefore we limit the ratio (v2/s2) to lie between 0 and 1.*/
+        vn3=0;
+        for(i=-1;i<2;i++){
+          psn2=sn2_buf[y+i&3];
+          for(j=0;j<3;j++)vn3+=psn2[x+j];
+        }
+        m=m_buf[y&3][x+1];
+        vn3=vn3+31>>5;
+        sn2=9*sn2+31>>5;
+        if(vn3<sn2){
+          int a;
+          g=_img[y*_width+x];
+          a=m-9*g;
+          sn2*=9;
+          _img[y*_width+x]=QR_CLAMP255(g+QR_DIVROUND(a,sn2));
+        }
+        else _img[y*_width+x]=(unsigned char)(((m<<1)+9)/18);
+      }
+    }
+  }
+  free(sn2_buf[0]);
+  free(m_buf[0]);
+}
+#endif
+
+/*Computes a (conservative) foreground mask using the adaptive binarization
+   threshold given in~\cite{SP00}, but knocking the threshold parameter down to
+   k=0.2.
+  Note on dynamic range: we assume _width*_height<=0x1000000 (24 bits).
+  Returns the average background value.
+  @ARTICLE{SP00,
+    author="Jaakko J. Sauvola and Matti Pietik\"{a}inen",
+    title="Adaptive Document Image Binarization",
+    volume=33,
+    number=2,
+    pages="225--236",
+    month=Feb,
+    year=2000
+  }*/
+static void qr_sauvola_mask(unsigned char *_mask,unsigned *_b,int *_nb,
+ const unsigned char *_img,int _width,int _height){
+  unsigned  b;
+  int       nb;
+  b=0;
+  nb=0;
+  if(_width>0&&_height>0){
+    unsigned *col_sums;
+    unsigned *col2_sums;
+    int       logwindw;
+    int       logwindh;
+    int       windw;
+    int       windh;
+    int       y0offs;
+    int       y1offs;
+    unsigned  g;
+    unsigned  g2;
+    int       x;
+    int       y;
+    /*We keep the window size fairly large to ensure it doesn't fit completely
+       inside the center of a finder pattern of a version 1 QR code at full
+       resolution.*/
+    for(logwindw=4;logwindw<8&&(1<<logwindw)<(_width+7>>3);logwindw++);
+    for(logwindh=4;logwindh<8&&(1<<logwindh)<(_height+7>>3);logwindh++);
+    windw=1<<logwindw;
+    windh=1<<logwindh;
+    col_sums=(unsigned *)malloc(_width*sizeof(*col_sums));
+    col2_sums=(unsigned *)malloc(_width*sizeof(*col2_sums));
+    /*Initialize sums down each column.*/
+    for(x=0;x<_width;x++){
+      g=_img[x];
+      g2=g*g;
+      col_sums[x]=(g<<logwindh-1)+g;
+      col2_sums[x]=(g2<<logwindh-1)+g2;
+    }
+    for(y=1;y<(windh>>1);y++){
+      y1offs=QR_MINI(y,_height-1)*_width;
+      for(x=0;x<_width;x++){
+        g=_img[y1offs+x];
+        col_sums[x]+=g;
+        col2_sums[x]+=g*g;
+      }
+    }
+    for(y=0;y<_height;y++){
+      unsigned m;
+      unsigned m2;
+      int      x0;
+      int      x1;
+      /*Initialize the sums over the window.*/
+      m=(col_sums[0]<<logwindw-1)+col_sums[0];
+      m2=(col2_sums[0]<<logwindw-1)+col2_sums[0];
+      for(x=1;x<(windw>>1);x++){
+        x1=QR_MINI(x,_width-1);
+        m+=col_sums[x1];
+        m2+=col2_sums[x1];
+      }
+      for(x=0;x<_width;x++){
+        int d;
+        /*Perform the test against the threshold T = (m/n)*(1+k*(s/R-1)),
+           where n=windw*windh, s=sqrt((m2-(m*m)/n)/n), and R=128.
+          We don't actually compute the threshold directly, as that would
+           require a square root.
+          Instead we perform the equivalent test:
+           (m/n)*(m/n)*(m2/n-(m/n)*(m/n))/16 > (((1/k)*g-((1-k)/k)*(m/n))*32)**2
+          R is split up across each side of the inequality to maximize the
+           dynamic range available for the right hand side, which requires
+           31 bits in the worst case.*/
+        /*(m/n)*(1+(1/5)*(sqrt((m2-m*m/n)/n)/128-1)) > g
+          m*(1+(1/5)*(sqrt((m2-m*m/n)/n)/128-1)) > g*n
+          m*sqrt((m2-m*m/n)/n) > 5*g*n-4*m<<7
+          m*m*(m2*n-m*m) > (5*g*n-4*m<<7)**2*n*n || 5*g*n-4*m < 0 */
+        g=_img[y*_width+x];
+        d=(5*g<<logwindw+logwindh)-4*m;
+        if(d>=0){
+          unsigned mm;
+          unsigned mms2;
+          unsigned d2;
+          mm=(m>>logwindw)*(m>>logwindh);
+          mms2=(m2-mm>>logwindw+logwindh)*(mm>>logwindw+logwindh)+15>>4;
+          d2=d>>logwindw+logwindh-5;
+          d2*=d2;
+          if(d2>=mms2){
+            /*Update the background average.*/
+            b+=g;
+            nb++;
+            _mask[y*_width+x]=0;
+          }
+          else _mask[y*_width+x]=0xFF;
+        }
+        else _mask[y*_width+x]=0xFF;
+        /*Update the window sums.*/
+        if(x+1<_width){
+          x0=QR_MAXI(0,x-(windw>>1));
+          x1=QR_MINI(x+(windw>>1),_width-1);
+          m+=col_sums[x1]-col_sums[x0];
+          m2+=col2_sums[x1]-col2_sums[x0];
+        }
+      }
+      /*Update the column sums.*/
+      if(y+1<_height){
+        y0offs=QR_MAXI(0,y-(windh>>1))*_width;
+        y1offs=QR_MINI(y+(windh>>1),_height-1)*_width;
+        for(x=0;x<_width;x++){
+          g=_img[y0offs+x];
+          col_sums[x]-=g;
+          col2_sums[x]-=g*g;
+          g=_img[y1offs+x];
+          col_sums[x]+=g;
+          col2_sums[x]+=g*g;
+        }
+      }
+    }
+    free(col2_sums);
+    free(col_sums);
+  }
+  *_b=b;
+  *_nb=nb;
+}
+
+/*Interpolates a background image given the source and a conservative
+   foreground mask.
+  If the current window contains no foreground pixels, the average background
+   value over the whole image is used.
+  Note on dynamic range: we assume _width*_height<=0x8000000 (23 bits).
+  Returns the average difference between the foreground and the interpolated
+   background.*/
+static void qr_interpolate_background(unsigned char *_dst,
+ int *_delta,int *_ndelta,const unsigned char *_img,const unsigned char *_mask,
+ int _width,int _height,unsigned _b,int _nb){
+  int delta;
+  int ndelta;
+  delta=ndelta=0;
+  if(_width>0&&_height>0){
+    unsigned *col_sums;
+    unsigned *ncol_sums;
+    int       logwindw;
+    int       logwindh;
+    int       windw;
+    int       windh;
+    int       y0offs;
+    int       y1offs;
+    unsigned  b;
+    unsigned  g;
+    int       x;
+    int       y;
+    b=_nb>0?((_b<<1)+_nb)/(_nb<<1):0xFF;
+    for(logwindw=4;logwindw<8&&(1<<logwindw)<(_width+15>>4);logwindw++);
+    for(logwindh=4;logwindh<8&&(1<<logwindh)<(_height+15>>4);logwindh++);
+    windw=1<<logwindw;
+    windh=1<<logwindh;
+    col_sums=(unsigned *)malloc(_width*sizeof(*col_sums));
+    ncol_sums=(unsigned *)malloc(_width*sizeof(*ncol_sums));
+    /*Initialize sums down each column.*/
+    for(x=0;x<_width;x++){
+      if(!_mask[x]){
+        g=_img[x];
+        col_sums[x]=(g<<logwindh-1)+g;
+        ncol_sums[x]=(1<<logwindh-1)+1;
+      }
+      else col_sums[x]=ncol_sums[x]=0;
+    }
+    for(y=1;y<(windh>>1);y++){
+      y1offs=QR_MINI(y,_height-1)*_width;
+      for(x=0;x<_width;x++)if(!_mask[y1offs+x]){
+        col_sums[x]+=_img[y1offs+x];
+        ncol_sums[x]++;
+      }
+    }
+    for(y=0;y<_height;y++){
+      unsigned n;
+      unsigned m;
+      int      x0;
+      int      x1;
+      /*Initialize the sums over the window.*/
+      m=(col_sums[0]<<logwindw-1)+col_sums[0];
+      n=(ncol_sums[0]<<logwindw-1)+ncol_sums[0];
+      for(x=1;x<(windw>>1);x++){
+        x1=QR_MINI(x,_width-1);
+        m+=col_sums[x1];
+        n+=ncol_sums[x1];
+      }
+      for(x=0;x<_width;x++){
+        if(!_mask[y*_width+x])g=_img[y*_width+x];
+        else{
+          g=n>0?((m<<1)+n)/(n<<1):b;
+          delta+=(int)g-_img[y*_width+x];
+          ndelta++;
+        }
+        _dst[y*_width+x]=(unsigned char)g;
+        /*Update the window sums.*/
+        if(x+1<_width){
+          x0=QR_MAXI(0,x-(windw>>1));
+          x1=QR_MINI(x+(windw>>1),_width-1);
+          m+=col_sums[x1]-col_sums[x0];
+          n+=ncol_sums[x1]-ncol_sums[x0];
+        }
+      }
+      /*Update the column sums.*/
+      if(y+1<_height){
+        y0offs=QR_MAXI(0,y-(windh>>1))*_width;
+        y1offs=QR_MINI(y+(windh>>1),_height-1)*_width;
+        for(x=0;x<_width;x++){
+          if(!_mask[y0offs+x]){
+            col_sums[x]-=_img[y0offs+x];
+            ncol_sums[x]--;
+          }
+          if(!_mask[y1offs+x]){
+            col_sums[x]+=_img[y1offs+x];
+            ncol_sums[x]++;
+          }
+        }
+      }
+    }
+    free(ncol_sums);
+    free(col_sums);
+  }
+  *_delta=delta;
+  *_ndelta=ndelta;
+}
+
+/*Parameters of the logistic sigmoid function that defines the threshold based
+   on the background intensity.
+  They should all be between 0 and 1.*/
+#define QR_GATOS_Q  (0.7)
+#define QR_GATOS_P1 (0.5)
+#define QR_GATOS_P2 (0.8)
+
+/*Compute the final binarization mask according to Gatos et al.'s
+   method~\cite{GPP06}.*/
+static void qr_gatos_mask(unsigned char *_mask,const unsigned char *_img,
+ const unsigned char *_background,int _width,int _height,
+ unsigned _b,int _nb,int _delta,int _ndelta){
+  unsigned thresh[256];
+  unsigned g;
+  double   delta;
+  double   b;
+  int      x;
+  int      y;
+  /*Construct a lookup table for the thresholds.
+    This bit uses floating point, but doesn't need to do much calculation, so
+     emulation should be fine.*/
+  b=_nb>0?(_b+0.5)/_nb:0xFF;
+  delta=_ndelta>0?(_delta+0.5)/_ndelta:0xFF;
+  for(g=0;g<256;g++){
+    double d;
+    d=QR_GATOS_Q*delta*(QR_GATOS_P2+(1-QR_GATOS_P2)/
+     (1+exp(2*(1+QR_GATOS_P1)/(1-QR_GATOS_P1)-4*g/(b*(1-QR_GATOS_P1)))));
+    if(d<1)d=1;
+    else if(d>0xFF)d=0xFF;
+    thresh[g]=(unsigned)floor(d);
+  }
+  /*Apply the adaptive threshold.*/
+  for(y=0;y<_height;y++)for(x=0;x<_width;x++){
+    g=_background[y*_width+x];
+    /*_background[y*_width+x]=thresh[g];*/
+    _mask[y*_width+x]=(unsigned char)(-(g-_img[y*_width+x]>thresh[g])&0xFF);
+  }
+  /*{
+    FILE *fout;
+    fout=fopen("thresh.png","wb");
+    image_write_png(_background,_width,_height,fout);
+    fclose(fout);
+  }*/
+}
+
+/*Binarizes a grayscale image.*/
+void qr_binarize(unsigned char *_img,int _width,int _height){
+  unsigned char *mask;
+  unsigned char *background;
+  unsigned       b;
+  int            nb;
+  int            delta;
+  int            ndelta;
+  /*qr_wiener_filter(_img,_width,_height);
+  {
+    FILE *fout;
+    fout=fopen("wiener.png","wb");
+    image_write_png(_img,_width,_height,fout);
+    fclose(fout);
+  }*/
+  mask=(unsigned char *)malloc(_width*_height*sizeof(*mask));
+  qr_sauvola_mask(mask,&b,&nb,_img,_width,_height);
+  /*{
+    FILE *fout;
+    fout=fopen("foreground.png","wb");
+    image_write_png(mask,_width,_height,fout);
+    fclose(fout);
+  }*/
+  background=(unsigned char *)malloc(_width*_height*sizeof(*mask));
+  qr_interpolate_background(background,&delta,&ndelta,
+   _img,mask,_width,_height,b,nb);
+  /*{
+    FILE *fout;
+    fout=fopen("background.png","wb");
+    image_write_png(background,_width,_height,fout);
+    fclose(fout);
+  }*/
+  qr_gatos_mask(_img,_img,background,_width,_height,b,nb,delta,ndelta);
+  free(background);
+  free(mask);
+}
+
+#else
+/*The above algorithms are computationally expensive, and do not work as well
+   as the simple algorithm below.
+  Sauvola by itself does an excellent job of classifying regions outside the
+   QR code as background, which greatly reduces the chance of false alarms.
+  However, it also tends to over-shrink isolated black dots inside the code,
+   making them easy to miss with even slight mis-alignment.
+  Since the Gatos method uses Sauvola as input to its background interpolation
+   method, it cannot possibly mark any pixels as foreground which Sauvola
+   classified as background, and thus suffers from the same problem.
+  The following simple adaptive threshold method does not have this problem,
+   though it produces essentially random noise outside the QR code region.
+  QR codes are structured well enough that this does not seem to lead to any
+   actual false alarms in practice, and it allows many more codes to be
+   detected and decoded successfully than the Sauvola or Gatos binarization
+   methods.*/
+
+/*A simplified adaptive thresholder.
+  This compares the current pixel value to the mean value of a (large) window
+   surrounding it.*/
+unsigned char *qr_binarize(const unsigned char *_img,int _width,int _height){
+  unsigned char *mask = NULL;
+  if(_width>0&&_height>0){
+    unsigned      *col_sums;
+    int            logwindw;
+    int            logwindh;
+    int            windw;
+    int            windh;
+    int            y0offs;
+    int            y1offs;
+    unsigned       g;
+    int            x;
+    int            y;
+    mask=(unsigned char *)malloc(_width*_height*sizeof(*mask));
+    /*We keep the window size fairly large to ensure it doesn't fit completely
+       inside the center of a finder pattern of a version 1 QR code at full
+       resolution.*/
+    for(logwindw=4;logwindw<8&&(1<<logwindw)<(_width+7>>3);logwindw++);
+    for(logwindh=4;logwindh<8&&(1<<logwindh)<(_height+7>>3);logwindh++);
+    windw=1<<logwindw;
+    windh=1<<logwindh;
+    col_sums=(unsigned *)malloc(_width*sizeof(*col_sums));
+    /*Initialize sums down each column.*/
+    for(x=0;x<_width;x++){
+      g=_img[x];
+      col_sums[x]=(g<<logwindh-1)+g;
+    }
+    for(y=1;y<(windh>>1);y++){
+      y1offs=QR_MINI(y,_height-1)*_width;
+      for(x=0;x<_width;x++){
+        g=_img[y1offs+x];
+        col_sums[x]+=g;
+      }
+    }
+    for(y=0;y<_height;y++){
+      unsigned m;
+      int      x0;
+      int      x1;
+      /*Initialize the sum over the window.*/
+      m=(col_sums[0]<<logwindw-1)+col_sums[0];
+      for(x=1;x<(windw>>1);x++){
+        x1=QR_MINI(x,_width-1);
+        m+=col_sums[x1];
+      }
+      for(x=0;x<_width;x++){
+        /*Perform the test against the threshold T = (m/n)-D,
+           where n=windw*windh and D=3.*/
+        g=_img[y*_width+x];
+        mask[y*_width+x]=-(g+3<<logwindw+logwindh<m)&0xFF;
+        /*Update the window sum.*/
+        if(x+1<_width){
+          x0=QR_MAXI(0,x-(windw>>1));
+          x1=QR_MINI(x+(windw>>1),_width-1);
+          m+=col_sums[x1]-col_sums[x0];
+        }
+      }
+      /*Update the column sums.*/
+      if(y+1<_height){
+        y0offs=QR_MAXI(0,y-(windh>>1))*_width;
+        y1offs=QR_MINI(y+(windh>>1),_height-1)*_width;
+        for(x=0;x<_width;x++){
+          col_sums[x]-=_img[y0offs+x];
+          col_sums[x]+=_img[y1offs+x];
+        }
+      }
+    }
+    free(col_sums);
+  }
+#if defined(QR_DEBUG)
+  {
+    FILE *fout;
+    fout=fopen("binary.png","wb");
+    image_write_png(_img,_width,_height,fout);
+    fclose(fout);
+  }
+#endif
+  return(mask);
+}
+#endif
+
+#if defined(TEST_BINARIZE)
+#include <stdio.h>
+#include "image.c"
+
+int main(int _argc,char **_argv){
+  unsigned char *img;
+  int            width;
+  int            height;
+  int            x;
+  int            y;
+  if(_argc<2){
+    fprintf(stderr,"usage: %s <image>.png\n",_argv[0]);
+    return EXIT_FAILURE;
+  }
+  /*width=1182;
+  height=1181;
+  img=(unsigned char *)malloc(width*height*sizeof(*img));
+  for(y=0;y<height;y++)for(x=0;x<width;x++){
+    img[y*width+x]=(unsigned char)(-((x&1)^(y&1))&0xFF);
+  }*/
+  {
+    FILE *fin;
+    fin=fopen(_argv[1],"rb");
+    image_read_png(&img,&width,&height,fin);
+    fclose(fin);
+  }
+  qr_binarize(img,width,height);
+  /*{
+    FILE *fout;
+    fout=fopen("binary.png","wb");
+    image_write_png(img,width,height,fout);
+    fclose(fout);
+  }*/
+  free(img);
+  return EXIT_SUCCESS;
+}
+#endif

+ 516 - 0
Third_Party/ZBAR/src/code128.c

@@ -0,0 +1,516 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <config.h>
+#include <string.h>     /* memmove */
+
+#include <zbar.h>
+#include "decoder.h"
+
+#ifdef DEBUG_CODE128
+//# define DEBUG_LEVEL (DEBUG_CODE128)
+#endif
+#include "debug.h"
+//#include "assert.h"
+
+#define NUM_CHARS 108           /* total number of character codes */
+
+typedef enum code128_char_e {
+    FNC3        = 0x60,
+    FNC2        = 0x61,
+    SHIFT       = 0x62,
+    CODE_C      = 0x63,
+    CODE_B      = 0x64,
+    CODE_A      = 0x65,
+    FNC1        = 0x66,
+    START_A     = 0x67,
+    START_B     = 0x68,
+    START_C     = 0x69,
+    STOP_FWD    = 0x6a,
+    STOP_REV    = 0x6b,
+    FNC4        = 0x6c,
+} code128_char_t;
+
+static const unsigned char characters[NUM_CHARS] = {
+    0x5c, 0xbf, 0xa1,                                           /* [00] 00 */
+    0x2a, 0xc5, 0x0c, 0xa4,                                     /* [03] 01 */
+    0x2d, 0xe3, 0x0f,                                           /* [07] 02 */
+    0x5f, 0xe4,                                                 /* [0a] 03 */
+
+    0x6b, 0xe8, 0x69, 0xa7, 0xe7,                               /* [0c] 10 */
+    0xc1, 0x51, 0x1e, 0x83, 0xd9, 0x00, 0x84, 0x1f,             /* [11] 11 */
+    0xc7, 0x0d, 0x33, 0x86, 0xb5, 0x0e, 0x15, 0x87,             /* [19] 12 */
+    0x10, 0xda, 0x11,                                           /* [21] 13 */
+
+    0x36, 0xe5, 0x18, 0x37,                                     /* [24] 20 */
+    0xcc, 0x13, 0x39, 0x89, 0x97, 0x14, 0x1b, 0x8a, 0x3a, 0xbd, /* [28] 21 */
+    0xa2, 0x5e, 0x01, 0x85, 0xb0, 0x02, 0xa3,                   /* [32] 22 */
+    0xa5, 0x2c, 0x16, 0x88, 0xbc, 0x12, 0xa6,                   /* [39] 23 */
+
+    0x61, 0xe6, 0x56, 0x62,                                     /* [40] 30 */
+    0x19, 0xdb, 0x1a,                                           /* [44] 31 */
+    0xa8, 0x32, 0x1c, 0x8b, 0xcd, 0x1d, 0xa9,                   /* [47] 32 */
+    0xc3, 0x20, 0xc4,                                           /* [4e] 33 */
+
+    0x50, 0x5d, 0xc0,       /* [51] 0014 0025 0034 */
+    0x2b, 0xc6,             /* [54] 0134 0143 */
+    0x2e,                   /* [56] 0243 */
+    0x53, 0x60,             /* [57] 0341 0352 */
+    0x31,                   /* [59] 1024 */
+    0x52, 0xc2,             /* [5a] 1114 1134 */
+    0x34, 0xc8,             /* [5c] 1242 1243 */
+    0x55,                   /* [5e] 1441 */
+
+    0x57, 0x3e, 0xce,       /* [5f] 4100 5200 4300 */
+    0x3b, 0xc9,             /* [62] 4310 3410 */
+    0x6a,                   /* [64] 3420 */
+    0x54, 0x4f,             /* [65] 1430 2530 */
+    0x38,                   /* [67] 4201 */
+    0x58, 0xcb,             /* [68] 4111 4311 */
+    0x2f, 0xca,             /* [6a] 2421 3421 */
+};
+
+static const unsigned char lo_base[8] = {
+    0x00, 0x07, 0x0c, 0x19, 0x24, 0x32, 0x40, 0x47
+};
+
+static const unsigned char lo_offset[0x80] = {
+    0xff, 0xf0, 0xff, 0x1f, 0xff, 0xf2, 0xff, 0xff,     /* 00 [00] */
+    0xff, 0xff, 0xff, 0x3f, 0xf4, 0xf5, 0xff, 0x6f,     /* 01 */
+    0xff, 0xff, 0xff, 0xff, 0xf0, 0xf1, 0xff, 0x2f,     /* 02 [07] */
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x4f,     /* 03 */
+    0xff, 0x0f, 0xf1, 0xf2, 0xff, 0x3f, 0xff, 0xf4,     /* 10 [0c] */
+    0xf5, 0xf6, 0xf7, 0x89, 0xff, 0xab, 0xff, 0xfc,     /* 11 */
+    0xff, 0xff, 0x0f, 0x1f, 0x23, 0x45, 0xf6, 0x7f,     /* 12 [19] */
+    0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xf9, 0xaf,     /* 13 */
+
+    0xf0, 0xf1, 0xff, 0x2f, 0xff, 0xf3, 0xff, 0xff,     /* 20 [24] */
+    0x4f, 0x5f, 0x67, 0x89, 0xfa, 0xbf, 0xff, 0xcd,     /* 21 */
+    0xf0, 0xf1, 0xf2, 0x3f, 0xf4, 0x56, 0xff, 0xff,     /* 22 [32] */
+    0xff, 0xff, 0x7f, 0x8f, 0x9a, 0xff, 0xbc, 0xdf,     /* 23 */
+    0x0f, 0x1f, 0xf2, 0xff, 0xff, 0x3f, 0xff, 0xff,     /* 30 [40] */
+    0xf4, 0xff, 0xf5, 0x6f, 0xff, 0xff, 0xff, 0xff,     /* 31 */
+    0x0f, 0x1f, 0x23, 0xff, 0x45, 0x6f, 0xff, 0xff,     /* 32 [47] */
+    0xf7, 0xff, 0xf8, 0x9f, 0xff, 0xff, 0xff, 0xff,     /* 33 */
+};
+
+static inline signed char decode_lo (int sig)
+{
+    unsigned char offset = (((sig >> 1) & 0x01) |
+                            ((sig >> 3) & 0x06) |
+                            ((sig >> 5) & 0x18) |
+                            ((sig >> 7) & 0x60));
+    unsigned char idx = lo_offset[offset];
+    if(sig & 1)
+        idx &= 0xf;
+    else
+        idx >>= 4;
+    if(idx == 0xf)
+        return(-1);
+
+    unsigned char base = (sig >> 11) | ((sig >> 9) & 1);
+    zassert(base < 8, -1, "sig=%x offset=%x idx=%x base=%x\n",
+            sig, offset, idx, base);
+    idx += lo_base[base];
+
+    zassert(idx <= 0x50, -1, "sig=%x offset=%x base=%x idx=%x\n",
+            sig, offset, base, idx);
+    unsigned char c = characters[idx];
+    dprintf(2, " %02x(%x(%02x)/%x(%02x)) => %02x",
+            idx, base, lo_base[base], offset, lo_offset[offset],
+            (unsigned char)c);
+    return(c);
+}
+
+static inline signed char decode_hi (int sig)
+{
+    unsigned char rev = (sig & 0x4400) != 0;
+    if(rev)
+        sig = (((sig >> 12) & 0x000f) |
+               ((sig >>  4) & 0x00f0) |
+               ((sig <<  4) & 0x0f00) |
+               ((sig << 12) & 0xf000));
+    dprintf(2, " rev=%x", rev != 0);
+
+    unsigned char idx;
+    switch(sig) {
+    case 0x0014: idx = 0x0; break;
+    case 0x0025: idx = 0x1; break;
+    case 0x0034: idx = 0x2; break;
+    case 0x0134: idx = 0x3; break;
+    case 0x0143: idx = 0x4; break;
+    case 0x0243: idx = 0x5; break;
+    case 0x0341: idx = 0x6; break;
+    case 0x0352: idx = 0x7; break;
+    case 0x1024: idx = 0x8; break;
+    case 0x1114: idx = 0x9; break;
+    case 0x1134: idx = 0xa; break;
+    case 0x1242: idx = 0xb; break;
+    case 0x1243: idx = 0xc; break;
+    case 0x1441: idx = 0xd; rev = 0; break;
+    default: return(-1);
+    }
+    if(rev)
+        idx += 0xe;
+    unsigned char c = characters[0x51 + idx];
+    dprintf(2, " %02x => %02x", idx, c);
+    return(c);
+}
+
+static inline unsigned char calc_check (unsigned char c)
+{
+    if(!(c & 0x80))
+        return(0x18);
+    c &= 0x7f;
+    if(c < 0x3d)
+        return((c < 0x30 && c != 0x17) ? 0x10 : 0x20);
+    if(c < 0x50)
+        return((c == 0x4d) ? 0x20 : 0x10);
+    return((c < 0x67) ? 0x20 : 0x10);
+}
+
+static inline signed char decode6 (zbar_decoder_t *dcode)
+{
+    /* build edge signature of character */
+    unsigned s = dcode->code128.s6;
+    dprintf(2, " s=%d", s);
+    if(s < 5)
+        return(-1);
+    /* calculate similar edge measurements */
+    int sig = (get_color(dcode) == ZBAR_BAR)
+        ? ((decode_e(get_width(dcode, 0) + get_width(dcode, 1), s, 11) << 12) |
+           (decode_e(get_width(dcode, 1) + get_width(dcode, 2), s, 11) << 8) |
+           (decode_e(get_width(dcode, 2) + get_width(dcode, 3), s, 11) << 4) |
+           (decode_e(get_width(dcode, 3) + get_width(dcode, 4), s, 11)))
+        : ((decode_e(get_width(dcode, 5) + get_width(dcode, 4), s, 11) << 12) |
+           (decode_e(get_width(dcode, 4) + get_width(dcode, 3), s, 11) << 8) |
+           (decode_e(get_width(dcode, 3) + get_width(dcode, 2), s, 11) << 4) |
+           (decode_e(get_width(dcode, 2) + get_width(dcode, 1), s, 11)));
+    if(sig < 0)
+        return(-1);
+    dprintf(2, " sig=%04x", sig);
+    /* lookup edge signature */
+    signed char c = (sig & 0x4444) ? decode_hi(sig) : decode_lo(sig);
+    if(c == -1)
+        return(-1);
+
+    /* character validation */
+    unsigned bars = (get_color(dcode) == ZBAR_BAR)
+        ? (get_width(dcode, 0) + get_width(dcode, 2) + get_width(dcode, 4))
+        : (get_width(dcode, 1) + get_width(dcode, 3) + get_width(dcode, 5));
+    bars = bars * 11 * 4 / s;
+    unsigned char chk = calc_check(c);
+    dprintf(2, " bars=%d chk=%d", bars, chk);
+    if(chk - 7 > bars || bars > chk + 7)
+        return(-1);
+
+    return(c & 0x7f);
+}
+
+static inline unsigned char validate_checksum (zbar_decoder_t *dcode)
+{
+    code128_decoder_t *dcode128 = &dcode->code128;
+    if(dcode128->character < 3)
+        return(1);
+
+    /* add in irregularly weighted start character */
+    unsigned idx = (dcode128->direction) ? dcode128->character - 1 : 0;
+    unsigned sum = dcode->buf[idx];
+    if(sum >= 103)
+        sum -= 103;
+
+    /* calculate sum in reverse to avoid multiply operations */
+    unsigned i, acc = 0;
+    for(i = dcode128->character - 3; i; i--) {
+        zassert(sum < 103, -1, "dir=%x i=%x sum=%x acc=%x %s\n",
+                dcode128->direction, i, sum, acc,
+                _zbar_decoder_buf_dump(dcode->buf, dcode128->character));
+        idx = (dcode128->direction) ? dcode128->character - 1 - i : i;
+        acc += dcode->buf[idx];
+        if(acc >= 103)
+            acc -= 103;
+        zassert(acc < 103, -1, "dir=%x i=%x sum=%x acc=%x %s\n",
+                dcode128->direction, i, sum, acc,
+                _zbar_decoder_buf_dump(dcode->buf, dcode128->character));
+        sum += acc;
+        if(sum >= 103)
+            sum -= 103;
+    }
+
+    /* and compare to check character */
+    idx = (dcode128->direction) ? 1 : dcode128->character - 2;
+    unsigned char check = dcode->buf[idx];
+    dprintf(2, " chk=%02x(%02x)", sum, check);
+    unsigned char err = (sum != check);
+    if(err)
+        dprintf(1, " [checksum error]\n");
+    return(err);
+}
+
+/* expand and decode character set C */
+static inline unsigned postprocess_c (zbar_decoder_t *dcode,
+                                      unsigned start,
+                                      unsigned end,
+                                      unsigned dst)
+{
+    /* expand buffer to accomodate 2x set C characters (2 digits per-char) */
+    unsigned delta = end - start;
+    unsigned newlen = dcode->code128.character + delta;
+    size_buf(dcode, newlen);
+
+    /* relocate unprocessed data to end of buffer */
+    memmove(dcode->buf + start + delta, dcode->buf + start,
+            dcode->code128.character - start);
+    dcode->code128.character = newlen;
+
+    unsigned i, j;
+    for(i = 0, j = dst; i < delta; i++, j += 2) {
+        /* convert each set C character into two ASCII digits */
+        unsigned char code = dcode->buf[start + delta + i];
+        dcode->buf[j] = '0';
+        if(code >= 50) {
+            code -= 50;
+            dcode->buf[j] += 5;
+        }
+        if(code >= 30) {
+            code -= 30;
+            dcode->buf[j] += 3;
+        }
+        if(code >= 20) {
+            code -= 20;
+            dcode->buf[j] += 2;
+        }
+        if(code >= 10) {
+            code -= 10;
+            dcode->buf[j] += 1;
+        }
+        zassert(dcode->buf[j] <= '9', delta,
+                "start=%x end=%x i=%x j=%x %s\n", start, end, i, j,
+                _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
+        zassert(code <= 9, delta,
+                "start=%x end=%x i=%x j=%x %s\n", start, end, i, j,
+                _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
+        dcode->buf[j + 1] = '0' + code;
+    }
+    return(delta);
+}
+
+/* resolve scan direction and convert to ASCII */
+static inline unsigned char postprocess (zbar_decoder_t *dcode)
+{
+    code128_decoder_t *dcode128 = &dcode->code128;
+    dprintf(2, "\n    postproc len=%d", dcode128->character);
+    unsigned i, j;
+    unsigned char code = 0;
+    if(dcode128->direction) {
+        /* reverse buffer */
+        dprintf(2, " (rev)");
+        for(i = 0; i < dcode128->character / 2; i++) {
+            unsigned j = dcode128->character - 1 - i;
+            code = dcode->buf[i];
+            dcode->buf[i] = dcode->buf[j];
+            dcode->buf[j] = code;
+        }
+        zassert(dcode->buf[dcode128->character - 1] == STOP_REV, 1,
+                "dir=%x %s\n", dcode128->direction,
+                _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
+    }
+    else
+        zassert(dcode->buf[dcode128->character - 1] == STOP_FWD, 1,
+                "dir=%x %s\n", dcode128->direction,
+                _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
+
+    code = dcode->buf[0];
+    zassert(code >= START_A && code <= START_C, 1, "%s\n",
+            _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
+
+    unsigned char charset = code - START_A;
+    unsigned cexp = (code == START_C) ? 1 : 0;
+    dprintf(2, " start=%c", 'A' + charset);
+
+    for(i = 1, j = 0; i < dcode128->character - 2; i++) {
+        unsigned char code = dcode->buf[i];
+        zassert(!(code & 0x80), 1,
+                "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
+                i, j, code, charset, cexp,
+                _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
+
+        if((charset & 0x2) && (code < 100))
+            /* defer character set C for expansion */
+            continue;
+        else if(code < 0x60) {
+            /* convert character set B to ASCII */
+            code = code + 0x20;
+            if((!charset || (charset == 0x81)) && (code >= 0x60))
+                /* convert character set A to ASCII */
+                code -= 0x60;
+            dcode->buf[j++] = code;
+            if(charset & 0x80)
+                charset &= 0x7f;
+        }
+        else {
+            dprintf(2, " %02x", code);
+            if(charset & 0x2) {
+                /* expand character set C to ASCII */
+                zassert(cexp, 1, "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
+                        i, j, code, charset, cexp,
+                        _zbar_decoder_buf_dump(dcode->buf,
+                                                dcode->code128.character));
+                unsigned delta = postprocess_c(dcode, cexp, i, j);
+                i += delta;
+                j += delta * 2;
+                cexp = 0;
+            }
+            if(code < CODE_C) {
+                if(code == SHIFT)
+                    charset |= 0x80;
+                else if(code == FNC2)
+                    /* FIXME FNC2 - message append */;
+                else if(code == FNC3)
+                    /* FIXME FNC3 - initialize */;
+            }
+            else if(code == FNC1)
+                /* FIXME FNC1 - Code 128 subsets or ASCII 0x1d */;
+            else if(code >= START_A) {
+                dprintf(1, " [truncated]\n");
+                return(1);
+            }
+            else {
+                zassert(code >= CODE_C && code <= CODE_A, 1,
+                        "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
+                        i, j, code, charset, cexp,
+                        _zbar_decoder_buf_dump(dcode->buf,
+                                                dcode->code128.character));
+                unsigned char newset = CODE_A - code;
+                if(newset != charset)
+                    charset = newset;
+                else
+                    /* FIXME FNC4 - extended ASCII */;
+            }
+            if(charset & 0x2)
+                cexp = i + 1;
+        }
+    }
+    if(charset & 0x2) {
+        zassert(cexp, 1, "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
+                i, j, code, charset, cexp,
+                _zbar_decoder_buf_dump(dcode->buf,
+                                        dcode->code128.character));
+        j += postprocess_c(dcode, cexp, i, j) * 2;
+    }
+    dcode->buflen = j;
+    dcode->buf[j] = '\0';
+    dcode->code128.character = j;
+    return(0);
+}
+
+zbar_symbol_type_t _zbar_decode_code128 (zbar_decoder_t *dcode)
+{
+    code128_decoder_t *dcode128 = &dcode->code128;
+
+    /* update latest character width */
+    dcode128->s6 -= get_width(dcode, 6);
+    dcode128->s6 += get_width(dcode, 0);
+
+    if(/* process every 6th element of active symbol */
+       (dcode128->character >= 0 &&
+        (++dcode128->element) != 6) ||
+       /* decode color based on direction */
+       (get_color(dcode) != dcode128->direction))
+        return(0);
+    dcode128->element = 0;
+
+    dprintf(2, "      code128[%c%02d+%x]:",
+            (dcode128->direction) ? '<' : '>',
+            dcode128->character, dcode128->element);
+
+    signed char c = decode6(dcode);
+    if(dcode128->character < 0) {
+        dprintf(2, " c=%02x", c);
+        if(c < START_A || c > STOP_REV || c == STOP_FWD) {
+            dprintf(2, " [invalid]\n");
+            return(0);
+        }
+        unsigned qz = get_width(dcode, 6);
+        if(qz && qz < (dcode->code128.s6 * 3) / 4) {
+            dprintf(2, " [invalid qz %d]\n", qz);
+            return(0);
+        }
+        /* lock shared resources */
+        if(get_lock(dcode, ZBAR_CODE128)) {
+            dprintf(2, " [locked %d]\n", dcode->lock);
+            dcode128->character = -1;
+            return(0);
+        }
+        /* decoded valid start/stop */
+        /* initialize state */
+        dcode128->character = 0;
+        if(c == STOP_REV) {
+            dcode128->direction = ZBAR_BAR;
+            dcode128->element = 7;
+        }
+        else
+            dcode128->direction = ZBAR_SPACE;
+        dprintf(2, " dir=%x [valid start]", dcode128->direction);
+    }
+    else if((c < 0) ||
+            ((dcode128->character >= BUFFER_MIN) &&
+             size_buf(dcode, dcode128->character + 1))) {
+        dprintf(1, (c < 0) ? " [aborted]\n" : " [overflow]\n");
+        dcode->lock = 0;
+        dcode128->character = -1;
+        return(0);
+    }
+
+    zassert(dcode->buf_alloc > dcode128->character, 0,
+            "alloc=%x idx=%x c=%02x %s\n",
+            dcode->buf_alloc, dcode128->character, c,
+            _zbar_decoder_buf_dump(dcode->buf, dcode->buf_alloc));
+
+    dcode->buf[dcode128->character++] = c;
+
+    if(dcode128->character > 2 &&
+       ((dcode128->direction)
+        ? c >= START_A && c <= START_C
+        : c == STOP_FWD)) {
+        /* FIXME STOP_FWD should check extra bar (and QZ!) */
+        zbar_symbol_type_t sym = ZBAR_CODE128;
+        if(validate_checksum(dcode) || postprocess(dcode))
+            sym = ZBAR_NONE;
+        else if(dcode128->character < CFG(*dcode128, ZBAR_CFG_MIN_LEN) ||
+                (CFG(*dcode128, ZBAR_CFG_MAX_LEN) > 0 &&
+                 dcode128->character > CFG(*dcode128, ZBAR_CFG_MAX_LEN))) {
+            dprintf(2, " [invalid len]\n");
+            sym = ZBAR_NONE;
+        }
+        else
+            dprintf(2, " [valid end]\n");
+        dcode128->character = -1;
+        if(!sym)
+            dcode->lock = 0;
+        return(sym);
+    }
+
+    dprintf(2, "\n");
+    return(0);
+}

+ 148 - 0
Third_Party/ZBAR/src/config.c

@@ -0,0 +1,148 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2008-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <config.h>
+//#include <stdlib.h>     /* strtol */
+#include <string.h>     /* strchr, strncmp, strlen */
+#include <errno.h>
+//#include <assert.h>
+
+#include <zbar.h>
+
+int zbar_parse_config (const char *cfgstr,
+                        zbar_symbol_type_t *sym,
+                        zbar_config_t *cfg,
+                        int *val)
+{
+    if(!cfgstr)
+        return(1);
+
+    const char *dot = strchr(cfgstr, '.');
+    if(dot) {
+        int len = dot - cfgstr;
+        if(!len || (len == 1 && !strncmp(cfgstr, "*", len)))
+            *sym = 0;
+        else if(len < 2)
+            return(1);
+        else if(!strncmp(cfgstr, "qrcode", len))
+            *sym = ZBAR_QRCODE;
+        else if(len < 3)
+            return(1);
+        else if(!strncmp(cfgstr, "upca", len))
+            *sym = ZBAR_UPCA;
+        else if(!strncmp(cfgstr, "upce", len))
+            *sym = ZBAR_UPCE;
+        else if(!strncmp(cfgstr, "ean13", len))
+            *sym = ZBAR_EAN13;
+        else if(!strncmp(cfgstr, "ean8", len))
+            *sym = ZBAR_EAN8;
+        else if(!strncmp(cfgstr, "i25", len))
+            *sym = ZBAR_I25;
+        else if(len < 4)
+            return(1);
+        else if(!strncmp(cfgstr, "scanner", len))
+            *sym = ZBAR_PARTIAL; /* FIXME lame */
+        else if(!strncmp(cfgstr, "isbn13", len))
+            *sym = ZBAR_ISBN13;
+        else if(!strncmp(cfgstr, "isbn10", len))
+            *sym = ZBAR_ISBN10;
+#if 0
+        /* FIXME addons are configured per-main symbol type */
+        else if(!strncmp(cfgstr, "addon2", len))
+            *sym = ZBAR_ADDON2;
+        else if(!strncmp(cfgstr, "addon5", len))
+            *sym = ZBAR_ADDON5;
+#endif
+        else if(len < 6)
+            return(1);
+        else if(!strncmp(cfgstr, "code39", len))
+            *sym = ZBAR_CODE39;
+        else if(!strncmp(cfgstr, "pdf417", len))
+            *sym = ZBAR_PDF417;
+        else if(len < 7)
+            return(1);
+        else if(!strncmp(cfgstr, "code128", len))
+            *sym = ZBAR_CODE128;
+        else
+            return(1);
+        cfgstr = dot + 1;
+    }
+    else
+        *sym = 0;
+
+    int len = strlen(cfgstr);
+    const char *eq = strchr(cfgstr, '=');
+    if(eq)
+        len = eq - cfgstr;
+    else
+        *val = 1;  /* handle this here so we can override later */
+    char negate = 0;
+
+    if(len > 3 && !strncmp(cfgstr, "no-", 3)) {
+        negate = 1;
+        cfgstr += 3;
+        len -= 3;
+    }
+
+    if(len < 1)
+        return(1);
+    else if(!strncmp(cfgstr, "y-density", len))
+        *cfg = ZBAR_CFG_Y_DENSITY;
+    else if(!strncmp(cfgstr, "x-density", len))
+        *cfg = ZBAR_CFG_X_DENSITY;
+    else if(len < 2)
+        return(1);
+    else if(!strncmp(cfgstr, "enable", len))
+        *cfg = ZBAR_CFG_ENABLE;
+    else if(len < 3)
+        return(1);
+    else if(!strncmp(cfgstr, "disable", len)) {
+        *cfg = ZBAR_CFG_ENABLE;
+        negate = !negate; /* no-disable ?!? */
+    }
+    else if(!strncmp(cfgstr, "min-length", len))
+        *cfg = ZBAR_CFG_MIN_LEN;
+    else if(!strncmp(cfgstr, "max-length", len))
+        *cfg = ZBAR_CFG_MAX_LEN;
+    else if(!strncmp(cfgstr, "ascii", len))
+        *cfg = ZBAR_CFG_ASCII;
+    else if(!strncmp(cfgstr, "add-check", len))
+        *cfg = ZBAR_CFG_ADD_CHECK;
+    else if(!strncmp(cfgstr, "emit-check", len))
+        *cfg = ZBAR_CFG_EMIT_CHECK;
+    else if(!strncmp(cfgstr, "position", len))
+        *cfg = ZBAR_CFG_POSITION;
+    else 
+        return(1);
+
+    if(eq) {
+        errno = 0;
+        *val = strtol(eq + 1, NULL, 0);
+        if(errno)
+            return(1);
+    }
+    if(negate)
+        *val = !*val;
+
+    return(0);
+}

+ 1139 - 0
Third_Party/ZBAR/src/convert.c

@@ -0,0 +1,1139 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include "image.h"
+#include "video.h"
+#include "window.h"
+
+//#define stderr 1
+//#define fprintf(err, format, ...) printf(format, ...)
+
+
+/* pack bit size and location offset of a component into one byte
+ */
+#define RGB_BITS(off, size) ((((8 - (size)) & 0x7) << 5) | ((off) & 0x1f))
+
+typedef void (conversion_handler_t)(zbar_image_t*,
+                                    const zbar_format_def_t*,
+                                    const zbar_image_t*,
+                                    const zbar_format_def_t*);
+
+typedef struct conversion_def_s {
+    int cost;                           /* conversion "badness" */
+    conversion_handler_t *func;         /* function that accomplishes it */
+} conversion_def_t;
+
+
+/* NULL terminated list of known formats, in order of preference
+ * (NB Cr=V Cb=U)
+ */
+const uint32_t _zbar_formats[] = {
+
+    /* planar YUV formats */
+    fourcc('4','2','2','P'), /* FIXME also YV16? */
+    fourcc('I','4','2','0'),
+    fourcc('Y','U','1','2'), /* FIXME also IYUV? */
+    fourcc('Y','V','1','2'),
+    fourcc('4','1','1','P'),
+
+    /* planar Y + packed UV plane */
+    fourcc('N','V','1','2'),
+    fourcc('N','V','2','1'),
+
+    /* packed YUV formats */
+    fourcc('Y','U','Y','V'),
+    fourcc('U','Y','V','Y'),
+    fourcc('Y','U','Y','2'), /* FIXME add YVYU */
+    fourcc('Y','U','V','4'), /* FIXME where is this from? */
+
+    /* packed rgb formats */
+    fourcc('R','G','B','3'),
+    fourcc( 3 , 0 , 0 , 0 ),
+    fourcc('B','G','R','3'),
+    fourcc('R','G','B','4'),
+    fourcc('B','G','R','4'),
+
+    fourcc('R','G','B','P'),
+    fourcc('R','G','B','O'),
+    fourcc('R','G','B','R'),
+    fourcc('R','G','B','Q'),
+
+    fourcc('Y','U','V','9'),
+    fourcc('Y','V','U','9'),
+
+    /* basic grayscale format */
+    fourcc('G','R','E','Y'),
+    fourcc('Y','8','0','0'),
+    fourcc('Y','8',' ',' '),
+    fourcc('Y','8', 0 , 0 ),
+
+    /* low quality RGB formats */
+    fourcc('R','G','B','1'),
+    fourcc('R','4','4','4'),
+    fourcc('B','A','8','1'),
+
+    /* unsupported packed YUV formats */
+    fourcc('Y','4','1','P'),
+    fourcc('Y','4','4','4'),
+    fourcc('Y','U','V','O'),
+    fourcc('H','M','1','2'),
+
+    /* unsupported packed RGB format */
+    fourcc('H','I','2','4'),
+
+    /* unsupported compressed formats */
+    fourcc('J','P','E','G'),
+    fourcc('M','J','P','G'),
+    fourcc('M','P','E','G'),
+
+    /* terminator */
+    0
+};
+
+const int _zbar_num_formats = sizeof(_zbar_formats) / sizeof(uint32_t);
+
+/* format definitions */
+static const zbar_format_def_t format_defs[] = {
+
+    { fourcc('R','G','B','4'), ZBAR_FMT_RGB_PACKED,
+        { { 4, RGB_BITS(8, 8), RGB_BITS(16, 8), RGB_BITS(24, 8) } } },
+    { fourcc('B','G','R','1'), ZBAR_FMT_RGB_PACKED,
+        { { 1, RGB_BITS(0, 3), RGB_BITS(3, 3), RGB_BITS(6, 2) } } },
+    { fourcc('4','2','2','P'), ZBAR_FMT_YUV_PLANAR, { { 1, 0, 0 /*UV*/ } } },
+    { fourcc('Y','8','0','0'), ZBAR_FMT_GRAY, },
+    { fourcc('Y','U','Y','2'), ZBAR_FMT_YUV_PACKED,
+        { { 1, 0, 0, /*YUYV*/ } } },
+    { fourcc('J','P','E','G'), ZBAR_FMT_JPEG, },
+    { fourcc('Y','V','Y','U'), ZBAR_FMT_YUV_PACKED,
+        { { 1, 0, 1, /*YVYU*/ } } },
+    { fourcc('Y','8', 0 , 0 ), ZBAR_FMT_GRAY, },
+    { fourcc('N','V','2','1'), ZBAR_FMT_YUV_NV,     { { 1, 1, 1 /*VU*/ } } },
+    { fourcc('N','V','1','2'), ZBAR_FMT_YUV_NV,     { { 1, 1, 0 /*UV*/ } } },
+    { fourcc('B','G','R','3'), ZBAR_FMT_RGB_PACKED,
+        { { 3, RGB_BITS(16, 8), RGB_BITS(8, 8), RGB_BITS(0, 8) } } },
+    { fourcc('Y','V','U','9'), ZBAR_FMT_YUV_PLANAR, { { 2, 2, 1 /*VU*/ } } },
+    { fourcc('R','G','B','O'), ZBAR_FMT_RGB_PACKED,
+        { { 2, RGB_BITS(10, 5), RGB_BITS(5, 5), RGB_BITS(0, 5) } } },
+    { fourcc('R','G','B','Q'), ZBAR_FMT_RGB_PACKED,
+        { { 2, RGB_BITS(2, 5), RGB_BITS(13, 5), RGB_BITS(8, 5) } } },
+    { fourcc('G','R','E','Y'), ZBAR_FMT_GRAY, },
+    { fourcc( 3 , 0 , 0 , 0 ), ZBAR_FMT_RGB_PACKED,
+        { { 4, RGB_BITS(16, 8), RGB_BITS(8, 8), RGB_BITS(0, 8) } } },
+    { fourcc('Y','8',' ',' '), ZBAR_FMT_GRAY, },
+    { fourcc('I','4','2','0'), ZBAR_FMT_YUV_PLANAR, { { 1, 1, 0 /*UV*/ } } },
+    { fourcc('R','G','B','1'), ZBAR_FMT_RGB_PACKED,
+        { { 1, RGB_BITS(5, 3), RGB_BITS(2, 3), RGB_BITS(0, 2) } } },
+    { fourcc('Y','U','1','2'), ZBAR_FMT_YUV_PLANAR, { { 1, 1, 0 /*UV*/ } } },
+    { fourcc('Y','V','1','2'), ZBAR_FMT_YUV_PLANAR, { { 1, 1, 1 /*VU*/ } } },
+    { fourcc('R','G','B','3'), ZBAR_FMT_RGB_PACKED,
+        { { 3, RGB_BITS(0, 8), RGB_BITS(8, 8), RGB_BITS(16, 8) } } },
+    { fourcc('R','4','4','4'), ZBAR_FMT_RGB_PACKED,
+        { { 2, RGB_BITS(8, 4), RGB_BITS(4, 4), RGB_BITS(0, 4) } } },
+    { fourcc('B','G','R','4'), ZBAR_FMT_RGB_PACKED,
+        { { 4, RGB_BITS(16, 8), RGB_BITS(8, 8), RGB_BITS(0, 8) } } },
+    { fourcc('Y','U','V','9'), ZBAR_FMT_YUV_PLANAR, { { 2, 2, 0 /*UV*/ } } },
+    { fourcc('M','J','P','G'), ZBAR_FMT_JPEG, },
+    { fourcc('4','1','1','P'), ZBAR_FMT_YUV_PLANAR, { { 2, 0, 0 /*UV*/ } } },
+    { fourcc('R','G','B','P'), ZBAR_FMT_RGB_PACKED,
+        { { 2, RGB_BITS(11, 5), RGB_BITS(5, 6), RGB_BITS(0, 5) } } },
+    { fourcc('R','G','B','R'), ZBAR_FMT_RGB_PACKED,
+        { { 2, RGB_BITS(3, 5), RGB_BITS(13, 6), RGB_BITS(8, 5) } } },
+    { fourcc('Y','U','Y','V'), ZBAR_FMT_YUV_PACKED,
+        { { 1, 0, 0, /*YUYV*/ } } },
+    { fourcc('U','Y','V','Y'), ZBAR_FMT_YUV_PACKED,
+        { { 1, 0, 2, /*UYVY*/ } } },
+};
+
+static const int num_format_defs =
+    sizeof(format_defs) / sizeof(zbar_format_def_t);
+
+#ifdef DEBUG_CONVERT
+static int intsort (const void *a,
+                    const void *b)
+{
+    return(*(uint32_t*)a - *(uint32_t*)b);
+}
+#endif
+
+/* verify that format list is in required sort order */
+static inline int verify_format_sort (void)
+{
+    int i;
+    for(i = 0; i < num_format_defs; i++) {
+        int j = i * 2 + 1;
+        if((j < num_format_defs &&
+            format_defs[i].format < format_defs[j].format) ||
+           (j + 1 < num_format_defs &&
+            format_defs[j + 1].format < format_defs[i].format))
+            break;
+    }
+    if(i == num_format_defs)
+        return(0);
+
+    /* spew correct order for fix */
+    //fprintf(stderr, "ERROR: image format list is not sorted!?\n");
+
+#ifdef DEBUG_CONVERT
+    assert(num_format_defs);
+    uint32_t sorted[num_format_defs];
+    uint32_t ordered[num_format_defs];
+    for(i = 0; i < num_format_defs; i++)
+        sorted[i] = format_defs[i].format;
+    qsort(sorted, num_format_defs, sizeof(uint32_t), intsort);
+    for(i = 0; i < num_format_defs; i = i << 1 | 1);
+    i = (i - 1) / 2;
+    ordered[i] = sorted[0];
+    int j, k;
+    for(j = 1; j < num_format_defs; j++) {
+        k = i * 2 + 2;
+        if(k < num_format_defs) {
+            i = k;
+            for(k = k * 2 + 1; k < num_format_defs; k = k * 2 + 1)
+                i = k;
+        }
+        else {
+            for(k = (i - 1) / 2; i != k * 2 + 1; k = (i - 1) / 2) {
+                assert(i);
+                i = k;
+            }
+            i = k;
+        }
+        ordered[i] = sorted[j];
+    }
+
+    #if 0
+    fprintf(stderr, "correct sort order is:");
+    for(i = 0; i < num_format_defs; i++)
+        fprintf(stderr, " %4.4s", (char*)&ordered[i]);
+    fprintf(stderr, "\n");
+    #endif
+#endif
+    return(-1);
+}
+
+static inline void uv_round (zbar_image_t *img,
+                             const zbar_format_def_t *fmt)
+{
+    img->width >>= fmt->p.yuv.xsub2;
+    img->width <<= fmt->p.yuv.xsub2;
+    img->height >>= fmt->p.yuv.ysub2;
+    img->height <<= fmt->p.yuv.ysub2;
+}
+
+static inline void uv_roundup (zbar_image_t *img,
+                               const zbar_format_def_t *fmt)
+{
+    if(fmt->group == ZBAR_FMT_GRAY)
+        return;
+    unsigned xmask = (1 << fmt->p.yuv.xsub2) - 1;
+    if(img->width & xmask)
+        img->width = (img->width + xmask) & ~xmask;
+    unsigned ymask = (1 << fmt->p.yuv.ysub2) - 1;
+    if(img->height & ymask)
+        img->height = (img->height + ymask) & ~ymask;
+}
+
+static inline unsigned long uvp_size (const zbar_image_t *img,
+                                      const zbar_format_def_t *fmt)
+{
+    if(fmt->group == ZBAR_FMT_GRAY)
+        return(0);
+    return((img->width >> fmt->p.yuv.xsub2) *
+           (img->height >> fmt->p.yuv.ysub2));
+}
+
+static inline uint32_t convert_read_rgb (const uint8_t *srcp,
+                                         int bpp)
+{
+    uint32_t p;
+    if(bpp == 3) {
+        p = *srcp;
+        p |= *(srcp + 1) << 8;
+        p |= *(srcp + 2) << 16;
+    }
+    else if(bpp == 4)
+        p = *((uint32_t*)(srcp));
+    else if(bpp == 2)
+        p = *((uint16_t*)(srcp));
+    else
+        p = *srcp;
+    return(p);
+}
+
+static inline void convert_write_rgb (uint8_t *dstp,
+                                      uint32_t p,
+                                      int bpp)
+{
+    if(bpp == 3) {
+        *dstp = p & 0xff;
+        *(dstp + 1) = (p >> 8) & 0xff;
+        *(dstp + 2) = (p >> 16) & 0xff;
+    }
+    else if(bpp == 4)
+        *((uint32_t*)dstp) = p;
+    else if(bpp == 2)
+        *((uint16_t*)dstp) = p;
+    else
+        *dstp = p;
+}
+
+/* cleanup linked image by unrefing */
+static void cleanup_ref (zbar_image_t *img)
+{
+    if(img->next)
+        _zbar_image_refcnt(img->next, -1);
+}
+
+/* resize y plane, drop extra columns/rows from the right/bottom,
+ * or duplicate last column/row to pad missing data
+ */
+static inline void convert_y_resize (zbar_image_t *dst,
+                                     const zbar_format_def_t *dstfmt,
+                                     const zbar_image_t *src,
+                                     const zbar_format_def_t *srcfmt,
+                                     size_t n)
+{
+    if(dst->width == src->width && dst->height == src->height) {
+        memcpy((void*)dst->data, src->data, n);
+        return;
+    }
+    uint8_t *psrc = (void*)src->data;
+    uint8_t *pdst = (void*)dst->data;
+    unsigned width = (dst->width > src->width) ? src->width : dst->width;
+    unsigned xpad = (dst->width > src->width) ? dst->width - src->width : 0;
+    unsigned height = (dst->height > src->height) ? src->height : dst->height;
+    unsigned y;
+    for(y = 0; y < height; y++) {
+        memcpy(pdst, psrc, width);
+        pdst += width;
+        psrc += src->width;
+        if(xpad) {
+            memset(pdst, *(psrc - 1), xpad);
+            pdst += xpad;
+        }
+    }
+    psrc -= src->width;
+    for(; y < dst->height; y++) {
+        memcpy(pdst, psrc, width);
+        pdst += width;
+        if(xpad) {
+            memset(pdst, *(psrc - 1), xpad);
+            pdst += xpad;
+        }
+    }
+}
+
+/* make new image w/reference to the same image data */
+static void convert_copy (zbar_image_t *dst,
+                          const zbar_format_def_t *dstfmt,
+                          const zbar_image_t *src,
+                          const zbar_format_def_t *srcfmt)
+{
+    if(src->width == dst->width &&
+       src->height == dst->height) {
+        dst->data = src->data;
+        dst->datalen = src->datalen;
+        dst->cleanup = cleanup_ref;
+        zbar_image_t *s = (zbar_image_t*)src;
+        dst->next = s;
+        _zbar_image_refcnt(s, 1);
+    }
+    else
+        /* NB only for GRAY/YUV_PLANAR formats */
+        convert_y_resize(dst, dstfmt, src, srcfmt, dst->width * dst->height);
+}
+
+/* append neutral UV plane to grayscale image */
+static void convert_uvp_append (zbar_image_t *dst,
+                                const zbar_format_def_t *dstfmt,
+                                const zbar_image_t *src,
+                                const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    dst->datalen = uvp_size(dst, dstfmt) * 2;
+    unsigned long n = dst->width * dst->height;
+    dst->datalen += n;
+    assert(src->datalen >= src->width * src->height);
+    zprintf(24, "dst=%dx%d (%lx) %lx src=%dx%d %lx\n",
+            dst->width, dst->height, n, dst->datalen,
+            src->width, src->height, src->datalen);
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    convert_y_resize(dst, dstfmt, src, srcfmt, n);
+    memset((unsigned int)dst->data + n, 0x80, dst->datalen - n);
+}
+
+/* interleave YUV planes into packed YUV */
+static void convert_yuv_pack (zbar_image_t *dst,
+                              const zbar_format_def_t *dstfmt,
+                              const zbar_image_t *src,
+                              const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    dst->datalen = dst->width * dst->height + uvp_size(dst, dstfmt) * 2;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    uint8_t *dstp = (void*)dst->data;
+
+    unsigned long srcm = uvp_size(src, srcfmt);
+    unsigned long srcn = src->width * src->height;
+    assert(src->datalen >= srcn + 2 * srcn);
+    uint8_t flags = dstfmt->p.yuv.packorder ^ srcfmt->p.yuv.packorder;
+    uint8_t *srcy = (void*)src->data;
+    const uint8_t *srcu, *srcv;
+    if(flags & 1) {
+        srcv = (unsigned int)src->data + srcn;
+        srcu = srcv + srcm;
+    } else {
+        srcu = (unsigned int)src->data + srcn;
+        srcv = srcu + srcm;
+    }
+    flags = dstfmt->p.yuv.packorder & 2;
+
+    unsigned srcl = src->width >> srcfmt->p.yuv.xsub2;
+    unsigned xmask = (1 << srcfmt->p.yuv.xsub2) - 1;
+    unsigned ymask = (1 << srcfmt->p.yuv.ysub2) - 1;
+    unsigned x, y;
+    uint8_t y0 = 0, y1 = 0, u = 0x80, v = 0x80;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height) {
+            srcy -= src->width;
+            srcu -= srcl;  srcv -= srcl;
+        }
+        else if(y & ymask) {
+            srcu -= srcl;  srcv -= srcl;
+        }
+        for(x = 0; x < dst->width; x += 2) {
+            if(x < src->width) {
+                y0 = *(srcy++);  y1 = *(srcy++);
+                if(!(x & xmask)) {
+                    u = *(srcu++);  v = *(srcv++);
+                }
+            }
+            if(flags) {
+                *(dstp++) = u;  *(dstp++) = y0;
+                *(dstp++) = v;  *(dstp++) = y1;
+            } else {
+                *(dstp++) = y0;  *(dstp++) = u;
+                *(dstp++) = y1;  *(dstp++) = v;
+            }
+        }
+        for(; x < src->width; x += 2) {
+            srcy += 2;
+            if(!(x & xmask)) {
+                srcu++;  srcv++;
+            }
+        }
+    }
+}
+
+/* split packed YUV samples and join into YUV planes
+ * FIXME currently ignores color and grayscales the image
+ */
+static void convert_yuv_unpack (zbar_image_t *dst,
+                                const zbar_format_def_t *dstfmt,
+                                const zbar_image_t *src,
+                                const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    unsigned long dstn = dst->width * dst->height;
+    unsigned long dstm2 = uvp_size(dst, dstfmt) * 2;
+    dst->datalen = dstn + dstm2;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    if(dstm2)
+        memset((unsigned int)dst->data + dstn, 0x80, dstm2);
+    uint8_t *dsty = (void*)dst->data;
+
+    uint8_t flags = srcfmt->p.yuv.packorder ^ dstfmt->p.yuv.packorder;
+    flags &= 2;
+    const uint8_t *srcp = src->data;
+    if(flags)
+        srcp++;
+
+    unsigned srcl = src->width + (src->width >> srcfmt->p.yuv.xsub2);
+    unsigned x, y;
+    uint8_t y0 = 0, y1 = 0;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            srcp -= srcl;
+        for(x = 0; x < dst->width; x += 2) {
+            if(x < src->width) {
+                y0 = *(srcp++);  srcp++;
+                y1 = *(srcp++);  srcp++;
+            }
+            *(dsty++) = y0;
+            *(dsty++) = y1;
+        }
+        if(x < src->width)
+            srcp += (src->width - x) * 2;
+    }
+}
+
+/* resample and resize UV plane(s)
+ * FIXME currently ignores color and grayscales the image
+ */
+static void convert_uvp_resample (zbar_image_t *dst,
+                                  const zbar_format_def_t *dstfmt,
+                                  const zbar_image_t *src,
+                                  const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    unsigned long dstn = dst->width * dst->height;
+    unsigned long dstm2 = uvp_size(dst, dstfmt) * 2;
+    dst->datalen = dstn + dstm2;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    convert_y_resize(dst, dstfmt, src, srcfmt, dstn);
+    if(dstm2)
+        memset((unsigned int)dst->data + dstn, 0x80, dstm2);
+}
+
+/* rearrange interleaved UV componets */
+static void convert_uv_resample (zbar_image_t *dst,
+                                 const zbar_format_def_t *dstfmt,
+                                 const zbar_image_t *src,
+                                 const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    unsigned long dstn = dst->width * dst->height;
+    dst->datalen = dstn + uvp_size(dst, dstfmt) * 2;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    uint8_t *dstp = (void*)dst->data;
+
+    uint8_t flags = (srcfmt->p.yuv.packorder ^ dstfmt->p.yuv.packorder) & 1;
+    const uint8_t *srcp = src->data;
+
+    unsigned srcl = src->width + (src->width >> srcfmt->p.yuv.xsub2);
+    unsigned x, y;
+    uint8_t y0 = 0, y1 = 0, u = 0x80, v = 0x80;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            srcp -= srcl;
+        for(x = 0; x < dst->width; x += 2) {
+            if(x < src->width) {
+                if(!(srcfmt->p.yuv.packorder & 2)) {
+                    y0 = *(srcp++);  u = *(srcp++);
+                    y1 = *(srcp++);  v = *(srcp++);
+                }
+                else {
+                    u = *(srcp++);  y0 = *(srcp++);
+                    v = *(srcp++);  y1 = *(srcp++);
+                }
+                if(flags) {
+                    uint8_t tmp = u;  u = v;  v = tmp;
+                }
+            }
+            if(!(dstfmt->p.yuv.packorder & 2)) {
+                *(dstp++) = y0;  *(dstp++) = u;
+                *(dstp++) = y1;  *(dstp++) = v;
+            }
+            else {
+                *(dstp++) = u;  *(dstp++) = y0;
+                *(dstp++) = v;  *(dstp++) = y1;
+            }
+        }
+        if(x < src->width)
+            srcp += (src->width - x) * 2;
+    }
+}
+
+/* YUV planes to packed RGB
+ * FIXME currently ignores color and grayscales the image
+ */
+static void convert_yuvp_to_rgb (zbar_image_t *dst,
+                                 const zbar_format_def_t *dstfmt,
+                                 const zbar_image_t *src,
+                                 const zbar_format_def_t *srcfmt)
+{
+    dst->datalen = dst->width * dst->height * dstfmt->p.rgb.bpp;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    uint8_t *dstp = (void*)dst->data;
+
+    int drbits = RGB_SIZE(dstfmt->p.rgb.red);
+    int drbit0 = RGB_OFFSET(dstfmt->p.rgb.red);
+    int dgbits = RGB_SIZE(dstfmt->p.rgb.green);
+    int dgbit0 = RGB_OFFSET(dstfmt->p.rgb.green);
+    int dbbits = RGB_SIZE(dstfmt->p.rgb.blue);
+    int dbbit0 = RGB_OFFSET(dstfmt->p.rgb.blue);
+
+    unsigned long srcm = uvp_size(src, srcfmt);
+    unsigned long srcn = src->width * src->height;
+    assert(src->datalen >= srcn + 2 * srcm);
+    uint8_t *srcy = (void*)src->data;
+
+    unsigned x, y;
+    uint32_t p = 0;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            srcy -= src->width;
+        for(x = 0; x < dst->width; x++) {
+            if(x < src->width) {
+                /* FIXME color space? */
+                unsigned y0 = *(srcy++);
+                p = (((y0 >> drbits) << drbit0) |
+                     ((y0 >> dgbits) << dgbit0) |
+                     ((y0 >> dbbits) << dbbit0));
+            }
+            convert_write_rgb(dstp, p, dstfmt->p.rgb.bpp);
+            dstp += dstfmt->p.rgb.bpp;
+        }
+        if(x < src->width)
+            srcy += (src->width - x);
+    }
+}
+
+/* packed RGB to YUV planes
+ * FIXME currently ignores color and grayscales the image
+ */
+static void convert_rgb_to_yuvp (zbar_image_t *dst,
+                                 const zbar_format_def_t *dstfmt,
+                                 const zbar_image_t *src,
+                                 const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    unsigned long dstn = dst->width * dst->height;
+    unsigned long dstm2 = uvp_size(dst, dstfmt) * 2;
+    dst->datalen = dstn + dstm2;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    if(dstm2)
+        memset((unsigned int)dst->data + dstn, 0x80, dstm2);
+    uint8_t *dsty = (void*)dst->data;
+
+    assert(src->datalen >= (src->width * src->height * srcfmt->p.rgb.bpp));
+    const uint8_t *srcp = src->data;
+
+    int rbits = RGB_SIZE(srcfmt->p.rgb.red);
+    int rbit0 = RGB_OFFSET(srcfmt->p.rgb.red);
+    int gbits = RGB_SIZE(srcfmt->p.rgb.green);
+    int gbit0 = RGB_OFFSET(srcfmt->p.rgb.green);
+    int bbits = RGB_SIZE(srcfmt->p.rgb.blue);
+    int bbit0 = RGB_OFFSET(srcfmt->p.rgb.blue);
+
+    unsigned srcl = src->width * srcfmt->p.rgb.bpp;
+    unsigned x, y;
+    uint16_t y0 = 0;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            srcp -= srcl;
+        for(x = 0; x < dst->width; x++) {
+            if(x < src->width) {
+                uint8_t r, g, b;
+                uint32_t p = convert_read_rgb(srcp, srcfmt->p.rgb.bpp);
+                srcp += srcfmt->p.rgb.bpp;
+
+                /* FIXME endianness? */
+                r = ((p >> rbit0) << rbits) & 0xff;
+                g = ((p >> gbit0) << gbits) & 0xff;
+                b = ((p >> bbit0) << bbits) & 0xff;
+
+                /* FIXME color space? */
+                y0 = ((77 * r + 150 * g + 29 * b) + 0x80) >> 8;
+            }
+            *(dsty++) = y0;
+        }
+        if(x < src->width)
+            srcp += (src->width - x) * srcfmt->p.rgb.bpp;
+    }
+}
+
+/* packed YUV to packed RGB */
+static void convert_yuv_to_rgb (zbar_image_t *dst,
+                                const zbar_format_def_t *dstfmt,
+                                const zbar_image_t *src,
+                                const zbar_format_def_t *srcfmt)
+{
+    unsigned long dstn = dst->width * dst->height;
+    dst->datalen = dstn * dstfmt->p.rgb.bpp;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    uint8_t *dstp = (void*)dst->data;
+
+    int drbits = RGB_SIZE(dstfmt->p.rgb.red);
+    int drbit0 = RGB_OFFSET(dstfmt->p.rgb.red);
+    int dgbits = RGB_SIZE(dstfmt->p.rgb.green);
+    int dgbit0 = RGB_OFFSET(dstfmt->p.rgb.green);
+    int dbbits = RGB_SIZE(dstfmt->p.rgb.blue);
+    int dbbit0 = RGB_OFFSET(dstfmt->p.rgb.blue);
+
+    assert(src->datalen >= (src->width * src->height +
+                            uvp_size(src, srcfmt) * 2));
+    const uint8_t *srcp = src->data;
+    if(srcfmt->p.yuv.packorder & 2)
+        srcp++;
+
+    assert(srcfmt->p.yuv.xsub2 == 1);
+    unsigned srcl = src->width + (src->width >> 1);
+    unsigned x, y;
+    uint32_t p = 0;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            srcp -= srcl;
+        for(x = 0; x < dst->width; x++) {
+            if(x < src->width) {
+                uint8_t y0 = *(srcp++);
+                srcp++;
+
+                if(y0 <= 16)
+                    y0 = 0;
+                else if(y0 >= 235)
+                    y0 = 255;
+                else
+                    y0 = (uint16_t)(y0 - 16) * 255 / 219;
+
+                p = (((y0 >> drbits) << drbit0) |
+                     ((y0 >> dgbits) << dgbit0) |
+                     ((y0 >> dbbits) << dbbit0));
+            }
+            convert_write_rgb(dstp, p, dstfmt->p.rgb.bpp);
+            dstp += dstfmt->p.rgb.bpp;
+        }
+        if(x < src->width)
+            srcp += (src->width - x) * 2;
+    }
+}
+
+/* packed RGB to packed YUV
+ * FIXME currently ignores color and grayscales the image
+ */
+static void convert_rgb_to_yuv (zbar_image_t *dst,
+                                const zbar_format_def_t *dstfmt,
+                                const zbar_image_t *src,
+                                const zbar_format_def_t *srcfmt)
+{
+    uv_roundup(dst, dstfmt);
+    dst->datalen = dst->width * dst->height + uvp_size(dst, dstfmt) * 2;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    uint8_t *dstp = (void*)dst->data;
+    uint8_t flags = dstfmt->p.yuv.packorder & 2;
+
+    assert(src->datalen >= (src->width * src->height * srcfmt->p.rgb.bpp));
+    const uint8_t *srcp = src->data;
+
+    int rbits = RGB_SIZE(srcfmt->p.rgb.red);
+    int rbit0 = RGB_OFFSET(srcfmt->p.rgb.red);
+    int gbits = RGB_SIZE(srcfmt->p.rgb.green);
+    int gbit0 = RGB_OFFSET(srcfmt->p.rgb.green);
+    int bbits = RGB_SIZE(srcfmt->p.rgb.blue);
+    int bbit0 = RGB_OFFSET(srcfmt->p.rgb.blue);
+
+    unsigned srcl = src->width * srcfmt->p.rgb.bpp;
+    unsigned x, y;
+    uint16_t y0 = 0;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            srcp -= srcl;
+        for(x = 0; x < dst->width; x++) {
+            if(x < src->width) {
+                uint8_t r, g, b;
+                uint32_t p = convert_read_rgb(srcp, srcfmt->p.rgb.bpp);
+                srcp += srcfmt->p.rgb.bpp;
+
+                /* FIXME endianness? */
+                r = ((p >> rbit0) << rbits) & 0xff;
+                g = ((p >> gbit0) << gbits) & 0xff;
+                b = ((p >> bbit0) << bbits) & 0xff;
+
+                /* FIXME color space? */
+                y0 = ((77 * r + 150 * g + 29 * b) + 0x80) >> 8;
+            }
+            if(flags) {
+                *(dstp++) = 0x80;  *(dstp++) = y0;
+            }
+            else {
+                *(dstp++) = y0;  *(dstp++) = 0x80;
+            }
+        }
+        if(x < src->width)
+            srcp += (src->width - x) * srcfmt->p.rgb.bpp;
+    }
+}
+
+/* resample and resize packed RGB components */
+static void convert_rgb_resample (zbar_image_t *dst,
+                                  const zbar_format_def_t *dstfmt,
+                                  const zbar_image_t *src,
+                                  const zbar_format_def_t *srcfmt)
+{
+    unsigned long dstn = dst->width * dst->height;
+    dst->datalen = dstn * dstfmt->p.rgb.bpp;
+    dst->data = malloc(dst->datalen);
+    if(!dst->data) return;
+    uint8_t *dstp = (void*)dst->data;
+
+    int drbits = RGB_SIZE(dstfmt->p.rgb.red);
+    int drbit0 = RGB_OFFSET(dstfmt->p.rgb.red);
+    int dgbits = RGB_SIZE(dstfmt->p.rgb.green);
+    int dgbit0 = RGB_OFFSET(dstfmt->p.rgb.green);
+    int dbbits = RGB_SIZE(dstfmt->p.rgb.blue);
+    int dbbit0 = RGB_OFFSET(dstfmt->p.rgb.blue);
+
+    assert(src->datalen >= (src->width * src->height * srcfmt->p.rgb.bpp));
+    const uint8_t *srcp = src->data;
+
+    int srbits = RGB_SIZE(srcfmt->p.rgb.red);
+    int srbit0 = RGB_OFFSET(srcfmt->p.rgb.red);
+    int sgbits = RGB_SIZE(srcfmt->p.rgb.green);
+    int sgbit0 = RGB_OFFSET(srcfmt->p.rgb.green);
+    int sbbits = RGB_SIZE(srcfmt->p.rgb.blue);
+    int sbbit0 = RGB_OFFSET(srcfmt->p.rgb.blue);
+
+    unsigned srcl = src->width * srcfmt->p.rgb.bpp;
+    unsigned x, y;
+    uint32_t p = 0;
+    for(y = 0; y < dst->height; y++) {
+        if(y >= src->height)
+            y -= srcl;
+        for(x = 0; x < dst->width; x++) {
+            if(x < src->width) {
+                uint8_t r, g, b;
+                p = convert_read_rgb(srcp, srcfmt->p.rgb.bpp);
+                srcp += srcfmt->p.rgb.bpp;
+
+                /* FIXME endianness? */
+                r = (p >> srbit0) << srbits;
+                g = (p >> sgbit0) << sgbits;
+                b = (p >> sbbit0) << sbbits;
+
+                p = (((r >> drbits) << drbit0) |
+                     ((g >> dgbits) << dgbit0) |
+                     ((b >> dbbits) << dbbit0));
+            }
+            convert_write_rgb(dstp, p, dstfmt->p.rgb.bpp);
+            dstp += dstfmt->p.rgb.bpp;
+        }
+        if(x < src->width)
+            srcp += (src->width - x) * srcfmt->p.rgb.bpp;
+    }
+}
+
+#ifdef HAVE_LIBJPEG
+void _zbar_convert_jpeg_to_y(zbar_image_t *dst,
+                              const zbar_format_def_t *dstfmt,
+                              const zbar_image_t *src,
+                              const zbar_format_def_t *srcfmt);
+
+static void convert_jpeg(zbar_image_t *dst,
+                         const zbar_format_def_t *dstfmt,
+                         const zbar_image_t *src,
+                         const zbar_format_def_t *srcfmt);
+#endif
+
+/* group conversion matrix */
+static conversion_def_t conversions[][ZBAR_FMT_NUM] = {
+    { /* *from* GRAY */
+        {   0, convert_copy },           /* to GRAY */
+        {   8, convert_uvp_append },     /* to YUV_PLANAR */
+        {  24, convert_yuv_pack },       /* to YUV_PACKED */
+        {  32, convert_yuvp_to_rgb },    /* to RGB_PACKED */
+        {   8, convert_uvp_append },     /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+    { /* from YUV_PLANAR */
+        {   1, convert_copy },           /* to GRAY */
+        {  48, convert_uvp_resample },   /* to YUV_PLANAR */
+        {  64, convert_yuv_pack },       /* to YUV_PACKED */
+        { 128, convert_yuvp_to_rgb },    /* to RGB_PACKED */
+        {  40, convert_uvp_append },     /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+    { /* from YUV_PACKED */
+        {  24, convert_yuv_unpack },     /* to GRAY */
+        {  52, convert_yuv_unpack },     /* to YUV_PLANAR */
+        {  20, convert_uv_resample },    /* to YUV_PACKED */
+        { 144, convert_yuv_to_rgb },     /* to RGB_PACKED */
+        {  18, convert_yuv_unpack },     /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+    { /* from RGB_PACKED */
+        { 112, convert_rgb_to_yuvp },    /* to GRAY */
+        { 160, convert_rgb_to_yuvp },    /* to YUV_PLANAR */
+        { 144, convert_rgb_to_yuv },     /* to YUV_PACKED */
+        { 120, convert_rgb_resample },   /* to RGB_PACKED */
+        { 152, convert_rgb_to_yuvp },    /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+    { /* from YUV_NV (FIXME treated as GRAY) */
+        {   1, convert_copy },           /* to GRAY */
+        {   8, convert_uvp_append },     /* to YUV_PLANAR */
+        {  24, convert_yuv_pack },       /* to YUV_PACKED */
+        {  32, convert_yuvp_to_rgb },    /* to RGB_PACKED */
+        {   8, convert_uvp_append },     /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+#ifdef HAVE_LIBJPEG
+    { /* from JPEG */
+        {  96, _zbar_convert_jpeg_to_y }, /* to GRAY */
+        { 104, convert_jpeg },           /* to YUV_PLANAR */
+        { 116, convert_jpeg },           /* to YUV_PACKED */
+        { 256, convert_jpeg },           /* to RGB_PACKED */
+        { 104, convert_jpeg },           /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+#else
+    { /* from JPEG */
+        {  -1, NULL },                   /* to GRAY */
+        {  -1, NULL },                   /* to YUV_PLANAR */
+        {  -1, NULL },                   /* to YUV_PACKED */
+        {  -1, NULL },                   /* to RGB_PACKED */
+        {  -1, NULL },                   /* to YUV_NV */
+        {  -1, NULL },                   /* to JPEG */
+    },
+#endif
+};
+
+const zbar_format_def_t *_zbar_format_lookup (uint32_t fmt)
+{
+    const zbar_format_def_t *def = NULL;
+    int i = 0;
+    while(i < num_format_defs) {
+        def = &format_defs[i];
+        if(fmt == def->format)
+            return(def);
+        i = i * 2 + 1;
+        if(fmt > def->format)
+            i++;
+    }
+    return(NULL);
+}
+
+#ifdef HAVE_LIBJPEG
+/* convert JPEG data via an intermediate format supported by libjpeg */
+static void convert_jpeg (zbar_image_t *dst,
+                          const zbar_format_def_t *dstfmt,
+                          const zbar_image_t *src,
+                          const zbar_format_def_t *srcfmt)
+{
+    /* define intermediate image in a format supported by libjpeg
+     * (currently only grayscale)
+     */
+    zbar_image_t *tmp;
+    if(!src->src) {
+        tmp = zbar_image_create();
+        tmp->format = fourcc('Y','8','0','0');
+        tmp->width = dst->width;
+        tmp->height = dst->height;
+    }
+    else {
+        tmp = src->src->jpeg_img;
+        assert(tmp);
+        dst->width = tmp->width;
+        dst->height = tmp->height;
+    }
+
+    const zbar_format_def_t *tmpfmt = _zbar_format_lookup(tmp->format);
+    assert(tmpfmt);
+
+    /* convert to intermediate format */
+    _zbar_convert_jpeg_to_y(tmp, tmpfmt, src, srcfmt);
+
+    /* now convert to dst */
+    dst->width = tmp->width;
+    dst->height = tmp->height;
+
+    conversion_handler_t *func =
+        conversions[tmpfmt->group][dstfmt->group].func;
+
+    func(dst, dstfmt, tmp, tmpfmt);
+
+    if(!src->src)
+        zbar_image_destroy(tmp);
+}
+#endif
+
+zbar_image_t *zbar_image_convert_resize (const zbar_image_t *src,
+                                         unsigned long fmt,
+                                         unsigned width,
+                                         unsigned height)
+{
+    zbar_image_t *dst = zbar_image_create();
+    dst->format = fmt;
+    dst->width = width;
+    dst->height = height;
+    if(src->format == fmt &&
+       src->width == width &&
+       src->height == height) {
+        convert_copy(dst, NULL, src, NULL);
+        return(dst);
+    }
+
+    const zbar_format_def_t *srcfmt = _zbar_format_lookup(src->format);
+    const zbar_format_def_t *dstfmt = _zbar_format_lookup(dst->format);
+    if(!srcfmt || !dstfmt)
+        /* FIXME free dst */
+        return(NULL);
+
+    if(srcfmt->group == dstfmt->group &&
+       srcfmt->p.cmp == dstfmt->p.cmp &&
+       src->width == width &&
+       src->height == height) {
+        convert_copy(dst, NULL, src, NULL);
+        return(dst);
+    }
+
+    conversion_handler_t *func =
+        conversions[srcfmt->group][dstfmt->group].func;
+
+    dst->cleanup = zbar_image_free_data;
+    func(dst, dstfmt, src, srcfmt);
+    if(!dst->data) {
+        /* conversion failed */
+        zbar_image_destroy(dst);
+        return(NULL);
+    }
+    return(dst);
+}
+
+zbar_image_t *zbar_image_convert (const zbar_image_t *src,
+                                  unsigned long fmt)
+{
+    return(zbar_image_convert_resize(src, fmt, src->width, src->height));
+}
+
+static inline int has_format (uint32_t fmt,
+                              const uint32_t *fmts)
+{
+    for(; *fmts; fmts++)
+        if(*fmts == fmt)
+            return(1);
+    return(0);
+}
+
+/* select least cost conversion from src format to available dsts */
+int _zbar_best_format (uint32_t src,
+                       uint32_t *dst,
+                       const uint32_t *dsts)
+{
+    if(dst)
+        *dst = 0;
+    if(!dsts)
+        return(-1);
+    if(has_format(src, dsts)) {
+        zprintf(8, "shared format: %4.4s\n", (char*)&src);
+        if(dst)
+            *dst = src;
+        return(0);
+    }
+    const zbar_format_def_t *srcfmt = _zbar_format_lookup(src);
+    if(!srcfmt)
+        return(-1);
+
+    zprintf(8, "from %.4s(%08" PRIx32 ") to", (char*)&src, src);
+    unsigned min_cost = -1;
+    for(; *dsts; dsts++) {
+        const zbar_format_def_t *dstfmt = _zbar_format_lookup(*dsts);
+        if(!dstfmt)
+            continue;
+        int cost;
+        if(srcfmt->group == dstfmt->group &&
+           srcfmt->p.cmp == dstfmt->p.cmp)
+            cost = 0;
+        else
+            cost = conversions[srcfmt->group][dstfmt->group].cost;
+
+#if 0
+        if(_zbar_verbosity >= 8)
+            fprintf(stderr, " %.4s(%08" PRIx32 ")=%d",
+                    (char*)dsts, *dsts, cost);
+#endif
+        if(cost >= 0 && min_cost > cost) {
+            min_cost = cost;
+            if(dst)
+                *dst = *dsts;
+        }
+    }
+#if 0
+    if(_zbar_verbosity >= 8)
+        fprintf(stderr, "\n");
+#endif
+    return(min_cost);
+}
+
+int zbar_negotiate_format (zbar_video_t *vdo,
+                           zbar_window_t *win)
+{
+    if(!vdo && !win)
+        return(0);
+
+    if(win)
+        (void)window_lock(win);
+
+    errinfo_t *errdst = (vdo) ? &vdo->err : &win->err;
+    if(verify_format_sort()) {
+        if(win)
+            (void)window_unlock(win);
+        return(err_capture(errdst, SEV_FATAL, ZBAR_ERR_INTERNAL, __func__,
+                           "image format list is not sorted!?"));
+    }
+
+    if((vdo && !vdo->formats) || (win && !win->formats)) {
+        if(win)
+            (void)window_unlock(win);
+        return(err_capture(errdst, SEV_ERROR, ZBAR_ERR_UNSUPPORTED, __func__,
+                           "no input or output formats available"));
+    }
+
+    static const uint32_t y800[2] = { fourcc('Y','8','0','0'), 0 };
+    const uint32_t *srcs = (vdo) ? vdo->formats : y800;
+    const uint32_t *dsts = (win) ? win->formats : y800;
+
+    unsigned min_cost = -1;
+    uint32_t min_fmt = 0;
+    const uint32_t *fmt;
+    for(fmt = _zbar_formats; *fmt; fmt++) {
+        /* only consider formats supported by video device */
+        if(!has_format(*fmt, srcs))
+            continue;
+        uint32_t win_fmt = 0;
+        int cost = _zbar_best_format(*fmt, &win_fmt, dsts);
+        if(cost < 0) {
+            zprintf(4, "%.4s(%08" PRIx32 ") -> ? (unsupported)\n",
+                    (char*)fmt, *fmt);
+            continue;
+        }
+        zprintf(4, "%.4s(%08" PRIx32 ") -> %.4s(%08" PRIx32 ") (%d)\n",
+                (char*)fmt, *fmt, (char*)&win_fmt, win_fmt, cost);
+        if(min_cost > cost) {
+            min_cost = cost;
+            min_fmt = *fmt;
+            if(!cost)
+                break;
+        }
+    }
+    if(win)
+        (void)window_unlock(win);
+
+    if(!min_fmt)
+        return(err_capture(errdst, SEV_ERROR, ZBAR_ERR_UNSUPPORTED, __func__,
+                           "no supported image formats available"));
+    if(!vdo)
+        return(0);
+
+    zprintf(2, "setting best format %.4s(%08" PRIx32 ") (%d)\n",
+            (char*)&min_fmt, min_fmt, min_cost);
+    return(zbar_video_init(vdo, min_fmt));
+}

+ 402 - 0
Third_Party/ZBAR/src/decoder.c

@@ -0,0 +1,402 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <config.h>
+//#include <stdlib.h>     /* malloc, calloc, free */
+#include <stdio.h>      /* snprintf */
+#include <string.h>     /* memset, strlen */
+
+#include <zbar.h>
+#include "decoder.h"
+#include "zbar_config.h"
+#if defined(DEBUG_DECODER) || defined(DEBUG_EAN) ||             \
+    defined(DEBUG_CODE39) || defined(DEBUG_I25) ||              \
+    defined(DEBUG_CODE128) || defined(DEBUG_QR_FINDER) ||       \
+    (defined(DEBUG_PDF417) && (DEBUG_PDF417 >= 4))
+//# define DEBUG_LEVEL 1
+#endif
+#include "debug.h"
+
+zbar_decoder_t *zbar_decoder_create ()
+{
+    zbar_decoder_t *dcode = calloc(1, sizeof(zbar_decoder_t));
+    dcode->buf_alloc = BUFFER_MIN;
+    dcode->buf = malloc(dcode->buf_alloc);
+
+    /* initialize default configs */
+#ifdef ENABLE_EAN
+    dcode->ean.enable = 1;
+    dcode->ean.ean13_config = ((1 << ZBAR_CFG_ENABLE) |
+                               (1 << ZBAR_CFG_EMIT_CHECK));
+    dcode->ean.ean8_config = ((1 << ZBAR_CFG_ENABLE) |
+                              (1 << ZBAR_CFG_EMIT_CHECK));
+    dcode->ean.upca_config = 1 << ZBAR_CFG_EMIT_CHECK;
+    dcode->ean.upce_config = 1 << ZBAR_CFG_EMIT_CHECK;
+    dcode->ean.isbn10_config = 1 << ZBAR_CFG_EMIT_CHECK;
+    dcode->ean.isbn13_config = 1 << ZBAR_CFG_EMIT_CHECK;
+#endif
+#ifdef ENABLE_I25
+    dcode->i25.config = 1 << ZBAR_CFG_ENABLE;
+    CFG(dcode->i25, ZBAR_CFG_MIN_LEN) = 6;
+#endif
+#ifdef ENABLE_CODE39
+    dcode->code39.config = 1 << ZBAR_CFG_ENABLE;
+    CFG(dcode->code39, ZBAR_CFG_MIN_LEN) = 1;
+#endif
+#ifdef ENABLE_CODE128
+    dcode->code128.config = 1 << ZBAR_CFG_ENABLE;
+#endif
+#ifdef ENABLE_PDF417
+    dcode->pdf417.config = 1 << ZBAR_CFG_ENABLE;
+#endif
+#ifdef ENABLE_QRCODE
+    dcode->qrf.config = 1 << ZBAR_CFG_ENABLE;
+#endif
+
+    zbar_decoder_reset(dcode);
+    return(dcode);
+}
+
+void zbar_decoder_destroy (zbar_decoder_t *dcode)
+{
+    if(dcode->buf)
+        free(dcode->buf);
+    free(dcode);
+}
+
+void zbar_decoder_reset (zbar_decoder_t *dcode)
+{
+    memset(dcode, 0, (long)&dcode->buf_alloc - (long)dcode);
+#ifdef ENABLE_EAN
+    ean_reset(&dcode->ean);
+#endif
+#ifdef ENABLE_I25
+    i25_reset(&dcode->i25);
+#endif
+#ifdef ENABLE_CODE39
+    code39_reset(&dcode->code39);
+#endif
+#ifdef ENABLE_CODE128
+    code128_reset(&dcode->code128);
+#endif
+#ifdef ENABLE_PDF417
+    pdf417_reset(&dcode->pdf417);
+#endif
+#ifdef ENABLE_QRCODE
+    qr_finder_reset(&dcode->qrf);
+#endif
+}
+
+void zbar_decoder_new_scan (zbar_decoder_t *dcode)
+{
+    /* soft reset decoder */
+    memset(dcode->w, 0, sizeof(dcode->w));
+    dcode->lock = 0;
+    dcode->idx = 0;
+#ifdef ENABLE_EAN
+    ean_new_scan(&dcode->ean);
+#endif
+#ifdef ENABLE_I25
+    i25_reset(&dcode->i25);
+#endif
+#ifdef ENABLE_CODE39
+    code39_reset(&dcode->code39);
+#endif
+#ifdef ENABLE_CODE128
+    code128_reset(&dcode->code128);
+#endif
+#ifdef ENABLE_PDF417
+    pdf417_reset(&dcode->pdf417);
+#endif
+#ifdef ENABLE_QRCODE
+    qr_finder_reset(&dcode->qrf);
+#endif
+}
+
+
+zbar_color_t zbar_decoder_get_color (const zbar_decoder_t *dcode)
+{
+    return(get_color(dcode));
+}
+
+const char *zbar_decoder_get_data (const zbar_decoder_t *dcode)
+{
+    return((char*)dcode->buf);
+}
+
+unsigned int zbar_decoder_get_data_length (const zbar_decoder_t *dcode)
+{
+    return(dcode->buflen);
+}
+
+zbar_decoder_handler_t *
+zbar_decoder_set_handler (zbar_decoder_t *dcode,
+                          zbar_decoder_handler_t handler)
+{
+    zbar_decoder_handler_t *result = dcode->handler;
+    dcode->handler = handler;
+    return(result);
+}
+
+void zbar_decoder_set_userdata (zbar_decoder_t *dcode,
+                                void *userdata)
+{
+    dcode->userdata = userdata;
+}
+
+void *zbar_decoder_get_userdata (const zbar_decoder_t *dcode)
+{
+    return(dcode->userdata);
+}
+
+zbar_symbol_type_t zbar_decoder_get_type (const zbar_decoder_t *dcode)
+{
+    return(dcode->type);
+}
+
+zbar_symbol_type_t zbar_decode_width (zbar_decoder_t *dcode,
+                                      unsigned w)
+{
+    dcode->w[dcode->idx & (DECODE_WINDOW - 1)] = w;
+    dprintf(1, "    decode[%x]: w=%d (%g)\n", dcode->idx, w, (w / 32.));
+
+    /* each decoder processes width stream in parallel */
+    zbar_symbol_type_t sym = dcode->type = ZBAR_NONE;
+    
+#ifdef ENABLE_EAN
+    if((dcode->ean.enable) &&
+       (sym = _zbar_decode_ean(dcode)))
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_CODE39
+    if(TEST_CFG(dcode->code39.config, ZBAR_CFG_ENABLE) &&
+       (sym = _zbar_decode_code39(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_CODE128
+    if(TEST_CFG(dcode->code128.config, ZBAR_CFG_ENABLE) &&
+       (sym = _zbar_decode_code128(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_I25
+    if(TEST_CFG(dcode->i25.config, ZBAR_CFG_ENABLE) &&
+       (sym = _zbar_decode_i25(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_PDF417
+    if(TEST_CFG(dcode->pdf417.config, ZBAR_CFG_ENABLE) &&
+       (sym = _zbar_decode_pdf417(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_QRCODE
+    if(TEST_CFG(dcode->qrf.config, ZBAR_CFG_ENABLE) &&
+       (sym = _zbar_find_qr(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+
+    dcode->idx++;
+    if(dcode->type) {
+        if(dcode->handler)
+            dcode->handler(dcode);
+        if(dcode->lock && dcode->type > ZBAR_PARTIAL)
+            dcode->lock = 0;
+    }
+
+    return(dcode->type);
+}
+
+static inline int decoder_set_config_bool (zbar_decoder_t *dcode,
+                                           zbar_symbol_type_t sym,
+                                           zbar_config_t cfg,
+                                           int val)
+{
+    unsigned *config = NULL;
+    switch(sym) {
+#ifdef ENABLE_EAN
+    case ZBAR_EAN13:
+        config = &dcode->ean.ean13_config;
+        break;
+
+    case ZBAR_EAN8:
+        config = &dcode->ean.ean8_config;
+        break;
+
+    case ZBAR_UPCA:
+        config = &dcode->ean.upca_config;
+        break;
+
+    case ZBAR_UPCE:
+        config = &dcode->ean.upce_config;
+        break;
+
+    case ZBAR_ISBN10:
+        config = &dcode->ean.isbn10_config;
+        break;
+
+    case ZBAR_ISBN13:
+        config = &dcode->ean.isbn13_config;
+        break;
+#endif
+
+#ifdef ENABLE_I25
+    case ZBAR_I25:
+        config = &dcode->i25.config;
+        break;
+#endif
+
+#ifdef ENABLE_CODE39
+    case ZBAR_CODE39:
+        config = &dcode->code39.config;
+        break;
+#endif
+
+#ifdef ENABLE_CODE128
+    case ZBAR_CODE128:
+        config = &dcode->code128.config;
+        break;
+#endif
+
+#ifdef ENABLE_PDF417
+    case ZBAR_PDF417:
+        config = &dcode->pdf417.config;
+        break;
+#endif
+
+#ifdef ENABLE_QRCODE
+    case ZBAR_QRCODE:
+        config = &dcode->qrf.config;
+        break;
+#endif
+
+    /* FIXME handle addons */
+
+    default:
+        return(1);
+    }
+    if(!config || cfg >= ZBAR_CFG_NUM)
+        return(1);
+
+    if(!val)
+        *config &= ~(1 << cfg);
+    else if(val == 1)
+        *config |= (1 << cfg);
+    else
+        return(1);
+
+#ifdef ENABLE_EAN
+    dcode->ean.enable = TEST_CFG(dcode->ean.ean13_config |
+                                 dcode->ean.ean8_config |
+                                 dcode->ean.upca_config |
+                                 dcode->ean.upce_config |
+                                 dcode->ean.isbn10_config |
+                                 dcode->ean.isbn13_config,
+                                 ZBAR_CFG_ENABLE);
+#endif
+
+    return(0);
+}
+
+static inline int decoder_set_config_int (zbar_decoder_t *dcode,
+                                          zbar_symbol_type_t sym,
+                                          zbar_config_t cfg,
+                                          int val)
+{
+    switch(sym) {
+
+#ifdef ENABLE_I25
+    case ZBAR_I25:
+        CFG(dcode->i25, cfg) = val;
+        break;
+#endif
+#ifdef ENABLE_CODE39
+    case ZBAR_CODE39:
+        CFG(dcode->code39, cfg) = val;
+        break;
+#endif
+#ifdef ENABLE_CODE128
+    case ZBAR_CODE128:
+        CFG(dcode->code128, cfg) = val;
+        break;
+#endif
+#ifdef ENABLE_PDF417
+    case ZBAR_PDF417:
+        CFG(dcode->pdf417, cfg) = val;
+        break;
+#endif
+
+    default:
+        return(1);
+    }
+    return(0);
+}
+
+int zbar_decoder_set_config (zbar_decoder_t *dcode,
+                             zbar_symbol_type_t sym,
+                             zbar_config_t cfg,
+                             int val)
+{
+    if(sym == ZBAR_NONE) {
+        zbar_decoder_set_config(dcode, ZBAR_EAN13, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_EAN8, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_UPCA, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_UPCE, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_ISBN10, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_ISBN13, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_I25, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_CODE39, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_CODE128, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_PDF417, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_QRCODE, cfg, val);
+        return(0);
+    }
+
+    if(cfg >= 0 && cfg < ZBAR_CFG_NUM)
+        return(decoder_set_config_bool(dcode, sym, cfg, val));
+    else if(cfg >= ZBAR_CFG_MIN_LEN && cfg <= ZBAR_CFG_MAX_LEN)
+        return(decoder_set_config_int(dcode, sym, cfg, val));
+    else
+        return(1);
+}
+
+
+static char *decoder_dump = NULL;
+static unsigned decoder_dumplen = 0;
+
+const char *_zbar_decoder_buf_dump (unsigned char *buf,
+                                    unsigned int buflen)
+{
+    int dumplen = (buflen * 3) + 12;
+    if(!decoder_dump || dumplen > decoder_dumplen) {
+        if(decoder_dump)
+            free(decoder_dump);
+        decoder_dump = malloc(dumplen);
+        decoder_dumplen = dumplen;
+    }
+    char *p = decoder_dump +
+        snprintf(decoder_dump, 12, "buf[%04x]=",
+                 (buflen > 0xffff) ? 0xffff : buflen);
+    int i;
+    for(i = 0; i < buflen; i++)
+        p += snprintf(p, 4, "%s%02x", (i) ? " " : "",  buf[i]);
+    return(decoder_dump);
+}

+ 182 - 0
Third_Party/ZBAR/src/error.c

@@ -0,0 +1,182 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include "error.h"
+#include <string.h>
+
+int _zbar_verbosity = 0;
+
+static const char * const sev_str[] = {
+    "FATAL ERROR", "ERROR", "OK", "WARNING", "NOTE"
+};
+#define SEV_MAX (strlen(sev_str[0]))
+
+static const char * const mod_str[] = {
+    "processor", "video", "window", "image scanner", "<unknown>"
+};
+#define MOD_MAX (strlen(mod_str[ZBAR_MOD_IMAGE_SCANNER]))
+
+static const char const * err_str[] = {
+    "no error",                 /* OK */
+    "out of memory",            /* NOMEM */
+    "internal library error",   /* INTERNAL */
+    "unsupported request",      /* UNSUPPORTED */
+    "invalid request",          /* INVALID */
+    "system error",             /* SYSTEM */
+    "locking error",            /* LOCKING */
+    "all resources busy",       /* BUSY */
+    "X11 display error",        /* XDISPLAY */
+    "X11 protocol error",       /* XPROTO */
+    "output window is closed",  /* CLOSED */
+    "windows system error",     /* WINAPI */
+    "unknown error"             /* NUM */
+};
+#define ERR_MAX (strlen(err_str[ZBAR_ERR_CLOSED]))
+
+#define ZBAR_VERSION_MAJOR 1
+#define ZBAR_VERSION_MINOR 0
+
+int zbar_version (unsigned *major,
+                  unsigned *minor)
+{
+    if(major)
+        *major = ZBAR_VERSION_MAJOR;
+    if(minor)
+        *minor = ZBAR_VERSION_MINOR;
+    return(0);
+}
+
+void zbar_set_verbosity (int level)
+{
+    _zbar_verbosity = level;
+}
+
+void zbar_increase_verbosity ()
+{
+    if(!_zbar_verbosity)
+        _zbar_verbosity++;
+    else
+        _zbar_verbosity <<= 1;
+}
+
+int _zbar_error_spew (const void *container,
+                      int verbosity)
+{
+    const errinfo_t *err = container;
+    assert(err->magic == ERRINFO_MAGIC);
+ //   fprintf(stderr, "%s", _zbar_error_string(err, verbosity));
+    return(-err->sev);
+}
+
+zbar_error_t _zbar_get_error_code (const void *container)
+{
+    const errinfo_t *err = container;
+    assert(err->magic == ERRINFO_MAGIC);
+    return(err->type);
+}
+
+/* ERROR: zbar video in v4l1_set_format():
+ *     system error: blah[: blah]
+ */
+
+const char *_zbar_error_string (const void *container,
+                                int verbosity)
+{
+    errinfo_t *err = (errinfo_t*)container;
+    assert(err->magic == ERRINFO_MAGIC);
+
+    const char *sev;
+    if(err->sev >= SEV_FATAL && err->sev <= SEV_NOTE)
+        sev = sev_str[err->sev + 2];
+    else
+        sev = sev_str[1];
+
+    const char *mod;
+    if(err->module >= ZBAR_MOD_PROCESSOR &&
+       err->module < ZBAR_MOD_UNKNOWN)
+        mod = mod_str[err->module];
+    else
+        mod = mod_str[ZBAR_MOD_UNKNOWN];
+
+    const char *func = (err->func) ? err->func : "<unknown>";
+
+    const char *type;
+    if(err->type >= 0 && err->type < ZBAR_ERR_NUM)
+        type = err_str[err->type];
+    else
+        type = err_str[ZBAR_ERR_NUM];
+
+    char basefmt[] = "%s: zbar %s in %s():\n    %s: ";
+    int len = SEV_MAX + MOD_MAX + ERR_MAX + strlen(func) + sizeof(basefmt);
+    err->buf = realloc(err->buf, len);
+    len = sprintf(err->buf, basefmt, sev, mod, func, type);
+    if(len <= 0)
+        return("<unknown>");
+
+    if(err->detail) {
+        int newlen = len + strlen(err->detail) + 1;
+        if(strstr(err->detail, "%s")) {
+            if(!err->arg_str)
+                err->arg_str = strdup("<?>");
+            err->buf = realloc(err->buf, newlen + strlen(err->arg_str));
+            len += sprintf(err->buf + len, err->detail, err->arg_str);
+        }
+        else if(strstr(err->detail, "%d") || strstr(err->detail, "%x")) {
+            err->buf = realloc(err->buf, newlen + 32);
+            len += sprintf(err->buf + len, err->detail, err->arg_int);
+        }
+        else {
+            err->buf = realloc(err->buf, newlen);
+            len += sprintf(err->buf + len, "%s", err->detail);
+        }
+        if(len <= 0)
+            return("<unknown>");
+    }
+
+    if(err->type == ZBAR_ERR_SYSTEM) {
+        char sysfmt[] = ": %s (%d)\n";
+        const char *syserr = strerror(err->errnum);
+        err->buf = realloc(err->buf, len + strlen(sysfmt) + strlen(syserr));
+        len += sprintf(err->buf + len, sysfmt, syserr, err->errnum);
+    }
+#ifdef _WIN32
+    else if(err->type == ZBAR_ERR_WINAPI) {
+        char *syserr = NULL;
+        if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                         FORMAT_MESSAGE_IGNORE_INSERTS,
+                         NULL, err->errnum, 0, (LPTSTR)&syserr, 1, NULL) &&
+           syserr) {
+            char sysfmt[] = ": %s (%d)\n";
+            err->buf = realloc(err->buf, len + strlen(sysfmt) + strlen(syserr));
+            len += sprintf(err->buf + len, sysfmt, syserr, err->errnum);
+            LocalFree(syserr);
+        }
+    }
+#endif
+    else {
+        err->buf = realloc(err->buf, len + 2);
+        len += sprintf(err->buf + len, "\n");
+    }
+    return(err->buf);
+}

+ 308 - 0
Third_Party/ZBAR/src/image.c

@@ -0,0 +1,308 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include "error.h"
+#include "image.h"
+#include "refcnt.h"
+
+zbar_image_t *zbar_image_create ()
+{
+    zbar_image_t *img = calloc(1, sizeof(zbar_image_t));
+    _zbar_refcnt_init();
+    _zbar_image_refcnt(img, 1);
+    img->srcidx = -1;
+    return(img);
+}
+
+void _zbar_image_free (zbar_image_t *img)
+{
+    if(img->syms) {
+        zbar_symbol_set_ref(img->syms, -1);
+        img->syms = NULL;
+    }
+    free(img);
+}
+
+void zbar_image_destroy (zbar_image_t *img)
+{
+    _zbar_image_refcnt(img, -1);
+}
+
+void zbar_image_ref (zbar_image_t *img,
+                     int refs)
+{
+    _zbar_image_refcnt(img, refs);
+}
+
+unsigned long zbar_image_get_format (const zbar_image_t *img)
+{
+    return(img->format);
+}
+
+unsigned zbar_image_get_sequence (const zbar_image_t *img)
+{
+    return(img->seq);
+}
+
+unsigned zbar_image_get_width (const zbar_image_t *img)
+{
+    return(img->width);
+}
+
+unsigned zbar_image_get_height (const zbar_image_t *img)
+{
+    return(img->height);
+}
+
+const void *zbar_image_get_data (const zbar_image_t *img)
+{
+    return(img->data);
+}
+
+unsigned long zbar_image_get_data_length (const zbar_image_t *img)
+{
+    return(img->datalen);
+}
+
+void zbar_image_set_format (zbar_image_t *img,
+                            unsigned long fmt)
+{
+    img->format = fmt;
+}
+
+void zbar_image_set_sequence (zbar_image_t *img,
+                              unsigned seq)
+{
+    img->seq = seq;
+}
+
+void zbar_image_set_size (zbar_image_t *img,
+                          unsigned w,
+                          unsigned h)
+{
+    img->width = w;
+    img->height = h;
+}
+
+inline void zbar_image_free_data (zbar_image_t *img)
+{
+    if(!img)
+        return;
+    if(img->src) {
+        /* replace video image w/new copy */
+        assert(img->refcnt); /* FIXME needs lock */
+        zbar_image_t *newimg = zbar_image_create();
+        memcpy(newimg, img, sizeof(zbar_image_t));
+        /* recycle video image */
+        newimg->cleanup(newimg);
+        /* detach old image from src */
+        img->cleanup = NULL;
+        img->src = NULL;
+        img->srcidx = -1;
+    }
+    else if(img->cleanup && img->data) {
+        if(img->cleanup != zbar_image_free_data) {
+            /* using function address to detect this case is a bad idea;
+             * windows link libraries add an extra layer of indirection...
+             * this works around that problem (bug #2796277)
+             */
+            zbar_image_cleanup_handler_t *cleanup = img->cleanup;
+            img->cleanup = zbar_image_free_data;
+            cleanup(img);
+        }
+        else
+        {
+        	#ifdef ZBAR_TODO
+            free((void*)img->data);
+			#endif
+        }
+    }
+    img->data = NULL;
+}
+
+void zbar_image_set_data (zbar_image_t *img,
+                          const void *data,
+                          unsigned long len,
+                          zbar_image_cleanup_handler_t *cleanup)
+{
+    zbar_image_free_data(img);
+    img->data = data;
+    img->datalen = len;
+    img->cleanup = cleanup;
+}
+
+void zbar_image_set_userdata (zbar_image_t *img,
+                              void *userdata)
+{
+    img->userdata = userdata;
+}
+
+void *zbar_image_get_userdata (const zbar_image_t *img)
+{
+    return(img->userdata);
+}
+
+zbar_image_t *zbar_image_copy (const zbar_image_t *src)
+{
+    zbar_image_t *dst = zbar_image_create();
+    dst->format = src->format;
+    dst->width = src->width;
+    dst->height = src->height;
+    dst->datalen = src->datalen;
+    dst->data = malloc(src->datalen);
+    assert(dst->data);
+    memcpy((void*)dst->data, src->data, src->datalen);
+    dst->cleanup = zbar_image_free_data;
+    return(dst);
+}
+
+const zbar_symbol_set_t *zbar_image_get_symbols (const zbar_image_t *img)
+{
+    return(img->syms);
+}
+
+void zbar_image_set_symbols (zbar_image_t *img,
+                             const zbar_symbol_set_t *syms)
+{
+    if(img->syms)
+        zbar_symbol_set_ref(img->syms, -1);
+    img->syms = (zbar_symbol_set_t*)syms;
+    if(syms)
+        zbar_symbol_set_ref(img->syms, 1);
+}
+
+const zbar_symbol_t *zbar_image_first_symbol (const zbar_image_t *img)
+{
+    return((img->syms) ? img->syms->head : NULL);
+}
+
+typedef struct zimg_hdr_s {
+    uint32_t magic, format;
+    uint16_t width, height;
+    uint32_t size;
+} zimg_hdr_t;
+
+#if 0
+int zbar_image_write (const zbar_image_t *img,
+                      const char *filebase)
+{
+    int len = strlen(filebase) + 16;
+    char filename[255];
+    strcpy(filename, filebase);
+    int n = 0;
+    if(*(char*)&img->format >= ' ')
+        n = snprintf(filename, len, "%s.%.4s.zimg",
+                     filebase, (char*)&img->format);
+    else
+        n = snprintf(filename, len, "%s.%08" PRIx32 ".zimg",
+                     filebase, img->format);
+    assert(n < len);
+    filename[len] = '\0';
+
+    zprintf(1, "dumping %.4s(%08" PRIx32 ") image to %s\n",
+            (char*)&img->format, img->format, filename);
+
+    FILE *f = fopen(filename, "w");
+    if(!f) {
+        int rc = errno;
+        zprintf(1, "ERROR opening %s: %s\n", filename, strerror(rc));
+        return(rc);
+    }
+
+    zimg_hdr_t hdr;
+    hdr.magic = 0x676d697a;
+    hdr.format = img->format;
+    hdr.width = img->width;
+    hdr.height = img->height;
+    hdr.size = img->datalen;
+
+    if(fwrite(&hdr, sizeof(hdr), 1, f) != 1 ||
+       fwrite(img->data, 1, img->datalen, f) != img->datalen) {
+        int rc = errno;
+        zprintf(1, "ERROR writing %s: %s\n", filename, strerror(rc));
+        fclose(f);
+        return(rc);
+    }
+    return(fclose(f));
+}
+#endif
+
+#ifdef DEBUG_SVG
+# include <png.h>
+
+int zbar_image_write_png (const zbar_image_t *img,
+                          const char *filename)
+{
+    int rc = -1;
+    FILE *file = NULL;
+    png_struct *png = NULL;
+    png_info *info = NULL;
+    const uint8_t **rows = NULL;
+
+    rows = malloc(img->height * sizeof(*rows));
+    if(!rows)
+        goto done;
+
+    rows[0] = img->data;
+    int y;
+    for(y = 1; y < img->height; y++)
+        rows[y] = rows[y - 1] + img->width;
+
+    file = fopen(filename, "wb");
+    if(!file)
+        goto done;
+
+    png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if(!png)
+        goto done;
+
+    info = png_create_info_struct(png);
+    if(!info)
+        goto done;
+
+    if(setjmp(png_jmpbuf(png)))
+        goto done;
+
+    png_init_io(png, file);
+    png_set_compression_level(png, 9);
+    png_set_IHDR(png, info, img->width, img->height, 8, PNG_COLOR_TYPE_GRAY,
+                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+                 PNG_FILTER_TYPE_DEFAULT);
+
+    png_set_rows(png, info, (void*)rows);
+    png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
+
+    png_write_end(png,info);
+    rc = 0;
+
+done:
+    if(png)
+        png_destroy_write_struct(&png, &info);
+    if(rows)
+        free(rows);
+    if(file)
+        fclose(file);
+    return(rc);
+}
+
+#endif

+ 792 - 0
Third_Party/ZBAR/src/img_scanner.c

@@ -0,0 +1,792 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <zbar_config.h>
+//#include <unistd.h>
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+//#include <stdlib.h>     /* malloc, free */
+#include <time.h>       /* clock_gettime */
+//#include <sys/time.h>   /* gettimeofday */
+#include <string.h>     /* memcmp, memset, memcpy */
+//#include <assert.h>
+
+#include <zbar.h>
+#include "error.h"
+#include "image.h"
+#ifdef ENABLE_QRCODE
+# include "qrcode.h"
+#endif
+#include "img_scanner.h"
+#include "svg.h"
+
+#ifdef ZBAR_TODO
+typedef unsigned int   intptr_t;//sheen
+#endif
+
+#if 1
+# define ASSERT_POS \
+    assert(p == data + x + y * (intptr_t)w)
+#else
+# define ASSERT_POS
+#endif
+
+/* FIXME cache setting configurability */
+
+/* number of times the same result must be detected
+ * in "nearby" images before being reported
+ */
+#define CACHE_CONSISTENCY    3 /* images */
+
+/* time interval for which two images are considered "nearby"
+ */
+#define CACHE_PROXIMITY   1000 /* ms */
+
+/* time that a result must *not* be detected before
+ * it will be reported again
+ */
+#define CACHE_HYSTERESIS  2000 /* ms */
+
+/* time after which cache entries are invalidated
+ */
+#define CACHE_TIMEOUT     (CACHE_HYSTERESIS * 2) /* ms */
+
+#define NUM_SCN_CFGS (ZBAR_CFG_Y_DENSITY - ZBAR_CFG_X_DENSITY + 1)
+
+#define CFG(iscn, cfg) ((iscn)->configs[(cfg) - ZBAR_CFG_X_DENSITY])
+#define TEST_CFG(iscn, cfg) (((iscn)->config >> ((cfg) - ZBAR_CFG_POSITION)) & 1)
+
+#ifndef NO_STATS
+# define STAT(x) iscn->stat_##x++
+#else
+# define STAT(...)
+# define dump_stats(...)
+#endif
+
+#define RECYCLE_BUCKETS     5
+
+typedef struct recycle_bucket_s {
+    int nsyms;
+    zbar_symbol_t *head;
+} recycle_bucket_t;
+
+/* image scanner state */
+struct zbar_image_scanner_s {
+    zbar_scanner_t *scn;        /* associated linear intensity scanner */
+    zbar_decoder_t *dcode;      /* associated symbol decoder */
+#ifdef ENABLE_QRCODE
+    qr_reader *qr;              /* QR Code 2D reader */
+#endif
+
+    const void *userdata;       /* application data */
+    /* user result callback */
+    zbar_image_data_handler_t *handler;
+
+    unsigned long time;         /* scan start time */
+    zbar_image_t *img;          /* currently scanning image *root* */
+    int dx, dy, du, umin, v;    /* current scan direction */
+    zbar_symbol_set_t *syms;    /* previous decode results */
+    /* recycled symbols in 4^n size buckets */
+    recycle_bucket_t recycle[RECYCLE_BUCKETS];
+
+    int enable_cache;           /* current result cache state */
+    zbar_symbol_t *cache;       /* inter-image result cache entries */
+
+    /* configuration settings */
+    unsigned config;            /* config flags */
+    int configs[NUM_SCN_CFGS];  /* int valued configurations */
+
+#ifndef NO_STATS
+    int stat_syms_new;
+    int stat_iscn_syms_inuse, stat_iscn_syms_recycle;
+    int stat_img_syms_inuse, stat_img_syms_recycle;
+    int stat_sym_new;
+    int stat_sym_recycle[RECYCLE_BUCKETS];
+#endif
+};
+
+void _zbar_image_scanner_recycle_syms (zbar_image_scanner_t *iscn,
+                                       zbar_symbol_t *sym)
+{
+    zbar_symbol_t *next = NULL;
+    for(; sym; sym = next) {
+        next = sym->next;
+        if(sym->refcnt && _zbar_refcnt(&sym->refcnt, -1)) {
+            /* unlink referenced symbol */
+            /* FIXME handle outstanding component refs (currently unsupported)
+             */
+            assert(sym->data_alloc);
+            sym->next = NULL;
+        }
+        else {
+            /* recycle unreferenced symbol */
+            if(!sym->data_alloc) {
+                sym->data = NULL;
+                sym->datalen = 0;
+            }
+            if(sym->syms) {
+                if(_zbar_refcnt(&sym->syms->refcnt, -1))
+                    assert(0);
+                _zbar_image_scanner_recycle_syms(iscn, sym->syms->head);
+                sym->syms->head = NULL;
+                _zbar_symbol_set_free(sym->syms);
+                sym->syms = NULL;
+            }
+            int i;
+            for(i = 0; i < RECYCLE_BUCKETS; i++)
+                if(sym->data_alloc < 1 << (i * 2))
+                    break;
+            if(i == RECYCLE_BUCKETS) {
+                assert(sym->data);
+                free(sym->data);
+                sym->data = NULL;
+                sym->data_alloc = 0;
+                i = 0;
+            }
+            recycle_bucket_t *bucket = &iscn->recycle[i];
+            /* FIXME cap bucket fill */
+            bucket->nsyms++;
+            sym->next = bucket->head;
+            bucket->head = sym;
+        }
+    }
+}
+
+static inline int recycle_syms (zbar_image_scanner_t *iscn,
+                                zbar_symbol_set_t *syms)
+{
+    if(_zbar_refcnt(&syms->refcnt, -1))
+        return(1);
+
+    _zbar_image_scanner_recycle_syms(iscn, syms->head);
+    syms->head = syms->tail = NULL;
+    syms->nsyms = 0;
+    return(0);
+}
+
+inline void zbar_image_scanner_recycle_image (zbar_image_scanner_t *iscn,
+                                              zbar_image_t *img)
+{
+    zbar_symbol_set_t *syms = iscn->syms;
+    if(syms && syms->refcnt) {
+        if(recycle_syms(iscn, syms)) {
+            STAT(iscn_syms_inuse);
+            iscn->syms = NULL;
+        }
+        else
+            STAT(iscn_syms_recycle);
+    }
+
+    syms = img->syms;
+    img->syms = NULL;
+    if(syms && recycle_syms(iscn, syms)) {
+        STAT(img_syms_inuse);
+        syms = iscn->syms;
+    }
+    else if(syms) {
+        STAT(img_syms_recycle);
+
+        /* select one set to resurrect, destroy the other */
+        if(iscn->syms) {
+            _zbar_symbol_set_free(syms);
+            syms = iscn->syms;
+        }
+        else
+            iscn->syms = syms;
+    }
+}
+
+inline zbar_symbol_t*
+_zbar_image_scanner_alloc_sym (zbar_image_scanner_t *iscn,
+                               zbar_symbol_type_t type,
+                               int datalen)
+{
+    /* recycle old or alloc new symbol */
+    int i;
+    for(i = 0; i < RECYCLE_BUCKETS - 1; i++)
+        if(datalen <= 1 << (i * 2))
+            break;
+
+    zbar_symbol_t *sym = NULL;
+    for(; i > 0; i--)
+        if((sym = iscn->recycle[i].head)) {
+            STAT(sym_recycle[i]);
+            break;
+        }
+
+    if(sym) {
+        iscn->recycle[i].head = sym->next;
+        sym->next = NULL;
+        assert(iscn->recycle[i].nsyms);
+        iscn->recycle[i].nsyms--;
+    }
+    else {
+        sym = calloc(1, sizeof(zbar_symbol_t));
+        STAT(sym_new);
+    }
+
+    /* init new symbol */
+    sym->type = type;
+    sym->quality = 1;
+    sym->npts = 0;
+    sym->cache_count = 0;
+    sym->time = iscn->time;
+    assert(!sym->syms);
+
+    if(datalen > 0) {
+        sym->datalen = datalen - 1;
+        if(sym->data_alloc < datalen) {
+            if(sym->data)
+                free(sym->data);
+            sym->data_alloc = datalen;
+            sym->data = malloc(datalen);
+        }
+    }
+    else {
+        if(sym->data)
+            free(sym->data);
+        sym->data = NULL;
+        sym->datalen = sym->data_alloc = 0;
+    }
+    return(sym);
+}
+
+static inline zbar_symbol_t *cache_lookup (zbar_image_scanner_t *iscn,
+                                           zbar_symbol_t *sym)
+{
+    /* search for matching entry in cache */
+    zbar_symbol_t **entry = &iscn->cache;
+    while(*entry) {
+        if((*entry)->type == sym->type &&
+           (*entry)->datalen == sym->datalen &&
+           !memcmp((*entry)->data, sym->data, sym->datalen))
+            break;
+        if((sym->time - (*entry)->time) > CACHE_TIMEOUT) {
+            /* recycle stale cache entry */
+            zbar_symbol_t *next = (*entry)->next;
+            (*entry)->next = NULL;
+            _zbar_image_scanner_recycle_syms(iscn, *entry);
+            *entry = next;
+        }
+        else
+            entry = &(*entry)->next;
+    }
+    return(*entry);
+}
+
+static inline void cache_sym (zbar_image_scanner_t *iscn,
+                              zbar_symbol_t *sym)
+{
+    if(iscn->enable_cache) {
+        zbar_symbol_t *entry = cache_lookup(iscn, sym);
+        if(!entry) {
+            /* FIXME reuse sym */
+            entry = _zbar_image_scanner_alloc_sym(iscn, sym->type,
+                                                  sym->datalen + 1);
+            memcpy(entry->data, sym->data, sym->datalen);
+            entry->time = sym->time - CACHE_HYSTERESIS;
+            entry->cache_count = -CACHE_CONSISTENCY;
+            /* add to cache */
+            entry->next = iscn->cache;
+            iscn->cache = entry;
+        }
+
+        /* consistency check and hysteresis */
+        uint32_t age = sym->time - entry->time;
+        entry->time = sym->time;
+        int near_thresh = (age < CACHE_PROXIMITY);
+        int far_thresh = (age >= CACHE_HYSTERESIS);
+        int dup = (entry->cache_count >= 0);
+        if((!dup && !near_thresh) || far_thresh)
+            entry->cache_count = -CACHE_CONSISTENCY;
+        else if(dup || near_thresh)
+            entry->cache_count++;
+
+        sym->cache_count = entry->cache_count;
+    }
+    else
+        sym->cache_count = 0;
+}
+
+void _zbar_image_scanner_add_sym(zbar_image_scanner_t *iscn,
+                                 zbar_symbol_t *sym)
+{
+    cache_sym(iscn, sym);
+
+    zbar_symbol_set_t *syms = iscn->syms;
+    if(sym->cache_count || !syms->tail) {
+        sym->next = syms->head;
+        syms->head = sym;
+    }
+    else {
+        sym->next = syms->tail->next;
+        syms->tail->next = sym;
+    }
+
+    if(!sym->cache_count)
+        syms->nsyms++;
+    else if(!syms->tail)
+        syms->tail = sym;
+
+    _zbar_symbol_refcnt(sym, 1);
+}
+
+#ifdef ENABLE_QRCODE
+extern qr_finder_line *_zbar_decoder_get_qr_finder_line(zbar_decoder_t*);
+
+# define QR_FIXED(v, rnd) ((((v) << 1) + (rnd)) << (QR_FINDER_SUBPREC - 1))
+# define PRINT_FIXED(val, prec) \
+    ((val) >> (prec)),         \
+        (1000 * ((val) & ((1 << (prec)) - 1)) / (1 << (prec)))
+
+static inline void qr_handler (zbar_image_scanner_t *iscn)
+{
+    qr_finder_line *line = _zbar_decoder_get_qr_finder_line(iscn->dcode);
+    assert(line);
+    unsigned u = zbar_scanner_get_edge(iscn->scn, line->pos[0],
+                                       QR_FINDER_SUBPREC);
+    line->boffs = u - zbar_scanner_get_edge(iscn->scn, line->boffs,
+                                            QR_FINDER_SUBPREC);
+    line->len = zbar_scanner_get_edge(iscn->scn, line->len,
+                                      QR_FINDER_SUBPREC);
+    line->eoffs = zbar_scanner_get_edge(iscn->scn, line->eoffs,
+                                        QR_FINDER_SUBPREC) - line->len;
+    line->len -= u;
+
+    u = QR_FIXED(iscn->umin, 0) + iscn->du * u;
+    if(iscn->du < 0) {
+        u -= line->len;
+        int tmp = line->boffs;
+        line->boffs = line->eoffs;
+        line->eoffs = tmp;
+    }
+    int vert = !iscn->dx;
+    line->pos[vert] = u;
+    line->pos[!vert] = QR_FIXED(iscn->v, 1);
+
+    _zbar_qr_found_line(iscn->qr, vert, line);
+}
+#endif
+
+static void symbol_handler (zbar_decoder_t *dcode)
+{
+    zbar_image_scanner_t *iscn = zbar_decoder_get_userdata(dcode);
+    zbar_symbol_type_t type = zbar_decoder_get_type(dcode);
+    /* FIXME assert(type == ZBAR_PARTIAL) */
+    /* FIXME debug flag to save/display all PARTIALs */
+    if(type <= ZBAR_PARTIAL)
+        return;
+
+#ifdef ENABLE_QRCODE
+    if(type == ZBAR_QRCODE) {
+        qr_handler(iscn);
+        return;
+    }
+#else
+    assert(type != ZBAR_QRCODE);
+#endif
+
+    const char *data = zbar_decoder_get_data(dcode);
+    unsigned datalen = zbar_decoder_get_data_length(dcode);
+
+    int x = 0, y = 0;
+    if(TEST_CFG(iscn, ZBAR_CFG_POSITION)) {
+        /* tmp position fixup */
+        int w = zbar_scanner_get_width(iscn->scn);
+        int u = iscn->umin + iscn->du * zbar_scanner_get_edge(iscn->scn, w, 0);
+        if(iscn->dx) {
+            x = u;
+            y = iscn->v;
+        }
+        else {
+            x = iscn->v;
+            y = u;
+        }
+    }
+
+    /* FIXME need better symbol matching */
+    zbar_symbol_t *sym;
+    for(sym = iscn->syms->head; sym; sym = sym->next)
+        if(sym->type == type &&
+           sym->datalen == datalen &&
+           !memcmp(sym->data, data, datalen)) {
+            sym->quality++;
+            if(TEST_CFG(iscn, ZBAR_CFG_POSITION))
+                /* add new point to existing set */
+                /* FIXME should be polygon */
+                sym_add_point(sym, x, y);
+            return;
+        }
+
+    sym = _zbar_image_scanner_alloc_sym(iscn, type, datalen + 1);
+    /* FIXME grab decoder buffer */
+    memcpy(sym->data, data, datalen + 1);
+
+    /* initialize first point */
+    if(TEST_CFG(iscn, ZBAR_CFG_POSITION))
+        sym_add_point(sym, x, y);
+
+    _zbar_image_scanner_add_sym(iscn, sym);
+}
+
+zbar_image_scanner_t *zbar_image_scanner_create ()
+{
+    zbar_image_scanner_t *iscn = calloc(1, sizeof(zbar_image_scanner_t));
+    if(!iscn)
+        return(NULL);
+    iscn->dcode = zbar_decoder_create();
+    iscn->scn = zbar_scanner_create(iscn->dcode);
+    if(!iscn->dcode || !iscn->scn) {
+        zbar_image_scanner_destroy(iscn);
+        return(NULL);
+    }
+    zbar_decoder_set_userdata(iscn->dcode, iscn);
+    zbar_decoder_set_handler(iscn->dcode, symbol_handler);
+
+#ifdef ENABLE_QRCODE
+    iscn->qr = _zbar_qr_create();
+#endif
+
+    /* apply default configuration */
+    CFG(iscn, ZBAR_CFG_X_DENSITY) = 1;
+    CFG(iscn, ZBAR_CFG_Y_DENSITY) = 1;
+    zbar_image_scanner_set_config(iscn, 0, ZBAR_CFG_POSITION, 1);
+    return(iscn);
+}
+
+#ifndef NO_STATS
+static inline void dump_stats (const zbar_image_scanner_t *iscn)
+{
+    zprintf(1, "symbol sets allocated   = %-4d\n", iscn->stat_syms_new);
+    zprintf(1, "    scanner syms in use = %-4d\trecycled  = %-4d\n",
+            iscn->stat_iscn_syms_inuse, iscn->stat_iscn_syms_recycle);
+    zprintf(1, "    image syms in use   = %-4d\trecycled  = %-4d\n",
+            iscn->stat_img_syms_inuse, iscn->stat_img_syms_recycle);
+    zprintf(1, "symbols allocated       = %-4d\n", iscn->stat_sym_new);
+    int i;
+    for(i = 0; i < RECYCLE_BUCKETS; i++)
+        zprintf(1, "     recycled[%d]        = %-4d\n",
+                i, iscn->stat_sym_recycle[i]);
+}
+#endif
+
+void zbar_image_scanner_destroy (zbar_image_scanner_t *iscn)
+{
+    dump_stats(iscn);
+    if(iscn->syms) {
+        if(iscn->syms->refcnt)
+            zbar_symbol_set_ref(iscn->syms, -1);
+        else
+            _zbar_symbol_set_free(iscn->syms);
+        iscn->syms = NULL;
+    }
+    if(iscn->scn)
+        zbar_scanner_destroy(iscn->scn);
+    iscn->scn = NULL;
+    if(iscn->dcode)
+        zbar_decoder_destroy(iscn->dcode);
+    iscn->dcode = NULL;
+    int i;
+    for(i = 0; i < RECYCLE_BUCKETS; i++) {
+        zbar_symbol_t *sym, *next;
+        for(sym = iscn->recycle[i].head; sym; sym = next) {
+            next = sym->next;
+            _zbar_symbol_free(sym);
+        }
+    }
+#ifdef ENABLE_QRCODE
+    if(iscn->qr) {
+        _zbar_qr_destroy(iscn->qr);
+        iscn->qr = NULL;
+    }
+#endif
+    free(iscn);
+}
+
+zbar_image_data_handler_t*
+zbar_image_scanner_set_data_handler (zbar_image_scanner_t *iscn,
+                                     zbar_image_data_handler_t *handler,
+                                     const void *userdata)
+{
+    zbar_image_data_handler_t *result = iscn->handler;
+    iscn->handler = handler;
+    iscn->userdata = userdata;
+    return(result);
+}
+
+int zbar_image_scanner_set_config (zbar_image_scanner_t *iscn,
+                                   zbar_symbol_type_t sym,
+                                   zbar_config_t cfg,
+                                   int val)
+{
+    if(cfg < ZBAR_CFG_POSITION)
+        return(zbar_decoder_set_config(iscn->dcode, sym, cfg, val));
+
+    if(sym > ZBAR_PARTIAL)
+        return(1);
+
+    if(cfg >= ZBAR_CFG_X_DENSITY && cfg <= ZBAR_CFG_Y_DENSITY) {
+
+        CFG(iscn, cfg) = val;
+        return(0);
+    }
+
+    if(cfg > ZBAR_CFG_POSITION)
+        return(1);
+    cfg -= ZBAR_CFG_POSITION;
+
+    if(!val)
+        iscn->config &= ~(1 << cfg);
+    else if(val == 1)
+        iscn->config |= (1 << cfg);
+    else
+        return(1);
+
+    return(0);
+}
+
+void zbar_image_scanner_enable_cache (zbar_image_scanner_t *iscn,
+                                      int enable)
+{
+    if(iscn->cache) {
+        /* recycle all cached syms */
+        _zbar_image_scanner_recycle_syms(iscn, iscn->cache);
+        iscn->cache = NULL;
+    }
+    iscn->enable_cache = (enable) ? 1 : 0;
+}
+
+const zbar_symbol_set_t *
+zbar_image_scanner_get_results (const zbar_image_scanner_t *iscn)
+{
+    return(iscn->syms);
+}
+
+static inline void quiet_border (zbar_image_scanner_t *iscn)
+{
+    /* flush scanner pipeline */
+    zbar_scanner_t *scn = iscn->scn;
+    zbar_scanner_flush(scn);
+    zbar_scanner_flush(scn);
+    zbar_scanner_new_scan(scn);
+}
+
+#define movedelta(dx, dy) do {                  \
+        x += (dx);                              \
+        y += (dy);                              \
+        p += (dx) + ((intptr_t)(dy) * w);       \
+    } while(0);
+
+int zbar_scan_image (zbar_image_scanner_t *iscn,
+                     zbar_image_t *img)
+{
+
+#if 0
+    /* timestamp image
+     * FIXME prefer video timestamp
+     */
+#if _POSIX_TIMERS > 0
+    struct timespec abstime;
+    clock_gettime(CLOCK_REALTIME, &abstime);
+    iscn->time = (abstime.tv_sec * 1000) + ((abstime.tv_nsec / 500000) + 1) / 2;
+#else
+    struct timeval abstime;
+    gettimeofday(&abstime, NULL);
+    iscn->time = (abstime.tv_sec * 1000) + ((abstime.tv_usec / 500) + 1) / 2;
+#endif
+#endif
+
+iscn->time = 10000;
+
+#ifdef ENABLE_QRCODE
+    _zbar_qr_reset(iscn->qr);
+#endif
+
+    /* get grayscale image, convert if necessary */
+    if(img->format != fourcc('Y','8','0','0') &&
+       img->format != fourcc('G','R','E','Y'))
+        return(-1);
+    iscn->img = img;
+
+    /* recycle previous scanner and image results */
+    zbar_image_scanner_recycle_image(iscn, img);
+    zbar_symbol_set_t *syms = iscn->syms;
+    if(!syms) {
+        syms = iscn->syms = _zbar_symbol_set_create();
+        STAT(syms_new);
+        zbar_symbol_set_ref(syms, 1);
+    }
+    else
+        zbar_symbol_set_ref(syms, 2);
+    img->syms = syms;
+
+    unsigned w = img->width;
+    unsigned h = img->height;
+    const uint8_t *data = img->data;
+
+    zbar_image_write_png(img, "debug.png");
+    svg_open("debug.svg", 0, 0, w, h);
+    svg_image("debug.png", w, h);
+
+    zbar_scanner_t *scn = iscn->scn;
+
+    int density = CFG(iscn, ZBAR_CFG_Y_DENSITY);
+    if(density > 0) {
+        svg_group_start("scanner", 0, 1, 1, 0, 0);
+        const uint8_t *p = data;
+        int x = 0, y = 0;
+        iscn->dy = 0;
+
+        int border = (((h - 1) % density) + 1) / 2;
+        if(border > h / 2)
+            border = h / 2;
+        movedelta(0, border);
+        iscn->v = y;
+
+        zbar_scanner_new_scan(scn);
+
+        while(y < h) {
+            zprintf(128, "img_x+: %04d,%04d @%p\n", x, y, p);
+            svg_path_start("vedge", 1. / 32, 0, y + 0.5);
+            iscn->dx = iscn->du = 1;
+            iscn->umin = 0;
+            while(x < w) {
+                uint8_t d = *p;
+                movedelta(1, 0);
+                zbar_scan_y(scn, d);
+            }
+            ASSERT_POS;
+            quiet_border(iscn);
+            svg_path_end();
+
+            movedelta(-1, density);
+            iscn->v = y;
+            if(y >= h)
+                break;
+
+            zprintf(128, "img_x-: %04d,%04d @%p\n", x, y, p);
+            svg_path_start("vedge", -1. / 32, w, y + 0.5);
+            iscn->dx = iscn->du = -1;
+            iscn->umin = w;
+            while(x >= 0) {
+                uint8_t d = *p;
+                movedelta(-1, 0);
+                zbar_scan_y(scn, d);
+            }
+            ASSERT_POS;
+            quiet_border(iscn);
+            svg_path_end();
+
+            movedelta(1, density);
+            iscn->v = y;
+        }
+        svg_group_end();
+    }
+    iscn->dx = 0;
+
+    density = CFG(iscn, ZBAR_CFG_X_DENSITY);
+    if(density > 0) {
+        svg_group_start("scanner", 90, 1, -1, 0, 0);
+        const uint8_t *p = data;
+        int x = 0, y = 0;
+
+        int border = (((w - 1) % density) + 1) / 2;
+        if(border > w / 2)
+            border = w / 2;
+        movedelta(border, 0);
+        iscn->v = x;
+
+        while(x < w) {
+            zprintf(128, "img_y+: %04d,%04d @%p\n", x, y, p);
+            svg_path_start("vedge", 1. / 32, 0, x + 0.5);
+            iscn->dy = iscn->du = 1;
+            iscn->umin = 0;
+            while(y < h) {
+                uint8_t d = *p;
+                movedelta(0, 1);
+                zbar_scan_y(scn, d);
+            }
+            ASSERT_POS;
+            quiet_border(iscn);
+            svg_path_end();
+
+            movedelta(density, -1);
+            iscn->v = x;
+            if(x >= w)
+                break;
+
+            zprintf(128, "img_y-: %04d,%04d @%p\n", x, y, p);
+            svg_path_start("vedge", -1. / 32, h, x + 0.5);
+            iscn->dy = iscn->du = -1;
+            iscn->umin = h;
+            while(y >= 0) {
+                uint8_t d = *p;
+                movedelta(0, -1);
+                zbar_scan_y(scn, d);
+            }
+            ASSERT_POS;
+            quiet_border(iscn);
+            svg_path_end();
+
+            movedelta(density, 1);
+            iscn->v = x;
+        }
+        svg_group_end();
+    }
+    iscn->dy = 0;
+    iscn->img = NULL;
+
+#ifdef ENABLE_QRCODE
+    _zbar_qr_decode(iscn->qr, iscn, img);
+#endif
+
+    /* FIXME tmp hack to filter bad EAN results */
+    if(syms->nsyms && !iscn->enable_cache &&
+       (density == 1 || CFG(iscn, ZBAR_CFG_Y_DENSITY) == 1)) {
+        zbar_symbol_t **symp = &syms->head, *sym;
+        while((sym = *symp)) {
+            if(sym->type < ZBAR_I25 && sym->type > ZBAR_PARTIAL &&
+               sym->quality < 3) {
+                /* recycle */
+                *symp = sym->next;
+                syms->nsyms--;
+                sym->next = NULL;
+                _zbar_image_scanner_recycle_syms(iscn, sym);
+            }
+            else
+                symp = &sym->next;
+        }
+    }
+
+    if(syms->nsyms && iscn->handler)
+        iscn->handler(img, iscn->userdata);
+
+    svg_close();
+    return(syms->nsyms);
+}
+
+#ifdef DEBUG_SVG
+/* FIXME lame...*/
+# include "svg.c"
+#endif

+ 138 - 0
Third_Party/ZBAR/src/isaac.c

@@ -0,0 +1,138 @@
+/*Written by Timothy B. Terriberry (tterribe@xiph.org) 1999-2009 public domain.
+  Based on the public domain implementation by Robert J. Jenkins Jr.*/
+
+#include <string.h>
+#include "isaac.h"
+
+
+
+#define ISAAC_MASK        (0xFFFFFFFFU)
+
+
+
+static void isaac_update(isaac_ctx *_ctx){
+  unsigned *m;
+  unsigned *r;
+  unsigned  a;
+  unsigned  b;
+  unsigned  x;
+  unsigned  y;
+  int       i;
+  m=_ctx->m;
+  r=_ctx->r;
+  a=_ctx->a;
+  b=_ctx->b+(++_ctx->c)&ISAAC_MASK;
+  for(i=0;i<ISAAC_SZ/2;i++){
+    x=m[i];
+    a=(a^a<<13)+m[i+ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+    x=m[++i];
+    a=(a^a>>6)+m[i+ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+    x=m[++i];
+    a=(a^a<<2)+m[i+ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+    x=m[++i];
+    a=(a^a>>16)+m[i+ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+  }
+  for(i=ISAAC_SZ/2;i<ISAAC_SZ;i++){
+    x=m[i];
+    a=(a^a<<13)+m[i-ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+    x=m[++i];
+    a=(a^a>>6)+m[i-ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+    x=m[++i];
+    a=(a^a<<2)+m[i-ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+    x=m[++i];
+    a=(a^a>>16)+m[i-ISAAC_SZ/2]&ISAAC_MASK;
+    m[i]=y=m[(x&ISAAC_SZ-1<<2)>>2]+a+b&ISAAC_MASK;
+    r[i]=b=m[y>>ISAAC_SZ_LOG+2&ISAAC_SZ-1]+x&ISAAC_MASK;
+  }
+  _ctx->b=b;
+  _ctx->a=a;
+  _ctx->n=ISAAC_SZ;
+}
+
+static void isaac_mix(unsigned _x[8]){
+  static const unsigned char SHIFT[8]={11,2,8,16,10,4,8,9};
+  int i;
+  for(i=0;i<8;i++){
+    _x[i]^=_x[i+1&7]<<SHIFT[i];
+    _x[i+3&7]+=_x[i];
+    _x[i+1&7]+=_x[i+2&7];
+    i++;
+    _x[i]^=_x[i+1&7]>>SHIFT[i];
+    _x[i+3&7]+=_x[i];
+    _x[i+1&7]+=_x[i+2&7];
+  }
+}
+
+
+void isaac_init(isaac_ctx *_ctx,const void *_seed,int _nseed){
+  const unsigned char *seed;
+  unsigned            *m;
+  unsigned            *r;
+  unsigned             x[8];
+  int                  i;
+  int                  j;
+  _ctx->a=_ctx->b=_ctx->c=0;
+  m=_ctx->m;
+  r=_ctx->r;
+  x[0]=x[1]=x[2]=x[3]=x[4]=x[5]=x[6]=x[7]=0x9E3779B9;
+  for(i=0;i<4;i++)isaac_mix(x);
+  if(_nseed>ISAAC_SEED_SZ_MAX)_nseed=ISAAC_SEED_SZ_MAX;
+  seed=(const unsigned char *)_seed;
+  for(i=0;i<_nseed>>2;i++){
+    r[i]=seed[i<<2|3]<<24|seed[i<<2|2]<<16|seed[i<<2|1]<<8|seed[i<<2];
+  }
+  if(_nseed&3){
+    r[i]=seed[i<<2];
+    for(j=1;j<(_nseed&3);j++)r[i]+=seed[i<<2|j]<<(j<<3);
+    i++;
+  }
+  memset(r+i,0,(ISAAC_SZ-i)*sizeof(*r));
+  for(i=0;i<ISAAC_SZ;i+=8){
+    for(j=0;j<8;j++)x[j]+=r[i+j];
+    isaac_mix(x);
+    memcpy(m+i,x,sizeof(x));
+  }
+  for(i=0;i<ISAAC_SZ;i+=8){
+    for(j=0;j<8;j++)x[j]+=m[i+j];
+    isaac_mix(x);
+    memcpy(m+i,x,sizeof(x));
+  }
+  isaac_update(_ctx);
+}
+
+unsigned isaac_next_uint32(isaac_ctx *_ctx){
+  if(!_ctx->n)isaac_update(_ctx);
+  return _ctx->r[--_ctx->n];
+}
+
+/*Returns a uniform random integer less than the given maximum value.
+  _n: The upper bound on the range of numbers returned (not inclusive).
+      This must be strictly less than 2**32.
+  Return: An integer uniformly distributed between 0 (inclusive) and _n
+           (exclusive).*/
+unsigned isaac_next_uint(isaac_ctx *_ctx,unsigned _n){
+  unsigned r;
+  unsigned v;
+  unsigned d;
+  do{
+    r=isaac_next_uint32(_ctx);
+    v=r%_n;
+    d=r-v;
+  }
+  while((d+_n-1&ISAAC_MASK)<d);
+  return v;
+}

+ 77 - 0
Third_Party/ZBAR/src/qr_finder.c

@@ -0,0 +1,77 @@
+#include <config.h>
+//#include <assert.h>
+
+#include <zbar.h>
+#include "decoder.h"
+
+#include "qr_finder.h"
+
+#ifdef DEBUG_QR_FINDER
+//# define DEBUG_LEVEL (DEBUG_QR_FINDER)
+#endif
+#include "debug.h"
+
+/* at this point lengths are all decode unit offsets from the decode edge
+ * NB owned by finder
+ */
+qr_finder_line *_zbar_decoder_get_qr_finder_line (zbar_decoder_t *dcode)
+{
+    return(&dcode->qrf.line);
+}
+
+zbar_symbol_type_t _zbar_find_qr (zbar_decoder_t *dcode)
+{
+    qr_finder_t *qrf = &dcode->qrf;
+
+    /* update latest finder pattern width */
+    qrf->s5 -= get_width(dcode, 6);
+    qrf->s5 += get_width(dcode, 1);
+    unsigned s = qrf->s5;
+
+    if(get_color(dcode) != ZBAR_SPACE || s < 7)
+        return(0);
+
+    dprintf(2, "    qrf: s=%d", s);
+
+    int ei = decode_e(pair_width(dcode, 1), s, 7);
+    dprintf(2, " %d", ei);
+    if(ei)
+        goto invalid;
+
+    ei = decode_e(pair_width(dcode, 2), s, 7);
+    dprintf(2, "%d", ei);
+    if(ei != 2)
+        goto invalid;
+
+    ei = decode_e(pair_width(dcode, 3), s, 7);
+    dprintf(2, "%d", ei);
+    if(ei != 2)
+        goto invalid;
+
+    ei = decode_e(pair_width(dcode, 4), s, 7);
+    dprintf(2, "%d", ei);
+    if(ei)
+        goto invalid;
+
+    /* valid QR finder symbol
+     * mark positions needed by decoder
+     */
+    unsigned qz = get_width(dcode, 0);
+    unsigned w = get_width(dcode, 1);
+    qrf->line.eoffs = qz + (w + 1) / 2;
+    qrf->line.len = qz + w + get_width(dcode, 2);
+    qrf->line.pos[0] = qrf->line.len + get_width(dcode, 3);
+    qrf->line.pos[1] = qrf->line.pos[0];
+    w = get_width(dcode, 5);
+    qrf->line.boffs = qrf->line.pos[0] + get_width(dcode, 4) + (w + 1) / 2;
+
+    dprintf(2, " boff=%d pos=%d len=%d eoff=%d [valid]\n",
+            qrf->line.boffs, qrf->line.pos[0], qrf->line.len,
+            qrf->line.eoffs);
+
+    return(ZBAR_QRCODE);
+
+invalid:
+    dprintf(2, " [invalid]\n");
+    return(0);
+}

+ 3957 - 0
Third_Party/ZBAR/src/qrdec.c

@@ -0,0 +1,3957 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+//#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <time.h>
+#include "qrcode.h"
+#include "qrdec.h"
+#include "bch15_5.h"
+#include "rs.h"
+#include "isaac.h"
+#include "util.h"
+#include "binarize.h"
+#include "image.h"
+#include "error.h"
+#include "svg.h"
+#include "zbar_config.h"
+
+typedef int qr_line[3];
+
+typedef struct qr_finder_cluster qr_finder_cluster;
+typedef struct qr_finder_edge_pt  qr_finder_edge_pt;
+typedef struct qr_finder_center   qr_finder_center;
+
+typedef struct qr_aff qr_aff;
+typedef struct qr_hom qr_hom;
+
+typedef struct qr_finder qr_finder;
+
+typedef struct qr_hom_cell      qr_hom_cell;
+typedef struct qr_sampling_grid qr_sampling_grid;
+typedef struct qr_pack_buf      qr_pack_buf;
+
+/*The number of bits in an int.
+  Note the cast to (int): this prevents this value from "promoting" whole
+   expressions to an (unsigned) size_t.*/
+#define QR_INT_BITS    ((int)sizeof(int)*CHAR_BIT)
+#define QR_INT_LOGBITS (QR_ILOG(QR_INT_BITS))
+
+/*A 14 bit resolution for a homography ensures that the ideal module size for a
+   version 40 code differs from that of a version 39 code by at least 2.*/
+#define QR_HOM_BITS (14)
+
+/*The number of bits of sub-module precision to use when searching for
+   alignment patterns.
+  Two bits allows an alignment pattern to be found even if the modules have
+   been eroded by up to 50% (due to blurring, etc.).
+  This must be at least one, since it affects the dynamic range of the
+   transforms, and we sample at half-module resolution to compute a bounding
+   quadrilateral for the code.*/
+#define QR_ALIGN_SUBPREC (2)
+
+
+/* collection of finder lines */
+typedef struct qr_finder_lines {
+    qr_finder_line *lines;
+    int nlines, clines;
+} qr_finder_lines;
+
+
+struct qr_reader {
+    /*The GF(256) representation used in Reed-Solomon decoding.*/
+    rs_gf256  gf;
+    /*The random number generator used by RANSAC.*/
+    isaac_ctx isaac;
+    /* current finder state, horizontal and vertical lines */
+    qr_finder_lines finder_lines[2];
+};
+
+
+/*Initializes a client reader handle.*/
+static void qr_reader_init (qr_reader *reader)
+{
+    /*time_t now;
+      now=time(NULL);
+      isaac_init(&_reader->isaac,&now,sizeof(now));*/
+    isaac_init(&reader->isaac, NULL, 0);
+    rs_gf256_init(&reader->gf, QR_PPOLY);
+}
+
+/*Allocates a client reader handle.*/
+qr_reader *_zbar_qr_create (void)
+{
+    qr_reader *reader = (qr_reader*)calloc(1, sizeof(*reader));
+    qr_reader_init(reader);
+    return(reader);
+}
+
+/*Frees a client reader handle.*/
+void _zbar_qr_destroy (qr_reader *reader)
+{
+    zprintf(1, "max finder lines = %dx%d\n",
+            reader->finder_lines[0].clines,
+            reader->finder_lines[1].clines);
+    if(reader->finder_lines[0].lines)
+        free(reader->finder_lines[0].lines);
+    if(reader->finder_lines[1].lines)
+        free(reader->finder_lines[1].lines);
+    free(reader);
+}
+
+/* reset finder state between scans */
+void _zbar_qr_reset (qr_reader *reader)
+{
+    reader->finder_lines[0].nlines = 0;
+    reader->finder_lines[1].nlines = 0;
+}
+
+
+/*A cluster of lines crossing a finder pattern (all in the same direction).*/
+struct qr_finder_cluster{
+  /*Pointers to the lines crossing the pattern.*/
+  qr_finder_line **lines;
+  /*The number of lines in the cluster.*/
+  int              nlines;
+};
+
+
+/*A point on the edge of a finder pattern.
+  These are obtained from the endpoints of the lines crossing this particular
+   pattern.*/
+struct qr_finder_edge_pt{
+  /*The location of the edge point.*/
+  qr_point pos;
+  /*A label classifying which edge this belongs to:
+    0: negative u edge (left)
+    1: positive u edge (right)
+    2: negative v edge (top)
+    3: positive v edge (bottom)*/
+  int      edge;
+  /*The (signed) perpendicular distance of the edge point from a line parallel
+     to the edge passing through the finder center, in (u,v) coordinates.
+    This is also re-used by RANSAC to store inlier flags.*/
+  int      extent;
+};
+
+
+/*The center of a finder pattern obtained from the crossing of one or more
+   clusters of horizontal finder lines with one or more clusters of vertical
+   finder lines.*/
+struct qr_finder_center{
+  /*The estimated location of the finder center.*/
+  qr_point           pos;
+  /*The list of edge points from the crossing lines.*/
+  qr_finder_edge_pt *edge_pts;
+  /*The number of edge points from the crossing lines.*/
+  int                nedge_pts;
+};
+
+
+static int qr_finder_vline_cmp(const void *_a,const void *_b){
+  const qr_finder_line *a;
+  const qr_finder_line *b;
+  a=(const qr_finder_line *)_a;
+  b=(const qr_finder_line *)_b;
+  return ((a->pos[0]>b->pos[0])-(a->pos[0]<b->pos[0])<<1)+
+   (a->pos[1]>b->pos[1])-(a->pos[1]<b->pos[1]);
+}
+
+/*Clusters adjacent lines into groups that are large enough to be crossing a
+   finder pattern (relative to their length).
+  _clusters:  The buffer in which to store the clusters found.
+  _neighbors: The buffer used to store the lists of lines in each cluster.
+  _lines:     The list of lines to cluster.
+              Horizontal lines must be sorted in ascending order by Y
+               coordinate, with ties broken by X coordinate.
+              Vertical lines must be sorted in ascending order by X coordinate,
+               with ties broken by Y coordinate.
+  _nlines:    The number of lines in the set of lines to cluster.
+  _v:         0 for horizontal lines, or 1 for vertical lines.
+  Return: The number of clusters.*/
+static int qr_finder_cluster_lines(qr_finder_cluster *_clusters,
+ qr_finder_line **_neighbors,qr_finder_line *_lines,int _nlines,int _v){
+  unsigned char   *mark;
+  qr_finder_line **neighbors;
+  int              nneighbors;
+  int              nclusters;
+  int              i;
+  /*TODO: Kalman filters!*/
+  mark=(unsigned char *)calloc(_nlines,sizeof(*mark));
+  neighbors=_neighbors;
+  nclusters=0;
+  for(i=0;i<_nlines-1;i++)if(!mark[i]){
+    int len;
+    int j;
+    nneighbors=1;
+    neighbors[0]=_lines+i;
+    len=_lines[i].len;
+    for(j=i+1;j<_nlines;j++)if(!mark[j]){
+      const qr_finder_line *a;
+      const qr_finder_line *b;
+      int                   thresh;
+      a=neighbors[nneighbors-1];
+      b=_lines+j;
+      /*The clustering threshold is proportional to the size of the lines,
+         since minor noise in large areas can interrupt patterns more easily
+         at high resolutions.*/
+      thresh=a->len+7>>2;
+      if(abs(a->pos[1-_v]-b->pos[1-_v])>thresh)break;
+      if(abs(a->pos[_v]-b->pos[_v])>thresh)continue;
+      if(abs(a->pos[_v]+a->len-b->pos[_v]-b->len)>thresh)continue;
+      if(a->boffs>0&&b->boffs>0&&
+       abs(a->pos[_v]-a->boffs-b->pos[_v]+b->boffs)>thresh){
+        continue;
+      }
+      if(a->eoffs>0&&b->eoffs>0&&
+       abs(a->pos[_v]+a->len+a->eoffs-b->pos[_v]-b->len-b->eoffs)>thresh){
+        continue;
+      }
+      neighbors[nneighbors++]=_lines+j;
+      len+=b->len;
+    }
+    /*We require at least three lines to form a cluster, which eliminates a
+       large number of false positives, saving considerable decoding time.
+      This should still be sufficient for 1-pixel codes with no noise.*/
+    if(nneighbors<3)continue;
+    /*The expected number of lines crossing a finder pattern is equal to their
+       average length.
+      We accept the cluster if size is at least 1/3 their average length (this
+       is a very small threshold, but was needed for some test images).*/
+    len=((len<<1)+nneighbors)/(nneighbors<<1);
+    if(nneighbors*(5<<QR_FINDER_SUBPREC)>=len){
+      _clusters[nclusters].lines=neighbors;
+      _clusters[nclusters].nlines=nneighbors;
+      for(j=0;j<nneighbors;j++)mark[neighbors[j]-_lines]=1;
+      neighbors+=nneighbors;
+      nclusters++;
+    }
+  }
+  free(mark);
+  return nclusters;
+}
+
+/*Adds the coordinates of the edge points from the lines contained in the
+   given list of clusters to the list of edge points for a finder center.
+  Only the edge point position is initialized.
+  The edge label and extent are set by qr_finder_edge_pts_aff_classify()
+   or qr_finder_edge_pts_hom_classify().
+  _edge_pts:   The buffer in which to store the edge points.
+  _nedge_pts:  The current number of edge points in the buffer.
+  _neighbors:  The list of lines in the cluster.
+  _nneighbors: The number of lines in the list of lines in the cluster.
+  _v:          0 for horizontal lines and 1 for vertical lines.
+  Return: The new total number of edge points.*/
+static int qr_finder_edge_pts_fill(qr_finder_edge_pt *_edge_pts,int _nedge_pts,
+ qr_finder_cluster **_neighbors,int _nneighbors,int _v){
+  int i;
+  for(i=0;i<_nneighbors;i++){
+    qr_finder_cluster *c;
+    int                j;
+    c=_neighbors[i];
+    for(j=0;j<c->nlines;j++){
+      qr_finder_line *l;
+      l=c->lines[j];
+      if(l->boffs>0){
+        _edge_pts[_nedge_pts].pos[0]=l->pos[0];
+        _edge_pts[_nedge_pts].pos[1]=l->pos[1];
+        _edge_pts[_nedge_pts].pos[_v]-=l->boffs;
+        _nedge_pts++;
+      }
+      if(l->eoffs>0){
+        _edge_pts[_nedge_pts].pos[0]=l->pos[0];
+        _edge_pts[_nedge_pts].pos[1]=l->pos[1];
+        _edge_pts[_nedge_pts].pos[_v]+=l->len+l->eoffs;
+        _nedge_pts++;
+      }
+    }
+  }
+  return _nedge_pts;
+}
+
+static int qr_finder_center_cmp(const void *_a,const void *_b){
+  const qr_finder_center *a;
+  const qr_finder_center *b;
+  a=(const qr_finder_center *)_a;
+  b=(const qr_finder_center *)_b;
+  return ((b->nedge_pts>a->nedge_pts)-(b->nedge_pts<a->nedge_pts)<<2)+
+   ((a->pos[1]>b->pos[1])-(a->pos[1]<b->pos[1])<<1)+
+   (a->pos[0]>b->pos[0])-(a->pos[0]<b->pos[0]);
+}
+
+/*Determine if a horizontal line crosses a vertical line.
+  _hline: The horizontal line.
+  _vline: The vertical line.
+  Return: A non-zero value if the lines cross, or zero if they do not.*/
+static int qr_finder_lines_are_crossing(const qr_finder_line *_hline,
+ const qr_finder_line *_vline){
+  return
+   _hline->pos[0]<=_vline->pos[0]&&_vline->pos[0]<_hline->pos[0]+_hline->len&&
+   _vline->pos[1]<=_hline->pos[1]&&_hline->pos[1]<_vline->pos[1]+_vline->len;
+}
+
+/*Finds horizontal clusters that cross corresponding vertical clusters,
+   presumably corresponding to a finder center.
+  _center:     The buffer in which to store putative finder centers.
+  _edge_pts:   The buffer to use for the edge point lists for each finder
+                center.
+  _hclusters:  The clusters of horizontal lines crossing finder patterns.
+  _nhclusters: The number of horizontal line clusters.
+  _vclusters:  The clusters of vertical lines crossing finder patterns.
+  _nvclusters: The number of vertical line clusters.
+  Return: The number of putative finder centers.*/
+static int qr_finder_find_crossings(qr_finder_center *_centers,
+ qr_finder_edge_pt *_edge_pts,qr_finder_cluster *_hclusters,int _nhclusters,
+ qr_finder_cluster *_vclusters,int _nvclusters){
+  qr_finder_cluster **hneighbors;
+  qr_finder_cluster **vneighbors;
+  unsigned char      *hmark;
+  unsigned char      *vmark;
+  int                 ncenters;
+  int                 i;
+  int                 j;
+  hneighbors=(qr_finder_cluster **)malloc(_nhclusters*sizeof(*hneighbors));
+  vneighbors=(qr_finder_cluster **)malloc(_nvclusters*sizeof(*vneighbors));
+  hmark=(unsigned char *)calloc(_nhclusters,sizeof(*hmark));
+  vmark=(unsigned char *)calloc(_nvclusters,sizeof(*vmark));
+  ncenters=0;
+  /*TODO: This may need some re-working.
+    We should be finding groups of clusters such that _all_ horizontal lines in
+     _all_ horizontal clusters in the group cross _all_ vertical lines in _all_
+     vertical clusters in the group.
+    This is equivalent to finding the maximum bipartite clique in the
+     connectivity graph, which requires linear progamming to solve efficiently.
+    In principle, that is easy to do, but a realistic implementation without
+     floating point is a lot of work (and computationally expensive).
+    Right now we are relying on a sufficient border around the finder patterns
+     to prevent false positives.*/
+  for(i=0;i<_nhclusters;i++)if(!hmark[i]){
+    qr_finder_line *a;
+    qr_finder_line *b;
+    int             nvneighbors;
+    int             nedge_pts;
+    int             y;
+    a=_hclusters[i].lines[_hclusters[i].nlines>>1];
+    y=nvneighbors=0;
+    for(j=0;j<_nvclusters;j++)if(!vmark[j]){
+      b=_vclusters[j].lines[_vclusters[j].nlines>>1];
+      if(qr_finder_lines_are_crossing(a,b)){
+        vmark[j]=1;
+        y+=(b->pos[1]<<1)+b->len;
+        if(b->boffs>0&&b->eoffs>0)y+=b->eoffs-b->boffs;
+        vneighbors[nvneighbors++]=_vclusters+j;
+      }
+    }
+    if(nvneighbors>0){
+      qr_finder_center *c;
+      int               nhneighbors;
+      int               x;
+      x=(a->pos[0]<<1)+a->len;
+      if(a->boffs>0&&a->eoffs>0)x+=a->eoffs-a->boffs;
+      hneighbors[0]=_hclusters+i;
+      nhneighbors=1;
+      j=nvneighbors>>1;
+      b=vneighbors[j]->lines[vneighbors[j]->nlines>>1];
+      for(j=i+1;j<_nhclusters;j++)if(!hmark[j]){
+        a=_hclusters[j].lines[_hclusters[j].nlines>>1];
+        if(qr_finder_lines_are_crossing(a,b)){
+          hmark[j]=1;
+          x+=(a->pos[0]<<1)+a->len;
+          if(a->boffs>0&&a->eoffs>0)x+=a->eoffs-a->boffs;
+          hneighbors[nhneighbors++]=_hclusters+j;
+        }
+      }
+      c=_centers+ncenters++;
+      c->pos[0]=(x+nhneighbors)/(nhneighbors<<1);
+      c->pos[1]=(y+nvneighbors)/(nvneighbors<<1);
+      c->edge_pts=_edge_pts;
+      nedge_pts=qr_finder_edge_pts_fill(_edge_pts,0,
+       hneighbors,nhneighbors,0);
+      nedge_pts=qr_finder_edge_pts_fill(_edge_pts,nedge_pts,
+       vneighbors,nvneighbors,1);
+      c->nedge_pts=nedge_pts;
+      _edge_pts+=nedge_pts;
+    }
+  }
+  free(vmark);
+  free(hmark);
+  free(vneighbors);
+  free(hneighbors);
+  /*Sort the centers by decreasing numbers of edge points.*/
+  qsort(_centers,ncenters,sizeof(*_centers),qr_finder_center_cmp);
+  return ncenters;
+}
+
+/*Locates a set of putative finder centers in the image.
+  First we search for horizontal and vertical lines that have
+   (dark:light:dark:light:dark) runs with size ratios of roughly (1:1:3:1:1).
+  Then we cluster them into groups such that each subsequent pair of endpoints
+   is close to the line before it in the cluster.
+  This will locate many line clusters that don't cross a finder pattern, but
+   qr_finder_find_crossings() will filter most of them out.
+  Where horizontal and vertical clusters cross, a prospective finder center is
+   returned.
+  _centers:  Returns a pointer to a freshly-allocated list of finder centers.
+             This must be freed by the caller.
+  _edge_pts: Returns a pointer to a freshly-allocated list of edge points
+              around those centers.
+             This must be freed by the caller.
+  _img:      The binary image to search.
+  _width:    The width of the image.
+  _height:   The height of the image.
+  Return: The number of putative finder centers located.*/
+static int qr_finder_centers_locate(qr_finder_center **_centers,
+ qr_finder_edge_pt **_edge_pts, qr_reader *reader,
+ int _width,int _height){
+  qr_finder_line     *hlines = reader->finder_lines[0].lines;
+  int                 nhlines = reader->finder_lines[0].nlines;
+  qr_finder_line     *vlines = reader->finder_lines[1].lines;
+  int                 nvlines = reader->finder_lines[1].nlines;
+
+  qr_finder_line    **hneighbors;
+  qr_finder_cluster  *hclusters;
+  int                 nhclusters;
+  qr_finder_line    **vneighbors;
+  qr_finder_cluster  *vclusters;
+  int                 nvclusters;
+  int                 ncenters;
+
+  /*Cluster the detected lines.*/
+  hneighbors=(qr_finder_line **)malloc(nhlines*sizeof(*hneighbors));
+  /*We require more than one line per cluster, so there are at most nhlines/2.*/
+  hclusters=(qr_finder_cluster *)malloc((nhlines>>1)*sizeof(*hclusters));
+  nhclusters=qr_finder_cluster_lines(hclusters,hneighbors,hlines,nhlines,0);
+  /*We need vertical lines to be sorted by X coordinate, with ties broken by Y
+     coordinate, for clustering purposes.
+    We scan the image in the opposite order for cache efficiency, so sort the
+     lines we found here.*/
+  qsort(vlines,nvlines,sizeof(*vlines),qr_finder_vline_cmp);
+  vneighbors=(qr_finder_line **)malloc(nvlines*sizeof(*vneighbors));
+  /*We require more than one line per cluster, so there are at most nvlines/2.*/
+  vclusters=(qr_finder_cluster *)malloc((nvlines>>1)*sizeof(*vclusters));
+  nvclusters=qr_finder_cluster_lines(vclusters,vneighbors,vlines,nvlines,1);
+  /*Find line crossings among the clusters.*/
+  if(nhclusters>=3&&nvclusters>=3){
+    qr_finder_edge_pt  *edge_pts;
+    qr_finder_center   *centers;
+    int                 nedge_pts;
+    int                 i;
+    nedge_pts=0;
+    for(i=0;i<nhclusters;i++)nedge_pts+=hclusters[i].nlines;
+    for(i=0;i<nvclusters;i++)nedge_pts+=vclusters[i].nlines;
+    nedge_pts<<=1;
+    edge_pts=(qr_finder_edge_pt *)malloc(nedge_pts*sizeof(*edge_pts));
+    centers=(qr_finder_center *)malloc(
+     QR_MINI(nhclusters,nvclusters)*sizeof(*centers));
+    ncenters=qr_finder_find_crossings(centers,edge_pts,
+     hclusters,nhclusters,vclusters,nvclusters);
+    *_centers=centers;
+    *_edge_pts=edge_pts;
+  }
+  else ncenters=0;
+  free(vclusters);
+  free(vneighbors);
+  free(hclusters);
+  free(hneighbors);
+  return ncenters;
+}
+
+
+
+static void qr_point_translate(qr_point _point,int _dx,int _dy){
+  _point[0]+=_dx;
+  _point[1]+=_dy;
+}
+
+static unsigned qr_point_distance2(const qr_point _p1,const qr_point _p2){
+  return (_p1[0]-_p2[0])*(_p1[0]-_p2[0])+(_p1[1]-_p2[1])*(_p1[1]-_p2[1]);
+}
+
+/*Returns the cross product of the three points, which is positive if they are
+   in CCW order (in a right-handed coordinate system), and 0 if they're
+   colinear.*/
+static int qr_point_ccw(const qr_point _p0,
+ const qr_point _p1,const qr_point _p2){
+  return (_p1[0]-_p0[0])*(_p2[1]-_p0[1])-(_p1[1]-_p0[1])*(_p2[0]-_p0[0]);
+}
+
+
+
+/*Evaluates a line equation at a point.
+  _line: The line to evaluate.
+  _x:    The X coordinate of the point.
+  _y:    The y coordinate of the point.
+  Return: The value of the line equation _line[0]*_x+_line[1]*_y+_line[2].*/
+static int qr_line_eval(qr_line _line,int _x,int _y){
+  return _line[0]*_x+_line[1]*_y+_line[2];
+}
+
+/*Computes a line passing through the given point using the specified second
+   order statistics.
+  Given a line defined by the equation
+    A*x+B*y+C = 0 ,
+   the least squares fit to n points (x_i,y_i) must satisfy the two equations
+    A^2 + (Syy - Sxx)/Sxy*A*B - B^2 = 0 ,
+    C = -(xbar*A+ybar*B) ,
+   where
+    xbar = sum(x_i)/n ,
+    ybar = sum(y_i)/n ,
+    Sxx = sum((x_i-xbar)**2) ,
+    Sxy = sum((x_i-xbar)*(y_i-ybar)) ,
+    Syy = sum((y_i-ybar)**2) .
+  The quadratic can be solved for the ratio (A/B) or (B/A):
+    A/B = (Syy + sqrt((Sxx-Syy)**2 + 4*Sxy**2) - Sxx)/(-2*Sxy) ,
+    B/A = (Sxx + sqrt((Sxx-Syy)**2 + 4*Sxy**2) - Syy)/(-2*Sxy) .
+  We pick the one that leads to the larger ratio to avoid destructive
+   cancellation (and e.g., 0/0 for horizontal or vertical lines).
+  The above solutions correspond to the actual minimum.
+  The other solution of the quadratic corresponds to a saddle point of the
+   least squares objective function.
+  _l:   Returns the fitted line values A, B, and C.
+  _x0:  The X coordinate of the point the line is supposed to pass through.
+  _y0:  The Y coordinate of the point the line is supposed to pass through.
+  _sxx: The sum Sxx.
+  _sxy: The sum Sxy.
+  _syy: The sum Syy.
+  _res: The maximum number of bits occupied by the product of any two of
+         _l[0] or _l[1].
+        Smaller numbers give less angular resolution, but allow more overhead
+         room for computations.*/
+static void qr_line_fit(qr_line _l,int _x0,int _y0,
+ int _sxx,int _sxy,int _syy,int _res){
+  int dshift;
+  int dround;
+  int u;
+  int v;
+  int w;
+  u=abs(_sxx-_syy);
+  v=-_sxy<<1;
+  w=qr_ihypot(u,v);
+  /*Computations in later stages can easily overflow with moderate sizes, so we
+     compute a shift factor to scale things down into a managable range.
+    We ensure that the product of any two of _l[0] and _l[1] fits within _res
+     bits, which allows computation of line intersections without overflow.*/
+  dshift=QR_MAXI(0,QR_MAXI(qr_ilog(u),qr_ilog(abs(v)))+1-(_res+1>>1));
+  dround=(1<<dshift)>>1;
+  if(_sxx>_syy){
+    _l[0]=v+dround>>dshift;
+    _l[1]=u+w+dround>>dshift;
+  }
+  else{
+    _l[0]=u+w+dround>>dshift;
+    _l[1]=v+dround>>dshift;
+  }
+  _l[2]=-(_x0*_l[0]+_y0*_l[1]);
+}
+
+/*Perform a least-squares line fit to a list of points.
+  At least two points are required.*/
+static void qr_line_fit_points(qr_line _l,qr_point *_p,int _np,int _res){
+  int sx;
+  int sy;
+  int xmin;
+  int xmax;
+  int ymin;
+  int ymax;
+  int xbar;
+  int ybar;
+  int dx;
+  int dy;
+  int sxx;
+  int sxy;
+  int syy;
+  int sshift;
+  int sround;
+  int i;
+  sx=sy=0;
+  ymax=xmax=INT_MIN;
+  ymin=xmin=INT_MAX;
+  for(i=0;i<_np;i++){
+    sx+=_p[i][0];
+    xmin=QR_MINI(xmin,_p[i][0]);
+    xmax=QR_MAXI(xmax,_p[i][0]);
+    sy+=_p[i][1];
+    ymin=QR_MINI(ymin,_p[i][1]);
+    ymax=QR_MAXI(ymax,_p[i][1]);
+  }
+  xbar=(sx+(_np>>1))/_np;
+  ybar=(sy+(_np>>1))/_np;
+  sshift=QR_MAXI(0,qr_ilog(_np*QR_MAXI(QR_MAXI(xmax-xbar,xbar-xmin),
+   QR_MAXI(ymax-ybar,ybar-ymin)))-(QR_INT_BITS-1>>1));
+  sround=(1<<sshift)>>1;
+  sxx=sxy=syy=0;
+  for(i=0;i<_np;i++){
+    dx=_p[i][0]-xbar+sround>>sshift;
+    dy=_p[i][1]-ybar+sround>>sshift;
+    sxx+=dx*dx;
+    sxy+=dx*dy;
+    syy+=dy*dy;
+  }
+  qr_line_fit(_l,xbar,ybar,sxx,sxy,syy,_res);
+}
+
+static void qr_line_orient(qr_line _l,int _x,int _y){
+  if(qr_line_eval(_l,_x,_y)<0){
+    _l[0]=-_l[0];
+    _l[1]=-_l[1];
+    _l[2]=-_l[2];
+  }
+}
+
+static int qr_line_isect(qr_point _p,const qr_line _l0,const qr_line _l1){
+  int d;
+  int x;
+  int y;
+  d=_l0[0]*_l1[1]-_l0[1]*_l1[0];
+  if(d==0)return -1;
+  x=_l0[1]*_l1[2]-_l1[1]*_l0[2];
+  y=_l1[0]*_l0[2]-_l0[0]*_l1[2];
+  if(d<0){
+    x=-x;
+    y=-y;
+    d=-d;
+  }
+  _p[0]=QR_DIVROUND(x,d);
+  _p[1]=QR_DIVROUND(y,d);
+  return 0;
+}
+
+
+
+/*An affine homography.
+  This maps from the image (at subpel resolution) to a square domain with
+   power-of-two sides (of res bits) and back.*/
+struct qr_aff{
+  int fwd[2][2];
+  int inv[2][2];
+  int x0;
+  int y0;
+  int res;
+};
+
+
+static void qr_aff_init(qr_aff *_aff,
+ const qr_point _p0,const qr_point _p1,const qr_point _p2,int _res){
+  int det;
+  int dx1;
+  int dy1;
+  int dx2;
+  int dy2;
+  /*det is ensured to be positive by our caller.*/
+  det=qr_point_ccw(_p0,_p1,_p2);
+  dx1=_p1[0]-_p0[0];
+  dx2=_p2[0]-_p0[0];
+  dy1=_p1[1]-_p0[1];
+  dy2=_p2[1]-_p0[1];
+  _aff->fwd[0][0]=dx1;
+  _aff->fwd[0][1]=dx2;
+  _aff->fwd[1][0]=dy1;
+  _aff->fwd[1][1]=dy2;
+  _aff->inv[0][0]=QR_DIVROUND(dy2<<_res,det);
+  _aff->inv[0][1]=QR_DIVROUND(-dx2<<_res,det);
+  _aff->inv[1][0]=QR_DIVROUND(-dy1<<_res,det);
+  _aff->inv[1][1]=QR_DIVROUND(dx1<<_res,det);
+  _aff->x0=_p0[0];
+  _aff->y0=_p0[1];
+  _aff->res=_res;
+}
+
+/*Map from the image (at subpel resolution) into the square domain.*/
+static void qr_aff_unproject(qr_point _q,const qr_aff *_aff,
+ int _x,int _y){
+  _q[0]=_aff->inv[0][0]*(_x-_aff->x0)+_aff->inv[0][1]*(_y-_aff->y0);
+  _q[1]=_aff->inv[1][0]*(_x-_aff->x0)+_aff->inv[1][1]*(_y-_aff->y0);
+}
+
+/*Map from the square domain into the image (at subpel resolution).*/
+static void qr_aff_project(qr_point _p,const qr_aff *_aff,
+ int _u,int _v){
+  _p[0]=(_aff->fwd[0][0]*_u+_aff->fwd[0][1]*_v+(1<<_aff->res-1)>>_aff->res)
+   +_aff->x0;
+  _p[1]=(_aff->fwd[1][0]*_u+_aff->fwd[1][1]*_v+(1<<_aff->res-1)>>_aff->res)
+   +_aff->y0;
+}
+
+
+
+/*A full homography.
+  Like the affine homography, this maps from the image (at subpel resolution)
+   to a square domain with power-of-two sides (of res bits) and back.*/
+struct qr_hom{
+  int fwd[3][2];
+  int inv[3][2];
+  int fwd22;
+  int inv22;
+  int x0;
+  int y0;
+  int res;
+};
+
+
+static void qr_hom_init(qr_hom *_hom,int _x0,int _y0,
+ int _x1,int _y1,int _x2,int _y2,int _x3,int _y3,int _res){
+  int dx10;
+  int dx20;
+  int dx30;
+  int dx31;
+  int dx32;
+  int dy10;
+  int dy20;
+  int dy30;
+  int dy31;
+  int dy32;
+  int a20;
+  int a21;
+  int a22;
+  int b0;
+  int b1;
+  int b2;
+  int s1;
+  int s2;
+  int r1;
+  int r2;
+  dx10=_x1-_x0;
+  dx20=_x2-_x0;
+  dx30=_x3-_x0;
+  dx31=_x3-_x1;
+  dx32=_x3-_x2;
+  dy10=_y1-_y0;
+  dy20=_y2-_y0;
+  dy30=_y3-_y0;
+  dy31=_y3-_y1;
+  dy32=_y3-_y2;
+  a20=dx32*dy10-dx10*dy32;
+  a21=dx20*dy31-dx31*dy20;
+  a22=dx32*dy31-dx31*dy32;
+  /*Figure out if we need to downscale anything.*/
+  b0=qr_ilog(QR_MAXI(abs(dx10),abs(dy10)))+qr_ilog(abs(a20+a22));
+  b1=qr_ilog(QR_MAXI(abs(dx20),abs(dy20)))+qr_ilog(abs(a21+a22));
+  b2=qr_ilog(QR_MAXI(QR_MAXI(abs(a20),abs(a21)),abs(a22)));
+  s1=QR_MAXI(0,_res+QR_MAXI(QR_MAXI(b0,b1),b2)-(QR_INT_BITS-2));
+  r1=(1<<s1)>>1;
+  /*Compute the final coefficients of the forward transform.
+    The 32x32->64 bit multiplies are really needed for accuracy with large
+     versions.*/
+  _hom->fwd[0][0]=QR_FIXMUL(dx10,a20+a22,r1,s1);
+  _hom->fwd[0][1]=QR_FIXMUL(dx20,a21+a22,r1,s1);
+  _hom->x0=_x0;
+  _hom->fwd[1][0]=QR_FIXMUL(dy10,a20+a22,r1,s1);
+  _hom->fwd[1][1]=QR_FIXMUL(dy20,a21+a22,r1,s1);
+  _hom->y0=_y0;
+  _hom->fwd[2][0]=a20+r1>>s1;
+  _hom->fwd[2][1]=a21+r1>>s1;
+  _hom->fwd22=s1>_res?a22+(r1>>_res)>>s1-_res:a22<<_res-s1;
+  /*Now compute the inverse transform.*/
+  b0=qr_ilog(QR_MAXI(QR_MAXI(abs(dx10),abs(dx20)),abs(dx30)))+
+   qr_ilog(QR_MAXI(abs(_hom->fwd[0][0]),abs(_hom->fwd[1][0])));
+  b1=qr_ilog(QR_MAXI(QR_MAXI(abs(dy10),abs(dy20)),abs(dy30)))+
+   qr_ilog(QR_MAXI(abs(_hom->fwd[0][1]),abs(_hom->fwd[1][1])));
+  b2=qr_ilog(abs(a22))-s1;
+  s2=QR_MAXI(0,QR_MAXI(b0,b1)+b2-(QR_INT_BITS-3));
+  r2=(1<<s2)>>1;
+  s1+=s2;
+  r1<<=s2;
+  /*The 32x32->64 bit multiplies are really needed for accuracy with large
+     versions.*/
+  _hom->inv[0][0]=QR_FIXMUL(_hom->fwd[1][1],a22,r1,s1);
+  _hom->inv[0][1]=QR_FIXMUL(-_hom->fwd[0][1],a22,r1,s1);
+  _hom->inv[1][0]=QR_FIXMUL(-_hom->fwd[1][0],a22,r1,s1);
+  _hom->inv[1][1]=QR_FIXMUL(_hom->fwd[0][0],a22,r1,s1);
+  _hom->inv[2][0]=QR_FIXMUL(_hom->fwd[1][0],_hom->fwd[2][1],
+   -QR_EXTMUL(_hom->fwd[1][1],_hom->fwd[2][0],r2),s2);
+  _hom->inv[2][1]=QR_FIXMUL(_hom->fwd[0][1],_hom->fwd[2][0],
+   -QR_EXTMUL(_hom->fwd[0][0],_hom->fwd[2][1],r2),s2);
+  _hom->inv22=QR_FIXMUL(_hom->fwd[0][0],_hom->fwd[1][1],
+   -QR_EXTMUL(_hom->fwd[0][1],_hom->fwd[1][0],r2),s2);
+  _hom->res=_res;
+}
+
+
+/*Map from the image (at subpel resolution) into the square domain.
+  Returns a negative value if the point went to infinity.*/
+static int qr_hom_unproject(qr_point _q,const qr_hom *_hom,int _x,int _y){
+  int x;
+  int y;
+  int w;
+  _x-=_hom->x0;
+  _y-=_hom->y0;
+  x=_hom->inv[0][0]*_x+_hom->inv[0][1]*_y;
+  y=_hom->inv[1][0]*_x+_hom->inv[1][1]*_y;
+  w=_hom->inv[2][0]*_x+_hom->inv[2][1]*_y
+   +_hom->inv22+(1<<_hom->res-1)>>_hom->res;
+  if(w==0){
+    _q[0]=x<0?INT_MIN:INT_MAX;
+    _q[1]=y<0?INT_MIN:INT_MAX;
+    return -1;
+  }
+  else{
+    if(w<0){
+      x=-x;
+      y=-y;
+      w=-w;
+    }
+    _q[0]=QR_DIVROUND(x,w);
+    _q[1]=QR_DIVROUND(y,w);
+  }
+  return 0;
+}
+
+/*Finish a partial projection, converting from homogeneous coordinates to the
+   normal 2-D representation.
+  In loops, we can avoid many multiplies by computing the homogeneous _x, _y,
+   and _w incrementally, but we cannot avoid the divisions, done here.*/
+static void qr_hom_fproject(qr_point _p,const qr_hom *_hom,
+ int _x,int _y,int _w){
+  if(_w==0){
+    _p[0]=_x<0?INT_MIN:INT_MAX;
+    _p[1]=_y<0?INT_MIN:INT_MAX;
+  }
+  else{
+    if(_w<0){
+      _x=-_x;
+      _y=-_y;
+      _w=-_w;
+    }
+    _p[0]=QR_DIVROUND(_x,_w)+_hom->x0;
+    _p[1]=QR_DIVROUND(_y,_w)+_hom->y0;
+  }
+}
+
+#if defined(QR_DEBUG)
+/*Map from the square domain into the image (at subpel resolution).
+  Currently only used directly by debug code.*/
+static void qr_hom_project(qr_point _p,const qr_hom *_hom,
+ int _u,int _v){
+  qr_hom_fproject(_p,_hom,
+   _hom->fwd[0][0]*_u+_hom->fwd[0][1]*_v,
+   _hom->fwd[1][0]*_u+_hom->fwd[1][1]*_v,
+   _hom->fwd[2][0]*_u+_hom->fwd[2][1]*_v+_hom->fwd22);
+}
+#endif
+
+
+
+/*All the information we've collected about a finder pattern in the current
+   configuration.*/
+struct qr_finder{
+  /*The module size along each axis (in the square domain).*/
+  int                size[2];
+  /*The version estimated from the module size along each axis.*/
+  int                eversion[2];
+  /*The list of classified edge points for each edge.*/
+  qr_finder_edge_pt *edge_pts[4];
+  /*The number of edge points classified as belonging to each edge.*/
+  int                nedge_pts[4];
+  /*The number of inliers found after running RANSAC on each edge.*/
+  int                ninliers[4];
+  /*The center of the finder pattern (in the square domain).*/
+  qr_point           o;
+  /*The finder center information from the original image.*/
+  qr_finder_center  *c;
+};
+
+
+static int qr_cmp_edge_pt(const void *_a,const void *_b){
+  const qr_finder_edge_pt *a;
+  const qr_finder_edge_pt *b;
+  a=(const qr_finder_edge_pt *)_a;
+  b=(const qr_finder_edge_pt *)_b;
+  return ((a->edge>b->edge)-(a->edge<b->edge)<<1)+
+   (a->extent>b->extent)-(a->extent<b->extent);
+}
+
+/*Computes the index of the edge each edge point belongs to, and its (signed)
+   distance along the corresponding axis from the center of the finder pattern
+   (in the square domain).
+  The resulting list of edge points is sorted by edge index, with ties broken
+   by extent.*/
+static void qr_finder_edge_pts_aff_classify(qr_finder *_f,const qr_aff *_aff){
+  qr_finder_center *c;
+  int               i;
+  int               e;
+  c=_f->c;
+  for(e=0;e<4;e++)_f->nedge_pts[e]=0;
+  for(i=0;i<c->nedge_pts;i++){
+    qr_point q;
+    int      d;
+    qr_aff_unproject(q,_aff,c->edge_pts[i].pos[0],c->edge_pts[i].pos[1]);
+    qr_point_translate(q,-_f->o[0],-_f->o[1]);
+    d=abs(q[1])>abs(q[0]);
+    e=d<<1|(q[d]>=0);
+    _f->nedge_pts[e]++;
+    c->edge_pts[i].edge=e;
+    c->edge_pts[i].extent=q[d];
+  }
+  qsort(c->edge_pts,c->nedge_pts,sizeof(*c->edge_pts),qr_cmp_edge_pt);
+  _f->edge_pts[0]=c->edge_pts;
+  for(e=1;e<4;e++)_f->edge_pts[e]=_f->edge_pts[e-1]+_f->nedge_pts[e-1];
+}
+
+/*Computes the index of the edge each edge point belongs to, and its (signed)
+   distance along the corresponding axis from the center of the finder pattern
+   (in the square domain).
+  The resulting list of edge points is sorted by edge index, with ties broken
+   by extent.*/
+static void qr_finder_edge_pts_hom_classify(qr_finder *_f,const qr_hom *_hom){
+  qr_finder_center *c;
+  int               i;
+  int               e;
+  c=_f->c;
+  for(e=0;e<4;e++)_f->nedge_pts[e]=0;
+  for(i=0;i<c->nedge_pts;i++){
+    qr_point q;
+    int      d;
+    if(qr_hom_unproject(q,_hom,
+     c->edge_pts[i].pos[0],c->edge_pts[i].pos[1])>=0){
+      qr_point_translate(q,-_f->o[0],-_f->o[1]);
+      d=abs(q[1])>abs(q[0]);
+      e=d<<1|(q[d]>=0);
+      _f->nedge_pts[e]++;
+      c->edge_pts[i].edge=e;
+      c->edge_pts[i].extent=q[d];
+    }
+    else{
+      c->edge_pts[i].edge=4;
+      c->edge_pts[i].extent=q[0];
+    }
+  }
+  qsort(c->edge_pts,c->nedge_pts,sizeof(*c->edge_pts),qr_cmp_edge_pt);
+  _f->edge_pts[0]=c->edge_pts;
+  for(e=1;e<4;e++)_f->edge_pts[e]=_f->edge_pts[e-1]+_f->nedge_pts[e-1];
+}
+
+/*TODO: Perhaps these thresholds should be on the module size instead?
+  Unfortunately, I'd need real-world images of codes with larger versions to
+   see if these thresholds are still effective, but such versions aren't used
+   often.*/
+
+/*The amount that the estimated version numbers are allowed to differ from the
+   real version number and still be considered valid.*/
+#define QR_SMALL_VERSION_SLACK (1)
+/*Since cell phone cameras can have severe radial distortion, the estimated
+   version for larger versions can be off by larger amounts.*/
+#define QR_LARGE_VERSION_SLACK (3)
+
+/*Estimates the size of a module after classifying the edge points.
+  _width:  The distance between UL and UR in the square domain.
+  _height: The distance between UL and DL in the square domain.*/
+static int qr_finder_estimate_module_size_and_version(qr_finder *_f,
+ int _width,int _height){
+  qr_point offs;
+  int      sums[4];
+  int      nsums[4];
+  int      usize;
+  int      nusize;
+  int      vsize;
+  int      nvsize;
+  int      uversion;
+  int      vversion;
+  int      e;
+  offs[0]=offs[1]=0;
+  for(e=0;e<4;e++)if(_f->nedge_pts[e]>0){
+    qr_finder_edge_pt *edge_pts;
+    int                sum;
+    int                mean;
+    int                n;
+    int                i;
+    /*Average the samples for this edge, dropping the top and bottom 25%.*/
+    edge_pts=_f->edge_pts[e];
+    n=_f->nedge_pts[e];
+    sum=0;
+    for(i=(n>>2);i<n-(n>>2);i++)sum+=edge_pts[i].extent;
+    n=n-((n>>2)<<1);
+    mean=QR_DIVROUND(sum,n);
+    offs[e>>1]+=mean;
+    sums[e]=sum;
+    nsums[e]=n;
+  }
+  else nsums[e]=sums[e]=0;
+  /*If we have samples on both sides of an axis, refine our idea of where the
+     unprojected finder center is located.*/
+  if(_f->nedge_pts[0]>0&&_f->nedge_pts[1]>0){
+    _f->o[0]-=offs[0]>>1;
+    sums[0]-=offs[0]*nsums[0]>>1;
+    sums[1]-=offs[0]*nsums[1]>>1;
+  }
+  if(_f->nedge_pts[2]>0&&_f->nedge_pts[3]>0){
+    _f->o[1]-=offs[1]>>1;
+    sums[2]-=offs[1]*nsums[2]>>1;
+    sums[3]-=offs[1]*nsums[3]>>1;
+  }
+  /*We must have _some_ samples along each axis... if we don't, our transform
+     must be pretty severely distorting the original square (e.g., with
+     coordinates so large as to cause overflow).*/
+  nusize=nsums[0]+nsums[1];
+  if(nusize<=0)return -1;
+  /*The module size is 1/3 the average edge extent.*/
+  nusize*=3;
+  usize=sums[1]-sums[0];
+  usize=((usize<<1)+nusize)/(nusize<<1);
+  if(usize<=0)return -1;
+  /*Now estimate the version directly from the module size and the distance
+     between the finder patterns.
+    This is done independently using the extents along each axis.
+    If either falls significantly outside the valid range (1 to 40), reject the
+     configuration.*/
+  uversion=(_width-8*usize)/(usize<<2);
+  if(uversion<1||uversion>40+QR_LARGE_VERSION_SLACK)return -1;
+  /*Now do the same for the other axis.*/
+  nvsize=nsums[2]+nsums[3];
+  if(nvsize<=0)return -1;
+  nvsize*=3;
+  vsize=sums[3]-sums[2];
+  vsize=((vsize<<1)+nvsize)/(nvsize<<1);
+  if(vsize<=0)return -1;
+  vversion=(_height-8*vsize)/(vsize<<2);
+  if(vversion<1||vversion>40+QR_LARGE_VERSION_SLACK)return -1;
+  /*If the estimated version using extents along one axis is significantly
+     different than the estimated version along the other axis, then the axes
+     have significantly different scalings (relative to the grid).
+    This can happen, e.g., when we have multiple adjacent QR codes, and we've
+     picked two finder patterns from one and the third finder pattern from
+     another, e.g.:
+      X---DL UL---X
+      |....   |....
+      X....  UR....
+    Such a configuration might even pass any other geometric checks if we
+     didn't reject it here.*/
+  if(abs(uversion-vversion)>QR_LARGE_VERSION_SLACK)return -1;
+  _f->size[0]=usize;
+  _f->size[1]=vsize;
+  /*We intentionally do not compute an average version from the sizes along
+     both axes.
+    In the presence of projective distortion, one of them will be much more
+     accurate than the other.*/
+  _f->eversion[0]=uversion;
+  _f->eversion[1]=vversion;
+  return 0;
+}
+
+/*Eliminate outliers from the classified edge points with RANSAC.*/
+static void qr_finder_ransac(qr_finder *_f,const qr_aff *_hom,
+ isaac_ctx *_isaac,int _e){
+  qr_finder_edge_pt *edge_pts;
+  int                best_ninliers;
+  int                n;
+  edge_pts=_f->edge_pts[_e];
+  n=_f->nedge_pts[_e];
+  best_ninliers=0;
+  if(n>1){
+    int max_iters;
+    int i;
+    int j;
+    /*17 iterations is enough to guarantee an outlier-free sample with more
+       than 99% probability given as many as 50% outliers.*/
+    max_iters=17;
+    for(i=0;i<max_iters;i++){
+      qr_point  q0;
+      qr_point  q1;
+      int       ninliers;
+      int       thresh;
+      int       p0i;
+      int       p1i;
+      int      *p0;
+      int      *p1;
+      int       j;
+      /*Pick two random points on this edge.*/
+      p0i=isaac_next_uint(_isaac,n);
+      p1i=isaac_next_uint(_isaac,n-1);
+      if(p1i>=p0i)p1i++;
+      p0=edge_pts[p0i].pos;
+      p1=edge_pts[p1i].pos;
+      /*If the corresponding line is not within 45 degrees of the proper
+         orientation in the square domain, reject it outright.
+        This can happen, e.g., when highly skewed orientations cause points to
+         be misclassified into the wrong edge.
+        The irony is that using such points might produce a line which _does_
+         pass the corresponding validity checks.*/
+      qr_aff_unproject(q0,_hom,p0[0],p0[1]);
+      qr_aff_unproject(q1,_hom,p1[0],p1[1]);
+      qr_point_translate(q0,-_f->o[0],-_f->o[1]);
+      qr_point_translate(q1,-_f->o[0],-_f->o[1]);
+      if(abs(q0[_e>>1]-q1[_e>>1])>abs(q0[1-(_e>>1)]-q1[1-(_e>>1)]))continue;
+      /*Identify the other edge points which are inliers.
+        The squared distance should be distributed as a \Chi^2 distribution
+         with one degree of freedom, which means for a 95% confidence the
+         point should lie within a factor 3.8414588 ~= 4 times the expected
+         variance of the point locations.
+        We grossly approximate the standard deviation as 1 pixel in one
+         direction, and 0.5 pixels in the other (because we average two
+         coordinates).*/
+      thresh=qr_isqrt(qr_point_distance2(p0,p1)<<2*QR_FINDER_SUBPREC+1);
+      ninliers=0;
+      for(j=0;j<n;j++){
+        if(abs(qr_point_ccw(p0,p1,edge_pts[j].pos))<=thresh){
+          edge_pts[j].extent|=1;
+          ninliers++;
+        }
+        else edge_pts[j].extent&=~1;
+      }
+      if(ninliers>best_ninliers){
+        for(j=0;j<n;j++)edge_pts[j].extent<<=1;
+        best_ninliers=ninliers;
+        /*The actual number of iterations required is
+            log(1-\alpha)/log(1-r*r),
+           where \alpha is the required probability of taking a sample with
+            no outliers (e.g., 0.99) and r is the estimated ratio of inliers
+            (e.g. ninliers/n).
+          This is just a rough (but conservative) approximation, but it
+           should be good enough to stop the iteration early when we find
+           a good set of inliers.*/
+        if(ninliers>n>>1)max_iters=(67*n-63*ninliers-1)/(n<<1);
+      }
+    }
+    /*Now collect all the inliers at the beginning of the list.*/
+    for(i=j=0;j<best_ninliers;i++)if(edge_pts[i].extent&2){
+      if(j<i){
+        qr_finder_edge_pt tmp;
+        *&tmp=*(edge_pts+i);
+        *(edge_pts+j)=*(edge_pts+i);
+        *(edge_pts+i)=*&tmp;
+      }
+      j++;
+    }
+  }
+  _f->ninliers[_e]=best_ninliers;
+}
+
+/*Perform a least-squares line fit to an edge of a finder pattern using the
+   inliers found by RANSAC.*/
+static int qr_line_fit_finder_edge(qr_line _l,
+ const qr_finder *_f,int _e,int _res){
+  qr_finder_edge_pt *edge_pts;
+  qr_point          *pts;
+  int                npts;
+  int                i;
+  npts=_f->ninliers[_e];
+  if(npts<2)return -1;
+  /*We could write a custom version of qr_line_fit_points that accesses
+     edge_pts directly, but this saves on code size and doesn't measurably slow
+     things down.*/
+  pts=(qr_point *)malloc(npts*sizeof(*pts));
+  edge_pts=_f->edge_pts[_e];
+  for(i=0;i<npts;i++){
+    pts[i][0]=edge_pts[i].pos[0];
+    pts[i][1]=edge_pts[i].pos[1];
+  }
+  qr_line_fit_points(_l,pts,npts,_res);
+  /*Make sure the center of the finder pattern lies in the positive halfspace
+     of the line.*/
+  qr_line_orient(_l,_f->c->pos[0],_f->c->pos[1]);
+  free(pts);
+  return 0;
+}
+
+/*Perform a least-squares line fit to a pair of common finder edges using the
+   inliers found by RANSAC.
+  Unlike a normal edge fit, we guarantee that this one succeeds by creating at
+   least one point on each edge using the estimated module size if it has no
+   inliers.*/
+static void qr_line_fit_finder_pair(qr_line _l,const qr_aff *_aff,
+ const qr_finder *_f0,const qr_finder *_f1,int _e){
+  qr_point          *pts;
+  int                npts;
+  qr_finder_edge_pt *edge_pts;
+  qr_point           q;
+  int                n0;
+  int                n1;
+  int                i;
+  n0=_f0->ninliers[_e];
+  n1=_f1->ninliers[_e];
+  /*We could write a custom version of qr_line_fit_points that accesses
+     edge_pts directly, but this saves on code size and doesn't measurably slow
+     things down.*/
+  npts=QR_MAXI(n0,1)+QR_MAXI(n1,1);
+  pts=(qr_point *)malloc(npts*sizeof(*pts));
+  if(n0>0){
+    edge_pts=_f0->edge_pts[_e];
+    for(i=0;i<n0;i++){
+      pts[i][0]=edge_pts[i].pos[0];
+      pts[i][1]=edge_pts[i].pos[1];
+    }
+  }
+  else{
+    q[0]=_f0->o[0];
+    q[1]=_f0->o[1];
+    q[_e>>1]+=_f0->size[_e>>1]*(2*(_e&1)-1);
+    qr_aff_project(pts[0],_aff,q[0],q[1]);
+    n0++;
+  }
+  if(n1>0){
+    edge_pts=_f1->edge_pts[_e];
+    for(i=0;i<n1;i++){
+      pts[n0+i][0]=edge_pts[i].pos[0];
+      pts[n0+i][1]=edge_pts[i].pos[1];
+    }
+  }
+  else{
+    q[0]=_f1->o[0];
+    q[1]=_f1->o[1];
+    q[_e>>1]+=_f1->size[_e>>1]*(2*(_e&1)-1);
+    qr_aff_project(pts[n0],_aff,q[0],q[1]);
+    n1++;
+  }
+  qr_line_fit_points(_l,pts,npts,_aff->res);
+  /*Make sure at least one finder center lies in the positive halfspace.*/
+  qr_line_orient(_l,_f0->c->pos[0],_f0->c->pos[1]);
+  free(pts);
+}
+
+static int qr_finder_quick_crossing_check(const unsigned char *_img,
+ int _width,int _height,int _x0,int _y0,int _x1,int _y1,int _v){
+  /*The points must be inside the image, and have a !_v:_v:!_v pattern.
+    We don't scan the whole line initially, but quickly reject if the endpoints
+     aren't !_v, or the midpoint isn't _v.
+    If either end point is out of the image, or we don't encounter a _v pixel,
+     we return a negative value, indicating the region should be considered
+     empty.
+    Otherwise, we return a positive value to indicate it is non-empty.*/
+  if(_x0<0||_x0>=_width||_y0<0||_y0>=_height||
+   _x1<0||_x1>=_width||_y1<0||_y1>=_height){
+    return -1;
+  }
+  if(!_img[_y0*_width+_x0]!=_v||!_img[_y1*_width+_x1]!=_v)return 1;
+  if(!_img[(_y0+_y1>>1)*_width+(_x0+_x1>>1)]==_v)return -1;
+  return 0;
+}
+
+/*Locate the midpoint of a _v segment along a !_v:_v:!_v line from (_x0,_y0) to
+   (_x1,_y1).
+  All coordinates, which are NOT in subpel resolution, must lie inside the
+   image, and the endpoints are already assumed to have the value !_v.
+  The returned value is in subpel resolution.*/
+static int qr_finder_locate_crossing(const unsigned char *_img,
+ int _width,int _height,int _x0,int _y0,int _x1,int _y1,int _v,qr_point _p){
+  qr_point x0;
+  qr_point x1;
+  qr_point dx;
+  int      step[2];
+  int      steep;
+  int      err;
+  int      derr;
+  /*Use Bresenham's algorithm to trace along the line and find the exact
+     transitions from !_v to _v and back.*/
+  x0[0]=_x0;
+  x0[1]=_y0;
+  x1[0]=_x1;
+  x1[1]=_y1;
+  dx[0]=abs(_x1-_x0);
+  dx[1]=abs(_y1-_y0);
+  steep=dx[1]>dx[0];
+  err=0;
+  derr=dx[1-steep];
+  step[0]=((_x0<_x1)<<1)-1;
+  step[1]=((_y0<_y1)<<1)-1;
+  /*Find the first crossing from !_v to _v.*/
+  for(;;){
+    /*If we make it all the way to the other side, there's no crossing.*/
+    if(x0[steep]==x1[steep])return -1;
+    x0[steep]+=step[steep];
+    err+=derr;
+    if(err<<1>dx[steep]){
+      x0[1-steep]+=step[1-steep];
+      err-=dx[steep];
+    }
+    if(!_img[x0[1]*_width+x0[0]]!=_v)break;
+  }
+  /*Find the last crossing from _v to !_v.*/
+  err=0;
+  for(;;){
+    if(x0[steep]==x1[steep])break;
+    x1[steep]-=step[steep];
+    err+=derr;
+    if(err<<1>dx[steep]){
+      x1[1-steep]-=step[1-steep];
+      err-=dx[steep];
+    }
+    if(!_img[x1[1]*_width+x1[0]]!=_v)break;
+  }
+  /*Return the midpoint of the _v segment.*/
+  _p[0]=(x0[0]+x1[0]+1<<QR_FINDER_SUBPREC)>>1;
+  _p[1]=(x0[1]+x1[1]+1<<QR_FINDER_SUBPREC)>>1;
+  return 0;
+}
+
+static int qr_aff_line_step(const qr_aff *_aff,qr_line _l,
+ int _v,int _du,int *_dv){
+  int shift;
+  int round;
+  int dv;
+  int n;
+  int d;
+  n=_aff->fwd[0][_v]*_l[0]+_aff->fwd[1][_v]*_l[1];
+  d=_aff->fwd[0][1-_v]*_l[0]+_aff->fwd[1][1-_v]*_l[1];
+  if(d<0){
+    n=-n;
+    d=-d;
+  }
+  shift=QR_MAXI(0,qr_ilog(_du)+qr_ilog(abs(n))+3-QR_INT_BITS);
+  round=(1<<shift)>>1;
+  n=n+round>>shift;
+  d=d+round>>shift;
+  /*The line should not be outside 45 degrees of horizontal/vertical.
+    TODO: We impose this restriction to help ensure the loop below terminates,
+     but it should not technically be required.
+    It also, however, ensures we avoid division by zero.*/
+  if(abs(n)>=d)return -1;
+  n=-_du*n;
+  dv=QR_DIVROUND(n,d);
+  if(abs(dv)>=_du)return -1;
+  *_dv=dv;
+  return 0;
+}
+
+/*Computes the Hamming distance between two bit patterns (the number of bits
+   that differ).
+  May stop counting after _maxdiff differences.*/
+static int qr_hamming_dist(unsigned _y1,unsigned _y2,int _maxdiff){
+  unsigned y;
+  int      ret;
+  y=_y1^_y2;
+  for(ret=0;ret<_maxdiff&&y;ret++)y&=y-1;
+  return ret;
+}
+
+/*Retrieve a bit (guaranteed to be 0 or 1) from the image, given coordinates in
+   subpel resolution which have not been bounds checked.*/
+static int qr_img_get_bit(const unsigned char *_img,int _width,int _height,
+ int _x,int _y){
+  _x>>=QR_FINDER_SUBPREC;
+  _y>>=QR_FINDER_SUBPREC;
+  return _img[QR_CLAMPI(0,_y,_height-1)*_width+QR_CLAMPI(0,_x,_width-1)]!=0;
+}
+
+#if defined(QR_DEBUG)
+#include "image.h"
+
+static void qr_finder_dump_aff_undistorted(qr_finder *_ul,qr_finder *_ur,
+ qr_finder *_dl,qr_aff *_aff,const unsigned char *_img,int _width,int _height){
+  unsigned char *gimg;
+  FILE          *fout;
+  int            lpsz;
+  int            pixel_size;
+  int            dim;
+  int            min;
+  int            max;
+  int            u;
+  int            y;
+  int            i;
+  int            j;
+  lpsz=qr_ilog(_ur->size[0]+_ur->size[1]+_dl->size[0]+_dl->size[1])-6;
+  pixel_size=1<<lpsz;
+  dim=(1<<_aff->res-lpsz)+128;
+  gimg=(unsigned char *)malloc(dim*dim*sizeof(*gimg));
+  for(i=0;i<dim;i++)for(j=0;j<dim;j++){
+    qr_point p;
+    qr_aff_project(p,_aff,(j-64)<<lpsz,(i-64)<<lpsz);
+    gimg[i*dim+j]=_img[
+     QR_CLAMPI(0,p[1]>>QR_FINDER_SUBPREC,_height-1)*_width+
+     QR_CLAMPI(0,p[0]>>QR_FINDER_SUBPREC,_width-1)];
+  }
+  {
+    min=(_ur->o[0]-7*_ur->size[0]>>lpsz)+64;
+    if(min<0)min=0;
+    max=(_ur->o[0]+7*_ur->size[0]>>lpsz)+64;
+    if(max>dim)max=dim;
+    for(y=-7;y<=7;y++){
+      i=(_ur->o[1]+y*_ur->size[1]>>lpsz)+64;
+      if(i<0||i>=dim)continue;
+      for(j=min;j<max;j++)gimg[i*dim+j]=0x7F;
+    }
+    min=(_ur->o[1]-7*_ur->size[1]>>lpsz)+64;
+    if(min<0)min=0;
+    max=(_ur->o[1]+7*_ur->size[1]>>lpsz)+64;
+    if(max>dim)max=dim;
+    for(u=-7;u<=7;u++){
+      j=(_ur->o[0]+u*_ur->size[0]>>lpsz)+64;
+      if(j<0||j>=dim)continue;
+      for(i=min;i<max;i++)gimg[i*dim+j]=0x7F;
+    }
+  }
+  {
+    min=(_dl->o[0]-7*_dl->size[0]>>lpsz)+64;
+    if(min<0)min=0;
+    max=(_dl->o[0]+7*_dl->size[0]>>lpsz)+64;
+    if(max>dim)max=dim;
+    for(y=-7;y<=7;y++){
+      i=(_dl->o[1]+y*_dl->size[1]>>lpsz)+64;
+      if(i<0||i>=dim)continue;
+      for(j=min;j<max;j++)gimg[i*dim+j]=0x7F;
+    }
+    min=(_dl->o[1]-7*_dl->size[1]>>lpsz)+64;
+    if(min<0)min=0;
+    max=(_dl->o[1]+7*_dl->size[1]>>lpsz)+64;
+    if(max>dim)max=dim;
+    for(u=-7;u<=7;u++){
+      j=(_dl->o[0]+u*_dl->size[0]>>lpsz)+64;
+      if(j<0||j>=dim)continue;
+      for(i=min;i<max;i++)gimg[i*dim+j]=0x7F;
+    }
+  }
+  fout=fopen("undistorted_aff.png","wb");
+  image_write_png(gimg,dim,dim,fout);
+  fclose(fout);
+  free(gimg);
+}
+
+static void qr_finder_dump_hom_undistorted(qr_finder *_ul,qr_finder *_ur,
+ qr_finder *_dl,qr_hom *_hom,const unsigned char *_img,int _width,int _height){
+  unsigned char *gimg;
+  FILE          *fout;
+  int            lpsz;
+  int            pixel_size;
+  int            dim;
+  int            min;
+  int            max;
+  int            u;
+  int            v;
+  int            i;
+  int            j;
+  lpsz=qr_ilog(_ur->size[0]+_ur->size[1]+_dl->size[0]+_dl->size[1])-6;
+  pixel_size=1<<lpsz;
+  dim=(1<<_hom->res-lpsz)+256;
+  gimg=(unsigned char *)malloc(dim*dim*sizeof(*gimg));
+  for(i=0;i<dim;i++)for(j=0;j<dim;j++){
+    qr_point p;
+    qr_hom_project(p,_hom,(j-128)<<lpsz,(i-128)<<lpsz);
+    gimg[i*dim+j]=_img[
+     QR_CLAMPI(0,p[1]>>QR_FINDER_SUBPREC,_height-1)*_width+
+     QR_CLAMPI(0,p[0]>>QR_FINDER_SUBPREC,_width-1)];
+  }
+  {
+    min=(_ur->o[0]-7*_ur->size[0]>>lpsz)+128;
+    if(min<0)min=0;
+    max=(_ur->o[0]+7*_ur->size[0]>>lpsz)+128;
+    if(max>dim)max=dim;
+    for(v=-7;v<=7;v++){
+      i=(_ur->o[1]+v*_ur->size[1]>>lpsz)+128;
+      if(i<0||i>=dim)continue;
+      for(j=min;j<max;j++)gimg[i*dim+j]=0x7F;
+    }
+    min=(_ur->o[1]-7*_ur->size[1]>>lpsz)+128;
+    if(min<0)min=0;
+    max=(_ur->o[1]+7*_ur->size[1]>>lpsz)+128;
+    if(max>dim)max=dim;
+    for(u=-7;u<=7;u++){
+      j=(_ur->o[0]+u*_ur->size[0]>>lpsz)+128;
+      if(j<0||j>=dim)continue;
+      for(i=min;i<max;i++)gimg[i*dim+j]=0x7F;
+    }
+  }
+  {
+    min=(_dl->o[0]-7*_dl->size[0]>>lpsz)+128;
+    if(min<0)min=0;
+    max=(_dl->o[0]+7*_dl->size[0]>>lpsz)+128;
+    if(max>dim)max=dim;
+    for(v=-7;v<=7;v++){
+      i=(_dl->o[1]+v*_dl->size[1]>>lpsz)+128;
+      if(i<0||i>=dim)continue;
+      for(j=min;j<max;j++)gimg[i*dim+j]=0x7F;
+    }
+    min=(_dl->o[1]-7*_dl->size[1]>>lpsz)+128;
+    if(min<0)min=0;
+    max=(_dl->o[1]+7*_dl->size[1]>>lpsz)+128;
+    if(max>dim)max=dim;
+    for(u=-7;u<=7;u++){
+      j=(_dl->o[0]+u*_dl->size[0]>>lpsz)+128;
+      if(j<0||j>=dim)continue;
+      for(i=min;i<max;i++)gimg[i*dim+j]=0x7F;
+    }
+  }
+  fout=fopen("undistorted_hom.png","wb");
+  image_write_png(gimg,dim,dim,fout);
+  fclose(fout);
+  free(gimg);
+}
+#endif
+
+
+
+/*A homography from one region of the grid back to the image.
+  Unlike a qr_hom, this does not include an inverse transform and maps directly
+   from the grid points, not a square with power-of-two sides.*/
+struct qr_hom_cell{
+  int fwd[3][3];
+  int x0;
+  int y0;
+  int u0;
+  int v0;
+};
+
+
+static void qr_hom_cell_init(qr_hom_cell *_cell,int _u0,int _v0,
+ int _u1,int _v1,int _u2,int _v2,int _u3,int _v3,int _x0,int _y0,
+ int _x1,int _y1,int _x2,int _y2,int _x3,int _y3){
+  int du10;
+  int du20;
+  int du30;
+  int du31;
+  int du32;
+  int dv10;
+  int dv20;
+  int dv30;
+  int dv31;
+  int dv32;
+  int dx10;
+  int dx20;
+  int dx30;
+  int dx31;
+  int dx32;
+  int dy10;
+  int dy20;
+  int dy30;
+  int dy31;
+  int dy32;
+  int a00;
+  int a01;
+  int a02;
+  int a10;
+  int a11;
+  int a12;
+  int a20;
+  int a21;
+  int a22;
+  int i00;
+  int i01;
+  int i10;
+  int i11;
+  int i20;
+  int i21;
+  int i22;
+  int b0;
+  int b1;
+  int b2;
+  int shift;
+  int round;
+  int x;
+  int y;
+  int w;
+  /*First, correct for the arrangement of the source points.
+    We take advantage of the fact that we know the source points have a very
+     limited dynamic range (so there will never be overflow) and a small amount
+     of projective distortion.*/
+  du10=_u1-_u0;
+  du20=_u2-_u0;
+  du30=_u3-_u0;
+  du31=_u3-_u1;
+  du32=_u3-_u2;
+  dv10=_v1-_v0;
+  dv20=_v2-_v0;
+  dv30=_v3-_v0;
+  dv31=_v3-_v1;
+  dv32=_v3-_v2;
+  /*Compute the coefficients of the forward transform from the unit square to
+     the source point configuration.*/
+  a20=du32*dv10-du10*dv32;
+  a21=du20*dv31-du31*dv20;
+  if(a20||a21)a22=du32*dv31-du31*dv32;
+  /*If the source grid points aren't in a non-affine arrangement, there's no
+     reason to scale everything by du32*dv31-du31*dv32.
+    Not doing so allows a much larger dynamic range, and is the only way we can
+     initialize a base cell that covers the whole grid.*/
+  else a22=1;
+  a00=du10*(a20+a22);
+  a01=du20*(a21+a22);
+  a10=dv10*(a20+a22);
+  a11=dv20*(a21+a22);
+  /*Now compute the inverse transform.*/
+  i00=a11*a22;
+  i01=-a01*a22;
+  i10=-a10*a22;
+  i11=a00*a22;
+  i20=a10*a21-a11*a20;
+  i21=a01*a20-a00*a21;
+  i22=a00*a11-a01*a10;
+  /*Invert the coefficients.
+    Since i22 is the largest, we divide it by all the others.
+    The quotient is often exact (e.g., when the source points contain no
+     projective distortion), and is never zero.
+    Hence we can use zero to signal "infinity" when the divisor is zero.*/
+  if(i00)i00=QR_FLIPSIGNI(QR_DIVROUND(i22,abs(i00)),i00);
+  if(i01)i01=QR_FLIPSIGNI(QR_DIVROUND(i22,abs(i01)),i01);
+  if(i10)i10=QR_FLIPSIGNI(QR_DIVROUND(i22,abs(i10)),i10);
+  if(i11)i11=QR_FLIPSIGNI(QR_DIVROUND(i22,abs(i11)),i11);
+  if(i20)i20=QR_FLIPSIGNI(QR_DIVROUND(i22,abs(i20)),i20);
+  if(i21)i21=QR_FLIPSIGNI(QR_DIVROUND(i22,abs(i21)),i21);
+  /*Now compute the map from the unit square into the image.*/
+  dx10=_x1-_x0;
+  dx20=_x2-_x0;
+  dx30=_x3-_x0;
+  dx31=_x3-_x1;
+  dx32=_x3-_x2;
+  dy10=_y1-_y0;
+  dy20=_y2-_y0;
+  dy30=_y3-_y0;
+  dy31=_y3-_y1;
+  dy32=_y3-_y2;
+  a20=dx32*dy10-dx10*dy32;
+  a21=dx20*dy31-dx31*dy20;
+  a22=dx32*dy31-dx31*dy32;
+  /*Figure out if we need to downscale anything.*/
+  b0=qr_ilog(QR_MAXI(abs(dx10),abs(dy10)))+qr_ilog(abs(a20+a22));
+  b1=qr_ilog(QR_MAXI(abs(dx20),abs(dy20)))+qr_ilog(abs(a21+a22));
+  b2=qr_ilog(QR_MAXI(QR_MAXI(abs(a20),abs(a21)),abs(a22)));
+  shift=QR_MAXI(0,QR_MAXI(QR_MAXI(b0,b1),b2)-(QR_INT_BITS-3-QR_ALIGN_SUBPREC));
+  round=(1<<shift)>>1;
+  /*Compute the final coefficients of the forward transform.*/
+  a00=QR_FIXMUL(dx10,a20+a22,round,shift);
+  a01=QR_FIXMUL(dx20,a21+a22,round,shift);
+  a10=QR_FIXMUL(dy10,a20+a22,round,shift);
+  a11=QR_FIXMUL(dy20,a21+a22,round,shift);
+  /*And compose the two transforms.
+    Since we inverted the coefficients above, we divide by them here instead
+     of multiplying.
+    This lets us take advantage of the full dynamic range.
+    Note a zero divisor is really "infinity", and thus the quotient should also
+     be zero.*/
+  _cell->fwd[0][0]=(i00?QR_DIVROUND(a00,i00):0)+(i10?QR_DIVROUND(a01,i10):0);
+  _cell->fwd[0][1]=(i01?QR_DIVROUND(a00,i01):0)+(i11?QR_DIVROUND(a01,i11):0);
+  _cell->fwd[1][0]=(i00?QR_DIVROUND(a10,i00):0)+(i10?QR_DIVROUND(a11,i10):0);
+  _cell->fwd[1][1]=(i01?QR_DIVROUND(a10,i01):0)+(i11?QR_DIVROUND(a11,i11):0);
+  _cell->fwd[2][0]=(i00?QR_DIVROUND(a20,i00):0)+(i10?QR_DIVROUND(a21,i10):0)
+   +(i20?QR_DIVROUND(a22,i20):0)+round>>shift;
+  _cell->fwd[2][1]=(i01?QR_DIVROUND(a20,i01):0)+(i11?QR_DIVROUND(a21,i11):0)
+   +(i21?QR_DIVROUND(a22,i21):0)+round>>shift;
+  _cell->fwd[2][2]=a22+round>>shift;
+  /*Mathematically, a02 and a12 are exactly zero.
+    However, that concentrates all of the rounding error in the (_u3,_v3)
+     corner; we compute offsets which distribute it over the whole range.*/
+  x=_cell->fwd[0][0]*du10+_cell->fwd[0][1]*dv10;
+  y=_cell->fwd[1][0]*du10+_cell->fwd[1][1]*dv10;
+  w=_cell->fwd[2][0]*du10+_cell->fwd[2][1]*dv10+_cell->fwd[2][2];
+  a02=dx10*w-x;
+  a12=dy10*w-y;
+  x=_cell->fwd[0][0]*du20+_cell->fwd[0][1]*dv20;
+  y=_cell->fwd[1][0]*du20+_cell->fwd[1][1]*dv20;
+  w=_cell->fwd[2][0]*du20+_cell->fwd[2][1]*dv20+_cell->fwd[2][2];
+  a02+=dx20*w-x;
+  a12+=dy20*w-y;
+  x=_cell->fwd[0][0]*du30+_cell->fwd[0][1]*dv30;
+  y=_cell->fwd[1][0]*du30+_cell->fwd[1][1]*dv30;
+  w=_cell->fwd[2][0]*du30+_cell->fwd[2][1]*dv30+_cell->fwd[2][2];
+  a02+=dx30*w-x;
+  a12+=dy30*w-y;
+  _cell->fwd[0][2]=a02+2>>2;
+  _cell->fwd[1][2]=a12+2>>2;
+  _cell->x0=_x0;
+  _cell->y0=_y0;
+  _cell->u0=_u0;
+  _cell->v0=_v0;
+}
+
+/*Finish a partial projection, converting from homogeneous coordinates to the
+   normal 2-D representation.
+  In loops, we can avoid many multiplies by computing the homogeneous _x, _y,
+   and _w incrementally, but we cannot avoid the divisions, done here.*/
+static void qr_hom_cell_fproject(qr_point _p,const qr_hom_cell *_cell,
+ int _x,int _y,int _w){
+  if(_w==0){
+    _p[0]=_x<0?INT_MIN:INT_MAX;
+    _p[1]=_y<0?INT_MIN:INT_MAX;
+  }
+  else{
+    if(_w<0){
+      _x=-_x;
+      _y=-_y;
+      _w=-_w;
+    }
+    _p[0]=QR_DIVROUND(_x,_w)+_cell->x0;
+    _p[1]=QR_DIVROUND(_y,_w)+_cell->y0;
+  }
+}
+
+static void qr_hom_cell_project(qr_point _p,const qr_hom_cell *_cell,
+ int _u,int _v,int _res){
+  _u-=_cell->u0<<_res;
+  _v-=_cell->v0<<_res;
+  qr_hom_cell_fproject(_p,_cell,
+   _cell->fwd[0][0]*_u+_cell->fwd[0][1]*_v+(_cell->fwd[0][2]<<_res),
+   _cell->fwd[1][0]*_u+_cell->fwd[1][1]*_v+(_cell->fwd[1][2]<<_res),
+   _cell->fwd[2][0]*_u+_cell->fwd[2][1]*_v+(_cell->fwd[2][2]<<_res));
+}
+
+
+
+/*Retrieves the bits corresponding to the alignment pattern template centered
+   at the given location in the original image (at subpel precision).*/
+static unsigned qr_alignment_pattern_fetch(qr_point _p[5][5],int _x0,int _y0,
+ const unsigned char *_img,int _width,int _height){
+  unsigned v;
+  int      i;
+  int      j;
+  int      k;
+  int      dx;
+  int      dy;
+  dx=_x0-_p[2][2][0];
+  dy=_y0-_p[2][2][1];
+  v=0;
+  for(k=i=0;i<5;i++)for(j=0;j<5;j++,k++){
+    v|=qr_img_get_bit(_img,_width,_height,_p[i][j][0]+dx,_p[i][j][1]+dy)<<k;
+  }
+  return v;
+}
+
+/*Searches for an alignment pattern near the given location.*/
+static int qr_alignment_pattern_search(qr_point _p,const qr_hom_cell *_cell,
+ int _u,int _v,int _r,const unsigned char *_img,int _width,int _height){
+  qr_point c[4];
+  int      nc[4];
+  qr_point p[5][5];
+  qr_point pc;
+  unsigned best_match;
+  int      best_dist;
+  int      bestx;
+  int      besty;
+  unsigned match;
+  int      dist;
+  int      u;
+  int      v;
+  int      x0;
+  int      y0;
+  int      w0;
+  int      x;
+  int      y;
+  int      w;
+  int      dxdu;
+  int      dydu;
+  int      dwdu;
+  int      dxdv;
+  int      dydv;
+  int      dwdv;
+  int      dx;
+  int      dy;
+  int      i;
+  int      j;
+  /*Build up a basic template using _cell to control shape and scale.
+    We project the points in the template back to the image just once, since if
+     the alignment pattern has moved, we don't really know why.
+    If it's because of radial distortion, or the code wasn't flat, or something
+     else, there's no reason to expect that a re-projection around each
+     subsequent search point would be any closer to the actual shape than our
+     first projection.
+    Therefore we simply slide this template around, as is.*/
+  u=(_u-2)-_cell->u0;
+  v=(_v-2)-_cell->v0;
+  x0=_cell->fwd[0][0]*u+_cell->fwd[0][1]*v+_cell->fwd[0][2];
+  y0=_cell->fwd[1][0]*u+_cell->fwd[1][1]*v+_cell->fwd[1][2];
+  w0=_cell->fwd[2][0]*u+_cell->fwd[2][1]*v+_cell->fwd[2][2];
+  dxdu=_cell->fwd[0][0];
+  dydu=_cell->fwd[1][0];
+  dwdu=_cell->fwd[2][0];
+  dxdv=_cell->fwd[0][1];
+  dydv=_cell->fwd[1][1];
+  dwdv=_cell->fwd[2][1];
+  for(i=0;i<5;i++){
+    x=x0;
+    y=y0;
+    w=w0;
+    for(j=0;j<5;j++){
+      qr_hom_cell_fproject(p[i][j],_cell,x,y,w);
+      x+=dxdu;
+      y+=dydu;
+      w+=dwdu;
+    }
+    x0+=dxdv;
+    y0+=dydv;
+    w0+=dwdv;
+  }
+  bestx=p[2][2][0];
+  besty=p[2][2][1];
+  best_match=qr_alignment_pattern_fetch(p,bestx,besty,_img,_width,_height);
+  best_dist=qr_hamming_dist(best_match,0x1F8D63F,25);
+  if(best_dist>0){
+    u=_u-_cell->u0;
+    v=_v-_cell->v0;
+    x=_cell->fwd[0][0]*u+_cell->fwd[0][1]*v+_cell->fwd[0][2]<<QR_ALIGN_SUBPREC;
+    y=_cell->fwd[1][0]*u+_cell->fwd[1][1]*v+_cell->fwd[1][2]<<QR_ALIGN_SUBPREC;
+    w=_cell->fwd[2][0]*u+_cell->fwd[2][1]*v+_cell->fwd[2][2]<<QR_ALIGN_SUBPREC;
+    /*Search an area at most _r modules around the target location, in
+       concentric squares..*/
+    for(i=1;i<_r<<QR_ALIGN_SUBPREC;i++){
+      int side_len;
+      side_len=(i<<1)-1;
+      x-=dxdu+dxdv;
+      y-=dydu+dydv;
+      w-=dwdu+dwdv;
+      for(j=0;j<4*side_len;j++){
+        int      dir;
+        qr_hom_cell_fproject(pc,_cell,x,y,w);
+        match=qr_alignment_pattern_fetch(p,pc[0],pc[1],_img,_width,_height);
+        dist=qr_hamming_dist(match,0x1F8D63F,best_dist+1);
+        if(dist<best_dist){
+          best_match=match;
+          best_dist=dist;
+          bestx=pc[0];
+          besty=pc[1];
+        }
+        if(j<2*side_len){
+          dir=j>=side_len;
+          x+=_cell->fwd[0][dir];
+          y+=_cell->fwd[1][dir];
+          w+=_cell->fwd[2][dir];
+        }
+        else{
+          dir=j>=3*side_len;
+          x-=_cell->fwd[0][dir];
+          y-=_cell->fwd[1][dir];
+          w-=_cell->fwd[2][dir];
+        }
+        if(!best_dist)break;
+      }
+      if(!best_dist)break;
+    }
+  }
+  /*If the best result we got was sufficiently bad, reject the match.
+    If we're wrong and we include it, we can grossly distort the nearby
+     region, whereas using the initial starting point should at least be
+     consistent with the geometry we already have.*/
+  if(best_dist>6){
+    _p[0]=p[2][2][0];
+    _p[1]=p[2][2][1];
+    return -1;
+  }
+  /*Now try to get a more accurate location of the pattern center.*/
+  dx=bestx-p[2][2][0];
+  dy=besty-p[2][2][1];
+  memset(nc,0,sizeof(nc));
+  memset(c,0,sizeof(c));
+  /*We consider 8 lines across the finder pattern in turn.
+    If we actually found a symmetric pattern along that line, search for its
+     exact center in the image.
+    There are plenty more lines we could use if these don't work, but if we've
+     found anything remotely close to an alignment pattern, we should be able
+     to use most of these.*/
+  for(i=0;i<8;i++){
+    static const unsigned MASK_TESTS[8][2]={
+      {0x1040041,0x1000001},{0x0041040,0x0001000},
+      {0x0110110,0x0100010},{0x0011100,0x0001000},
+      {0x0420084,0x0400004},{0x0021080,0x0001000},
+      {0x0006C00,0x0004400},{0x0003800,0x0001000},
+    };
+    static const unsigned char MASK_COORDS[8][2]={
+      {0,0},{1,1},{4,0},{3,1},{2,0},{2,1},{0,2},{1,2}
+    };
+    if((best_match&MASK_TESTS[i][0])==MASK_TESTS[i][1]){
+      int x0;
+      int y0;
+      int x1;
+      int y1;
+      x0=p[MASK_COORDS[i][1]][MASK_COORDS[i][0]][0]+dx>>QR_FINDER_SUBPREC;
+      if(x0<0||x0>=_width)continue;
+      y0=p[MASK_COORDS[i][1]][MASK_COORDS[i][0]][1]+dy>>QR_FINDER_SUBPREC;
+      if(y0<0||y0>=_height)continue;
+      x1=p[4-MASK_COORDS[i][1]][4-MASK_COORDS[i][0]][0]+dx>>QR_FINDER_SUBPREC;
+      if(x1<0||x1>=_width)continue;
+      y1=p[4-MASK_COORDS[i][1]][4-MASK_COORDS[i][0]][1]+dy>>QR_FINDER_SUBPREC;
+      if(y1<0||y1>=_height)continue;
+      if(!qr_finder_locate_crossing(_img,_width,_height,x0,y0,x1,y1,i&1,pc)){
+        int w;
+        int cx;
+        int cy;
+        cx=pc[0]-bestx;
+        cy=pc[1]-besty;
+        if(i&1){
+          /*Weight crossings around the center dot more highly, as they are
+             generally more reliable.*/
+          w=3;
+          cx+=cx<<1;
+          cy+=cy<<1;
+        }
+        else w=1;
+        nc[i>>1]+=w;
+        c[i>>1][0]+=cx;
+        c[i>>1][1]+=cy;
+      }
+    }
+  }
+  /*Sum offsets from lines in orthogonal directions.*/
+  for(i=0;i<2;i++){
+    int a;
+    int b;
+    a=nc[i<<1];
+    b=nc[i<<1|1];
+    if(a&&b){
+      int w;
+      w=QR_MAXI(a,b);
+      c[i<<1][0]=QR_DIVROUND(w*(b*c[i<<1][0]+a*c[i<<1|1][0]),a*b);
+      c[i<<1][1]=QR_DIVROUND(w*(b*c[i<<1][1]+a*c[i<<1|1][1]),a*b);
+      nc[i<<1]=w<<1;
+    }
+    else{
+      c[i<<1][0]+=c[i<<1|1][0];
+      c[i<<1][1]+=c[i<<1|1][1];
+      nc[i<<1]+=b;
+    }
+  }
+  /*Average offsets from pairs of orthogonal lines.*/
+  c[0][0]+=c[2][0];
+  c[0][1]+=c[2][1];
+  nc[0]+=nc[2];
+  /*If we actually found any such lines, apply the adjustment.*/
+  if(nc[0]){
+    dx=QR_DIVROUND(c[0][0],nc[0]);
+    dy=QR_DIVROUND(c[0][1],nc[0]);
+    /*But only if it doesn't make things worse.*/
+    match=qr_alignment_pattern_fetch(p,bestx+dx,besty+dy,_img,_width,_height);
+    dist=qr_hamming_dist(match,0x1F8D63F,best_dist+1);
+    if(dist<=best_dist){
+      bestx+=dx;
+      besty+=dy;
+    }
+  }
+  _p[0]=bestx;
+  _p[1]=besty;
+  return 0;
+}
+
+static int qr_hom_fit(qr_hom *_hom,qr_finder *_ul,qr_finder *_ur,
+ qr_finder *_dl,qr_point _p[4],const qr_aff *_aff,isaac_ctx *_isaac,
+ const unsigned char *_img,int _width,int _height){
+  qr_point *b;
+  int       nb;
+  int       cb;
+  qr_point *r;
+  int       nr;
+  int       cr;
+  qr_line   l[4];
+  qr_point  q;
+  qr_point  p;
+  int       ox;
+  int       oy;
+  int       ru;
+  int       rv;
+  int       dru;
+  int       drv;
+  int       bu;
+  int       bv;
+  int       dbu;
+  int       dbv;
+  int       rx;
+  int       ry;
+  int       drxi;
+  int       dryi;
+  int       drxj;
+  int       dryj;
+  int       rdone;
+  int       nrempty;
+  int       rlastfit;
+  int       bx;
+  int       by;
+  int       dbxi;
+  int       dbyi;
+  int       dbxj;
+  int       dbyj;
+  int       bdone;
+  int       nbempty;
+  int       blastfit;
+  int       shift;
+  int       round;
+  int       version4;
+  int       brx;
+  int       bry;
+  int       i;
+  /*We attempt to correct large-scale perspective distortion by fitting lines
+     to the edge of the code area.
+    We could also look for an alignment pattern now, but that wouldn't work for
+     version 1 codes, which have no alignment pattern.
+    Even if the code is supposed to have one, there's go guarantee we'd find it
+     intact.*/
+  /*Fitting lines is easy for the edges on which we have two finder patterns.
+    After the fit, UL is guaranteed to be on the proper side, but if either of
+     the other two finder patterns aren't, something is wrong.*/
+  qr_finder_ransac(_ul,_aff,_isaac,0);
+  qr_finder_ransac(_dl,_aff,_isaac,0);
+  qr_line_fit_finder_pair(l[0],_aff,_ul,_dl,0);
+  if(qr_line_eval(l[0],_dl->c->pos[0],_dl->c->pos[1])<0||
+   qr_line_eval(l[0],_ur->c->pos[0],_ur->c->pos[1])<0){
+    return -1;
+  }
+  qr_finder_ransac(_ul,_aff,_isaac,2);
+  qr_finder_ransac(_ur,_aff,_isaac,2);
+  qr_line_fit_finder_pair(l[2],_aff,_ul,_ur,2);
+  if(qr_line_eval(l[2],_dl->c->pos[0],_dl->c->pos[1])<0||
+   qr_line_eval(l[2],_ur->c->pos[0],_ur->c->pos[1])<0){
+    return -1;
+  }
+  /*The edges which only have one finder pattern are more difficult.
+    We start by fitting a line to the edge of the one finder pattern we do
+     have.
+    This can fail due to an insufficient number of sample points, and even if
+     it succeeds can be fairly inaccurate, because all of the points are
+     clustered in one corner of the QR code.
+    If it fails, we just use an axis-aligned line in the affine coordinate
+     system.
+    Then we walk along the edge of the entire code, looking for
+     light:dark:light patterns perpendicular to the edge.
+    Wherever we find one, we take the center of the dark portion as an
+     additional sample point.
+    At the end, we re-fit the line using all such sample points found.*/
+  drv=_ur->size[1]>>1;
+  qr_finder_ransac(_ur,_aff,_isaac,1);
+  if(qr_line_fit_finder_edge(l[1],_ur,1,_aff->res)>=0){
+    if(qr_line_eval(l[1],_ul->c->pos[0],_ul->c->pos[1])<0||
+     qr_line_eval(l[1],_dl->c->pos[0],_dl->c->pos[1])<0){
+      return -1;
+    }
+    /*Figure out the change in ru for a given change in rv when stepping along
+       the fitted line.*/
+    if(qr_aff_line_step(_aff,l[1],1,drv,&dru)<0)return -1;
+  }
+  else dru=0;
+  ru=_ur->o[0]+3*_ur->size[0]-2*dru;
+  rv=_ur->o[1]-2*drv;
+  dbu=_dl->size[0]>>1;
+  qr_finder_ransac(_dl,_aff,_isaac,3);
+  if(qr_line_fit_finder_edge(l[3],_dl,3,_aff->res)>=0){
+    if(qr_line_eval(l[3],_ul->c->pos[0],_ul->c->pos[1])<0||
+     qr_line_eval(l[3],_ur->c->pos[0],_ur->c->pos[1])<0){
+      return -1;
+    }
+    /*Figure out the change in bv for a given change in bu when stepping along
+       the fitted line.*/
+    if(qr_aff_line_step(_aff,l[3],0,dbu,&dbv)<0)return -1;
+  }
+  else dbv=0;
+  bu=_dl->o[0]-2*dbu;
+  bv=_dl->o[1]+3*_dl->size[1]-2*dbv;
+  /*Set up the initial point lists.*/
+  nr=rlastfit=_ur->ninliers[1];
+  cr=nr+(_dl->o[1]-rv+drv-1)/drv;
+  r=(qr_point *)malloc(cr*sizeof(*r));
+  for(i=0;i<_ur->ninliers[1];i++){
+    memcpy(r[i],_ur->edge_pts[1][i].pos,sizeof(r[i]));
+  }
+  nb=blastfit=_dl->ninliers[3];
+  cb=nb+(_ur->o[0]-bu+dbu-1)/dbu;
+  b=(qr_point *)malloc(cb*sizeof(*b));
+  for(i=0;i<_dl->ninliers[3];i++){
+    memcpy(b[i],_dl->edge_pts[3][i].pos,sizeof(b[i]));
+  }
+  /*Set up the step parameters for the affine projection.*/
+  ox=(_aff->x0<<_aff->res)+(1<<_aff->res-1);
+  oy=(_aff->y0<<_aff->res)+(1<<_aff->res-1);
+  rx=_aff->fwd[0][0]*ru+_aff->fwd[0][1]*rv+ox;
+  ry=_aff->fwd[1][0]*ru+_aff->fwd[1][1]*rv+oy;
+  drxi=_aff->fwd[0][0]*dru+_aff->fwd[0][1]*drv;
+  dryi=_aff->fwd[1][0]*dru+_aff->fwd[1][1]*drv;
+  drxj=_aff->fwd[0][0]*_ur->size[0];
+  dryj=_aff->fwd[1][0]*_ur->size[0];
+  bx=_aff->fwd[0][0]*bu+_aff->fwd[0][1]*bv+ox;
+  by=_aff->fwd[1][0]*bu+_aff->fwd[1][1]*bv+oy;
+  dbxi=_aff->fwd[0][0]*dbu+_aff->fwd[0][1]*dbv;
+  dbyi=_aff->fwd[1][0]*dbu+_aff->fwd[1][1]*dbv;
+  dbxj=_aff->fwd[0][1]*_dl->size[1];
+  dbyj=_aff->fwd[1][1]*_dl->size[1];
+  /*Now step along the lines, looking for new sample points.*/
+  nrempty=nbempty=0;
+  for(;;){
+    int ret;
+    int x0;
+    int y0;
+    int x1;
+    int y1;
+    /*If we take too many steps without encountering a non-zero pixel, assume
+       we have wandered off the edge and stop looking before we hit the other
+       side of the quiet region.
+      Otherwise, stop when the lines cross (if they do so inside the affine
+       region) or come close to crossing (outside the affine region).
+      TODO: We don't have any way of detecting when we've wandered into the
+       code interior; we could stop if the outside sample ever shows up dark,
+       but this could happen because of noise in the quiet region, too.*/
+    rdone=rv>=QR_MINI(bv,_dl->o[1]+bv>>1)||nrempty>14;
+    bdone=bu>=QR_MINI(ru,_ur->o[0]+ru>>1)||nbempty>14;
+    if(!rdone&&(bdone||rv<bu)){
+      x0=rx+drxj>>_aff->res+QR_FINDER_SUBPREC;
+      y0=ry+dryj>>_aff->res+QR_FINDER_SUBPREC;
+      x1=rx-drxj>>_aff->res+QR_FINDER_SUBPREC;
+      y1=ry-dryj>>_aff->res+QR_FINDER_SUBPREC;
+      if(nr>=cr){
+        cr=cr<<1|1;
+        r=(qr_point *)realloc(r,cr*sizeof(*r));
+      }
+      ret=qr_finder_quick_crossing_check(_img,_width,_height,x0,y0,x1,y1,1);
+      if(!ret){
+        ret=qr_finder_locate_crossing(_img,_width,_height,x0,y0,x1,y1,1,r[nr]);
+      }
+      if(ret>=0){
+        if(!ret){
+          qr_aff_unproject(q,_aff,r[nr][0],r[nr][1]);
+          /*Move the current point halfway towards the crossing.
+            We don't move the whole way to give us some robustness to noise.*/
+          ru=ru+q[0]>>1;
+          /*But ensure that rv monotonically increases.*/
+          if(q[1]+drv>rv)rv=rv+q[1]>>1;
+          rx=_aff->fwd[0][0]*ru+_aff->fwd[0][1]*rv+ox;
+          ry=_aff->fwd[1][0]*ru+_aff->fwd[1][1]*rv+oy;
+          nr++;
+          /*Re-fit the line to update the step direction periodically.*/
+          if(nr>QR_MAXI(1,rlastfit+(rlastfit>>2))){
+            qr_line_fit_points(l[1],r,nr,_aff->res);
+            if(qr_aff_line_step(_aff,l[1],1,drv,&dru)>=0){
+              drxi=_aff->fwd[0][0]*dru+_aff->fwd[0][1]*drv;
+              dryi=_aff->fwd[1][0]*dru+_aff->fwd[1][1]*drv;
+            }
+            rlastfit=nr;
+          }
+        }
+        else nrempty=0;
+      }
+      else nrempty++;
+      ru+=dru;
+      /*Our final defense: if we overflow, stop.*/
+      if(rv+drv>rv)rv+=drv;
+      else nrempty=INT_MAX;
+      rx+=drxi;
+      ry+=dryi;
+    }
+    else if(!bdone){
+      x0=bx+dbxj>>_aff->res+QR_FINDER_SUBPREC;
+      y0=by+dbyj>>_aff->res+QR_FINDER_SUBPREC;
+      x1=bx-dbxj>>_aff->res+QR_FINDER_SUBPREC;
+      y1=by-dbyj>>_aff->res+QR_FINDER_SUBPREC;
+      if(nb>=cb){
+        cb=cb<<1|1;
+        b=(qr_point *)realloc(b,cb*sizeof(*b));
+      }
+      ret=qr_finder_quick_crossing_check(_img,_width,_height,x0,y0,x1,y1,1);
+      if(!ret){
+        ret=qr_finder_locate_crossing(_img,_width,_height,x0,y0,x1,y1,1,b[nb]);
+      }
+      if(ret>=0){
+        if(!ret){
+          qr_aff_unproject(q,_aff,b[nb][0],b[nb][1]);
+          /*Move the current point halfway towards the crossing.
+            We don't move the whole way to give us some robustness to noise.*/
+          /*But ensure that bu monotonically increases.*/
+          if(q[0]+dbu>bu)bu=bu+q[0]>>1;
+          bv=bv+q[1]>>1;
+          bx=_aff->fwd[0][0]*bu+_aff->fwd[0][1]*bv+ox;
+          by=_aff->fwd[1][0]*bu+_aff->fwd[1][1]*bv+oy;
+          nb++;
+          /*Re-fit the line to update the step direction periodically.*/
+          if(nb>QR_MAXI(1,blastfit+(blastfit>>2))){
+            qr_line_fit_points(l[3],b,nb,_aff->res);
+            if(qr_aff_line_step(_aff,l[3],0,dbu,&dbv)>=0){
+              dbxi=_aff->fwd[0][0]*dbu+_aff->fwd[0][1]*dbv;
+              dbyi=_aff->fwd[1][0]*dbu+_aff->fwd[1][1]*dbv;
+            }
+            blastfit=nb;
+          }
+        }
+        nbempty=0;
+      }
+      else nbempty++;
+      /*Our final defense: if we overflow, stop.*/
+      if(bu+dbu>bu)bu+=dbu;
+      else nbempty=INT_MAX;
+      bv+=dbv;
+      bx+=dbxi;
+      by+=dbyi;
+    }
+    else break;
+  }
+  /*Fit the new lines.
+    If we _still_ don't have enough sample points, then just use an
+     axis-aligned line from the affine coordinate system (e.g., one parallel
+     to the opposite edge in the image).*/
+  if(nr>1)qr_line_fit_points(l[1],r,nr,_aff->res);
+  else{
+    qr_aff_project(p,_aff,_ur->o[0]+3*_ur->size[0],_ur->o[1]);
+    shift=QR_MAXI(0,
+     qr_ilog(QR_MAXI(abs(_aff->fwd[0][1]),abs(_aff->fwd[1][1])))
+     -(_aff->res+1>>1));
+    round=(1<<shift)>>1;
+    l[1][0]=_aff->fwd[1][1]+round>>shift;
+    l[1][1]=-_aff->fwd[0][1]+round>>shift;
+    l[1][2]=-(l[1][0]*p[0]+l[1][1]*p[1]);
+  }
+  free(r);
+  if(nb>1)qr_line_fit_points(l[3],b,nb,_aff->res);
+  else{
+    qr_aff_project(p,_aff,_dl->o[0],_dl->o[1]+3*_dl->size[1]);
+    shift=QR_MAXI(0,
+     qr_ilog(QR_MAXI(abs(_aff->fwd[0][1]),abs(_aff->fwd[1][1])))
+     -(_aff->res+1>>1));
+    round=(1<<shift)>>1;
+    l[3][0]=_aff->fwd[1][0]+round>>shift;
+    l[3][1]=-_aff->fwd[0][0]+round>>shift;
+    l[3][2]=-(l[1][0]*p[0]+l[1][1]*p[1]);
+  }
+  free(b);
+  for(i=0;i<4;i++){
+    if(qr_line_isect(_p[i],l[i&1],l[2+(i>>1)])<0)return -1;
+    /*It's plausible for points to be somewhat outside the image, but too far
+       and too much of the pattern will be gone for it to be decodable.*/
+    if(_p[i][0]<-_width<<QR_FINDER_SUBPREC||
+     _p[i][0]>=_width<<QR_FINDER_SUBPREC+1||
+     _p[i][1]<-_height<<QR_FINDER_SUBPREC||
+     _p[i][1]>=_height<<QR_FINDER_SUBPREC+1){
+      return -1;
+    }
+  }
+  /*By default, use the edge intersection point for the bottom-right corner.*/
+  brx=_p[3][0];
+  bry=_p[3][1];
+  /*However, if our average version estimate is greater than 1, NOW we try to
+     search for an alignment pattern.
+    We get a much better success rate by doing this after our initial attempt
+     to promote the transform to a homography than before.
+    You might also think it would be more reliable to use the interior finder
+     pattern edges, since the outer ones may be obscured or damaged, and it
+     would save us a reprojection below, since they would form a nice square
+     with the location of the alignment pattern, but this turns out to be a bad
+     idea.
+    Non-linear distortion is usually maximal on the outside edge, and thus
+     estimating the grid position from points on the interior means we might
+     get mis-aligned by the time we reach the edge.*/
+  version4=_ul->eversion[0]+_ul->eversion[1]+_ur->eversion[0]+_dl->eversion[1];
+  if(version4>4){
+    qr_hom_cell cell;
+    qr_point    p3;
+    int         dim;
+    dim=17+version4;
+    qr_hom_cell_init(&cell,0,0,dim-1,0,0,dim-1,dim-1,dim-1,
+     _p[0][0],_p[0][1],_p[1][0],_p[1][1],
+     _p[2][0],_p[2][1],_p[3][0],_p[3][1]);
+    if(qr_alignment_pattern_search(p3,&cell,dim-7,dim-7,4,
+     _img,_width,_height)>=0){
+      int c21;
+      int dx21;
+      int dy21;
+      int mask;
+      int w;
+      /*There's no real need to update the bounding box corner, and in fact we
+         actively perform worse if we do.
+        Clearly it was good enough for us to find this alignment pattern, so
+         it should be good enough to use for grid initialization.
+        The point of doing the search was to get more accurate version
+         estimates and a better chance of decoding the version and format info.
+        This is particularly important for small versions that have no encoded
+         version info, since any mismatch in version renders the code
+         undecodable.*/
+      /*We do, however, need four points in a square to initialize our
+         homography, so project the point from the alignment center to the
+         corner of the code area.*/
+      c21=_p[2][0]*_p[1][1]-_p[2][1]*_p[1][0];
+      dx21=_p[2][0]-_p[1][0];
+      dy21=_p[2][1]-_p[1][1];
+      w=(dim-7)*c21
+       +(dim-13)*(_p[0][0]*dy21-_p[0][1]*dx21)+6*(p3[0]*dy21-p3[1]*dx21);
+      mask=QR_SIGNMASK(w);
+      w=abs(w);
+      brx=(int)QR_DIVROUND(QR_EXTMUL((dim-7)*_p[0][0],p3[0]*dy21,
+       QR_EXTMUL((dim-13)*p3[0],c21-_p[0][1]*dx21,
+       QR_EXTMUL(6*_p[0][0],c21-p3[1]*dx21,0)))+mask^mask,w);
+      bry=(int)QR_DIVROUND(QR_EXTMUL((dim-7)*_p[0][1],-p3[1]*dx21,
+       QR_EXTMUL((dim-13)*p3[1],c21+_p[0][0]*dy21,
+       QR_EXTMUL(6*_p[0][1],c21+p3[0]*dy21,0)))+mask^mask,w);
+    }
+  }
+  /*Now we have four points that map to a square: initialize the projection.*/
+  qr_hom_init(_hom,_p[0][0],_p[0][1],_p[1][0],_p[1][1],
+   _p[2][0],_p[2][1],brx,bry,QR_HOM_BITS);
+  return 0;
+}
+
+
+
+/*The BCH(18,6,3) codes are only used for version information, which must lie
+   between 7 and 40 (inclusive).*/
+static const unsigned BCH18_6_CODES[34]={
+                                                          0x07C94,
+  0x085BC,0x09A99,0x0A4D3,0x0BBF6,0x0C762,0x0D847,0x0E60D,0x0F928,
+  0x10B78,0x1145D,0x12A17,0x13532,0x149A6,0x15683,0x168C9,0x177EC,
+  0x18EC4,0x191E1,0x1AFAB,0x1B08E,0x1CC1A,0x1D33F,0x1ED75,0x1F250,
+  0x209D5,0x216F0,0x228BA,0x2379F,0x24B0B,0x2542E,0x26A64,0x27541,
+  0x28C69
+};
+
+/*Corrects a BCH(18,6,3) code word.
+  _y: Contains the code word to be checked on input, and the corrected value on
+       output.
+  Return: The number of errors.
+          If more than 3 errors are detected, returns a negative value and
+           performs no correction.*/
+static int bch18_6_correct(unsigned *_y){
+  unsigned x;
+  unsigned y;
+  int      nerrs;
+  y=*_y;
+  /*Check the easy case first: see if the data bits were uncorrupted.*/
+  x=y>>12;
+  if(x>=7&&x<=40){
+    nerrs=qr_hamming_dist(y,BCH18_6_CODES[x-7],4);
+    if(nerrs<4){
+      *_y=BCH18_6_CODES[x-7];
+      return nerrs;
+    }
+  }
+  /*Exhaustive search is faster than field operations in GF(19).*/
+  for(x=0;x<34;x++)if(x+7!=y>>12){
+    nerrs=qr_hamming_dist(y,BCH18_6_CODES[x],4);
+    if(nerrs<4){
+      *_y=BCH18_6_CODES[x];
+      return nerrs;
+    }
+  }
+  return -1;
+}
+
+#if 0
+static unsigned bch18_6_encode(unsigned _x){
+  return (-(_x&1)&0x01F25)^(-(_x>>1&1)&0x0216F)^(-(_x>>2&1)&0x042DE)^
+   (-(_x>>3&1)&0x085BC)^(-(_x>>4&1)&0x10B78)^(-(_x>>5&1)&0x209D5);
+}
+#endif
+
+/*Reads the version bits near a finder module and decodes the version number.*/
+static int qr_finder_version_decode(qr_finder *_f,const qr_hom *_hom,
+ const unsigned char *_img,int _width,int _height,int _dir){
+  qr_point q;
+  unsigned v;
+  int      x0;
+  int      y0;
+  int      w0;
+  int      dxi;
+  int      dyi;
+  int      dwi;
+  int      dxj;
+  int      dyj;
+  int      dwj;
+  int      ret;
+  int      i;
+  int      j;
+  int      k;
+  v=0;
+  q[_dir]=_f->o[_dir]-7*_f->size[_dir];
+  q[1-_dir]=_f->o[1-_dir]-3*_f->size[1-_dir];
+  x0=_hom->fwd[0][0]*q[0]+_hom->fwd[0][1]*q[1];
+  y0=_hom->fwd[1][0]*q[0]+_hom->fwd[1][1]*q[1];
+  w0=_hom->fwd[2][0]*q[0]+_hom->fwd[2][1]*q[1]+_hom->fwd22;
+  dxi=_hom->fwd[0][1-_dir]*_f->size[1-_dir];
+  dyi=_hom->fwd[1][1-_dir]*_f->size[1-_dir];
+  dwi=_hom->fwd[2][1-_dir]*_f->size[1-_dir];
+  dxj=_hom->fwd[0][_dir]*_f->size[_dir];
+  dyj=_hom->fwd[1][_dir]*_f->size[_dir];
+  dwj=_hom->fwd[2][_dir]*_f->size[_dir];
+  for(k=i=0;i<6;i++){
+    int x;
+    int y;
+    int w;
+    x=x0;
+    y=y0;
+    w=w0;
+    for(j=0;j<3;j++,k++){
+      qr_point p;
+      qr_hom_fproject(p,_hom,x,y,w);
+      v|=qr_img_get_bit(_img,_width,_height,p[0],p[1])<<k;
+      x+=dxj;
+      y+=dyj;
+      w+=dwj;
+    }
+    x0+=dxi;
+    y0+=dyi;
+    w0+=dwi;
+  }
+  ret=bch18_6_correct(&v);
+  /*TODO: I'd certainly hope the order the version bits is accessed in is
+     well-defined, but I seem to have images for two different codes with the
+     same version using two different orders?
+    Maybe the other one is a model 1 code?
+    Even if I parse the version here, I can't decode the rest of the code.
+    If this is really needed, we should just re-order the bits.*/
+#if 0
+  if(ret<0){
+    /*17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+       0  3  6  9 12 15  1  4  7 10 13 16  2  5  8 11 14 17
+      17 13  9  5  1 -3 10  6  2 -2 -6-10  3 -1 -5 -9-13-17*/
+    v=0;
+    for(k=i=0;i<3;i++){
+      p[_dir]=_f->o[_dir]+_f->size[_dir]*(-5-i);
+      for(j=0;j<6;j++,k++){
+        qr_point q;
+        p[1-_dir]=_f->o[1-_dir]+_f->size[1-_dir]*(2-j);
+        qr_hom_project(q,_hom,p[0],p[1]);
+        v|=qr_img_get_bit(_img,_width,_height,q[0],q[1])<<k;
+      }
+    }
+    ret=bch18_6_correct(&v);
+  }
+#endif
+  return ret>=0?(int)(v>>12):ret;
+}
+
+/*Reads the format info bits near the finder modules and decodes them.*/
+static int qr_finder_fmt_info_decode(qr_finder *_ul,qr_finder *_ur,
+ qr_finder *_dl,const qr_hom *_hom,
+ const unsigned char *_img,int _width,int _height){
+  qr_point p;
+  unsigned lo[2];
+  unsigned hi[2];
+  int      u;
+  int      v;
+  int      x;
+  int      y;
+  int      w;
+  int      dx;
+  int      dy;
+  int      dw;
+  int      fmt_info[4];
+  int      count[4];
+  int      nerrs[4];
+  int      nfmt_info;
+  int      besti;
+  int      imax;
+  int      di;
+  int      i;
+  int      k;
+  /*Read the bits around the UL corner.*/
+  lo[0]=0;
+  u=_ul->o[0]+5*_ul->size[0];
+  v=_ul->o[1]-3*_ul->size[1];
+  x=_hom->fwd[0][0]*u+_hom->fwd[0][1]*v;
+  y=_hom->fwd[1][0]*u+_hom->fwd[1][1]*v;
+  w=_hom->fwd[2][0]*u+_hom->fwd[2][1]*v+_hom->fwd22;
+  dx=_hom->fwd[0][1]*_ul->size[1];
+  dy=_hom->fwd[1][1]*_ul->size[1];
+  dw=_hom->fwd[2][1]*_ul->size[1];
+  for(k=i=0;;i++){
+    /*Skip the timing pattern row.*/
+    if(i!=6){
+      qr_hom_fproject(p,_hom,x,y,w);
+      lo[0]|=qr_img_get_bit(_img,_width,_height,p[0],p[1])<<k++;
+      /*Don't advance q in the last iteration... we'll start the next loop from
+         the current position.*/
+      if(i>=8)break;
+    }
+    x+=dx;
+    y+=dy;
+    w+=dw;
+  }
+  hi[0]=0;
+  dx=-_hom->fwd[0][0]*_ul->size[0];
+  dy=-_hom->fwd[1][0]*_ul->size[0];
+  dw=-_hom->fwd[2][0]*_ul->size[0];
+  while(i-->0){
+    x+=dx;
+    y+=dy;
+    w+=dw;
+    /*Skip the timing pattern column.*/
+    if(i!=6){
+      qr_hom_fproject(p,_hom,x,y,w);
+      hi[0]|=qr_img_get_bit(_img,_width,_height,p[0],p[1])<<k++;
+    }
+  }
+  /*Read the bits next to the UR corner.*/
+  lo[1]=0;
+  u=_ur->o[0]+3*_ur->size[0];
+  v=_ur->o[1]+5*_ur->size[1];
+  x=_hom->fwd[0][0]*u+_hom->fwd[0][1]*v;
+  y=_hom->fwd[1][0]*u+_hom->fwd[1][1]*v;
+  w=_hom->fwd[2][0]*u+_hom->fwd[2][1]*v+_hom->fwd22;
+  dx=-_hom->fwd[0][0]*_ur->size[0];
+  dy=-_hom->fwd[1][0]*_ur->size[0];
+  dw=-_hom->fwd[2][0]*_ur->size[0];
+  for(k=0;k<8;k++){
+    qr_hom_fproject(p,_hom,x,y,w);
+    lo[1]|=qr_img_get_bit(_img,_width,_height,p[0],p[1])<<k;
+    x+=dx;
+    y+=dy;
+    w+=dw;
+  }
+  /*Read the bits next to the DL corner.*/
+  hi[1]=0;
+  u=_dl->o[0]+5*_dl->size[0];
+  v=_dl->o[1]-3*_dl->size[1];
+  x=_hom->fwd[0][0]*u+_hom->fwd[0][1]*v;
+  y=_hom->fwd[1][0]*u+_hom->fwd[1][1]*v;
+  w=_hom->fwd[2][0]*u+_hom->fwd[2][1]*v+_hom->fwd22;
+  dx=_hom->fwd[0][1]*_dl->size[1];
+  dy=_hom->fwd[1][1]*_dl->size[1];
+  dw=_hom->fwd[2][1]*_dl->size[1];
+  for(k=8;k<15;k++){
+    qr_hom_fproject(p,_hom,x,y,w);
+    hi[1]|=qr_img_get_bit(_img,_width,_height,p[0],p[1])<<k;
+    x+=dx;
+    y+=dy;
+    w+=dw;
+  }
+  /*For the 8th bit we have 3 samples... use the majority value.
+    TODO: The DL bit appears to be wrong as much as right? Guess it's not
+     really a third copy after all, but doesn't appear to be used for data.
+  i=((lo[0]>>7&1)+(lo[1]>>7&1)+(hi[1]>>7&1)>>1)<<7;
+  lo[0]=lo[0]&~0x80|i;
+  lo[1]=lo[1]&~0x80|i;
+  hi[1]&=~0x80;*/
+  /*For the remaining bits we have two samples... try them in all
+     combinations and pick the most popular valid code, breaking ties using
+     the number of bit errors.*/
+  imax=2<<(hi[0]!=hi[1]);
+  di=1+(lo[0]==lo[1]);
+  nfmt_info=0;
+  for(i=0;i<imax;i+=di){
+    unsigned v;
+    int      ret;
+    int      j;
+    v=(lo[i&1]|hi[i>>1])^0x5412;
+    ret=bch15_5_correct(&v);
+    v>>=10;
+    if(ret<0)ret=4;
+    for(j=0;;j++){
+      if(j>=nfmt_info){
+        fmt_info[j]=v;
+        count[j]=1;
+        nerrs[j]=ret;
+        nfmt_info++;
+        break;
+      }
+      if(fmt_info[j]==(int)v){
+        count[j]++;
+        if(ret<nerrs[j])nerrs[j]=ret;
+        break;
+      }
+    }
+  }
+  besti=0;
+  for(i=1;i<nfmt_info;i++){
+    if(nerrs[besti]>3&&nerrs[i]<=3||
+     count[i]>count[besti]||count[i]==count[besti]&&nerrs[i]<nerrs[besti]){
+      besti=i;
+    }
+  }
+  return nerrs[besti]<4?fmt_info[besti]:-1;
+}
+
+
+
+/*The grid used to sample the image bits.
+  The grid is divided into separate cells bounded by finder patterns and/or
+   alignment patterns, and a separate map back to the original image is
+   constructed for each cell.
+  All of these structural elements, as well as the timing patterns, version
+   info, and format info, are marked in fpmask so they can easily be skipped
+   during decode.*/
+struct qr_sampling_grid{
+  qr_hom_cell    *cells[6];
+  unsigned       *fpmask;
+  int             cell_limits[6];
+  int             ncells;
+};
+
+
+/*Mark a given region as belonging to the function pattern.*/
+static void qr_sampling_grid_fp_mask_rect(qr_sampling_grid *_grid,int _dim,
+ int _u,int _v,int _w,int _h){
+  int i;
+  int j;
+  int stride;
+  stride=_dim+QR_INT_BITS-1>>QR_INT_LOGBITS;
+  /*Note that we store bits column-wise, since that's how they're read out of
+     the grid.*/
+  for(j=_u;j<_u+_w;j++)for(i=_v;i<_v+_h;i++){
+    _grid->fpmask[j*stride+(i>>QR_INT_LOGBITS)]|=1<<(i&QR_INT_BITS-1);
+  }
+}
+
+/*Determine if a given grid location is inside the function pattern.*/
+static int qr_sampling_grid_is_in_fp(const qr_sampling_grid *_grid,int _dim,
+ int _u,int _v){
+  return _grid->fpmask[_u*(_dim+QR_INT_BITS-1>>QR_INT_LOGBITS)
+   +(_v>>QR_INT_LOGBITS)]>>(_v&QR_INT_BITS-1)&1;
+}
+
+/*The spacing between alignment patterns after the second for versions >= 7.
+  We could compact this more, but the code to access it would eliminate the
+   gains.*/
+static const unsigned char QR_ALIGNMENT_SPACING[34]={
+  16,18,20,22,24,26,28,
+  20,22,24,24,26,28,28,
+  22,24,24,26,26,28,28,
+  24,24,26,26,26,28,28,
+  24,26,26,26,28,28
+};
+
+static inline void qr_svg_points(const char *cls,
+                                 qr_point *p,
+                                 int n)
+{
+    svg_path_start(cls, 1, 0, 0);
+    int i;
+    for(i = 0; i < n; i++, p++)
+        svg_path_moveto(SVG_ABS, p[0][0], p[0][1]);
+    svg_path_end();
+}
+
+/*Initialize the sampling grid for each region of the code.
+  _version:  The (decoded) version number.
+  _ul_pos:   The location of the UL finder pattern.
+  _ur_pos:   The location of the UR finder pattern.
+  _dl_pos:   The location of the DL finder pattern.
+  _p:        On input, contains estimated positions of the four corner modules.
+             On output, contains a bounding quadrilateral for the code.
+  _img:      The binary input image.
+  _width:    The width of the input image.
+  _height:   The height of the input image.
+  Return: 0 on success, or a negative value on error.*/
+static void qr_sampling_grid_init(qr_sampling_grid *_grid,int _version,
+ const qr_point _ul_pos,const qr_point _ur_pos,const qr_point _dl_pos,
+ qr_point _p[4],const unsigned char *_img,int _width,int _height){
+  qr_hom_cell          base_cell;
+  int                  align_pos[7];
+  int                  dim;
+  int                  nalign;
+  int                  i;
+  dim=17+(_version<<2);
+  nalign=(_version/7)+2;
+  /*Create a base cell to bootstrap the alignment pattern search.*/
+  qr_hom_cell_init(&base_cell,0,0,dim-1,0,0,dim-1,dim-1,dim-1,
+   _p[0][0],_p[0][1],_p[1][0],_p[1][1],_p[2][0],_p[2][1],_p[3][0],_p[3][1]);
+  /*Allocate the array of cells.*/
+  _grid->ncells=nalign-1;
+  _grid->cells[0]=(qr_hom_cell *)malloc(
+   (nalign-1)*(nalign-1)*sizeof(*_grid->cells[0]));
+  for(i=1;i<_grid->ncells;i++)_grid->cells[i]=_grid->cells[i-1]+_grid->ncells;
+  /*Initialize the function pattern mask.*/
+  _grid->fpmask=(unsigned *)calloc(dim,
+   (dim+QR_INT_BITS-1>>QR_INT_LOGBITS)*sizeof(*_grid->fpmask));
+  /*Mask out the finder patterns (and separators and format info bits).*/
+  qr_sampling_grid_fp_mask_rect(_grid,dim,0,0,9,9);
+  qr_sampling_grid_fp_mask_rect(_grid,dim,0,dim-8,9,8);
+  qr_sampling_grid_fp_mask_rect(_grid,dim,dim-8,0,8,9);
+  /*Mask out the version number bits.*/
+  if(_version>6){
+    qr_sampling_grid_fp_mask_rect(_grid,dim,0,dim-11,6,3);
+    qr_sampling_grid_fp_mask_rect(_grid,dim,dim-11,0,3,6);
+  }
+  /*Mask out the timing patterns.*/
+  qr_sampling_grid_fp_mask_rect(_grid,dim,9,6,dim-17,1);
+  qr_sampling_grid_fp_mask_rect(_grid,dim,6,9,1,dim-17);
+  /*If we have no alignment patterns (e.g., this is a version 1 code), just use
+     the base cell and hope it's good enough.*/
+  if(_version<2)memcpy(_grid->cells[0],&base_cell,sizeof(base_cell));
+  else{
+    qr_point *q;
+    qr_point *p;
+    int       j;
+    int       k;
+    q=(qr_point *)malloc(nalign*nalign*sizeof(*q));
+    p=(qr_point *)malloc(nalign*nalign*sizeof(*p));
+    /*Initialize the alignment pattern position list.*/
+    align_pos[0]=6;
+    align_pos[nalign-1]=dim-7;
+    if(_version>6){
+      int d;
+      d=QR_ALIGNMENT_SPACING[_version-7];
+      for(i=nalign-1;i-->1;)align_pos[i]=align_pos[i+1]-d;
+    }
+    /*Three of the corners use a finder pattern instead of a separate
+       alignment pattern.*/
+    q[0][0]=3;
+    q[0][1]=3;
+    p[0][0]=_ul_pos[0];
+    p[0][1]=_ul_pos[1];
+    q[nalign-1][0]=dim-4;
+    q[nalign-1][1]=3;
+    p[nalign-1][0]=_ur_pos[0];
+    p[nalign-1][1]=_ur_pos[1];
+    q[(nalign-1)*nalign][0]=3;
+    q[(nalign-1)*nalign][1]=dim-4;
+    p[(nalign-1)*nalign][0]=_dl_pos[0];
+    p[(nalign-1)*nalign][1]=_dl_pos[1];
+    /*Scan for alignment patterns using a diagonal sweep.*/
+    for(k=1;k<2*nalign-1;k++){
+      int jmin;
+      int jmax;
+      jmax=QR_MINI(k,nalign-1)-(k==nalign-1);
+      jmin=QR_MAXI(0,k-(nalign-1))+(k==nalign-1);
+      for(j=jmin;j<=jmax;j++){
+        qr_hom_cell *cell;
+        int          u;
+        int          v;
+        int          k;
+        i=jmax-(j-jmin);
+        k=i*nalign+j;
+        u=align_pos[j];
+        v=align_pos[i];
+        q[k][0]=u;
+        q[k][1]=v;
+        /*Mask out the alignment pattern.*/
+        qr_sampling_grid_fp_mask_rect(_grid,dim,u-2,v-2,5,5);
+        /*Pick a cell to use to govern the alignment pattern search.*/
+        if(i>1&&j>1){
+          qr_point p0;
+          qr_point p1;
+          qr_point p2;
+          /*Each predictor is basically a straight-line extrapolation from two
+             neighboring alignment patterns (except possibly near the opposing
+             finder patterns).*/
+          qr_hom_cell_project(p0,_grid->cells[i-2]+j-1,u,v,0);
+          qr_hom_cell_project(p1,_grid->cells[i-2]+j-2,u,v,0);
+          qr_hom_cell_project(p2,_grid->cells[i-1]+j-2,u,v,0);
+          /*Take the median of the predictions as the search center.*/
+          QR_SORT2I(p0[0],p1[0]);
+          QR_SORT2I(p0[1],p1[1]);
+          QR_SORT2I(p1[0],p2[0]);
+          QR_SORT2I(p1[1],p2[1]);
+          QR_SORT2I(p0[0],p1[0]);
+          QR_SORT2I(p0[1],p1[1]);
+          /*We need a cell that has the target point at a known (u,v) location.
+            Since our cells don't have inverses, just construct one from our
+             neighboring points.*/
+          cell=_grid->cells[i-1]+j-1;
+          qr_hom_cell_init(cell,
+           q[k-nalign-1][0],q[k-nalign-1][1],q[k-nalign][0],q[k-nalign][1],
+           q[k-1][0],q[k-1][1],q[k][0],q[k][1],
+           p[k-nalign-1][0],p[k-nalign-1][1],p[k-nalign][0],p[k-nalign][1],
+           p[k-1][0],p[k-1][1],p1[0],p1[1]);
+        }
+        else if(i>1&&j>0)cell=_grid->cells[i-2]+j-1;
+        else if(i>0&&j>1)cell=_grid->cells[i-1]+j-2;
+        else cell=&base_cell;
+        /*Use a very small search radius.
+          A large displacement here usually means a false positive (e.g., when
+           the real alignment pattern is damaged or missing), which can
+           severely distort the projection.*/
+        qr_alignment_pattern_search(p[k],cell,u,v,2,_img,_width,_height);
+        if(i>0&&j>0){
+          qr_hom_cell_init(_grid->cells[i-1]+j-1,
+           q[k-nalign-1][0],q[k-nalign-1][1],q[k-nalign][0],q[k-nalign][1],
+           q[k-1][0],q[k-1][1],q[k][0],q[k][1],
+           p[k-nalign-1][0],p[k-nalign-1][1],p[k-nalign][0],p[k-nalign][1],
+           p[k-1][0],p[k-1][1],p[k][0],p[k][1]);
+        }
+      }
+    }
+    qr_svg_points("align", p, nalign * nalign);
+    free(q);
+    free(p);
+  }
+  /*Set the limits over which each cell is used.*/
+  memcpy(_grid->cell_limits,align_pos+1,
+   (_grid->ncells-1)*sizeof(*_grid->cell_limits));
+  _grid->cell_limits[_grid->ncells-1]=dim;
+  /*Produce a bounding square for the code (to mark finder centers with).
+    Because of non-linear distortion, this might not actually bound the code,
+     but it should be good enough.
+    I don't think it's worth computing a convex hull or anything silly like
+     that.*/
+  qr_hom_cell_project(_p[0],_grid->cells[0]+0,-1,-1,1);
+  qr_hom_cell_project(_p[1],_grid->cells[0]+_grid->ncells-1,(dim<<1)-1,-1,1);
+  qr_hom_cell_project(_p[2],_grid->cells[_grid->ncells-1]+0,-1,(dim<<1)-1,1);
+  qr_hom_cell_project(_p[3],_grid->cells[_grid->ncells-1]+_grid->ncells-1,
+   (dim<<1)-1,(dim<<1)-1,1);
+  /*Clamp the points somewhere near the image (this is really just in case a
+     corner is near the plane at infinity).*/
+  for(i=0;i<4;i++){
+    _p[i][0]=QR_CLAMPI(-_width<<QR_FINDER_SUBPREC,_p[i][0],
+     _width<<QR_FINDER_SUBPREC+1);
+    _p[i][1]=QR_CLAMPI(-_height<<QR_FINDER_SUBPREC,_p[i][1],
+     _height<<QR_FINDER_SUBPREC+1);
+  }
+  /*TODO: Make fine adjustments using the timing patterns.
+    Possible strategy: scan the timing pattern at QR_ALIGN_SUBPREC (or finer)
+     resolution, use dynamic programming to match midpoints between
+     transitions to the ideal grid locations.*/
+}
+
+static void qr_sampling_grid_clear(qr_sampling_grid *_grid){
+  free(_grid->fpmask);
+  free(_grid->cells[0]);
+}
+
+
+
+#if defined(QR_DEBUG)
+static void qr_sampling_grid_dump(qr_sampling_grid *_grid,int _version,
+ const unsigned char *_img,int _width,int _height){
+  unsigned char *gimg;
+  FILE          *fout;
+  int            dim;
+  int            u;
+  int            v;
+  int            x;
+  int            y;
+  int            w;
+  int            i;
+  int            j;
+  int            r;
+  int            s;
+  dim=17+(_version<<2)+8<<QR_ALIGN_SUBPREC;
+  gimg=(unsigned char *)malloc(dim*dim*sizeof(*gimg));
+  for(i=0;i<dim;i++)for(j=0;j<dim;j++){
+    qr_hom_cell *cell;
+    if(i>=(4<<QR_ALIGN_SUBPREC)&&i<=dim-(5<<QR_ALIGN_SUBPREC)&&
+     j>=(4<<QR_ALIGN_SUBPREC)&&j<=dim-(5<<QR_ALIGN_SUBPREC)&&
+     ((!(i&(1<<QR_ALIGN_SUBPREC)-1))^(!(j&(1<<QR_ALIGN_SUBPREC)-1)))){
+      gimg[i*dim+j]=0x7F;
+    }
+    else{
+      qr_point p;
+      u=(j>>QR_ALIGN_SUBPREC)-4;
+      v=(i>>QR_ALIGN_SUBPREC)-4;
+      for(r=0;r<_grid->ncells-1;r++)if(u<_grid->cell_limits[r])break;
+      for(s=0;s<_grid->ncells-1;s++)if(v<_grid->cell_limits[s])break;
+      cell=_grid->cells[s]+r;
+      u=j-(cell->u0+4<<QR_ALIGN_SUBPREC);
+      v=i-(cell->v0+4<<QR_ALIGN_SUBPREC);
+      x=cell->fwd[0][0]*u+cell->fwd[0][1]*v+(cell->fwd[0][2]<<QR_ALIGN_SUBPREC);
+      y=cell->fwd[1][0]*u+cell->fwd[1][1]*v+(cell->fwd[1][2]<<QR_ALIGN_SUBPREC);
+      w=cell->fwd[2][0]*u+cell->fwd[2][1]*v+(cell->fwd[2][2]<<QR_ALIGN_SUBPREC);
+      qr_hom_cell_fproject(p,cell,x,y,w);
+      gimg[i*dim+j]=_img[
+       QR_CLAMPI(0,p[1]>>QR_FINDER_SUBPREC,_height-1)*_width+
+       QR_CLAMPI(0,p[0]>>QR_FINDER_SUBPREC,_width-1)];
+    }
+  }
+  for(v=0;v<17+(_version<<2);v++)for(u=0;u<17+(_version<<2);u++){
+    if(qr_sampling_grid_is_in_fp(_grid,17+(_version<<2),u,v)){
+      j=u+4<<QR_ALIGN_SUBPREC;
+      i=v+4<<QR_ALIGN_SUBPREC;
+      gimg[(i-1)*dim+j-1]=0x7F;
+      gimg[(i-1)*dim+j]=0x7F;
+      gimg[(i-1)*dim+j+1]=0x7F;
+      gimg[i*dim+j-1]=0x7F;
+      gimg[i*dim+j+1]=0x7F;
+      gimg[(i+1)*dim+j-1]=0x7F;
+      gimg[(i+1)*dim+j]=0x7F;
+      gimg[(i+1)*dim+j+1]=0x7F;
+    }
+  }
+  fout=fopen("grid.png","wb");
+  image_write_png(gimg,dim,dim,fout);
+  fclose(fout);
+  free(gimg);
+}
+#endif
+
+/*Generate the data mask corresponding to the given mask pattern.*/
+static void qr_data_mask_fill(unsigned *_mask,int _dim,int _pattern){
+  int stride;
+  int i;
+  int j;
+  stride=_dim+QR_INT_BITS-1>>QR_INT_LOGBITS;
+  /*Note that we store bits column-wise, since that's how they're read out of
+     the grid.*/
+  switch(_pattern){
+    /*10101010 i+j+1&1
+      01010101
+      10101010
+      01010101*/
+    case 0:{
+      int m;
+      m=0x55;
+      for(j=0;j<_dim;j++){
+        memset(_mask+j*stride,m,stride*sizeof(*_mask));
+        m^=0xFF;
+      }
+    }break;
+    /*11111111 i+1&1
+      00000000
+      11111111
+      00000000*/
+    case 1:memset(_mask,0x55,_dim*stride*sizeof(*_mask));break;
+    /*10010010 (j+1)%3&1
+      10010010
+      10010010
+      10010010*/
+    case 2:{
+      unsigned m;
+      m=0xFF;
+      for(j=0;j<_dim;j++){
+        memset(_mask+j*stride,m&0xFF,stride*sizeof(*_mask));
+        m=m<<8|m>>16;
+      }
+    }break;
+    /*10010010 (i+j+1)%3&1
+      00100100
+      01001001
+      10010010*/
+    case 3:{
+      unsigned mi;
+      unsigned mj;
+      mj=0;
+      for(i=0;i<(QR_INT_BITS+2)/3;i++)mj|=1<<3*i;
+      for(j=0;j<_dim;j++){
+        mi=mj;
+        for(i=0;i<stride;i++){
+          _mask[j*stride+i]=mi;
+          mi=mi>>QR_INT_BITS%3|mi<<3-QR_INT_BITS%3;
+        }
+        mj=mj>>1|mj<<2;
+      }
+    }break;
+    /*11100011 (i>>1)+(j/3)+1&1
+      11100011
+      00011100
+      00011100*/
+    case 4:{
+      unsigned m;
+      m=7;
+      for(j=0;j<_dim;j++){
+        memset(_mask+j*stride,(0xCC^-(m&1))&0xFF,stride*sizeof(*_mask));
+        m=m>>1|m<<5;
+      }
+    }break;
+    /*11111111 !((i*j)%6)
+      10000010
+      10010010
+      10101010*/
+    case 5:{
+      for(j=0;j<_dim;j++){
+        unsigned m;
+        m=0;
+        for(i=0;i<6;i++)m|=!((i*j)%6)<<i;
+        for(i=6;i<QR_INT_BITS;i<<=1)m|=m<<i;
+        for(i=0;i<stride;i++){
+          _mask[j*stride+i]=m;
+          m=m>>QR_INT_BITS%6|m<<6-QR_INT_BITS%6;
+        }
+      }
+    }break;
+    /*11111111 (i*j)%3+i*j+1&1
+      11100011
+      11011011
+      10101010*/
+    case 6:{
+      for(j=0;j<_dim;j++){
+        unsigned m;
+        m=0;
+        for(i=0;i<6;i++)m|=((i*j)%3+i*j+1&1)<<i;
+        for(i=6;i<QR_INT_BITS;i<<=1)m|=m<<i;
+        for(i=0;i<stride;i++){
+          _mask[j*stride+i]=m;
+          m=m>>QR_INT_BITS%6|m<<6-QR_INT_BITS%6;
+        }
+      }
+    }break;
+    /*10101010 (i*j)%3+i+j+1&1
+      00011100
+      10001110
+      01010101*/
+    default:{
+      for(j=0;j<_dim;j++){
+        unsigned m;
+        m=0;
+        for(i=0;i<6;i++)m|=((i*j)%3+i+j+1&1)<<i;
+        for(i=6;i<QR_INT_BITS;i<<=1)m|=m<<i;
+        for(i=0;i<stride;i++){
+          _mask[j*stride+i]=m;
+          m=m>>QR_INT_BITS%6|m<<6-QR_INT_BITS%6;
+        }
+      }
+    }break;
+  }
+}
+
+static void qr_sampling_grid_sample(const qr_sampling_grid *_grid,
+ unsigned *_data_bits,int _dim,int _fmt_info,
+ const unsigned char *_img,int _width,int _height){
+  int stride;
+  int u0;
+  int u1;
+  int j;
+  /*We initialize the buffer with the data mask and XOR bits into it as we read
+     them out of the image instead of unmasking in a separate step.*/
+  qr_data_mask_fill(_data_bits,_dim,_fmt_info&7);
+  stride=_dim+QR_INT_BITS-1>>QR_INT_LOGBITS;
+  u0=0;
+  svg_path_start("sampling-grid", 1, 0, 0);
+  /*We read data cell-by-cell to avoid having to constantly change which
+     projection we're using as we read each bit.
+    This (and the position-dependent data mask) is the reason we buffer the
+     bits we read instead of converting them directly to codewords here.
+    Note that bits are stored column-wise, since that's how we'll scan them.*/
+  for(j=0;j<_grid->ncells;j++){
+    int i;
+    int v0;
+    int v1;
+    u1=_grid->cell_limits[j];
+    v0=0;
+    for(i=0;i<_grid->ncells;i++){
+      qr_hom_cell *cell;
+      int          x0;
+      int          y0;
+      int          w0;
+      int          u;
+      int          du;
+      int          dv;
+      v1=_grid->cell_limits[i];
+      cell=_grid->cells[i]+j;
+      du=u0-cell->u0;
+      dv=v0-cell->v0;
+      x0=cell->fwd[0][0]*du+cell->fwd[0][1]*dv+cell->fwd[0][2];
+      y0=cell->fwd[1][0]*du+cell->fwd[1][1]*dv+cell->fwd[1][2];
+      w0=cell->fwd[2][0]*du+cell->fwd[2][1]*dv+cell->fwd[2][2];
+      for(u=u0;u<u1;u++){
+        int x;
+        int y;
+        int w;
+        int v;
+        x=x0;
+        y=y0;
+        w=w0;
+        for(v=v0;v<v1;v++){
+          /*Skip doing all the divisions and bounds checks if the bit is in the
+             function pattern.*/
+          if(!qr_sampling_grid_is_in_fp(_grid,_dim,u,v)){
+            qr_point p;
+            qr_hom_cell_fproject(p,cell,x,y,w);
+            _data_bits[u*stride+(v>>QR_INT_LOGBITS)]^=
+             qr_img_get_bit(_img,_width,_height,p[0],p[1])<<(v&QR_INT_BITS-1);
+            svg_path_moveto(SVG_ABS, p[0], p[1]);
+          }
+          x+=cell->fwd[0][1];
+          y+=cell->fwd[1][1];
+          w+=cell->fwd[2][1];
+        }
+        x0+=cell->fwd[0][0];
+        y0+=cell->fwd[1][0];
+        w0+=cell->fwd[2][0];
+      }
+      v0=v1;
+    }
+    u0=u1;
+  }
+  svg_path_end();
+}
+
+/*Arranges the sample bits read by qr_sampling_grid_sample() into bytes and
+   groups those bytes into Reed-Solomon blocks.
+  The individual block pointers are destroyed by this routine.*/
+static void qr_samples_unpack(unsigned char **_blocks,int _nblocks,
+ int _nshort_data,int _nshort_blocks,const unsigned *_data_bits,
+ const unsigned *_fp_mask,int _dim){
+  unsigned bits;
+  int      biti;
+  int      stride;
+  int      blocki;
+  int      blockj;
+  int      i;
+  int      j;
+  stride=_dim+QR_INT_BITS-1>>QR_INT_LOGBITS;
+  /*If _all_ the blocks are short, don't skip anything (see below).*/
+  if(_nshort_blocks>=_nblocks)_nshort_blocks=0;
+  /*Scan columns in pairs from right to left.*/
+  bits=0;
+  for(blocki=blockj=biti=0,j=_dim-1;j>0;j-=2){
+    unsigned data1;
+    unsigned data2;
+    unsigned fp_mask1;
+    unsigned fp_mask2;
+    int      nbits;
+    int      l;
+    /*Scan up a pair of columns.*/
+    nbits=(_dim-1&QR_INT_BITS-1)+1;
+    l=j*stride;
+    for(i=stride;i-->0;){
+      data1=_data_bits[l+i];
+      fp_mask1=_fp_mask[l+i];
+      data2=_data_bits[l+i-stride];
+      fp_mask2=_fp_mask[l+i-stride];
+      while(nbits-->0){
+        /*Pull a bit from the right column.*/
+        if(!(fp_mask1>>nbits&1)){
+          bits=bits<<1|data1>>nbits&1;
+          biti++;
+        }
+        /*Pull a bit from the left column.*/
+        if(!(fp_mask2>>nbits&1)){
+          bits=bits<<1|data2>>nbits&1;
+          biti++;
+        }
+        /*If we finished a byte, drop it in a block.*/
+        if(biti>=8){
+          biti-=8;
+          *_blocks[blocki++]++=(unsigned char)(bits>>biti);
+          /*For whatever reason, the long blocks are at the _end_ of the list,
+             instead of the beginning.
+            Even worse, the extra bytes they get come at the end of the data
+             bytes, before the parity bytes.
+            Hence the logic here: when we've filled up the data portion of the
+             short blocks, skip directly to the long blocks for the next byte.
+            It's also the reason we increment _blocks[blocki] on each store,
+             instead of just indexing with blockj (after this iteration the
+             number of bytes in each block differs).*/
+          if(blocki>=_nblocks)blocki=++blockj==_nshort_data?_nshort_blocks:0;
+        }
+      }
+      nbits=QR_INT_BITS;
+    }
+    j-=2;
+    /*Skip the column with the vertical timing pattern.*/
+    if(j==6)j--;
+    /*Scan down a pair of columns.*/
+    l=j*stride;
+    for(i=0;i<stride;i++){
+      data1=_data_bits[l+i];
+      fp_mask1=_fp_mask[l+i];
+      data2=_data_bits[l+i-stride];
+      fp_mask2=_fp_mask[l+i-stride];
+      nbits=QR_MINI(_dim-(i<<QR_INT_LOGBITS),QR_INT_BITS);
+      while(nbits-->0){
+        /*Pull a bit from the right column.*/
+        if(!(fp_mask1&1)){
+          bits=bits<<1|data1&1;
+          biti++;
+        }
+        data1>>=1;
+        fp_mask1>>=1;
+        /*Pull a bit from the left column.*/
+        if(!(fp_mask2&1)){
+          bits=bits<<1|data2&1;
+          biti++;
+        }
+        data2>>=1;
+        fp_mask2>>=1;
+        /*If we finished a byte, drop it in a block.*/
+        if(biti>=8){
+          biti-=8;
+          *_blocks[blocki++]++=(unsigned char)(bits>>biti);
+          /*See comments on the "up" loop for the reason behind this mess.*/
+          if(blocki>=_nblocks)blocki=++blockj==_nshort_data?_nshort_blocks:0;
+        }
+      }
+    }
+  }
+}
+
+
+/*Bit reading code blatantly stolen^W^Wadapted from libogg/libtheora (because
+   I've already debugged it and I know it works).
+  Portions (C) Xiph.Org Foundation 1994-2008, BSD-style license.*/
+struct qr_pack_buf{
+  const unsigned char *buf;
+  int                  endbyte;
+  int                  endbit;
+  int                  storage;
+};
+
+
+static void qr_pack_buf_init(qr_pack_buf *_b,
+ const unsigned char *_data,int _ndata){
+  _b->buf=_data;
+  _b->storage=_ndata;
+  _b->endbyte=_b->endbit=0;
+}
+
+/*Assumes 0<=_bits<=16.*/
+static int qr_pack_buf_read(qr_pack_buf *_b,int _bits){
+  const unsigned char *p;
+  unsigned             ret;
+  int                  m;
+  int                  d;
+  m=16-_bits;
+  _bits+=_b->endbit;
+  d=_b->storage-_b->endbyte;
+  if(d<=2){
+    /*Not the main path.*/
+    if(d*8<_bits){
+      _b->endbyte+=_bits>>3;
+      _b->endbit=_bits&7;
+      return -1;
+    }
+    /*Special case to avoid reading p[0] below, which might be past the end of
+       the buffer; also skips some useless accounting.*/
+    else if(!_bits)return 0;
+  }
+  p=_b->buf+_b->endbyte;
+  ret=p[0]<<8+_b->endbit;
+  if(_bits>8){
+    ret|=p[1]<<_b->endbit;
+    if(_bits>16)ret|=p[2]>>8-_b->endbit;
+  }
+  _b->endbyte+=_bits>>3;
+  _b->endbit=_bits&7;
+  return (ret&0xFFFF)>>m;
+}
+
+static int qr_pack_buf_avail(const qr_pack_buf *_b){
+  return (_b->storage-_b->endbyte<<3)-_b->endbit;
+}
+
+
+/*The characters available in QR_MODE_ALNUM.*/
+static const unsigned char QR_ALNUM_TABLE[45]={
+  '0','1','2','3','4','5','6','7','8','9',
+  'A','B','C','D','E','F','G','H','I','J',
+  'K','L','M','N','O','P','Q','R','S','T',
+  'U','V','W','X','Y','Z',' ','$','%','*',
+  '+','-','.','/',':'
+};
+
+static int qr_code_data_parse(qr_code_data *_qrdata,int _version,
+ const unsigned char *_data,int _ndata){
+  qr_pack_buf qpb;
+  int         centries;
+  int         len_bits_idx;
+  /*Entries are stored directly in the struct during parsing.
+    Caller cleans up any allocated data on failure.*/
+  _qrdata->entries=NULL;
+  _qrdata->nentries=0;
+  _qrdata->sa_size=0;
+  centries=0;
+  /*The versions are divided into 3 ranges that each use a different number of
+     bits for length fields.*/
+  len_bits_idx=(_version>9)+(_version>26);
+  qr_pack_buf_init(&qpb,_data,_ndata);
+  /*While we have enough bits to read a mode...*/
+  while(qr_pack_buf_avail(&qpb)>=4){
+    qr_code_data_entry *entry;
+    int                 mode;
+    mode=qr_pack_buf_read(&qpb,4);
+    /*Mode 0 is a terminator.*/
+    if(!mode)break;
+    if(_qrdata->nentries>=centries){
+      centries=centries<<1|1;
+      _qrdata->entries=(qr_code_data_entry *)realloc(_qrdata->entries,
+       centries*sizeof(*_qrdata->entries));
+    }
+    entry=_qrdata->entries+_qrdata->nentries++;
+    /*Set the mode to an invalid value until we allocate a buffer for it.
+      This ensures we don't try to free it on clean-up until then.*/
+    entry->mode=-1;
+    switch(mode){
+      /*The number of bits used to encode the character count for each version
+         range and each data mode.*/
+      static const unsigned char LEN_BITS[3][4]={
+        {10, 9, 8, 8},
+        {12,11,16,10},
+        {14,13,16,12}
+      };
+      case QR_MODE_NUM:{
+        unsigned char *buf;
+        unsigned       bits;
+        int            len;
+        int            count;
+        int            rem;
+        len=qr_pack_buf_read(&qpb,LEN_BITS[len_bits_idx][0]);
+        if(len<0)return -1;
+        /*Check to see if there are enough bits left now, so we don't have to
+           in the decode loop.*/
+        count=len/3;
+        rem=len%3;
+        if(qr_pack_buf_avail(&qpb)<10*count+7*(rem>>1&1)+4*(rem&1))return -1;
+        entry->mode=mode;
+        entry->payload.data.buf=buf=(unsigned char *)malloc(len*sizeof(*buf));
+        entry->payload.data.len=len;
+        /*Read groups of 3 digits encoded in 10 bits.*/
+        while(count-->0){
+          bits=qr_pack_buf_read(&qpb,10);
+          if(bits>=1000)return -1;
+          *buf++=(unsigned char)('0'+bits/100);
+          bits%=100;
+          *buf++=(unsigned char)('0'+bits/10);
+          *buf++=(unsigned char)('0'+bits%10);
+        }
+        /*Read the last two digits encoded in 7 bits.*/
+        if(rem>1){
+          bits=qr_pack_buf_read(&qpb,7);
+          if(bits>=100)return -1;
+          *buf++=(unsigned char)('0'+bits/10);
+          *buf++=(unsigned char)('0'+bits%10);
+        }
+        /*Or the last one digit encoded in 4 bits.*/
+        else if(rem){
+          bits=qr_pack_buf_read(&qpb,4);
+          if(bits>=10)return -1;
+          *buf++=(unsigned char)('0'+bits);
+        }
+      }break;
+      case QR_MODE_ALNUM:{
+        unsigned char *buf;
+        unsigned       bits;
+        int            len;
+        int            count;
+        int            rem;
+        len=qr_pack_buf_read(&qpb,LEN_BITS[len_bits_idx][1]);
+        if(len<0)return -1;
+        /*Check to see if there are enough bits left now, so we don't have to
+           in the decode loop.*/
+        count=len>>1;
+        rem=len&1;
+        if(qr_pack_buf_avail(&qpb)<11*count+6*rem)return -1;
+        entry->mode=mode;
+        entry->payload.data.buf=buf=(unsigned char *)malloc(len*sizeof(*buf));
+        entry->payload.data.len=len;
+        /*Read groups of two characters encoded in 11 bits.*/
+        while(count-->0){
+          bits=qr_pack_buf_read(&qpb,11);
+          if(bits>=2025)return -1;
+          *buf++=QR_ALNUM_TABLE[bits/45];
+          *buf++=QR_ALNUM_TABLE[bits%45];
+          len-=2;
+        }
+        /*Read the last character encoded in 6 bits.*/
+        if(rem){
+          bits=qr_pack_buf_read(&qpb,6);
+          if(bits>=45)return -1;
+          *buf++=QR_ALNUM_TABLE[bits];
+        }
+      }break;
+      /*Structured-append header.*/
+      case QR_MODE_STRUCT:{
+        int bits;
+        entry->mode=mode;
+        bits=qr_pack_buf_read(&qpb,16);
+        if(bits<0)return -1;
+        /*We also save a copy of the data in _qrdata for easy reference when
+           grouping structured-append codes.
+          If for some reason the code has multiple S-A headers, last one wins
+           (TODO: should we return an error instead?).*/
+        _qrdata->sa_index=entry->payload.sa.sa_index=
+         (unsigned char)(bits>>12&0xF);
+        _qrdata->sa_size=entry->payload.sa.sa_size=
+         (unsigned char)((bits>>8&0xF)+1);
+        _qrdata->sa_parity=entry->payload.sa.sa_parity=
+         (unsigned char)(bits&0xFF);
+      }break;
+      case QR_MODE_BYTE:{
+        unsigned char *buf;
+        int            len;
+        len=qr_pack_buf_read(&qpb,LEN_BITS[len_bits_idx][2]);
+        if(len<0)return -1;
+        /*Check to see if there are enough bits left now, so we don't have to
+           in the decode loop.*/
+        if(qr_pack_buf_avail(&qpb)<len<<3)return -1;
+        entry->mode=mode;
+        entry->payload.data.buf=buf=(unsigned char *)malloc(len*sizeof(*buf));
+        entry->payload.data.len=len;
+        while(len-->0)*buf++=(unsigned char)qr_pack_buf_read(&qpb,8);
+      }break;
+      /*FNC1 first position marker.*/
+      case QR_MODE_FNC1_1ST:entry->mode=mode;break;
+      /*Extended Channel Interpretation data.*/
+      case QR_MODE_ECI:{
+        unsigned val;
+        int      bits;
+        /*ECI uses a variable-width encoding similar to UTF-8*/
+        bits=qr_pack_buf_read(&qpb,8);
+        if(bits<0)return -1;
+        /*One byte:*/
+        if(!(bits&0x80))val=bits;
+        /*Two bytes:*/
+        else if(!(bits&0x40)){
+          val=bits&0x3F<<8;
+          bits=qr_pack_buf_read(&qpb,8);
+          if(bits<0)return -1;
+          val|=bits;
+        }
+        /*Three bytes:*/
+        else if(!(bits&0x20)){
+          val=bits&0x1F<<16;
+          bits=qr_pack_buf_read(&qpb,16);
+          if(bits<0)return -1;
+          val|=bits;
+          /*Valid ECI values are 0...999999.*/
+          if(val>=1000000)return -1;
+        }
+        /*Invalid lead byte.*/
+        else return -1;
+        entry->mode=mode;
+        entry->payload.eci=val;
+      }break;
+      case QR_MODE_KANJI:{
+        unsigned char *buf;
+        unsigned       bits;
+        int            len;
+        len=qr_pack_buf_read(&qpb,LEN_BITS[len_bits_idx][3]);
+        if(len<0)return -1;
+        /*Check to see if there are enough bits left now, so we don't have to
+           in the decode loop.*/
+        if(qr_pack_buf_avail(&qpb)<13*len)return -1;
+        entry->mode=mode;
+        entry->payload.data.buf=buf=(unsigned char *)malloc(2*len*sizeof(*buf));
+        entry->payload.data.len=2*len;
+        /*Decode 2-byte SJIS characters encoded in 13 bits.*/
+        while(len-->0){
+          bits=qr_pack_buf_read(&qpb,13);
+          bits=(bits/0xC0<<8|bits%0xC0)+0x8140;
+          if(bits>=0xA000)bits+=0x4000;
+          /*Are values 0xXX7F, 0xXXFD...0xXXFF always invalid?
+            Should we reject them here?*/
+          *buf++=(unsigned char)(bits>>8);
+          *buf++=(unsigned char)(bits&0xFF);
+        }
+      }break;
+      /*FNC1 second position marker.*/
+      case QR_MODE_FNC1_2ND:entry->mode=mode;break;
+      /*Unknown mode number:*/
+      default:{
+        /*Unfortunately, because we have to understand the format of a mode to
+           know how many bits it occupies, we can't skip unknown modes.
+          Therefore we have to fail.*/
+        return -1;
+      }break;
+    }
+  }
+  /*TODO: If there was a S-A header, we should compute the parity of this
+     code; how are non-data modes handled (ECI, FNC1)?*/
+  _qrdata->self_parity=0;
+  /*Success.*/
+  _qrdata->entries=(qr_code_data_entry *)realloc(_qrdata->entries,
+   _qrdata->nentries*sizeof(*_qrdata->entries));
+  return 0;
+}
+
+static void qr_code_data_clear(qr_code_data *_qrdata){
+  int i;
+  for(i=0;i<_qrdata->nentries;i++){
+    if(QR_MODE_HAS_DATA(_qrdata->entries[i].mode)){
+      free(_qrdata->entries[i].payload.data.buf);
+    }
+  }
+  free(_qrdata->entries);
+}
+
+
+void qr_code_data_list_init(qr_code_data_list *_qrlist){
+  _qrlist->qrdata=NULL;
+  _qrlist->nqrdata=_qrlist->cqrdata=0;
+}
+
+void qr_code_data_list_clear(qr_code_data_list *_qrlist){
+  int i;
+  for(i=0;i<_qrlist->nqrdata;i++)qr_code_data_clear(_qrlist->qrdata+i);
+  free(_qrlist->qrdata);
+  qr_code_data_list_init(_qrlist);
+}
+
+static void qr_code_data_list_add(qr_code_data_list *_qrlist,
+ qr_code_data *_qrdata){
+  if(_qrlist->nqrdata>=_qrlist->cqrdata){
+    _qrlist->cqrdata=_qrlist->cqrdata<<1|1;
+    _qrlist->qrdata=(qr_code_data *)realloc(_qrlist->qrdata,
+     _qrlist->cqrdata*sizeof(*_qrlist->qrdata));
+  }
+  memcpy(_qrlist->qrdata+_qrlist->nqrdata++,_qrdata,sizeof(*_qrdata));
+}
+
+#if 0
+static const unsigned short QR_NCODEWORDS[40]={
+    26,  44,  70, 100, 134, 172, 196, 242, 292, 346,
+   404, 466, 532, 581, 655, 733, 815, 901, 991,1085,
+  1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,
+  2323,2465,2611,2761,2876,3034,3196,3362,3532,3706
+};
+#endif
+
+/*The total number of codewords in a QR code.*/
+static int qr_code_ncodewords(unsigned _version){
+  unsigned nalign;
+  /*This is 24-27 instructions on ARM in thumb mode, or a 26-32 byte savings
+     over just using a table (not counting the instructions that would be
+     needed to do the table lookup).*/
+  if(_version==1)return 26;
+  nalign=(_version/7)+2;
+  return (_version<<4)*(_version+8)
+   -(5*nalign)*(5*nalign-2)+36*(_version<7)+83>>3;
+}
+
+#if 0
+/*The number of parity bytes per Reed-Solomon block for each version and error
+   correction level.*/
+static const unsigned char QR_RS_NPAR[40][4]={
+  { 7,10,13,17},{10,16,22,28},{15,26,18,22},{20,18,26,16},
+  {26,24,18,22},{18,16,24,28},{20,18,18,26},{24,22,22,26},
+  {30,22,20,24},{18,26,24,28},{20,30,28,24},{24,22,26,28},
+  {26,22,24,22},{30,24,20,24},{22,24,30,24},{24,28,24,30},
+  {28,28,28,28},{30,26,28,28},{28,26,26,26},{28,26,30,28},
+  {28,26,28,30},{28,28,30,24},{30,28,30,30},{30,28,30,30},
+  {26,28,30,30},{28,28,28,30},{30,28,30,30},{30,28,30,30},
+  {30,28,30,30},{30,28,30,30},{30,28,30,30},{30,28,30,30},
+  {30,28,30,30},{30,28,30,30},{30,28,30,30},{30,28,30,30},
+  {30,28,30,30},{30,28,30,30},{30,28,30,30},{30,28,30,30}
+};
+#endif
+
+/*Bulk data for the number of parity bytes per Reed-Solomon block.*/
+static const unsigned char QR_RS_NPAR_VALS[71]={
+  /*[ 0]*/ 7,10,13,17,
+  /*[ 4]*/10,16,22, 28,26,26, 26,22, 24,22,22, 26,24,18,22,
+  /*[19]*/15,26,18, 22,24, 30,24,20,24,
+  /*[28]*/18,16,24, 28, 28, 28,28,30,24,
+  /*[37]*/20,18, 18,26, 24,28,24, 30,26,28, 28, 26,28,30, 30,22,20,24,
+  /*[55]*/20,18,26,16,
+  /*[59]*/20,30,28, 24,22,26, 28,26, 30,28,30,30
+};
+
+/*An offset into QR_RS_NPAR_DATA for each version that gives the number of
+   parity bytes per Reed-Solomon block for each error correction level.*/
+static const unsigned char QR_RS_NPAR_OFFS[40]={
+   0, 4,19,55,15,28,37,12,51,39,
+  59,62,10,24,22,41,31,44, 7,65,
+  47,33,67,67,48,32,67,67,67,67,
+  67,67,67,67,67,67,67,67,67,67
+};
+
+/*The number of Reed-Solomon blocks for each version and error correction
+   level.*/
+static const unsigned char QR_RS_NBLOCKS[40][4]={
+  { 1, 1, 1, 1},{ 1, 1, 1, 1},{ 1, 1, 2, 2},{ 1, 2, 2, 4},
+  { 1, 2, 4, 4},{ 2, 4, 4, 4},{ 2, 4, 6, 5},{ 2, 4, 6, 6},
+  { 2, 5, 8, 8},{ 4, 5, 8, 8},{ 4, 5, 8,11},{ 4, 8,10,11},
+  { 4, 9,12,16},{ 4, 9,16,16},{ 6,10,12,18},{ 6,10,17,16},
+  { 6,11,16,19},{ 6,13,18,21},{ 7,14,21,25},{ 8,16,20,25},
+  { 8,17,23,25},{ 9,17,23,34},{ 9,18,25,30},{10,20,27,32},
+  {12,21,29,35},{12,23,34,37},{12,25,34,40},{13,26,35,42},
+  {14,28,38,45},{15,29,40,48},{16,31,43,51},{17,33,45,54},
+  {18,35,48,57},{19,37,51,60},{19,38,53,63},{20,40,56,66},
+  {21,43,59,70},{22,45,62,74},{24,47,65,77},{25,49,68,81}
+};
+
+/*Attempts to fully decode a QR code.
+  _qrdata:   Returns the parsed code data.
+  _gf:       Used for Reed-Solomon error correction.
+  _ul_pos:   The location of the UL finder pattern.
+  _ur_pos:   The location of the UR finder pattern.
+  _dl_pos:   The location of the DL finder pattern.
+  _version:  The (decoded) version number.
+  _fmt_info: The decoded format info.
+  _img:      The binary input image.
+  _width:    The width of the input image.
+  _height:   The height of the input image.
+  Return: 0 on success, or a negative value on error.*/
+static int qr_code_decode(qr_code_data *_qrdata,const rs_gf256 *_gf,
+ const qr_point _ul_pos,const qr_point _ur_pos,const qr_point _dl_pos,
+ int _version,int _fmt_info,
+ const unsigned char *_img,int _width,int _height){
+  qr_sampling_grid   grid;
+  unsigned          *data_bits;
+  unsigned char    **blocks;
+  unsigned char     *block_data;
+  int                nblocks;
+  int                nshort_blocks;
+  int                ncodewords;
+  int                block_sz;
+  int                ecc_level;
+  int                ndata;
+  int                npar;
+  int                dim;
+  int                ret;
+  int                i;
+  /*Read the bits out of the image.*/
+  qr_sampling_grid_init(&grid,_version,_ul_pos,_ur_pos,_dl_pos,_qrdata->bbox,
+   _img,_width,_height);
+#if defined(QR_DEBUG)
+  qr_sampling_grid_dump(&grid,_version,_img,_width,_height);
+#endif
+  dim=17+(_version<<2);
+  data_bits=(unsigned *)malloc(
+   dim*(dim+QR_INT_BITS-1>>QR_INT_LOGBITS)*sizeof(*data_bits));
+  qr_sampling_grid_sample(&grid,data_bits,dim,_fmt_info,_img,_width,_height);
+  /*Group those bits into Reed-Solomon codewords.*/
+  ecc_level=(_fmt_info>>3)^1;
+  nblocks=QR_RS_NBLOCKS[_version-1][ecc_level];
+  npar=*(QR_RS_NPAR_VALS+QR_RS_NPAR_OFFS[_version-1]+ecc_level);
+  ncodewords=qr_code_ncodewords(_version);
+  block_sz=ncodewords/nblocks;
+  nshort_blocks=nblocks-(ncodewords%nblocks);
+  blocks=(unsigned char **)malloc(nblocks*sizeof(*blocks));
+  block_data=(unsigned char *)malloc(ncodewords*sizeof(*block_data));
+  blocks[0]=block_data;
+  for(i=1;i<nblocks;i++)blocks[i]=blocks[i-1]+block_sz+(i>nshort_blocks);
+  qr_samples_unpack(blocks,nblocks,block_sz-npar,nshort_blocks,
+   data_bits,grid.fpmask,dim);
+  qr_sampling_grid_clear(&grid);
+  free(blocks);
+  free(data_bits);
+  /*Perform the error correction.*/
+  ndata=0;
+  ncodewords=0;
+  ret=0;
+  for(i=0;i<nblocks;i++){
+    int block_szi;
+    int ndatai;
+    block_szi=block_sz+(i>=nshort_blocks);
+    if(rs_correct(_gf,QR_M0,block_data+ncodewords,block_szi,npar,NULL,0)<0){
+      ret=-1;
+      break;
+    }
+    ndatai=block_szi-npar;
+    memmove(block_data+ndata,block_data+ncodewords,ndatai*sizeof(*block_data));
+    ncodewords+=block_szi;
+    ndata+=ndatai;
+  }
+  /*Parse the corrected bitstream.*/
+  if(ret>=0){
+    ret=qr_code_data_parse(_qrdata,_version,block_data,ndata);
+    /*We could return any partially decoded data, but then we'd have to have
+       API support for that; a mode ignoring ECC errors might also be useful.*/
+    if(ret<0)qr_code_data_clear(_qrdata);
+    _qrdata->version=_version;
+    _qrdata->ecc_level=ecc_level;
+  }
+  free(block_data);
+  return ret;
+}
+
+/*Searches for an arrangement of these three finder centers that yields a valid
+   configuration.
+  _c: On input, the three finder centers to consider in any order.
+  Return: The detected version number, or a negative value on error.*/
+static int qr_reader_try_configuration(qr_reader *_reader,
+ qr_code_data *_qrdata,const unsigned char *_img,int _width,int _height,
+ qr_finder_center *_c[3]){
+  int      ci[7];
+  unsigned maxd;
+  int      ccw;
+  int      i0;
+  int      i;
+  /*Sort the points in counter-clockwise order.*/
+  ccw=qr_point_ccw(_c[0]->pos,_c[1]->pos,_c[2]->pos);
+  /*Colinear points can't be the corners of a quadrilateral.*/
+  if(!ccw)return -1;
+  /*Include a few extra copies of the cyclical list to avoid mods.*/
+  ci[6]=ci[3]=ci[0]=0;
+  ci[4]=ci[1]=1+(ccw<0);
+  ci[5]=ci[2]=2-(ccw<0);
+  /*Assume the points farthest from each other are the opposite corners, and
+     find the top-left point.*/
+  maxd=qr_point_distance2(_c[1]->pos,_c[2]->pos);
+  i0=0;
+  for(i=1;i<3;i++){
+    unsigned d;
+    d=qr_point_distance2(_c[ci[i+1]]->pos,_c[ci[i+2]]->pos);
+    if(d>maxd){
+      i0=i;
+      maxd=d;
+    }
+  }
+  /*However, try all three possible orderings, just to be sure (a severely
+     skewed projection could move opposite corners closer than adjacent).*/
+  for(i=i0;i<i0+3;i++){
+    qr_aff    aff;
+    qr_hom    hom;
+    qr_finder ul;
+    qr_finder ur;
+    qr_finder dl;
+    int       res;
+    int       ur_version;
+    int       dl_version;
+    int       fmt_info;
+    ul.c=_c[ci[i]];
+    ur.c=_c[ci[i+1]];
+    dl.c=_c[ci[i+2]];
+    /*Estimate the module size and version number from the two opposite corners.
+      The module size is not constant in the image, so we compute an affine
+       projection from the three points we have to a square domain, and
+       estimate it there.
+      Although it should be the same along both axes, we keep separate
+       estimates to account for any remaining projective distortion.*/
+    res=QR_INT_BITS-2-QR_FINDER_SUBPREC-qr_ilog(QR_MAXI(_width,_height)-1);
+    qr_aff_init(&aff,ul.c->pos,ur.c->pos,dl.c->pos,res);
+    qr_aff_unproject(ur.o,&aff,ur.c->pos[0],ur.c->pos[1]);
+    qr_finder_edge_pts_aff_classify(&ur,&aff);
+    if(qr_finder_estimate_module_size_and_version(&ur,1<<res,1<<res)<0)continue;
+    qr_aff_unproject(dl.o,&aff,dl.c->pos[0],dl.c->pos[1]);
+    qr_finder_edge_pts_aff_classify(&dl,&aff);
+    if(qr_finder_estimate_module_size_and_version(&dl,1<<res,1<<res)<0)continue;
+    /*If the estimated versions are significantly different, reject the
+       configuration.*/
+    if(abs(ur.eversion[1]-dl.eversion[0])>QR_LARGE_VERSION_SLACK)continue;
+    qr_aff_unproject(ul.o,&aff,ul.c->pos[0],ul.c->pos[1]);
+    qr_finder_edge_pts_aff_classify(&ul,&aff);
+    if(qr_finder_estimate_module_size_and_version(&ul,1<<res,1<<res)<0||
+     abs(ul.eversion[1]-ur.eversion[1])>QR_LARGE_VERSION_SLACK||
+     abs(ul.eversion[0]-dl.eversion[0])>QR_LARGE_VERSION_SLACK){
+      continue;
+    }
+#if defined(QR_DEBUG)
+    qr_finder_dump_aff_undistorted(&ul,&ur,&dl,&aff,_img,_width,_height);
+#endif
+    /*If we made it this far, upgrade the affine homography to a full
+       homography.*/
+    if(qr_hom_fit(&hom,&ul,&ur,&dl,_qrdata->bbox,&aff,
+     &_reader->isaac,_img,_width,_height)<0){
+      continue;
+    }
+    qr_hom_unproject(ul.o,&hom,ul.c->pos[0],ul.c->pos[1]);
+    qr_hom_unproject(ur.o,&hom,ur.c->pos[0],ur.c->pos[1]);
+    qr_hom_unproject(dl.o,&hom,dl.c->pos[0],dl.c->pos[1]);
+    qr_finder_edge_pts_hom_classify(&ur,&hom);
+    if(qr_finder_estimate_module_size_and_version(&ur,
+     ur.o[0]-ul.o[0],ur.o[0]-ul.o[0])<0){
+      continue;
+    }
+    qr_finder_edge_pts_hom_classify(&dl,&hom);
+    if(qr_finder_estimate_module_size_and_version(&dl,
+     dl.o[1]-ul.o[1],dl.o[1]-ul.o[1])<0){
+      continue;
+    }
+#if defined(QR_DEBUG)
+    qr_finder_dump_hom_undistorted(&ul,&ur,&dl,&hom,_img,_width,_height);
+#endif
+    /*If we have a small version (less than 7), there's no encoded version
+       information.
+      If the estimated version on the two corners matches and is sufficiently
+       small, we assume this is the case.*/
+    if(ur.eversion[1]==dl.eversion[0]&&ur.eversion[1]<7){
+      /*We used to do a whole bunch of extra geometric checks for small
+         versions, because with just an affine correction, it was fairly easy
+         to estimate two consistent module sizes given a random configuration.
+        However, now that we're estimating a full homography, these appear to
+         be unnecessary.*/
+#if 0
+      static const signed char LINE_TESTS[12][6]={
+        /*DL left, UL > 0, UR > 0*/
+        {2,0,0, 1,1, 1},
+        /*DL right, UL > 0, UR < 0*/
+        {2,1,0, 1,1,-1},
+        /*UR top, UL > 0, DL > 0*/
+        {1,2,0, 1,2, 1},
+        /*UR bottom, UL > 0, DL < 0*/
+        {1,3,0, 1,2,-1},
+        /*UR left, DL < 0, UL < 0*/
+        {1,0,2,-1,0,-1},
+        /*UR right, DL > 0, UL > 0*/
+        {1,1,2, 1,0, 1},
+        /*DL top, UR < 0, UL < 0*/
+        {2,2,1,-1,0,-1},
+        /*DL bottom, UR > 0, UL > 0*/
+        {2,3,1, 1,0, 1},
+        /*UL left, DL > 0, UR > 0*/
+        {0,0,2, 1,1, 1},
+        /*UL right, DL > 0, UR < 0*/
+        {0,1,2, 1,1,-1},
+        /*UL top, UR > 0, DL > 0*/
+        {0,2,1, 1,2, 1},
+        /*UL bottom, UR > 0, DL < 0*/
+        {0,3,1, 1,2,-1}
+      };
+      qr_finder *f[3];
+      int        j;
+      /*Start by decoding the format information.
+        This is cheap, but unlikely to reject invalid configurations.
+        56.25% of all bitstrings are valid, and we mix and match several pieces
+         until we find a valid combination, so our real chances of finding a
+         valid codeword in random bits are even higher.*/
+      fmt_info=qr_finder_fmt_info_decode(&ul,&ur,&dl,&aff,_img,_width,_height);
+      if(fmt_info<0)continue;
+      /*Now we fit lines to the edges of each finder pattern and check to make
+         sure the centers of the other finder patterns lie on the proper side.*/
+      f[0]=&ul;
+      f[1]=&ur;
+      f[2]=&dl;
+      for(j=0;j<12;j++){
+        const signed char *t;
+        qr_line            l0;
+        int               *p;
+        t=LINE_TESTS[j];
+        qr_finder_ransac(f[t[0]],&aff,&_reader->isaac,t[1]);
+        /*We may not have enough points to fit a line accurately here.
+          If not, we just skip the test.*/
+        if(qr_line_fit_finder_edge(l0,f[t[0]],t[1],res)<0)continue;
+        p=f[t[2]]->c->pos;
+        if(qr_line_eval(l0,p[0],p[1])*t[3]<0)break;
+        p=f[t[4]]->c->pos;
+        if(qr_line_eval(l0,p[0],p[1])*t[5]<0)break;
+      }
+      if(j<12)continue;
+      /*All tests passed.*/
+#endif
+      ur_version=ur.eversion[1];
+    }
+    else{
+      /*If the estimated versions are significantly different, reject the
+         configuration.*/
+      if(abs(ur.eversion[1]-dl.eversion[0])>QR_LARGE_VERSION_SLACK)continue;
+      /*Otherwise we try to read the actual version data from the image.
+        If the real version is not sufficiently close to our estimated version,
+         then we assume there was an unrecoverable decoding error (so many bit
+         errors we were within 3 errors of another valid code), and throw that
+         value away.
+        If no decoded version could be sufficiently close, we don't even try.*/
+      if(ur.eversion[1]>=7-QR_LARGE_VERSION_SLACK){
+        ur_version=qr_finder_version_decode(&ur,&hom,_img,_width,_height,0);
+        if(abs(ur_version-ur.eversion[1])>QR_LARGE_VERSION_SLACK)ur_version=-1;
+      }
+      else ur_version=-1;
+      if(dl.eversion[0]>=7-QR_LARGE_VERSION_SLACK){
+        dl_version=qr_finder_version_decode(&dl,&hom,_img,_width,_height,1);
+        if(abs(dl_version-dl.eversion[0])>QR_LARGE_VERSION_SLACK)dl_version=-1;
+      }
+      else dl_version=-1;
+      /*If we got at least one valid version, or we got two and they match,
+         then we found a valid configuration.*/
+      if(ur_version>=0){
+        if(dl_version>=0&&dl_version!=ur_version)continue;
+      }
+      else if(dl_version<0)continue;
+      else ur_version=dl_version;
+    }
+    qr_finder_edge_pts_hom_classify(&ul,&hom);
+    if(qr_finder_estimate_module_size_and_version(&ul,
+     ur.o[0]-dl.o[0],dl.o[1]-ul.o[1])<0||
+     abs(ul.eversion[1]-ur.eversion[1])>QR_SMALL_VERSION_SLACK||
+     abs(ul.eversion[0]-dl.eversion[0])>QR_SMALL_VERSION_SLACK){
+      continue;
+    }
+    fmt_info=qr_finder_fmt_info_decode(&ul,&ur,&dl,&hom,_img,_width,_height);
+    if(fmt_info<0)continue;
+    if(qr_code_decode(_qrdata,&_reader->gf,ul.c->pos,ur.c->pos,dl.c->pos,
+     ur_version,fmt_info,_img,_width,_height)<0){
+      /*TODO: Maybe somebody flipped the code?
+        We'd still get a valid version, and probably valid (but incorrect)
+         format info.
+        After we've come this far, it should be a simple matter to check.*/
+      continue;
+    }
+    return ur_version;
+  }
+  return -1;
+}
+
+void qr_reader_match_centers(qr_reader *_reader,qr_code_data_list *_qrlist,
+ qr_finder_center *_centers,int _ncenters,
+ const unsigned char *_img,int _width,int _height){
+  /*The number of centers should be small, so an O(n^3) exhaustive search of
+     which ones go together should be reasonable.*/
+  unsigned char *mark;
+  int            i;
+  int            j;
+  int            k;
+  mark=(unsigned char *)calloc(_ncenters,sizeof(*mark));
+  for(i=0;i<_ncenters;i++){
+    /*TODO: We might be able to accelerate this step significantly by
+       considering the remaining finder centers in a more intelligent order,
+       based on the first finder center we just chose.*/
+    for(j=i+1;!mark[i]&&j<_ncenters;j++){
+      for(k=j+1;!mark[j]&&k<_ncenters;k++)if(!mark[k]){
+        qr_finder_center *c[3];
+        qr_code_data      qrdata;
+        int               version;
+        c[0]=_centers+i;
+        c[1]=_centers+j;
+        c[2]=_centers+k;
+        version=qr_reader_try_configuration(_reader,&qrdata,
+         _img,_width,_height,c);
+        if(version>=0){
+          int ninside;
+          int l;
+          /*Add the data to the list.*/
+          qr_code_data_list_add(_qrlist,&qrdata);
+          /*Convert the bounding box we're returning to the user to normal
+             image coordinates.*/
+          for(l=0;l<4;l++){
+            _qrlist->qrdata[_qrlist->nqrdata-1].bbox[l][0]>>=QR_FINDER_SUBPREC;
+            _qrlist->qrdata[_qrlist->nqrdata-1].bbox[l][1]>>=QR_FINDER_SUBPREC;
+          }
+          /*Mark these centers as used.*/
+          mark[i]=mark[j]=mark[k]=1;
+          /*Find any other finder centers located inside this code.*/
+          for(l=ninside=0;l<_ncenters;l++)if(!mark[l]){
+            if(qr_point_ccw(qrdata.bbox[0],qrdata.bbox[1],_centers[l].pos)>=0&&
+             qr_point_ccw(qrdata.bbox[1],qrdata.bbox[3],_centers[l].pos)>=0&&
+             qr_point_ccw(qrdata.bbox[3],qrdata.bbox[2],_centers[l].pos)>=0&&
+             qr_point_ccw(qrdata.bbox[2],qrdata.bbox[0],_centers[l].pos)>=0){
+              mark[l]=2;
+              ninside++;
+            }
+          }
+          if(ninside>=3){
+            /*We might have a "Double QR": a code inside a code.
+              Copy the relevant centers to a new array and do a search confined
+               to that subset.*/
+            qr_finder_center *inside;
+            inside=(qr_finder_center *)malloc(ninside*sizeof(*inside));
+            for(l=ninside=0;l<_ncenters;l++){
+              if(mark[l]==2)*&inside[ninside++]=*&_centers[l];
+            }
+            qr_reader_match_centers(_reader,_qrlist,inside,ninside,
+             _img,_width,_height);
+            free(inside);
+          }
+          /*Mark _all_ such centers used: codes cannot partially overlap.*/
+          for(l=0;l<_ncenters;l++)if(mark[l]==2)mark[l]=1;
+        }
+      }
+    }
+  }
+  free(mark);
+}
+
+int _zbar_qr_found_line (qr_reader *reader,
+                         int dir,
+                         const qr_finder_line *line)
+{
+    /* minimally intrusive brute force version */
+    qr_finder_lines *lines = &reader->finder_lines[dir];
+
+    if(lines->nlines >= lines->clines) {
+        lines->clines *= 2;
+        lines->lines = realloc(lines->lines,
+                               ++lines->clines * sizeof(*lines->lines));
+    }
+
+    memcpy(lines->lines + lines->nlines++, line, sizeof(*line));
+
+    return(0);
+}
+
+static inline void qr_svg_centers (const qr_finder_center *centers,
+                                   int ncenters)
+{
+    int i, j;
+    svg_path_start("centers", 1, 0, 0);
+    for(i = 0; i < ncenters; i++)
+        svg_path_moveto(SVG_ABS, centers[i].pos[0], centers[i].pos[1]);
+    svg_path_end();
+
+    svg_path_start("edge-pts", 1, 0, 0);
+    for(i = 0; i < ncenters; i++) {
+        const qr_finder_center *cen = centers + i;
+        for(j = 0; j < cen->nedge_pts; j++)
+            svg_path_moveto(SVG_ABS,
+                            cen->edge_pts[j].pos[0], cen->edge_pts[j].pos[1]);
+    }
+    svg_path_end();
+}
+
+int _zbar_qr_decode (qr_reader *reader,
+                     zbar_image_scanner_t *iscn,
+                     zbar_image_t *img)
+{
+    int nqrdata = 0;
+    qr_finder_edge_pt *edge_pts = NULL;
+    qr_finder_center *centers = NULL;
+
+    if(reader->finder_lines[0].nlines < 9 ||
+       reader->finder_lines[1].nlines < 9)
+        return(0);
+
+    svg_group_start("finder", 0, 1. / (1 << QR_FINDER_SUBPREC), 0, 0, 0);
+
+    int ncenters = qr_finder_centers_locate(&centers, &edge_pts, reader, 0, 0);
+
+    zprintf(14, "%dx%d finders, %d centers:\n",
+            reader->finder_lines[0].nlines,
+            reader->finder_lines[1].nlines,
+            ncenters);
+    qr_svg_centers(centers, ncenters);
+
+    if(ncenters >= 3) {
+        void *bin = qr_binarize(img->data, img->width, img->height);
+
+        qr_code_data_list qrlist;
+        qr_code_data_list_init(&qrlist);
+
+        qr_reader_match_centers(reader, &qrlist, centers, ncenters,
+                                bin, img->width, img->height);
+
+        if(qrlist.nqrdata > 0)
+            nqrdata = qr_code_data_list_extract_text(&qrlist, iscn, img);
+
+        qr_code_data_list_clear(&qrlist);
+        free(bin);
+    }
+    svg_group_end();
+
+    if(centers)
+        free(centers);
+    if(edge_pts)
+        free(edge_pts);
+    return(nqrdata);
+}

+ 403 - 0
Third_Party/ZBAR/src/qrdectxt.c

@@ -0,0 +1,403 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+#include <stdio.h>
+//#include <stdlib.h>
+#include <string.h>
+#include <iconv.h>
+#include "qrcode.h"
+#include "qrdec.h"
+#include "util.h"
+#include "image.h"
+#include "error.h"
+#include "img_scanner.h"
+
+static int text_is_ascii(const unsigned char *_text,int _len){
+  int i;
+  for(i=0;i<_len;i++)if(_text[i]>=0x80)return 0;
+  return 1;
+}
+
+static int text_is_latin1(const unsigned char *_text,int _len){
+  int i;
+  for(i=0;i<_len;i++){
+    /*The following line fails to compile correctly with gcc 3.4.4 on ARM with
+       any optimizations enabled.*/
+    if(_text[i]>=0x80&&_text[i]<0xA0)return 0;
+  }
+  return 1;
+}
+
+static void enc_list_mtf(iconv_t _enc_list[3],iconv_t _enc){
+  int i;
+  for(i=0;i<3;i++)if(_enc_list[i]==_enc){
+    int j;
+    for(j=i;j-->0;)_enc_list[j+1]=_enc_list[j];
+    _enc_list[0]=_enc;
+    break;
+  }
+}
+
+//#include "assert.h"
+
+int qr_code_data_list_extract_text(const qr_code_data_list *_qrlist,
+                                   zbar_image_scanner_t *iscn,
+                                   zbar_image_t *img)
+{
+  iconv_t              sjis_cd;
+  iconv_t              utf8_cd;
+  iconv_t              latin1_cd;
+  const qr_code_data  *qrdata;
+  int                  nqrdata;
+  unsigned char       *mark;
+//  char               **text;
+  int                  ntext;
+  int                  i;
+  qrdata=_qrlist->qrdata;
+  nqrdata=_qrlist->nqrdata;
+//  text=(char **)malloc(nqrdata*sizeof(*text));
+  mark=(unsigned char *)calloc(nqrdata,sizeof(*mark));
+  ntext=0;
+  /*This is the encoding the standard says is the default.*/
+  latin1_cd=iconv_open_ext("UTF-8","ISO8859-1");
+  /*But this one is often used, as well.*/
+  sjis_cd=iconv_open_ext("UTF-8","SJIS");
+  /*This is a trivial conversion just to check validity without extra code.*/
+  utf8_cd=iconv_open_ext("UTF-8","UTF-8");
+  for(i=0;i<nqrdata;i++)if(!mark[i]){
+    const qr_code_data       *qrdataj;
+    const qr_code_data_entry *entry;
+    iconv_t                   enc_list[3];
+    iconv_t                   eci_cd;
+    int                       sa[16];
+    int                       sa_size;
+    char                     *sa_text;
+    size_t                    sa_ntext;
+    size_t                    sa_ctext;
+    int                       fnc1;
+    int                       eci;
+    int                       err;
+    int                       j;
+    int                       k;
+    /*Step 0: Collect the other QR codes belonging to this S-A group.*/
+    if(qrdata[i].sa_size){
+      unsigned sa_parity;
+      sa_size=qrdata[i].sa_size;
+      sa_parity=qrdata[i].sa_parity;
+      for(j=0;j<sa_size;j++)sa[j]=-1;
+      for(j=i;j<nqrdata;j++)if(!mark[j]){
+        /*TODO: We could also match version, ECC level, etc. if size and
+           parity alone are too ambiguous.*/
+        if(qrdata[j].sa_size==sa_size&&qrdata[j].sa_parity==sa_parity&&
+         sa[qrdata[j].sa_index]<0){
+          sa[qrdata[j].sa_index]=j;
+          mark[j]=1;
+        }
+      }
+      /*TODO: If the S-A group is complete, check the parity.*/
+    }
+    else{
+      sa[0]=i;
+      sa_size=1;
+    }
+
+    sa_ctext=0;
+    fnc1=0;
+    /*Step 1: Detect FNC1 markers and estimate the required buffer size.*/
+    for(j=0;j<sa_size;j++)if(sa[j]>=0){
+      qrdataj=qrdata+sa[j];
+      for(k=0;k<qrdataj->nentries;k++){
+        int shift;
+        entry=qrdataj->entries+k;
+        shift=0;
+        switch(entry->mode){
+          /*FNC1 applies to the entire code and ignores subsequent markers.*/
+          case QR_MODE_FNC1_1ST:
+          case QR_MODE_FNC1_2ND:fnc1=1;break;
+          /*2 SJIS bytes will be at most 4 UTF-8 bytes.*/
+          case QR_MODE_KANJI:shift++;
+          /*We assume at most 4 UTF-8 bytes per input byte.
+            I believe this is true for all the encodings we actually use.*/
+          case QR_MODE_BYTE:shift++;
+          default:{
+            /*The remaining two modes are already valid UTF-8.*/
+            if(QR_MODE_HAS_DATA(entry->mode)){
+              sa_ctext+=entry->payload.data.len<<shift;
+            }
+          }break;
+        }
+      }
+    }
+
+    /*Step 2: Convert the entries.*/
+    sa_text=(char *)malloc((sa_ctext+1)*sizeof(*sa_text));
+    sa_ntext=0;
+    eci=-1;
+    enc_list[0]=sjis_cd;
+    enc_list[1]=latin1_cd;
+    enc_list[2]=utf8_cd;
+    eci_cd=(iconv_t)-1;
+    err=0;
+    zbar_symbol_t *syms = NULL, **sym = &syms;
+    for(j = 0; j < sa_size && !err; j++, sym = &(*sym)->next) {
+      *sym = _zbar_image_scanner_alloc_sym(iscn, ZBAR_QRCODE, 0);
+      (*sym)->datalen = sa_ntext;
+      if(sa[j]<0){
+        /* generic placeholder for unfinished results */
+        (*sym)->type = ZBAR_PARTIAL;
+
+        /*Skip all contiguous missing segments.*/
+        for(j++;j<sa_size&&sa[j]<0;j++);
+        /*If there aren't any more, stop.*/
+        if(j>=sa_size)break;
+
+        /* mark break in data */
+        sa_text[sa_ntext++]='\0';
+        (*sym)->datalen = sa_ntext;
+
+        /* advance to next symbol */
+        sym = &(*sym)->next;
+        *sym = _zbar_image_scanner_alloc_sym(iscn, ZBAR_QRCODE, 0);
+      }
+
+      qrdataj=qrdata+sa[j];
+      /* expose bounding box */
+      sym_add_point(*sym, qrdataj->bbox[0][0], qrdataj->bbox[0][1]);
+      sym_add_point(*sym, qrdataj->bbox[2][0], qrdataj->bbox[2][1]);
+      sym_add_point(*sym, qrdataj->bbox[3][0], qrdataj->bbox[3][1]);
+      sym_add_point(*sym, qrdataj->bbox[1][0], qrdataj->bbox[1][1]);
+
+      for(k=0;k<qrdataj->nentries&&!err;k++){
+        size_t              inleft;
+        size_t              outleft;
+        char               *in;
+        char               *out;
+        entry=qrdataj->entries+k;
+        switch(entry->mode){
+          case QR_MODE_NUM:{
+            if(sa_ctext-sa_ntext>=(size_t)entry->payload.data.len){
+              memcpy(sa_text+sa_ntext,entry->payload.data.buf,
+               entry->payload.data.len*sizeof(*sa_text));
+              sa_ntext+=entry->payload.data.len;
+            }
+            else err=1;
+          }break;
+          case QR_MODE_ALNUM:{
+            char *p;
+            in=(char *)entry->payload.data.buf;
+            inleft=entry->payload.data.len;
+            /*FNC1 uses '%' as an escape character.*/
+            if(fnc1)for(;;){
+              size_t plen;
+              char   c;
+              p=memchr(in,'%',inleft*sizeof(*in));
+              if(p==NULL)break;
+              plen=p-in;
+              if(sa_ctext-sa_ntext<plen+1)break;
+              memcpy(sa_text+sa_ntext,in,plen*sizeof(*in));
+              sa_ntext+=plen;
+              /*Two '%'s is a literal '%'*/
+              if(plen+1<inleft&&p[1]=='%'){
+                c='%';
+                plen++;
+                p++;
+              }
+              /*One '%' is the ASCII group separator.*/
+              else c=0x1D;
+              sa_text[sa_ntext++]=c;
+              inleft-=plen+1;
+              in=p+1;
+            }
+            else p=NULL;
+            if(p!=NULL||sa_ctext-sa_ntext<inleft)err=1;
+            else{
+              memcpy(sa_text+sa_ntext,in,inleft*sizeof(*sa_text));
+              sa_ntext+=inleft;
+            }
+          }break;
+          /*TODO: This will not handle a multi-byte sequence split between
+             multiple data blocks.
+            Does such a thing occur?
+            Is it allowed?
+            It requires copying buffers around to handle correctly.*/
+          case QR_MODE_BYTE:{
+            in=(char *)entry->payload.data.buf;
+            inleft=entry->payload.data.len;
+            out=sa_text+sa_ntext;
+            outleft=sa_ctext-sa_ntext;
+
+            /*If we have no specified encoding, attempt to auto-detect it.*/
+            if(eci<0){
+              int ei;
+              /*First check for the UTF-8 BOM.*/
+              if(inleft>=3&&
+               in[0]==(char)0xEF&&in[1]==(char)0xBB&&in[2]==(char)0xBF){
+                in+=3;
+                inleft-=3;
+                /*Actually try converting (to check validity).*/
+                err=utf8_cd==(iconv_t)-1||
+                 iconv_ext(utf8_cd,&in,&inleft,&out,&outleft)==(size_t)-1;
+                if(!err){
+                  sa_ntext=out-sa_text;
+                  enc_list_mtf(enc_list,utf8_cd);
+                  continue;
+                }
+                in=(char *)entry->payload.data.buf;
+                inleft=entry->payload.data.len;
+                out=sa_text+sa_ntext;
+                outleft=sa_ctext-sa_ntext;
+              }
+              /*If the text is 8-bit clean, prefer UTF-8 over SJIS, since SJIS
+                 will corrupt the backslashes used for DoCoMo formats.*/
+              else if(text_is_ascii((unsigned char *)in,inleft)){
+                //enc_list_mtf(enc_list,utf8_cd);
+                  memcpy(sa_text+sa_ntext,
+                     entry->payload.data.buf,
+                     entry->payload.data.len*sizeof(*sa_text));
+
+                  sa_ntext+=entry->payload.data.len;
+                  break;
+              }
+              /*Try our list of encodings.*/
+              for(ei=0;ei<3;ei++)if(enc_list[ei]!=(iconv_t)-1){
+                /*According to the standard, ISO/IEC 8859-1 (one hyphen) is
+                   supposed to be used, but reality is not always so.
+                  It's got an invalid range that is used often with SJIS
+                   and UTF-8, though, which makes detection easier.
+                  However, iconv() does not properly reject characters in
+                   those ranges, since ISO-8859-1 (two hyphens) defines a
+                   number of seldom-used control code characters there.
+                  So if we see any of those characters, move this
+                   conversion to the end of the list.*/
+                if(ei<2&&enc_list[ei]==latin1_cd&&
+                 !text_is_latin1((unsigned char *)in,inleft)){
+                  int ej;
+                  for(ej=ei+1;ej<3;ej++)enc_list[ej-1]=enc_list[ej];
+                  enc_list[2]=latin1_cd;
+                }
+                err=iconv_ext(enc_list[ei],&in,&inleft,&out,&outleft)==(size_t)-1;
+                if(!err){
+                  sa_ntext=out-sa_text;
+                  enc_list_mtf(enc_list,enc_list[ei]);
+                  break;
+                }
+                in=(char *)entry->payload.data.buf;
+                inleft=entry->payload.data.len;
+                out=sa_text+sa_ntext;
+                outleft=sa_ctext-sa_ntext;
+              }
+            }
+            /*We were actually given a character set; use it.*/
+            else{
+              err=eci_cd==(iconv_t)-1||
+               iconv_ext(eci_cd,&in,&inleft,&out,&outleft)==(size_t)-1;
+              if(!err)sa_ntext=out-sa_text;
+            }
+          }break;
+          /*Kanji mode always uses SJIS.*/
+          case QR_MODE_KANJI:{
+            in=(char *)entry->payload.data.buf;
+            inleft=entry->payload.data.len;
+            out=sa_text+sa_ntext;
+            outleft=sa_ctext-sa_ntext;
+            err=sjis_cd==(iconv_t)-1||
+             iconv_ext(sjis_cd,&in,&inleft,&out,&outleft)==(size_t)-1;
+            if(!err)sa_ntext=out-sa_text;
+          }break;
+          /*Check to see if a character set was specified.*/
+          case QR_MODE_ECI:{
+            const char *enc;
+            char        buf[16];
+            unsigned    cur_eci;
+            cur_eci=entry->payload.eci;
+            if(cur_eci<=QR_ECI_ISO8859_16&&cur_eci!=14){
+              if(cur_eci!=QR_ECI_GLI0&&cur_eci!=QR_ECI_CP437){
+                sprintf_(buf,"ISO8859-%i",QR_MAXI(cur_eci,3)-2);
+                enc=buf;
+              }
+              /*Note that CP437 requires an iconv compiled with
+                 --enable-extra-encodings, and thus may not be available.*/
+              else enc="CP437";
+            }
+            else if(cur_eci==QR_ECI_SJIS)enc="SJIS";
+            /*Don't know what this ECI code specifies, but not an encoding that
+               we recognize.*/
+            else continue;
+            eci=cur_eci;
+            eci_cd=iconv_open_ext("UTF-8",enc);
+          }break;
+          /*Silence stupid compiler warnings.*/
+          default:break;
+        }
+      }
+      /*If eci should be reset between codes, do so.*/
+      if(eci<=QR_ECI_GLI1){
+        eci=-1;
+        if(eci_cd!=(iconv_t)-1)iconv_close_ext(eci_cd);
+      }
+    }
+    if(eci_cd!=(iconv_t)-1)iconv_close_ext(eci_cd);
+    if(!err){
+      sa_text[sa_ntext++]='\0';
+      if(sa_ctext+1>sa_ntext){
+        sa_text=(char *)realloc(sa_text,sa_ntext*sizeof(*sa_text));
+      }
+
+      zbar_symbol_t *sa_sym;
+      if(sa_size == 1)
+          sa_sym = syms;
+      else {
+          /* create "virtual" container symbol for composite result */
+          sa_sym = _zbar_image_scanner_alloc_sym(iscn, ZBAR_QRCODE, 0);
+          sa_sym->syms = _zbar_symbol_set_create();
+          sa_sym->syms->head = syms;
+
+          /* cheap out w/axis aligned bbox for now */
+          int xmin = img->width, xmax = -2;
+          int ymin = img->height, ymax = -2;
+
+          /* fixup data references */
+          for(; syms; syms = syms->next) {
+              _zbar_symbol_refcnt(syms, 1);
+              if(syms->type == ZBAR_PARTIAL)
+                  sa_sym->type = ZBAR_PARTIAL;
+              else
+                  for(j = 0; j < syms->npts; j++) {
+                      int u = syms->pts[j].x;
+                      if(xmin >= u) xmin = u - 1;
+                      if(xmax <= u) xmax = u + 1;
+                      u = syms->pts[j].y;
+                      if(ymin >= u) ymin = u - 1;
+                      if(ymax <= u) ymax = u + 1;
+                  }
+              syms->data = sa_text + syms->datalen;
+              int next = (syms->next) ? syms->next->datalen : sa_ntext;
+              assert(next > syms->datalen);
+              syms->datalen = next - syms->datalen - 1;
+          }
+          if(xmax >= -1) {
+              sym_add_point(sa_sym, xmin, ymin);
+              sym_add_point(sa_sym, xmin, ymax);
+              sym_add_point(sa_sym, xmax, ymax);
+              sym_add_point(sa_sym, xmax, ymin);
+          }
+      }
+      sa_sym->data = sa_text;
+      sa_sym->data_alloc = sa_ntext;
+      sa_sym->datalen = sa_ntext - 1;
+
+      _zbar_image_scanner_add_sym(iscn, sa_sym);
+    }
+    else {
+        _zbar_image_scanner_recycle_syms(iscn, syms);
+        free(sa_text);
+    }
+  }
+  if(utf8_cd!=(iconv_t)-1)iconv_close_ext(utf8_cd);
+  if(sjis_cd!=(iconv_t)-1)iconv_close_ext(sjis_cd);
+  if(latin1_cd!=(iconv_t)-1)iconv_close_ext(latin1_cd);
+  free(mark);
+  return ntext;
+}

+ 48 - 0
Third_Party/ZBAR/src/refcnt.c

@@ -0,0 +1,48 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include "refcnt.h"
+
+#ifdef HAVE_LIBPTHREAD
+
+pthread_once_t initialized = PTHREAD_ONCE_INIT;
+pthread_mutex_t _zbar_reflock;
+
+static void initialize (void)
+{
+    pthread_mutex_init(&_zbar_reflock, NULL);
+}
+
+void _zbar_refcnt_init ()
+{
+    pthread_once(&initialized, initialize);
+}
+
+
+#else
+
+void _zbar_refcnt_init ()
+{
+}
+
+#endif

+ 799 - 0
Third_Party/ZBAR/src/rs.c

@@ -0,0 +1,799 @@
+/*Copyright (C) 1991-1995  Henry Minsky (hqm@ua.com, hqm@ai.mit.edu)
+  Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+//#include <stdlib.h>
+#include <string.h>
+#include "rs.h"
+
+/*Reed-Solomon encoder and decoder.
+  Original implementation (C) Henry Minsky (hqm@ua.com, hqm@ai.mit.edu),
+   Universal Access 1991-1995.
+  Updates by Timothy B. Terriberry (C) 2008-2009:
+   - Properly reject codes when error-locator polynomial has repeated roots or
+      non-trivial irreducible factors.
+   - Removed the hard-coded parity size and performed general API cleanup.
+   - Allow multiple representations of GF(2**8), since different standards use
+      different irreducible polynomials.
+   - Allow different starting indices for the generator polynomial, since
+      different standards use different values.
+   - Greatly reduced the computation by eliminating unnecessary operations.
+   - Explicitly solve for the roots of low-degree polynomials instead of using
+      an exhaustive search.
+     This is another major speed boost when there are few errors.*/
+
+
+/*Galois Field arithmetic in GF(2**8).*/
+
+void rs_gf256_init(rs_gf256 *_gf,unsigned _ppoly){
+  unsigned p;
+  int      i;
+  /*Initialize the table of powers of a primtive root, alpha=0x02.*/
+  p=1;
+  for(i=0;i<256;i++){
+    _gf->exp[i]=_gf->exp[i+255]=p;
+    p=((p<<1)^(-(p>>7)&_ppoly))&0xFF;
+  }
+  /*Invert the table to recover the logs.*/
+  for(i=0;i<255;i++)_gf->log[_gf->exp[i]]=i;
+  /*Note that we rely on the fact that _gf->log[0]=0 below.*/
+  _gf->log[0]=0;
+}
+
+/*Multiplication in GF(2**8) using logarithms.*/
+static unsigned rs_gmul(const rs_gf256 *_gf,unsigned _a,unsigned _b){
+  return _a==0||_b==0?0:_gf->exp[_gf->log[_a]+_gf->log[_b]];
+}
+
+/*Division in GF(2**8) using logarithms.
+  The result of division by zero is undefined.*/
+static unsigned rs_gdiv(const rs_gf256 *_gf,unsigned _a,unsigned _b){
+  return _a==0?0:_gf->exp[_gf->log[_a]+255-_gf->log[_b]];
+}
+
+/*Multiplication in GF(2**8) when one of the numbers is known to be non-zero
+   (proven by representing it by its logarithm).*/
+static unsigned rs_hgmul(const rs_gf256 *_gf,unsigned _a,unsigned _logb){
+  return _a==0?0:_gf->exp[_gf->log[_a]+_logb];
+}
+
+/*Square root in GF(2**8) using logarithms.*/
+static unsigned rs_gsqrt(const rs_gf256 *_gf,unsigned _a){
+  unsigned loga;
+  if(!_a)return 0;
+  loga=_gf->log[_a];
+  return _gf->exp[loga+(255&-(loga&1))>>1];
+}
+
+/*Polynomial root finding in GF(2**8).
+  Each routine returns a list of the distinct roots (i.e., with duplicates
+   removed).*/
+
+/*Solve a quadratic equation x**2 + _b*x + _c in GF(2**8) using the method
+   of~\cite{Wal99}.
+  Returns the number of distinct roots.
+  ARTICLE{Wal99,
+    author="C. Wayne Walker",
+    title="New Formulas for Solving Quadratic Equations over Certain Finite
+     Fields",
+    journal="{IEEE} Transactions on Information Theory",
+    volume=45,
+    number=1,
+    pages="283--284",
+    month=Jan,
+    year=1999
+  }*/
+static int rs_quadratic_solve(const rs_gf256 *_gf,unsigned _b,unsigned _c,
+ unsigned char _x[2]){
+  unsigned b;
+  unsigned logb;
+  unsigned logb2;
+  unsigned logb4;
+  unsigned logb8;
+  unsigned logb12;
+  unsigned logb14;
+  unsigned logc;
+  unsigned logc2;
+  unsigned logc4;
+  unsigned c8;
+  unsigned g3;
+  unsigned z3;
+  unsigned l3;
+  unsigned c0;
+  unsigned g2;
+  unsigned l2;
+  unsigned z2;
+  int      inc;
+  /*If _b is zero, all we need is a square root.*/
+  if(!_b){
+    _x[0]=rs_gsqrt(_gf,_c);
+    return 1;
+  }
+  /*If _c is zero, 0 and _b are the roots.*/
+  if(!_c){
+    _x[0]=0;
+    _x[1]=_b;
+    return 2;
+  }
+  logb=_gf->log[_b];
+  logc=_gf->log[_c];
+  /*If _b lies in GF(2**4), scale x to move it out.*/
+  inc=logb%(255/15)==0;
+  if(inc){
+    b=_gf->exp[logb+254];
+    logb=_gf->log[b];
+    _c=_gf->exp[logc+253];
+    logc=_gf->log[_c];
+  }
+  else b=_b;
+  logb2=_gf->log[_gf->exp[logb<<1]];
+  logb4=_gf->log[_gf->exp[logb2<<1]];
+  logb8=_gf->log[_gf->exp[logb4<<1]];
+  logb12=_gf->log[_gf->exp[logb4+logb8]];
+  logb14=_gf->log[_gf->exp[logb2+logb12]];
+  logc2=_gf->log[_gf->exp[logc<<1]];
+  logc4=_gf->log[_gf->exp[logc2<<1]];
+  c8=_gf->exp[logc4<<1];
+  g3=rs_hgmul(_gf,
+   _gf->exp[logb14+logc]^_gf->exp[logb12+logc2]^_gf->exp[logb8+logc4]^c8,logb);
+  /*If g3 doesn't lie in GF(2**4), then our roots lie in an extension field.
+    Note that we rely on the fact that _gf->log[0]==0 here.*/
+  if(_gf->log[g3]%(255/15)!=0)return 0;
+  /*Construct the corresponding quadratic in GF(2**4):
+    x**2 + x/alpha**(255/15) + l3/alpha**(2*(255/15))*/
+  z3=rs_gdiv(_gf,g3,_gf->exp[logb8<<1]^b);
+  l3=rs_hgmul(_gf,rs_gmul(_gf,z3,z3)^rs_hgmul(_gf,z3,logb)^_c,255-logb2);
+  c0=rs_hgmul(_gf,l3,255-2*(255/15));
+  /*Construct the corresponding quadratic in GF(2**2):
+    x**2 + x/alpha**(255/3) + l2/alpha**(2*(255/3))*/
+  g2=rs_hgmul(_gf,
+   rs_hgmul(_gf,c0,255-2*(255/15))^rs_gmul(_gf,c0,c0),255-255/15);
+  z2=rs_gdiv(_gf,g2,_gf->exp[255-(255/15)*4]^_gf->exp[255-(255/15)]);
+  l2=rs_hgmul(_gf,
+   rs_gmul(_gf,z2,z2)^rs_hgmul(_gf,z2,255-(255/15))^c0,2*(255/15));
+  /*Back substitute to the solution in the original field.*/
+  _x[0]=_gf->exp[_gf->log[z3^rs_hgmul(_gf,
+   rs_hgmul(_gf,l2,255/3)^rs_hgmul(_gf,z2,255/15),logb)]+inc];
+  _x[1]=_x[0]^_b;
+  return 2;
+}
+
+/*Solve a cubic equation x**3 + _a*x**2 + _b*x + _c in GF(2**8).
+  Returns the number of distinct roots.*/
+static int rs_cubic_solve(const rs_gf256 *_gf,
+ unsigned _a,unsigned _b,unsigned _c,unsigned char _x[3]){
+  unsigned k;
+  unsigned logd;
+  unsigned d2;
+  unsigned logd2;
+  unsigned logw;
+  int      nroots;
+  /*If _c is zero, factor out the 0 root.*/
+  if(!_c){
+    nroots=rs_quadratic_solve(_gf,_a,_b,_x);
+    if(_b)_x[nroots++]=0;
+    return nroots;
+  }
+  /*Substitute x=_a+y*sqrt(_a**2+_b) to get y**3 + y + k == 0,
+     k = (_a*_b+c)/(_a**2+b)**(3/2).*/
+  k=rs_gmul(_gf,_a,_b)^_c;
+  d2=rs_gmul(_gf,_a,_a)^_b;
+  if(!d2){
+    int logx;
+    if(!k){
+      /*We have a triple root.*/
+      _x[0]=_a;
+      return 1;
+    }
+    logx=_gf->log[k];
+    if(logx%3!=0)return 0;
+    logx/=3;
+    _x[0]=_a^_gf->exp[logx];
+    _x[1]=_a^_gf->exp[logx+255/3];
+    _x[2]=_a^_x[0]^_x[1];
+    return 3;
+  }
+  logd2=_gf->log[d2];
+  logd=logd2+(255&-(logd2&1))>>1;
+  k=rs_gdiv(_gf,k,_gf->exp[logd+logd2]);
+  /*Substitute y=w+1/w and z=w**3 to get z**2 + k*z + 1 == 0.*/
+  nroots=rs_quadratic_solve(_gf,k,1,_x);
+  if(nroots<1){
+    /*The Reed-Solomon code is only valid if we can find 3 distinct roots in
+       GF(2**8), so if we know there's only one, we don't actually need to find
+       it.
+      Note that we're also called by the quartic solver, but if we contain a
+       non-trivial irreducible factor, than so does the original
+       quartic~\cite{LW72}, and failing to return a root here actually saves us
+       some work there, also.*/
+    return 0;
+  }
+  /*Recover w from z.*/
+  logw=_gf->log[_x[0]];
+  if(logw){
+    if(logw%3!=0)return 0;
+    logw/=3;
+    /*Recover x from w.*/
+    _x[0]=_gf->exp[_gf->log[_gf->exp[logw]^_gf->exp[255-logw]]+logd]^_a;
+    logw+=255/3;
+    _x[1]=_gf->exp[_gf->log[_gf->exp[logw]^_gf->exp[255-logw]]+logd]^_a;
+    _x[2]=_x[0]^_x[1]^_a;
+    return 3;
+  }
+  else{
+    _x[0]=_a;
+    /*In this case _x[1] is a double root, so we know the Reed-Solomon code is
+       invalid.
+      Note that we still have to return at least one root, because if we're
+       being called by the quartic solver, the quartic might still have 4
+       distinct roots.
+      But we don't need more than one root, so we can avoid computing the
+       expensive one.*/
+    /*_x[1]=_gf->exp[_gf->log[_gf->exp[255/3]^_gf->exp[2*(255/3)]]+logd]^_a;*/
+    return 1;
+  }
+}
+
+/*Solve a quartic equation x**4 + _a*x**3 + _b*x**2 + _c*x + _d in GF(2**8) by
+   decomposing it into the cases given by~\cite{LW72}.
+  Returns the number of distinct roots.
+  @ARTICLE{LW72,
+    author="Philip A. Leonard and Kenneth S. Williams",
+    title="Quartics over $GF(2^n)$",
+    journal="Proceedings of the American Mathematical Society",
+    volume=36,
+    number=2,
+    pages="347--450",
+    month=Dec,
+    year=1972
+  }*/
+static int rs_quartic_solve(const rs_gf256 *_gf,
+ unsigned _a,unsigned _b,unsigned _c,unsigned _d,unsigned char _x[3]){
+  unsigned r;
+  unsigned s;
+  unsigned t;
+  unsigned b;
+  int      nroots;
+  int      i;
+  /*If _d is zero, factor out the 0 root.*/
+  if(!_d){
+    nroots=rs_cubic_solve(_gf,_a,_b,_c,_x);
+    if(_c)_x[nroots++]=0;
+    return nroots;
+  }
+  if(_a){
+    unsigned loga;
+    /*Substitute x=(1/y) + sqrt(_c/_a) to eliminate the cubic term.*/
+    loga=_gf->log[_a];
+    r=rs_hgmul(_gf,_c,255-loga);
+    s=rs_gsqrt(_gf,r);
+    t=_d^rs_gmul(_gf,_b,r)^rs_gmul(_gf,r,r);
+    if(t){
+      unsigned logti;
+      logti=255-_gf->log[t];
+      /*The result is still quartic, but with no cubic term.*/
+      nroots=rs_quartic_solve(_gf,0,rs_hgmul(_gf,_b^rs_hgmul(_gf,s,loga),logti),
+       _gf->exp[loga+logti],_gf->exp[logti],_x);
+      for(i=0;i<nroots;i++)_x[i]=_gf->exp[255-_gf->log[_x[i]]]^s;
+    }
+    else{
+      /*s must be a root~\cite{LW72}, and is in fact a double-root~\cite{CCO69}.
+        Thus we're left with only a quadratic to solve.
+        @ARTICLE{CCO69,
+          author="Robert T. Chien and B. D. Cunningham and I. B. Oldham",
+          title="Hybrid Methods for Finding Roots of a Polynomial---With
+           Applications to {BCH} Decoding",
+          journal="{IEEE} Transactions on Information Theory",
+          volume=15,
+          number=2,
+          pages="329--335",
+          month=Mar,
+          year=1969
+        }*/
+      nroots=rs_quadratic_solve(_gf,_a,_b^r,_x);
+      /*s may be a triple root if s=_b/_a, but not quadruple, since _a!=0.*/
+      if(nroots!=2||_x[0]!=s&&_x[1]!=s)_x[nroots++]=s;
+    }
+    return nroots;
+  }
+  /*If there are no odd powers, it's really just a quadratic in disguise.*/
+  if(!_c)return rs_quadratic_solve(_gf,rs_gsqrt(_gf,_b),rs_gsqrt(_gf,_d),_x);
+  /*Factor into (x**2 + r*x + s)*(x**2 + r*x + t) by solving for r, which can
+     be shown to satisfy r**3 + _b*r + _c == 0.*/
+  nroots=rs_cubic_solve(_gf,0,_b,_c,_x);
+  if(nroots<1){
+    /*The Reed-Solomon code is only valid if we can find 4 distinct roots in
+       GF(2**8).
+      If the cubic does not factor into 3 (possibly duplicate) roots, then we
+       know that the quartic must have a non-trivial irreducible factor.*/
+    return 0;
+  }
+  r=_x[0];
+  /*Now solve for s and t.*/
+  b=rs_gdiv(_gf,_c,r);
+  nroots=rs_quadratic_solve(_gf,b,_d,_x);
+  if(nroots<2)return 0;
+  s=_x[0];
+  t=_x[1];
+  /*_c=r*(s^t) was non-zero, so s and t must be distinct.
+    But if z is a root of z**2 ^ r*z ^ s, then so is (z^r), and s = z*(z^r).
+    Hence if z is also a root of z**2 ^ r*z ^ t, then t = s, a contradiction.
+    Thus all four roots are distinct, if they exist.*/
+  nroots=rs_quadratic_solve(_gf,r,s,_x);
+  return nroots+rs_quadratic_solve(_gf,r,t,_x+nroots);
+}
+
+/*Polynomial arithmetic with coefficients in GF(2**8).*/
+
+static void rs_poly_zero(unsigned char *_p,int _dp1){
+  memset(_p,0,_dp1*sizeof(*_p));
+}
+
+static void rs_poly_copy(unsigned char *_p,const unsigned char *_q,int _dp1){
+  memcpy(_p,_q,_dp1*sizeof(*_p));
+}
+
+/*Multiply the polynomial by the free variable, x (shift the coefficients).
+  The number of coefficients, _dp1, must be non-zero.*/
+static void rs_poly_mul_x(unsigned char *_p,const unsigned char *_q,int _dp1){
+  memmove(_p+1,_q,(_dp1-1)*sizeof(*_p));
+  _p[0]=0;
+}
+
+/*Divide the polynomial by the free variable, x (shift the coefficients).
+  The number of coefficients, _dp1, must be non-zero.*/
+static void rs_poly_div_x(unsigned char *_p,const unsigned char *_q,int _dp1){
+  memmove(_p,_q+1,(_dp1-1)*sizeof(*_p));
+  _p[_dp1-1]=0;
+}
+
+/*Compute the first (d+1) coefficients of the product of a degree e and a
+   degree f polynomial.*/
+static void rs_poly_mult(const rs_gf256 *_gf,unsigned char *_p,int _dp1,
+ const unsigned char *_q,int _ep1,const unsigned char *_r,int _fp1){
+  int m;
+  int i;
+  rs_poly_zero(_p,_dp1);
+  m=_ep1<_dp1?_ep1:_dp1;
+  for(i=0;i<m;i++)if(_q[i]!=0){
+    unsigned logqi;
+    int      n;
+    int      j;
+    n=_dp1-i<_fp1?_dp1-i:_fp1;
+    logqi=_gf->log[_q[i]];
+    for(j=0;j<n;j++)_p[i+j]^=rs_hgmul(_gf,_r[j],logqi);
+  }
+}
+
+/*Decoding.*/
+
+/*Computes the syndrome of a codeword.*/
+static void rs_calc_syndrome(const rs_gf256 *_gf,int _m0,
+ unsigned char *_s,int _npar,const unsigned char *_data,int _ndata){
+  int i;
+  int j;
+  for(j=0;j<_npar;j++){
+    unsigned alphaj;
+    unsigned sj;
+    sj=0;
+    alphaj=_gf->log[_gf->exp[j+_m0]];
+    for(i=0;i<_ndata;i++)sj=_data[i]^rs_hgmul(_gf,sj,alphaj);
+    _s[j]=sj;
+  }
+}
+
+/*Berlekamp-Peterson and Berlekamp-Massey Algorithms for error-location,
+   modified to handle known erasures, from \cite{CC81}, p. 205.
+  This finds the coefficients of the error locator polynomial.
+  The roots are then found by looking for the values of alpha**n where
+   evaluating the polynomial yields zero.
+  Error correction is done using the error-evaluator equation on p. 207.
+  @BOOK{CC81,
+    author="George C. Clark, Jr and J. Bibb Cain",
+    title="Error-Correction Coding for Digitial Communications",
+    series="Applications of Communications Theory",
+    publisher="Springer",
+    address="New York, NY",
+    month=Jun,
+    year=1981
+  }*/
+
+/*Initialize lambda to the product of (1-x*alpha**e[i]) for erasure locations
+   e[i].
+  Note that the user passes in array indices counting from the beginning of the
+   data, while our polynomial indexes starting from the end, so
+   e[i]=(_ndata-1)-_erasures[i].*/
+static void rs_init_lambda(const rs_gf256 *_gf,unsigned char *_lambda,int _npar,
+ const unsigned char *_erasures,int _nerasures,int _ndata){
+  int i;
+  int j;
+  rs_poly_zero(_lambda,(_npar<4?4:_npar)+1);
+  _lambda[0]=1;
+  for(i=0;i<_nerasures;i++)for(j=i+1;j>0;j--){
+    _lambda[j]^=rs_hgmul(_gf,_lambda[j-1],_ndata-1-_erasures[i]);
+  }
+}
+
+/*From \cite{CC81}, p. 216.
+  Returns the number of errors detected (degree of _lambda).*/
+static int rs_modified_berlekamp_massey(const rs_gf256 *_gf,
+ unsigned char *_lambda,const unsigned char *_s,unsigned char *_omega,int _npar,
+ const unsigned char *_erasures,int _nerasures,int _ndata){
+  unsigned char tt[256];
+  int           n;
+  int           l;
+  int           k;
+  int           i;
+  /*Initialize _lambda, the error locator-polynomial, with the location of
+     known erasures.*/
+  rs_init_lambda(_gf,_lambda,_npar,_erasures,_nerasures,_ndata);
+  rs_poly_copy(tt,_lambda,_npar+1);
+  l=_nerasures;
+  k=0;
+  for(n=_nerasures+1;n<=_npar;n++){
+    unsigned d;
+    rs_poly_mul_x(tt,tt,n-k+1);
+    d=0;
+    for(i=0;i<=l;i++)d^=rs_gmul(_gf,_lambda[i],_s[n-1-i]);
+    if(d!=0){
+      unsigned logd;
+      logd=_gf->log[d];
+      if(l<n-k){
+        int t;
+        for(i=0;i<=n-k;i++){
+          unsigned tti;
+          tti=tt[i];
+          tt[i]=rs_hgmul(_gf,_lambda[i],255-logd);
+          _lambda[i]=_lambda[i]^rs_hgmul(_gf,tti,logd);
+        }
+        t=n-k;
+        k=n-l;
+        l=t;
+      }
+      else for(i=0;i<=l;i++)_lambda[i]=_lambda[i]^rs_hgmul(_gf,tt[i],logd);
+    }
+  }
+  rs_poly_mult(_gf,_omega,_npar,_lambda,l+1,_s,_npar);
+  return l;
+}
+
+/*Finds all the roots of an error-locator polynomial _lambda by evaluating it
+   at successive values of alpha, and returns the positions of the associated
+   errors in _epos.
+  Returns the number of valid roots identified.*/
+static int rs_find_roots(const rs_gf256 *_gf,unsigned char *_epos,
+ const unsigned char *_lambda,int _nerrors,int _ndata){
+  unsigned alpha;
+  int      nroots;
+  int      i;
+  nroots=0;
+  if(_nerrors<=4){
+    /*Explicit solutions for higher degrees are possible.
+      Chien uses large lookup tables to solve quintics, and Truong et al. give
+       special algorithms for degree up through 11, though they use exhaustive
+       search (with reduced complexity) for some portions.
+      Quartics are good enough for reading CDs, and represent a reasonable code
+       complexity trade-off without requiring any extra tables.
+      Note that _lambda[0] is always 1.*/
+    _nerrors=rs_quartic_solve(_gf,_lambda[1],_lambda[2],_lambda[3],_lambda[4],
+     _epos);
+    for(i=0;i<_nerrors;i++)if(_epos[i]){
+      alpha=_gf->log[_epos[i]];
+      if((int)alpha<_ndata)_epos[nroots++]=alpha;
+    }
+    return nroots;
+  }
+  else for(alpha=0;(int)alpha<_ndata;alpha++){
+    unsigned alphai;
+    unsigned sum;
+    sum=0;
+    alphai=0;
+    for(i=0;i<=_nerrors;i++){
+      sum^=rs_hgmul(_gf,_lambda[_nerrors-i],alphai);
+      alphai=_gf->log[_gf->exp[alphai+alpha]];
+    }
+    if(!sum)_epos[nroots++]=alpha;
+  }
+  return nroots;
+}
+
+/*Corrects a codeword with _ndata<256 bytes, of which the last _npar are parity
+   bytes.
+  Known locations of errors can be passed in the _erasures array.
+  Twice as many (up to _npar) errors with a known location can be corrected
+   compared to errors with an unknown location.
+  Returns the number of errors corrected if successful, or a negative number if
+   the message could not be corrected because too many errors were detected.*/
+int rs_correct(const rs_gf256 *_gf,int _m0,unsigned char *_data,int _ndata,
+ int _npar,const unsigned char *_erasures,int _nerasures){
+  /*lambda must have storage for at least five entries to avoid special cases
+     in the low-degree polynomial solver.*/
+  unsigned char lambda[256];
+  unsigned char omega[256];
+  unsigned char epos[256];
+  unsigned char s[256];
+  int           i;
+  /*If we already have too many erasures, we can't possibly succeed.*/
+  if(_nerasures>_npar)return -1;
+  /*Compute the syndrome values.*/
+  rs_calc_syndrome(_gf,_m0,s,_npar,_data,_ndata);
+  /*Check for a non-zero value.*/
+  for(i=0;i<_npar;i++)if(s[i]){
+    int nerrors;
+    int j;
+    /*Construct the error locator polynomial.*/
+    nerrors=rs_modified_berlekamp_massey(_gf,lambda,s,omega,_npar,
+     _erasures,_nerasures,_ndata);
+    /*If we can't locate any errors, we can't force the syndrome values to
+       zero, and must have a decoding error.
+      Conversely, if we have too many errors, there's no reason to even attempt
+       the root search.*/
+    if(nerrors<=0||nerrors-_nerasures>_npar-_nerasures>>1)return -1;
+    /*Compute the locations of the errors.
+      If they are not all distinct, or some of them were outside the valid
+       range for our block size, we have a decoding error.*/
+    if(rs_find_roots(_gf,epos,lambda,nerrors,_ndata)<nerrors)return -1;
+    /*Now compute the error magnitudes.*/
+    for(i=0;i<nerrors;i++){
+      unsigned a;
+      unsigned b;
+      unsigned alpha;
+      unsigned alphan1;
+      unsigned alphan2;
+      unsigned alphanj;
+      alpha=epos[i];
+      /*Evaluate omega at alpha**-1.*/
+      a=0;
+      alphan1=255-alpha;
+      alphanj=0;
+      for(j=0;j<_npar;j++){
+        a^=rs_hgmul(_gf,omega[j],alphanj);
+        alphanj=_gf->log[_gf->exp[alphanj+alphan1]];
+      }
+      /*Evaluate the derivative of lambda at alpha**-1
+        All the odd powers vanish.*/
+      b=0;
+      alphan2=_gf->log[_gf->exp[alphan1<<1]];
+      alphanj=alphan1+_m0*alpha%255;
+      for(j=1;j<=_npar;j+=2){
+        b^=rs_hgmul(_gf,lambda[j],alphanj);
+        alphanj=_gf->log[_gf->exp[alphanj+alphan2]];
+      }
+      /*Apply the correction.*/
+      _data[_ndata-1-alpha]^=rs_gdiv(_gf,a,b);
+    }
+    return nerrors;
+  }
+  return 0;
+}
+
+/*Encoding.*/
+
+/*Create an _npar-coefficient generator polynomial for a Reed-Solomon code
+   with _npar<256 parity bytes.*/
+void rs_compute_genpoly(const rs_gf256 *_gf,int _m0,
+ unsigned char *_genpoly,int _npar){
+  int i;
+  if(_npar<=0)return;
+  rs_poly_zero(_genpoly,_npar);
+  _genpoly[0]=1;
+  /*Multiply by (x+alpha^i) for i = 1 ... _ndata.*/
+  for(i=0;i<_npar;i++){
+    unsigned alphai;
+    int      n;
+    int      j;
+    n=i+1<_npar-1?i+1:_npar-1;
+    alphai=_gf->log[_gf->exp[_m0+i]];
+    for(j=n;j>0;j--)_genpoly[j]=_genpoly[j-1]^rs_hgmul(_gf,_genpoly[j],alphai);
+    _genpoly[0]=rs_hgmul(_gf,_genpoly[0],alphai);
+  }
+}
+
+/*Adds _npar<=_ndata parity bytes to an _ndata-_npar byte message.
+  _data must contain room for _ndata<256 bytes.*/
+void rs_encode(const rs_gf256 *_gf,unsigned char *_data,int _ndata,
+ const unsigned char *_genpoly,int _npar){
+  unsigned char *lfsr;
+  unsigned       d;
+  int            i;
+  int            j;
+  if(_npar<=0)return;
+  lfsr=_data+_ndata-_npar;
+  rs_poly_zero(lfsr,_npar);
+  for(i=0;i<_ndata-_npar;i++){
+    d=_data[i]^lfsr[0];
+    if(d){
+      unsigned logd;
+      logd=_gf->log[d];
+      for(j=0;j<_npar-1;j++){
+        lfsr[j]=lfsr[j+1]^rs_hgmul(_gf,_genpoly[_npar-1-j],logd);
+      }
+      lfsr[_npar-1]=rs_hgmul(_gf,_genpoly[0],logd);
+    }
+    else rs_poly_div_x(lfsr,lfsr,_npar);
+  }
+}
+
+#if defined(RS_TEST_ENC)
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void){
+  rs_gf256 gf;
+  int      k;
+  rs_gf256_init(&gf,QR_PPOLY);
+  srand(0);
+  for(k=0;k<64*1024;k++){
+    unsigned char genpoly[256];
+    unsigned char data[256];
+    unsigned char epos[256];
+    int           ndata;
+    int           npar;
+    int           nerrors;
+    int           i;
+    ndata=rand()&0xFF;
+    npar=ndata>0?rand()%ndata:0;
+    for(i=0;i<ndata-npar;i++)data[i]=rand()&0xFF;
+    rs_compute_genpoly(&gf,QR_M0,genpoly,npar);
+    rs_encode(&gf,QR_M0,data,ndata,genpoly,npar);
+    /*Write a clean version of the codeword.*/
+    printf("%i %i",ndata,npar);
+    for(i=0;i<ndata;i++)printf(" %i",data[i]);
+    printf(" 0\n");
+    /*Write the correct output to compare the decoder against.*/
+    fprintf(stderr,"Success!\n",nerrors);
+    for(i=0;i<ndata;i++)fprintf(stderr,"%i%s",data[i],i+1<ndata?" ":"\n");
+    if(npar>0){
+      /*Corrupt it.*/
+      nerrors=rand()%(npar+1);
+      if(nerrors>0){
+        /*This test is not quite correct: there could be so many errors it
+           comes within (npar>>1) errors of another valid codeword.
+          I don't know a simple way to test for that without trying to decode
+           the corrupt codeword, though, which is the very code we're trying to
+           test.*/
+        if(nerrors<=npar>>1){
+          fprintf(stderr,"Success!\n",nerrors);
+          for(i=0;i<ndata;i++){
+            fprintf(stderr,"%i%s",data[i],i+1<ndata?" ":"\n");
+          }
+        }
+        else fprintf(stderr,"Failure.\n");
+        fprintf(stderr,"Success!\n",nerrors);
+        for(i=0;i<ndata;i++)fprintf(stderr,"%i%s",data[i],i+1<ndata?" ":"\n");
+        for(i=0;i<ndata;i++)epos[i]=i;
+        for(i=0;i<nerrors;i++){
+          unsigned char e;
+          int           ei;
+          ei=rand()%(ndata-i)+i;
+          e=epos[ei];
+          epos[ei]=epos[i];
+          epos[i]=e;
+          data[e]^=rand()%255+1;
+        }
+        /*First with no erasure locations.*/
+        printf("%i %i",ndata,npar);
+        for(i=0;i<ndata;i++)printf(" %i",data[i]);
+        printf(" 0\n");
+        /*Now with erasure locations.*/
+        printf("%i %i",ndata,npar);
+        for(i=0;i<ndata;i++)printf(" %i",data[i]);
+        printf(" %i",nerrors);
+        for(i=0;i<nerrors;i++)printf(" %i",epos[i]);
+        printf("\n");
+      }
+    }
+  }
+  return 0;
+}
+#endif
+
+#if defined(RS_TEST_DEC)
+#include <stdio.h>
+
+int main(void){
+  rs_gf256 gf;
+  rs_gf256_init(&gf,QR_PPOLY);
+  for(;;){
+    unsigned char data[255];
+    unsigned char erasures[255];
+    int idata[255];
+    int ierasures[255];
+    int ndata;
+    int npar;
+    int nerasures;
+    int nerrors;
+    int i;
+    if(scanf("%i",&ndata)<1||ndata<0||ndata>255||
+     scanf("%i",&npar)<1||npar<0||npar>ndata)break;
+    for(i=0;i<ndata;i++){
+      if(scanf("%i",idata+i)<1||idata[i]<0||idata[i]>255)break;
+      data[i]=idata[i];
+    }
+    if(i<ndata)break;
+    if(scanf("%i",&nerasures)<1||nerasures<0||nerasures>ndata)break;
+    for(i=0;i<nerasures;i++){
+      if(scanf("%i",ierasures+i)<1||ierasures[i]<0||ierasures[i]>=ndata)break;
+      erasures[i]=ierasures[i];
+    }
+    nerrors=rs_correct(&gf,QR_M0,data,ndata,npar,erasures,nerasures);
+    if(nerrors>=0){
+      unsigned char data2[255];
+      unsigned char genpoly[255];
+      for(i=0;i<ndata-npar;i++)data2[i]=data[i];
+      rs_compute_genpoly(&gf,QR_M0,genpoly,npar);
+      rs_encode(&gf,QR_M0,data2,ndata,genpoly,npar);
+      for(i=ndata-npar;i<ndata;i++)if(data[i]!=data2[i]){
+        printf("Abject failure! %i!=%i\n",data[i],data2[i]);
+      }
+      printf("Success!\n",nerrors);
+      for(i=0;i<ndata;i++)printf("%i%s",data[i],i+1<ndata?" ":"\n");
+    }
+    else printf("Failure.\n");
+  }
+  return 0;
+}
+#endif
+
+#if defined(RS_TEST_ROOTS)
+#include <stdio.h>
+
+/*Exhaustively test the root finder.*/
+int main(void){
+  rs_gf256 gf;
+  int      a;
+  int      b;
+  int      c;
+  int      d;
+  rs_gf256_init(&gf,QR_PPOLY);
+  for(a=0;a<256;a++)for(b=0;b<256;b++)for(c=0;c<256;c++)for(d=0;d<256;d++){
+    unsigned char x[4];
+    unsigned char r[4];
+    unsigned      x2;
+    unsigned      e[5];
+    int           nroots;
+    int           mroots;
+    int           i;
+    int           j;
+    nroots=rs_quartic_solve(&gf,a,b,c,d,x);
+    for(i=0;i<nroots;i++){
+      x2=rs_gmul(&gf,x[i],x[i]);
+      e[0]=rs_gmul(&gf,x2,x2)^rs_gmul(&gf,a,rs_gmul(&gf,x[i],x2))^
+       rs_gmul(&gf,b,x2)^rs_gmul(&gf,c,x[i])^d;
+      if(e[0]){
+        printf("Invalid root: (0x%02X)**4 ^ 0x%02X*(0x%02X)**3 ^ "
+         "0x%02X*(0x%02X)**2 ^ 0x%02X(0x%02X) ^ 0x%02X = 0x%02X\n",
+         x[i],a,x[i],b,x[i],c,x[i],d,e[0]);
+      }
+      for(j=0;j<i;j++)if(x[i]==x[j]){
+        printf("Repeated root %i=%i: (0x%02X)**4 ^ 0x%02X*(0x%02X)**3 ^ "
+         "0x%02X*(0x%02X)**2 ^ 0x%02X(0x%02X) ^ 0x%02X = 0x%02X\n",
+         i,j,x[i],a,x[i],b,x[i],c,x[i],d,e[0]);
+      }
+    }
+    mroots=0;
+    for(j=1;j<256;j++){
+      int logx;
+      int logx2;
+      logx=gf.log[j];
+      logx2=gf.log[gf.exp[logx<<1]];
+      e[mroots]=d^rs_hgmul(&gf,c,logx)^rs_hgmul(&gf,b,logx2)^
+       rs_hgmul(&gf,a,gf.log[gf.exp[logx+logx2]])^gf.exp[logx2<<1];
+      if(!e[mroots])r[mroots++]=j;
+    }
+    /*We only care about missing roots if the quartic had 4 distinct, non-zero
+       roots.*/
+    if(mroots==4)for(j=0;j<mroots;j++){
+      for(i=0;i<nroots;i++)if(x[i]==r[j])break;
+      if(i>=nroots){
+        printf("Missing root: (0x%02X)**4 ^ 0x%02X*(0x%02X)**3 ^ "
+         "0x%02X*(0x%02X)**2 ^ 0x%02X(0x%02X) ^ 0x%02X = 0x%02X\n",
+         r[j],a,r[j],b,r[j],c,r[j],d,e[j]);
+      }
+    }
+  }
+  return 0;
+}
+#endif

+ 311 - 0
Third_Party/ZBAR/src/scanner.c

@@ -0,0 +1,311 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <config.h>
+//#include <stdlib.h>     /* malloc, free, abs */
+#include <string.h>     /* memset */
+
+#include <zbar.h>
+#include "svg.h"
+
+#ifdef DEBUG_SCANNER
+# define DEBUG_LEVEL (DEBUG_SCANNER)
+#endif
+#include "debug.h"
+
+#ifndef ZBAR_FIXED
+# define ZBAR_FIXED 5
+#endif
+#define ROUND (1 << (ZBAR_FIXED - 1))
+
+/* FIXME add runtime config API for these */
+#ifndef ZBAR_SCANNER_THRESH_MIN
+# define ZBAR_SCANNER_THRESH_MIN  4
+#endif
+
+#ifndef ZBAR_SCANNER_THRESH_INIT_WEIGHT
+# define ZBAR_SCANNER_THRESH_INIT_WEIGHT .44
+#endif
+#define THRESH_INIT ((unsigned)((ZBAR_SCANNER_THRESH_INIT_WEIGHT       \
+                                 * (1 << (ZBAR_FIXED + 1)) + 1) / 2))
+
+#ifndef ZBAR_SCANNER_THRESH_FADE
+# define ZBAR_SCANNER_THRESH_FADE 8
+#endif
+
+#ifndef ZBAR_SCANNER_EWMA_WEIGHT
+# define ZBAR_SCANNER_EWMA_WEIGHT .78
+#endif
+#define EWMA_WEIGHT ((unsigned)((ZBAR_SCANNER_EWMA_WEIGHT              \
+                                 * (1 << (ZBAR_FIXED + 1)) + 1) / 2))
+
+/* scanner state */
+struct zbar_scanner_s {
+    zbar_decoder_t *decoder; /* associated bar width decoder */
+    unsigned y1_min_thresh; /* minimum threshold */
+
+    unsigned x;             /* relative scan position of next sample */
+    int y0[4];              /* short circular buffer of average intensities */
+
+    int y1_sign;            /* slope at last crossing */
+    unsigned y1_thresh;     /* current slope threshold */
+
+    unsigned cur_edge;      /* interpolated position of tracking edge */
+    unsigned last_edge;     /* interpolated position of last located edge */
+    unsigned width;         /* last element width */
+};
+
+zbar_scanner_t *zbar_scanner_create (zbar_decoder_t *dcode)
+{
+    zbar_scanner_t *scn = malloc(sizeof(zbar_scanner_t));
+    scn->decoder = dcode;
+    scn->y1_min_thresh = ZBAR_SCANNER_THRESH_MIN;
+    zbar_scanner_reset(scn);
+    return(scn);
+}
+
+void zbar_scanner_destroy (zbar_scanner_t *scn)
+{
+    free(scn);
+}
+
+zbar_symbol_type_t zbar_scanner_reset (zbar_scanner_t *scn)
+{
+    memset(&scn->x, 0, sizeof(zbar_scanner_t) + (unsigned int)scn - (unsigned int)&scn->x);
+    scn->y1_thresh = scn->y1_min_thresh;
+    if(scn->decoder)
+        zbar_decoder_reset(scn->decoder);
+    return(ZBAR_NONE);
+}
+
+unsigned zbar_scanner_get_width (const zbar_scanner_t *scn)
+{
+    return(scn->width);
+}
+
+unsigned zbar_scanner_get_edge (const zbar_scanner_t *scn,
+                                unsigned offset,
+                                int prec)
+{
+    unsigned edge = scn->last_edge - offset - (1 << ZBAR_FIXED) - ROUND;
+    prec = ZBAR_FIXED - prec;
+    if(prec > 0)
+        return(edge >> prec);
+    else if(!prec)
+        return(edge);
+    else
+        return(edge << -prec);
+}
+
+zbar_color_t zbar_scanner_get_color (const zbar_scanner_t *scn)
+{
+    return((scn->y1_sign <= 0) ? ZBAR_SPACE : ZBAR_BAR);
+}
+
+static inline unsigned calc_thresh (zbar_scanner_t *scn)
+{
+    /* threshold 1st to improve noise rejection */
+    unsigned thresh = scn->y1_thresh;
+    if((thresh <= scn->y1_min_thresh) || !scn->width) {
+        dprintf(1, " tmin=%d", scn->y1_min_thresh);
+        return(scn->y1_min_thresh);
+    }
+    /* slowly return threshold to min */
+    unsigned dx = (scn->x << ZBAR_FIXED) - scn->last_edge;
+    unsigned long t = thresh * dx;
+    t /= scn->width;
+    t /= ZBAR_SCANNER_THRESH_FADE;
+    dprintf(1, " thr=%d t=%ld x=%d last=%d.%d (%d)",
+            thresh, t, scn->x, scn->last_edge >> ZBAR_FIXED,
+            scn->last_edge & ((1 << ZBAR_FIXED) - 1), dx);
+    if(thresh > t) {
+        thresh -= t;
+        if(thresh > scn->y1_min_thresh)
+            return(thresh);
+    }
+    scn->y1_thresh = scn->y1_min_thresh;
+    return(scn->y1_min_thresh);
+}
+
+static inline zbar_symbol_type_t process_edge (zbar_scanner_t *scn,
+                                               int y1)
+{
+    if(!scn->y1_sign)
+        scn->last_edge = scn->cur_edge = (1 << ZBAR_FIXED) + ROUND;
+    else if(!scn->last_edge)
+        scn->last_edge = scn->cur_edge;
+
+    scn->width = scn->cur_edge - scn->last_edge;
+    dprintf(1, " sgn=%d cur=%d.%d w=%d (%s)\n",
+            scn->y1_sign, scn->cur_edge >> ZBAR_FIXED,
+            scn->cur_edge & ((1 << ZBAR_FIXED) - 1), scn->width,
+            ((y1 > 0) ? "SPACE" : "BAR"));
+    scn->last_edge = scn->cur_edge;
+
+#if DEBUG_SVG > 1
+    svg_path_moveto(SVG_ABS, scn->last_edge - (1 << ZBAR_FIXED) - ROUND, 0);
+#endif
+
+    /* pass to decoder */
+    if(scn->decoder)
+        return(zbar_decode_width(scn->decoder, scn->width));
+    return(ZBAR_PARTIAL);
+}
+
+inline zbar_symbol_type_t zbar_scanner_flush (zbar_scanner_t *scn)
+{
+    if(!scn->y1_sign)
+        return(ZBAR_NONE);
+
+    unsigned x = (scn->x << ZBAR_FIXED) + ROUND;
+
+    if(scn->cur_edge != x || scn->y1_sign > 0) {
+        dprintf(1, "flush0:");
+        zbar_symbol_type_t edge = process_edge(scn, -scn->y1_sign);
+        scn->cur_edge = x;
+        scn->y1_sign = -scn->y1_sign;
+        return(edge);
+    }
+
+    scn->y1_sign = scn->width = 0;
+    if(scn->decoder)
+        return(zbar_decode_width(scn->decoder, 0));
+    return(ZBAR_PARTIAL);
+}
+
+zbar_symbol_type_t zbar_scanner_new_scan (zbar_scanner_t *scn)
+{
+    zbar_symbol_type_t edge = ZBAR_NONE;
+    while(scn->y1_sign) {
+        zbar_symbol_type_t tmp = zbar_scanner_flush(scn);
+        if(tmp < 0 || tmp > edge)
+            edge = tmp;
+    }
+
+    /* reset scanner and associated decoder */
+    memset(&scn->x, 0, sizeof(zbar_scanner_t) + (unsigned int)scn - (unsigned int)&scn->x);
+    scn->y1_thresh = scn->y1_min_thresh;
+    if(scn->decoder)
+        zbar_decoder_new_scan(scn->decoder);
+    return(edge);
+}
+
+zbar_symbol_type_t zbar_scan_y (zbar_scanner_t *scn,
+                                int y)
+{
+    /* FIXME calc and clip to max y range... */
+    /* retrieve short value history */
+    register int x = scn->x;
+    register int y0_1 = scn->y0[(x - 1) & 3];
+    register int y0_0 = y0_1;
+    if(x) {
+        /* update weighted moving average */
+        y0_0 += ((int)((y - y0_1) * EWMA_WEIGHT)) >> ZBAR_FIXED;
+        scn->y0[x & 3] = y0_0;
+    }
+    else
+        y0_0 = y0_1 = scn->y0[0] = scn->y0[1] = scn->y0[2] = scn->y0[3] = y;
+    register int y0_2 = scn->y0[(x - 2) & 3];
+    register int y0_3 = scn->y0[(x - 3) & 3];
+    /* 1st differential @ x-1 */
+    register int y1_1 = y0_1 - y0_2;
+    {
+        register int y1_2 = y0_2 - y0_3;
+        if((abs(y1_1) < abs(y1_2)) &&
+           ((y1_1 >= 0) == (y1_2 >= 0)))
+            y1_1 = y1_2;
+    }
+
+    /* 2nd differentials @ x-1 & x-2 */
+    register int y2_1 = y0_0 - (y0_1 * 2) + y0_2;
+    register int y2_2 = y0_1 - (y0_2 * 2) + y0_3;
+
+    dprintf(1, "scan: x=%d y=%d y0=%d y1=%d y2=%d",
+            x, y, y0_1, y1_1, y2_1);
+
+    zbar_symbol_type_t edge = ZBAR_NONE;
+    /* 2nd zero-crossing is 1st local min/max - could be edge */
+    if((!y2_1 ||
+        ((y2_1 > 0) ? y2_2 < 0 : y2_2 > 0)) &&
+       (calc_thresh(scn) <= abs(y1_1)))
+    {
+        /* check for 1st sign change */
+        char y1_rev = (scn->y1_sign > 0) ? y1_1 < 0 : y1_1 > 0;
+        if(y1_rev)
+            /* intensity change reversal - finalize previous edge */
+            edge = process_edge(scn, y1_1);
+
+        if(y1_rev || (abs(scn->y1_sign) < abs(y1_1))) {
+            scn->y1_sign = y1_1;
+
+            /* adaptive thresholding */
+            /* start at multiple of new min/max */
+            scn->y1_thresh = (abs(y1_1) * THRESH_INIT + ROUND) >> ZBAR_FIXED;
+            dprintf(1, "\tthr=%d", scn->y1_thresh);
+            if(scn->y1_thresh < scn->y1_min_thresh)
+                scn->y1_thresh = scn->y1_min_thresh;
+
+            /* update current edge */
+            int d = y2_1 - y2_2;
+            scn->cur_edge = 1 << ZBAR_FIXED;
+            if(!d)
+                scn->cur_edge >>= 1;
+            else if(y2_1)
+                /* interpolate zero crossing */
+                scn->cur_edge -= ((y2_1 << ZBAR_FIXED) + 1) / d;
+            scn->cur_edge += x << ZBAR_FIXED;
+            dprintf(1, "\n");
+        }
+    }
+    else
+        dprintf(1, "\n");
+    /* FIXME add fall-thru pass to decoder after heuristic "idle" period
+       (eg, 6-8 * last width) */
+    scn->x = x + 1;
+    return(edge);
+}
+
+/* undocumented API for drawing cutesy debug graphics */
+void zbar_scanner_get_state (const zbar_scanner_t *scn,
+                             unsigned *x,
+                             unsigned *cur_edge,
+                             unsigned *last_edge,
+                             int *y0,
+                             int *y1,
+                             int *y2,
+                             int *y1_thresh)
+{
+    register int y0_0 = scn->y0[(scn->x - 1) & 3];
+    register int y0_1 = scn->y0[(scn->x - 2) & 3];
+    register int y0_2 = scn->y0[(scn->x - 3) & 3];
+    if(x) *x = scn->x - 1;
+    if(cur_edge) *cur_edge = scn->cur_edge;
+    if(last_edge) *last_edge = scn->last_edge;
+    if(y0) *y0 = y0_1;
+    if(y1) *y1 = y0_1 - y0_2;
+    if(y2) *y2 = y0_0 - (y0_1 * 2) + y0_2;
+    /* NB not quite accurate (uses updated x) */
+    zbar_scanner_t *mut_scn = (zbar_scanner_t*)scn;
+    if(y1_thresh) *y1_thresh = calc_thresh(mut_scn);
+    dprintf(1, "\n");
+}

+ 244 - 0
Third_Party/ZBAR/src/symbol.c

@@ -0,0 +1,244 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+//#include <assert.h>
+
+#include <zbar.h>
+#include "symbol.h"
+
+const char *zbar_get_symbol_name (zbar_symbol_type_t sym)
+{
+    switch(sym & ZBAR_SYMBOL) {
+    case ZBAR_EAN8: return("EAN-8");
+    case ZBAR_UPCE: return("UPC-E");
+    case ZBAR_ISBN10: return("ISBN-10");
+    case ZBAR_UPCA: return("UPC-A");
+    case ZBAR_EAN13: return("EAN-13");
+    case ZBAR_ISBN13: return("ISBN-13");
+    case ZBAR_I25: return("I2/5");
+    case ZBAR_CODE39: return("CODE-39");
+    case ZBAR_CODE128: return("CODE-128");
+    case ZBAR_PDF417: return("PDF417");
+    case ZBAR_QRCODE: return("QR-Code");
+    default: return("UNKNOWN");
+    }
+}
+
+const char *zbar_get_addon_name (zbar_symbol_type_t sym)
+{
+    switch(sym & ZBAR_ADDON) {
+    case ZBAR_ADDON2: return("+2");
+    case ZBAR_ADDON5: return("+5");
+    default: return("");
+    }
+}
+
+
+void _zbar_symbol_free (zbar_symbol_t *sym)
+{
+    if(sym->syms) {
+        zbar_symbol_set_ref(sym->syms, -1);
+        sym->syms = NULL;
+    }
+    if(sym->pts)
+        free(sym->pts);
+    if(sym->data_alloc && sym->data)
+        free(sym->data);
+    free(sym);
+}
+
+void zbar_symbol_ref (const zbar_symbol_t *sym,
+                      int refs)
+{
+    zbar_symbol_t *ncsym = (zbar_symbol_t*)sym;
+    _zbar_symbol_refcnt(ncsym, refs);
+}
+
+zbar_symbol_type_t zbar_symbol_get_type (const zbar_symbol_t *sym)
+{
+    return(sym->type);
+}
+
+const char *zbar_symbol_get_data (const zbar_symbol_t *sym)
+{
+    return(sym->data);
+}
+
+unsigned int zbar_symbol_get_data_length (const zbar_symbol_t *sym)
+{
+    return(sym->datalen);
+}
+
+int zbar_symbol_get_count (const zbar_symbol_t *sym)
+{
+    return(sym->cache_count);
+}
+
+int zbar_symbol_get_quality (const zbar_symbol_t *sym)
+{
+    return(sym->quality);
+}
+
+unsigned zbar_symbol_get_loc_size (const zbar_symbol_t *sym)
+{
+    return(sym->npts);
+}
+
+int zbar_symbol_get_loc_x (const zbar_symbol_t *sym,
+                           unsigned idx)
+{
+    if(idx < sym->npts)
+        return(sym->pts[idx].x);
+    else
+        return(-1);
+}
+
+int zbar_symbol_get_loc_y (const zbar_symbol_t *sym,
+                           unsigned idx)
+{
+    if(idx < sym->npts)
+        return(sym->pts[idx].y);
+    else
+        return(-1);
+}
+
+const zbar_symbol_t *zbar_symbol_next (const zbar_symbol_t *sym)
+{
+    return((sym) ? sym->next : NULL);
+}
+
+const zbar_symbol_set_t*
+zbar_symbol_get_components (const zbar_symbol_t *sym)
+{
+    return(sym->syms);
+}
+
+const zbar_symbol_t *zbar_symbol_first_component (const zbar_symbol_t *sym)
+{
+    return((sym && sym->syms) ? sym->syms->head : NULL);
+}
+
+
+static const char *xmlfmt[] = {
+    "<symbol type='%s' quality='%d'",
+    " count='%d'",
+    "><data><![CDATA[",
+    "]]></data></symbol>",
+};
+
+/* FIXME suspect... */
+#define MAX_INT_DIGITS 10
+
+char *zbar_symbol_xml (const zbar_symbol_t *sym,
+                       char **buf,
+                       unsigned *len)
+{
+    const char *type = zbar_get_symbol_name(sym->type);
+    /* FIXME binary data */
+    unsigned datalen = strlen(sym->data);
+    unsigned maxlen = (strlen(xmlfmt[0]) + strlen(xmlfmt[1]) +
+                       strlen(xmlfmt[2]) + strlen(xmlfmt[3]) +
+                       strlen(type) + datalen + MAX_INT_DIGITS + 1);
+    if(!*buf || (*len < maxlen)) {
+        if(*buf)
+            free(*buf);
+        *buf = malloc(maxlen);
+        /* FIXME check OOM */
+        *len = maxlen;
+    }
+
+    int n = snprintf(*buf, maxlen, xmlfmt[0], type, sym->quality);
+    assert(n > 0);
+    assert(n <= maxlen);
+
+    if(sym->cache_count) {
+        int i = snprintf(*buf + n, maxlen - n, xmlfmt[1], sym->cache_count);
+        assert(i > 0);
+        n += i;
+        assert(n <= maxlen);
+    }
+
+    int i = strlen(xmlfmt[2]);
+    memcpy(*buf + n, xmlfmt[2], i + 1);
+    n += i;
+    assert(n <= maxlen);
+
+    /* FIXME binary data */
+    /* FIXME handle "]]>" */
+    strncpy(*buf + n, sym->data, datalen + 1);
+    n += datalen;
+    assert(n <= maxlen);
+
+    i = strlen(xmlfmt[3]);
+    memcpy(*buf + n, xmlfmt[3], i + 1);
+    n += i;
+    assert(n <= maxlen);
+
+    *len = n;
+    return(*buf);
+}
+
+
+zbar_symbol_set_t *_zbar_symbol_set_create ()
+{
+    zbar_symbol_set_t *syms = calloc(1, sizeof(*syms));
+    _zbar_refcnt(&syms->refcnt, 1);
+    return(syms);
+}
+
+inline void _zbar_symbol_set_free (zbar_symbol_set_t *syms)
+{
+    zbar_symbol_t *sym, *next;
+    for(sym = syms->head; sym; sym = next) {
+        next = sym->next;
+        sym->next = NULL;
+        _zbar_symbol_refcnt(sym, -1);
+    }
+    syms->head = NULL;
+    free(syms);
+}
+
+void zbar_symbol_set_ref (const zbar_symbol_set_t *syms,
+                          int delta)
+{
+    zbar_symbol_set_t *ncsyms = (zbar_symbol_set_t*)syms;
+    if(!_zbar_refcnt(&ncsyms->refcnt, delta) && delta <= 0)
+        _zbar_symbol_set_free(ncsyms);
+}
+
+int zbar_symbol_set_get_size (const zbar_symbol_set_t *syms)
+{
+    return(syms->nsyms);
+}
+
+const zbar_symbol_t*
+zbar_symbol_set_first_symbol (const zbar_symbol_set_t *syms)
+{
+    zbar_symbol_t *sym = syms->tail;
+    if(sym)
+        return(sym->next);
+    return(syms->head);
+}

+ 140 - 0
Third_Party/ZBAR/src/util.c

@@ -0,0 +1,140 @@
+/*Copyright (C) 2008-2009  Timothy B. Terriberry (tterribe@xiph.org)
+  You can redistribute this library 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.*/
+//#include <stdlib.h>
+#include "util.h"
+
+/*Computes floor(sqrt(_val)) exactly.*/
+unsigned qr_isqrt(unsigned _val){
+  unsigned g;
+  unsigned b;
+  int      bshift;
+  /*Uses the second method from
+     http://www.azillionmonkeys.com/qed/sqroot.html
+    The main idea is to search for the largest binary digit b such that
+     (g+b)*(g+b) <= _val, and add it to the solution g.*/
+  g=0;
+  b=0x8000;
+  for(bshift=16;bshift-->0;){
+    unsigned t;
+    t=(g<<1)+b<<bshift;
+    if(t<=_val){
+      g+=b;
+      _val-=t;
+    }
+    b>>=1;
+  }
+  return g;
+}
+
+/*Computes sqrt(_x*_x+_y*_y) using CORDIC.
+  This implementation is valid for all 32-bit inputs and returns a result
+   accurate to about 27 bits of precision.
+  It has been tested for all postiive 16-bit inputs, where it returns correctly
+   rounded results in 99.998% of cases and the maximum error is
+   0.500137134862598032 (for _x=48140, _y=63018).
+  Very nearly all results less than (1<<16) are correctly rounded.
+  All Pythagorean triples with a hypotenuse of less than ((1<<27)-1) evaluate
+   correctly, and the total bias over all Pythagorean triples is -0.04579, with
+   a relative RMS error of 7.2864E-10 and a relative peak error of 7.4387E-9.*/
+unsigned qr_ihypot(int _x,int _y){
+  unsigned x;
+  unsigned y;
+  int      mask;
+  int      shift;
+  int      u;
+  int      v;
+  int      i;
+  x=_x=abs(_x);
+  y=_y=abs(_y);
+  mask=-(x>y)&(_x^_y);
+  x^=mask;
+  y^=mask;
+  _y^=mask;
+  shift=31-qr_ilog(y);
+  shift=QR_MAXI(shift,0);
+  x=(unsigned)((x<<shift)*0x9B74EDAAULL>>32);
+  _y=(int)((_y<<shift)*0x9B74EDA9LL>>32);
+  u=x;
+  mask=-(_y<0);
+  x+=_y+mask^mask;
+  _y-=u+mask^mask;
+  u=x+1>>1;
+  v=_y+1>>1;
+  mask=-(_y<0);
+  x+=v+mask^mask;
+  _y-=u+mask^mask;
+  for(i=1;i<16;i++){
+    int r;
+    u=x+1>>2;
+    r=(1<<2*i)>>1;
+    v=_y+r>>2*i;
+    mask=-(_y<0);
+    x+=v+mask^mask;
+    _y=_y-(u+mask^mask)<<1;
+  }
+  return x+((1U<<shift)>>1)>>shift;
+}
+
+#if defined(__GNUC__) && defined(HAVE_FEATURES_H)
+# include <features.h>
+# if __GNUC_PREREQ(3,4)
+#  include <limits.h>
+#  if INT_MAX>=2147483647
+#   define QR_CLZ0 sizeof(unsigned)*CHAR_BIT
+#   define QR_CLZ(_x) (__builtin_clz(_x))
+#  elif LONG_MAX>=2147483647L
+#   define QR_CLZ0 sizeof(unsigned long)*CHAR_BIT
+#   define QR_CLZ(_x) (__builtin_clzl(_x))
+#  endif
+# endif
+#endif
+
+int qr_ilog(unsigned _v){
+#if defined(QR_CLZ)
+/*Note that __builtin_clz is not defined when _x==0, according to the gcc
+   documentation (and that of the x86 BSR instruction that implements it), so
+   we have to special-case it.*/
+  return QR_CLZ0-QR_CLZ(_v)&-!!_v;
+#else
+  int ret;
+  int m;
+  m=!!(_v&0xFFFF0000)<<4;
+  _v>>=m;
+  ret=m;
+  m=!!(_v&0xFF00)<<3;
+  _v>>=m;
+  ret|=m;
+  m=!!(_v&0xF0)<<2;
+  _v>>=m;
+  ret|=m;
+  m=!!(_v&0xC)<<1;
+  _v>>=m;
+  ret|=m;
+  ret|=!!(_v&0x2);
+  return ret + !!_v;
+#endif
+}
+
+#if defined(QR_TEST_SQRT)
+#include <math.h>
+#include <stdio.h>
+
+/*Exhaustively test the integer square root function.*/
+int main(void){
+  unsigned u;
+  u=0;
+  do{
+    unsigned r;
+    unsigned s;
+    r=qr_isqrt(u);
+    s=(int)sqrt(u);
+    if(r!=s)printf("%u: %u!=%u\n",u,r,s);
+    u++;
+  }
+  while(u);
+  return 0;
+}
+#endif

+ 380 - 0
Third_Party/ZBAR/src/video.c

@@ -0,0 +1,380 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include "video.h"
+#include "image.h"
+
+
+#ifdef HAVE_LIBJPEG
+extern struct jpeg_decompress_struct *_zbar_jpeg_decomp_create(void);
+extern void _zbar_jpeg_decomp_destroy(struct jpeg_decompress_struct *cinfo);
+#endif
+
+static void _zbar_video_recycle_image (zbar_image_t *img)
+{
+    zbar_video_t *vdo = img->src;
+    assert(vdo);
+    assert(img->srcidx >= 0);
+    video_lock(vdo);
+    if(vdo->images[img->srcidx] != img)
+        vdo->images[img->srcidx] = img;
+    if(vdo->active)
+        vdo->nq(vdo, img);
+    else
+        video_unlock(vdo);
+}
+
+static void _zbar_video_recycle_shadow (zbar_image_t *img)
+{
+    zbar_video_t *vdo = img->src;
+    assert(vdo);
+    assert(img->srcidx == -1);
+    video_lock(vdo);
+    img->next = vdo->shadow_image;
+    vdo->shadow_image = img;
+    video_unlock(vdo);
+}
+
+zbar_video_t *zbar_video_create ()
+{
+    zbar_video_t *vdo = calloc(1, sizeof(zbar_video_t));
+    if(!vdo)
+        return(NULL);
+    err_init(&vdo->err, ZBAR_MOD_VIDEO);
+    vdo->fd = -1;
+
+    (void)_zbar_mutex_init(&vdo->qlock);
+
+    /* pre-allocate images */
+    vdo->num_images = ZBAR_VIDEO_IMAGES_MAX;
+    vdo->images = calloc(ZBAR_VIDEO_IMAGES_MAX, sizeof(zbar_image_t*));
+    if(!vdo->images) {
+        zbar_video_destroy(vdo);
+        return(NULL);
+    }
+
+    int i;
+    for(i = 0; i < ZBAR_VIDEO_IMAGES_MAX; i++) {
+        zbar_image_t *img = vdo->images[i] = zbar_image_create();
+        if(!img) {
+            zbar_video_destroy(vdo);
+            return(NULL);
+        }
+        img->refcnt = 0;
+        img->cleanup = _zbar_video_recycle_image;
+        img->srcidx = i;
+        img->src = vdo;
+    }
+
+    return(vdo);
+}
+
+void zbar_video_destroy (zbar_video_t *vdo)
+{
+    if(vdo->intf != VIDEO_INVALID)
+        zbar_video_open(vdo, NULL);
+    if(vdo->images) {
+        int i;
+        for(i = 0; i < ZBAR_VIDEO_IMAGES_MAX; i++)
+            if(vdo->images[i])
+                free(vdo->images[i]);
+        free(vdo->images);
+    }
+    while(vdo->shadow_image) {
+        zbar_image_t *img = vdo->shadow_image;
+        vdo->shadow_image = img->next;
+        free((void*)img->data);
+        img->data = NULL;
+        free(img);
+    }
+    if(vdo->buf)
+        free(vdo->buf);
+    if(vdo->formats)
+        free(vdo->formats);
+    err_cleanup(&vdo->err);
+    _zbar_mutex_destroy(&vdo->qlock);
+
+#ifdef HAVE_LIBJPEG
+    if(vdo->jpeg_img) {
+        zbar_image_destroy(vdo->jpeg_img);
+        vdo->jpeg_img = NULL;
+    }
+    if(vdo->jpeg) {
+        _zbar_jpeg_decomp_destroy(vdo->jpeg);
+        vdo->jpeg = NULL;
+    }
+#endif
+    free(vdo);
+}
+
+int zbar_video_open (zbar_video_t *vdo,
+                     const char *dev)
+{
+    zbar_video_enable(vdo, 0);
+    video_lock(vdo);
+    if(vdo->intf != VIDEO_INVALID) {
+        if(vdo->cleanup) {
+            vdo->cleanup(vdo);
+            vdo->cleanup = NULL;
+        }
+        zprintf(1, "closed camera (fd=%d)\n", vdo->fd);
+        vdo->intf = VIDEO_INVALID;
+    }
+    video_unlock(vdo);
+
+    if(!dev)
+        return(0);
+
+    char *ldev = NULL;
+    if((unsigned char)dev[0] < 0x10) {
+        /* default linux device, overloaded for other platforms */
+        int id = dev[0];
+        dev = ldev = strdup("/dev/video0");
+        ldev[10] = '0' + id;
+    }
+
+    int rc = _zbar_video_open(vdo, dev);
+
+    if(ldev)
+        free(ldev);
+    return(rc);
+}
+
+int zbar_video_get_fd (const zbar_video_t *vdo)
+{
+    if(vdo->intf == VIDEO_INVALID)
+        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                           "video device not opened"));
+    if(vdo->intf != VIDEO_V4L2)
+        return(err_capture(vdo, SEV_WARNING, ZBAR_ERR_UNSUPPORTED, __func__,
+                           "video driver does not support polling"));
+    return(vdo->fd);
+}
+
+int zbar_video_request_size (zbar_video_t *vdo,
+                             unsigned width,
+                             unsigned height)
+{
+    if(vdo->initialized)
+        /* FIXME re-init different format? */
+        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                           "already initialized, unable to resize"));
+
+    vdo->width = width;
+    vdo->height = height;
+    zprintf(1, "request size: %d x %d\n", width, height);
+    return(0);
+}
+
+int zbar_video_request_interface (zbar_video_t *vdo,
+                                  int ver)
+{
+    if(vdo->intf != VIDEO_INVALID)
+        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                         "device already opened, unable to change interface"));
+    vdo->intf = (video_interface_t)ver;
+    zprintf(1, "request interface version %d\n", vdo->intf);
+    return(0);
+}
+
+int zbar_video_request_iomode (zbar_video_t *vdo,
+                               int iomode)
+{
+    if(vdo->intf != VIDEO_INVALID)
+        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                         "device already opened, unable to change iomode"));
+    if(iomode < 0 || iomode > VIDEO_USERPTR)
+        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                         "invalid iomode requested"));
+    vdo->iomode = iomode;
+    return(0);
+}
+
+int zbar_video_get_width (const zbar_video_t *vdo)
+{
+    return(vdo->width);
+}
+
+int zbar_video_get_height (const zbar_video_t *vdo)
+{
+    return(vdo->height);
+}
+
+uint32_t zbar_video_get_format (const zbar_video_t *vdo)
+{
+    return(vdo->format);
+}
+
+static inline int video_init_images (zbar_video_t *vdo)
+{
+    
+    assert(vdo->datalen);
+    if(vdo->iomode != VIDEO_MMAP) {
+        assert(!vdo->buf);
+        vdo->buflen = vdo->num_images * vdo->datalen;
+        vdo->buf = malloc(vdo->buflen);
+        if(!vdo->buf)
+            return(err_capture(vdo, SEV_FATAL, ZBAR_ERR_NOMEM, __func__,
+                               "unable to allocate image buffers"));
+        zprintf(1, "pre-allocated %d %s buffers size=0x%lx\n", vdo->num_images,
+                (vdo->iomode == VIDEO_READWRITE) ? "READ" : "USERPTR",
+                vdo->buflen);
+    }
+    int i;
+    for(i = 0; i < vdo->num_images; i++) {
+        zbar_image_t *img = vdo->images[i];
+        img->format = vdo->format;
+        img->width = vdo->width;
+        img->height = vdo->height;
+        if(vdo->iomode != VIDEO_MMAP) {
+            img->datalen = vdo->datalen;
+            unsigned long offset = i * vdo->datalen;
+            img->data = vdo->buf + offset;
+            zprintf(2, "    [%02d] @%08lx\n", i, offset);
+        }
+    }
+    return(0);
+}
+
+int zbar_video_init (zbar_video_t *vdo,
+                     unsigned long fmt)
+{
+    if(vdo->initialized)
+        /* FIXME re-init different format? */
+        return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                           "already initialized, re-init unimplemented"));
+
+    if(vdo->init(vdo, fmt))
+        return(-1);
+    vdo->format = fmt;
+    if(video_init_images(vdo))
+        return(-1);
+#ifdef HAVE_LIBJPEG
+    const zbar_format_def_t *vidfmt = _zbar_format_lookup(fmt);
+    if(vidfmt && vidfmt->group == ZBAR_FMT_JPEG) {
+        /* prepare for decoding */
+        if(!vdo->jpeg)
+            vdo->jpeg = _zbar_jpeg_decomp_create();
+        if(vdo->jpeg_img)
+            zbar_image_destroy(vdo->jpeg_img);
+
+        /* create intermediate image for decoder to use*/
+        zbar_image_t *img = vdo->jpeg_img = zbar_image_create();
+        img->format = fourcc('Y','8','0','0');
+        img->width = vdo->width;
+        img->height = vdo->height;
+        img->datalen = vdo->width * vdo->height;
+    }
+#endif
+    vdo->initialized = 1;
+    return(0);
+}
+
+int zbar_video_enable (zbar_video_t *vdo,
+                       int enable)
+{
+    if(vdo->active == enable)
+        return(0);
+
+    if(enable) {
+        if(vdo->intf == VIDEO_INVALID)
+            return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
+                               "video device not opened"));
+
+        if(!vdo->initialized &&
+           zbar_negotiate_format(vdo, NULL))
+            return(-1);
+    }
+
+    if(video_lock(vdo))
+        return(-1);
+    vdo->active = enable;
+    if(enable) {
+        /* enqueue all buffers */
+        int i;
+        for(i = 0; i < vdo->num_images; i++)
+            if(vdo->nq(vdo, vdo->images[i]) ||
+               ((i + 1 < vdo->num_images) && video_lock(vdo)))
+                return(-1);
+        
+        return(vdo->start(vdo));
+    }
+    else {
+        int i;
+        for(i = 0; i < vdo->num_images; i++)
+            vdo->images[i]->next = NULL;
+        vdo->nq_image = vdo->dq_image = NULL;
+        if(video_unlock(vdo))
+            return(-1);
+
+        return(vdo->stop(vdo));
+    }
+}
+
+zbar_image_t *zbar_video_next_image (zbar_video_t *vdo)
+{
+    if(video_lock(vdo))
+        return(NULL);
+    if(!vdo->active) {
+        video_unlock(vdo);
+        return(NULL);
+    }
+
+    unsigned frame = vdo->frame++;
+    zbar_image_t *img = vdo->dq(vdo);
+    if(img) {
+        img->seq = frame;
+        if(vdo->num_images < 2) {
+            /* return a *copy* of the video image and immediately recycle
+             * the driver's buffer to avoid deadlocking the resources
+             */
+            zbar_image_t *tmp = img;
+            video_lock(vdo);
+            img = vdo->shadow_image;
+            vdo->shadow_image = (img) ? img->next : NULL;
+            video_unlock(vdo);
+                
+            if(!img) {
+                img = zbar_image_create();
+                assert(img);
+                img->refcnt = 0;
+                img->src = vdo;
+                /* recycle the shadow images */
+
+                img->format = vdo->format;
+                img->width = vdo->width;
+                img->height = vdo->height;
+                img->datalen = vdo->datalen;
+                img->data = malloc(vdo->datalen);
+            }
+            img->cleanup = _zbar_video_recycle_shadow;
+            img->seq = frame;
+            memcpy((void*)img->data, tmp->data, img->datalen);
+            _zbar_video_recycle_image(tmp);
+        }
+        else
+            img->cleanup = _zbar_video_recycle_image;
+        _zbar_image_refcnt(img, 1);
+    }
+    return(img);
+}

+ 1760 - 0
Third_Party/ZBAR/src/zbar.c

@@ -0,0 +1,1760 @@
+#include "zbar.h"
+#include "symbol.h"
+#include "bsp_common.h"
+#define MODULE_NAME "ZBAR"
+
+extern int errno;
+
+
+zbar_t *zbar_create(void)
+{
+	zbar_t *p = zalloc(sizeof(zbar_t));
+	if (!p)
+	{
+		return NULL;
+	}
+	p->scanner = zbar_image_scanner_create();
+	if (!p->scanner)
+	{
+		free(p);
+		return NULL;
+	}
+	zbar_image_scanner_set_config(p->scanner, 0, ZBAR_CFG_ENABLE, 1);
+	p->image = NULL;
+	return p;
+}
+
+int zbar_run(zbar_t *zbar, int width, int height, void *Data)
+{
+  int n;
+
+  if (zbar->image)
+  {
+  	zbar_image_destroy(zbar->image);
+  }
+  zbar->image = zbar_image_create();
+  if (!zbar->image)
+  {
+  	return -1;
+  }
+
+  zbar_image_set_format(zbar->image, *(int*)"Y800");
+  zbar_image_set_size(zbar->image, width, height);
+  zbar_image_set_data(zbar->image, Data, width * height, zbar_image_free_data);
+  n = zbar_scan_image(zbar->scanner, zbar->image);
+  zbar->symbol = (zbar_symbol_t *)zbar_image_first_symbol(zbar->image);

+
+  return n;
+}
+
+char *zbar_get_data_ptr(zbar_t* zbar, unsigned int* len)
+{
+	if (!zbar->symbol)
+	{
+		return NULL;
+	}
+	*len = zbar->symbol->datalen;
+	return zbar->symbol->data;
+}
+
+int zbar_find_next_data(zbar_t *zbar)
+{
+	if (!zbar->symbol)
+	{
+		return 0;
+	}
+	zbar->symbol = (zbar_symbol_t *)zbar_symbol_next(zbar->symbol);
+	if (zbar->symbol)
+	{
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+void zbar_destory(zbar_t *zbar)
+{
+	if (zbar->image)
+		zbar_image_destroy(zbar->image);
+	if (zbar->scanner)
+		zbar_image_scanner_destroy(zbar->scanner);
+	if (zbar)
+		free(zbar);
+}
+
+#ifdef zbar_test
+const unsigned char pngData[]=
+{
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfd,0xfc,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfd,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfd,0xfd,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xff,0xff,
+0xff,0xfc,0xfe,0xfd,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfd,0xfe,0xff,0xbd,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc0,0xe7,
+0xff,0xfd,0xff,0xd2,0xc3,0xc4,0xc4,0xc4,0xc4,0xc4,0xbe,0xf9,0xff,0xfe,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbd,0xc3,0xc5,0xc4,0xc4,0xc4,0xc2,0xcc,0xff,
+0xfd,0xff,0xee,0xbe,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc0,0xe3,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xd1,0xc2,0xc4,0xc4,0xc4,0xc4,0xc5,0xbd,0xfa,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc4,0xc3,0xc3,0xff,0xfd,0xff,0xff,0xff,0xfd,
+0xff,0xf2,0xbe,0xc5,0xc2,0xd4,0xff,0xff,0xff,0xe6,0xbe,0xc5,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xbe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99,0xff,0xff,
+0xff,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe5,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0xff,0xfe,0xff,
+0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xc7,
+0x00,0x00,0x00,0x39,0xff,0xff,0xff,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0xff,0xff,0xff,0x42,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xff,0xfe,0xff,0xba,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8f,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xed,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcd,0x00,0x00,
+0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xff,0xff,0xff,0xc2,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd3,0x00,0x00,0x00,0x41,
+0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x05,
+0x5f,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,
+0x56,0x56,0x5c,0x28,0x00,0x00,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xa6,0xa7,0xa8,0xa3,0xff,0xff,0xff,0xff,0x45,
+0x56,0x58,0x50,0x00,0x00,0x00,0x1e,0xb6,0xa8,0xae,0x7b,0x00,0x00,0x00,0x20,0x5d,
+0x56,0x56,0x56,0x56,0x56,0x51,0x84,0xac,0xa8,0xa8,0xa8,0xa8,0xa8,0xb6,0x29,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x9b,0xab,0xa8,0xa8,0xa8,0xa8,0xa9,0xaa,0x53,0x56,
+0x54,0x56,0xff,0xff,0xff,0xf6,0x9f,0xa8,0xaa,0x97,0x50,0x56,0x50,0x86,0xff,0xff,
+0xff,0x9b,0x00,0x01,0x00,0x29,0x5c,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,
+0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x5f,0x04,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x14,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x7d,0x00,0x00,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xea,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xf9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0xe1,0x00,0x00,0x00,0x28,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0x9b,
+0x00,0x01,0x00,0x84,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x10,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x74,
+0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xea,0x00,
+0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xe6,0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,
+0x00,0x7b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x74,0x00,0x01,
+0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf2,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xef,
+0x00,0x00,0x00,0x2b,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,
+0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xea,0x7e,0x8a,0x89,0x89,
+0x89,0x89,0x89,0x89,0x89,0x89,0x83,0xbb,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,
+0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0x90,0x8a,0x89,0x89,0x89,0x89,0x8a,0x87,0x73,0x74,0x79,0x60,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb0,0x6d,
+0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,0x74,
+0x74,0x74,0x74,0x74,0x73,0x6f,0xff,0xff,0xff,0xfb,0x7c,0x8a,0x8a,0x87,0x73,0x74,
+0x73,0x78,0x8b,0x89,0x84,0xab,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xfd,
+0xff,0xb8,0x83,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x7f,0xec,0xff,0xff,
+0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x68,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,
+0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0x00,0x00,0x02,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0xff,0xff,0xff,0xde,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfa,0x00,0x00,0x00,0x10,0xff,0xff,0xff,0xd4,
+0x00,0x00,0x00,0x3e,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xfb,0xff,0x63,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd8,0xff,0xff,0xff,0x0d,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x70,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xfe,0xff,0x00,0x00,0x01,0x00,0x01,
+0x00,0x00,0x00,0x00,0x00,0x00,0x15,0xff,0xfc,0xff,0xd1,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xff,0xff,0xff,0xff,0xfe,0x00,0x01,0x00,0x19,0xff,0xfd,0xff,0xcc,0x00,0x00,
+0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xfd,0xff,0x69,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0xff,0xff,0xff,0x0d,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x11,0xff,0xff,0xff,0xd7,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfe,0xff,0x38,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x18,0xff,0xff,0xff,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x18,0xff,0xfe,0xff,0xc9,0x00,0x00,0x00,0x3d,
+0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xda,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,
+0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,
+0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfe,0xff,0xae,0x8d,0x91,0x9e,0x1a,
+0x00,0x00,0x00,0xea,0xff,0xfe,0xff,0x90,0x8f,0x92,0x99,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x0a,0x78,0x6d,0x6c,0x74,0x94,0x90,0x98,0x6b,0x00,0x00,0x00,0x5e,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xac,0x64,0x6d,0x61,0xca,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0x6a,0x6b,0x6c,0x67,0xff,0xff,
+0xff,0xfe,0x00,0x00,0x00,0x18,0xff,0xfd,0xff,0xe8,0x87,0x92,0x8c,0xb1,0xff,0xff,
+0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,
+0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfe,0xfd,0xff,0xff,0xff,0xff,0x2f,0x00,0x00,
+0x00,0xea,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x27,0xff,0xff,0xff,0xc3,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x68,0x00,0x00,0x00,0xa1,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,
+0xff,0xff,0xff,0xfe,0xfe,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,
+0x00,0x00,0x00,0x18,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0x9b,
+0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,
+0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,
+0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0xe7,
+0xff,0xfd,0xfe,0xfd,0xfd,0xfd,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
+0x01,0x00,0x2d,0xff,0xff,0xff,0xba,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x71,0x00,0x02,0x00,0xa5,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfd,0xfd,0xfd,0xfd,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,0x00,0x01,
+0x00,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,
+0x00,0x7b,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xdc,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,
+0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1d,0x00,0x00,0x00,0xe5,0xff,0xfd,
+0xfe,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x1d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x65,0x00,0x00,0x00,0xab,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xfd,0xfd,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x03,0x00,0x18,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,
+0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,
+0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbc,0xad,0xaf,0xa5,0xf6,0xff,0xfe,0xff,0x4e,
+0x4e,0x4f,0x4b,0xb2,0xb0,0xb1,0xb0,0x00,0x00,0x00,0x10,0xbd,0xaf,0xac,0xbc,0xff,
+0xfd,0xff,0xba,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd0,0xaa,
+0xaf,0xb5,0x72,0x4c,0x4f,0x4f,0x4f,0x4f,0x4e,0x41,0xe1,0xff,0xfe,0xff,0x5b,0x4c,
+0x4f,0x48,0xaf,0xb0,0xb0,0xb2,0x4a,0x4e,0x50,0x53,0x00,0x02,0x00,0x18,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,
+0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,
+0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x16,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xba,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd5,0xff,0xff,0xff,0x07,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0x6a,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0x0d,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xba,0x00,
+0x00,0x00,0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x58,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xd7,0xff,0xff,0xff,0x11,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0x6a,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0x0d,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x11,0xff,0xff,0xff,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x63,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb2,0x00,0x00,0x00,
+0x4f,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x53,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xe9,0xff,0xff,0xff,0x15,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0x5d,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd6,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,
+0xff,0xff,0xff,0xf7,0xc4,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xc8,0xe0,
+0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x69,0x2b,0x32,0x22,0xd9,
+0xff,0xff,0xff,0x46,0x2f,0x32,0x3a,0x00,0x00,0x00,0x00,0x38,0x32,0x33,0x34,0x00,
+0x00,0x00,0x14,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xc6,0xcc,0xc7,0xdd,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x8d,0x27,0x32,0x2a,0x95,0xd1,0xcc,0xdc,0x33,0x00,
+0x00,0x00,0x2c,0x35,0x32,0x38,0x04,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x04,0x3a,0x32,0x32,0x32,0x32,0x32,0x2a,0x6d,0xff,0xff,
+0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0xdf,0xc8,0xcc,0xcc,0xcc,0xcc,0xcc,
+0xcc,0xcc,0xcc,0xcc,0xc4,0xf8,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfe,0xff,0x3d,0x00,0x00,0x00,0xd0,0xff,0xff,
+0xff,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x14,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x6b,0x00,0x00,0x00,0xa7,0xff,0xff,0xff,0x41,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0xff,0xff,0xff,0x9b,
+0x00,0x01,0x00,0x7b,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x74,
+0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x16,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x71,0x00,0x00,0x00,0xa7,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x01,
+0x00,0x7b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x15,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,
+0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x16,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
+0x6d,0x00,0x00,0x00,0xac,0xff,0xff,0xff,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x87,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x13,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x18,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x17,0x09,0x00,0x01,0x00,0xa1,
+0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x16,0x00,0x00,0x00,0xe9,
+0xec,0xea,0xf4,0x00,0x00,0x00,0x00,0xff,0xeb,0xee,0xd4,0x06,0x15,0x0d,0x3f,0xff,
+0xfd,0xff,0xbe,0x02,0x14,0x0a,0x6b,0xff,0xff,0xff,0x91,0x07,0x15,0x0a,0x8c,0xf3,
+0xe9,0xf7,0x60,0x0c,0x14,0x05,0xb3,0xf1,0xeb,0xfe,0x27,0x00,0x00,0x00,0xd7,0xef,
+0xe8,0xf7,0x15,0x12,0x12,0x10,0xf2,0xeb,0xed,0xe7,0x00,0x01,0x00,0x1a,0xfd,0xe9,
+0xef,0xbb,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x0b,0x17,0x14,
+0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x15,
+0x19,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0xa1,0xff,0xff,
+0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x16,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xec,0x00,0x00,0x00,0x28,0xff,0xfd,0xff,
+0xb9,0x00,0x00,0x00,0x5b,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0x8f,0xff,0xff,0xff,
+0x56,0x00,0x00,0x00,0xc2,0xff,0xff,0xff,0x28,0x00,0x01,0x00,0xf1,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x02,0x00,0x1a,0xff,0xff,0xff,0xd2,
+0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0xff,0xfe,0xff,0x42,
+0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x15,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0xff,0xfe,0xff,0xea,0x00,0x00,0x00,0x2d,0xff,0xfe,0xff,0xb9,0x00,
+0x00,0x00,0x5d,0xff,0xff,0xff,0x8a,0x00,0x00,0x00,0x8e,0xff,0xfe,0xff,0x58,0x00,
+0x00,0x00,0xbf,0xff,0xfe,0xff,0x28,0x00,0x00,0x00,0xec,0xff,0xfe,0xff,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x19,0xff,0xfe,0xff,0xcc,0x00,0x00,
+0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x96,0xff,0xfd,0xff,0x42,0x00,0x00,
+0x00,0xd2,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x1b,0xff,0xfe,0xff,0xb1,0x00,0x00,0x00,
+0x58,0xff,0xff,0xff,0x8b,0x00,0x00,0x00,0x82,0xff,0xfd,0xff,0x49,0x00,0x00,0x00,
+0xc9,0xff,0xff,0xff,0x2e,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x05,0xff,0xfe,0xff,0xcd,0x00,0x00,0x00,0x49,
+0xff,0xff,0xff,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0x42,0x00,0x00,0x00,0xd2,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x16,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xa0,0x00,
+0x00,0x00,0x76,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcd,0x00,0x00,0x00,0x49,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfd,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
+0x13,0xff,0xff,0xff,0xff,0xfe,0xfd,0xff,0xfe,0xff,0xff,0xff,0xa1,0x00,0x00,0x00,
+0x74,0xff,0xff,0xff,0xff,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0x3e,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xcd,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,
+0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,
+0xff,0xfe,0xff,0xff,0xfd,0xfd,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xfd,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x14,0xff,
+0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xa1,0x00,0x00,0x00,0x75,0xff,
+0xfc,0xfe,0xff,0xff,0xfe,0xff,0xfe,0xfe,0xff,0xff,0x3d,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0xfe,0xfd,0xff,0xcc,0x00,0x00,0x00,0x48,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfe,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x14,0xff,0xff,0xfd,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00,0x00,0x00,0x70,0xff,0xfd,0xfe,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0xff,0xfd,0xff,0xc8,0x00,0x00,0x00,0x46,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd0,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0xff,0xff,0xff,0x6b,0x00,0x00,0x00,0x9a,
+0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x08,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xcc,0x00,
+0x00,0x00,0x39,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x66,0x00,
+0x00,0x00,0x9e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x0b,0xff,0xfe,
+0xfe,0xff,0xff,0xff,0xff,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x8b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x00,0x00,0xa1,0xff,0xff,
+0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x15,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xd0,0x00,0x00,0x00,
+0x43,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x70,0x00,0x00,0x00,
+0xa6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x17,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xb6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x00,0x00,0xa2,0xff,0xff,0xff,0x41,
+0x00,0x00,0x00,0xd1,0xff,0xff,0xff,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x01,0x00,0x00,0x15,0xff,0xff,0xff,0xd2,0x00,0x00,0x00,0x42,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x6f,0x00,0x00,0x00,0xa7,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x16,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x92,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xf7,0xfa,0xff,0xd1,0x00,0x00,0x00,0x01,0x07,0x04,0x04,0x04,0x04,0x04,
+0x00,0x70,0xff,0xfa,0xff,0x75,0x00,0x04,0x00,0x9f,0xff,0xfa,0xff,0x48,0x00,0x04,
+0x00,0xd0,0xff,0xff,0xff,0x1a,0x00,0x04,0x08,0x00,0x00,0x00,0x00,0x08,0x04,0x04,
+0x07,0x00,0x00,0x00,0x17,0xff,0xfa,0xff,0xcc,0x00,0x04,0x00,0x48,0xff,0xfa,0xfa,
+0xfa,0xfa,0xfa,0xf8,0xfa,0xff,0xff,0xff,0x72,0x00,0x04,0x00,0xa4,0xff,0xfa,0xf7,
+0xfd,0xff,0xff,0xff,0xf8,0xf9,0xfa,0xfa,0xfa,0xfa,0xfa,0xff,0x00,0x00,0x00,0x00,
+0xff,0xfb,0xfc,0xf4,0x00,0x04,0x00,0x21,0xff,0xfa,0xf9,0xf8,0xff,0xff,0xff,0xb5,
+0x00,0x00,0x00,0x03,0x06,0x04,0x04,0x04,0x04,0x04,0x00,0x95,0xff,0xff,0xff,0xfa,
+0xf9,0xfa,0xff,0x3f,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xea,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x91,
+0x00,0x00,0x00,0x8b,0xff,0xff,0xff,0x57,0x00,0x00,0x00,0xc5,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x66,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x51,0x00,0x00,0x00,0xb7,0xff,
+0xff,0xff,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x1c,0xff,0xff,0xff,0xb5,0x00,0x00,
+0x00,0x6d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,
+0x00,0xd1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xee,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x8f,0x00,0x00,
+0x00,0x89,0xff,0xff,0xff,0x5d,0x00,0x01,0x00,0xbb,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x74,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x58,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,
+0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xfe,0xff,0xe6,0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x62,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0xc5,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf4,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x3a,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x92,0x00,0x00,0x00,0x8d,
+0xff,0xff,0xff,0x5f,0x00,0x01,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x5b,0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0x23,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,
+0xff,0xeb,0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xb3,0x00,0x00,0x00,0x62,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4e,0x00,0x00,0x00,0xc9,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xd4,0xdc,0xdf,0xcb,0x00,0x00,0x00,0x06,0x28,0x24,
+0x1b,0x59,0xff,0xfe,0xff,0xef,0xd6,0xdc,0xe7,0x7a,0x00,0x00,0x00,0x77,0xe6,0xdb,
+0xec,0x51,0x00,0x00,0x00,0xa0,0xe4,0xdb,0xdb,0xdb,0xdb,0xdb,0xd5,0xfb,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xe4,0xdd,0xde,0xdd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,
+0xe9,0xd8,0xdb,0xeb,0x4d,0x00,0x00,0x00,0xa5,0xe4,0xdc,0xe8,0x42,0x1f,0x23,0x27,
+0x03,0x00,0x01,0x00,0x27,0x22,0x22,0x26,0x00,0x00,0x00,0x04,0xf1,0xdb,0xe0,0xc5,
+0x00,0x00,0x00,0x31,0xff,0xff,0xff,0xbf,0x12,0x22,0x1b,0x6b,0xe6,0xdc,0xdc,0xdc,
+0xdc,0xdb,0xd7,0xee,0xff,0xff,0xff,0x6a,0x19,0x22,0x15,0xb1,0xe1,0xdc,0xdb,0xdb,
+0xdb,0xdb,0xdb,0xdb,0xdb,0xdb,0xd6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfe,0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xff,0xff,0xff,0xff,
+0xfd,0xfd,0xff,0x9e,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
+0x01,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe5,0xff,0xfd,0xff,0x00,
+0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xff,
+0xfd,0xff,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0x62,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0xff,0xff,0xff,0x16,0x00,
+0x03,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,
+0x00,0x31,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x87,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0xff,0xfd,0xfd,0xfd,0xfe,0xfd,
+0xff,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x00,0x00,0x02,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0xff,0xfe,0xff,0x00,0x00,0x01,
+0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xff,0xfd,0xff,
+0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0x71,0x00,0x00,0x00,
+0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd6,0xff,0xfd,0xff,0x12,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x32,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x9c,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x95,
+0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x3a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xab,
+0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xff,0xff,0xff,0xc0,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x79,0xff,0xff,0xff,0x74,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0xff,0xff,0xff,0x14,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x2a,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xff,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x21,0xce,0xbf,0xbf,0xbf,0xbf,0xbf,0xc7,0x7d,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x25,0x44,0x40,0x3f,0x3f,0x3f,0x40,0x46,0x12,0x00,0x00,
+0x00,0x36,0x42,0x3f,0x37,0xb2,0xc0,0xbe,0xc7,0x42,0x40,0x3f,0x3f,0x3f,0x3f,0x40,
+0x42,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x24,0xce,0xbd,0xc6,0x8b,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x59,0xca,0xbe,0xc9,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x31,0x42,0x3f,0x37,0xa9,0xc0,0xbd,0xce,0x0f,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0x35,0x3e,0x40,0x42,0x00,0x01,0x00,0x07,0x48,0x41,0x39,0x65,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x20,0x45,0x40,0x3a,0x89,0xc4,0xbf,0xbf,0xbf,
+0xbf,0xbf,0xc7,0x5e,0x3d,0x41,0x48,0x09,0x00,0x00,0x00,0x3e,0x41,0x3f,0x31,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x94,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a,0x00,0x00,0x00,0xe3,
+0xff,0xff,0xff,0x06,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0xff,
+0xff,0xff,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x1d,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0x9c,0x00,0x01,0x00,0x85,0xff,0xff,0xff,0x67,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xce,0xff,0xff,0xff,0x28,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x8a,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0x43,0x00,0x00,0x00,0xd2,0xff,0xff,
+0xff,0x16,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,
+0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,
+0x00,0x01,0x00,0x1a,0xff,0xfe,0xff,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0x9c,
+0x00,0x00,0x00,0x7a,0xff,0xfc,0xff,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,
+0xff,0xfd,0xff,0x23,0x00,0x00,0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x89,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0x0d,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0xbd,0xff,0xff,0xff,0x27,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x03,
+0x00,0x1b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa1,0x00,0x03,
+0x00,0x80,0xff,0xff,0xff,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xff,0xff,
+0xff,0x26,0x00,0x00,0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x66,0x5f,
+0x5d,0x5d,0x5d,0x5e,0x63,0x3d,0x00,0x00,0x00,0x2a,0x64,0x5d,0x5a,0x82,0xa3,0xa0,
+0xa1,0xa1,0xa1,0xa0,0xae,0x2c,0x00,0x00,0x00,0x85,0xa5,0xa1,0xa6,0x64,0x5e,0x5e,
+0x4e,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,
+0x5d,0x5d,0x5e,0x62,0x44,0x00,0x00,0x00,0x22,0x65,0x5d,0x63,0x33,0x00,0x01,0x00,
+0x00,0x00,0x01,0x00,0x3d,0x62,0x5d,0x50,0xd6,0xff,0xff,0xff,0x27,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x9b,0xa0,0xa3,0xa0,0x00,0x01,0x00,0x11,
+0xb0,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa1,0xa8,0x63,0x00,0x00,0x00,0x4f,
+0xaa,0xa0,0xa4,0x7a,0x5a,0x5d,0x5d,0x5d,0x5d,0x5d,0x58,0x91,0xa1,0xa0,0xaf,0x18,
+0x00,0x00,0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xb2,0x00,0x00,0x00,0x79,0xff,0xff,0xff,0x73,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0xff,0xff,0xff,0xfe,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xc7,0x00,0x00,0x00,0x64,0xff,0xff,0xff,0x92,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xb1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x96,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x31,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0xff,0xff,0xff,0xff,0xff,0xfd,
+0xff,0xa6,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xba,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
+0xa6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x94,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xf1,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xa0,
+0x00,0x00,0x00,0x6e,0xff,0xff,0xff,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb5,0x00,
+0x00,0x00,0x54,0xff,0xff,0xff,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x94,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x09,0x87,0x7c,0x7c,0x7d,0x83,0x82,0x7e,0xa1,0xff,0xff,0xff,0xd1,0x72,0x7c,
+0x7c,0x7f,0x82,0x82,0x82,0x7f,0x7b,0x7b,0x85,0x2e,0x00,0x00,0x00,0x5c,0x81,0x7c,
+0x7c,0x7c,0x7c,0x7c,0x6f,0xf3,0xff,0xff,0xff,0x80,0x81,0x82,0x82,0x82,0x82,0x81,
+0x80,0xff,0xfe,0xff,0xf3,0x77,0x82,0x7e,0x97,0xff,0xff,0xff,0xdb,0x71,0x7c,0x75,
+0xac,0xff,0xff,0xff,0xc2,0x73,0x7c,0x7c,0x7c,0x7c,0x7c,0x7b,0x7f,0x82,0x82,0x78,
+0xde,0xff,0xff,0xff,0x27,0x00,0x00,0x00,0x73,0x7e,0x7c,0x6f,0xff,0xff,0xff,0xff,
+0x75,0x7b,0x7d,0x7c,0x00,0x00,0x00,0x0d,0x87,0x7c,0x7c,0x7c,0x7c,0x7c,0x81,0x59,
+0x00,0x00,0x00,0x31,0x85,0x7c,0x84,0x41,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0xaa,
+0x7d,0x82,0x8e,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x13,
+0xff,0xff,0xff,0xde,0x00,0x00,0x00,0x34,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x90,
+0x00,0x00,0x00,0x8a,0xff,0xff,0xff,0x63,0x00,0x01,0x00,0xc6,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xe7,0x00,0x00,0x00,0x21,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x54,0x00,0x00,0x00,0xbb,0xff,
+0xff,0xff,0x27,0x00,0x00,0x00,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x1b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,
+0x00,0x68,0xff,0xff,0xff,0x8b,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x48,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xd6,0x00,0x01,0x00,0x3f,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0x8e,0x00,0x00,
+0x00,0x88,0xff,0xff,0xff,0x5c,0x00,0x00,0x00,0xbb,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfe,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xe9,0x00,0x00,0x00,0x2d,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x58,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,
+0x27,0x00,0x00,0x00,0xed,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,
+0x00,0x00,0x00,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb6,0x00,0x00,0x00,0x62,
+0xff,0xff,0xff,0x83,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xd6,
+0x00,0x01,0x00,0x3f,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0x90,0x00,0x00,0x00,0x8b,
+0xff,0xff,0xff,0x64,0x00,0x00,0x00,0xc8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xf5,0x00,
+0x00,0x00,0x24,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0xbf,0xff,0xfe,0xff,0x1a,0x00,
+0x00,0x00,0xf9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x0e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc2,0x00,0x00,0x00,0x62,0xff,0xff,
+0xff,0x83,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xfe,0xff,0x90,0x98,0x96,0x9f,0xff,0xff,0xff,0xd6,0x00,0x01,
+0x00,0x3f,0xff,0xfd,0xff,0xc7,0x59,0x66,0x64,0x7c,0x9c,0x99,0x9b,0x7d,0x64,0x66,
+0x6e,0x26,0x00,0x01,0x00,0x4a,0x69,0x66,0x66,0x66,0x66,0x66,0x57,0xf0,0xff,0xfe,
+0xff,0x00,0x00,0x00,0x00,0xa1,0x9a,0x99,0x98,0x62,0x65,0x65,0x6a,0x9c,0x98,0x9a,
+0x8e,0x62,0x66,0x60,0x8e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb7,0x5c,0x65,0x66,
+0x66,0x65,0x66,0x6d,0x24,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xa6,0x94,0x98,0x9c,
+0x6a,0x64,0x66,0x59,0xff,0xff,0xff,0xff,0x5d,0x65,0x65,0x66,0x9c,0x98,0x99,0x93,
+0x62,0x65,0x65,0x66,0x66,0x66,0x6a,0x48,0x00,0x00,0x00,0x62,0xff,0xff,0xff,0x83,
+0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x77,0x9d,0x99,0xa7,0x16,
+0x00,0x01,0x00,0x5f,0x68,0x65,0x59,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfd,0xfc,0xfd,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xd6,0x00,0x01,0x00,0x3f,
+0xff,0xfd,0xff,0xa2,0x00,0x00,0x00,0x6e,0xff,0xff,0xff,0x75,0x00,0x00,0x00,0x00,
+0x01,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xfe,0xff,0x00,
+0x00,0x01,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x0c,0xff,0xff,0xff,0xd7,0x00,
+0x00,0x00,0x3a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x81,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x01,0x00,0x00,0xbf,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0x09,0x00,
+0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xec,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xff,0xff,0xff,0x83,0x00,0x01,
+0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0xcf,0xff,0xff,0xff,0x26,0x00,0x02,
+0x01,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x3f,0xff,0xfe,
+0xff,0xa5,0x00,0x00,0x00,0x6f,0xff,0xfe,0xff,0x75,0x00,0x02,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe8,0xff,0xfe,0xff,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x16,0xff,0xfd,0xff,0xd2,0x00,0x01,0x00,
+0x44,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+0x01,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xfd,0xfd,0xfe,0xff,0x11,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xfc,0xff,0xe5,0x00,0x00,0x00,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x62,0xff,0xff,0xff,0x83,0x00,0x00,0x00,0x94,
+0xff,0xff,0xff,0x53,0x00,0x00,0x00,0xc3,0xff,0xfd,0xff,0x23,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x46,0xff,0xff,0xff,0xb3,
+0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xcd,0x00,0x00,0x00,0x36,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,
+0x00,0x00,0xc8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xf7,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x56,0xff,0xfd,0xff,0x7a,0x00,0x00,0x00,0x8b,0xff,0xff,
+0xff,0x45,0x00,0x00,0x00,0xbf,0xff,0xfe,0xff,0x23,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x12,0x50,0x48,0x4c,0x31,0x00,0x00,
+0x00,0x6f,0xff,0xff,0xff,0xd6,0xb1,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,0xb7,
+0xc7,0x22,0x00,0x00,0x00,0xea,0xff,0xfe,0xff,0xb4,0xb6,0xb6,0xb1,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xf0,0xaf,0xb6,0xb3,0xc8,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xdc,0xb0,0xb6,0xc3,0x52,0x00,0x01,0x00,0x78,0xbe,0xb7,0xbe,
+0x64,0x44,0x47,0x47,0x47,0x47,0x47,0x41,0xad,0xb8,0xb7,0xbd,0x47,0x46,0x46,0x45,
+0xbb,0xb7,0xb7,0xb4,0x3e,0x48,0x4a,0x42,0x00,0x00,0x00,0x26,0xc6,0xb7,0xb7,0xb7,
+0xb7,0xb7,0xb2,0xd1,0xff,0xfe,0xff,0xdb,0xb0,0xb7,0xb1,0xdf,0xff,0xff,0xff,0xcd,
+0xb3,0xb7,0xaf,0xee,0xff,0xfe,0xff,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2d,
+0x00,0x00,0x00,0xea,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x14,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x75,0x00,0x00,0x00,0xac,0xff,0xff,0xff,0x3a,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x35,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfe,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xff,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xfd,0xfe,0xfe,0xff,0xff,0xff,
+0xff,0xd6,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x00,0x00,0x00,0x6f,0xff,0xfe,
+0xff,0xff,0xfe,0xff,0xff,0xfe,0xfe,0xfc,0xfd,0xfd,0xff,0xff,0xff,0x2b,0x00,0x00,
+0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0x00,0x00,0x00,
+0x15,0xff,0xfd,0xfd,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfd,0xfe,0xfd,0xff,0x70,0x00,0x02,0x00,0xa6,0xff,0xfe,0xff,0x3e,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xec,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,
+0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfd,0xfe,0xfd,0xfd,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xff,0xff,0xff,0xfd,
+0xfe,0xfe,0xff,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfd,0xfc,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xd6,
+0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x7b,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x2b,0x00,0x00,0x00,0xea,
+0xff,0xff,0xff,0xff,0xff,0xfc,0xfe,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x06,0xff,
+0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+0xff,0xff,0x6d,0x00,0x00,0x00,0xab,0xff,0xff,0xff,0x35,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xfd,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x03,
+0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfd,0xfc,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,
+0xff,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0x1a,0x2a,0x27,0x3a,0xff,0xff,0xff,0xd6,0x00,0x00,
+0x00,0x35,0xe5,0xd3,0xdb,0x8a,0x00,0x00,0x00,0x12,0x2e,0x2a,0x2a,0x2a,0x2a,0x2a,
+0x2a,0x2a,0x2a,0x2b,0x1a,0xc5,0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0xea,0xff,0xff,
+0xff,0xff,0xfd,0xff,0xff,0x22,0x29,0x29,0x2b,0xe1,0xd4,0xd6,0xc2,0x1f,0x2b,0x25,
+0x51,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x1e,0x2b,0x21,
+0x8a,0xdb,0xd4,0xde,0x66,0x24,0x2a,0x1f,0xa8,0xd9,0xd4,0xd4,0xd4,0xd3,0xd4,0xe0,
+0x38,0x29,0x2b,0x30,0x00,0x00,0x00,0x00,0x2f,0x2b,0x2a,0x2f,0x00,0x01,0x00,0x00,
+0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xc1,0x1a,0x2a,0x2a,0x2a,0x2a,0x2a,0x1f,0x90,
+0xff,0xfe,0xff,0x83,0x20,0x2a,0x1b,0xb9,0xff,0xff,0xff,0x5b,0x25,0x2b,0x1e,0xba,
+0xd7,0xd3,0xd4,0xd4,0xd4,0xd3,0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x0a,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x41,
+0xff,0xff,0xff,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xb9,0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,
+0xfd,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xee,0x00,0x00,0x00,0x28,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x86,0x00,0x00,0x00,0x8f,0xff,
+0xff,0xff,0x56,0x00,0x00,0x00,0xc2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0c,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+0x00,0x31,0xff,0xff,0xff,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0xff,0xfe,
+0xff,0x66,0x00,0x00,0x00,0xa9,0xff,0xff,0xff,0x34,0x00,0x00,0x00,0xe0,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x3f,0xff,0xfd,
+0xff,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+0x00,0xba,0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xea,0x00,0x01,0x00,0x2d,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x8f,0xff,0xff,0xff,
+0x58,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x31,
+0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7b,0xff,0xff,0xff,0x6a,
+0x00,0x00,0x00,0xab,0xff,0xff,0xff,0x3a,0x00,0x01,0x00,0xdc,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xeb,0x00,0x00,0x00,0x47,0xff,0xff,0xff,0xb8,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xba,
+0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xe4,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x8f,0xff,0xff,0xff,0x47,0x00,
+0x00,0x00,0xb7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0xff,0xff,
+0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0xff,0xff,0xff,0x5b,0x00,0x00,
+0x00,0xb3,0xff,0xff,0xff,0x41,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xf2,
+0xf5,0xde,0x00,0x0c,0x0d,0x0c,0x00,0x00,0x00,0x02,0x0f,0x0c,0x0d,0x09,0x00,0x00,
+0x00,0x6c,0xff,0xf2,0xf2,0xf2,0xf2,0xf2,0xff,0x5a,0x00,0x01,0x00,0xba,0xff,0xff,
+0xff,0x2b,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0x0c,0x09,0x0b,0x06,0xf9,0xf3,0xf2,
+0xef,0xff,0xfe,0xff,0xfe,0xed,0xf2,0xf7,0xc6,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x02,
+0x66,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x8f,0xff,0xff,0xff,0xf5,0xf0,0xf2,0xee,
+0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x00,0x00,0x00,0xf5,0xf4,0xf4,0xf9,
+0x00,0x00,0x00,0x03,0xff,0xf1,0xf2,0xf2,0xf2,0xf2,0xf1,0xf2,0xff,0xff,0xff,0xb5,
+0x00,0x00,0x00,0x5f,0xff,0xf2,0xf0,0xf7,0xff,0xff,0xff,0xf5,0xf0,0xf2,0xff,0x59,
+0x04,0x0c,0x0f,0x02,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5e,0x00,0x01,0x00,0xba,0xff,0xff,0xff,0x2b,
+0x00,0x00,0x00,0xea,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xfe,
+0xff,0xff,0xff,0xff,0xff,0xff,0xd3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0xff,
+0xff,0xff,0x8a,0x00,0x01,0x00,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb5,0x00,0x00,
+0x00,0x64,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x51,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xee,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0x5c,0x00,0x00,0x00,0xba,0xff,0xff,0xff,0x2b,0x00,0x00,
+0x00,0xea,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+0xff,0xff,0xff,0xff,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,
+0x8a,0x00,0x00,0x00,0x8f,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0xfe,
+0xff,0xff,0xff,0xff,0x10,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb6,0x00,0x00,0x00,0x61,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xea,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x6f,0xff,0xfe,0xfd,0xff,
+0xff,0xff,0xff,0x59,0x00,0x00,0x00,0xb2,0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0xfa,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0x8a,0x00,
+0x00,0x00,0x9a,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+0xff,0xff,0x04,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xfd,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbc,0x00,0x00,0x00,0x60,0xff,0xff,
+0xff,0xff,0xfe,0xfd,0xfe,0xff,0xff,0xff,0xff,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xe6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xab,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x71,0x00,0x00,
+0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0x8a,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xa2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x23,0x00,0x00,0x00,
+0xef,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xfc,0xff,0xe2,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x47,0xff,0xff,0xff,0x9c,0x00,0x00,0x00,0x77,
+0xff,0xfd,0xff,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0xff,0xff,0xff,0x21,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xa8,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x72,0x00,0x00,0x00,0xa1,
+0xff,0xff,0xff,0xfd,0xfe,0xff,0xff,0x2b,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+0xff,0xff,0xbc,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0x8a,0x00,0x00,0x01,0x00,0x00,
+0x00,0x00,0xa4,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x25,0x00,0x00,0x00,0xee,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,0xfe,0xfc,0xff,0xe5,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x48,0xff,0xff,0xff,0x9d,0x00,0x00,0x00,0x79,0xff,0xfc,
+0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0xff,0xff,0xff,0x22,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xa5,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x76,0x00,0x00,0x00,0xa0,0xff,0xff,
+0xff,0xfe,0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xbc,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0x88,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
+0xa6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x29,0x00,0x00,0x00,0xef,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x48,0xff,0xff,0xff,0x9c,0x00,0x00,0x00,0x7c,0xff,0xff,0xff,0x6a,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc3,0xff,0xfe,0xff,0x21,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa7,
+0x00,0x00,0x00,0x70,0xff,0xff,0xff,0x74,0x00,0x00,0x00,0x9d,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x00,
+0x00,0x00,0x5e,0xff,0xff,0xff,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa6,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0xf2,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x48,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x7e,0xff,0xff,0xff,0x6e,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xc1,0xff,0xfe,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xff,0xff,
+0xff,0x91,0x00,0x00,0x00,0x8b,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0x2b,0x00,0x00,0x00,0xf9,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
+0x00,0xff,0xff,0xff,0xe5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x5e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x79,0x00,0x00,0x00,0xa6,0xff,0xff,0xff,
+0x31,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xfa,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x38,0xff,0xff,0xff,0xbc,
+0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,
+0xff,0xff,0xff,0xff,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0x12,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xd7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0xff,0xff,0xff,0x8e,
+0x00,0x00,0x00,0x8a,0xff,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,
+0x00,0x00,0x00,0xea,0xff,0xff,0xff,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,
+0xff,0xff,0xff,0xfe,0xff,0xff,0x71,0x00,0x00,0x00,0xa7,0xff,0xff,0xff,0x3e,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0xff,0xff,0xff,0xb6,0x00,0x00,
+0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0xff,0xff,
+0xff,0xff,0xfe,0xff,0xfd,0xfe,0xfe,0xff,0xff,0x0e,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xd3,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x58,0xff,0xff,0xff,0x8d,0x00,0x00,
+0x00,0x88,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x29,0x00,0x00,
+0x00,0xeb,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xff,0xff,0xff,
+0xeb,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x5b,0xff,0xff,0xfe,
+0xff,0xff,0xff,0xff,0x70,0x00,0x00,0x00,0xa3,0xff,0xff,0xff,0x3c,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xae,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xfc,0xff,0x0c,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,
+0x00,0x0d,0x0d,0x0b,0x00,0x00,0x00,0x58,0xff,0xff,0xff,0x94,0x00,0x0c,0x00,0x88,
+0xfb,0xf2,0xf0,0xf9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x37,0x05,0x0c,0x00,0xda,
+0xf5,0xf2,0xff,0x0f,0x0a,0x0d,0x10,0x00,0x00,0x00,0x00,0xff,0xf3,0xf6,0xdb,0x00,
+0x0d,0x0d,0x0d,0x00,0x01,0x00,0x04,0x0f,0x0c,0x01,0x66,0xff,0xff,0xff,0xf7,0xef,
+0xf1,0xfd,0x71,0x02,0x0d,0x00,0xa9,0xff,0xff,0xff,0x49,0x04,0x0c,0x0c,0x0c,0x0c,
+0x0c,0x0c,0x0c,0x0b,0x0d,0x11,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,0x00,0x00,
+0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xfc,0xf2,0xf2,0xf2,0xf2,0xf2,
+0xef,0xfd,0xff,0xfd,0xff,0x1b,0x09,0x0b,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xd2,0x00,0x00,0x00,0x58,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x72,0x00,0x00,
+0x00,0x97,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x03,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xff,
+0xe6,0x00,0x01,0x00,0x4c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7d,0x00,0x00,0x00,
+0x91,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,
+0x00,0x01,0x00,0x31,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd6,
+0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xbf,
+0x00,0x00,0x00,0x58,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x16,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xd2,0x00,
+0x00,0x00,0x44,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x89,0x00,0x00,0x00,0x8f,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x01,
+0x00,0x31,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbd,0x00,0x00,
+0x00,0x56,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x70,0x00,0x00,0x00,0x9e,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x10,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,
+0x44,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x93,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,
+0xff,0xff,0xff,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xda,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfd,0xce,0xd4,0xd2,0xd9,0xff,0xff,0xff,0xc9,0x19,0x2a,0x24,0x66,
+0xdf,0xd4,0xd1,0xe6,0xff,0xff,0xff,0x8b,0x1e,0x2b,0x1b,0xb0,0xff,0xfe,0xff,0xdf,
+0xd2,0xd4,0xcf,0xf8,0xff,0xff,0xff,0x3e,0x26,0x2a,0x16,0xfe,0xff,0xff,0xff,0x20,
+0x29,0x2a,0x2a,0x2a,0x2a,0x27,0x3a,0xe1,0xd4,0xdb,0xad,0x00,0x00,0x00,0x44,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x77,0xdf,0xd4,0xd4,0xd4,0xd4,
+0xd4,0xd4,0xd4,0xd4,0xd4,0xce,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xfb,0x15,0x2a,0x2a,0x2a,0x2a,0x2b,0x23,0x54,0xff,0xff,
+0xff,0xc1,0x19,0x2a,0x2a,0x2a,0x2a,0x2a,0x2d,0x16,0x00,0x00,0x00,0x18,0x2d,0x2a,
+0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x19,0xe0,0xff,0xff,0xff,0xd5,0xd3,0xd4,
+0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xe9,0x00,0x00,0x00,0x16,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xac,0x00,0x00,
+0x00,0x62,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x32,0x00,0x00,
+0x00,0xcb,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xf9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xd1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x90,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xee,
+0x00,0x00,0x00,0x27,0xff,0xfe,0xff,0xfe,0xfe,0xfd,0xff,0xa6,0x00,0x00,0x00,0x6f,
+0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xff,0x42,0x00,0x00,0x00,0xd2,
+0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xe9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0x83,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xee,0x00,0x00,
+0x00,0x29,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xad,0x00,0x00,0x00,0x6f,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x3c,0x00,0x00,0x00,0xd8,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
+0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x8a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xd5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x84,0x00,0x00,0x00,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0e,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xee,0x00,0x00,0x00,0x20,
+0xc5,0xb7,0xb8,0xb8,0xb7,0xb8,0xbf,0x77,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0xd6,
+0xb2,0xb7,0xb0,0xe2,0xff,0xfd,0xff,0x79,0x3f,0x46,0x3e,0xa2,0xba,0xb8,0xb8,0xb8,
+0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb8,0xb7,0xb6,0xff,0xfe,0xff,0xea,0x00,
+0x00,0x00,0x0d,0x4e,0x46,0x3f,0x79,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,
+0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x49,0x46,0x37,0xdf,0xff,
+0xfe,0xff,0xff,0xfe,0xfd,0xff,0x46,0x45,0x45,0x40,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xf6,0xaf,0xb8,0xb5,0xc1,0xff,0xff,0xff,0xea,0xb0,0xb8,0xb8,0xb8,0xb8,0xb8,
+0xbc,0x81,0x42,0x46,0x3b,0xb1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc4,0xb4,0xb8,
+0xb8,0xb8,0xb7,0xb7,0xc5,0x0c,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x6f,0xff,0xff,0xff,0x68,0x00,0x00,
+0x00,0x99,0xff,0xfc,0xfe,0xff,0xff,0xff,0xff,0x21,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xea,0x00,0x00,0x00,
+0x32,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0xff,0xff,0xff,0xff,0xfc,0xfd,0xff,
+0xff,0xfe,0xfc,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe1,
+0x00,0x00,0x00,0x21,0xff,0xff,0xff,0xae,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x29,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xee,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x75,0x00,0x01,0x00,0xa1,
+0xff,0xfd,0xfe,0xfe,0xfe,0xfe,0xff,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xea,0x00,0x01,0x00,0x2d,0xff,
+0xfd,0xfe,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xfe,0xfd,0xfd,0xfe,0xfe,0xff,0xff,0xff,
+0xfd,0xfe,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00,0x01,
+0x00,0x32,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0xff,0xfd,
+0xfe,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x39,0x00,0x01,0x00,0x00,0x00,0x00,
+0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfd,0xff,0xff,0xff,0xff,0xf9,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x69,0xff,0xff,0xff,0x6e,0x00,0x00,0x00,0x9b,0xff,0xfe,
+0xfd,0xff,0xff,0xff,0xff,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xfe,0xff,0xe6,0x00,0x00,0x00,0x23,0xff,0xfd,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xba,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xff,0xff,0xff,0xed,0x00,0x00,0x00,0x28,
+0xff,0xff,0xff,0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xfd,0xff,0xff,0xff,0xff,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x8f,0x99,0x9b,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x6f,0x66,0x65,0x65,
+0x65,0x65,0x5d,0xa8,0xff,0xff,0xff,0xab,0x5c,0x66,0x5b,0xc6,0xff,0xfd,0xff,0xb3,
+0x95,0x99,0x9c,0x6e,0x64,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,
+0x65,0x64,0x64,0xff,0xfe,0xff,0xf0,0x57,0x65,0x61,0x80,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x00,0x00,0x3a,0x6b,0x66,0x65,0x65,0x65,
+0x65,0x59,0xd8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfd,0x8c,0x99,0x9a,0x94,0x61,0x65,0x61,0x82,0xff,0xff,
+0xff,0xd2,0x59,0x65,0x65,0x65,0x65,0x65,0x63,0x7f,0x9c,0x99,0x91,0xd3,0xff,0xff,
+0xff,0xba,0x94,0x99,0x9c,0x72,0x65,0x66,0x65,0x65,0x65,0x65,0x65,0x65,0x65,0x65,
+0x59,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xff,0x37,0x00,0x00,
+0x00,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x99,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfb,0x00,0x00,0x00,0x0d,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x85,0x00,0x00,0x00,0x8c,0xff,0xff,0xff,0x47,
+0x00,0x00,0x00,0xcc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xfd,0xfd,0xfd,0xff,0xff,0xff,0xff,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe,0xfd,0xff,0x42,0x00,0x00,0x00,0xd2,
+0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+0xfe,0xff,0x89,0x00,0x00,0x00,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x01,0x00,0x1a,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+0xff,0xfe,0xfe,0xfe,0xff,0x83,0x00,0x00,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,
+0x00,0xc4,0xff,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x43,0xff,0xff,0xff,0xff,0xfd,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfb,0xff,0x3a,0x00,0x00,0x00,0xda,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xfe,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
+0x90,0x00,0x03,0x00,0x8e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfa,
+0x00,0x00,0x00,0x0c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+0xff,0xff,0xff,0x8b,0x00,0x00,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0xd2,
+0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x74,0x81,0x84,0x79,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x21,0x87,0x7d,0x76,0xa8,0xff,0xff,0xff,0xc5,0x74,0x7d,0x7d,0x7d,
+0x7d,0x7d,0x73,0xcd,0xff,0xfe,0xff,0xa0,0x7d,0x81,0x82,0x7e,0x7c,0x7d,0x7d,0x7d,
+0x7d,0x7d,0x70,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0x7c,0x7a,0x87,0xff,
+0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcd,0x73,0x7d,0x84,0x45,0x00,
+0x00,0x00,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x79,0x7d,0x7d,0x7d,0x7d,
+0x7c,0x71,0xf3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0x74,0x82,
+0x7f,0x8d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xca,0x73,0x7c,
+0x84,0x42,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x60,0x80,0x7c,
+0x70,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfb,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x4f,0xff,0xff,0xff,0x88,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x9c,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0x23,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x09,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x95,0x00,0x00,0x00,0x00,
+0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd8,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x58,0xff,0xff,0xff,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x14,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8f,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xed,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x00,0x00,0x01,
+0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x54,0xff,0xff,0xff,0x99,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x9a,0xff,0xff,
+0xfd,0xff,0xff,0xff,0xff,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x08,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xac,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x31,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xed,0xff,0xfe,0xfd,
+0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9e,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x94,
+0xff,0xff,0xff,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd7,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x4f,0x5d,0x5c,0x63,0xa6,0xa0,0xa5,0x86,0x00,0x00,0x00,0x28,0xae,0xa0,0xa3,0x88,
+0x5a,0x5d,0x63,0x35,0x00,0x00,0x00,0x57,0xa9,0xa0,0x98,0xdc,0xff,0xff,0xff,0x88,
+0x57,0x5d,0x67,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x5e,0x5d,0x56,0xff,
+0xff,0xff,0xff,0x97,0xa0,0xa1,0x9a,0x58,0x5e,0x59,0x7a,0xff,0xfe,0xff,0xd2,0x51,
+0x5d,0x63,0x3c,0x00,0x00,0x00,0x4a,0xaa,0xa0,0x99,0xd5,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xb7,0x9c,0xa0,0xae,0x1a,0x00,0x00,0x00,0xed,0xff,0xff,0xff,0x5b,0x5c,
+0x5c,0x58,0xff,0xff,0xff,0xfd,0x4d,0x5d,0x5a,0x6e,0xff,0xff,0xff,0xde,0x4f,0x5d,
+0x5e,0x5d,0x5d,0x5d,0x5b,0x78,0xa4,0xa1,0xa9,0x53,0x00,0x01,0x00,0x94,0xff,0xff,
+0xff,0x53,0x00,0x00,0x00,0x7b,0xa6,0xa0,0x97,0xf2,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x08,0xff,0xff,0xff,0xdf,0x00,0x01,0x00,0x42,0xff,0xff,0xff,0xaa,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3a,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xf2,0x00,0x00,0x00,0x24,0xff,0xfd,0xff,0xb6,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x7a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x2a,0x00,0x00,0x00,0xed,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x0e,0xff,0xff,0xff,0xca,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x5f,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,
+0x00,0x00,0x00,0xcd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,
+0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x3f,0xff,0xfe,0xff,0xa6,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x89,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x43,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xe9,0x00,0x00,0x00,0x2d,0xff,0xff,0xff,0xba,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x75,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x27,0x00,0x00,0x00,0xed,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xfe,0x00,0x00,0x00,0x18,0xff,0xff,0xff,0xcd,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x62,0xff,0xff,0xff,0x83,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x53,0x00,0x00,
+0x00,0xc5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xd1,0x00,0x00,0x00,0x36,0xff,0xff,0xff,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x8b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xe4,0x00,0x00,0x00,0x1d,0xff,0xfe,0xff,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x81,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x1a,0x00,0x00,0x00,0xea,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x1c,0xff,0xff,0xff,0xd7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,
+0xff,0xff,0xff,0x8f,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0x45,0x00,0x00,0x00,0xbf,
+0xff,0xfe,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xf3,
+0xb6,0xbd,0xc2,0x9d,0x38,0x40,0x44,0x2b,0x00,0x00,0x00,0x55,0xca,0xbf,0xc4,0x7a,
+0x3c,0x40,0x3f,0x3f,0x3f,0x40,0x48,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xbd,0xc1,0xbd,0xc1,0x3c,0x3f,0x3d,0x3f,0xff,0xff,0xff,0xf8,0xb6,
+0xbd,0xbc,0xc7,0xff,0xfe,0xff,0xeb,0xb8,0xbf,0xc6,0x78,0x00,0x00,0x00,0x1e,0x47,
+0x41,0x34,0xa9,0xff,0xfd,0xff,0x81,0x37,0x3f,0x3f,0x3f,0x3f,0x40,0x37,0xa9,0xbf,
+0xbe,0xb7,0xfa,0xff,0xfc,0xff,0xbc,0xbe,0xbf,0xc1,0x3c,0x3f,0x41,0x42,0x00,0x01,
+0x00,0x07,0x48,0x40,0x3f,0x5a,0xc7,0xbe,0xbe,0xbe,0xbe,0xbe,0xc3,0x8d,0x3a,0x41,
+0x44,0x22,0x00,0x01,0x00,0x94,0xff,0xff,0xff,0xd3,0xbb,0xbf,0xb8,0xee,0xff,0xfd,
+0xff,0xff,0xff,0xfd,0xff,0x4a,0x3d,0x3f,0x31,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xc3,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x73,0xff,0xff,0xff,0x74,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xfe,0xff,0xfd,0xff,0xff,0xff,
+0xff,0xfe,0xfc,0xfd,0xff,0xff,0xff,0xff,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x8b,0xff,0xfb,0xff,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdb,0xff,0xff,0xff,
+0xff,0xfd,0xfd,0xfd,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x01,0x02,0x01,0x00,
+0x00,0x00,0x00,0x2e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9d,0x00,0x00,0x00,0x00,
+0x01,0x01,0x00,0x94,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xfd,0xff,0xff,
+0xff,0xfb,0xff,0x08,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xfd,0xfe,0xfe,0xff,0xbf,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xfe,0xff,0x75,0x00,0x01,0x00,0x00,
+0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xfe,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,
+0xfe,0xfe,0xfd,0xff,0xfe,0xff,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8f,0xff,
+0xfd,0xff,0x57,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd7,0xff,0xfd,0xfd,0xfd,0xff,
+0xfe,0xfe,0xfe,0xfe,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x32,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0x9c,0x00,0x02,0x00,0x01,0x00,0x01,
+0x00,0x94,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,
+0xff,0x0d,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd1,0x00,0x00,
+0x01,0x00,0x00,0x00,0x00,0x62,0xff,0xff,0xff,0x67,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xfe,
+0xff,0xff,0xff,0xff,0xa5,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x8f,0xff,0xfe,0xff,
+0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0xff,0xff,0xff,0xff,0xff,0xfd,0xfc,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x31,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa0,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x94,
+0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xff,0xff,0xff,0xff,0x12,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd9,0x10,0x23,0x25,0x1c,0x00,0x01,0x00,0x4d,
+0xea,0xdb,0xd8,0xeb,0xff,0xff,0xff,0xea,0xd8,0xdb,0xdb,0xdb,0xdb,0xdb,0xed,0x3b,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0xff,0xd6,
+0xdb,0xdd,0xda,0x14,0x23,0x23,0x23,0x23,0x23,0x1e,0x4a,0xff,0xfe,0xff,0xc2,0x13,
+0x23,0x1c,0x68,0xe6,0xdb,0xe6,0x76,0x00,0x01,0x00,0x8e,0xff,0xfe,0xff,0xe6,0xd9,
+0xdb,0xdb,0xdb,0xdb,0xdb,0xd5,0xf9,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x21,0x21,
+0x22,0x1f,0xe2,0xdc,0xdd,0xd8,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xff,
+0xff,0xbf,0x12,0x23,0x1b,0x6b,0xe5,0xda,0xe6,0x72,0x00,0x01,0x00,0x94,0xff,0xff,
+0xff,0x6c,0x1a,0x23,0x11,0xcb,0xff,0xfe,0xff,0x43,0x1e,0x23,0x29,0x02,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x11,0xff,0xff,0xff,0xd4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x46,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xfd,0xfe,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0xff,0xfe,0xff,0xb8,0x00,0x00,0x00,
+0x5d,0xff,0xff,0xff,0x8c,0x00,0x00,0x00,0x8e,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x32,0xff,0xff,0xff,0xb3,
+0x00,0x00,0x00,0x61,0xff,0xff,0xff,0x87,0x00,0x00,0x00,0x94,0xff,0xff,0xff,0x4e,
+0x00,0x00,0x00,0xc3,0xff,0xfe,0xff,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,
+0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x58,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfd,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xff,0x44,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xfc,0xfe,0xfd,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xff,0xfd,0xff,0xbb,0x00,0x00,0x00,0x5d,0xff,
+0xfe,0xff,0x8a,0x00,0x02,0x00,0x8f,0xff,0xfd,0xfe,0xfd,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xff,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xfd,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x31,0xff,0xfe,0xff,0xb5,0x00,0x00,
+0x00,0x63,0xff,0xfc,0xff,0x85,0x00,0x02,0x00,0x93,0xff,0xfe,0xff,0x52,0x00,0x01,
+0x00,0xc4,0xff,0xfd,0xff,0x23,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x68,0xff,0xff,0xff,
+0x8b,0x00,0x00,0x00,0x91,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x38,0xff,0xff,0xff,0xc9,0x00,0x00,0x00,0x6e,
+0xff,0xff,0xff,0x92,0x00,0x02,0x00,0xa3,0xff,0xff,0xff,0x4a,0x00,0x00,0x00,0xd1,
+0xff,0xff,0xff,0x28,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,
+0x00,0x00,0x00,0x3f,0xff,0xf9,0xf8,0xf7,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x77,
+0x00,0x04,0x05,0x04,0x05,0x05,0x08,0x03,0x00,0x00,0x00,0xcc,0xff,0xfa,0xfa,0xfa,
+0xfa,0xfa,0xff,0x08,0x04,0x04,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x02,0x06,0x04,0x00,0x77,0xff,
+0xf9,0xff,0x71,0x00,0x05,0x00,0xa6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfd,0xff,0xf4,0xf9,0xfb,0xfe,0x00,0x03,0x04,0x0b,0x00,0x01,
+0x00,0x00,0x00,0x00,0x00,0x03,0x09,0x04,0x05,0x04,0x00,0x00,0x00,0x05,0x08,0x06,
+0x06,0x04,0x00,0x00,0x00,0x07,0x06,0x04,0x00,0xa8,0xff,0xfa,0xff,0x3e,0x00,0x05,
+0x08,0x01,0x00,0x00,0x00,0xe9,0xfd,0xfa,0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,
+0x00,0x40,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,0x72,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd5,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,
+0x70,0x00,0x00,0x00,0xa5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0xff,0xff,0xff,0x38,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xf3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xd5,0x00,0x00,0x00,0x3e,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x74,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xff,
+0xfe,0xff,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0x70,0x00,
+0x00,0x00,0xa7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xab,0xff,0xff,0xff,0x39,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x04,0xff,0xff,0xff,0xd1,0x00,0x00,0x00,0x33,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xd2,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0xff,0xff,0xff,
+0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0x66,0x00,0x00,0x00,
+0xaa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xab,0xff,0xff,0xff,0x2d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xed,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47,
+0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x0e,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd4,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x00,
+0x00,0x00,0xbb,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0xed,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x4c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0x00,0x00,
+0x00,0xab,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x43,0x00,0x00,
+0x00,0xd2,0xff,0xff,0xff,0x14,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x00,0x00,0x00,
+0xbf,0xff,0xff,0xff,0x25,0x00,0x00,0x00,0xed,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6b,0x00,0x00,0x00,0xab,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd4,
+0xff,0xff,0xff,0x14,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x76,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x58,0x00,0x00,0x00,0xbf,0xff,
+0xff,0xff,0x27,0x00,0x00,0x00,0xed,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0xad,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,
+0xff,0x15,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xd0,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x78,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0x58,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,
+0x27,0x00,0x00,0x00,0xed,0xff,0xfd,0xff,0xfc,0xff,0xff,0xff,0x00,0x00,0x00,0x04,
+0xff,0xff,0xff,0xe5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0xfd,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0xad,0xff,0xff,0xff,0xff,
+0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x96,0xff,0xfd,0xfc,0xff,0xff,0xff,0xff,0x21,0x00,0x00,0x00,0xf8,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x22,0xff,0xff,0xff,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x83,0xff,0xfe,0xff,0x58,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x27,0x00,
+0x00,0x00,0xed,0xff,0xfc,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x0b,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x90,0x00,0x00,
+0x00,0x6e,0xff,0xfe,0xff,0x6a,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xbe,0xff,0xfe,
+0xff,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xa1,0xff,0xfc,0xff,0xfd,0xfe,0xfe,0xff,0x2c,0x00,0x00,0x00,0xe8,0xff,0xfe,
+0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x2d,0xff,0xfd,0xff,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,
+0x8f,0xff,0xff,0xff,0x58,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x27,0x00,0x00,0x00,
+0xed,0xff,0xfc,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x19,
+0xff,0xfe,0xff,0xcd,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7a,
+0xff,0xff,0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0xff,0xfc,0xff,0x23,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,
+0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0xed,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0xff,
+0xff,0xff,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0xff,
+0xfe,0xff,0x55,0x00,0x00,0x00,0xc1,0xff,0xff,0xff,0x29,0x00,0x00,0x00,0xf1,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x18,0xff,0xfe,
+0xff,0xcd,0x00,0x00,0x00,0x49,0xff,0xff,0xff,0x9a,0x00,0x00,0x00,0x78,0xff,0xff,
+0xff,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc3,0xff,0xff,0xff,0x22,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x00,0x18,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
+0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x18,0x0b,0x00,0x01,0x00,0xa1,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x2a,0x00,0x00,0x00,0xd4,0xef,0xeb,0xfb,0x17,0x12,0x15,
+0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x14,0x0f,0x3e,0xfa,0xea,0xf0,
+0xaf,0x06,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x07,0x96,0xff,0xfd,0xff,
+0x65,0x0a,0x14,0x05,0xb3,0xf1,0xea,0xfc,0x27,0x00,0x00,0x00,0xd8,0xee,0xeb,0xfc,
+0x00,0x00,0x00,0x00,0x18,0x14,0x16,0x17,0x00,0x01,0x00,0x18,0xff,0xff,0xff,0xcd,
+0x00,0x00,0x00,0x49,0xff,0xff,0xff,0xa2,0x03,0x13,0x07,0x84,0xff,0xfe,0xff,0x6a,
+0x00,0x00,0x00,0x0f,0x16,0x14,0x01,0xc7,0xff,0xfe,0xff,0x22,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x15,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x81,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0xff,0xff,0xff,0xde,0x00,0x00,0x00,0x3a,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfe,0xff,0xff,
+0xff,0xff,0x33,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x01,0x00,0x18,0xff,0xff,0xff,0xcd,0x00,0x00,
+0x00,0x49,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xff,0x6a,0x00,0x00,
+0x00,0xbc,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x22,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x11,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xff,0xff,0xff,0xff,0x75,0x00,0x01,0x00,0xa1,0xff,0xfe,0xff,0xfe,0xfe,0xfe,
+0xff,0x2b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xff,0xff,0xfe,0xff,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x14,0xff,0xfe,0xff,0xd2,0x00,0x00,0x00,0x44,0xff,0xff,0xff,
+0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xfe,0xff,0xfe,0xff,0xff,0xff,
+0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x19,0xff,0xfd,0xff,0xcd,0x00,0x00,0x00,0x49,
+0xff,0xfe,0xfe,0xfe,0xfd,0xfd,0xff,0xff,0xff,0xfe,0xff,0x69,0x00,0x00,0x00,0xab,
+0xff,0xff,0xff,0xfd,0xfe,0xfe,0xff,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,
+0xff,0xff,0xfe,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xfe,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfc,0xfc,0xff,0xff,0xff,0xff,0x2d,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x10,0xff,0xfc,0xff,0xd1,0x00,0x00,0x00,0x44,0xff,0xff,0xfe,0xff,0xff,
+0xff,0xff,0xff,0xfd,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x39,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
+0xff,0xff,0x00,0x03,0x00,0x1b,0xff,0xff,0xff,0xd3,0x00,0x00,0x00,0x4b,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6f,0x00,0x00,0x00,0xab,0xff,0xff,
+0xfd,0xff,0xff,0xff,0xff,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xf6,0xc4,0xcb,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xc8,0xe1,0xff,0xff,
+0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfc,0xff,0xd7,0xca,0xcc,0xdd,0x26,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xcb,0xce,0xcc,0xd0,0x2d,0x31,0x32,0x32,0x32,0x32,0x2e,
+0x44,0xff,0xfd,0xff,0xd1,0x00,0x01,0x00,0x44,0xff,0xff,0xff,0xea,0xc7,0xcc,0xc8,
+0xe2,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x65,0x2b,0x32,0x32,
+0x32,0x32,0x32,0x39,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd6,0xcd,0xce,0xcb,
+0x00,0x00,0x00,0x17,0xde,0xcc,0xd0,0xa3,0x00,0x00,0x00,0x3b,0xdc,0xcc,0xcc,0xcc,
+0xcc,0xcc,0xcc,0xcc,0xcc,0xcb,0xd9,0x57,0x00,0x00,0x00,0xab,0xff,0xff,0xff,0xd5,
+0xc9,0xcb,0xdc,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd0,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0xff,0xff,0xff,0x74,
+0x00,0x01,0x00,0xa1,0xff,0xfe,0xff,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
+0xfe,0xff,0xd1,0x00,0x01,0x00,0x44,0xff,0xff,0xff,0x97,0x00,0x00,0x00,0x69,0xff,
+0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xab,0xff,0xff,0xff,0x29,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,
+0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,
+0xd1,0x00,0x01,0x00,0x44,0xff,0xff,0xff,0xa0,0x00,0x00,0x00,0x75,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xab,0xff,0xff,0xff,0x39,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,
+0xff,0xff,0xff,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd6,0x00,
+0x00,0x00,0x3c,0xff,0xff,0xff,0x9c,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xae,0xff,0xff,0xff,0x3d,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,
+0xff,0x42,0x00,0x00,0x00,0x43,0x50,0x4e,0x57,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xb8,0xb1,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb0,0xb3,0x9d,0x48,0x4f,0x48,
+0x7d,0xff,0xff,0xff,0xbd,0x41,0x4e,0x44,0x9e,0xff,0xff,0xff,0xd1,0xab,0xb0,0xa9,
+0xe2,0xff,0xff,0xff,0xc3,0xad,0xb0,0xa8,0xf2,0xff,0xff,0xff,0x5b,0x4a,0x4e,0x4e,
+0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x4e,0x50,0x40,
+0x00,0x00,0x00,0x16,0x56,0x4e,0x52,0x30,0x00,0x00,0x00,0x26,0x54,0x4e,0x4e,0x4e,
+0x4e,0x4e,0x48,0x90,0xb4,0xb0,0xbf,0x29,0x00,0x00,0x00,0x44,0x50,0x4e,0x4e,0x4e,
+0x4e,0x4d,0x41,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,
+0x00,0x00,0x00,0xe2,0xff,0xff,0xff,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xff,0xff,0xff,0xff,0xfe,
+0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x65,0x00,0x00,0x00,0x9e,0xff,
+0xff,0xff,0x30,0x00,0x00,0x00,0xd2,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdc,0x00,0x00,
+0x00,0x4f,0xff,0xff,0xff,0xa8,0x00,0x01,0x00,0x84,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,
+0x00,0xd2,0xff,0xff,0xff,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x71,0x00,0x00,0x00,0xa6,0xff,0xff,0xff,
+0x3f,0x00,0x00,0x00,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcd,0x00,0x00,0x00,0x49,
+0xff,0xff,0xff,0x9b,0x00,0x01,0x00,0x7b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x53,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,
+0xff,0xff,0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,
+0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,
+0xff,0xff,0xff,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x27,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfd,0xfe,0xff,0x68,0x00,0x00,0x00,0xa1,0xff,0xff,0xff,0x3f,0x00,
+0x00,0x00,0xe1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd6,0x00,0x00,0x00,0x4d,0xff,0xff,
+0xff,0x9e,0x00,0x00,0x00,0x7a,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x4a,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xd9,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,
+0xff,0xd6,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,
+0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,
+0xff,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x0b,0x78,0x6d,0x6c,0x74,0x95,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x8b,
+0xc1,0xff,0xfd,0xff,0xac,0x64,0x6c,0x62,0xca,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,
+0x7b,0x96,0x91,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x91,0x8d,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xf2,0x86,0x92,0x96,0x74,0x00,0x00,0x00,0x29,0x9d,0x92,0x94,0x81,
+0x6a,0x6c,0x6b,0x7e,0x94,0x91,0x8a,0xcf,0xff,0xff,0xff,0x9c,0x66,0x6c,0x6c,0x6c,
+0x6d,0x6c,0x60,0xea,0xff,0xfd,0xff,0x94,0x90,0x91,0x89,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,
+0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,
+0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0x42,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x16,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0xff,
+0xff,0xff,0xda,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0xff,
+0xfb,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x3f,0x00,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xe2,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0xff,0xff,
+0xff,0x84,0x00,0x00,0x00,0x8a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xfe,0xfc,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd6,0x00,0x01,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6f,0xff,0xff,0xff,0x74,0x00,0x01,
+0x00,0xa1,0xff,0xff,0xff,0x43,0x00,0x00,0x00,0xd2,0xff,0xff,0xff,0x15,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0xff,0xfe,0xff,
+0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xfd,0xfe,
+0xfe,0xfd,0xfc,0xfe,0xfd,0xfe,0xff,0xff,0x3f,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,
+0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xff,0xfc,0xff,0x84,
+0x00,0x00,0x00,0x94,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xfe,
+0xfe,0xfd,0xff,0x0e,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xd2,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,
+0xff,0xfe,0xff,0x38,0x00,0x00,0x00,0xdb,0xff,0xff,0xff,0x18,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0xff,0xff,0xff,0xdb,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0xff,0xff,0xff,0x8c,0x00,0x00,
+0x00,0x9d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x0c,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x00,0x00,0x11,0xff,0xff,0xff,0xea,0x7e,0x89,0x89,0x89,0x89,0x89,
+0x89,0x89,0x89,0x89,0x83,0xbb,0xff,0xff,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xfd,
+0xff,0xa8,0x85,0x89,0x8b,0x78,0x74,0x74,0x80,0x0b,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x80,0x75,0x75,0x79,0x8a,0x8a,0x89,
+0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x8a,0x7f,0x73,0x75,0x74,0x74,0x75,0x75,0x6a,
+0xcd,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x8c,0x8a,0x89,0x84,0xff,0xff,0xff,0xfb,0x66,0x75,0x74,0x78,0x8a,0x89,0x8d,0x70,
+0x00,0x00,0x00,0x27,0x96,0x89,0x8a,0x81,0x75,0x75,0x7b,0x3d,0x00,0x01,0x00,0x45,
+0x7b,0x74,0x6a,0xd2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0d,
+0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0x00,0x00,0x00,0x11,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x75,0x00,0x00,0x00,0xa1,0xff,0xfe,0xfd,0xff,
+0xff,0xff,0xff,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0xff,
+0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xff,0xff,
+0xff,0xff,0xfe,0xfe,0xff,0xfc,0x00,0x00,0x00,0x10,0xff,0xff,0xff,0xd6,0x00,0x00,
+0x00,0x4d,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
+0x00,0xa6,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0x0d,0x00,0x00,
+0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
+0x00,0x11,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xff,0x74,0x00,0x01,0x00,0xa1,0xff,0xff,0xfe,0xff,0xff,0xff,
+0xff,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,
+0xff,0xff,0xff,0xff,0x8a,0x00,0x00,0x01,0x01,0x00,0x01,0x00,0xa6,0xff,0xff,0xff,
+0x3f,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+0xff,0xfe,0xff,0xfe,0x00,0x01,0x00,0x19,0xff,0xfe,0xff,0xcc,0x00,0x00,0x00,0x49,
+0xff,0xfe,0xff,0x9b,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xab,
+0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0x0c,0x00,0x00,0x00,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x13,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x7c,0x00,0x03,0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1e,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x8a,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x9d,0xff,0xff,0xff,0x31,0x00,
+0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0x00,0x03,0x00,0x18,0xff,0xfd,0xff,0xc8,0x00,0x00,0x00,0x42,0xff,0xff,
+0xff,0xa5,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb8,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x13,0x00,0x00,0x00,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x05,0x60,0x57,
+0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,0x57,
+0x5e,0x2a,0x00,0x01,0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb6,0xa5,0xa8,
+0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa7,0xa9,0xae,0x00,0x00,0x00,0x00,0xb7,0xa7,0xa8,
+0xa8,0xa8,0xa8,0xaa,0x98,0x51,0x57,0x57,0x57,0x57,0x57,0x4f,0x95,0xff,0xff,0xff,
+0x8a,0x00,0x00,0x00,0x5f,0xb0,0xa7,0xa0,0xdd,0xff,0xff,0xff,0xbc,0xa4,0xa8,0xb4,
+0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x4d,0x56,0x58,0x5a,
+0x00,0x01,0x00,0x18,0xff,0xfd,0xff,0xec,0x9d,0xa8,0xab,0x8f,0x51,0x57,0x5b,0x37,
+0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x5b,0x57,0x57,0x57,
+0x57,0x57,0x57,0x57,0x57,0x57,0x60,0x06,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0xff,0xff,0xff,0x8a,0x00,
+0x01,0x00,0x95,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x29,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x18,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xff,0xff,0xff,0x8a,0x00,0x01,0x00,
+0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x27,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,
+0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x99,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcb,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x84,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x15,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xae,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xbd,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xbe,0xe8,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xbe,0xc4,0xc3,0xc2,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xf3,0xbe,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc0,0xd8,0xff,0xff,0xff,0xe3,0xc0,0xc4,0xbf,0xe3,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcb,0xc2,0xc4,0xc4,0xc4,0xc4,0xc3,0xbd,
+0xff,0xff,0xff,0xff,0xc0,0xc3,0xc4,0xc4,0xc4,0xc4,0xc2,0xc8,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xed,0xbe,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
+0xc4,0xc4,0xbd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+};
+#endif

+ 740 - 0
Third_Party/cm_backtrace/cm_backtrace.c

@@ -0,0 +1,740 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016-2019, Armink, <armink.ztl@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Function: Initialize function and other general function.
+ * Created on: 2016-12-15
+ */
+
+#include <cm_backtrace.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef __RAMRUN__
+void cm_backtrace_init(const char *firmware_name, const char *hardware_ver, const char *software_ver) {}
+void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp){}
+#else
+#if __STDC_VERSION__ < 199901L
+    #error "must be C99 or higher. try to add '-std=c99' to compile parameters"
+#endif
+
+#if defined(__CC_ARM)
+    #define SECTION_START(_name_)                _name_##$$Base
+    #define SECTION_END(_name_)                  _name_##$$Limit
+    #define IMAGE_SECTION_START(_name_)          Image$$##_name_##$$Base
+    #define IMAGE_SECTION_END(_name_)            Image$$##_name_##$$Limit
+    #define CSTACK_BLOCK_START(_name_)           SECTION_START(_name_)
+    #define CSTACK_BLOCK_END(_name_)             SECTION_END(_name_)
+    #define CODE_SECTION_START(_name_)           IMAGE_SECTION_START(_name_)
+    #define CODE_SECTION_END(_name_)             IMAGE_SECTION_END(_name_)
+
+    extern const int CSTACK_BLOCK_START(CMB_CSTACK_BLOCK_NAME);
+    extern const int CSTACK_BLOCK_END(CMB_CSTACK_BLOCK_NAME);
+    extern const int CODE_SECTION_START(CMB_CODE_SECTION_NAME);
+    extern const int CODE_SECTION_END(CMB_CODE_SECTION_NAME);
+#elif defined(__ICCARM__)
+    #pragma section=CMB_CSTACK_BLOCK_NAME
+    #pragma section=CMB_CODE_SECTION_NAME
+#elif defined(__GNUC__)
+    extern const int CMB_CSTACK_BLOCK_START;
+    extern const int CMB_CSTACK_BLOCK_END;
+    extern const int CMB_CODE_SECTION_START;
+    extern const int CMB_CODE_SECTION_END;
+#else
+    #error "not supported compiler"
+#endif
+
+enum {
+    PRINT_MAIN_STACK_CFG_ERROR,
+    PRINT_FIRMWARE_INFO,
+    PRINT_ASSERT_ON_THREAD,
+    PRINT_ASSERT_ON_HANDLER,
+    PRINT_THREAD_STACK_INFO,
+    PRINT_MAIN_STACK_INFO,
+    PRINT_THREAD_STACK_OVERFLOW,
+    PRINT_MAIN_STACK_OVERFLOW,
+    PRINT_CALL_STACK_INFO,
+    PRINT_CALL_STACK_ERR,
+    PRINT_FAULT_ON_THREAD,
+    PRINT_FAULT_ON_HANDLER,
+    PRINT_REGS_TITLE,
+    PRINT_HFSR_VECTBL,
+    PRINT_MFSR_IACCVIOL,
+    PRINT_MFSR_DACCVIOL,
+    PRINT_MFSR_MUNSTKERR,
+    PRINT_MFSR_MSTKERR,
+    PRINT_MFSR_MLSPERR,
+    PRINT_BFSR_IBUSERR,
+    PRINT_BFSR_PRECISERR,
+    PRINT_BFSR_IMPREISERR,
+    PRINT_BFSR_UNSTKERR,
+    PRINT_BFSR_STKERR,
+    PRINT_BFSR_LSPERR,
+    PRINT_UFSR_UNDEFINSTR,
+    PRINT_UFSR_INVSTATE,
+    PRINT_UFSR_INVPC,
+    PRINT_UFSR_NOCP,
+    PRINT_UFSR_UNALIGNED,
+    PRINT_UFSR_DIVBYZERO0,
+    PRINT_DFSR_HALTED,
+    PRINT_DFSR_BKPT,
+    PRINT_DFSR_DWTTRAP,
+    PRINT_DFSR_VCATCH,
+    PRINT_DFSR_EXTERNAL,
+    PRINT_MMAR,
+    PRINT_BFAR,
+};
+
+static const char * const print_info[] = {
+#if (CMB_PRINT_LANGUAGE == CMB_PRINT_LANGUAGE_ENGLISH)
+        [PRINT_MAIN_STACK_CFG_ERROR]  = "ERROR: Unable to get the main stack information, please check the configuration of the main stack",
+        [PRINT_FIRMWARE_INFO]         = "Firmware name: %s, hardware version: %s, software version: %s",
+        [PRINT_ASSERT_ON_THREAD]      = "Assert on thread %s",
+        [PRINT_ASSERT_ON_HANDLER]     = "Assert on interrupt or bare metal(no OS) environment",
+        [PRINT_THREAD_STACK_INFO]     = "===== Thread stack information =====",
+        [PRINT_MAIN_STACK_INFO]       = "====== Main stack information ======",
+        [PRINT_THREAD_STACK_OVERFLOW] = "Error: Thread stack(%08x) was overflow",
+        [PRINT_MAIN_STACK_OVERFLOW]   = "Error: Main stack(%08x) was overflow",
+        [PRINT_CALL_STACK_INFO]       = "Show more call stack info by run: addr2line -e %s%s -a -f %.*s",
+        [PRINT_CALL_STACK_ERR]        = "Dump call stack has an error",
+        [PRINT_FAULT_ON_THREAD]       = "Fault on thread %s",
+        [PRINT_FAULT_ON_HANDLER]      = "Fault on interrupt or bare metal(no OS) environment",
+        [PRINT_REGS_TITLE]            = "=================== Registers information ====================",
+        [PRINT_HFSR_VECTBL]           = "Hard fault is caused by failed vector fetch",
+        [PRINT_MFSR_IACCVIOL]         = "Memory management fault is caused by instruction access violation",
+        [PRINT_MFSR_DACCVIOL]         = "Memory management fault is caused by data access violation",
+        [PRINT_MFSR_MUNSTKERR]        = "Memory management fault is caused by unstacking error",
+        [PRINT_MFSR_MSTKERR]          = "Memory management fault is caused by stacking error",
+        [PRINT_MFSR_MLSPERR]          = "Memory management fault is caused by floating-point lazy state preservation",
+        [PRINT_BFSR_IBUSERR]          = "Bus fault is caused by instruction access violation",
+        [PRINT_BFSR_PRECISERR]        = "Bus fault is caused by precise data access violation",
+        [PRINT_BFSR_IMPREISERR]       = "Bus fault is caused by imprecise data access violation",
+        [PRINT_BFSR_UNSTKERR]         = "Bus fault is caused by unstacking error",
+        [PRINT_BFSR_STKERR]           = "Bus fault is caused by stacking error",
+        [PRINT_BFSR_LSPERR]           = "Bus fault is caused by floating-point lazy state preservation",
+        [PRINT_UFSR_UNDEFINSTR]       = "Usage fault is caused by attempts to execute an undefined instruction",
+        [PRINT_UFSR_INVSTATE]         = "Usage fault is caused by attempts to switch to an invalid state (e.g., ARM)",
+        [PRINT_UFSR_INVPC]            = "Usage fault is caused by attempts to do an exception with a bad value in the EXC_RETURN number",
+        [PRINT_UFSR_NOCP]             = "Usage fault is caused by attempts to execute a coprocessor instruction",
+        [PRINT_UFSR_UNALIGNED]        = "Usage fault is caused by indicates that an unaligned access fault has taken place",
+        [PRINT_UFSR_DIVBYZERO0]       = "Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)",
+        [PRINT_DFSR_HALTED]           = "Debug fault is caused by halt requested in NVIC",
+        [PRINT_DFSR_BKPT]             = "Debug fault is caused by BKPT instruction executed",
+        [PRINT_DFSR_DWTTRAP]          = "Debug fault is caused by DWT match occurred",
+        [PRINT_DFSR_VCATCH]           = "Debug fault is caused by Vector fetch occurred",
+        [PRINT_DFSR_EXTERNAL]         = "Debug fault is caused by EDBGRQ signal asserted",
+        [PRINT_MMAR]                  = "The memory management fault occurred address is %08x",
+        [PRINT_BFAR]                  = "The bus fault occurred address is %08x",
+#elif (CMB_PRINT_LANGUAGE == CMB_PRINT_LANGUAGE_CHINESE)
+        [PRINT_MAIN_STACK_CFG_ERROR]  = "�����޷���ȡ��ջ��Ϣ��������ջ���������",
+        [PRINT_FIRMWARE_INFO]         = "�̼����ƣ�%s��Ӳ���汾�ţ�%s������汾�ţ�%s",
+        [PRINT_ASSERT_ON_THREAD]      = "���߳�(%s)�з�������",
+        [PRINT_ASSERT_ON_HANDLER]     = "���жϻ���������·�������",
+        [PRINT_THREAD_STACK_INFO]     = "=========== �̶߳�ջ��Ϣ ===========",
+        [PRINT_MAIN_STACK_INFO]       = "============ ����ջ��Ϣ ============",
+        [PRINT_THREAD_STACK_OVERFLOW] = "�����߳�ջ(%08x)�������",
+        [PRINT_MAIN_STACK_OVERFLOW]   = "������ջ(%08x)�������",
+        [PRINT_CALL_STACK_INFO]       = "�鿴���ຯ������ջ��Ϣ�������У�addr2line -e %s%s -a -f %.*s",
+        [PRINT_CALL_STACK_ERR]        = "��ȡ��������ջʧ��",
+        [PRINT_FAULT_ON_THREAD]       =  "���߳�(%s)�з��������쳣",
+        [PRINT_FAULT_ON_HANDLER]      = "���жϻ���������·��������쳣",
+        [PRINT_REGS_TITLE]            = "========================= �Ĵ�����Ϣ =========================",
+        [PRINT_HFSR_VECTBL]           = "����Ӳ����ԭ��ȡ�ж�����ʱ����",
+        [PRINT_MFSR_IACCVIOL]         = "�����洢���������ԭ����ͼ�Ӳ�������ʵ�����ȡָ��",
+        [PRINT_MFSR_DACCVIOL]         = "�����洢���������ԭ����ͼ�Ӳ�������ʵ��������д����",
+        [PRINT_MFSR_MUNSTKERR]        = "�����洢���������ԭ�򣺳�ջʱ��ͼ���ʲ������������",
+        [PRINT_MFSR_MSTKERR]          = "�����洢���������ԭ����ջʱ��ͼ���ʲ������������",
+        [PRINT_MFSR_MLSPERR]          = "�����洢���������ԭ�򣺶��Ա��渡��״̬ʱ��������",
+        [PRINT_BFSR_IBUSERR]          = "�������ߴ���ԭ��ָ�����ߴ���",
+        [PRINT_BFSR_PRECISERR]        = "�������ߴ���ԭ�򣺾�ȷ���������ߴ���",
+        [PRINT_BFSR_IMPREISERR]       = "�������ߴ���ԭ�򣺲���ȷ���������ߴ���",
+        [PRINT_BFSR_UNSTKERR]         = "�������ߴ���ԭ�򣺳�ջʱ��������",
+        [PRINT_BFSR_STKERR]           = "�������ߴ���ԭ����ջʱ��������",
+        [PRINT_BFSR_LSPERR]           = "�������ߴ���ԭ�򣺶��Ա��渡��״̬ʱ��������",
+        [PRINT_UFSR_UNDEFINSTR]       = "�����÷�����ԭ����ͼִ��δ����ָ��",
+        [PRINT_UFSR_INVSTATE]         = "�����÷�����ԭ����ͼ�л��� ARM ״̬",
+        [PRINT_UFSR_INVPC]            = "�����÷�����ԭ����Ч���쳣������",
+        [PRINT_UFSR_NOCP]             = "�����÷�����ԭ����ͼִ��Э������ָ��",
+        [PRINT_UFSR_UNALIGNED]        = "�����÷�����ԭ����ͼִ�зǶ������",
+        [PRINT_UFSR_DIVBYZERO0]       = "�����÷�����ԭ����ͼִ�г� 0 ����",
+        [PRINT_DFSR_HALTED]           = "�������Դ���ԭ��NVIC ͣ������",
+        [PRINT_DFSR_BKPT]             = "�������Դ���ԭ��ִ�� BKPT ָ��",
+        [PRINT_DFSR_DWTTRAP]          = "�������Դ���ԭ�����ݼ���ƥ��",
+        [PRINT_DFSR_VCATCH]           = "�������Դ���ԭ�򣺷�����������",
+        [PRINT_DFSR_EXTERNAL]         = "�������Դ���ԭ���ⲿ��������",
+        [PRINT_MMAR]                  = "�����洢���������ĵ�ַ��%08x",
+        [PRINT_BFAR]                  = "�������ߴ���ĵ�ַ��%08x",
+#else
+    #error "CMB_PRINT_LANGUAGE defined error in 'cmb_cfg.h'"
+#endif
+};
+
+//static char fw_name[CMB_NAME_MAX] = {0};
+//static char hw_ver[CMB_NAME_MAX] = {0};
+//static char sw_ver[CMB_NAME_MAX] = {0};
+static char *fw_name = "";
+static char *hw_ver = "";
+static char *sw_ver = "";
+static uint32_t main_stack_start_addr = 0;
+static size_t main_stack_size = 0;
+static uint32_t code_start_addr = 0;
+static size_t code_size = 0;
+static bool init_ok = false;
+static char call_stack_info[CMB_CALL_STACK_MAX_DEPTH * (8 + 1)] = { 0 };
+static bool on_fault = false;
+static bool stack_is_overflow = false;
+static struct cmb_hard_fault_regs regs;
+static void (*user_run_code)(void);
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7)
+static bool statck_has_fpu_regs = false;
+#endif
+
+static bool on_thread_before_fault = false;
+
+/**
+ * library initialize
+ */
+void cm_backtrace_init(const char *firmware_name, const char *hardware_ver, const char *software_ver) {
+    if (firmware_name) fw_name = (char *)firmware_name;
+    if (hardware_ver) hw_ver = (char *)hardware_ver;
+    if (software_ver) sw_ver = (char *)software_ver;
+#if defined(__CC_ARM)
+    main_stack_start_addr = (uint32_t)&CSTACK_BLOCK_START(CMB_CSTACK_BLOCK_NAME);
+    main_stack_size = (uint32_t)&CSTACK_BLOCK_END(CMB_CSTACK_BLOCK_NAME) - main_stack_start_addr;
+    code_start_addr = (uint32_t)&CODE_SECTION_START(CMB_CODE_SECTION_NAME);
+    code_size = (uint32_t)&CODE_SECTION_END(CMB_CODE_SECTION_NAME) - code_start_addr;
+#elif defined(__ICCARM__)
+    main_stack_start_addr = (uint32_t)__section_begin(CMB_CSTACK_BLOCK_NAME);
+    main_stack_size = (uint32_t)__section_end(CMB_CSTACK_BLOCK_NAME) - main_stack_start_addr;
+    code_start_addr = (uint32_t)__section_begin(CMB_CODE_SECTION_NAME);
+    code_size = (uint32_t)__section_end(CMB_CODE_SECTION_NAME) - code_start_addr;
+#elif defined(__GNUC__)
+    main_stack_start_addr = (uint32_t)(&CMB_CSTACK_BLOCK_START);
+    main_stack_size = (uint32_t)(&CMB_CSTACK_BLOCK_END) - main_stack_start_addr;
+    code_start_addr = (uint32_t)(&CMB_CODE_SECTION_START);
+    code_size = (uint32_t)(&CMB_CODE_SECTION_END) - code_start_addr;
+#else
+    #error "not supported compiler"
+#endif
+
+    if (main_stack_size == 0) {
+        cmb_println(print_info[PRINT_MAIN_STACK_CFG_ERROR]);
+        return;
+    }
+
+    init_ok = true;
+}
+
+void cm_backtrace_init_ex(const char *firmware_name, const char *hardware_ver, const char *software_ver, void *user_code) {
+	cm_backtrace_init(firmware_name, hardware_ver, software_ver);
+    user_run_code = user_code;
+}
+/**
+ * print firmware information, such as: firmware name, hardware version, software version
+ */
+void cm_backtrace_firmware_info(void) {
+    cmb_println(print_info[PRINT_FIRMWARE_INFO], fw_name, hw_ver, sw_ver);
+}
+
+#ifdef CMB_USING_OS_PLATFORM
+/**
+ * Get current thread stack information
+ *
+ * @param sp stack current pointer
+ * @param start_addr stack start address
+ * @param size stack size
+ */
+static void get_cur_thread_stack_info(uint32_t sp, uint32_t *start_addr, size_t *size) {
+    CMB_ASSERT(start_addr);
+    CMB_ASSERT(size);
+
+#if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)
+    *start_addr = (uint32_t) rt_thread_self()->stack_addr;
+    *size = rt_thread_self()->stack_size;
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSII)
+    extern OS_TCB *OSTCBCur;
+
+    *start_addr = (uint32_t) OSTCBCur->OSTCBStkBottom;
+    *size = OSTCBCur->OSTCBStkSize * sizeof(OS_STK);
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSIII)
+    extern OS_TCB *OSTCBCurPtr; 
+    
+    *start_addr = (uint32_t) OSTCBCurPtr->StkBasePtr;
+    *size = OSTCBCurPtr->StkSize * sizeof(CPU_STK_SIZE);
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_FREERTOS)   
+    *start_addr = (uint32_t)vTaskStackAddr();
+    *size = vTaskStackSize() * sizeof( StackType_t );
+#endif
+}
+
+/**
+ * Get current thread name
+ */
+static const char *get_cur_thread_name(void) {
+#if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)
+    return rt_thread_self()->name;
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSII)
+    extern OS_TCB *OSTCBCur;
+
+#if OS_TASK_NAME_SIZE > 0 || OS_TASK_NAME_EN > 0
+        return (const char *)OSTCBCur->OSTCBTaskName;
+#else
+        return NULL;
+#endif /* OS_TASK_NAME_SIZE > 0 || OS_TASK_NAME_EN > 0 */
+
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSIII)
+    extern OS_TCB *OSTCBCurPtr; 
+    
+    return (const char *)OSTCBCurPtr->NamePtr;
+#elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_FREERTOS)
+    return vTaskName();
+#endif
+}
+
+#endif /* CMB_USING_OS_PLATFORM */
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+/**
+ * dump current stack information
+ */
+static void dump_stack(uint32_t stack_start_addr, size_t stack_size, uint32_t *stack_pointer) {
+    if (stack_is_overflow) {
+        if (on_thread_before_fault) {
+            cmb_println(print_info[PRINT_THREAD_STACK_OVERFLOW], stack_pointer);
+        } else {
+            cmb_println(print_info[PRINT_MAIN_STACK_OVERFLOW], stack_pointer);
+        }
+        if ((uint32_t) stack_pointer < stack_start_addr) {
+            stack_pointer = (uint32_t *) stack_start_addr;
+        } else if ((uint32_t) stack_pointer > stack_start_addr + stack_size) {
+            stack_pointer = (uint32_t *) (stack_start_addr + stack_size);
+        }
+    }
+    cmb_println(print_info[PRINT_THREAD_STACK_INFO]);
+    for (; (uint32_t) stack_pointer < stack_start_addr + stack_size; stack_pointer++) {
+        cmb_println("  addr: %08x    data: %08x", stack_pointer, *stack_pointer);
+    }
+    cmb_println("====================================");
+}
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+/* check the disassembly instruction is 'BL' or 'BLX' */
+static bool disassembly_ins_is_bl_blx(uint32_t addr) {
+    uint16_t ins1 = *((uint16_t *)addr);
+    uint16_t ins2 = *((uint16_t *)(addr + 2));
+
+#define BL_INS_MASK         0xF800
+#define BL_INS_HIGH         0xF800
+#define BL_INS_LOW          0xF000
+#define BLX_INX_MASK        0xFF00
+#define BLX_INX             0x4700
+
+    if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW) {
+        return true;
+    } else if ((ins2 & BLX_INX_MASK) == BLX_INX) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * backtrace function call stack
+ *
+ * @param buffer call stack buffer
+ * @param size buffer size
+ * @param sp stack pointer
+ *
+ * @return depth
+ */
+size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp) {
+    uint32_t stack_start_addr = main_stack_start_addr, pc;
+    size_t depth = 0, stack_size = main_stack_size;
+    bool regs_saved_lr_is_valid = false;
+
+    if (on_fault) {
+        if (!stack_is_overflow) {
+            /* first depth is PC */
+            buffer[depth++] = regs.saved.pc;
+            /* fix the LR address in thumb mode */
+            pc = regs.saved.lr - 1;
+            if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH)
+                    && (depth < size)) {
+                buffer[depth++] = pc;
+                regs_saved_lr_is_valid = true;
+            }
+        }
+
+#ifdef CMB_USING_OS_PLATFORM
+        /* program is running on thread before fault */
+        if (on_thread_before_fault) {
+            get_cur_thread_stack_info(sp, &stack_start_addr, &stack_size);
+        }
+    } else {
+        /* OS environment */
+        if (cmb_get_sp() == cmb_get_psp()) {
+            get_cur_thread_stack_info(sp, &stack_start_addr, &stack_size);
+        }
+#endif /* CMB_USING_OS_PLATFORM */
+
+    }
+
+    if (stack_is_overflow) {
+        if (sp < stack_start_addr) {
+            sp = stack_start_addr;
+        } else if (sp > stack_start_addr + stack_size) {
+            sp = stack_start_addr + stack_size;
+        }
+    }
+
+    /* copy called function address */
+    for (; sp < stack_start_addr + stack_size; sp += sizeof(size_t)) {
+        /* the *sp value may be LR, so need decrease a word to PC */
+        pc = *((uint32_t *) sp) - sizeof(size_t);
+        /* the Cortex-M using thumb instruction, so the pc must be an odd number */
+        if (pc % 2 == 0) {
+            continue;
+        }
+        /* fix the PC address in thumb mode */
+        pc = *((uint32_t *) sp) - 1;
+        if ((pc >= code_start_addr) && (pc <= code_start_addr + code_size) && (depth < CMB_CALL_STACK_MAX_DEPTH)
+                /* check the the instruction before PC address is 'BL' or 'BLX' */
+                && disassembly_ins_is_bl_blx(pc - sizeof(size_t)) && (depth < size)) {
+            /* the second depth function may be already saved, so need ignore repeat */
+            if ((depth == 2) && regs_saved_lr_is_valid && (pc == buffer[1])) {
+                continue;
+            }
+            buffer[depth++] = pc;
+        }
+    }
+
+    return depth;
+}
+
+/**
+ * dump function call stack
+ *
+ * @param sp stack pointer
+ */
+static void print_call_stack(uint32_t sp) {
+    size_t i, cur_depth = 0;
+    uint32_t call_stack_buf[CMB_CALL_STACK_MAX_DEPTH] = {0};
+
+    cur_depth = cm_backtrace_call_stack(call_stack_buf, CMB_CALL_STACK_MAX_DEPTH, sp);
+
+    for (i = 0; i < cur_depth; i++) {
+        #ifdef __BUILD_APP__
+        sprintf_(call_stack_info + i * (8 + 1), "%x", call_stack_buf[i]);
+        #else
+        sprintf(call_stack_info + i * (8 + 1), "%08lx", call_stack_buf[i]);
+        #endif
+        call_stack_info[i * (8 + 1) + 8] = ' ';
+    }
+
+    if (cur_depth) {
+        cmb_println(print_info[PRINT_CALL_STACK_INFO], fw_name, CMB_ELF_FILE_EXTENSION_NAME, cur_depth * (8 + 1),
+                call_stack_info);
+    } else {
+        cmb_println(print_info[PRINT_CALL_STACK_ERR]);
+    }
+#ifdef __BUILD_OS__
+    Core_PrintServiceStack();
+#endif
+}
+
+/**
+ * backtrace for assert
+ *
+ * @param sp the stack pointer when on assert occurred
+ */
+void cm_backtrace_assert(uint32_t sp) {
+    CMB_ASSERT(init_ok);
+
+#ifdef CMB_USING_OS_PLATFORM
+    uint32_t cur_stack_pointer = cmb_get_sp();
+#endif
+
+    cmb_println("");
+    cm_backtrace_firmware_info();
+
+#ifdef CMB_USING_OS_PLATFORM
+    /* OS environment */
+    if (cur_stack_pointer == cmb_get_msp()) {
+        cmb_println(print_info[PRINT_ASSERT_ON_HANDLER]);
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+        dump_stack(main_stack_start_addr, main_stack_size, (uint32_t *) sp);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    } else if (cur_stack_pointer == cmb_get_psp()) {
+        cmb_println(print_info[PRINT_ASSERT_ON_THREAD], get_cur_thread_name());
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+        uint32_t stack_start_addr;
+        size_t stack_size;
+        get_cur_thread_stack_info(sp, &stack_start_addr, &stack_size);
+        dump_stack(stack_start_addr, stack_size, (uint32_t *) sp);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    }
+
+#else
+
+    /* bare metal(no OS) environment */
+#ifdef CMB_USING_DUMP_STACK_INFO
+    dump_stack(main_stack_start_addr, main_stack_size, (uint32_t *) sp);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+#endif /* CMB_USING_OS_PLATFORM */
+
+    print_call_stack(sp);
+}
+
+#if (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0)
+/**
+ * fault diagnosis then print cause of fault
+ */
+static void fault_diagnosis(void) {
+    if (regs.hfsr.bits.VECTBL) {
+        cmb_println(print_info[PRINT_HFSR_VECTBL]);
+    }
+    if (regs.hfsr.bits.FORCED) {
+        /* Memory Management Fault */
+        if (regs.mfsr.value) {
+            if (regs.mfsr.bits.IACCVIOL) {
+                cmb_println(print_info[PRINT_MFSR_IACCVIOL]);
+            }
+            if (regs.mfsr.bits.DACCVIOL) {
+                cmb_println(print_info[PRINT_MFSR_DACCVIOL]);
+            }
+            if (regs.mfsr.bits.MUNSTKERR) {
+                cmb_println(print_info[PRINT_MFSR_MUNSTKERR]);
+            }
+            if (regs.mfsr.bits.MSTKERR) {
+                cmb_println(print_info[PRINT_MFSR_MSTKERR]);
+            }
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7)
+            if (regs.mfsr.bits.MLSPERR) {
+                cmb_println(print_info[PRINT_MFSR_MLSPERR]);
+            }
+#endif
+
+            if (regs.mfsr.bits.MMARVALID) {
+                if (regs.mfsr.bits.IACCVIOL || regs.mfsr.bits.DACCVIOL) {
+                    cmb_println(print_info[PRINT_MMAR], regs.mmar);
+                }
+            }
+        }
+        /* Bus Fault */
+        if (regs.bfsr.value) {
+            if (regs.bfsr.bits.IBUSERR) {
+                cmb_println(print_info[PRINT_BFSR_IBUSERR]);
+            }
+            if (regs.bfsr.bits.PRECISERR) {
+                cmb_println(print_info[PRINT_BFSR_PRECISERR]);
+            }
+            if (regs.bfsr.bits.IMPREISERR) {
+                cmb_println(print_info[PRINT_BFSR_IMPREISERR]);
+            }
+            if (regs.bfsr.bits.UNSTKERR) {
+                cmb_println(print_info[PRINT_BFSR_UNSTKERR]);
+            }
+            if (regs.bfsr.bits.STKERR) {
+                cmb_println(print_info[PRINT_BFSR_STKERR]);
+            }
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7)
+            if (regs.bfsr.bits.LSPERR) {
+                cmb_println(print_info[PRINT_BFSR_LSPERR]);
+            }
+#endif
+
+            if (regs.bfsr.bits.BFARVALID) {
+                if (regs.bfsr.bits.PRECISERR) {
+                    cmb_println(print_info[PRINT_BFAR], regs.bfar);
+                }
+            }
+
+        }
+        /* Usage Fault */
+        if (regs.ufsr.value) {
+            if (regs.ufsr.bits.UNDEFINSTR) {
+                cmb_println(print_info[PRINT_UFSR_UNDEFINSTR]);
+            }
+            if (regs.ufsr.bits.INVSTATE) {
+                cmb_println(print_info[PRINT_UFSR_INVSTATE]);
+            }
+            if (regs.ufsr.bits.INVPC) {
+                cmb_println(print_info[PRINT_UFSR_INVPC]);
+            }
+            if (regs.ufsr.bits.NOCP) {
+                cmb_println(print_info[PRINT_UFSR_NOCP]);
+            }
+            if (regs.ufsr.bits.UNALIGNED) {
+                cmb_println(print_info[PRINT_UFSR_UNALIGNED]);
+            }
+            if (regs.ufsr.bits.DIVBYZERO0) {
+                cmb_println(print_info[PRINT_UFSR_DIVBYZERO0]);
+            }
+        }
+    }
+    /* Debug Fault */
+    if (regs.hfsr.bits.DEBUGEVT) {
+        if (regs.dfsr.value) {
+            if (regs.dfsr.bits.HALTED) {
+                cmb_println(print_info[PRINT_DFSR_HALTED]);
+            }
+            if (regs.dfsr.bits.BKPT) {
+                cmb_println(print_info[PRINT_DFSR_BKPT]);
+            }
+            if (regs.dfsr.bits.DWTTRAP) {
+                cmb_println(print_info[PRINT_DFSR_DWTTRAP]);
+            }
+            if (regs.dfsr.bits.VCATCH) {
+                cmb_println(print_info[PRINT_DFSR_VCATCH]);
+            }
+            if (regs.dfsr.bits.EXTERNAL) {
+                cmb_println(print_info[PRINT_DFSR_EXTERNAL]);
+            }
+        }
+    }
+}
+#endif /* (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0) */
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7)
+static uint32_t statck_del_fpu_regs(uint32_t fault_handler_lr, uint32_t sp) {
+    statck_has_fpu_regs = (fault_handler_lr & (1UL << 4)) == 0 ? true : false;
+
+    /* the stack has S0~S15 and FPSCR registers when statck_has_fpu_regs is true, double word align */
+    return statck_has_fpu_regs == true ? sp + sizeof(size_t) * 18 : sp;
+}
+#endif
+
+/**
+ * backtrace for fault
+ * @note only call once
+ *
+ * @param fault_handler_lr the LR register value on fault handler
+ * @param fault_handler_sp the stack pointer on fault handler
+ */
+void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp) {
+    uint32_t stack_pointer = fault_handler_sp, saved_regs_addr = stack_pointer;
+    const char *regs_name[] = { "R0 ", "R1 ", "R2 ", "R3 ", "R12", "LR ", "PC ", "PSR" };
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+    uint32_t stack_start_addr = main_stack_start_addr;
+    size_t stack_size = main_stack_size;
+#endif
+    CMB_ASSERT(init_ok);
+    /* only call once */
+    CMB_ASSERT(!on_fault);
+
+    on_fault = true;
+
+    cmb_println("");
+    cm_backtrace_firmware_info();
+
+#ifdef CMB_USING_OS_PLATFORM
+    on_thread_before_fault = fault_handler_lr & (1UL << 2);
+    /* check which stack was used before (MSP or PSP) */
+    if (on_thread_before_fault) {
+        cmb_println(print_info[PRINT_FAULT_ON_THREAD], get_cur_thread_name() != NULL ? get_cur_thread_name() : "NO_NAME");
+        saved_regs_addr = stack_pointer = cmb_get_psp();
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+        get_cur_thread_stack_info(stack_pointer, &stack_start_addr, &stack_size);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    } else {
+        cmb_println(print_info[PRINT_FAULT_ON_HANDLER]);
+    }
+#else
+    /* bare metal(no OS) environment */
+    cmb_println(print_info[PRINT_FAULT_ON_HANDLER]);
+#endif /* CMB_USING_OS_PLATFORM */
+
+    /* delete saved R0~R3, R12, LR,PC,xPSR registers space */
+    stack_pointer += sizeof(size_t) * 8;
+
+#if (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7)
+    stack_pointer = statck_del_fpu_regs(fault_handler_lr, stack_pointer);
+#endif /* (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M4) || (CMB_CPU_PLATFORM_TYPE == CMB_CPU_ARM_CORTEX_M7) */
+
+#ifdef CMB_USING_DUMP_STACK_INFO
+    /* check stack overflow */
+    if (stack_pointer < stack_start_addr || stack_pointer > stack_start_addr + stack_size) {
+        stack_is_overflow = true;
+    }
+    /* dump stack information */
+    dump_stack(stack_start_addr, stack_size, (uint32_t *) stack_pointer);
+#endif /* CMB_USING_DUMP_STACK_INFO */
+
+    /* the stack frame may be get failed when it is overflow  */
+    if (!stack_is_overflow) {
+        /* dump register */
+        cmb_println(print_info[PRINT_REGS_TITLE]);
+
+        regs.saved.r0        = ((uint32_t *)saved_regs_addr)[0];  // Register R0
+        regs.saved.r1        = ((uint32_t *)saved_regs_addr)[1];  // Register R1
+        regs.saved.r2        = ((uint32_t *)saved_regs_addr)[2];  // Register R2
+        regs.saved.r3        = ((uint32_t *)saved_regs_addr)[3];  // Register R3
+        regs.saved.r12       = ((uint32_t *)saved_regs_addr)[4];  // Register R12
+        regs.saved.lr        = ((uint32_t *)saved_regs_addr)[5];  // Link register LR
+        regs.saved.pc        = ((uint32_t *)saved_regs_addr)[6];  // Program counter PC
+        regs.saved.psr.value = ((uint32_t *)saved_regs_addr)[7];  // Program status word PSR
+
+        cmb_println("  %s: %08x  %s: %08x  %s: %08x  %s: %08x", regs_name[0], regs.saved.r0,
+                                                                regs_name[1], regs.saved.r1,
+                                                                regs_name[2], regs.saved.r2,
+                                                                regs_name[3], regs.saved.r3);
+        cmb_println("  %s: %08x  %s: %08x  %s: %08x  %s: %08x", regs_name[4], regs.saved.r12,
+                                                                regs_name[5], regs.saved.lr,
+                                                                regs_name[6], regs.saved.pc,
+                                                                regs_name[7], regs.saved.psr.value);
+        cmb_println("==============================================================");
+    }
+
+    /* the Cortex-M0 is not support fault diagnosis */
+#if (CMB_CPU_PLATFORM_TYPE != CMB_CPU_ARM_CORTEX_M0)
+    regs.syshndctrl.value = CMB_SYSHND_CTRL;  // System Handler Control and State Register
+    regs.mfsr.value       = CMB_NVIC_MFSR;    // Memory Fault Status Register
+    regs.mmar             = CMB_NVIC_MMAR;    // Memory Management Fault Address Register
+    regs.bfsr.value       = CMB_NVIC_BFSR;    // Bus Fault Status Register
+    regs.bfar             = CMB_NVIC_BFAR;    // Bus Fault Manage Address Register
+    regs.ufsr.value       = CMB_NVIC_UFSR;    // Usage Fault Status Register
+    regs.hfsr.value       = CMB_NVIC_HFSR;    // Hard Fault Status Register
+    regs.dfsr.value       = CMB_NVIC_DFSR;    // Debug Fault Status Register
+    regs.afsr             = CMB_NVIC_AFSR;    // Auxiliary Fault Status Register
+
+    fault_diagnosis();
+#endif
+
+    print_call_stack(stack_pointer);
+    if (user_run_code)
+    {
+    	user_run_code();
+    }
+}
+
+#endif

+ 40 - 0
Third_Party/cm_backtrace/cm_backtrace.h

@@ -0,0 +1,40 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Function: It is an head file for this library. You can see all be called functions.
+ * Created on: 2016-12-15
+ */
+
+#ifndef _CORTEXM_BACKTRACE_H_
+#define _CORTEXM_BACKTRACE_H_
+
+#include "cmb_def.h"
+
+void cm_backtrace_init(const char *firmware_name, const char *hardware_ver, const char *software_ver);
+void cm_backtrace_firmware_info(void);
+size_t cm_backtrace_call_stack(uint32_t *buffer, size_t size, uint32_t sp);
+void cm_backtrace_assert(uint32_t sp);
+void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp);
+
+#endif /* _CORTEXM_BACKTRACE_H_ */

+ 50 - 0
Third_Party/cm_backtrace/cmb_cfg.h

@@ -0,0 +1,50 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Function: It is the configure head file for this library.
+ * Created on: 2016-12-15
+ */
+
+#ifndef _CMB_CFG_H_
+#define _CMB_CFG_H_
+extern void DBG_Trace(const char* format, ...);
+#define cmb_println(...)        DBG_Trace(__VA_ARGS__)       /* e.g., printf(__VA_ARGS__);printf("\r\n") */
+
+/* print line, must config by user */
+
+/* enable bare metal(no OS) platform */
+/* #define CMB_USING_BARE_METAL_PLATFORM */
+/* enable OS platform */
+//#define CMB_USING_OS_PLATFORM
+/* OS platform type, must config when CMB_USING_OS_PLATFORM is enable */
+//#define CMB_OS_PLATFORM_TYPE          CMB_OS_PLATFORM_FREERTOS
+/* cpu platform type, must config by user */
+#ifndef CMB_CPU_PLATFORM_TYPE
+#define CMB_CPU_PLATFORM_TYPE         CMB_CPU_ARM_CORTEX_M0
+#endif
+/* enable dump stack information */
+//#define CMB_USING_DUMP_STACK_INFO
+/* language of print information */
+/* #define CMB_PRINT_LANGUAGE             CMB_PRINT_LANGUAGE_ENGLISH(default) or CMB_PRINT_LANGUAGE_CHINESE */
+#endif /* _CMB_CFG_H_ */

+ 368 - 0
Third_Party/cm_backtrace/cmb_def.h

@@ -0,0 +1,368 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016-2020, Armink, <armink.ztl@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Function: It is the macro definition head file for this library.
+ * Created on: 2016-12-15
+ */
+
+#ifndef _CMB_DEF_H_
+#define _CMB_DEF_H_
+
+#include <cmb_cfg.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/* library software version number */
+#define CMB_SW_VERSION                "1.4.0"
+
+#define CMB_CPU_ARM_CORTEX_M0          0
+#define CMB_CPU_ARM_CORTEX_M3          1
+#define CMB_CPU_ARM_CORTEX_M4          2
+#define CMB_CPU_ARM_CORTEX_M7          3
+
+#define CMB_OS_PLATFORM_RTT            0
+#define CMB_OS_PLATFORM_UCOSII         1
+#define CMB_OS_PLATFORM_UCOSIII        2
+#define CMB_OS_PLATFORM_FREERTOS       3
+
+#define CMB_PRINT_LANGUAGE_ENGLISH     0
+#define CMB_PRINT_LANGUAGE_CHINESE     1
+
+/* name max length, default size: 32 */
+#ifndef CMB_NAME_MAX
+#define CMB_NAME_MAX                   32
+#endif
+
+/* print information language, default is English */
+#ifndef CMB_PRINT_LANGUAGE
+#define CMB_PRINT_LANGUAGE             CMB_PRINT_LANGUAGE_ENGLISH
+#endif
+
+
+#if defined(__CC_ARM)
+    /* C stack block name, default is STACK */
+    #ifndef CMB_CSTACK_BLOCK_NAME
+    #define CMB_CSTACK_BLOCK_NAME          STACK
+    #endif
+    /* code section name, default is ER_IROM1 */
+    #ifndef CMB_CODE_SECTION_NAME
+    #define CMB_CODE_SECTION_NAME          ER_IROM1
+    #endif
+#elif defined(__ICCARM__)
+    /* C stack block name, default is 'CSTACK' */
+    #ifndef CMB_CSTACK_BLOCK_NAME
+    #define CMB_CSTACK_BLOCK_NAME          "CSTACK"
+    #endif
+    /* code section name, default is '.text' */
+    #ifndef CMB_CODE_SECTION_NAME
+    #define CMB_CODE_SECTION_NAME          ".text"
+    #endif
+#elif defined(__GNUC__)
+    /* C stack block start address, defined on linker script file, default is _sstack */
+    #ifndef CMB_CSTACK_BLOCK_START
+    #define CMB_CSTACK_BLOCK_START         _sstack
+    #endif
+    /* C stack block end address, defined on linker script file, default is _estack */
+    #ifndef CMB_CSTACK_BLOCK_END
+    #define CMB_CSTACK_BLOCK_END           _estack
+    #endif
+    /* code section start address, defined on linker script file, default is _stext */
+    #ifndef CMB_CODE_SECTION_START
+    #define CMB_CODE_SECTION_START         _stext
+    #endif
+    /* code section end address, defined on linker script file, default is _etext */
+    #ifndef CMB_CODE_SECTION_END
+    #define CMB_CODE_SECTION_END           _etext
+    #endif
+#else
+    #error "not supported compiler"
+#endif
+
+/* supported function call stack max depth, default is 16 */
+#ifndef CMB_CALL_STACK_MAX_DEPTH
+#define CMB_CALL_STACK_MAX_DEPTH       16
+#endif
+
+/* system handler control and state register */
+#ifndef CMB_SYSHND_CTRL
+#define CMB_SYSHND_CTRL                (*(volatile unsigned int*)  (0xE000ED24u))
+#endif
+
+/* memory management fault status register */
+#ifndef CMB_NVIC_MFSR
+#define CMB_NVIC_MFSR                  (*(volatile unsigned char*) (0xE000ED28u))
+#endif
+
+/* bus fault status register */
+#ifndef CMB_NVIC_BFSR
+#define CMB_NVIC_BFSR                  (*(volatile unsigned char*) (0xE000ED29u))
+#endif
+
+/* usage fault status register */
+#ifndef CMB_NVIC_UFSR
+#define CMB_NVIC_UFSR                  (*(volatile unsigned short*)(0xE000ED2Au))
+#endif
+
+/* hard fault status register */
+#ifndef CMB_NVIC_HFSR
+#define CMB_NVIC_HFSR                  (*(volatile unsigned int*)  (0xE000ED2Cu))
+#endif
+
+/* debug fault status register */
+#ifndef CMB_NVIC_DFSR
+#define CMB_NVIC_DFSR                  (*(volatile unsigned short*)(0xE000ED30u))
+#endif
+
+/* memory management fault address register */
+#ifndef CMB_NVIC_MMAR
+#define CMB_NVIC_MMAR                  (*(volatile unsigned int*)  (0xE000ED34u))
+#endif
+
+/* bus fault manage address register */
+#ifndef CMB_NVIC_BFAR
+#define CMB_NVIC_BFAR                  (*(volatile unsigned int*)  (0xE000ED38u))
+#endif
+
+/* auxiliary fault status register */
+#ifndef CMB_NVIC_AFSR
+#define CMB_NVIC_AFSR                  (*(volatile unsigned short*)(0xE000ED3Cu))
+#endif
+
+/**
+ * Cortex-M fault registers
+ */
+struct cmb_hard_fault_regs{
+  struct {
+    unsigned int r0;                     // Register R0
+    unsigned int r1;                     // Register R1
+    unsigned int r2;                     // Register R2
+    unsigned int r3;                     // Register R3
+    unsigned int r12;                    // Register R12
+    unsigned int lr;                     // Link register
+    unsigned int pc;                     // Program counter
+    union {
+      unsigned int value;
+      struct {
+        unsigned int IPSR : 8;           // Interrupt Program Status register (IPSR)
+        unsigned int EPSR : 19;          // Execution Program Status register (EPSR)
+        unsigned int APSR : 5;           // Application Program Status register (APSR)
+      } bits;
+    } psr;                               // Program status register.
+  } saved;
+
+  union {
+    unsigned int value;
+    struct {
+      unsigned int MEMFAULTACT    : 1;   // Read as 1 if memory management fault is active
+      unsigned int BUSFAULTACT    : 1;   // Read as 1 if bus fault exception is active
+      unsigned int UnusedBits1    : 1;
+      unsigned int USGFAULTACT    : 1;   // Read as 1 if usage fault exception is active
+      unsigned int UnusedBits2    : 3;
+      unsigned int SVCALLACT      : 1;   // Read as 1 if SVC exception is active
+      unsigned int MONITORACT     : 1;   // Read as 1 if debug monitor exception is active
+      unsigned int UnusedBits3    : 1;
+      unsigned int PENDSVACT      : 1;   // Read as 1 if PendSV exception is active
+      unsigned int SYSTICKACT     : 1;   // Read as 1 if SYSTICK exception is active
+      unsigned int USGFAULTPENDED : 1;   // Usage fault pended; usage fault started but was replaced by a higher-priority exception
+      unsigned int MEMFAULTPENDED : 1;   // Memory management fault pended; memory management fault started but was replaced by a higher-priority exception
+      unsigned int BUSFAULTPENDED : 1;   // Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception
+      unsigned int SVCALLPENDED   : 1;   // SVC pended; SVC was started but was replaced by a higher-priority exception
+      unsigned int MEMFAULTENA    : 1;   // Memory management fault handler enable
+      unsigned int BUSFAULTENA    : 1;   // Bus fault handler enable
+      unsigned int USGFAULTENA    : 1;   // Usage fault handler enable
+    } bits;
+  } syshndctrl;                          // System Handler Control and State Register (0xE000ED24)
+
+  union {
+    unsigned char value;
+    struct {
+      unsigned char IACCVIOL    : 1;     // Instruction access violation
+      unsigned char DACCVIOL    : 1;     // Data access violation
+      unsigned char UnusedBits  : 1;
+      unsigned char MUNSTKERR   : 1;     // Unstacking error
+      unsigned char MSTKERR     : 1;     // Stacking error
+      unsigned char MLSPERR     : 1;     // Floating-point lazy state preservation (M4/M7)
+      unsigned char UnusedBits2 : 1;
+      unsigned char MMARVALID   : 1;     // Indicates the MMAR is valid
+    } bits;
+  } mfsr;                                // Memory Management Fault Status Register (0xE000ED28)
+  unsigned int mmar;                     // Memory Management Fault Address Register (0xE000ED34)
+
+  union {
+    unsigned char value;
+    struct {
+      unsigned char IBUSERR    : 1;      // Instruction access violation
+      unsigned char PRECISERR  : 1;      // Precise data access violation
+      unsigned char IMPREISERR : 1;      // Imprecise data access violation
+      unsigned char UNSTKERR   : 1;      // Unstacking error
+      unsigned char STKERR     : 1;      // Stacking error
+      unsigned char LSPERR     : 1;      // Floating-point lazy state preservation (M4/M7)
+      unsigned char UnusedBits : 1;
+      unsigned char BFARVALID  : 1;      // Indicates BFAR is valid
+    } bits;
+  } bfsr;                                // Bus Fault Status Register (0xE000ED29)
+  unsigned int bfar;                     // Bus Fault Manage Address Register (0xE000ED38)
+
+  union {
+    unsigned short value;
+    struct {
+      unsigned short UNDEFINSTR : 1;     // Attempts to execute an undefined instruction
+      unsigned short INVSTATE   : 1;     // Attempts to switch to an invalid state (e.g., ARM)
+      unsigned short INVPC      : 1;     // Attempts to do an exception with a bad value in the EXC_RETURN number
+      unsigned short NOCP       : 1;     // Attempts to execute a coprocessor instruction
+      unsigned short UnusedBits : 4;
+      unsigned short UNALIGNED  : 1;     // Indicates that an unaligned access fault has taken place
+      unsigned short DIVBYZERO0 : 1;     // Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
+    } bits;
+  } ufsr;                                // Usage Fault Status Register (0xE000ED2A)
+
+  union {
+    unsigned int value;
+    struct {
+      unsigned int UnusedBits  : 1;
+      unsigned int VECTBL      : 1;      // Indicates hard fault is caused by failed vector fetch
+      unsigned int UnusedBits2 : 28;
+      unsigned int FORCED      : 1;      // Indicates hard fault is taken because of bus fault/memory management fault/usage fault
+      unsigned int DEBUGEVT    : 1;      // Indicates hard fault is triggered by debug event
+    } bits;
+  } hfsr;                                // Hard Fault Status Register (0xE000ED2C)
+
+  union {
+    unsigned int value;
+    struct {
+      unsigned int HALTED   : 1;         // Halt requested in NVIC
+      unsigned int BKPT     : 1;         // BKPT instruction executed
+      unsigned int DWTTRAP  : 1;         // DWT match occurred
+      unsigned int VCATCH   : 1;         // Vector fetch occurred
+      unsigned int EXTERNAL : 1;         // EDBGRQ signal asserted
+    } bits;
+  } dfsr;                                // Debug Fault Status Register (0xE000ED30)
+
+  unsigned int afsr;                     // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
+};
+
+/* assert for developer. */
+#define CMB_ASSERT(EXPR)                                                       \
+if (!(EXPR))                                                                   \
+{                                                                              \
+    cmb_println("(%s) has assert failed at %s.", #EXPR, __FUNCTION__);         \
+    while (1);                                                                 \
+}
+
+/* ELF(Executable and Linking Format) file extension name for each compiler */
+#if defined(__CC_ARM)
+    #define CMB_ELF_FILE_EXTENSION_NAME          ".axf"
+#elif defined(__ICCARM__)
+    #define CMB_ELF_FILE_EXTENSION_NAME          ".out"
+#elif defined(__GNUC__)
+    #define CMB_ELF_FILE_EXTENSION_NAME          ".elf"
+#else
+    #error "not supported compiler"
+#endif
+
+#ifndef cmb_println
+    #error "cmb_println isn't defined in 'cmb_cfg.h'"
+#endif
+
+#ifndef CMB_CPU_PLATFORM_TYPE
+    #error "CMB_CPU_PLATFORM_TYPE isn't defined in 'cmb_cfg.h'"
+#endif
+
+#if (defined(CMB_USING_BARE_METAL_PLATFORM) && defined(CMB_USING_OS_PLATFORM))
+    #error "CMB_USING_BARE_METAL_PLATFORM and CMB_USING_OS_PLATFORM only one of them can be used"
+#elif defined(CMB_USING_OS_PLATFORM)
+    #if !defined(CMB_OS_PLATFORM_TYPE)
+        #error "CMB_OS_PLATFORM_TYPE isn't defined in 'cmb_cfg.h'"
+    #endif /* !defined(CMB_OS_PLATFORM_TYPE) */
+    #if (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT)
+        #include <rtthread.h>
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSII)
+        #include <ucos_ii.h>
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_UCOSIII)
+        #include <os.h>
+    #elif (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_FREERTOS)
+        #include <FreeRTOS.h>  
+        extern uint32_t *vTaskStackAddr(void);/* need to modify the FreeRTOS/tasks source code */
+        extern uint32_t vTaskStackSize(void);
+        extern char * vTaskName(void);
+    #else
+        #error "not supported OS type"
+    #endif /* (CMB_OS_PLATFORM_TYPE == CMB_OS_PLATFORM_RTT) */
+#endif /* (defined(CMB_USING_BARE_METAL_PLATFORM) && defined(CMB_USING_OS_PLATFORM)) */
+
+/* include or export for supported cmb_get_msp, cmb_get_psp and cmb_get_sp function */
+#if defined(__CC_ARM)
+    static __inline __asm uint32_t cmb_get_msp(void) {
+        mrs r0, msp
+        bx lr
+    }
+    static __inline __asm uint32_t cmb_get_psp(void) {
+        mrs r0, psp
+        bx lr
+    }
+    static __inline __asm uint32_t cmb_get_sp(void) {
+        mov r0, sp
+        bx lr
+    }
+#elif defined(__ICCARM__)
+/* IAR iccarm specific functions */
+/* Close Raw Asm Code Warning */  
+#pragma diag_suppress=Pe940    
+    static uint32_t cmb_get_msp(void)
+    {
+      __asm("mrs r0, msp");
+      __asm("bx lr");        
+    }
+    static uint32_t cmb_get_psp(void)
+    {
+      __asm("mrs r0, psp");
+      __asm("bx lr");        
+    }
+    static uint32_t cmb_get_sp(void)
+    {
+      __asm("mov r0, sp");
+      __asm("bx lr");       
+    }
+#pragma diag_default=Pe940  
+#elif defined(__GNUC__)
+    __attribute__( ( always_inline ) ) static inline uint32_t cmb_get_msp(void) {
+        register uint32_t result;
+        __asm volatile ("MRS %0, msp\n" : "=r" (result) );
+        return(result);
+    }
+    __attribute__( ( always_inline ) ) static inline uint32_t cmb_get_psp(void) {
+        register uint32_t result;
+        __asm volatile ("MRS %0, psp\n" : "=r" (result) );
+        return(result);
+    }
+    __attribute__( ( always_inline ) ) static inline uint32_t cmb_get_sp(void) {
+        register uint32_t result;
+        __asm volatile ("MOV %0, sp\n" : "=r" (result) );
+        return(result);
+    }
+#else
+    #error "not supported compiler"
+#endif
+
+#endif /* _CMB_DEF_H_ */

+ 43 - 0
Third_Party/cm_backtrace/fault_handler/gcc/cmb_fault.S

@@ -0,0 +1,43 @@
+/*
+ * This file is part of the CmBacktrace Library.
+ *
+ * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * 'Software'), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Function: Fault handler by GCC assembly code
+ * Created on: 2016-12-16
+ */
+
+.syntax unified
+.thumb
+.text
+
+/* NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file. */
+
+.global HardFault_Handler
+.type HardFault_Handler, %function
+HardFault_Handler:
+    MOV     r0, lr                  /* get lr */
+    MOV     r1, sp                  /* get stack pointer (current is MSP) */
+    BL      cm_backtrace_fault
+
+Fault_Loop:
+    BL      Fault_Loop              /* while(1) */

+ 46 - 0
Third_Party/cm_backtrace/fault_handler/iar/cmb_fault.S

@@ -0,0 +1,46 @@
+;/*
+; * This file is part of the CmBacktrace Library.
+; *
+; * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+; *
+; * Permission is hereby granted, free of charge, to any person obtaining
+; * a copy of this software and associated documentation files (the
+; * 'Software'), to deal in the Software without restriction, including
+; * without limitation the rights to use, copy, modify, merge, publish,
+; * distribute, sublicense, and/or sell copies of the Software, and to
+; * permit persons to whom the Software is furnished to do so, subject to
+; * the following conditions:
+; *
+; * The above copyright notice and this permission notice shall be
+; * included in all copies or substantial portions of the Software.
+; *
+; * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+; * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+; * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+; * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+; * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+; * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+; * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+; *
+; * Function: Fault handler by EWARM assembly code
+; * Created on: 2016-12-16
+; */
+
+    SECTION    .text:CODE(2)
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+; NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file.
+    IMPORT cm_backtrace_fault
+    EXPORT HardFault_Handler
+
+HardFault_Handler:
+    MOV     r0, lr                  ; get lr
+    MOV     r1, sp                  ; get stack pointer (current is MSP)
+    BL      cm_backtrace_fault
+
+Fault_Loop
+    BL      Fault_Loop              ;while(1)
+
+    END

+ 47 - 0
Third_Party/cm_backtrace/fault_handler/keil/cmb_fault.S

@@ -0,0 +1,47 @@
+;/*
+; * This file is part of the CmBacktrace Library.
+; *
+; * Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
+; *
+; * Permission is hereby granted, free of charge, to any person obtaining
+; * a copy of this software and associated documentation files (the
+; * 'Software'), to deal in the Software without restriction, including
+; * without limitation the rights to use, copy, modify, merge, publish,
+; * distribute, sublicense, and/or sell copies of the Software, and to
+; * permit persons to whom the Software is furnished to do so, subject to
+; * the following conditions:
+; *
+; * The above copyright notice and this permission notice shall be
+; * included in all copies or substantial portions of the Software.
+; *
+; * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+; * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+; * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+; * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+; * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+; * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+; * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+; *
+; * Function: Fault handler by MDK-ARM assembly code
+; * Created on: 2016-12-16
+; */
+
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+; NOTE: If use this file's HardFault_Handler, please comments the HardFault_Handler code on other file.
+    IMPORT cm_backtrace_fault
+    EXPORT HardFault_Handler
+
+HardFault_Handler    PROC
+    MOV     r0, lr                  ; get lr
+    MOV     r1, sp                  ; get stack pointer (current is MSP)
+    BL      cm_backtrace_fault
+
+Fault_Loop
+    BL      Fault_Loop              ;while(1)
+    ENDP
+
+    END

+ 1603 - 0
Third_Party/heap/bget.c

@@ -0,0 +1,1603 @@
+/*
+
+                               B G E T
+
+                           Buffer allocator
+
+    Designed and implemented in April of 1972 by John Walker, based on the
+    Case Algol OPRO$ algorithm implemented in 1966.
+
+    Reimplemented in 1975 by John Walker for the Interdata 70.
+    Reimplemented in 1977 by John Walker for the Marinchip 9900.
+    Reimplemented in 1982 by Duff Kurland for the Intel 8080.
+
+    Portable C version implemented in September of 1990 by an older, wiser
+    instance of the original implementor.
+
+    Souped up and/or weighed down  slightly  shortly  thereafter  by  Greg
+    Lutz.
+
+    AMIX  edition, including the new compaction call-back option, prepared
+    by John Walker in July of 1992.
+
+    Bug in built-in test program fixed, ANSI compiler warnings eradicated,
+    buffer pool validator  implemented,  and  guaranteed  repeatable  test
+    added by John Walker in October of 1995.
+
+    This program is in the public domain.
+
+     1. This is the book of the generations of Adam.   In the day that God
+        created man, in the likeness of God made he him;
+     2. Male and female created he them;  and  blessed  them,  and  called
+        their name Adam, in the day when they were created.
+     3. And  Adam  lived  an hundred and thirty years,  and begat a son in
+        his own likeness, and after his image; and called his name Seth:
+     4. And the days of  Adam  after  he  had  begotten  Seth  were  eight
+        hundred years: and he begat sons and daughters:
+     5. And  all  the  days  that Adam lived were nine  hundred and thirty
+        years: and he died.
+     6. And Seth lived an hundred and five years, and begat Enos:
+     7. And Seth lived after he begat Enos eight hundred and seven  years,
+        and begat sons and daughters:
+     8.  And  all the days of Seth were nine hundred and twelve years: and
+         he died.
+     9. And Enos lived ninety years, and begat Cainan:
+    10. And Enos lived after he begat  Cainan eight  hundred  and  fifteen
+        years, and begat sons and daughters:
+    11. And  all  the days of Enos were nine hundred  and five years:  and
+        he died.
+    12. And Cainan lived seventy years and begat Mahalaleel:
+    13. And Cainan lived  after he  begat  Mahalaleel  eight  hundred  and
+        forty years, and begat sons and daughters:
+    14. And  all the days of Cainan were nine  hundred and ten years:  and
+        he died.
+    15. And Mahalaleel lived sixty and five years, and begat Jared:
+    16. And Mahalaleel lived  after  he  begat  Jared  eight  hundred  and
+        thirty years, and begat sons and daughters:
+    17. And  all  the  days  of Mahalaleel  were eight hundred  ninety and
+        five years: and he died.
+    18. And Jared lived an hundred sixty and  two  years,   and  he  begat
+        Enoch:
+    19. And  Jared  lived  after he begat Enoch  eight hundred years,  and
+        begat sons and daughters:
+    20. And all the days of Jared  were nine hundred sixty and two  years:
+        and he died.
+    21. And Enoch lived sixty and five years, and begat Methuselah:
+    22. And  Enoch  walked   with  God  after  he  begat Methuselah  three
+        hundred years, and begat sons and daughters:
+    23. And all the days of  Enoch  were  three  hundred  sixty  and  five
+        years:
+    24. And Enoch walked with God: and he was not; for God took him.
+    25. And  Methuselah  lived  an  hundred  eighty and  seven years,  and
+        begat Lamech.
+    26. And Methuselah lived after he  begat Lamech seven  hundred  eighty
+        and two years, and begat sons and daughters:
+    27. And  all the days of Methuselah  were nine hundred  sixty and nine
+        years: and he died.
+    28. And Lamech lived an hundred eighty  and two  years,  and  begat  a
+        son:
+    29. And  he called his name Noah, saying,  This same shall  comfort us
+        concerning  our  work and toil of our hands, because of the ground
+        which the LORD hath cursed.
+    30. And  Lamech  lived  after  he begat Noah  five hundred  ninety and
+        five years, and begat sons and daughters:
+    31. And all the days of Lamech were  seven hundred seventy  and  seven
+        years: and he died.
+    32. And  Noah  was five hundred years old:  and Noah begat Shem,  Ham,
+        and Japheth.
+
+    And buffers begat buffers, and links begat  links,  and  buffer  pools
+    begat  links  to chains of buffer pools containing buffers, and lo the
+    buffers and links and pools of buffers and pools of links to chains of
+    pools  of  buffers were fruitful and they multiplied and the Operating
+    System looked down upon them and said that it was Good.
+
+
+    INTRODUCTION
+    ============
+
+    BGET  is a comprehensive memory allocation package which is easily
+    configured to the needs of an application.  BGET is  efficient  in
+    both  the  time  needed to allocate and release buffers and in the
+    memory  overhead  required  for  buffer   pool   management.    It
+    automatically    consolidates   contiguous   space   to   minimise
+    fragmentation.  BGET is configured  by  compile-time  definitions,
+    Major options include:
+
+        *   A  built-in  test  program  to  exercise  BGET   and
+            demonstrate how the various functions are used.
+
+        *   Allocation  by  either the "first fit" or "best fit"
+            method.
+
+        *   Wiping buffers at release time to catch  code  which
+            references previously released storage.
+
+        *   Built-in  routines to dump individual buffers or the
+            entire buffer pool.
+
+        *   Retrieval of allocation and pool size statistics.
+
+        *   Quantisation of buffer sizes to a power  of  two  to
+            satisfy hardware alignment constraints.
+
+        *   Automatic  pool compaction, growth, and shrinkage by
+            means of call-backs to user defined functions.
+
+    Applications  of  BGET  can  range  from  storage  management   in
+    ROM-based  embedded programs to providing the framework upon which
+    a  multitasking  system  incorporating   garbage   collection   is
+    constructed.   BGET  incorporates  extensive  internal consistency
+    checking using the <assert.h> mechanism; all these checks  can  be
+    turned off by compiling with NDEBUG defined, yielding a version of
+    BGET with minimal size and maximum speed.
+
+    The  basic  algorithm  underlying  BGET  has withstood the test of
+    time;  more  than  25  years   have   passed   since   the   first
+    implementation  of  this  code.  And yet, it is substantially more
+    efficient than the native allocation  schemes  of  many  operating
+    systems: the Macintosh and Microsoft Windows to name two, on which
+    programs have obtained substantial speed-ups by layering  BGET  as
+    an application level memory manager atop the underlying system's.
+
+    BGET has been implemented on the largest mainframes and the lowest
+    of  microprocessors.   It  has served as the core for multitasking
+    operating systems, multi-thread applications, embedded software in
+    data  network switching processors, and a host of C programs.  And
+    while it has accreted flexibility and additional options over  the
+    years,  it  remains  fast, memory efficient, portable, and easy to
+    integrate into your program.
+
+
+    BGET IMPLEMENTATION ASSUMPTIONS
+    ===============================
+
+    BGET is written in as portable a dialect of C  as  possible.   The
+    only   fundamental   assumption   about  the  underlying  hardware
+    architecture is that memory is allocated is a linear  array  which
+    can  be  addressed  as a vector of C "char" objects.  On segmented
+    address space architectures, this generally means that BGET should
+    be used to allocate storage within a single segment (although some
+    compilers   simulate   linear   address   spaces   on    segmented
+    architectures).   On  segmented  architectures,  then, BGET buffer
+    pools  may not be larger than a segment, but since BGET allows any
+    number of separate buffer pools, there is no limit  on  the  total
+    storage  which  can  be  managed,  only  on the largest individual
+    object which can be allocated.  Machines  with  a  linear  address
+    architecture,  such  as  the VAX, 680x0, Sparc, MIPS, or the Intel
+    80386 and above in native mode, may use BGET without restriction.
+
+
+    GETTING STARTED WITH BGET
+    =========================
+
+    Although BGET can be configured in a multitude of fashions,  there
+    are  three  basic  ways  of  working  with  BGET.   The  functions
+    mentioned below are documented in the following  section.   Please
+    excuse  the  forward  references which are made in the interest of
+    providing a roadmap to guide you  to  the  BGET  functions  you're
+    likely to need.
+
+    Embedded Applications
+    ---------------------
+
+    Embedded applications  typically  have  a  fixed  area  of  memory
+    dedicated  to  buffer  allocation (often in a separate RAM address
+    space distinct from the ROM that contains  the  executable  code).
+    To  use  BGET in such an environment, simply call bpool() with the
+    start address and length of the buffer  pool  area  in  RAM,  then
+    allocate  buffers  with  bget()  and  release  them  with  brel().
+    Embedded applications with very limited RAM but abundant CPU speed
+    may  benefit  by configuring BGET for BestFit allocation (which is
+    usually not worth it in other environments).
+
+    Malloc() Emulation
+    ------------------
+
+    If the C library malloc() function is too  slow,  not  present  in
+    your  development environment (for example, an a native Windows or
+    Macintosh program), or otherwise unsuitable, you  can  replace  it
+    with  BGET.  Initially define a buffer pool of an appropriate size
+    with bpool()--usually obtained by making a call to  the  operating
+    system's  low-level  memory allocator.  Then allocate buffers with
+    bget(), bgetz(), and bgetr() (the last two permit  the  allocation
+    of  buffers initialised to zero and [inefficient] re-allocation of
+    existing buffers for  compatibility  with  C  library  functions).
+    Release buffers by calling brel().  If a buffer allocation request
+    fails, obtain more storage from the underlying  operating  system,
+    add it to the buffer pool by another call to bpool(), and continue
+    execution.
+
+    Automatic Storage Management
+    ----------------------------
+
+    You can use BGET as your application's native memory  manager  and
+    implement  automatic  storage  pool  expansion,  contraction,  and
+    optionally application-specific  memory  compaction  by  compiling
+    BGET  with  the  BECtl  variable defined, then calling bectl() and
+    supplying  functions  for  storage  compaction,  acquisition,  and
+    release,  as  well as a standard pool expansion increment.  All of
+    these functions are optional (although it doesn't make much  sense
+    to  provide  a  release  function without an acquisition function,
+    does it?).  Once the call-back functions have  been  defined  with
+    bectl(),  you simply use bget() and brel() to allocate and release
+    storage as before.  You can supply an  initial  buffer  pool  with
+    bpool()  or  rely  on  automatic  allocation to acquire the entire
+    pool.  When a call on  bget()  cannot  be  satisfied,  BGET  first
+    checks  if  a compaction function has been supplied.  If so, it is
+    called (with the space required to satisfy the allocation  request
+    and a sequence number to allow the compaction routine to be called
+    successively without looping).  If the compaction function is able
+    to  free any storage (it needn't know whether the storage it freed
+    was adequate) it should return a  nonzero  value,  whereupon  BGET
+    will retry the allocation request and, if it fails again, call the
+    compaction function again with the next-higher sequence number.
+
+    If  the  compaction  function  returns zero, indicating failure to
+    free space, or no compaction function is defined, BGET next  tests
+    whether  a  non-NULL  allocation function was supplied to bectl().
+    If so, that function is called with  an  argument  indicating  how
+    many  bytes  of  additional  space are required.  This will be the
+    standard pool expansion increment supplied in the call to  bectl()
+    unless  the  original  bget()  call requested a buffer larger than
+    this; buffers larger than the standard pool block can  be  managed
+    "off  the books" by BGET in this mode.  If the allocation function
+    succeeds in obtaining the storage, it returns a pointer to the new
+    block  and  BGET  expands  the  buffer  pool;  if  it  fails,  the
+    allocation request fails and returns NULL to  the  caller.   If  a
+    non-NULL  release  function  is  supplied,  expansion blocks which
+    become totally empty are released  to  the  global  free  pool  by
+    passing their addresses to the release function.
+
+    Equipped  with  appropriate  allocation,  release,  and compaction
+    functions, BGET can be used as part of very  sophisticated  memory
+    management   strategies,  including  garbage  collection.   (Note,
+    however, that BGET is *not* a garbage  collector  by  itself,  and
+    that  developing  such a system requires much additional logic and
+    careful design of the application's memory allocation strategy.)
+
+
+    BGET FUNCTION DESCRIPTIONS
+    ==========================
+
+    Functions implemented in this file (some are enabled by certain of
+    the optional settings below):
+
+            void bpool(void *buffer, bufsize len);
+
+    Create a buffer pool of <len> bytes, using the storage starting at
+    <buffer>.   You  can  call  bpool()  subsequently  to   contribute
+    additional storage to the overall buffer pool.
+
+            void *bget(bufsize size);
+
+    Allocate  a  buffer of <size> bytes.  The address of the buffer is
+    returned, or NULL if insufficient memory was available to allocate
+    the buffer.
+
+            void *bgetz(bufsize size);
+
+    Allocate a buffer of <size> bytes and clear it to all zeroes.  The
+    address of the buffer is returned, or NULL if insufficient  memory
+    was available to allocate the buffer.
+
+            void *bgetr(void *buffer, bufsize newsize);
+
+    Reallocate a buffer previously allocated by bget(),  changing  its
+    size  to  <newsize>  and  preserving  all  existing data.  NULL is
+    returned if insufficient memory is  available  to  reallocate  the
+    buffer, in which case the original buffer remains intact.
+
+            void brel(void *buf);
+
+    Return  the  buffer  <buf>, previously allocated by bget(), to the
+    free space pool.
+
+            void bectl(int (*compact)(bufsize sizereq, int sequence),
+                       void *(*acquire)(bufsize size),
+                       void (*release)(void *buf),
+                       bufsize pool_incr);
+
+    Expansion control: specify functions through which the package may
+    compact  storage  (or  take  other  appropriate  action)  when  an
+    allocation  request  fails,  and  optionally automatically acquire
+    storage for expansion blocks  when  necessary,  and  release  such
+    blocks when they become empty.  If <compact> is non-NULL, whenever
+    a buffer allocation request fails, the <compact> function will  be
+    called with arguments specifying the number of bytes (total buffer
+    size,  including  header  overhead)  required   to   satisfy   the
+    allocation request, and a sequence number indicating the number of
+    consecutive  calls  on  <compact>  attempting  to   satisfy   this
+    allocation  request.   The sequence number is 1 for the first call
+    on <compact> for a given allocation  request,  and  increments  on
+    subsequent  calls,  permitting  the  <compact>  function  to  take
+    increasingly dire measures in an attempt to free up  storage.   If
+    the  <compact>  function  returns  a nonzero value, the allocation
+    attempt is re-tried.  If <compact> returns 0 (as  it  must  if  it
+    isn't  able  to  release  any  space  or add storage to the buffer
+    pool), the allocation request fails, which can  trigger  automatic
+    pool expansion if the <acquire> argument is non-NULL.  At the time
+    the  <compact>  function  is  called,  the  state  of  the  buffer
+    allocator  is  identical  to  that  at  the  moment the allocation
+    request was made; consequently, the <compact>  function  may  call
+    brel(), bpool(), bstats(), and/or directly manipulate  the  buffer
+    pool  in  any  manner which would be valid were the application in
+    control.  This does not, however, relieve the  <compact>  function
+    of the need to ensure that whatever actions it takes do not change
+    things   underneath  the  application  that  made  the  allocation
+    request.  For example, a <compact> function that released a buffer
+    in  the  process  of  being reallocated with bgetr() would lead to
+    disaster.  Implementing a safe and effective  <compact>  mechanism
+    requires  careful  design of an application's memory architecture,
+    and cannot generally be easily retrofitted into existing code.
+
+    If <acquire> is non-NULL, that function will be called whenever an
+    allocation  request  fails.  If the <acquire> function succeeds in
+    allocating the requested space and returns a pointer  to  the  new
+    area,  allocation will proceed using the expanded buffer pool.  If
+    <acquire> cannot obtain the requested space, it should return NULL
+    and   the   entire  allocation  process  will  fail.   <pool_incr>
+    specifies the normal expansion block size.  Providing an <acquire>
+    function will cause subsequent bget()  requests  for  buffers  too
+    large  to  be  managed in the linked-block scheme (in other words,
+    larger than <pool_incr> minus the buffer overhead) to be satisfied
+    directly by calls to the <acquire> function.  Automatic release of
+    empty pool blocks will occur only if all pool blocks in the system
+    are the size given by <pool_incr>.
+
+            void bstats(bufsize *curalloc, bufsize *totfree,
+                        bufsize *maxfree, unsigned long *nget, unsigned long *nrel);
+
+    The amount  of  space  currently  allocated  is  stored  into  the
+    variable  pointed  to by <curalloc>.  The total free space (sum of
+    all free blocks in the pool) is stored into the  variable  pointed
+    to  by  <totfree>, and the size of the largest single block in the
+    free space  pool  is  stored  into  the  variable  pointed  to  by
+    <maxfree>.   The  variables  pointed  to  by <nget> and <nrel> are
+    filled, respectively, with  the  number  of  successful  (non-NULL
+    return) bget() calls and the number of brel() calls.
+
+            void bstatse(bufsize *pool_incr, unsigned long *npool,
+                         unsigned long *npget, unsigned long *nprel,
+                         unsigned long *ndget, unsigned long *ndrel);
+
+    Extended  statistics: The expansion block size will be stored into
+    the variable pointed to by <pool_incr>, or the negative thereof if
+    automatic  expansion  block  releases are disabled.  The number of
+    currently active pool blocks will  be  stored  into  the  variable
+    pointed  to  by  <npool>.  The variables pointed to by <npget> and
+    <nprel> will be filled with, respectively, the number of expansion
+    block   acquisitions   and  releases  which  have  occurred.   The
+    variables pointed to by <ndget> and <ndrel> will  be  filled  with
+    the  number  of  bget()  and  brel()  calls, respectively, managed
+    through blocks directly allocated by the acquisition  and  release
+    functions.
+
+            void bufdump(void *buf);
+
+    The buffer pointed to by <buf> is dumped on standard output.
+
+            void bpoold(void *pool, int dumpalloc, int dumpfree);
+
+    All buffers in the buffer pool <pool>, previously initialised by a
+    call on bpool(), are listed in ascending memory address order.  If
+    <dumpalloc> is nonzero, the  contents  of  allocated  buffers  are
+    dumped;  if <dumpfree> is nonzero, the contents of free blocks are
+    dumped.
+
+            int bpoolv(void *pool);
+
+    The  named  buffer  pool,  previously  initialised  by  a  call on
+    bpool(), is validated for bad pointers, overwritten data, etc.  If
+    compiled with NDEBUG not defined, any error generates an assertion
+    failure.  Otherwise 1 is returned if the pool is valid,  0  if  an
+    error is found.
+
+
+    BGET CONFIGURATION
+    ==================
+*/
+
+#if 0
+#define TestProg    20000             /* Generate built-in test program
+                                         if defined.  The value specifies
+                                         how many buffer allocation attempts
+                                         the test program should make. */
+#endif
+
+#define SizeQuant   8                 /* Buffer allocation size quantum:
+                                         all buffers allocated are a
+                                         multiple of this size.  This
+                                         MUST be a power of two. */
+#if 0
+#define BufDump     1                 /* Define this symbol to enable the
+                                         bpoold() function which dumps the
+                                         buffers in a buffer pool. */
+#endif
+
+#if 0
+#define BufValid    1                 /* Define this symbol to enable the
+                                         bpoolv() function for validating
+                                         a buffer pool. */ 
+#endif
+
+#if 0
+#define DumpData    1                 /* Define this symbol to enable the
+                                         bufdump() function which allows
+                                         dumping the contents of an allocated
+                                         or free buffer. */
+#endif
+
+#if 1
+#define BufStats    1                 /* Define this symbol to enable the
+                                         bstats() function which calculates
+                                         the total free space in the buffer
+                                         pool, the largest available
+                                         buffer, and the total space
+                                         currently allocated. */
+#endif
+
+#if 0
+#define FreeWipe    1                 /* Wipe free buffers to a guaranteed
+                                         pattern of garbage to trip up
+                                         miscreants who attempt to use
+                                         pointers into released buffers. */
+#endif
+
+#if 1
+#define BestFit     1                 /* Use a best fit algorithm when
+                                         searching for space for an
+                                         allocation request.  This uses
+                                         memory more efficiently, but
+                                         allocation will be much slower. */
+#endif
+
+#if 0
+#define BECtl       1                 /* Define this symbol to enable the
+                                         bectl() function for automatic
+                                         pool space control.  */
+#endif
+
+#include <stdio.h>
+
+#ifdef lint
+#define NDEBUG                        /* Exits in asserts confuse lint */
+/* LINTLIBRARY */                     /* Don't complain about def, no ref */
+extern char *sprintf();               /* Sun includes don't define sprintf */
+#endif
+
+//#include <assert.h>
+#include <string.h>
+
+#ifdef BufDump                        /* BufDump implies DumpData */
+#ifndef DumpData
+#define DumpData    1
+#endif
+#endif
+
+#ifdef DumpData
+#include <ctype.h>
+#endif
+
+/*  Declare the interface, including the requested buffer size type,
+    bufsize.  */
+
+#include "bget.h"
+
+#define MemSize     int               /* Type for size arguments to memxxx()
+                                         functions such as memcmp(). */
+
+/* Queue links */
+
+struct qlinks {
+    struct bfhead *flink;             /* Forward link */
+    struct bfhead *blink;             /* Backward link */
+};
+
+/* Header in allocated and free buffers */
+
+struct bhead {
+    bufsize prevfree;                 /* Relative link back to previous
+                                         free buffer in memory or 0 if
+                                         previous buffer is allocated.  */
+    bufsize bsize;                    /* Buffer size: positive if free,
+                                         negative if allocated. */
+};
+#define BH(p)   ((struct bhead *) (p))
+
+/*  Header in directly allocated buffers (by acqfcn) */
+
+struct bdhead {
+    bufsize tsize;                    /* Total size, including overhead */
+    struct bhead bh;                  /* Common header */
+};
+#define BDH(p)  ((struct bdhead *) (p))
+
+/* Header in free buffers */
+
+struct bfhead {
+    struct bhead bh;                  /* Common allocated/free header */
+    struct qlinks ql;                 /* Links on free list */
+};
+#define BFH(p)  ((struct bfhead *) (p))
+
+static struct bfhead freelist = {     /* List of free buffers */
+    {0, 0},
+    {&freelist, &freelist}
+};
+
+
+#ifdef BufStats
+static bufsize totalloc = 0;          /* Total space currently allocated */
+static bufsize maxalloc = 0;
+static unsigned long numget = 0, numrel = 0;   /* Number of bget() and brel() calls */
+#ifdef BECtl
+static long numpblk = 0;              /* Number of pool blocks */
+static unsigned long numpget = 0, numprel = 0; /* Number of block gets and rels */
+static unsigned long numdget = 0, numdrel = 0; /* Number of direct gets and rels */
+#endif /* BECtl */
+#endif /* BufStats */
+
+#ifdef BECtl
+
+/* Automatic expansion block management functions */
+
+static int (*compfcn) _((bufsize sizereq, int sequence)) = NULL;
+static void *(*acqfcn) _((bufsize size)) = NULL;
+static void (*relfcn) _((void *buf)) = NULL;
+
+static bufsize exp_incr = 0;          /* Expansion block size */
+static bufsize pool_len = 0;          /* 0: no bpool calls have been made
+                                         -1: not all pool blocks are
+                                             the same size
+                                         >0: (common) block size for all
+                                             bpool calls made so far
+                                      */
+#endif
+
+/*  Minimum allocation quantum: */
+
+#define QLSize  (sizeof(struct qlinks))
+#define SizeQ   ((SizeQuant > QLSize) ? SizeQuant : QLSize)
+
+#define V   (void)                    /* To denote unwanted returned values */
+
+/* End sentinel: value placed in bsize field of dummy block delimiting
+   end of pool block.  The most negative number which will  fit  in  a
+   bufsize, defined in a way that the compiler will accept. */
+
+#define ESent   ((bufsize) (-(((1L << (sizeof(bufsize) * 8 - 2)) - 1) * 2) - 2))
+#define assert(x)
+/*  BGET  --  Allocate a buffer.  */
+
+void *bget(bufsize requested_size)
+{
+    bufsize size = requested_size;
+    struct bfhead *b;
+#ifdef BestFit
+    struct bfhead *best;
+#endif
+    void *buf;
+#ifdef BECtl
+    int compactseq = 0;
+#endif
+
+    assert(size >= 0);
+    if (!size)
+    {
+    	return NULL;
+    }
+
+    if (size < (bufsize)SizeQ) {              /* Need at least room for the */
+        size = SizeQ;                 /*    queue links.  */
+    }
+#ifdef SizeQuant
+#if SizeQuant > 1
+    size = (size + (SizeQuant - 1)) & (~(SizeQuant - 1));
+#endif
+#endif
+
+    size += sizeof(struct bhead);     /* Add overhead in allocated buffer
+                                         to size required. */
+
+#ifdef BECtl
+    /* If a compact function was provided in the call to bectl(), wrap
+       a loop around the allocation process  to  allow  compaction  to
+       intervene in case we don't find a suitable buffer in the chain. */
+
+    while (1) {
+#endif
+        b = freelist.ql.flink;
+#ifdef BestFit
+        best = &freelist;
+#endif
+
+
+        /* Scan the free list searching for the first buffer big enough
+           to hold the requested size buffer. */
+
+#ifdef BestFit
+        while (b != &freelist) {
+            if (b->bh.bsize >= size) {
+                if ((best == &freelist) || (b->bh.bsize < best->bh.bsize)) {
+                    best = b;
+                }
+            }
+            b = b->ql.flink;              /* Link to next buffer */
+        }
+        b = best;
+#endif /* BestFit */
+
+        while (b != &freelist) {
+            if ((bufsize) b->bh.bsize >= size) {
+
+                /* Buffer  is big enough to satisfy  the request.  Allocate it
+                   to the caller.  We must decide whether the buffer is  large
+                   enough  to  split  into  the part given to the caller and a
+                   free buffer that remains on the free list, or  whether  the
+                   entire  buffer  should  be  removed  from the free list and
+                   given to the caller in its entirety.   We  only  split  the
+                   buffer if enough room remains for a header plus the minimum
+                   quantum of allocation. */
+
+                if ((b->bh.bsize - size) > (bufsize)(SizeQ + (sizeof(struct bhead)))) {
+                    struct bhead *ba, *bn;
+
+                    ba = BH(((char *) b) + (b->bh.bsize - size));
+                    bn = BH(((char *) ba) + size);
+                    assert(bn->prevfree == b->bh.bsize);
+                    /* Subtract size from length of free block. */
+                    b->bh.bsize -= size;
+                    /* Link allocated buffer to the previous free buffer. */
+                    ba->prevfree = b->bh.bsize;
+                    /* Plug negative size into user buffer. */
+                    ba->bsize = -(bufsize) size;
+                    /* Mark buffer after this one not preceded by free block. */
+                    bn->prevfree = 0;
+
+#ifdef BufStats
+                    totalloc += size;
+                    if (totalloc > maxalloc)
+                    {
+                    	maxalloc = totalloc;
+                    }
+                    numget++;             /* Increment number of bget() calls */
+#endif
+                    buf = (void *) ((((char *) ba) + sizeof(struct bhead)));
+                    return buf;
+                } else {
+                    struct bhead *ba;
+
+                    ba = BH(((char *) b) + b->bh.bsize);
+                    assert(ba->prevfree == b->bh.bsize);
+
+                    /* The buffer isn't big enough to split.  Give  the  whole
+                       shebang to the caller and remove it from the free list. */
+
+                    assert(b->ql.blink->ql.flink == b);
+                    assert(b->ql.flink->ql.blink == b);
+                    b->ql.blink->ql.flink = b->ql.flink;
+                    b->ql.flink->ql.blink = b->ql.blink;
+
+#ifdef BufStats
+                    totalloc += b->bh.bsize;
+                    if (totalloc > maxalloc)
+                    {
+                    	maxalloc = totalloc;
+                    }
+                    numget++;             /* Increment number of bget() calls */
+#endif
+                    /* Negate size to mark buffer allocated. */
+                    b->bh.bsize = -(b->bh.bsize);
+
+                    /* Zero the back pointer in the next buffer in memory
+                       to indicate that this buffer is allocated. */
+                    ba->prevfree = 0;
+
+                    /* Give user buffer starting at queue links. */
+                    buf =  (void *) &(b->ql);
+                    return buf;
+                }
+            }
+            b = b->ql.flink;              /* Link to next buffer */
+        }
+#ifdef BECtl
+
+        /* We failed to find a buffer.  If there's a compact  function
+           defined,  notify  it  of the size requested.  If it returns
+           TRUE, try the allocation again. */
+
+        if ((compfcn == NULL) || (!(*compfcn)(size, ++compactseq))) {
+            break;
+        }
+    }
+
+    /* No buffer available with requested size free. */
+
+    /* Don't give up yet -- look in the reserve supply. */
+
+    if (acqfcn != NULL) {
+        if (size > exp_incr - sizeof(struct bhead)) {
+
+            /* Request  is  too  large  to  fit in a single expansion
+               block.  Try to satisy it by a direct buffer acquisition. */
+
+            struct bdhead *bdh;
+
+            size += sizeof(struct bdhead) - sizeof(struct bhead);
+            if ((bdh = BDH((*acqfcn)((bufsize) size))) != NULL) {
+
+                /*  Mark the buffer special by setting the size field
+                    of its header to zero.  */
+                bdh->bh.bsize = 0;
+                bdh->bh.prevfree = 0;
+                bdh->tsize = size;
+#ifdef BufStats
+                totalloc += size;
+                numget++;             /* Increment number of bget() calls */
+                numdget++;            /* Direct bget() call count */
+#endif
+                buf =  (void *) (bdh + 1);
+                return buf;
+            }
+
+        } else {
+
+            /*  Try to obtain a new expansion block */
+
+            void *newpool;
+
+            if ((newpool = (*acqfcn)((bufsize) exp_incr)) != NULL) {
+                bpool(newpool, exp_incr);
+                buf =  bget(requested_size);  /* This can't, I say, can't
+                                                 get into a loop. */
+                return buf;
+            }
+        }
+    }
+
+    /*  Still no buffer available */
+
+#endif /* BECtl */
+
+    return NULL;
+}
+
+/*  BGETZ  --  Allocate a buffer and clear its contents to zero.  We clear
+               the  entire  contents  of  the buffer to zero, not just the
+               region requested by the caller. */
+
+void *bgetz(bufsize size)
+{
+    char *buf = (char *) bget(size);
+
+    if (buf != NULL) {
+        struct bhead *b;
+        bufsize rsize;
+
+        b = BH(buf - sizeof(struct bhead));
+        rsize = -(b->bsize);
+        if (rsize == 0) {
+            struct bdhead *bd;
+
+            bd = BDH(buf - sizeof(struct bdhead));
+            rsize = bd->tsize - sizeof(struct bdhead);
+        } else {
+            rsize -= sizeof(struct bhead);
+        }
+        assert(rsize >= size);
+        memset(buf, 0, (MemSize) rsize);
+    }
+    return ((void *) buf);
+}
+
+/*  BGETR  --  Reallocate a buffer.  This is a minimal implementation,
+               simply in terms of brel()  and  bget().   It  could  be
+               enhanced to allow the buffer to grow into adjacent free
+               blocks and to avoid moving data unnecessarily.  */
+
+void *bgetr(void *buf, bufsize size)
+{
+    void *nbuf;
+    bufsize osize;                    /* Old size of buffer */
+    struct bhead *b;
+
+    if ((nbuf = bget(size)) == NULL) { /* Acquire new buffer */
+        return NULL;
+    }
+    if (buf == NULL) {
+        return nbuf;
+    }
+    b = BH(((char *) buf) - sizeof(struct bhead));
+    osize = -b->bsize;
+#ifdef BECtl
+    if (osize == 0) {
+        /*  Buffer acquired directly through acqfcn. */
+        struct bdhead *bd;
+
+        bd = BDH(((char *) buf) - sizeof(struct bdhead));
+        osize = bd->tsize - sizeof(struct bdhead);
+    } else
+#endif
+        osize -= sizeof(struct bhead);
+    assert(osize > 0);
+    V memcpy((char *) nbuf, (char *) buf, /* Copy the data */
+             (MemSize) ((size < osize) ? size : osize));
+    brel(buf);
+    return nbuf;
+}
+
+/*  BREL  --  Release a buffer.  */
+
+void brel(void *buf)
+{
+    struct bfhead *b, *bn;
+
+    b = BFH(((char *) buf) - sizeof(struct bhead));
+#ifdef BufStats
+    numrel++;                         /* Increment number of brel() calls */
+#endif
+    assert(buf != NULL);
+    if (!buf)
+    {
+    	return;
+    }
+#ifdef BECtl
+    if (b->bh.bsize == 0) {           /* Directly-acquired buffer? */
+        struct bdhead *bdh;
+
+        bdh = BDH(((char *) buf) - sizeof(struct bdhead));
+        assert(b->bh.prevfree == 0);
+#ifdef BufStats
+        totalloc -= bdh->tsize;
+        assert(totalloc >= 0);
+        numdrel++;                    /* Number of direct releases */
+#endif /* BufStats */
+#ifdef FreeWipe
+        V memset((char *) buf, 0x55,
+                 (MemSize) (bdh->tsize - sizeof(struct bdhead)));
+#endif /* FreeWipe */
+        assert(relfcn != NULL);
+        (*relfcn)((void *) bdh);      /* Release it directly. */
+        return;
+    }
+#endif /* BECtl */
+
+    /* Buffer size must be negative, indicating that the buffer is
+       allocated. */
+
+    if (b->bh.bsize >= 0) {
+        bn = NULL;
+    }
+    assert(b->bh.bsize < 0);
+
+    /*  Back pointer in next buffer must be zero, indicating the
+        same thing: */
+
+    assert(BH((char *) b - b->bh.bsize)->prevfree == 0);
+
+#ifdef BufStats
+    totalloc += b->bh.bsize;
+    assert(totalloc >= 0);
+#endif
+
+    /* If the back link is nonzero, the previous buffer is free.  */
+
+    if (b->bh.prevfree != 0) {
+
+        /* The previous buffer is free.  Consolidate this buffer  with  it
+           by  adding  the  length  of  this  buffer  to the previous free
+           buffer.  Note that we subtract the size  in  the  buffer  being
+           released,  since  it's  negative to indicate that the buffer is
+           allocated. */
+
+        register bufsize size = b->bh.bsize;
+
+        /* Make the previous buffer the one we're working on. */
+        assert(BH((char *) b - b->bh.prevfree)->bsize == b->bh.prevfree);
+        b = BFH(((char *) b) - b->bh.prevfree);
+        b->bh.bsize -= size;
+    } else {
+
+        /* The previous buffer isn't allocated.  Insert this buffer
+           on the free list as an isolated free block. */
+
+        assert(freelist.ql.blink->ql.flink == &freelist);
+        assert(freelist.ql.flink->ql.blink == &freelist);
+        b->ql.flink = &freelist;
+        b->ql.blink = freelist.ql.blink;
+        freelist.ql.blink = b;
+        b->ql.blink->ql.flink = b;
+        b->bh.bsize = -b->bh.bsize;
+    }
+
+    /* Now we look at the next buffer in memory, located by advancing from
+       the  start  of  this  buffer  by its size, to see if that buffer is
+       free.  If it is, we combine  this  buffer  with  the  next  one  in
+       memory, dechaining the second buffer from the free list. */
+
+    bn =  BFH(((char *) b) + b->bh.bsize);
+    if (bn->bh.bsize > 0) {
+
+        /* The buffer is free.  Remove it from the free list and add
+           its size to that of our buffer. */
+
+        assert(BH((char *) bn + bn->bh.bsize)->prevfree == bn->bh.bsize);
+        assert(bn->ql.blink->ql.flink == bn);
+        assert(bn->ql.flink->ql.blink == bn);
+        bn->ql.blink->ql.flink = bn->ql.flink;
+        bn->ql.flink->ql.blink = bn->ql.blink;
+        b->bh.bsize += bn->bh.bsize;
+
+        /* Finally,  advance  to   the  buffer  that   follows  the  newly
+           consolidated free block.  We must set its  backpointer  to  the
+           head  of  the  consolidated free block.  We know the next block
+           must be an allocated block because the process of recombination
+           guarantees  that  two  free  blocks will never be contiguous in
+           memory.  */
+
+        bn = BFH(((char *) b) + b->bh.bsize);
+    }
+#ifdef FreeWipe
+    V memset(((char *) b) + sizeof(struct bfhead), 0x55,
+            (MemSize) (b->bh.bsize - sizeof(struct bfhead)));
+#endif
+    assert(bn->bh.bsize < 0);
+
+    /* The next buffer is allocated.  Set the backpointer in it  to  point
+       to this buffer; the previous free buffer in memory. */
+
+    bn->bh.prevfree = b->bh.bsize;
+
+#ifdef BECtl
+
+    /*  If  a  block-release function is defined, and this free buffer
+        constitutes the entire block, release it.  Note that  pool_len
+        is  defined  in  such a way that the test will fail unless all
+        pool blocks are the same size.  */
+
+    if (relfcn != NULL &&
+        ((bufsize) b->bh.bsize) == (pool_len - sizeof(struct bhead))) {
+
+        assert(b->bh.prevfree == 0);
+        assert(BH((char *) b + b->bh.bsize)->bsize == ESent);
+        assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize);
+        /*  Unlink the buffer from the free list  */
+        b->ql.blink->ql.flink = b->ql.flink;
+        b->ql.flink->ql.blink = b->ql.blink;
+
+        (*relfcn)(b);
+#ifdef BufStats
+        numprel++;                    /* Nr of expansion block releases */
+        numpblk--;                    /* Total number of blocks */
+        assert(numpblk == numpget - numprel);
+#endif /* BufStats */
+    }
+#endif /* BECtl */
+}
+
+#ifdef BECtl
+
+/*  BECTL  --  Establish automatic pool expansion control  */
+
+void bectl(int (*compact) _((bufsize sizereq, int sequence)), void *(*acquire) _((bufsize size)), void (*release) _((void *buf)), bufsize pool_incr)
+{
+    compfcn = compact;
+    acqfcn = acquire;
+    relfcn = release;
+    exp_incr = pool_incr;
+}
+#endif
+
+/*  BPOOL  --  Add a region of memory to the buffer pool.  */
+
+void bpool(void *buf, bufsize len)
+{
+    struct bfhead *b = BFH(buf);
+    struct bhead *bn;
+
+#ifdef SizeQuant
+    len &= ~(SizeQuant - 1);
+#endif
+#ifdef BECtl
+    if (pool_len == 0) {
+        pool_len = len;
+    } else if (len != pool_len) {
+        pool_len = -1;
+    }
+#ifdef BufStats
+    numpget++;                        /* Number of block acquisitions */
+    numpblk++;                        /* Number of blocks total */
+    assert(numpblk == numpget - numprel);
+#endif /* BufStats */
+#endif /* BECtl */
+
+    /* Since the block is initially occupied by a single free  buffer,
+       it  had  better  not  be  (much) larger than the largest buffer
+       whose size we can store in bhead.bsize. */
+
+    assert(len - sizeof(struct bhead) <= -((bufsize) ESent + 1));
+
+    /* Clear  the  backpointer at  the start of the block to indicate that
+       there  is  no  free  block  prior  to  this   one.    That   blocks
+       recombination when the first block in memory is released. */
+
+    b->bh.prevfree = 0;
+
+    /* Chain the new block to the free list. */
+
+    assert(freelist.ql.blink->ql.flink == &freelist);
+    assert(freelist.ql.flink->ql.blink == &freelist);
+    b->ql.flink = &freelist;
+    b->ql.blink = freelist.ql.blink;
+    freelist.ql.blink = b;
+    b->ql.blink->ql.flink = b;
+
+    /* Create a dummy allocated buffer at the end of the pool.  This dummy
+       buffer is seen when a buffer at the end of the pool is released and
+       blocks  recombination  of  the last buffer with the dummy buffer at
+       the end.  The length in the dummy buffer  is  set  to  the  largest
+       negative  number  to  denote  the  end  of  the pool for diagnostic
+       routines (this specific value is  not  counted  on  by  the  actual
+       allocation and release functions). */
+
+    len -= sizeof(struct bhead);
+    b->bh.bsize = (bufsize) len;
+#ifdef FreeWipe
+    V memset(((char *) b) + sizeof(struct bfhead), 0x55,
+             (MemSize) (len - sizeof(struct bfhead)));
+#endif
+    bn = BH(((char *) b) + len);
+    bn->prevfree = (bufsize) len;
+    /* Definition of ESent assumes two's complement! */
+    assert((~0) == -1);
+    bn->bsize = ESent;
+}
+
+#ifdef BufStats
+
+/*  BSTATS  --  Return buffer allocation free space statistics.  */
+
+void bstats(bufsize *curalloc, bufsize *totfree, bufsize *maxfree, unsigned long *nget, unsigned long *nrel)
+{
+    struct bfhead *b = freelist.ql.flink;
+
+    *nget = numget;
+    *nrel = numrel;
+    *curalloc = totalloc;
+    *totfree = 0;
+    *maxfree = -1;
+    while (b != &freelist) {
+        assert(b->bh.bsize > 0);
+        *totfree += b->bh.bsize;
+        if (b->bh.bsize > *maxfree) {
+            *maxfree = b->bh.bsize;
+        }
+        b = b->ql.flink;              /* Link to next buffer */
+    }
+}
+
+bufsize bstatsmaxget(void)
+{
+	return maxalloc;
+}
+#ifdef BECtl
+
+/*  BSTATSE  --  Return extended statistics  */
+
+void bstatse(bufsize *pool_incr, long *npool, unsigned long *npget, unsigned long *nprel, unsigned long * ndget, unsigned long *ndrel)
+{
+    *pool_incr = (pool_len < 0) ? -exp_incr : exp_incr;
+    *npool = numpblk;
+    *npget = numpget;
+    *nprel = numprel;
+    *ndget = numdget;
+    *ndrel = numdrel;
+}
+#endif /* BECtl */
+#endif /* BufStats */
+
+#ifdef DumpData
+
+/*  BUFDUMP  --  Dump the data in a buffer.  This is called with the  user
+                 data pointer, and backs up to the buffer header.  It will
+                 dump either a free block or an allocated one.  */
+
+void bufdump(buf)
+  void *buf;
+{
+    struct bfhead *b;
+    unsigned char *bdump;
+    bufsize bdlen;
+
+    b = BFH(((char *) buf) - sizeof(struct bhead));
+    assert(b->bh.bsize != 0);
+    if (b->bh.bsize < 0) {
+        bdump = (unsigned char *) buf;
+        bdlen = (-b->bh.bsize) - sizeof(struct bhead);
+    } else {
+        bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead));
+        bdlen = b->bh.bsize - sizeof(struct bfhead);
+    }
+
+    while (bdlen > 0) {
+        int i, dupes = 0;
+        bufsize l = bdlen;
+        char bhex[50], bascii[20];
+
+        if (l > 16) {
+            l = 16;
+        }
+
+        for (i = 0; i < l; i++) {
+            V sprintf(bhex + i * 3, "%02X ", bdump[i]);
+            bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
+        }
+        bascii[i] = 0;
+        V printf("%-48s   %s\n", bhex, bascii);
+        bdump += l;
+        bdlen -= l;
+        while ((bdlen > 16) && (memcmp((char *) (bdump - 16),
+                                       (char *) bdump, 16) == 0)) {
+            dupes++;
+            bdump += 16;
+            bdlen -= 16;
+        }
+        if (dupes > 1) {
+            V printf(
+                "     (%d lines [%d bytes] identical to above line skipped)\n",
+                dupes, dupes * 16);
+        } else if (dupes == 1) {
+            bdump -= 16;
+            bdlen += 16;
+        }
+    }
+}
+#endif
+
+#ifdef BufDump
+
+/*  BPOOLD  --  Dump a buffer pool.  The buffer headers are always listed.
+                If DUMPALLOC is nonzero, the contents of allocated buffers
+                are  dumped.   If  DUMPFREE  is  nonzero,  free blocks are
+                dumped as well.  If FreeWipe  checking  is  enabled,  free
+                blocks  which  have  been clobbered will always be dumped. */
+
+void bpoold(void *buf, int dumpalloc, int dumpfree)
+{
+    struct bfhead *b = BFH(buf);
+
+    while (b->bh.bsize != ESent) {
+        bufsize bs = b->bh.bsize;
+
+        if (bs < 0) {
+            bs = -bs;
+            V printf("Allocated buffer: size %6ld bytes.\n", (unsigned long) bs);
+            if (dumpalloc) {
+                bufdump((void *) (((char *) b) + sizeof(struct bhead)));
+            }
+        } else {
+            char *lerr = "";
+
+            assert(bs > 0);
+            if ((b->ql.blink->ql.flink != b) ||
+                (b->ql.flink->ql.blink != b)) {
+                lerr = "  (Bad free list links)";
+            }
+            V printf("Free block:       size %6ld bytes.%s\n",
+                (unsigned long) bs, lerr);
+#ifdef FreeWipe
+            lerr = ((char *) b) + sizeof(struct bfhead);
+            if ((bs > sizeof(struct bfhead)) && ((*lerr != 0x55) ||
+                (memcmp(lerr, lerr + 1,
+                  (MemSize) (bs - (sizeof(struct bfhead) + 1))) != 0))) {
+                V printf(
+                    "(Contents of above free block have been overstored.)\n");
+                bufdump((void *) (((char *) b) + sizeof(struct bhead)));
+            } else
+#endif
+            if (dumpfree) {
+                bufdump((void *) (((char *) b) + sizeof(struct bhead)));
+            }
+        }
+        b = BFH(((char *) b) + bs);
+    }
+}
+#endif /* BufDump */
+
+#ifdef BufValid
+
+/*  BPOOLV  --  Validate a buffer pool.  If NDEBUG isn't defined,
+                any error generates an assertion failure.  */
+
+int bpoolv(void *buf)
+{
+    struct bfhead *b = BFH(buf);
+
+    while (b->bh.bsize != ESent) {
+        bufsize bs = b->bh.bsize;
+
+        if (bs < 0) {
+            bs = -bs;
+        } else {
+            char *lerr = "";
+
+            assert(bs > 0);
+            if (bs <= 0) {
+                return 0;
+            }
+            if ((b->ql.blink->ql.flink != b) ||
+                (b->ql.flink->ql.blink != b)) {
+                V printf("Free block: size %6ld bytes.  (Bad free list links)\n",
+                     (unsigned long) bs);
+                assert(0);
+                return 0;
+            }
+#ifdef FreeWipe
+            lerr = ((char *) b) + sizeof(struct bfhead);
+            if ((bs > sizeof(struct bfhead)) && ((*lerr != 0x55) ||
+                (memcmp(lerr, lerr + 1,
+                  (MemSize) (bs - (sizeof(struct bfhead) + 1))) != 0))) {
+                V printf(
+                    "(Contents of above free block have been overstored.)\n");
+                bufdump((void *) (((char *) b) + sizeof(struct bhead)));
+                assert(0);
+                return 0;
+            }
+#endif
+        }
+        b = BFH(((char *) b) + bs);
+    }
+    return 1;
+}
+#endif /* BufValid */
+
+        /***********************\
+        *                       *
+        * Built-in test program *
+        *                       *
+        \***********************/
+
+#ifdef TestProg
+
+#define Repeatable  1                 /* Repeatable pseudorandom sequence */
+                                      /* If Repeatable is not defined, a
+                                         time-seeded pseudorandom sequence
+                                         is generated, exercising BGET with
+                                         a different pattern of calls on each
+                                         run. */
+#define OUR_RAND                      /* Use our own built-in version of
+                                         rand() to guarantee the test is
+                                         100% repeatable. */
+
+#ifdef BECtl
+#define PoolSize    300000            /* Test buffer pool size */
+#else
+#define PoolSize    50000             /* Test buffer pool size */
+#endif
+#define ExpIncr     32768             /* Test expansion block size */
+#define CompactTries 10               /* Maximum tries at compacting */
+
+#define dumpAlloc   0                 /* Dump allocated buffers ? */
+#define dumpFree    0                 /* Dump free buffers ? */
+
+#ifndef Repeatable
+extern unsigned long time();
+#endif
+
+extern char *malloc();
+extern int free _((char *));
+
+static char *bchain = NULL;           /* Our private buffer chain */
+static char *bp = NULL;               /* Our initial buffer pool */
+
+#include <math.h>
+
+#ifdef OUR_RAND
+
+static unsigned long int next = 1;
+
+/* Return next random integer */
+
+int rand()
+{
+        next = next * 1103515245L + 12345;
+        return (unsigned int) (next / 65536L) % 32768L;
+}
+
+/* Set seed for random generator */
+
+void srand(unsigned int seed)
+{
+        next = seed;
+}
+#endif
+
+/*  STATS  --  Edit statistics returned by bstats() or bstatse().  */
+
+static void stats(char *when)
+{
+    bufsize cural, totfree, maxfree;
+    unsigned long nget, nfree;
+#ifdef BECtl
+    bufsize pincr;
+    long totblocks;
+    unsigned npget, nprel, ndget, ndrel;
+#endif
+
+    bstats(&cural, &totfree, &maxfree, &nget, &nfree);
+    V printf(
+        "%s: %ld gets, %ld releases.  %ld in use, %ld free, largest = %ld\n",
+        when, nget, nfree, (unsigned long) cural, (unsigned long) totfree, (unsigned long) maxfree);
+#ifdef BECtl
+    bstatse(&pincr, &totblocks, &npget, &nprel, &ndget, &ndrel);
+    V printf(
+         "  Blocks: size = %ld, %ld (%ld bytes) in use, %ld gets, %ld frees\n",
+         (long)pincr, totblocks, pincr * totblocks, npget, nprel);
+    V printf("  %ld direct gets, %ld direct frees\n", ndget, ndrel);
+#endif /* BECtl */
+}
+
+#ifdef BECtl
+static int protect = 0;               /* Disable compaction during bgetr() */
+
+/*  BCOMPACT  --  Compaction call-back function.  */
+
+static int bcompact(bufsize bsize, int seq)
+{
+#ifdef CompactTries
+    char *bc = bchain;
+    int i = rand() & 0x3;
+
+#ifdef COMPACTRACE
+    V printf("Compaction requested.  %ld bytes needed, sequence %d.\n",
+        (long) bsize, seq);
+#endif
+
+    if (protect || (seq > CompactTries)) {
+#ifdef COMPACTRACE
+        V printf("Compaction gave up.\n");
+#endif
+        return 0;
+    }
+
+    /* Based on a random cast, release a random buffer in the list
+       of allocated buffers. */
+
+    while (i > 0 && bc != NULL) {
+        bc = *((char **) bc);
+        i--;
+    }
+    if (bc != NULL) {
+        char *fb;
+
+        fb = *((char **) bc);
+        if (fb != NULL) {
+            *((char **) bc) = *((char **) fb);
+            brel((void *) fb);
+            return 1;
+        }
+    }
+
+#ifdef COMPACTRACE
+    V printf("Compaction bailed out.\n");
+#endif
+#endif /* CompactTries */
+    return 0;
+}
+
+/*  BEXPAND  --  Expand pool call-back function.  */
+
+static void *bexpand(bufsize size)
+{
+    void *np = NULL;
+    bufsize cural, totfree, maxfree;
+    unsigned long nget, nfree;
+
+    /* Don't expand beyond the total allocated size given by PoolSize. */
+
+    bstats(&cural, &totfree, &maxfree, &nget, &nfree);
+
+    if (cural < PoolSize) {
+        np = (void *) malloc((unsigned) size);
+    }
+#ifdef EXPTRACE
+    V printf("Expand pool by %ld -- %s.\n", (unsigned long) size,
+        np == NULL ? "failed" : "succeeded");
+#endif
+    return np;
+}
+
+/*  BSHRINK  --  Shrink buffer pool call-back function.  */
+
+static void bshrink(void *buf)
+{
+    if (((char *) buf) == bp) {
+#ifdef EXPTRACE
+        V printf("Initial pool released.\n");
+#endif
+        bp = NULL;
+    }
+#ifdef EXPTRACE
+    V printf("Shrink pool.\n");
+#endif
+    free((char *) buf);
+}
+
+#endif /* BECtl */
+
+/*  Restrict buffer requests to those large enough to contain our pointer and
+    small enough for the CPU architecture.  */
+
+static bufsize blimit(bufsize bs)
+{
+    if (bs < sizeof(char *)) {
+        bs = sizeof(char *);
+    }
+
+    /* This is written out in this ugly fashion because the
+       cool expression in sizeof(int) that auto-configured
+       to any length int befuddled some compilers. */
+
+    if (sizeof(int) == 2) {
+        if (bs > 32767) {
+            bs = 32767;
+        }
+    } else {
+        if (bs > 200000) {
+            bs = 200000;
+        }
+    }
+    return bs;
+}
+
+int main()
+{
+    int i;
+    double x;
+
+    /* Seed the random number generator.  If Repeatable is defined, we
+       always use the same seed.  Otherwise, we seed from the clock to
+       shake things up from run to run. */
+
+#ifdef Repeatable
+    V srand(1234);
+#else
+    V srand((int) time((unsigned long *) NULL));
+#endif
+
+    /*  Compute x such that pow(x, p) ranges between 1 and 4*ExpIncr as
+        p ranges from 0 to ExpIncr-1, with a concentration in the lower
+        numbers.  */
+
+    x = 4.0 * ExpIncr;
+    x = log(x);
+    x = exp(log(4.0 * ExpIncr) / (ExpIncr - 1.0));
+
+#ifdef BECtl
+    bectl(bcompact, bexpand, bshrink, (bufsize) ExpIncr);
+    bp = malloc(ExpIncr);
+    assert(bp != NULL);
+    bpool((void *) bp, (bufsize) ExpIncr);
+#else
+    bp = malloc(PoolSize);
+    assert(bp != NULL);
+    bpool((void *) bp, (bufsize) PoolSize);
+#endif
+
+    stats("Create pool");
+    V bpoolv((void *) bp);
+    bpoold((void *) bp, dumpAlloc, dumpFree);
+
+    for (i = 0; i < TestProg; i++) {
+        char *cb;
+        bufsize bs = pow(x, (double) (rand() & (ExpIncr - 1)));
+
+        assert(bs <= (((bufsize) 4) * ExpIncr));
+        bs = blimit(bs);
+        if (rand() & 0x400) {
+            cb = (char *) bgetz(bs);
+        } else {
+            cb = (char *) bget(bs);
+        }
+        if (cb == NULL) {
+#ifdef EasyOut
+            break;
+#else
+            char *bc = bchain;
+
+            if (bc != NULL) {
+                char *fb;
+
+                fb = *((char **) bc);
+                if (fb != NULL) {
+                    *((char **) bc) = *((char **) fb);
+                    brel((void *) fb);
+                }
+                continue;
+            }
+#endif
+        }
+        *((char **) cb) = (char *) bchain;
+        bchain = cb;
+
+        /* Based on a random cast, release a random buffer in the list
+           of allocated buffers. */
+
+        if ((rand() & 0x10) == 0) {
+            char *bc = bchain;
+            int i = rand() & 0x3;
+
+            while (i > 0 && bc != NULL) {
+                bc = *((char **) bc);
+                i--;
+            }
+            if (bc != NULL) {
+                char *fb;
+
+                fb = *((char **) bc);
+                if (fb != NULL) {
+                    *((char **) bc) = *((char **) fb);
+                    brel((void *) fb);
+                }
+            }
+        }
+
+        /* Based on a random cast, reallocate a random buffer in the list
+           to a random size */
+
+        if ((rand() & 0x20) == 0) {
+            char *bc = bchain;
+            int i = rand() & 0x3;
+
+            while (i > 0 && bc != NULL) {
+                bc = *((char **) bc);
+                i--;
+            }
+            if (bc != NULL) {
+                char *fb;
+
+                fb = *((char **) bc);
+                if (fb != NULL) {
+                    char *newb;
+
+                    bs = pow(x, (double) (rand() & (ExpIncr - 1)));
+                    bs = blimit(bs);
+#ifdef BECtl
+                    protect = 1;      /* Protect against compaction */
+#endif
+                    newb = (char *) bgetr((void *) fb, bs);
+#ifdef BECtl
+                    protect = 0;
+#endif
+                    if (newb != NULL) {
+                        *((char **) bc) = newb;
+                    }
+                }
+            }
+        }
+    }
+    stats("\nAfter allocation");
+    if (bp != NULL) {
+        V bpoolv((void *) bp);
+        bpoold((void *) bp, dumpAlloc, dumpFree);
+    }
+
+    while (bchain != NULL) {
+        char *buf = bchain;
+
+        bchain = *((char **) buf);
+        brel((void *) buf);
+    }
+    stats("\nAfter release");
+#ifndef BECtl
+    if (bp != NULL) {
+        V bpoolv((void *) bp);
+        bpoold((void *) bp, dumpAlloc, dumpFree);
+    }
+#endif
+
+    return 0;
+}
+#endif
+

+ 17 - 0
Third_Party/heap/bget.h

@@ -0,0 +1,17 @@
+/*
+    Interface definitions for bget.c, the memory management package.
+*/
+
+typedef long bufsize;
+void bpool(void *buffer, bufsize len);
+void *bget(bufsize size);
+void *bgetz(bufsize size);
+void *bgetr(void *buffer, bufsize newsize);
+void brel(void *buf);
+void bectl(int (*compact)(bufsize sizereq, int sequence), void *(*acquire)(bufsize size), void (*release)(void *buf), bufsize pool_incr);
+void bstats(bufsize *curalloc, bufsize *totfree, bufsize *maxfree, unsigned long  *nget, unsigned long *nrel);
+void bstatse(bufsize *pool_incr, long *npool, unsigned long *npget, unsigned long *nprel, unsigned long *ndget, unsigned long *ndrel);
+void bufdump(void *buf);
+void bpoold(void *pool, int dumpalloc, int dumpfree);
+int bpoolv(void *pool);
+bufsize bstatsmaxget(void);

+ 36 - 0
Third_Party/iconv/include/iconv.h

@@ -0,0 +1,36 @@
+/**************************************************************************
+ *              Copyright (C), AirM2M Tech. Co., Ltd.
+ *
+ * Name:    iconv.h
+ * Author:  liweiqiang
+ * Version: V0.1
+ * Date:    2013/7/15
+ *
+ * Description:
+ *          �ַ�����ת��
+ **************************************************************************/
+
+#ifndef __ICONV_H__
+#define __ICONV_H__
+
+#include "stddef.h"
+
+/* Identifier for conversion method from one codeset to another.  */
+typedef void *iconv_t;
+
+/* Allocate descriptor for code conversion from codeset FROMCODE to
+   codeset TOCODE.  */
+extern iconv_t iconv_open_ext (const char *__tocode, const char *__fromcode);
+
+/* Convert at most *INBYTESLEFT bytes from *INBUF according to the
+   code conversion algorithm specified by CD and place up to
+   *OUTBYTESLEFT bytes in buffer at *OUTBUF.  */
+extern size_t iconv_ext (iconv_t __cd, char ** __inbuf,
+		     size_t * __inbytesleft,
+		     char ** __outbuf,
+		     size_t * __outbytesleft);
+
+/* Free resources allocated for descriptor CD for code conversion.  */
+extern int iconv_close_ext (iconv_t __cd);
+
+#endif/*__ICONV_H__*/

+ 23 - 0
Third_Party/iconv/include/prv_iconv.h

@@ -0,0 +1,23 @@
+/**************************************************************************
+ *              Copyright (C), AirM2M Tech. Co., Ltd.
+ *
+ * Name:    prv_iconv.h
+ * Author:  liweiqiang
+ * Version: V0.1
+ * Date:    2013/7/15
+ *
+ * Description:
+ *          �ַ�����ת���ڲ������ļ�
+ **************************************************************************/
+
+#ifndef __PRV_ICONV_H__
+#define __PRV_ICONV_H__
+
+
+typedef size_t (*iconv_fct) (char ** __inbuf,
+                      size_t * __inbytesleft,
+                      char ** __outbuf,
+                      size_t * __outbytesleft);
+
+
+#endif/*__PRV_ICONV_H__*/

+ 100 - 0
Third_Party/iconv/src/iconv.c

@@ -0,0 +1,100 @@
+/**************************************************************************
+ *              Copyright (C), AirM2M Tech. Co., Ltd.
+ *
+ * Name:    iconv.c
+ * Author:  liweiqiang
+ * Version: V0.1
+ * Date:    2013/7/15
+ *
+ * Description:
+ *          字符编码转换
+ **************************************************************************/
+
+#include <string.h>
+#include "iconv.h"
+#include "prv_iconv.h"
+
+typedef struct builtin_iconv_map_tag
+{
+    const char      *from;
+    const char      *to;
+    const iconv_fct fct;
+}builtin_iconv_map;
+
+size_t iconv_utf8_to_utf8_ext(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
+{
+    size_t copylen;
+    size_t inlen = *inbytesleft;
+    size_t outlen = *outbytesleft;
+    size_t ret = 0;
+    if (outlen >= inlen)
+    {
+    	copylen = inlen;
+    }
+    else
+    {
+    	copylen = outlen;
+    }
+    memcpy(*_outbuf, *_inbuf, copylen);
+    *_outbuf += copylen;
+    *_inbuf += copylen;
+    *inbytesleft = inlen - copylen;
+    *outbytesleft = outlen - copylen;
+    return ret;
+}
+
+static const builtin_iconv_map iconv_map[] =
+{
+//    {"ucs2",    "gb2312",   iconv_ucs2_to_gb2312_ext},
+///*+\NEW\liweiqiang\2013.11.26\完善gb2312<->ucs2(ucs2be)编码转换*/
+//    {"ucs2be",  "gb2312",   iconv_ucs2be_to_gb2312_ext},
+//    {"gb2312",  "ucs2",     iconv_gb2312_to_ucs2_ext},
+//    {"gb2312",  "ucs2be",   iconv_gb2312_to_ucs2be_ext},
+///*-\NEW\liweiqiang\2013.11.26\完善gb2312<->ucs2(ucs2be)编码转换*/
+///*+\NEW\liweiqiang\2013.7.19\增加utf8<->ucs2,ucs2be编码转换*/
+//    {"utf8",    "ucs2",     iconv_utf8_to_ucs2_ext},
+//    {"utf8",    "ucs2be",   iconv_utf8_to_ucs2be_ext},
+//    {"ucs2",    "utf8",     iconv_ucs2_to_utf8_ext},
+//    {"ucs2be",    "utf8",     iconv_ucs2be_to_utf8_ext},
+///*-\NEW\liweiqiang\2013.7.19\增加utf8<->ucs2,ucs2be编码转换*/
+		{"UTF-8", "UTF-8", iconv_utf8_to_utf8_ext},
+};
+
+iconv_t iconv_open_ext (const char *__tocode, const char *__fromcode)
+{
+    size_t i;
+
+    for(i = 0; i < sizeof(iconv_map)/sizeof(iconv_map[0]); i++)
+    {
+        if(strcmp(iconv_map[i].from, __fromcode) == 0 &&
+            strcmp(iconv_map[i].to, __tocode) == 0)
+        {
+            return (iconv_t)&iconv_map[i];
+        }
+    }
+
+    return (iconv_t)-1;
+}
+
+size_t iconv_ext (iconv_t __cd, char ** __inbuf,
+		     size_t * __inbytesleft,
+		     char ** __outbuf,
+		     size_t * __outbytesleft)
+{
+    builtin_iconv_map *_map_cd = (builtin_iconv_map *)__cd;
+
+    if(__inbuf == NULL || *__inbuf == NULL)
+        return (size_t)-1;
+
+    if(_map_cd < &iconv_map[0] &&
+        _map_cd > &iconv_map[sizeof(iconv_map)/sizeof(iconv_map[0])])
+        return (size_t)-1;
+
+    return _map_cd->fct(__inbuf, __inbytesleft, __outbuf, __outbytesleft);
+}
+
+int iconv_close_ext (iconv_t __cd)
+{
+    return 0;
+}
+

+ 117 - 0
Third_Party/vsprintf/printf.h

@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////////////////////////////////
+// \author (c) Marco Paland (info@paland.com)
+//             2014-2019, PALANDesign Hannover, Germany
+//
+// \license The MIT License (MIT)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
+//        embedded systems with a very limited resources.
+//        Use this instead of bloated standard/newlib printf.
+//        These routines are thread safe and reentrant.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PRINTF_H_
+#define _PRINTF_H_
+
+#include <stdarg.h>
+#include <stddef.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Output a character to a custom device like UART, used by the printf() function
+ * This function is declared here only. You have to write your custom implementation somewhere
+ * \param character Character to output
+ */
+void _putchar(char character);
+
+
+/**
+ * Tiny printf implementation
+ * You have to implement _putchar if you use printf()
+ * To avoid conflicts with the regular printf() API it is overridden by macro defines
+ * and internal underscore-appended functions like printf_() are used
+ * \param format A string that specifies the format of the output
+ * \return The number of characters that are written into the array, not counting the terminating null character
+ */
+//#define printf printf_
+int printf_(const char* format, ...);
+
+
+/**
+ * Tiny sprintf implementation
+ * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!
+ * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
+ * \param format A string that specifies the format of the output
+ * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
+ */
+//#define sprintf sprintf_
+int sprintf_(char* buffer, const char* format, ...);
+
+
+/**
+ * Tiny snprintf/vsnprintf implementation
+ * \param buffer A pointer to the buffer where to store the formatted string
+ * \param count The maximum number of characters to store in the buffer, including a terminating null character
+ * \param format A string that specifies the format of the output
+ * \param va A value identifying a variable arguments list
+ * \return The number of characters that COULD have been written into the buffer, not counting the terminating
+ *         null character. A value equal or larger than count indicates truncation. Only when the returned value
+ *         is non-negative and less than count, the string has been completely written.
+ */
+//#define snprintf  snprintf_
+//#define vsnprintf vsnprintf_
+int  snprintf_(char* buffer, size_t count, const char* format, ...);
+int vsnprintf_(char* buffer, size_t count, const char* format, va_list va);
+
+
+/**
+ * Tiny vprintf implementation
+ * \param format A string that specifies the format of the output
+ * \param va A value identifying a variable arguments list
+ * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
+ */
+//#define vprintf vprintf_
+int vprintf_(const char* format, va_list va);
+
+
+/**
+ * printf with output function
+ * You may use this as dynamic alternative to printf() with its fixed _putchar() output
+ * \param out An output function which takes one character and an argument pointer
+ * \param arg An argument pointer for user data passed to output function
+ * \param format A string that specifies the format of the output
+ * \return The number of characters that are sent to the output function, not counting the terminating null character
+ */
+int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif  // _PRINTF_H_

+ 24 - 0
application/include/app_interface.h

@@ -0,0 +1,24 @@
+#ifndef __APP_INTERFACE_H__
+#define __APP_INTERFACE_H__
+#include "global_config.h"
+#include "platform_define.h"
+#include "resource_map.h"
+#include "bsp_common.h"
+#include "core_flash.h"
+#include "core_debug.h"
+#include "core_tick.h"
+#include "core_otp.h"
+#include "core_timer.h"
+#include "core_i2c.h"
+#include "core_spi.h"
+#include "core_wdt.h"
+#include "core_rtc.h"
+#include "core_hwtimer.h"
+#include "core_service.h"
+#include "core_keyboard.h"
+#include "core_dcmi.h"
+#include "core_rng.h"
+#include "core_task.h"
+#include "lfs.h"
+void FileSystem_Init(void);
+#endif

+ 141 - 0
application/include/luat_conf_bsp.h

@@ -0,0 +1,141 @@
+
+#ifndef LUAT_CONF_BSP
+#define LUAT_CONF_BSP
+
+#define LUAT_BSP_VERSION "V0002"
+
+
+#define LUAT_USE_FS_VFS 1
+#define LUAT_USE_VFS_INLINE_LIB 1
+
+
+#define LUAT_USE_UART 1
+#define LUAT_USE_GPIO 1
+#define LUAT_USE_I2C  1
+#define LUAT_USE_SPI  1
+#define LUAT_USE_ADC  1
+#define LUAT_USE_PWM  1
+#define LUAT_USE_WDT  1
+// #define LUAT_USE_PM  1
+#define LUAT_USE_MCU  1
+// #define LUAT_USE_HWTIMER  1
+#define LUAT_USE_RTC 1
+// #define LUAT_USE_SDIO 1
+#define LUAT_USE_KEYBOARD 1
+#define LUAT_USE_DAC 1
+#define LUAT_USE_OTP 1
+
+// #define LUAT_USE_CRYPTO  1
+#define LUAT_USE_CJSON  1
+#define LUAT_USE_ZBUFF  1
+#define LUAT_USE_PACK  1
+//#define LUAT_USE_GNSS  1
+#define LUAT_USE_FS  1
+#define LUAT_USE_SENSOR  1
+#define LUAT_USE_SFUD  1
+#define LUAT_USE_SFD  1
+// #define LUAT_USE_STATEM 1
+// #define LUAT_USE_COREMARK 1
+// #define LUAT_USE_FDB 1
+// #define LUAT_USE_ZLIB 
+#define LUAT_USE_CAMERA  1
+
+//----------------------------
+// 高通字体, 需配合芯片使用
+// #define LUAT_USE_GTFONT 1
+// #define LUAT_USE_GTFONT_UTF8
+
+//----------------------------
+// 高级功能, 其中shell是推荐启用, 除非你打算uart0也读数据
+#define LUAT_USE_SHELL 
+
+#define LUAT_USE_DBG
+
+//---------------------
+// UI
+#define LUAT_USE_LCD
+#define LUAT_LCD_CMD_DELAY_US 7
+#define LUAT_USE_EINK
+
+//---------------------
+// U8G2
+#define LUAT_USE_DISP 
+#define LUAT_USE_U8G2
+#define U8G2_USE_SH1106
+#define U8G2_USE_ST7567
+
+/**************FONT*****************/
+/**********U8G2&LCD FONT*************/
+// #define USE_U8G2_UNIFONT_SYMBOLS
+// #define USE_U8G2_OPPOSANSM12_CHINESE
+// #define USE_U8G2_OPPOSANSM16_CHINESE
+// #define USE_U8G2_OPPOSANSM24_CHINESE
+// #define USE_U8G2_OPPOSANSM32_CHINESE
+/**********LVGL FONT*************/
+// #define LV_FONT_OPPOSANS_M_8
+// #define LV_FONT_OPPOSANS_M_10
+
+//---------------------
+// LVGL
+#define LUAT_USE_LCD
+#define LUAT_USE_LVGL
+#define LV_DISP_DEF_REFR_PERIOD gLVFlashTime
+extern unsigned int gLVFlashTime;
+#define LUAT_LV_DEBUG 0
+#define LV_USE_LOG 1
+#define LV_MEM_CUSTOM 1
+
+#define LUAT_USE_LVGL_INDEV 1
+
+#define LUAT_USE_LVGL_ARC   //圆弧 无依赖
+#define LUAT_USE_LVGL_BAR   //进度条 无依赖
+#define LUAT_USE_LVGL_BTN   //按钮 依赖容器CONT
+#define LUAT_USE_LVGL_BTNMATRIX   //按钮矩阵 无依赖
+#define LUAT_USE_LVGL_CALENDAR   //日历 无依赖
+#define LUAT_USE_LVGL_CANVAS   //画布 依赖图片IMG
+#define LUAT_USE_LVGL_CHECKBOX   //复选框 依赖按钮BTN 标签LABEL
+#define LUAT_USE_LVGL_CHART   //图表 无依赖
+#define LUAT_USE_LVGL_CONT   //容器 无依赖
+#define LUAT_USE_LVGL_CPICKER   //颜色选择器 无依赖
+#define LUAT_USE_LVGL_DROPDOWN   //下拉列表 依赖页面PAGE 标签LABEL
+#define LUAT_USE_LVGL_GAUGE   //仪表 依赖进度条BAR 仪表(弧形刻度)LINEMETER
+#define LUAT_USE_LVGL_IMG   //图片 依赖标签LABEL
+#define LUAT_USE_LVGL_IMGBTN   //图片按钮 依赖按钮BTN
+#define LUAT_USE_LVGL_KEYBOARD   //键盘 依赖图片按钮IMGBTN
+#define LUAT_USE_LVGL_LABEL   //标签 无依赖
+#define LUAT_USE_LVGL_LED   //LED 无依赖
+#define LUAT_USE_LVGL_LINE   //线 无依赖
+#define LUAT_USE_LVGL_LIST   //列表 依赖页面PAGE 按钮BTN 标签LABEL
+#define LUAT_USE_LVGL_LINEMETER   //仪表(弧形刻度) 无依赖
+#define LUAT_USE_LVGL_OBJMASK   //对象蒙版 无依赖
+#define LUAT_USE_LVGL_MSGBOX   //消息框 依赖图片按钮IMGBTN 标签LABEL
+#define LUAT_USE_LVGL_PAGE   //页面 依赖容器CONT
+#define LUAT_USE_LVGL_SPINNER   //旋转器 依赖圆弧ARC 动画ANIM
+#define LUAT_USE_LVGL_ROLLER   //滚筒 无依赖
+#define LUAT_USE_LVGL_SLIDER   //滑杆 依赖进度条BAR
+#define LUAT_USE_LVGL_SPINBOX   //数字调整框 无依赖
+#define LUAT_USE_LVGL_SWITCH   //开关 依赖滑杆SLIDER
+#define LUAT_USE_LVGL_TEXTAREA   //文本框 依赖标签LABEL 页面PAGE
+#define LUAT_USE_LVGL_TABLE   //表格 依赖标签LABEL
+#define LUAT_USE_LVGL_TABVIEW   //页签 依赖页面PAGE 图片按钮IMGBTN
+#define LUAT_USE_LVGL_TILEVIEW   //平铺视图 依赖页面PAGE
+#define LUAT_USE_LVGL_WIN   //窗口 依赖容器CONT 按钮BTN 标签LABEL 图片IMG 页面PAGE
+
+#define LV_HOR_RES_MAX          (240)
+#define LV_VER_RES_MAX          (240)
+#define LV_COLOR_DEPTH          16
+
+#define LV_COLOR_16_SWAP   1
+#define LV_TICK_CUSTOM 1
+#define LV_TICK_CUSTOM_INCLUDE  "app_interface.h"         /*Header for the system time function*/
+#define LV_TICK_CUSTOM_SYS_TIME_EXPR ((uint32_t)GetSysTickMS())     /*Expression evaluating to current system time in ms*/
+
+#define LV_NO_BLOCK_FLUSH
+#define time(X)	luat_time(X)
+#endif
+
+#define LV_USE_PERF_MONITOR     1
+#ifndef __DEBUG__
+#undef LV_USE_PERF_MONITOR
+#endif
+//#define LV_ATTRIBUTE_FAST_MEM	__attribute__((section (".RamFunc")))

+ 3964 - 0
application/include/mbedtls/config.h

@@ -0,0 +1,3964 @@
+/**
+ * \file config.h
+ *
+ * \brief Configuration options (set of defines)
+ *
+ *  This set of compile-time options may be used to enable
+ *  or disable features selectively, and reduce the global
+ *  memory footprint.
+ */
+/*
+ *  Copyright The Mbed TLS Contributors
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ *      library/aria.c
+ *      library/timing.c
+ *      include/mbedtls/bn_mul.h
+ *
+ * Required by:
+ *      MBEDTLS_AESNI_C
+ *      MBEDTLS_PADLOCK_C
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDTLS_HAVE_ASM
+
+/**
+ * \def MBEDTLS_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ *      include/mbedtls/bignum.h
+ *      library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDTLS_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDTLS_NO_64BIT_MULTIPLICATION
+ *
+ * The platform lacks support for 32x32 -> 64-bit multiplication.
+ *
+ * Used in:
+ *      library/poly1305.c
+ *
+ * Some parts of the library may use multiplication of two unsigned 32-bit
+ * operands with a 64-bit result in order to speed up computations. On some
+ * platforms, this is not available in hardware and has to be implemented in
+ * software, usually in a library provided by the toolchain.
+ *
+ * Sometimes it is not desirable to have to link to that library. This option
+ * removes the dependency of that library on platforms that lack a hardware
+ * 64-bit multiplier by embedding a software implementation in Mbed TLS.
+ *
+ * Note that depending on the compiler, this may decrease performance compared
+ * to using the library function provided by the toolchain.
+ */
+//#define MBEDTLS_NO_64BIT_MULTIPLICATION
+
+/**
+ * \def MBEDTLS_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDTLS_HAVE_SSE2
+
+/**
+ * \def MBEDTLS_HAVE_TIME
+ *
+ * System has time.h and time().
+ * The time does not need to be correct, only time differences are used,
+ * by contrast with MBEDTLS_HAVE_TIME_DATE
+ *
+ * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT,
+ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
+ * MBEDTLS_PLATFORM_STD_TIME.
+ *
+ * Comment if your system does not support time functions
+ */
+// #define MBEDTLS_HAVE_TIME
+
+/**
+ * \def MBEDTLS_HAVE_TIME_DATE
+ *
+ * System has time.h, time(), and an implementation for
+ * mbedtls_platform_gmtime_r() (see below).
+ * The time needs to be correct (not necessarily very accurate, but at least
+ * the date should be correct). This is used to verify the validity period of
+ * X.509 certificates.
+ *
+ * Comment if your system does not have a correct clock.
+ *
+ * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
+ * behaves similarly to the gmtime_r() function from the C standard. Refer to
+ * the documentation for mbedtls_platform_gmtime_r() for more information.
+ *
+ * \note It is possible to configure an implementation for
+ * mbedtls_platform_gmtime_r() at compile-time by using the macro
+ * MBEDTLS_PLATFORM_GMTIME_R_ALT.
+ */
+// #define MBEDTLS_HAVE_TIME_DATE
+
+/**
+ * \def MBEDTLS_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default mbed TLS uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+//#define MBEDTLS_PLATFORM_MEMORY
+
+/**
+ * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDTLS_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDTLS_PLATFORM_EXIT_ALT
+ *
+ * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
+ * provide a function "mbedtls_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDTLS_PLATFORM_C to be defined!
+ *
+ * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDTLS_PLATFORM_XXX_MACRO!
+ *
+ * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
+//#define MBEDTLS_PLATFORM_FPRINTF_ALT
+//#define MBEDTLS_PLATFORM_PRINTF_ALT
+//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
+//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDTLS_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions and features so that they generate a warning if
+ * used. Functionality deprecated in one version will usually be removed in the
+ * next version. You can enable this to help you prepare the transition to a
+ * new major version by making sure your code is not using this functionality.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions and features.
+ */
+//#define MBEDTLS_DEPRECATED_WARNING
+
+/**
+ * \def MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions and features so that they generate an error if
+ * used. Functionality deprecated in one version will usually be removed in the
+ * next version. You can enable this to help you prepare the transition to a
+ * new major version by making sure your code is not using this functionality.
+ *
+ * Uncomment to get errors on using deprecated functions and features.
+ */
+//#define MBEDTLS_DEPRECATED_REMOVED
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * For example, when a function accepts as input a pointer to a buffer that may
+ * contain untrusted data, and its documentation mentions that this pointer
+ * must not be NULL:
+ * - The pointer is checked to be non-NULL only if this option is enabled.
+ * - The content of the buffer is always validated.
+ *
+ * When this flag is defined, if a library function receives a parameter that
+ * is invalid:
+ * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED().
+ * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function
+ *   will immediately return. If the function returns an Mbed TLS error code,
+ *   the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA.
+ *
+ * When defining this flag, you also need to arrange a definition for
+ * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods:
+ * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a
+ *   function mbedtls_param_failed(), but the library does not define this
+ *   function. If you do not make any other arrangements, you must provide
+ *   the function mbedtls_param_failed() in your application.
+ *   See `platform_util.h` for its prototype.
+ * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
+ *   library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
+ *   You can still supply an alternative definition of
+ *   MBEDTLS_PARAM_FAILED(), which may call `assert`.
+ * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
+ *   or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`,
+ *   the library will call the macro that you defined and will not supply
+ *   its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`,
+ *   you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source
+ *   files include `<assert.h>`.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS_ASSERT
+ *
+ * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to
+ * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined.
+ *
+ * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to
+ * calling a function mbedtls_param_failed(). See the documentation of
+ * #MBEDTLS_CHECK_PARAMS for details.
+ *
+ * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`.
+ */
+//#define MBEDTLS_CHECK_PARAMS_ASSERT
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: mbed TLS feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
+ *
+ * Only works if you have MBEDTLS_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_TIMING_ALT
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer
+ * provide the "struct mbedtls_aes_context" definition and omit the base
+ * function declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning   MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ *            use constitutes a security risk. If possible, we recommend
+ *            avoiding dependencies on them, and considering stronger message
+ *            digests and ciphers instead.
+ *
+ */
+//#define MBEDTLS_AES_ALT
+//#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
+//#define MBEDTLS_BLOWFISH_ALT
+//#define MBEDTLS_CAMELLIA_ALT
+//#define MBEDTLS_CCM_ALT
+//#define MBEDTLS_CHACHA20_ALT
+//#define MBEDTLS_CHACHAPOLY_ALT
+//#define MBEDTLS_CMAC_ALT
+//#define MBEDTLS_DES_ALT
+//#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+//#define MBEDTLS_GCM_ALT
+//#define MBEDTLS_NIST_KW_ALT
+//#define MBEDTLS_MD2_ALT
+//#define MBEDTLS_MD4_ALT
+//#define MBEDTLS_MD5_ALT
+//#define MBEDTLS_POLY1305_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+//#define MBEDTLS_RSA_ALT
+//#define MBEDTLS_SHA1_ALT
+//#define MBEDTLS_SHA256_ALT
+//#define MBEDTLS_SHA512_ALT
+//#define MBEDTLS_XTEA_ALT
+
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ *      - ecp.c
+ *      - ecp_curves.c
+ * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDTLS_ECP_ALT
+
+/**
+ * \def MBEDTLS_MD2_PROCESS_ALT
+ *
+ * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
+ * no longer provide the mbedtls_sha1_process() function, but it will still provide
+ * the other function (using your mbedtls_sha1_process() function) and the definition
+ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
+ *       respectively. When setting up alternative implementations, these functions should
+ *       be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ *       tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ *            constitutes a security risk. If possible, we recommend avoiding
+ *            dependencies on them, and considering stronger message digests
+ *            and ciphers instead.
+ *
+ * \warning   If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are
+ *            enabled, then the deterministic ECDH signature functions pass the
+ *            the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore
+ *            alternative implementations should use the RNG only for generating
+ *            the ephemeral key and nothing else. If this is not possible, then
+ *            MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative
+ *            implementation should be provided for mbedtls_ecdsa_sign_det_ext()
+ *            (and for mbedtls_ecdsa_sign_det() too if backward compatibility is
+ *            desirable).
+ *
+ */
+//#define MBEDTLS_MD2_PROCESS_ALT
+//#define MBEDTLS_MD4_PROCESS_ALT
+//#define MBEDTLS_MD5_PROCESS_ALT
+//#define MBEDTLS_RIPEMD160_PROCESS_ALT
+//#define MBEDTLS_SHA1_PROCESS_ALT
+//#define MBEDTLS_SHA256_PROCESS_ALT
+//#define MBEDTLS_SHA512_PROCESS_ALT
+//#define MBEDTLS_DES_SETKEY_ALT
+//#define MBEDTLS_DES_CRYPT_ECB_ALT
+//#define MBEDTLS_DES3_CRYPT_ECB_ALT
+//#define MBEDTLS_AES_SETKEY_ENC_ALT
+//#define MBEDTLS_AES_SETKEY_DEC_ALT
+//#define MBEDTLS_AES_ENCRYPT_ALT
+//#define MBEDTLS_AES_DECRYPT_ALT
+//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+//#define MBEDTLS_ECDSA_VERIFY_ALT
+//#define MBEDTLS_ECDSA_SIGN_ALT
+//#define MBEDTLS_ECDSA_GENKEY_ALT
+
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * The original implementation can in addition be removed by setting the
+ * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the
+ * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be
+ * able to fallback to curves not supported by the alternative implementation.
+ *
+ * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ *      unsigned char mbedtls_internal_ecp_grp_capable(
+ *          const mbedtls_ecp_group *grp )
+ *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
+ * The mbedtls_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac()
+ * function, but will use your mbedtls_internal_ecp_double_jac() if the group
+ * for the operation is supported by your implementation (i.e. your
+ * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the
+ * group is not supported by your implementation, then the original mbed TLS
+ * implementation of ecp_double_jac() is used instead, unless this fallback
+ * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case
+ * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE).
+ *
+ * The function prototypes and the definition of mbedtls_ecp_group and
+ * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your
+ * implementation of mbedtls_internal_ecp__function_name__ must be compatible
+ * with their definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Turn off software fallback for curves not supported in hardware */
+//#define MBEDTLS_ECP_NO_FALLBACK
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDTLS_ECP_ADD_MIXED_ALT
+//#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let mbed TLS use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedtls_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+//#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDTLS_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_ROM_TABLES
+
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
+/**
+ * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
+ */
+#define MBEDTLS_CIPHER_MODE_XTS
+
+/**
+ * \def MBEDTLS_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define MBEDTLS_CIPHER_NULL_CIPHER
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+#define MBEDTLS_CIPHER_PADDING_PKCS7
+#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+#define MBEDTLS_CIPHER_PADDING_ZEROS
+
+/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+ *
+ * Uncomment this macro to use a 128-bit key in the CTR_DRBG module.
+ * By default, CTR_DRBG uses a 256-bit key.
+ */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+
+/**
+ * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ *      MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+// #define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES
+ *
+ * Remove 3DES ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on 3DES from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible
+ * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including
+ * them explicitly.
+ *
+ * A man-in-the-browser attacker can recover authentication tokens sent through
+ * a TLS connection using a 3DES based cipher suite (see "On the Practical
+ * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan
+ * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls
+ * in your threat model or you are unsure, then you should keep this option
+ * enabled to remove 3DES based cipher suites.
+ *
+ * Comment this macro to keep 3DES in the default ciphersuite list.
+ */
+#define MBEDTLS_REMOVE_3DES_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module.  By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+/* Montgomery curves (supporting ECP) */
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define MBEDTLS_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDTLS_ECP_NO_INTERNAL_RNG
+ *
+ * When this option is disabled, mbedtls_ecp_mul() will make use of an
+ * internal RNG when called with a NULL \c f_rng argument, in order to protect
+ * against some side-channel attacks.
+ *
+ * This protection introduces a dependency of the ECP module on one of the
+ * DRBG modules. For very constrained implementations that don't require this
+ * protection (for example, because you're only doing signature verification,
+ * so not manipulating any secret, or because local/physical side-channel
+ * attacks are outside your threat model), it might be desirable to get rid of
+ * that dependency.
+ *
+ * \warning Enabling this option makes some uses of ECP vulnerable to some
+ * side-channel attacks. Only enable it if you know that's not a problem for
+ * your use case.
+ *
+ * Uncomment this macro to disable some counter-measures in ECP.
+ */
+//#define MBEDTLS_ECP_NO_INTERNAL_RNG
+
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT
+ *        and MBEDTLS_ECDH_LEGACY_CONTEXT.
+ */
+//#define MBEDTLS_ECP_RESTARTABLE
+
+/**
+ * \def MBEDTLS_ECDH_LEGACY_CONTEXT
+ *
+ * Use a backward compatible ECDH context.
+ *
+ * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context
+ * defined in `ecdh.h`). For most applications, the choice of format makes
+ * no difference, since all library functions can work with either format,
+ * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE.
+
+ * The new format used when this option is disabled is smaller
+ * (56 bytes on a 32-bit platform). In future versions of the library, it
+ * will support alternative implementations of ECDH operations.
+ * The new format is incompatible with applications that access
+ * context fields directly and with restartable ECP operations.
+ *
+ * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you
+ * want to access ECDH context fields directly. Otherwise you should
+ * comment out this macro definition.
+ *
+ * This option has no effect if #MBEDTLS_ECDH_C is not enabled.
+ *
+ * \note This configuration option is experimental. Future versions of the
+ *       library may modify the way the ECDH context layout is configured
+ *       and may modify the layout of the new context type.
+ */
+#define MBEDTLS_ECDH_LEGACY_CONTEXT
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+// #define MBEDTLS_ECDSA_DETERMINISTIC
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ */
+// #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+// #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+// #define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+// #define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ */
+// #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+// #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+// #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+// #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+// #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ *
+ * Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Requires: MBEDTLS_ECJPAKE_C
+ *           MBEDTLS_SHA256_C
+ *           MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+/**
+ * \def MBEDTLS_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+// #define MBEDTLS_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDTLS_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedtls_strerror() in
+ * third party libraries easier when MBEDTLS_ERROR_C is disabled
+ * (no effect when MBEDTLS_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
+ * not using mbedtls_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedtls_strerror()
+ */
+#define MBEDTLS_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDTLS_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDTLS_BIGNUM_C
+ */
+#define MBEDTLS_GENPRIME
+
+/**
+ * \def MBEDTLS_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+// #define MBEDTLS_FS_IO
+
+/**
+ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedtls_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDTLS_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDTLS_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDTLS_SHA256_C and
+ * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDTLS_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+ *
+ * Enable key identifiers that encode a key owner identifier.
+ *
+ * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t
+ * which is currently hard-coded to be int32_t.
+ *
+ * Note that this option is meant for internal use only and may be removed
+ * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO.
+ */
+//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+
+/**
+ * \def MBEDTLS_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDTLS_MEMORY_DEBUG
+
+/**
+ * \def MBEDTLS_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *           GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDTLS_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDTLS_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+// #define MBEDTLS_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+// #define MBEDTLS_PKCS1_V15
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+// #define MBEDTLS_PKCS1_V21
+
+/** \def MBEDTLS_PSA_CRYPTO_CLIENT
+ *
+ * Enable support for PSA crypto client.
+ *
+ * \note This option allows to include the code necessary for a PSA
+ *       crypto client when the PSA crypto implementation is not included in
+ *       the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the
+ *       code to set and get PSA key attributes.
+ *       The development of PSA drivers partially relying on the library to
+ *       fulfill the hardware gaps is another possible usage of this option.
+ *
+ * \warning This interface is experimental and may change or be removed
+ * without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_CLIENT
+
+/** \def MBEDTLS_PSA_CRYPTO_DRIVERS
+ *
+ * Enable support for the experimental PSA crypto driver interface.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ * \warning This interface is experimental and may change or be removed
+ * without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_DRIVERS
+
+/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ *
+ * Make the PSA Crypto module use an external random generator provided
+ * by a driver, instead of Mbed TLS's entropy and DRBG modules.
+ *
+ * \note This random generator must deliver random numbers with cryptographic
+ *       quality and high performance. It must supply unpredictable numbers
+ *       with a uniform distribution. The implementation of this function
+ *       is responsible for ensuring that the random generator is seeded
+ *       with sufficient entropy. If you have a hardware TRNG which is slow
+ *       or delivers non-uniform output, declare it as an entropy source
+ *       with mbedtls_entropy_add_source() instead of enabling this option.
+ *
+ * If you enable this option, you must configure the type
+ * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h
+ * and define a function called mbedtls_psa_external_get_random()
+ * with the following prototype:
+ * ```
+ * psa_status_t mbedtls_psa_external_get_random(
+ *     mbedtls_psa_external_random_context_t *context,
+ *     uint8_t *output, size_t output_size, size_t *output_length);
+ * );
+ * ```
+ * The \c context value is initialized to 0 before the first call.
+ * The function must fill the \c output buffer with \p output_size bytes
+ * of random data and set \c *output_length to \p output_size.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ * \warning If you enable this option, code that uses the PSA cryptography
+ *          interface will not use any of the entropy sources set up for
+ *          the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED
+ *          enables.
+ *
+ * \note This option is experimental and may be removed without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_SPM
+ *
+ * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
+ * Partition Manager) integration which separates the code into two parts: a
+ * NSPE (Non-Secure Process Environment) and an SPE (Secure Process
+ * Environment).
+ *
+ * Module:  library/psa_crypto.c
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_SPM
+
+/**
+ * \def MBEDTLS_PSA_INJECT_ENTROPY
+ *
+ * Enable support for entropy injection at first boot. This feature is
+ * required on systems that do not have a built-in entropy source (TRNG).
+ * This feature is currently not supported on systems that have a built-in
+ * entropy source.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED
+ *
+ */
+//#define MBEDTLS_PSA_INJECT_ENTROPY
+
+/**
+ * \def MBEDTLS_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem
+ * for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDTLS_RSA_NO_CRT
+
+/**
+ * \def MBEDTLS_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+#define MBEDTLS_SELF_TEST
+
+/**
+ * \def MBEDTLS_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDTLS_SHA256_SMALLER
+
+/**
+ * \def MBEDTLS_SHA512_SMALLER
+ *
+ * Enable an implementation of SHA-512 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * Uncomment to enable the smaller implementation of SHA512.
+ */
+//#define MBEDTLS_SHA512_SMALLER
+
+/**
+ * \def MBEDTLS_SHA512_NO_SHA384
+ *
+ * Disable the SHA-384 option of the SHA-512 module. Use this to save some
+ * code size on devices that don't use SHA-384.
+ *
+ * Requires: MBEDTLS_SHA512_C
+ *
+ * Uncomment to disable SHA-384
+ */
+//#define MBEDTLS_SHA512_NO_SHA384
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+
+/**
+ * \def MBEDTLS_SSL_RECORD_CHECKING
+ *
+ * Enable the function mbedtls_ssl_check_record() which can be used to check
+ * the validity and authenticity of an incoming record, to verify that it has
+ * not been seen before. These checks are performed without modifying the
+ * externally visible state of the SSL context.
+ *
+ * See mbedtls_ssl_check_record() for more information.
+ *
+ * Uncomment to enable support for record checking.
+ */
+#define MBEDTLS_SSL_RECORD_CHECKING
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CONNECTION_ID
+ *
+ * Enable support for the DTLS Connection ID extension
+ * (version draft-ietf-tls-dtls-connection-id-05,
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
+ * which allows to identify DTLS connections across changes
+ * in the underlying transport.
+ *
+ * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`,
+ * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`.
+ * See the corresponding documentation for more information.
+ *
+ * \warning The Connection ID extension is still in draft state.
+ *          We make no stability promises for the availability
+ *          or the shape of the API controlled by this option.
+ *
+ * The maximum lengths of outgoing and incoming CIDs can be configured
+ * through the options
+ * - MBEDTLS_SSL_CID_OUT_LEN_MAX
+ * - MBEDTLS_SSL_CID_IN_LEN_MAX.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Uncomment to enable the Connection ID extension.
+ */
+//#define MBEDTLS_SSL_DTLS_CONNECTION_ID
+
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
+/**
+ * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
+ *
+ * Enable serialization of the TLS context structures, through use of the
+ * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load().
+ *
+ * This pair of functions allows one side of a connection to serialize the
+ * context associated with the connection, then free or re-use that context
+ * while the serialized state is persisted elsewhere, and finally deserialize
+ * that state to a live context for resuming read/write operations on the
+ * connection. From a protocol perspective, the state of the connection is
+ * unaffected, in particular this is entirely transparent to the peer.
+ *
+ * Note: this is distinct from TLS session resumption, which is part of the
+ * protocol and fully visible by the peer. TLS session resumption enables
+ * establishing new connections associated to a saved session with shorter,
+ * lighter handshakes, while context serialization is a local optimization in
+ * handling a single, potentially long-lived connection.
+ *
+ * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are
+ * saved after the handshake to allow for more efficient serialization, so if
+ * you don't need this feature you'll save RAM by disabling it.
+ *
+ * Comment to disable the context serialization APIs.
+ */
+// #define MBEDTLS_SSL_CONTEXT_SERIALIZATION
+
+/**
+ * \def MBEDTLS_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define MBEDTLS_SSL_DEBUG_ALL
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+// #define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for RFC 7627: Session Hash and Extended Master Secret
+ * Extension.
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+// #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+
+/**
+ * \def MBEDTLS_SSL_FALLBACK_SCSV
+ *
+ * Enable support for RFC 7507: Fallback Signaling Cipher Suite Value (SCSV)
+ * for Preventing Protocol Downgrade Attacks.
+ *
+ * For servers, it is recommended to always enable this, unless you support
+ * only one version of TLS, or know for sure that none of your clients
+ * implements a fallback strategy.
+ *
+ * For clients, you only need this if you're using a fallback strategy, which
+ * is not recommended in the first place, unless you absolutely need it to
+ * interoperate with buggy (version-intolerant) servers.
+ *
+ * Comment this macro to disable support for FALLBACK_SCSV
+ */
+// #define MBEDTLS_SSL_FALLBACK_SCSV
+
+/**
+ * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+ *
+ * This option controls the availability of the API mbedtls_ssl_get_peer_cert()
+ * giving access to the peer's certificate after completion of the handshake.
+ *
+ * Unless you need mbedtls_ssl_peer_cert() in your application, it is
+ * recommended to disable this option for reduced RAM usage.
+ *
+ * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still
+ *       defined, but always returns \c NULL.
+ *
+ * \note This option has no influence on the protection against the
+ *       triple handshake attack. Even if it is disabled, Mbed TLS will
+ *       still ensure that certificates do not change during renegotiation,
+ *       for exaple by keeping a hash of the peer's certificate.
+ *
+ * Comment this macro to disable storing the peer's certificate
+ * after the handshake.
+ */
+// #define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+
+/**
+ * \def MBEDTLS_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * \deprecated This option is deprecated and will be removed in a future
+ *             version of Mbed TLS.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define MBEDTLS_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING
+ *
+ * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
+ *
+ * This is a countermeasure to the BEAST attack, which also minimizes the risk
+ * of interoperability issues compared to sending 0-length records.
+ *
+ * Comment this macro to disable 1/n-1 record splitting.
+ */
+// #define MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Enable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note   Even if this option is disabled, both client and server are aware
+ *         of the Renegotiation Indication Extension (RFC 5746) used to
+ *         prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ *         (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ *          configuration of this extension).
+ *
+ */
+// #define MBEDTLS_SSL_RENEGOTIATION
+
+/**
+ * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * \deprecated This option is deprecated and will be removed in a future
+ *             version of Mbed TLS.
+ *
+ * Uncomment this macro to enable support for SSLv2 Client Hello messages.
+ */
+//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+// #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def MBEDTLS_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * \deprecated This option is deprecated and will be removed in a future
+ *             version of Mbed TLS.
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+//#define MBEDTLS_SSL_PROTO_SSL3
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+// #define MBEDTLS_SSL_PROTO_TLS1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
+ */
+// #define MBEDTLS_SSL_PROTO_TLS1_1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ *           (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+// #define MBEDTLS_SSL_PROTO_TLS1_2
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+ *
+ * This macro is used to selectively enable experimental parts
+ * of the code that contribute to the ongoing development of
+ * the prototype TLS 1.3 and DTLS 1.3 implementation, and provide
+ * no other purpose.
+ *
+ * \warning TLS 1.3 and DTLS 1.3 aren't yet supported in Mbed TLS,
+ *          and no feature exposed through this macro is part of the
+ *          public API. In particular, features under the control
+ *          of this macro are experimental and don't come with any
+ *          stability guarantees.
+ *
+ * Uncomment this macro to enable experimental and partial
+ * functionality specific to TLS 1.3.
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ *        or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+// #define MBEDTLS_SSL_PROTO_DTLS
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+// #define MBEDTLS_SSL_ALPN
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *           MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+// #define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+// #define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_SRTP
+ *
+ * Enable support for negotation of DTLS-SRTP (RFC 5764)
+ * through the use_srtp extension.
+ *
+ * \note This feature provides the minimum functionality required
+ * to negotiate the use of DTLS-SRTP and to allow the derivation of
+ * the associated SRTP packet protection key material.
+ * In particular, the SRTP packet protection itself, as well as the
+ * demultiplexing of RTP and DTLS packets at the datagram layer
+ * (see Section 5 of RFC 5764), are not handled by this feature.
+ * Instead, after successful completion of a handshake negotiating
+ * the use of DTLS-SRTP, the extended key exporter API
+ * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement
+ * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705
+ * (this is implemented in the SSL example programs).
+ * The resulting key should then be passed to an SRTP stack.
+ *
+ * Setting this option enables the runtime API
+ * mbedtls_ssl_conf_dtls_srtp_protection_profiles()
+ * through which the supported DTLS-SRTP protection
+ * profiles can be configured. You must call this API at
+ * runtime if you wish to negotiate the use of DTLS-SRTP.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Uncomment this to enable support for use_srtp extension.
+ */
+//#define MBEDTLS_SSL_DTLS_SRTP
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+// #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+// #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintenance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+// #define MBEDTLS_SSL_SESSION_TICKETS
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+// #define MBEDTLS_SSL_EXPORT_KEYS
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+// #define MBEDTLS_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+// #define MBEDTLS_SSL_TRUNCATED_HMAC
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and will be removed in a future
+ * version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ *          (2^80 brute force attack on the HMAC key used for a single,
+ *          uninterrupted connection). This should only be enabled temporarily
+ *          when (1) the use of truncated HMAC is essential in order to save
+ *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ *          the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will be removed in a
+ *             future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
+/**
+ * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ *
+ * When this option is enabled, the SSL buffer will be resized automatically
+ * based on the negotiated maximum fragment length in each direction.
+ *
+ * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ */
+//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+
+/**
+ * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
+ *
+ * Enable testing of the constant-flow nature of some sensitive functions with
+ * clang's MemorySanitizer. This causes some existing tests to also test
+ * this non-functional property of the code under test.
+ *
+ * This setting requires compiling with clang -fsanitize=memory. The test
+ * suites can then be run normally.
+ *
+ * \warning This macro is only used for extended testing; it is not considered
+ * part of the library's API, so it may change or disappear at any time.
+ *
+ * Uncomment to enable testing of the constant-flow nature of selected code.
+ */
+//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
+
+/**
+ * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
+ *
+ * Enable testing of the constant-flow nature of some sensitive functions with
+ * valgrind's memcheck tool. This causes some existing tests to also test
+ * this non-functional property of the code under test.
+ *
+ * This setting requires valgrind headers for building, and is only useful for
+ * testing if the tests suites are run with valgrind's memcheck. This can be
+ * done for an individual test suite with 'valgrind ./test_suite_xxx', or when
+ * using CMake, this can be done for all test suites with 'make memcheck'.
+ *
+ * \warning This macro is only used for extended testing; it is not considered
+ * part of the library's API, so it may change or disappear at any time.
+ *
+ * Uncomment to enable testing of the constant-flow nature of selected code.
+ */
+//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
+
+/**
+ * \def MBEDTLS_TEST_HOOKS
+ *
+ * Enable features for invasive testing such as introspection functions and
+ * hooks for fault injection. This enables additional unit tests.
+ *
+ * Merely enabling this feature should not change the behavior of the product.
+ * It only adds new code, and new branching points where the default behavior
+ * is the same as when this feature is disabled.
+ * However, this feature increases the attack surface: there is an added
+ * risk of vulnerabilities, and more gadgets that can make exploits easier.
+ * Therefore this feature must never be enabled in production.
+ *
+ * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more
+ * information.
+ *
+ * Uncomment to enable invasive tests.
+ */
+//#define MBEDTLS_TEST_HOOKS
+
+/**
+ * \def MBEDTLS_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDTLS_THREADING_ALT
+
+/**
+ * \def MBEDTLS_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define MBEDTLS_THREADING_PTHREAD
+
+/**
+ * \def MBEDTLS_USE_PSA_CRYPTO
+ *
+ * Make the X.509 and TLS library use PSA for cryptographic operations, and
+ * enable new APIs for using keys handled by PSA Crypto.
+ *
+ * \note Development of this option is currently in progress, and parts of Mbed
+ * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts
+ * will still continue to work as usual, so enabling this option should not
+ * break backwards compatibility.
+ *
+ * \warning The PSA Crypto API is in beta stage. While you're welcome to
+ * experiment using it, incompatible API changes are still possible, and some
+ * parts may not have reached the same quality as the rest of Mbed TLS yet.
+ *
+ * \warning This option enables new Mbed TLS APIs that are dependent on the
+ * PSA Crypto API, so can't come with the same stability guarantees as the
+ * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for
+ * now, access to these APIs is opt-in (via enabling the present option), in
+ * order to clearly differentiate them from the stable Mbed TLS APIs.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C.
+ *
+ * Uncomment this to enable internal use of PSA Crypto and new associated APIs.
+ */
+//#define MBEDTLS_USE_PSA_CRYPTO
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_CONFIG
+ *
+ * This setting allows support for cryptographic mechanisms through the PSA
+ * API to be configured separately from support through the mbedtls API.
+ *
+ * Uncomment this to enable use of PSA Crypto configuration settings which
+ * can be found in include/psa/crypto_config.h.
+ *
+ * If you enable this option and write your own configuration file, you must
+ * include mbedtls/config_psa.h in your configuration file. The default
+ * provided mbedtls/config.h contains the necessary inclusion.
+ *
+ * This feature is still experimental and is not ready for production since
+ * it is not completed.
+ */
+//#define MBEDTLS_PSA_CRYPTO_CONFIG
+
+/**
+ * \def MBEDTLS_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedtls_version_check_feature().
+ *
+ * Requires: MBEDTLS_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDTLS_VERSION_FEATURES
+
+/**
+ * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * \warning Depending on your PKI use, enabling this can be a security risk!
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+ *
+ * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()`
+ * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure
+ * the set of trusted certificates through a callback instead of a linked
+ * list.
+ *
+ * This is useful for example in environments where a large number of trusted
+ * certificates is present and storing them in a linked list isn't efficient
+ * enough, or when the set of trusted certificates changes frequently.
+ *
+ * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and
+ * `mbedtls_ssl_conf_ca_cb()` for more information.
+ *
+ * Uncomment to enable trusted certificate callbacks.
+ */
+//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+// #define MBEDTLS_X509_CHECK_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+// #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+// #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def MBEDTLS_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be applicable to your use case.
+ *
+ * \note Currently compression can't be used with DTLS.
+ *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
+ * Used in: library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define MBEDTLS_ZLIB_SUPPORT
+/* \} name SECTION: mbed TLS feature support */
+
+/**
+ * \name SECTION: mbed TLS modules
+ *
+ * This section enables or disables entire modules in mbed TLS
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module:  library/aesni.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+// #define MBEDTLS_AESNI_C
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module:  library/aes.c
+ * Caller:  library/cipher.c
+ *          library/pem.c
+ *          library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDTLS_AES_C
+
+/**
+ * \def MBEDTLS_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module:  library/arc4.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. If possible, we recommend avoidng dependencies on
+ *            it, and considering stronger ciphers instead.
+ *
+ */
+// #define MBEDTLS_ARC4_C
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module:  library/asn1.c
+ * Caller:  library/x509.c
+ *          library/dhm.c
+ *          library/pkcs12.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ */
+#define MBEDTLS_ASN1_PARSE_C
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module:  library/asn1write.c
+ * Caller:  library/ecdsa.c
+ *          library/pkwrite.c
+ *          library/x509_create.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ */
+// #define MBEDTLS_ASN1_WRITE_C
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module:  library/base64.c
+ * Caller:  library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDTLS_BASE64_C
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module:  library/bignum.c
+ * Caller:  library/dhm.c
+ *          library/ecp.c
+ *          library/ecdsa.c
+ *          library/rsa.c
+ *          library/rsa_internal.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDTLS_BIGNUM_C
+
+/**
+ * \def MBEDTLS_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module:  library/blowfish.c
+ */
+#define MBEDTLS_BLOWFISH_C
+
+/**
+ * \def MBEDTLS_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module:  library/camellia.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+#define MBEDTLS_CAMELLIA_C
+
+/**
+ * \def MBEDTLS_ARIA_C
+ *
+ * Enable the ARIA block cipher.
+ *
+ * Module:  library/aria.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
+ */
+//#define MBEDTLS_ARIA_C
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module:  library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define MBEDTLS_CCM_C
+
+/**
+ * \def MBEDTLS_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module:  library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+// #define MBEDTLS_CERTS_C
+
+/**
+ * \def MBEDTLS_CHACHA20_C
+ *
+ * Enable the ChaCha20 stream cipher.
+ *
+ * Module:  library/chacha20.c
+ */
+#define MBEDTLS_CHACHA20_C
+
+/**
+ * \def MBEDTLS_CHACHAPOLY_C
+ *
+ * Enable the ChaCha20-Poly1305 AEAD algorithm.
+ *
+ * Module:  library/chachapoly.c
+ *
+ * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
+ */
+#define MBEDTLS_CHACHAPOLY_C
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module:  library/cipher.c
+ * Caller:  library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDTLS_CIPHER_C
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module:  library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+//#define MBEDTLS_CMAC_C
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-based random generator.
+ * The CTR_DRBG generator uses AES-256 by default.
+ * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
+ *
+ * \note To achieve a 256-bit security strength with CTR_DRBG,
+ *       you must use AES-256 *and* use sufficient entropy.
+ *       See ctr_drbg.h for more details.
+ *
+ * Module:  library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES random number generator.
+ */
+#define MBEDTLS_CTR_DRBG_C
+
+/**
+ * \def MBEDTLS_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module:  library/debug.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+#define MBEDTLS_DEBUG_C
+
+/**
+ * \def MBEDTLS_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module:  library/des.c
+ * Caller:  library/pem.c
+ *          library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+#define MBEDTLS_DES_C
+
+/**
+ * \def MBEDTLS_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module:  library/dhm.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      DHE-RSA, DHE-PSK
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+#define MBEDTLS_DHM_C
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module:  library/ecdh.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#define MBEDTLS_ECDH_C
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module:  library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C,
+ *           and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a
+ *           short Weierstrass curve.
+ */
+// #define MBEDTLS_ECDSA_C
+
+/**
+ * \def MBEDTLS_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module:  library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECJPAKE
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
+ */
+//#define MBEDTLS_ECJPAKE_C
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module:  library/ecp.c
+ * Caller:  library/ecdh.c
+ *          library/ecdsa.c
+ *          library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#define MBEDTLS_ECP_C
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module:  library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDTLS_ENTROPY_C
+
+/**
+ * \def MBEDTLS_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module:  library/error.c
+ * Caller:
+ *
+ * This module enables mbedtls_strerror().
+ */
+#define MBEDTLS_ERROR_C
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM).
+ *
+ * Module:  library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDTLS_GCM_C
+
+/**
+ * \def MBEDTLS_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ *          environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ *          processor traits. It is therefore not advised to use HAVEGE as
+ *          your applications primary random generator or primary entropy pool
+ *          input. As a secondary input to your entropy pool, it IS able add
+ *          the (limited) extra entropy it provides.
+ *
+ * Module:  library/havege.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define MBEDTLS_HAVEGE_C
+
+/**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module:  library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module:  library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDTLS_HMAC_DRBG_C
+
+/**
+ * \def MBEDTLS_NIST_KW_C
+ *
+ * Enable the Key Wrapping mode for 128-bit block ciphers,
+ * as defined in NIST SP 800-38F. Only KW and KWP modes
+ * are supported. At the moment, only AES is approved by NIST.
+ *
+ * Module:  library/nist_kw.c
+ *
+ * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
+ */
+//#define MBEDTLS_NIST_KW_C
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module:  library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDTLS_MD_C
+
+/**
+ * \def MBEDTLS_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module:  library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning   MD2 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD2_C
+
+/**
+ * \def MBEDTLS_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module:  library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning   MD4 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD4_C
+
+/**
+ * \def MBEDTLS_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module:  library/md5.c
+ * Caller:  library/md.c
+ *          library/pem.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_MD5_C
+
+/**
+ * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module:  library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *           MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDTLS_NET_C
+ *
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/net_sockets.c
+ *
+ * This module provides networking routines.
+ */
+// #define MBEDTLS_NET_C
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module:  library/oid.c
+ * Caller:  library/asn1write.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ *          library/pkwrite.c
+ *          library/rsa.c
+ *          library/x509.c
+ *          library/x509_create.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+// #define MBEDTLS_OID_C
+
+/**
+ * \def MBEDTLS_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module:  library/padlock.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+// #define MBEDTLS_PADLOCK_C
+
+/**
+ * \def MBEDTLS_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/dhm.c
+ *          library/pkparse.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+// #define MBEDTLS_PEM_PARSE_C
+
+/**
+ * \def MBEDTLS_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/pkwrite.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+// #define MBEDTLS_PEM_WRITE_C
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module:  library/pk.c
+ * Caller:  library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+// #define MBEDTLS_PK_C
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module:  library/pkparse.c
+ * Caller:  library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+// #define MBEDTLS_PK_PARSE_C
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module:  library/pkwrite.c
+ * Caller:  library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+// #define MBEDTLS_PK_WRITE_C
+
+/**
+ * \def MBEDTLS_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module:  library/pkcs5.c
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+// #define MBEDTLS_PKCS5_C
+
+/**
+ * \def MBEDTLS_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support via the pkcs11-helper library.
+ *
+ * \deprecated This option is deprecated and will be removed in a future
+ *             version of Mbed TLS.
+ *
+ * Module:  library/pkcs11.c
+ * Caller:  library/pk.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDTLS_PKCS11_C
+
+/**
+ * \def MBEDTLS_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module:  library/pkcs12.c
+ * Caller:  library/pkparse.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * Can use:  MBEDTLS_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+// #define MBEDTLS_PKCS12_C
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module:  library/platform.c
+ * Caller:  Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDTLS_PLATFORM_C
+
+/**
+ * \def MBEDTLS_POLY1305_C
+ *
+ * Enable the Poly1305 MAC algorithm.
+ *
+ * Module:  library/poly1305.c
+ * Caller:  library/chachapoly.c
+ */
+#define MBEDTLS_POLY1305_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_C
+ *
+ * Enable the Platform Security Architecture cryptography API.
+ *
+ * \warning The PSA Crypto API is still beta status. While you're welcome to
+ * experiment using it, incompatible API changes are still possible, and some
+ * parts may not have reached the same quality as the rest of Mbed TLS yet.
+ *
+ * Module:  library/psa_crypto.c
+ *
+ * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
+ *           or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
+ *           or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
+ *
+ */
+#define MBEDTLS_PSA_CRYPTO_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_SE_C
+ *
+ * Enable secure element support in the Platform Security Architecture
+ * cryptography API.
+ *
+ * \warning This feature is not yet suitable for production. It is provided
+ *          for API evaluation and testing purposes only.
+ *
+ * Module:  library/psa_crypto_se.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_SE_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_STORAGE_C
+ *
+ * Enable the Platform Security Architecture persistent key storage.
+ *
+ * Module:  library/psa_crypto_storage.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C,
+ *           either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
+ *           the PSA ITS interface
+ */
+// #define MBEDTLS_PSA_CRYPTO_STORAGE_C
+
+/**
+ * \def MBEDTLS_PSA_ITS_FILE_C
+ *
+ * Enable the emulation of the Platform Security Architecture
+ * Internal Trusted Storage (PSA ITS) over files.
+ *
+ * Module:  library/psa_its_file.c
+ *
+ * Requires: MBEDTLS_FS_IO
+ */
+// #define MBEDTLS_PSA_ITS_FILE_C
+
+/**
+ * \def MBEDTLS_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module:  library/ripemd160.c
+ * Caller:  library/md.c
+ *
+ */
+// #define MBEDTLS_RIPEMD160_C
+
+/**
+ * \def MBEDTLS_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module:  library/rsa.c
+ *          library/rsa_internal.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ *      RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C
+ */
+// #define MBEDTLS_RSA_C
+
+/**
+ * \def MBEDTLS_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module:  library/sha1.c
+ * Caller:  library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_SHA1_C
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module:  library/sha256.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDTLS_SHA256_C
+
+/**
+ * \def MBEDTLS_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module:  library/sha512.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDTLS_SHA512_C
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module:  library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+// #define MBEDTLS_SSL_CACHE_C
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module:  library/ssl_cookie.c
+ * Caller:
+ */
+// #define MBEDTLS_SSL_COOKIE_C
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module:  library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+// #define MBEDTLS_SSL_TICKET_C
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module:  library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+// #define MBEDTLS_SSL_CLI_C
+
+/**
+ * \def MBEDTLS_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module:  library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+// #define MBEDTLS_SSL_SRV_C
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module:  library/ssl_tls.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ *           and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+// #define MBEDTLS_SSL_TLS_C
+
+/**
+ * \def MBEDTLS_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default mbed TLS assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module:  library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDTLS_THREADING_ALT or
+ * MBEDTLS_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within mbed TLS
+ */
+//#define MBEDTLS_THREADING_C
+
+/**
+ * \def MBEDTLS_TIMING_C
+ *
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/timing.c
+ * Caller:  library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+// #define MBEDTLS_TIMING_C
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module:  library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDTLS_VERSION_C
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module:  library/x509.c
+ * Caller:  library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ *           MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+// #define MBEDTLS_X509_USE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module:  library/x509_crt.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+// #define MBEDTLS_X509_CRT_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module:  library/x509_crl.c
+ * Caller:  library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+// #define MBEDTLS_X509_CRL_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module:  library/x509_csr.c
+ * Caller:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+// #define MBEDTLS_X509_CSR_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module:  library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+// #define MBEDTLS_X509_CREATE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+// #define MBEDTLS_X509_CRT_WRITE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module:  library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+// #define MBEDTLS_X509_CSR_WRITE_C
+
+/**
+ * \def MBEDTLS_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module:  library/xtea.c
+ * Caller:
+ */
+// #define MBEDTLS_XTEA_C
+
+/* \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum window size used. */
+//#define MBEDTLS_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN               48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL        10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_CTR_DRBG_MAX_INPUT                256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_CTR_DRBG_MAX_REQUEST             1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT           384 /**< Maximum size of (re)seed buffer */
+
+/* HMAC_DRBG options */
+//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_HMAC_DRBG_MAX_INPUT           256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST        1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT      384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDTLS_ECP_MAX_BITS             521 /**< Maximum bit size of groups */
+//#define MBEDTLS_ECP_WINDOW_SIZE            6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
+//#define MBEDTLS_ENTROPY_MAX_GATHER                128 /**< Maximum amount requested from entropy sources */
+//#define MBEDTLS_ENTROPY_MIN_HARDWARE               32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE      4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correctly zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO        calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correctly zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO    vsnprintf /**< Default vsnprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with #MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, the library provides
+ *              a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT
+ *              is defined, the default definition is `assert(cond)`,
+ *              otherwise the default definition calls a function
+ *              mbedtls_param_failed(). This function is declared in
+ *              `platform_util.h` for the benefit of the library, but
+ *              you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *              If you define this macro to call `assert`, also define
+ *              #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files
+ *              include `<assert.h>`.
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
+/* PSA options */
+/**
+ * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
+ * PSA crypto subsystem.
+ *
+ * If this option is unset:
+ * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG.
+ * - Otherwise, the PSA subsystem uses HMAC_DRBG with either
+ *   #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and
+ *   on unspecified heuristics.
+ */
+//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
+
+/** \def MBEDTLS_PSA_KEY_SLOT_COUNT
+ * Restrict the PSA library to supporting a maximum amount of simultaneously
+ * loaded keys. A loaded key is a key stored by the PSA Crypto core as a
+ * volatile key, or a persistent key which is loaded temporarily by the
+ * library as part of a crypto operation in flight.
+ *
+ * If this option is unset, the library will fall back to a default value of
+ * 32 keys.
+ */
+//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
+
+/* SSL Cache options */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
+
+/* SSL options */
+
+/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
+ *
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
+ *
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
+ */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming plaintext fragments.
+ *
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
+ */
+//#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
+
+/** \def MBEDTLS_SSL_CID_IN_LEN_MAX
+ *
+ * The maximum length of CIDs used for incoming DTLS messages.
+ *
+ */
+//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32
+
+/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX
+ *
+ * The maximum length of CIDs used for outgoing DTLS messages.
+ *
+ */
+//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32
+
+/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY
+ *
+ * This option controls the use of record plaintext padding
+ * when using the Connection ID extension in DTLS 1.2.
+ *
+ * The padding will always be chosen so that the length of the
+ * padded plaintext is a multiple of the value of this option.
+ *
+ * Note: A value of \c 1 means that no padding will be used
+ *       for outgoing records.
+ *
+ * Note: On systems lacking division instructions,
+ *       a power of two should be preferred.
+ *
+ */
+//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16
+
+/** \def MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY
+ *
+ * This option controls the use of record plaintext padding
+ * in TLS 1.3.
+ *
+ * The padding will always be chosen so that the length of the
+ * padded plaintext is a multiple of the value of this option.
+ *
+ * Note: A value of \c 1 means that no padding will be used
+ *       for outgoing records.
+ *
+ * Note: On systems lacking division instructions,
+ *       a power of two should be preferred.
+ */
+//#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of outgoing plaintext fragments.
+ *
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
+ */
+//#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
+ *
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ *
+ * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * to account for a reassembled handshake message of maximum size,
+ * together with its reassembly bitmap.
+ *
+ * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
+ * should be sufficient for all practical situations as it allows
+ * to reassembly a large handshake message (such as a certificate)
+ * while buffering multiple smaller handshake messages.
+ *
+ */
+//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING             32768
+
+//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
+//#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+//#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* X509 options */
+//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
+//#define MBEDTLS_X509_MAX_FILE_PATH_LEN     512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
+
+/**
+ * Allow SHA-1 in the default TLS configuration for certificate signing.
+ * Without this build-time option, SHA-1 support must be activated explicitly
+ * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
+ * recommended because of it is possible to generate SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+/**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
+ * signature and ciphersuite selection. Without this build-time option, SHA-1
+ * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
+ * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
+ * default. At the time of writing, there is no practical attack on the use
+ * of SHA-1 in handshake signatures, hence this option is turned on by default
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+
+/**
+ * Uncomment the macro to let mbed TLS use your alternate implementation of
+ * mbedtls_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedtls_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedtls_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedtls_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
+
+/**
+ * Uncomment the macro to let Mbed TLS use your alternate implementation of
+ * mbedtls_platform_gmtime_r(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * gmtime() is not a thread-safe function as defined in the C standard. The
+ * library will try to use safer implementations of this function, such as
+ * gmtime_r() when available. However, if Mbed TLS cannot identify the target
+ * system, the implementation of mbedtls_platform_gmtime_r() will default to
+ * using the standard gmtime(). In this case, calls from the library to
+ * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
+ * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
+ * library are also guarded with this mutex to avoid race conditions. However,
+ * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
+ * unconditionally use the implementation for mbedtls_platform_gmtime_r()
+ * supplied at compile time.
+ */
+//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
+
+/**
+ * Enable the verified implementations of ECDH primitives from Project Everest
+ * (currently only Curve25519). This feature changes the layout of ECDH
+ * contexts and therefore is a compatibility break for applications that access
+ * fields of a mbedtls_ecdh_context structure directly. See also
+ * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h.
+ */
+//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
+
+/* \} name SECTION: Customisation configuration options */
+
+/* Target and application specific configurations
+ *
+ * Allow user to override any previous default.
+ *
+ */
+#if defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#include "mbedtls/config_psa.h"
+#endif
+
+#include "mbedtls/check_config.h"
+
+#endif /* MBEDTLS_CONFIG_H */

+ 1 - 0
application/include/readme.txt

@@ -0,0 +1 @@
+把需要适配luatos的接口头文件放在本目录,比如luat_air105_xxx.h

+ 53 - 0
application/src/luat_adc_air105.c

@@ -0,0 +1,53 @@
+#include "luat_adc.h"
+#include "luat_base.h"
+
+#include "core_adc.h"
+#include "platform_define.h"
+
+#define LUAT_LOG_TAG "luat.adc"
+#include "luat_log.h"
+
+int luat_adc_open(int ch, void *args)
+{
+    switch (ch)
+    {
+    case 0:
+        return 0;
+    case 1:
+        GPIO_Iomux(GPIOC_00, 2);
+        break;
+    case 2:
+        GPIO_Iomux(GPIOC_01, 2);
+        break;
+    case 3:
+        return -1;
+    case 4:
+        GPIO_Iomux(GPIOC_03, 2);
+        break;
+    case 5:
+        GPIO_Iomux(GPIOC_04, 2);
+        break;
+    case 6:
+        GPIO_Iomux(GPIOC_05, 2);
+        break;
+    default:
+        return -1;
+    }
+    ADC_ChannelOnOff(ch, 1);
+    return 0;
+}
+
+int luat_adc_read(int ch, int *val, int *val2)
+{
+    int voltage = 0;
+    voltage = ADC_GetChannelValue(ch);
+    *val = voltage;
+    *val2 = voltage;
+    return 0;
+}
+
+int luat_adc_close(int ch){
+    if (ch)
+        ADC_ChannelOnOff(ch, 0);
+    return 0;
+}

+ 257 - 0
application/src/luat_base_air105.c

@@ -0,0 +1,257 @@
+#include "luat_base.h"
+#include "luat_msgbus.h"
+#include "luat_fs.h"
+#include "luat_timer.h"
+#include "luat_lcd.h"
+#include "time.h"
+#include <stdlib.h>
+
+#include "app_interface.h"
+
+
+#ifdef LUAT_USE_LVGL
+#include "lvgl.h"
+void luat_lv_fs_init(void);
+void lv_bmp_init(void);
+void lv_png_init(void);
+void lv_split_jpeg_init(void);
+#endif
+
+LUAMOD_API int luaopen_gtfont( lua_State *L );
+
+static const luaL_Reg loadedlibs[] = {
+  {"_G", luaopen_base}, // _G
+  {LUA_LOADLIBNAME, luaopen_package}, // require
+  {LUA_COLIBNAME, luaopen_coroutine}, // coroutine协程库
+  {LUA_TABLIBNAME, luaopen_table},    // table库,操作table类型的数据结构
+  {LUA_IOLIBNAME, luaopen_io},        // io库,操作文件
+  {LUA_OSLIBNAME, luaopen_os},        // os库,已精简
+  {LUA_STRLIBNAME, luaopen_string},   // string库,字符串操作
+  {LUA_MATHLIBNAME, luaopen_math},    // math 数值计算
+//  {LUA_UTF8LIBNAME, luaopen_utf8},
+  {LUA_DBLIBNAME, luaopen_debug},     // debug库,已精简
+#ifdef LUAT_USE_DBG
+#ifndef LUAT_USE_SHELL
+#define LUAT_USE_SHELL
+#endif
+  {"dbg",  luaopen_dbg},               // 调试库
+#endif
+#if defined(LUA_COMPAT_BITLIB)
+  {LUA_BITLIBNAME, luaopen_bit32},    // 不太可能启用
+#endif
+// 往下是LuatOS定制的库, 如需精简请仔细测试
+//----------------------------------------------------------------------
+// 核心支撑库, 不可禁用!!
+  {"rtos",    luaopen_rtos},              // rtos底层库, 核心功能是队列和定时器
+  {"log",     luaopen_log},               // 日志库
+  {"timer",   luaopen_timer},             // 延时库
+//-----------------------------------------------------------------------
+// 设备驱动类, 可按实际情况删减. 即使最精简的固件, 也强烈建议保留uart库
+#ifdef LUAT_USE_UART
+  {"uart",    luaopen_uart},              // 串口操作
+#endif
+#ifdef LUAT_USE_GPIO
+  {"gpio",    luaopen_gpio},              // GPIO脚的操作
+#endif
+#ifdef LUAT_USE_I2C
+  {"i2c",     luaopen_i2c},               // I2C操作
+#endif
+#ifdef LUAT_USE_SPI
+  {"spi",     luaopen_spi},               // SPI操作
+#endif
+#ifdef LUAT_USE_ADC
+  {"adc",     luaopen_adc},               // ADC模块
+#endif
+// #ifdef LUAT_USE_SDIO
+//   {"sdio",     luaopen_sdio},             // SDIO模块
+// #endif
+#ifdef LUAT_USE_PWM
+  {"pwm",     luaopen_pwm},               // PWM模块
+#endif
+#ifdef LUAT_USE_WDT
+  {"wdt",     luaopen_wdt},               // watchdog模块
+#endif
+// #ifdef LUAT_USE_PM
+//   {"pm",      luaopen_pm},                // 电源管理模块
+// #endif
+#ifdef LUAT_USE_MCU
+  {"mcu",     luaopen_mcu},               // MCU特有的一些操作
+#endif
+// #ifdef LUAT_USE_HWTIMER
+//   {"hwtimer", luaopen_hwtimer},           // 硬件定时器
+// #endif
+#ifdef LUAT_USE_RTC
+  {"rtc", luaopen_rtc},                   // 实时时钟
+#endif
+  {"pin", luaopen_pin},                   // pin
+#ifdef LUAT_USE_DAC
+  {"dac", luaopen_dac},
+#endif
+#ifdef LUAT_USE_KEYBOARD
+  {"keyboard", luaopen_keyboard},
+#endif
+#ifdef LUAT_USE_OTP
+  {"otp", luaopen_otp},
+#endif
+#ifdef LUAT_USE_CAMERA
+  {"camera", luaopen_camera},
+#endif
+//-----------------------------------------------------------------------
+// 工具库, 按需选用
+#ifdef LUAT_USE_CRYPTO
+  {"crypto",luaopen_crypto},            // 加密和hash模块
+#endif
+#ifdef LUAT_USE_CJSON
+  {"json",    luaopen_cjson},          // json的序列化和反序列化
+#endif
+#ifdef LUAT_USE_ZBUFF
+  {"zbuff",   luaopen_zbuff},             // 像C语言语言操作内存块
+#endif
+#ifdef LUAT_USE_PACK
+  {"pack",    luaopen_pack},              // pack.pack/pack.unpack
+#endif
+  // {"mqttcore",luaopen_mqttcore},          // MQTT 协议封装
+  // {"libcoap", luaopen_libcoap},           // 处理COAP消息
+
+#ifdef LUAT_USE_GNSS
+  {"libgnss", luaopen_libgnss},           // 处理GNSS定位数据
+#endif
+#ifdef LUAT_USE_FS
+  {"fs",      luaopen_fs},                // 文件系统库,在io库之外再提供一些方法
+#endif
+#ifdef LUAT_USE_SENSOR
+  {"sensor",  luaopen_sensor},            // 传感器库,支持DS18B20
+#endif
+#ifdef LUAT_USE_SFUD
+  {"sfud", luaopen_sfud},              // sfud
+#endif
+#ifdef LUAT_USE_SFD
+  {"sfd",  luaopen_sfd},                
+#endif
+#ifdef LUAT_USE_DISP
+  {"disp",  luaopen_disp},              // OLED显示模块,支持SSD1306
+#endif
+#ifdef LUAT_USE_U8G2
+  {"u8g2", luaopen_u8g2},              // u8g2
+#endif
+
+#ifdef LUAT_USE_EINK
+  {"eink",  luaopen_eink},              // 电子墨水屏,试验阶段
+#endif
+
+#ifdef LUAT_USE_LVGL
+#ifndef LUAT_USE_LCD
+#define LUAT_USE_LCD
+#endif
+  {"lvgl",   luaopen_lvgl},
+#endif
+
+#ifdef LUAT_USE_LCD
+  {"lcd",    luaopen_lcd},
+#endif
+#ifdef LUAT_USE_STATEM
+  {"statem",    luaopen_statem},
+#endif
+#ifdef LUAT_USE_GTFONT
+  {"gtfont",    luaopen_gtfont},
+#endif
+#ifdef LUAT_USE_COREMARK
+  {"coremark", luaopen_coremark},
+#endif
+#ifdef LUAT_USE_FDB
+  {"fdb", luaopen_fdb},
+#endif
+#ifdef LUAT_USE_ZLIB
+  {"zlib", luaopen_zlib},
+#endif
+  {NULL, NULL}
+};
+
+// 按不同的rtconfig加载不同的库函数
+void luat_openlibs(lua_State *L) {
+    // 初始化队列服务
+    luat_msgbus_init();
+    //print_list_mem("done>luat_msgbus_init");
+    // 加载系统库
+    const luaL_Reg *lib;
+    /* "require" functions from 'loadedlibs' and set results to global table */
+    for (lib = loadedlibs; lib->func; lib++) {
+        luaL_requiref(L, lib->name, lib->func, 1);
+        lua_pop(L, 1);  /* remove lib */
+    }
+}
+
+void luat_os_reboot(int code) {
+	SystemReset();
+}
+
+const char* luat_os_bsp(void) {
+    return "air105";
+}
+
+void vConfigureTimerForRunTimeStats( void ) {}
+
+/** 设备进入待机模式 */
+void luat_os_standy(int timeout) {
+    return; // nop
+}
+
+void luat_ota_reboot(int timeout_ms) {
+  if (timeout_ms > 0)
+    luat_timer_mdelay(timeout_ms);
+  SystemReset();
+}
+
+#ifdef LUAT_USE_LVGL
+#include "app_interface.h"
+#define LVGL_TICK_PERIOD	10
+unsigned int gLVFlashTime;
+static timer_t *lv_timer;
+static int luat_lvg_handler(lua_State* L, void* ptr) {
+//	DBG("%u", lv_tick_get());
+    lv_task_handler();
+    return 0;
+}
+static int32_t _lvgl_handler(void *pData, void *pParam) {
+    rtos_msg_t msg = {0};
+    msg.handler = luat_lvg_handler;
+    luat_msgbus_put(&msg, 0);
+}
+#endif
+
+void luat_shell_poweron(int _drv);
+
+void luat_base_init(void)
+{
+	luat_gpio_init();
+#ifdef LUAT_USE_SHELL
+  luat_shell_poweron(0);
+#endif
+
+#ifdef LUAT_USE_LVGL
+  gLVFlashTime = 33;
+	lv_init();
+	lv_timer = Timer_Create(_lvgl_handler, NULL, NULL);
+	Timer_StartMS(lv_timer, LVGL_TICK_PERIOD, 1);
+#endif
+}
+
+time_t luat_time(time_t *_Time) {
+  if (_Time != NULL) {
+    *_Time = RTC_GetUTC();
+  }
+  return RTC_GetUTC();
+}
+
+//static uint32_t cri = 0;
+void luat_os_entry_cri(void) {
+//  if (cri == 0)
+//    cri = OS_EnterCritical();
+}
+
+void luat_os_exit_cri(void) {
+//  if (cri != 0) {
+//    OS_ExitCritical(cri);
+//    cri = 0;
+//  }
+}

+ 243 - 0
application/src/luat_camera_air105.c

@@ -0,0 +1,243 @@
+#include "app_interface.h"
+#include "luat_base.h"
+
+#include "luat_lcd.h"
+#include "luat_camera.h"
+#include "luat_msgbus.h"
+#include "luat_spi.h"
+#include "luat_gpio.h"
+
+#include "user.h"
+#include "zbar.h"
+#include "symbol.h"
+#include "image.h"
+
+#define LUAT_LOG_TAG "camera"
+#include "luat_log.h"
+
+static luat_lcd_conf_t* lcd_conf;
+
+#define DECODE_DONE (USER_EVENT_ID_START + 100)
+
+typedef struct
+{
+	HANDLE NotifyTaskHandler;
+	uint8_t TestBuf[4096];
+	uint8_t *DataCache;
+	uint32_t TotalSize;
+	uint32_t CurSize;
+	uint16_t Width;
+	uint16_t Height;
+	uint8_t DataBytes;
+	uint8_t IsDecode;
+	uint8_t BufferFull;
+}QR_DecodeCtrlStruct;
+
+static QR_DecodeCtrlStruct prvDecodeQR;
+
+static uint32_t prvVLen;
+static uint32_t drawVLen;
+
+static int32_t prvCamera_DCMICB(void *pData, void *pParam){
+    uint8_t zbar_scan = (uint8_t)pParam;
+    if (zbar_scan == 0){
+        Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
+        if (!pData){
+            prvVLen = 0;
+            return 0;
+        }
+        LCD_DrawStruct *draw = OS_Malloc(sizeof(LCD_DrawStruct));
+        if (!draw){
+            DBG("lcd flush no memory");
+            return -1;
+        }
+        uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.CPHA;
+        uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.CPOL;
+        draw->Mode = SPI_MODE_0;
+        if(CPHA&&CPOL)draw->Mode = SPI_MODE_3;
+        else if(CPOL)draw->Mode = SPI_MODE_1;
+        else if(CPHA)draw->Mode = SPI_MODE_2;
+		draw->Speed = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.bandrate;
+        if (((luat_spi_device_t*)(lcd_conf->userdata))->bus_id == 5) draw->SpiID = HSPI_ID0;
+        else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->userdata))->bus_id;
+		draw->CSPin = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.cs;
+		draw->DCPin = lcd_conf->pin_dc;
+        draw->x1 = 0;
+        draw->x2 = 239;
+        draw->y1 = prvVLen;
+        draw->y2 = prvVLen + drawVLen -1;
+        draw->xoffset = lcd_conf->xoffset;
+		draw->yoffset = lcd_conf->yoffset;
+        draw->Size = (draw->x2 - draw->x1 + 1) * (draw->y2 - draw->y1 + 1) * 2;
+        draw->ColorMode = COLOR_MODE_RGB_565;
+        draw->Data = OS_Malloc(draw->Size);
+        if (!draw->Data){
+            DBG("lcd flush data no memory");
+            OS_Free(draw);
+            return -1;
+        }
+    //	DBG_HexPrintf(RxBuf->Data, 8);
+        memcpy(draw->Data, RxBuf->Data, draw->Size);
+        Core_LCDDraw(draw);
+        prvVLen += drawVLen;
+        return 0;
+    }else if (zbar_scan == 1){
+        Buffer_Struct *RxBuf = (Buffer_Struct *)pData;
+        if (!pData)
+        {
+            if (!prvDecodeQR.DataCache)
+            {
+                prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
+                prvDecodeQR.BufferFull = 0;
+            }
+            else
+            {
+                if (prvDecodeQR.TotalSize != prvDecodeQR.CurSize)
+                {
+    //				DBG_ERR("%d, %d", prvDecodeQR.CurSize, prvDecodeQR.TotalSize);
+                }
+                else if (!prvDecodeQR.IsDecode)
+                {
+                    prvDecodeQR.IsDecode = 1;
+                    Task_SendEvent(prvDecodeQR.NotifyTaskHandler, DECODE_DONE, prvDecodeQR.DataCache, 0, 0);
+                    prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
+                    prvDecodeQR.BufferFull = 0;
+                }
+                else
+                {
+                    prvDecodeQR.BufferFull = 1;
+                }
+            }
+            prvDecodeQR.CurSize = 0;
+            return 0;
+        }
+        if (prvDecodeQR.DataCache)
+        {
+            if (prvDecodeQR.BufferFull)
+            {
+                if (!prvDecodeQR.IsDecode){
+                    prvDecodeQR.IsDecode = 1;
+                    Task_SendEvent(prvDecodeQR.NotifyTaskHandler, DECODE_DONE, prvDecodeQR.DataCache, 0, 0);
+                    prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
+                    prvDecodeQR.BufferFull = 0;
+                    prvDecodeQR.CurSize = 0;
+                }else{
+                    return 0;
+                }
+            }
+        }
+        else
+        {
+            prvDecodeQR.DataCache = malloc(prvDecodeQR.TotalSize);
+            prvDecodeQR.BufferFull = 0;
+            prvDecodeQR.CurSize = 0;
+        }
+        memcpy(&prvDecodeQR.DataCache[prvDecodeQR.CurSize], RxBuf->Data, RxBuf->MaxLen * 4);
+        prvDecodeQR.CurSize += RxBuf->MaxLen * 4;
+        if (prvDecodeQR.TotalSize < prvDecodeQR.CurSize){
+            DBG_ERR("%d,%d", prvDecodeQR.TotalSize, prvDecodeQR.CurSize);
+            prvDecodeQR.CurSize = 0;
+        }
+        return 0;
+    }
+}
+
+static void zbar_task(void *pData){
+    rtos_msg_t msg = {0};
+	OS_EVENT Event;
+	unsigned int len;
+	int ret;
+	char *string;
+	zbar_t *zbar;
+	LCD_DrawStruct *draw;
+	while (1) {
+		Task_GetEvent(prvDecodeQR.NotifyTaskHandler, DECODE_DONE, &Event, NULL, 0);
+		draw = malloc(sizeof(LCD_DrawStruct));
+        uint8_t CPHA = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.CPHA;
+        uint8_t CPOL = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.CPOL;
+        draw->Mode = SPI_MODE_0;
+        if(CPHA&&CPOL)draw->Mode = SPI_MODE_3;
+        else if(CPOL)draw->Mode = SPI_MODE_1;
+        else if(CPHA)draw->Mode = SPI_MODE_2;
+		draw->Speed = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.bandrate;
+        if (((luat_spi_device_t*)(lcd_conf->userdata))->bus_id == 5) draw->SpiID = HSPI_ID0;
+        else draw->SpiID = ((luat_spi_device_t*)(lcd_conf->userdata))->bus_id;
+		draw->CSPin = ((luat_spi_device_t*)(lcd_conf->userdata))->spi_config.cs;
+		draw->DCPin = lcd_conf->pin_dc;
+		draw->x1 = 0;
+		draw->x2 = prvDecodeQR.Width - 1;
+		draw->y1 = 0;
+		draw->y2 = prvDecodeQR.Height - 1;
+		draw->xoffset = lcd_conf->xoffset;
+		draw->yoffset = lcd_conf->yoffset;
+		draw->Size = prvDecodeQR.TotalSize;
+		draw->ColorMode = COLOR_MODE_GRAY;
+		draw->Data = Event.Param1;
+		Core_CameraDraw(draw);
+		zbar = zbar_create();
+		ret = zbar_run(zbar, prvDecodeQR.Width, prvDecodeQR.Height, Event.Param1);
+		if (ret > 0){
+			string = zbar_get_data_ptr(zbar, &len);
+            msg.handler = l_camera_handler;
+            msg.ptr = string;
+            msg.arg1 = 0;
+            msg.arg2 = len;
+            luat_msgbus_put(&msg, 1);
+		}
+		zbar_destory(zbar);
+		free(Event.Param1);
+		prvDecodeQR.IsDecode = 0;
+	}
+}
+
+
+int luat_camera_init(luat_camera_conf_t *conf){
+    lcd_conf = conf->lcd_conf;
+
+	GPIO_Iomux(GPIOD_01, 3);
+	GPIO_Iomux(GPIOD_02, 3);
+	GPIO_Iomux(GPIOD_03, 3);
+	GPIO_Iomux(GPIOD_08, 3);
+	GPIO_Iomux(GPIOD_09, 3);
+	GPIO_Iomux(GPIOD_10, 3);
+	GPIO_Iomux(GPIOD_11, 3);
+	GPIO_Iomux(GPIOE_00, 3);
+    GPIO_Iomux(GPIOE_01, 3);
+	GPIO_Iomux(GPIOE_02, 3);
+	GPIO_Iomux(GPIOE_03, 3);
+
+    luat_i2c_setup(conf->i2c_id,1,NULL);
+	
+    if (conf->zbar_scan == 1){
+        prvDecodeQR.DataCache = NULL;
+        prvDecodeQR.Width = lcd_conf->w;
+        prvDecodeQR.Height = lcd_conf->h;
+        prvDecodeQR.TotalSize = prvDecodeQR.Width * prvDecodeQR.Height;
+        prvDecodeQR.DataBytes = 1;
+        prvDecodeQR.NotifyTaskHandler = Task_Create(zbar_task, NULL, 8 * 1024, 1, "test zbar");
+    }
+    GPIO_Iomux(GPIOA_05, 2);
+    HWTimer_SetPWM(conf->pwm_id, conf->pwm_period, conf->pwm_pulse, 0);
+
+    luat_gpio_mode(conf->camera_pwdn, Luat_GPIO_OUTPUT, Luat_GPIO_DEFAULT, Luat_GPIO_HIGH);
+    luat_gpio_mode(conf->camera_rst, Luat_GPIO_OUTPUT, Luat_GPIO_DEFAULT, Luat_GPIO_HIGH);
+	luat_timer_us_delay(10);
+    luat_gpio_set(conf->camera_rst, Luat_GPIO_LOW);
+
+    for(size_t i = 0; i < conf->init_cmd_size; i++){
+        luat_i2c_send(conf->i2c_id, conf->i2c_addr, &(conf->init_cmd[i]), 2);
+        i++;
+	}
+
+    DCMI_Setup(0, 0, 0, 8, 0);
+	DCMI_SetCallback(prvCamera_DCMICB, conf->zbar_scan);
+
+    if (conf->zbar_scan == 0){
+        DCMI_SetCROPConfig(1, (conf->sensor_height-lcd_conf->h)/2, ((conf->sensor_width-lcd_conf->w)/2)*2, lcd_conf->h - 1, 2*lcd_conf->w - 1);
+        DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, 2, &drawVLen);	
+        prvVLen = 0;
+    }else if(conf->zbar_scan == 1){
+        DCMI_SetCROPConfig(1, (conf->sensor_height-prvDecodeQR.Height)/2, ((conf->sensor_width-prvDecodeQR.Width)/2)*prvDecodeQR.DataBytes, prvDecodeQR.Height - 1, prvDecodeQR.DataBytes*prvDecodeQR.Width - 1);
+        DCMI_CaptureSwitch(1, 0,lcd_conf->w, lcd_conf->h, prvDecodeQR.DataBytes, &drawVLen);	
+    }
+}

+ 427 - 0
application/src/luat_crypto_air105.c

@@ -0,0 +1,427 @@
+
+#include "luat_base.h"
+#include "luat_crypto.h"
+
+#include "app_interface.h"
+
+int luat_crypto_trng(char* buff, size_t len) {
+    size_t t = 0;
+    char tmp[4];
+    while (len > t) {
+        RNG_GetData((uint32_t*)tmp);
+        for (; t < len; t++)
+        {
+            buff[t] = (char)tmp[t % 4];
+        }
+    }
+    return 0;
+}
+
+
+#ifdef LUAT_USE_CRYPTO
+
+#define LUAT_LOG_TAG "crypto"
+#include "luat_log.h"
+
+#define PKG_USING_MBEDTLS
+
+#ifdef PKG_USING_MBEDTLS
+#include "mbedtls/cipher.h"
+#endif
+
+int l_crypto_cipher_xxx(lua_State *L, uint8_t flags) {
+    size_t cipher_size = 0;
+    size_t pad_size = 0;
+    size_t str_size = 0;
+    size_t key_size = 0;
+    size_t iv_size = 0;
+    const char* cipher = luaL_optlstring(L, 1, "AES-128-ECB", &cipher_size);
+    const char* pad = luaL_optlstring(L, 2, "PKCS7", &pad_size);
+    const char* str = luaL_checklstring(L, 3, &str_size);
+    const char* key = luaL_checklstring(L, 4, &key_size);
+    const char* iv = luaL_optlstring(L, 5, "", &iv_size);
+
+    int ret = 0;
+
+    unsigned char output[32] = {0};
+    size_t input_size = 0;
+    size_t output_size = 0;
+    size_t block_size = 0;
+    
+    luaL_Buffer buff;
+
+#ifdef PKG_USING_MBEDTLS
+    mbedtls_cipher_context_t ctx;
+    mbedtls_cipher_init(&ctx);
+
+
+
+    const mbedtls_cipher_info_t * _cipher = mbedtls_cipher_info_from_string(cipher);
+    if (_cipher == NULL) {
+        lua_pushstring(L, "bad cipher name");
+        lua_error(L);
+        return 0;
+    }
+
+
+	ret = mbedtls_cipher_setup(&ctx, _cipher);
+    if (ret) {
+        LLOGE("mbedtls_cipher_setup fail %ld", ret);
+        goto _exit;
+    }
+    ret = mbedtls_cipher_setkey(&ctx, key, key_size * 8, flags & 0x1);
+    if (ret) {
+        LLOGE("mbedtls_cipher_setkey fail %ld", ret);
+        goto _exit;
+    }
+    // TODO 设置padding mode
+    // mbedtls_cipher_set_padding_mode
+    if (iv_size) {
+        ret = mbedtls_cipher_set_iv(&ctx, iv, iv_size);
+        if (ret) {
+            LLOGE("mbedtls_cipher_set_iv fail %ld", ret);
+            goto _exit;
+        }
+    }
+
+    mbedtls_cipher_reset(&ctx);
+
+    //mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_PKCS7);
+
+    // 开始注入数据
+    luaL_buffinit(L, &buff);
+    block_size = mbedtls_cipher_get_block_size(&ctx);
+    for (size_t i = 0; i < str_size; i+=block_size) {
+        input_size = str_size - i;
+        if (input_size > block_size)
+            input_size = block_size;
+        ret = mbedtls_cipher_update(&ctx, str+i, input_size, output, &output_size);
+        if (ret) {
+            LLOGE("mbedtls_cipher_update fail %ld", ret);
+            goto _exit;
+        }
+        //else LLOGD("mbedtls_cipher_update, output size=%ld", output_size);
+        if (output_size > 0)
+            luaL_addlstring(&buff, output, output_size);
+        output_size = 0;
+    }
+    ret = mbedtls_cipher_finish(&ctx, output, &output_size);
+    if (ret) {
+        LLOGE("mbedtls_cipher_finish fail %ld", ret);
+        goto _exit;
+    }
+    //else LLOGD("mbedtls_cipher_finish, output size=%ld", output_size);
+    if (output_size > 0)
+        luaL_addlstring(&buff, output, output_size);
+
+_exit:
+    mbedtls_cipher_free(&ctx);
+    luaL_pushresult(&buff);
+    return 1;
+#else
+    return 0;
+#endif
+}
+
+
+#ifdef PKG_USING_MBEDTLS
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#ifdef MBEDTLS_SHA512_C
+#include "mbedtls/sha512.h"
+#endif
+#include "mbedtls/md5.h"
+
+#define LUAT_LOG_TAG "crypto"
+#include "luat_log.h"
+
+void luat_crypto_HmacSha1(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+void luat_crypto_HmacSha256(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+void luat_crypto_HmacSha512(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+void luat_crypto_HmacMd5(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen);
+
+#ifndef LUAT_CRYPTO_MD5
+#define LUAT_CRYPTO_MD5
+int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr) {
+    mbedtls_md5_context ctx;
+    mbedtls_md5_init(&ctx);
+
+    mbedtls_md5_starts(&ctx);
+    mbedtls_md5_update(&ctx, (const unsigned char *)str, str_size);
+    mbedtls_md5_finish(&ctx, (unsigned char *)out_ptr);
+    mbedtls_md5_free(&ctx);
+    return 0;
+}
+#endif
+#ifndef LUAT_CRYPTO_SHA1
+#define LUAT_CRYPTO_SHA1
+int luat_crypto_sha1_simple(const char* str, size_t str_size, void* out_ptr) {
+    mbedtls_sha1_context ctx;
+    mbedtls_sha1_init(&ctx);
+
+    mbedtls_sha1_starts(&ctx);
+    mbedtls_sha1_update(&ctx, (const unsigned char *)str, str_size);
+    mbedtls_sha1_finish(&ctx, (unsigned char *)out_ptr);
+    mbedtls_sha1_free(&ctx);
+    return 0;
+}
+#endif
+
+int luat_crypto_sha256_simple(const char* str, size_t str_size, void* out_ptr) {
+    mbedtls_sha256_context ctx;
+    mbedtls_sha256_init(&ctx);
+
+    mbedtls_sha256_starts(&ctx, 0);
+    mbedtls_sha256_update(&ctx, (const unsigned char *)str, str_size);
+    mbedtls_sha256_finish(&ctx, (unsigned char *)out_ptr);
+    mbedtls_sha256_free(&ctx);
+    return 0;
+}
+#ifdef MBEDTLS_SHA512_C
+int luat_crypto_sha512_simple(const char* str, size_t str_size, void* out_ptr) {
+    mbedtls_sha512_context ctx;
+    mbedtls_sha512_init(&ctx);
+
+    mbedtls_sha512_starts(&ctx, 0);
+    mbedtls_sha512_update(&ctx, (const unsigned char *)str, str_size);
+    mbedtls_sha512_finish(&ctx, (unsigned char *)out_ptr);
+    mbedtls_sha512_free(&ctx);
+    return 0;
+}
+#endif
+
+#ifndef LUAT_CRYPTO_MD5
+#define LUAT_CRYPTO_MD5
+int luat_crypto_hmac_md5_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacMd5((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+#endif
+#ifndef LUAT_CRYPTO_SHA1
+#define LUAT_CRYPTO_SHA1
+int luat_crypto_hmac_sha1_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacSha1((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+#endif
+
+int luat_crypto_hmac_sha256_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacSha256((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+#ifdef MBEDTLS_SHA512_C
+int luat_crypto_hmac_sha512_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
+    luat_crypto_HmacSha512((const unsigned char *)str, str_size, (unsigned char *)out_ptr, (const unsigned char *)mac, mac_size);
+    return 0;
+}
+#endif
+
+
+///----------------------------
+
+#define ALI_SHA1_KEY_IOPAD_SIZE (64)
+#define ALI_SHA1_DIGEST_SIZE    (20)
+
+#define ALI_SHA256_KEY_IOPAD_SIZE   (64)
+#define ALI_SHA256_DIGEST_SIZE      (32)
+
+#define ALI_SHA512_KEY_IOPAD_SIZE   (128)
+#define ALI_SHA512_DIGEST_SIZE      (64)
+
+#define ALI_MD5_KEY_IOPAD_SIZE  (64)
+#define ALI_MD5_DIGEST_SIZE     (16)
+
+// char atHb2Hex(unsigned char hb)
+// {
+//     hb = hb&0xF;
+//     return (char)(hb<10 ? '0'+hb : hb-10+'a');
+// }
+
+
+/*
+ * output = SHA-1( input buffer )
+ */
+void luat_crypto_HmacSha1(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    mbedtls_sha1_context ctx;
+    unsigned char k_ipad[ALI_SHA1_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_SHA1_KEY_IOPAD_SIZE] = {0};
+    unsigned char tempbuf[ALI_SHA1_DIGEST_SIZE];
+
+    memset(k_ipad, 0x36, ALI_SHA1_KEY_IOPAD_SIZE);
+    memset(k_opad, 0x5C, ALI_SHA1_KEY_IOPAD_SIZE);
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_SHA1_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+    mbedtls_sha1_init(&ctx);
+
+    mbedtls_sha1_starts(&ctx);
+    mbedtls_sha1_update(&ctx, k_ipad, ALI_SHA1_KEY_IOPAD_SIZE);
+    mbedtls_sha1_update(&ctx, input, ilen);
+    mbedtls_sha1_finish(&ctx, tempbuf);
+
+    mbedtls_sha1_starts(&ctx);
+    mbedtls_sha1_update(&ctx, k_opad, ALI_SHA1_KEY_IOPAD_SIZE);
+    mbedtls_sha1_update(&ctx, tempbuf, ALI_SHA1_DIGEST_SIZE);
+    mbedtls_sha1_finish(&ctx, tempbuf);
+
+    // for(i=0; i<ALI_SHA1_DIGEST_SIZE; ++i)
+    // {
+    //     output[i*2] = atHb2Hex(tempbuf[i]>>4);
+    //     output[i*2+1] = atHb2Hex(tempbuf[i]);
+    // }
+    memcpy(output, tempbuf, ALI_SHA1_DIGEST_SIZE);
+
+    mbedtls_sha1_free(&ctx);
+}
+/*
+ * output = SHA-256( input buffer )
+ */
+void luat_crypto_HmacSha256(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    mbedtls_sha256_context ctx;
+    unsigned char k_ipad[ALI_SHA256_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_SHA256_KEY_IOPAD_SIZE] = {0};
+
+    memset(k_ipad, 0x36, 64);
+    memset(k_opad, 0x5C, 64);
+
+    if ((NULL == input) || (NULL == key) || (NULL == output)) {
+        return;
+    }
+
+    if (keylen > ALI_SHA256_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_SHA256_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+    mbedtls_sha256_init(&ctx);
+
+    mbedtls_sha256_starts(&ctx, 0);
+    mbedtls_sha256_update(&ctx, k_ipad, ALI_SHA256_KEY_IOPAD_SIZE);
+    mbedtls_sha256_update(&ctx, input, ilen);
+    mbedtls_sha256_finish(&ctx, output);
+
+    mbedtls_sha256_starts(&ctx, 0);
+    mbedtls_sha256_update(&ctx, k_opad, ALI_SHA256_KEY_IOPAD_SIZE);
+    mbedtls_sha256_update(&ctx, output, ALI_SHA256_DIGEST_SIZE);
+    mbedtls_sha256_finish(&ctx, output);
+
+    mbedtls_sha256_free(&ctx);
+}
+#ifdef MBEDTLS_SHA512_C
+/*
+ * output = SHA-512( input buffer )
+ */
+void luat_crypto_HmacSha512(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    mbedtls_sha512_context ctx;
+    unsigned char k_ipad[ALI_SHA512_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_SHA512_KEY_IOPAD_SIZE] = {0};
+
+    memset(k_ipad, 0x36, ALI_SHA512_KEY_IOPAD_SIZE);
+    memset(k_opad, 0x5C, ALI_SHA512_KEY_IOPAD_SIZE);
+
+    if ((NULL == input) || (NULL == key) || (NULL == output)) {
+        return;
+    }
+
+    if (keylen > ALI_SHA512_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_SHA512_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+    mbedtls_sha512_init(&ctx);
+
+    mbedtls_sha512_starts(&ctx, 0);
+    mbedtls_sha512_update(&ctx, k_ipad, ALI_SHA512_KEY_IOPAD_SIZE);
+    mbedtls_sha512_update(&ctx, input, ilen);
+    mbedtls_sha512_finish(&ctx, output);
+
+    mbedtls_sha512_starts(&ctx, 0);
+    mbedtls_sha512_update(&ctx, k_opad, ALI_SHA512_KEY_IOPAD_SIZE);
+    mbedtls_sha512_update(&ctx, output, ALI_SHA512_DIGEST_SIZE);
+    mbedtls_sha512_finish(&ctx, output);
+
+    mbedtls_sha512_free(&ctx);
+}
+#endif
+/*
+ * output = MD-5( input buffer )
+ */
+void luat_crypto_HmacMd5(const unsigned char *input, int ilen, unsigned char *output,const unsigned char *key, int keylen)
+{
+    int i;
+    mbedtls_md5_context ctx;
+    unsigned char k_ipad[ALI_MD5_KEY_IOPAD_SIZE] = {0};
+    unsigned char k_opad[ALI_MD5_KEY_IOPAD_SIZE] = {0};
+    unsigned char tempbuf[ALI_MD5_DIGEST_SIZE];
+
+    memset(k_ipad, 0x36, ALI_MD5_KEY_IOPAD_SIZE);
+    memset(k_opad, 0x5C, ALI_MD5_KEY_IOPAD_SIZE);
+
+    for(i=0; i<keylen; i++)
+    {
+        if(i>=ALI_MD5_KEY_IOPAD_SIZE)
+        {
+            break;
+        }
+        k_ipad[i] ^=key[i];
+        k_opad[i] ^=key[i];
+    }
+    mbedtls_md5_init(&ctx);
+
+    mbedtls_md5_starts(&ctx);
+    mbedtls_md5_update(&ctx, k_ipad, ALI_MD5_KEY_IOPAD_SIZE);
+    mbedtls_md5_update(&ctx, input, ilen);
+    mbedtls_md5_finish(&ctx, tempbuf);
+
+    mbedtls_md5_starts(&ctx);
+    mbedtls_md5_update(&ctx, k_opad, ALI_MD5_KEY_IOPAD_SIZE);
+    mbedtls_md5_update(&ctx, tempbuf, ALI_MD5_DIGEST_SIZE);
+    mbedtls_md5_finish(&ctx, tempbuf);
+
+    // for(i=0; i<ALI_MD5_DIGEST_SIZE; ++i)
+    // {
+    //     output[i*2] = atHb2Hex(tempbuf[i]>>4);
+    //     output[i*2+1] = atHb2Hex(tempbuf[i]);
+    // }
+    memcpy(output, tempbuf, ALI_MD5_DIGEST_SIZE);
+    mbedtls_md5_free(&ctx);
+}
+#endif
+
+#endif

+ 24 - 0
application/src/luat_dac_air105.c

@@ -0,0 +1,24 @@
+#include "luat_base.h"
+#include "luat_dac.h"
+#include "app_interface.h"
+
+int luat_dac_setup(uint32_t ch, uint32_t freq, uint32_t mode) {
+    if (ch != 0)
+        return -1;
+    GPIO_Iomux(GPIOC_01, 2);
+    DAC_Init(0);
+    DAC_Setup(freq, mode);
+    return 0;
+}
+
+int luat_dac_write(uint32_t ch, uint16_t* buff, size_t len) {
+    if (ch != 0)
+        return -1;
+    DAC_Send(buff, len, NULL, NULL);
+    return 0;
+}
+
+int luat_dac_close(uint32_t ch) {
+    return 0; // 暂不支持关闭
+}
+

+ 154 - 0
application/src/luat_fs_air105.c

@@ -0,0 +1,154 @@
+#include "app_interface.h"
+#include "luat_base.h"
+#include "luat_fs.h"
+
+
+struct lfs_config mcu_flash_lfs_cfg;
+struct lfs LFS;
+
+#define LFS_BLOCK_DEVICE_READ_SIZE      (256)
+#define LFS_BLOCK_DEVICE_PROG_SIZE      (__FLASH_PAGE_SIZE__)
+#define LFS_BLOCK_DEVICE_LOOK_AHEAD     (16)
+#define LFS_BLOCK_DEVICE_CACHE_SIZE     (256)
+
+// 根据头文件的定义, 算出脚本区和文件系统区的绝对地址
+const size_t script_luadb_start_addr = __FLASH_BASE_ADDR__ + __CORE_FLASH_SECTOR_NUM__ * __FLASH_SECTOR_SIZE__ ;
+const size_t lfs_fs_start_addr = script_luadb_start_addr + __SCRIPT_FLASH_SECTOR_NUM__ * __FLASH_SECTOR_SIZE__ ;
+
+static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
+        lfs_off_t off, void *buffer, lfs_size_t size)
+{
+	uint32_t start_address = block * __FLASH_SECTOR_SIZE__ + off + lfs_fs_start_addr;
+	memcpy(buffer, start_address, size);
+//	DBG("%x, %u", start_address, size);
+//	DBG_HexPrintf(buffer, 16);
+	return LFS_ERR_OK;
+}
+
+static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
+        lfs_off_t off, const void *buffer, lfs_size_t size)
+{
+	uint32_t start_address = block * __FLASH_SECTOR_SIZE__ + off + lfs_fs_start_addr;
+//	DBG("%x", start_address);
+	if (Flash_ProgramData(start_address, buffer, size, 0))
+	{
+		return LFS_ERR_IO;
+
+	}
+	return LFS_ERR_OK;
+}
+
+static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block)
+{
+	uint32_t start_address = block * __FLASH_SECTOR_SIZE__ + lfs_fs_start_addr;
+//	DBG("%x", start_address);
+	if (Flash_EraseSector(start_address, 0))
+	{
+		return LFS_ERR_IO;
+	}
+	return LFS_ERR_OK;
+}
+
+static int block_device_sync(const struct lfs_config *cfg)
+{
+	//DBG_Trace("block_device_sync");
+    return 0;
+}
+
+#define LFS_BLOCK_DEVICE_READ_SIZE      (256)
+#define LFS_BLOCK_DEVICE_PROG_SIZE      (__FLASH_PAGE_SIZE__)
+#define LFS_BLOCK_DEVICE_LOOK_AHEAD     (16)
+#define LFS_BLOCK_DEVICE_CACHE_SIZE     (256)
+
+#ifdef __BUILD_APP__
+//__attribute__ ((aligned (8))) static char lfs_cache_buff[LFS_BLOCK_DEVICE_CACHE_SIZE];
+__attribute__ ((aligned (8))) static char lfs_read_buff[LFS_BLOCK_DEVICE_READ_SIZE];
+__attribute__ ((aligned (8))) static char lfs_prog_buff[LFS_BLOCK_DEVICE_PROG_SIZE];
+__attribute__ ((aligned (8))) static char lfs_lookahead_buff[16];
+#endif
+
+
+void FileSystem_Init(void)
+{
+	struct lfs_config *config = &mcu_flash_lfs_cfg;
+	//DBG_INFO("ID:%02x,%02x,%02x,Size:%uKB", Ctrl->FlashID[0], Ctrl->FlashID[1], Ctrl->FlashID[2], Ctrl->Size);
+	config->context = NULL;
+	config->cache_size = LFS_BLOCK_DEVICE_READ_SIZE;
+	config->prog_size = __FLASH_PAGE_SIZE__;
+	config->block_size = __FLASH_SECTOR_SIZE__;
+	config->read_size = LFS_BLOCK_DEVICE_READ_SIZE;
+	config->block_cycles = 200;
+	config->lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
+	//config->block_count = (Ctrl->Size / 4) - __CORE_FLASH_SECTOR_NUM__ - __SCRIPT_FLASH_SECTOR_NUM__;
+	config->block_count = 512 / 4 ;
+	config->name_max = 63;
+	config->read = block_device_read;
+	config->prog = block_device_prog;
+	config->erase = block_device_erase;
+	config->sync  = block_device_sync;
+
+	//config->buffer = (void*)lfs_cache_buff;
+	config->read_buffer = (void*)lfs_read_buff;
+	config->prog_buffer = (void*)lfs_prog_buff;
+	config->lookahead_buffer = (void*)lfs_lookahead_buff;
+/*
+ * 正式加入luatos代码可以开启
+ */
+	int re = lfs_mount(&LFS, &mcu_flash_lfs_cfg);
+	if (re) {
+		DBG_INFO("lfs, mount fail=%d", re);
+		re = lfs_format(&LFS, &mcu_flash_lfs_cfg);
+		if (re) {
+			DBG_INFO("lfs, format fail=%d", re);
+		}
+		else {
+			lfs_mount(&LFS, &mcu_flash_lfs_cfg);
+		}
+	}
+}
+
+extern const struct luat_vfs_filesystem vfs_fs_lfs2;
+extern const struct luat_vfs_filesystem vfs_fs_luadb;
+
+#ifdef LUAT_USE_VFS_INLINE_LIB
+//extern const char luadb_inline[];
+// extern const char luadb_inline_sys[];
+#endif
+
+int luat_fs_init(void) {
+	FileSystem_Init();
+	#ifdef LUAT_USE_FS_VFS
+	// vfs进行必要的初始化
+	luat_vfs_init(NULL);
+
+	// 注册vfs for posix 实现
+	luat_vfs_reg(&vfs_fs_lfs2);
+	luat_vfs_reg(&vfs_fs_luadb);
+	// 指向3M + 512k的littefs 文件区
+	luat_fs_conf_t conf = {
+		.busname = (char*)&LFS,
+		.type = "lfs2",
+		.filesystem = "lfs2",
+		.mount_point = "",
+	};
+	luat_fs_mount(&conf);
+
+	// 指向3M 的脚本区, luadb格式
+	luat_fs_conf_t conf2 = {
+		.busname = (char*)script_luadb_start_addr,
+		.type = "luadb",
+		.filesystem = "luadb",
+		.mount_point = "/luadb/",
+	};
+	luat_fs_mount(&conf2);
+	// #endif
+	#endif
+
+	#ifdef LUAT_USE_LVGL
+	luat_lv_fs_init();
+	//lv_bmp_init();
+	lv_png_init();
+	lv_split_jpeg_init();
+	#endif
+	return 0;
+}

+ 105 - 0
application/src/luat_gpio_air105.c

@@ -0,0 +1,105 @@
+#include "luat_base.h"
+#include "luat_malloc.h"
+#include "luat_msgbus.h"
+#include "luat_timer.h"
+#include "luat_gpio.h"
+#include "core_gpio.h"
+#include "platform_define.h"
+#include "luat_irq.h"
+
+typedef struct wm_gpio_conf
+{
+    luat_gpio_irq_cb cb;
+    void* args;
+}wm_gpio_conf_t;
+
+
+static wm_gpio_conf_t confs[HAL_GPIO_MAX];
+
+static void luat_gpio_irq_callback(void *ptr, void *pParam)
+{
+    int pin = (int)ptr;
+    luat_gpio_irq_cb cb = confs[pin].cb;
+    if (cb == NULL)
+        luat_irq_gpio_cb(pin, confs[pin].args);
+    else
+        cb(pin, confs[pin].args);
+}
+
+int luat_gpio_setup(luat_gpio_t *gpio){
+    if (gpio->pin < HAL_GPIO_2 || gpio->pin > HAL_GPIO_MAX) return 0;
+    GPIO_Iomux(gpio->pin, 1);
+    switch (gpio->mode){
+        case Luat_GPIO_OUTPUT:
+            GPIO_Config(gpio->pin, 0, 0);
+            break;
+        case Luat_GPIO_INPUT:
+            GPIO_Config(gpio->pin, 1, 0);
+            break;
+        case Luat_GPIO_IRQ:{
+            switch (gpio->irq){
+                case Luat_GPIO_RISING:
+                    GPIO_ExtiConfig(gpio->pin, 0,1,0);
+                    break;
+                case Luat_GPIO_FALLING:
+                    GPIO_ExtiConfig(gpio->pin, 0,0,1);
+                    break;
+                case Luat_GPIO_BOTH:
+                    GPIO_ExtiConfig(gpio->pin, 0,1,1);
+                default:
+                    break;
+            }
+            if (gpio->irq_cb) {
+                confs[gpio->pin].cb = gpio->irq_cb;
+                confs[gpio->pin].args = gpio->irq_args;
+            }
+
+        }break;
+        default:
+            break;
+    }
+    switch (gpio->pull){
+        case Luat_GPIO_PULLUP:
+            GPIO_PullConfig(gpio->pin, 1, 1);
+            break;
+        case Luat_GPIO_PULLDOWN:
+            GPIO_PullConfig(gpio->pin, 1, 0);
+            break;
+        case Luat_GPIO_DEFAULT:
+            GPIO_PullConfig(gpio->pin, 0, 0);
+        default:
+            break;
+    }
+    return 0;
+}
+
+int luat_gpio_set(int pin, int level){
+    if (pin < HAL_GPIO_2 || pin >= HAL_GPIO_MAX) return 0;
+    GPIO_Output(pin, level);
+    return 0;
+}
+
+int luat_gpio_get(int pin){
+    if (pin < HAL_GPIO_2 || pin >= HAL_GPIO_MAX) return 0;
+    int re = GPIO_Input(pin);
+    return re;
+}
+
+void luat_gpio_close(int pin){
+    if (pin < HAL_GPIO_2 || pin >= HAL_GPIO_MAX) return 0;
+    confs[pin].cb = NULL;
+    return 0;
+}
+
+void luat_gpio_init(void){
+    GPIO_GlobalInit(luat_gpio_irq_callback);
+}
+
+int luat_gpio_set_irq_cb(int pin, luat_gpio_irq_cb cb, void* args) {
+    if (pin < HAL_GPIO_2 || pin >= HAL_GPIO_MAX) return -1;
+    if (cb) {
+        confs[pin].cb = cb;
+        confs[pin].args = args;
+    }
+    return 0;
+}

+ 43 - 0
application/src/luat_i2c_air105.c

@@ -0,0 +1,43 @@
+
+#include "luat_base.h"
+#include "luat_i2c.h"
+
+#include "app_interface.h"
+
+#define LUAT_LOG_TAG "luat.i2c"
+#include "luat_log.h"
+
+int luat_i2c_exist(int id) {
+    return id == 0;
+}
+    
+int luat_i2c_setup(int id, int speed, int slaveaddr) {
+    if (speed == 0)
+        speed = 100 * 1000; // SLOW
+    else if (speed == 1)
+        speed = 400 * 1000; // FAST
+    else if (speed == 2)
+        speed = 400 * 1000; // SuperFast
+	GPIO_Iomux(GPIOE_06, 2);
+	GPIO_Iomux(GPIOE_07, 2);
+	I2C_MasterSetup(id, speed);
+    return 0;
+}
+
+int luat_i2c_close(int id) {
+    return 0;
+}
+
+int luat_i2c_send(int id, int addr, void* buff, size_t len) {
+    I2C_BlockWrite(id, addr, (const uint8_t *)buff, len, 100, NULL, NULL);
+    // I2C_Prepare(id, addr, 1, NULL, NULL);
+    // I2C_MasterXfer(id, I2C_OP_WRITE, 0, buff, len, 20);
+    return 0;
+}
+
+int luat_i2c_recv(int id, int addr, void* buff, size_t len) {
+    I2C_BlockRead(id, addr, 0, (uint8_t *)buff, len, 100, NULL, NULL);
+    // I2C_Prepare(id, addr, 1, NULL, NULL);
+    // I2C_MasterXfer(id, I2C_OP_READ, 0, buff, len, 20);
+    return 0;
+}

+ 51 - 0
application/src/luat_keyboard_air105.c

@@ -0,0 +1,51 @@
+#include "luat_base.h"
+#include "luat_keyboard.h"
+
+#include "app_interface.h"
+
+#define LUAT_LOG_TAG "keyboard"
+#include "luat_log.h"
+
+static luat_keyboard_irq_cb cb = NULL;
+
+static int32_t kb_cb(void *pData, void *pParam) {
+    if (cb) {
+        luat_keyboard_ctx_t ctx;
+        ctx.port = 0;
+        ctx.pin_data = (uint16_t) pData;
+        ctx.state = (((uint32_t)pData) >> 16) & 0x1;
+        //cb(&ctx);
+    }
+}
+
+int luat_keyboard_init(luat_keyboard_conf_t *conf) {
+    // 按conf->port_conf 设置io复用
+    if (conf->pin_conf & (1 << 0)) 
+        GPIO_Iomux(GPIOD_12, 2); // keyboard0
+    if (conf->pin_conf & (1 << 1))
+        GPIO_Iomux(GPIOD_13, 2); // keyboard1
+    if (conf->pin_conf & (1 << 2))
+        GPIO_Iomux(GPIOD_14, 2); // keyboard2
+    if (conf->pin_conf & (1 << 3))
+        GPIO_Iomux(GPIOD_15, 2); // keyboard3
+    if (conf->pin_conf & (1 << 4))
+        GPIO_Iomux(GPIOE_00, 2); // keyboard4
+    if (conf->pin_conf & (1 << 5))
+        GPIO_Iomux(GPIOE_01, 2); // keyboard5
+    if (conf->pin_conf & (1 << 6))
+        GPIO_Iomux(GPIOE_02, 2); // keyboard6
+    if (conf->pin_conf & (1 << 7))
+        GPIO_Iomux(GPIOD_10, 2); // keyboard7
+    if (conf->pin_conf & (1 << 8))
+        GPIO_Iomux(GPIOD_11, 2); // keyboard8
+    //---------------------------
+    cb = conf->cb;
+    KB_Setup(conf->pin_map, 7, kb_cb, NULL);
+    return 0;
+}
+
+int luat_keyboard_deinit(luat_keyboard_conf_t *conf) {
+    KB_Stop();
+    return 0;
+}
+

+ 41 - 0
application/src/luat_log_air105.c

@@ -0,0 +1,41 @@
+#include "luat_base.h"
+#include "luat_log.h"
+#include "luat_cmux.h"
+#include "luat_conf_bsp.h"
+#include "app_interface.h"
+
+extern uint8_t cmux_state;
+extern uint8_t cmux_log_state;
+
+void DBG_DirectOut(void *Data, uint32_t Len);
+
+void luat_nprint(char *s, size_t l) {
+#ifdef LUAT_USE_SHELL
+    if (cmux_state == 1 && cmux_log_state ==1){
+        luat_cmux_write(LUAT_CMUX_CH_LOG,  CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,s, l);
+    }else
+#endif
+    DBG_DirectOut(s, l);
+}
+
+void luat_log_write(char *s, size_t l) {
+#ifdef LUAT_USE_SHELL
+    if (cmux_state == 1 && cmux_log_state ==1){
+        luat_cmux_write(LUAT_CMUX_CH_LOG,  CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,s, l);
+    }else
+#endif
+    DBG_DirectOut(s, l);
+}
+
+static void luat_cmux_write_cb(uint8_t *data, uint32_t len){
+    luat_cmux_write(LUAT_CMUX_CH_LOG,  CMUX_FRAME_UIH & ~ CMUX_CONTROL_PF,data, len);
+}
+
+void luat_cmux_log_set(uint8_t state) {
+    if (state == 1){
+        DBG_SetTxCB(luat_cmux_write_cb);
+    }else if(state == 0){
+        DBG_SetTxCB(add_printf_data);
+    }
+    
+}

+ 109 - 0
application/src/luat_malloc_air105.c

@@ -0,0 +1,109 @@
+
+// 这个文件包含 系统heap和lua heap的默认实现
+
+
+#include <stdlib.h>
+#include <string.h>//add for memset
+#include "bget.h"
+#include "luat_malloc.h"
+
+#define LUAT_LOG_TAG "heap"
+#include "luat_log.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+
+//------------------------------------------------
+//  管理系统内存
+
+void* luat_heap_malloc(size_t len) {
+    return OS_Malloc(len);
+}
+
+void luat_heap_free(void* ptr) {
+    OS_Free(ptr);
+}
+
+void* luat_heap_realloc(void* ptr, size_t len) {
+    void* tmp = luat_heap_malloc(len);
+    if (tmp && ptr) {
+        memcpy(tmp, ptr, len);
+    }
+    return tmp;
+}
+
+void* luat_heap_calloc(size_t count, size_t _size) {
+    void *ptr = luat_heap_malloc(count * _size);
+    if (ptr) {
+        memset(ptr, 0, _size);
+    }
+    return ptr;
+}
+//------------------------------------------------
+
+//------------------------------------------------
+// ---------- 管理 LuaVM所使用的内存----------------
+void* luat_heap_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
+//    if (0) {
+//        if (ptr) {
+//            if (nsize) {
+//                // 缩放内存块
+//                LLOGD("realloc %p from %d to %d", ptr, osize, nsize);
+//            }
+//            else {
+//                // 释放内存块
+//                LLOGD("free %p ", ptr);
+//                OS_Free(ptr);
+//                return NULL;
+//            }
+//        }
+//        else {
+//            // 申请内存块
+//            ptr = OS_Malloc(nsize);
+//            LLOGD("malloc %p type=%d size=%d", ptr, osize, nsize);
+//            return ptr;
+//        }
+//    }
+
+    if (nsize)
+    {
+    	void* ptmp = pvPortMalloc(nsize);
+    	if (ptmp)
+    	{
+    		if (osize > nsize)
+    		{
+    			memcpy(ptmp, ptr, nsize);
+    		}
+    		else
+    		{
+    			memcpy(ptmp, ptr, osize);
+    		}
+    		vPortFree(ptr);
+    		return ptmp;
+    	}
+    	else if (osize >= nsize)
+    	{
+    		return ptr;
+    	}
+    }
+    vPortFree(ptr);
+    return NULL;
+}
+
+void luat_meminfo_luavm(size_t *total, size_t *used, size_t *max_used) {
+	*used = configTOTAL_HEAP_SIZE - xPortGetFreeHeapSize();
+	*max_used = configTOTAL_HEAP_SIZE - xPortGetMinimumEverFreeHeapSize();
+    *total = configTOTAL_HEAP_SIZE;
+}
+
+void luat_meminfo_sys(size_t *total, size_t *used, size_t *max_used) {
+	long curalloc, totfree, maxfree;
+	unsigned long nget, nrel;
+	bstats(&curalloc, &totfree, &maxfree, &nget, &nrel);
+	*used = curalloc;
+	*max_used = bstatsmaxget();
+    *total = curalloc + totfree;
+}
+
+//-----------------------------------------------------------------------------

+ 25 - 0
application/src/luat_mcu_air105.c

@@ -0,0 +1,25 @@
+#include "luat_base.h"
+#include "luat_mcu.h"
+
+#include "app_interface.h"
+
+#include "FreeRTOS.h"
+
+int luat_mcu_set_clk(size_t mhz) {
+    return 0;
+}
+
+int luat_mcu_get_clk(void) {
+    return 0;
+}
+
+static uint8_t unique_id[16] = {0};
+const char* luat_mcu_unique_id(size_t* t) {
+    OTP_GetSn(unique_id);
+    *t = sizeof(unique_id);
+    return unique_id;
+}
+
+long luat_mcu_ticks(void) {
+    return GetSysTickMS();
+}

+ 65 - 0
application/src/luat_msgbus_air105.c

@@ -0,0 +1,65 @@
+
+#include "luat_msgbus.h"
+
+#include "app_interface.h"
+#if 0
+#define QUEUE_LENGTH 0xFF
+#define ITEM_SIZE sizeof(rtos_msg_t)
+
+#if configSUPPORT_STATIC_ALLOCATION
+static StaticQueue_t xStaticQueue = {0};
+#endif
+static QueueHandle_t xQueue = {0};
+
+#if configSUPPORT_STATIC_ALLOCATION
+static uint8_t ucQueueStorageArea[ QUEUE_LENGTH * ITEM_SIZE ];
+#endif
+
+void luat_msgbus_init(void) {
+    if (!xQueue) {
+        #if configSUPPORT_STATIC_ALLOCATION
+        xQueue = xQueueCreateStatic( QUEUE_LENGTH,
+                                 ITEM_SIZE,
+                                 ucQueueStorageArea,
+                                 &xStaticQueue );
+        #else
+        xQueue = xQueueCreate(QUEUE_LENGTH, ITEM_SIZE);
+        #endif
+    }
+}
+
+uint32_t luat_msgbus_put(rtos_msg_t* msg, size_t timeout) {
+    if (xQueue == NULL)
+        return 1;
+    return xQueueSendFromISR(xQueue, msg, NULL) == pdTRUE ? 0 : 1;
+}
+
+uint32_t luat_msgbus_get(rtos_msg_t* msg, size_t timeout) {
+    if (xQueue == NULL)
+        return 1;
+    return xQueueReceive(xQueue, msg, timeout) == pdTRUE ? 0 : 1; // 要不要除portTICK_RATE_MS呢?
+}
+
+uint32_t luat_msgbus_freesize(void) {
+    if (xQueue == NULL)
+        return 1;
+    return 1;
+}
+#endif
+static HANDLE prvTaskHandle;
+void luat_msgbus_init(void) {
+	prvTaskHandle = Task_GetCurrent();
+}
+
+uint32_t luat_msgbus_put(rtos_msg_t* msg, size_t timeout) {
+    Task_SendEvent(prvTaskHandle, msg->handler, (uint32_t)msg->ptr, msg->arg1, msg->arg2);
+    return 0;
+}
+
+uint32_t luat_msgbus_get(rtos_msg_t* msg, size_t timeout) {
+    return Task_GetEventByMS(prvTaskHandle, 0, msg, NULL, timeout);
+}
+
+uint32_t luat_msgbus_freesize(void) {
+    return 1;
+}

+ 29 - 0
application/src/luat_otp_air105.c

@@ -0,0 +1,29 @@
+#include "luat_base.h"
+#include "luat_otp.h"
+
+#include "app_interface.h"
+
+int luat_otp_read(int zone, char* buff, size_t offset, size_t len) {
+    if (zone < 0 || zone > 2)
+        return -1;
+    int addr = zone * 1024 + offset;
+    OTP_Read((uint32_t)addr, (const uint32_t *)buff, len / 4);
+    return len;
+}
+
+int luat_otp_write(int zone, char* buff, size_t offset, size_t len) {
+    if (zone < 0 || zone > 2)
+        return -1;
+    int addr = zone * 1024 + offset;
+    OTP_Write(addr, (const uint32_t *)buff, len / 4);
+    return 0;
+}
+
+int luat_otp_erase(int zone, size_t offset, size_t len) {
+    return 0; // 无需主动擦除
+}
+
+int luat_otp_lock(int zone) {
+    OTP_Lock();
+    return 0;
+}

+ 22 - 0
application/src/luat_pin_air105.c

@@ -0,0 +1,22 @@
+#include "app_interface.h"
+#include "luat_base.h"
+
+#define LUAT_LOG_TAG "pin"
+#include "luat_log.h"
+
+#include "luat_pin.h"
+
+int luat_pin_to_gpio(const char* pin_name) {
+    int zone = 0;
+    int index = 0;
+    int re = 0;
+    re = luat_pin_parse(pin_name, &zone, &index);
+    if (re < 0) {
+        return -1;
+    }
+    // PA00 ~ PF15
+    if (zone < 6 && index < 16) {
+        return zone*16 + index;
+    }
+    return -1;
+}

+ 104 - 0
application/src/luat_pwm_air105.c

@@ -0,0 +1,104 @@
+
+#include "luat_base.h"
+#include "luat_pwm.h"
+
+#include "app_interface.h"
+
+#define LUAT_LOG_TAG "luat.pwm"
+#include "luat_log.h"
+
+int luat_pwm_setup(luat_pwm_conf_t* conf) {
+    int channel = conf->channel;
+	size_t period = conf->period;
+	size_t pulse = conf->pulse;
+	size_t pnum = conf->pnum;
+	size_t precision = conf->precision;
+
+	if (precision != 100 && precision != 1000) {
+		LLOGW("only 100 or 1000 PWM precision supported");
+		return -1;
+	}
+
+	switch (channel)
+	{
+		case 0:
+			GPIO_Iomux(GPIOB_00, 2);
+			break;
+		case 1:
+			GPIO_Iomux(GPIOB_01, 2);
+			break;
+		case 2:
+			GPIO_Iomux(GPIOA_02, 2);
+			break;
+		case 3:
+			GPIO_Iomux(GPIOA_03, 2);
+			break;
+		case 4:
+			GPIO_Iomux(GPIOC_06, 2);
+			break;
+		case 5:
+			GPIO_Iomux(GPIOC_07, 2);
+			break;
+		case 6:
+			GPIO_Iomux(GPIOC_08, 2);
+			break;
+		case 7:
+			GPIO_Iomux(GPIOC_09, 2);
+			break;
+		default:
+			break;
+	}
+
+	// 主频48M
+	//uint32_t hz = 48000000 / period / precision;
+
+	//HWTimer_StartPWM(channel, hz * pulse, hz * (precision - pulse), pnum);
+	HWTimer_SetPWM(channel, period, pulse * (1000 / precision), pnum);
+    return 0;
+}
+
+// @return -1 打开失败。 0 打开成功
+int luat_pwm_open(int channel, size_t period, size_t pulse,int pnum) {
+	switch (channel)
+	{
+		case 0:
+			GPIO_Iomux(GPIOB_00, 2);
+			break;
+		case 1:
+			GPIO_Iomux(GPIOB_01, 2);
+			break;
+		case 2:
+			GPIO_Iomux(GPIOA_02, 2);
+			break;
+		case 3:
+			GPIO_Iomux(GPIOA_03, 2);
+			break;
+		case 4:
+			GPIO_Iomux(GPIOC_06, 2);
+			break;
+		case 5:
+			GPIO_Iomux(GPIOC_07, 2);
+			break;
+		case 6:
+			GPIO_Iomux(GPIOC_08, 2);
+			break;
+		case 7:
+			GPIO_Iomux(GPIOC_09, 2);
+			break;
+		default:
+			break;
+	}
+	HWTimer_SetPWM(channel, period, pulse * 10, pnum);
+    return 0;
+}
+
+int luat_pwm_capture(int channel,int freq) {
+	return 0;
+}
+
+// @return -1 关闭失败。 0 关闭成功
+int luat_pwm_close(int channel) {
+    HWTimer_Stop(channel);
+    return 0;
+}
+

+ 45 - 0
application/src/luat_rtc_air105.c

@@ -0,0 +1,45 @@
+#include "luat_base.h"
+#include "luat_rtc.h"
+#include "app_interface.h"
+
+int luat_rtc_set(struct tm *tblock) {
+	Date_UserDataStruct Date;
+	Time_UserDataStruct Time;
+
+    Time.Sec = tblock->tm_sec;
+    Time.Min = tblock->tm_min;
+    Time.Hour = tblock->tm_hour;
+    //tblock->tm_wday = uTime.Time.Week;
+
+    Date.Year = tblock->tm_year;
+    Date.Mon = tblock->tm_mon;
+    Date.Day = tblock->tm_mday;
+
+    RTC_SetDateTime(&Date, &Time, 1);
+    return 0;
+}
+
+int luat_rtc_get(struct tm *tblock) {
+	Date_UserDataStruct Date;
+	Time_UserDataStruct Time;
+    
+    RTC_GetDateTime(&Date, &Time);
+    
+    tblock->tm_sec = Time.Sec;
+    tblock->tm_min = Time.Min;
+    tblock->tm_hour = Time.Hour;
+    tblock->tm_wday = Time.Week;
+
+    tblock->tm_year = Date.Year;
+    tblock->tm_mon = Date.Mon;
+    tblock->tm_mday = Date.Day;
+    return 0;
+}
+
+int luat_rtc_timer_start(int id, struct tm *tblock) {
+    return -1; // 暂不支持
+}
+
+int luat_rtc_timer_stop(int id) {
+    return -1; // 暂不支持
+}

+ 63 - 0
application/src/luat_sfd_onchip_air105.c

@@ -0,0 +1,63 @@
+#include "luat_base.h"
+#include "luat_sfd.h"
+
+// #ifdef LUAT_SFD_ONCHIP
+
+#define LUAT_LOG_TAG "onchip"
+#include "luat_log.h"
+
+#include "app_interface.h"
+
+extern const size_t script_luadb_start_addr;
+
+int sfd_onchip_init (void* userdata) {
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+       return -1;
+    onchip->addr = script_luadb_start_addr - 64*1024;
+    return 0;
+}
+
+int sfd_onchip_status (void* userdata) {
+    return 0;
+}
+
+int sfd_onchip_read (void* userdata, char* buff, size_t offset, size_t len) {
+    int ret;
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+       return -1;
+    mempcpy(buff, (char*)(offset + onchip->addr), len);
+    return 0;
+}
+
+int sfd_onchip_write (void* userdata, const char* buff, size_t offset, size_t len) {
+    int ret;
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+       return -1;
+    ret = Flash_ProgramData(offset + onchip->addr, (uint32_t *)buff, len, 0);
+    if (ret != 0)
+    {
+        return -1;
+    }
+    return 0;
+}
+int sfd_onchip_erase (void* userdata, size_t offset, size_t len) {
+    int ret;
+    sfd_onchip_t* onchip = (sfd_onchip_t*)userdata;
+    if (onchip == NULL)
+       return -1;
+    ret = Flash_EraseSector(offset + onchip->addr, 0);
+    if (ret != 0)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+int sfd_onchip_ioctl (void* userdata, size_t cmd, void* buff) {
+    return 0;
+}
+
+// #endif

+ 61 - 0
application/src/luat_shell_air105.c

@@ -0,0 +1,61 @@
+
+#include "luat_base.h"
+#include "luat_shell.h"
+
+#include "luat_uart.h"
+#include "app_interface.h"
+
+
+#define LUAT_LOG_TAG "luat.shell"
+#include "luat_log.h"
+enum
+{
+	SHELL_READ_DATA = USER_EVENT_ID_START + 1,
+};
+static HANDLE prvhShell;
+void luat_shell_write(char* buff, size_t len) {
+    DBG_DirectOut(buff, len);
+}
+
+void luat_shell_notify_recv(void) {
+}
+
+
+static int32_t luat_shell_uart_cb(void *pData, void *pParam){
+    Task_SendEvent(prvhShell, SHELL_READ_DATA, 0, 0, 0);
+    return -1;
+}
+
+static void luat_shell(void *sdata)
+{
+	OS_EVENT Event;
+	char buff[512];
+	int ret = 0;
+	int len = 1;
+	while (1) {
+		// printf("tls_os_queue_receive \r");
+		Task_GetEvent(prvhShell, CORE_EVENT_ID_ANY, &Event, NULL, 0);
+		len = 1;
+		while (len > 0 && len < 512) {
+            len = Uart_RxBufferRead(0, buff, 512);
+            if (len > 0 && len < 512){
+                buff[len] = 0x00; // 确保结尾
+                luat_shell_push(buff, len);
+            }
+		}
+		// printf("shell loop end\r");
+	}
+}
+
+void luat_shell_poweron(int _drv) {
+	DBG_SetRxCB(luat_shell_uart_cb);
+	if (!prvhShell)
+	{
+		prvhShell = Task_Create(luat_shell,
+                NULL, 
+                2048,
+                1,
+                "luat_shell");
+	}
+
+}

+ 230 - 0
application/src/luat_spi_air105.c

@@ -0,0 +1,230 @@
+
+
+#include "luat_base.h"
+#include "luat_spi.h"
+#include "luat_lcd.h"
+
+#include "app_interface.h"
+
+#define LUAT_LOG_TAG "luat.spi"
+#include "luat_log.h"
+
+typedef struct
+{
+	uint8_t id;
+	uint8_t mark;
+    uint8_t mode;//spi模式
+}Spi_Struct;
+
+static Spi_Struct luat_spi[6] ={0};
+
+int32_t luat_spi_cb(void *pData, void *pParam){
+//    LLOGD("luat_spi_cb pData:%d pParam:%d ",(int)pData,(int)pParam);
+    switch ((int)pData){
+        case 0:
+            luat_spi[5].mark = 0;
+            break;
+        case 1:
+            luat_spi[0].mark = 0;
+            break;
+        case 2:
+            luat_spi[1].mark = 0;
+            break;
+        case 3:
+            luat_spi[2].mark = 0;
+            break;
+        default:
+            break;
+    }
+}
+
+int luat_spi_device_config(luat_spi_device_t* spi_dev) {
+    uint8_t spi_mode = SPI_MODE_0;
+    if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
+    else if(spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_1;
+    else if(spi_dev->spi_config.CPHA)spi_mode = SPI_MODE_2;
+    SPI_SetNewConfig(luat_spi[spi_dev->bus_id].id, spi_dev->spi_config.bandrate, spi_mode);
+    return 0;
+}
+
+int luat_spi_bus_setup(luat_spi_device_t* spi_dev){
+    int bus_id = spi_dev->bus_id;
+    if (bus_id == 0) {
+        luat_spi[bus_id].id=SPI_ID0;
+        GPIO_Iomux(GPIOB_12, 0);
+        GPIO_Iomux(GPIOB_14, 0);
+        GPIO_Iomux(GPIOB_15, 0);
+    }
+    else if (bus_id == 1) {
+        luat_spi[bus_id].id=SPI_ID1;
+	    GPIO_Iomux(GPIOA_06,3);
+	    GPIO_Iomux(GPIOA_08,3);
+	    GPIO_Iomux(GPIOA_09,3);
+    }
+    else if (bus_id == 2) {
+        luat_spi[bus_id].id=SPI_ID2;
+	    GPIO_Iomux(GPIOB_02,0);
+	    GPIO_Iomux(GPIOB_04,0);
+	    GPIO_Iomux(GPIOB_05,0);
+    }
+    else if (bus_id == 5) {
+        luat_spi[bus_id].id=HSPI_ID0;
+	    GPIO_Iomux(GPIOC_12,3);
+	    GPIO_Iomux(GPIOC_13,3);
+	    GPIO_Iomux(GPIOC_15,3);
+    }
+    else {
+        return -1;
+    }
+    uint8_t spi_mode = SPI_MODE_0;
+    if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
+    else if(spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_1;
+    else if(spi_dev->spi_config.CPHA)spi_mode = SPI_MODE_2;
+    luat_spi[bus_id].mode=spi_dev->spi_config.mode;
+    // LLOGD("SPI_MasterInit luat_bus_%d:%d dataw:%d spi_mode:%d bandrate:%d ",bus_id,luat_spi[bus_id].id, spi_dev->spi_config.dataw, spi_mode, spi_dev->spi_config.bandrate);
+    SPI_MasterInit(luat_spi[bus_id].id, spi_dev->spi_config.dataw, spi_mode, spi_dev->spi_config.bandrate, luat_spi_cb, NULL);
+    return 0;
+}
+
+//初始化配置SPI各项参数,并打开SPI
+//成功返回0
+int luat_spi_setup(luat_spi_t* spi) {
+    uint8_t spi_id = spi->id;
+    if (spi_id == 0) {
+        luat_spi[spi_id].id=SPI_ID0;
+        if (spi_id == 0 || spi->cs == GPIOB_13)
+            GPIO_Iomux(GPIOB_13, 0);
+        GPIO_Iomux(GPIOB_12, 0);
+        GPIO_Iomux(GPIOB_14, 0);
+        GPIO_Iomux(GPIOB_15, 0);
+    }
+    else if (spi_id == 1) {
+        luat_spi[spi_id].id=SPI_ID1;
+        if (spi_id == 1 || spi->cs == GPIOA_07)
+	        GPIO_Iomux(GPIOA_07,3);
+	    GPIO_Iomux(GPIOA_06,3);
+	    GPIO_Iomux(GPIOA_08,3);
+	    GPIO_Iomux(GPIOA_09,3);
+    }
+    else if (spi_id == 2) {
+        luat_spi[spi_id].id=SPI_ID2;
+        if (spi_id == 2 || spi->cs == GPIOB_03)
+	        GPIO_Iomux(GPIOB_03,0);
+	    GPIO_Iomux(GPIOB_02,0);
+	    GPIO_Iomux(GPIOB_04,0);
+	    GPIO_Iomux(GPIOB_05,0);
+    }
+    else if (spi_id == 5) {
+        luat_spi[spi_id].id=HSPI_ID0;
+        if (spi_id == 5 || spi->cs == GPIOC_14)
+	        GPIO_Iomux(GPIOC_14,3);
+	    GPIO_Iomux(GPIOC_12,3);
+	    GPIO_Iomux(GPIOC_13,3);
+	    GPIO_Iomux(GPIOC_15,3);
+    }
+    else {
+        return -1;
+    }
+    uint8_t spi_mode = SPI_MODE_0;
+    if(spi->CPHA&&spi->CPOL)spi_mode = SPI_MODE_3;
+    else if(spi->CPOL)spi_mode = SPI_MODE_1;
+    else if(spi->CPHA)spi_mode = SPI_MODE_2;
+    luat_spi[spi_id].mode=spi->mode;
+    // LLOGD("SPI_MasterInit luat_spi%d:%d dataw:%d spi_mode:%d bandrate:%d ",spi_id,luat_spi[spi_id], spi->dataw, spi_mode, spi->bandrate);
+    SPI_MasterInit(luat_spi[spi_id].id, spi->dataw, spi_mode, spi->bandrate, luat_spi_cb, NULL);
+    return 0;
+}
+
+//关闭SPI,成功返回0
+int luat_spi_close(int spi_id) {
+    return 0;
+}
+//收发SPI数据,返回接收字节数
+int luat_spi_transfer(int spi_id, const char* send_buf, size_t send_length, char* recv_buf, size_t recv_length) {
+    // LLOGD("SPI_MasterInit luat_spi%d:%d send_buf:%x recv_buf:%x length:%d ",spi_id,luat_spi[spi_id], *send_buf, *recv_buf, length);
+    // while(luat_spi[spi_id].mark)
+    luat_spi[spi_id].mark = 1;
+    if(luat_spi[spi_id].mode==1)
+        SPI_FlashBlockTransfer(luat_spi[spi_id].id, send_buf, send_length, recv_buf, recv_length);
+    else
+    	SPI_BlockTransfer(luat_spi[spi_id].id, send_buf, recv_buf, recv_length);
+    return recv_length;
+}
+//收SPI数据,返回接收字节数
+int luat_spi_recv(int spi_id, char* recv_buf, size_t length) {
+    // LLOGD("SPI_MasterInit luat_spi%d:%d recv_buf:%x length:%d ",spi_id,luat_spi[spi_id], *recv_buf, length);
+    // while(luat_spi[spi_id].mark)
+    luat_spi[spi_id].mark = 1;
+    SPI_BlockTransfer(luat_spi[spi_id].id, recv_buf, recv_buf, length);
+    return length;
+}
+//发SPI数据,返回发送字节数
+int luat_spi_send(int spi_id, const char* send_buf, size_t length) {
+    // LLOGD("luat_spi_send luat_spi%d:%d send_buf:%x length:%d ",spi_id,luat_spi[spi_id], *send_buf, length);
+    // while(luat_spi[spi_id].mark)
+    luat_spi[spi_id].mark = 1;
+    SPI_BlockTransfer(luat_spi[spi_id].id, send_buf, NULL, length);
+    return length;
+}
+
+int luat_lcd_draw_no_block(luat_lcd_conf_t* conf, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, luat_color_t* color, uint8_t last_flush)
+{
+	uint32_t retry_cnt = 0;
+	uint32_t cache_len = Core_LCDDrawCacheLen();
+//	if (last_flush)
+//	{
+//		LLOGD("lcd flush done!");
+//	}
+
+	if (conf->port == LUAT_LCD_SPI_DEVICE){
+		while (Core_LCDDrawCacheLen() > (conf->buffer_size))
+		{
+			retry_cnt++;
+			luat_timer_mdelay(1);
+		}
+		if (retry_cnt)
+		{
+			LLOGD("lcd flush delay %ums, status %u,%u,%u,%d", retry_cnt, cache_len, x2-x1+1, y2-y1+1, last_flush);
+		}
+		LCD_DrawStruct *draw = OS_Malloc(sizeof(LCD_DrawStruct));
+		if (!draw)
+		{
+			LLOGE("lcd flush no memory");
+			return -1;
+		}
+		luat_spi_device_t* spi_dev = (luat_spi_device_t*)conf->userdata;
+		int spi_id = spi_dev->bus_id;
+	    uint8_t spi_mode = SPI_MODE_0;
+	    if(spi_dev->spi_config.CPHA&&spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_3;
+	    else if(spi_dev->spi_config.CPOL)spi_mode = SPI_MODE_1;
+	    else if(spi_dev->spi_config.CPHA)spi_mode = SPI_MODE_2;
+
+	    draw->Mode = spi_mode;
+	    draw->Speed = spi_dev->spi_config.bandrate;
+	    draw->SpiID = luat_spi[spi_id].id;
+	    draw->CSPin = spi_dev->spi_config.cs;
+	    draw->DCPin = conf->pin_dc;
+	    draw->x1 = x1;
+	    draw->x2 = x2;
+	    draw->y1 = y1;
+	    draw->y2 = y2;
+	    draw->xoffset = conf->xoffset;
+	    draw->yoffset = conf->yoffset;
+	    draw->Size = (draw->x2 - draw->x1 + 1) * (draw->y2 - draw->y1 + 1) * 2;
+	    draw->ColorMode = COLOR_MODE_RGB_565;
+	    draw->Data = OS_Malloc(draw->Size);
+		if (!draw->Data)
+		{
+			LLOGE("lcd flush data no memory");
+			OS_Free(draw);
+			return -1;
+		}
+	    memcpy(draw->Data, color, draw->Size);
+	    Core_LCDDraw(draw);
+	    return 0;
+	}
+	else
+	{
+		return -1;
+	}
+}

+ 103 - 0
application/src/luat_timer_air105.c

@@ -0,0 +1,103 @@
+
+#include "luat_base.h"
+#include "luat_malloc.h"
+#include "luat_timer.h"
+#include "luat_msgbus.h"
+#include "app_interface.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+
+#define LUAT_LOG_TAG "luat.timer"
+#include "luat_log.h"
+
+#define FREERTOS_TIMER_COUNT 128
+static luat_timer_t* timers[FREERTOS_TIMER_COUNT] = {0};
+/*
+static void luat_timer_callback(TimerHandle_t xTimer) {
+    //LLOGD("timer callback");
+    rtos_msg_t msg;
+    luat_timer_t *timer = (luat_timer_t*) pvTimerGetTimerID(xTimer);
+    msg.handler = timer->func;
+    msg.ptr = timer;
+    msg.arg1 = 0;
+    msg.arg2 = 0;
+    int re = luat_msgbus_put(&msg, 0);
+    //LLOGD("timer msgbus re=%ld", re);
+}
+*/
+static int32_t luat_timer_callback(void *pData, void *pParam)
+{
+    rtos_msg_t msg;
+    luat_timer_t *timer = (luat_timer_t*)pParam;
+    msg.handler = timer->func;
+    msg.ptr = timer;
+    msg.arg1 = 0;
+    msg.arg2 = 0;
+    luat_msgbus_put(&msg, 0);
+}
+
+static int nextTimerSlot() {
+    for (size_t i = 0; i < FREERTOS_TIMER_COUNT; i++)
+    {
+        if (timers[i] == NULL) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int luat_timer_start(luat_timer_t* timer) {
+    Timer_t *os_timer;
+    int timerIndex;
+    //LLOGD(">>luat_timer_start timeout=%ld", timer->timeout);
+    timerIndex = nextTimerSlot();
+    //LLOGD("timer id=%ld", timerIndex);
+    if (timerIndex < 0) {
+        return 1; // too many timer!!
+    }
+    os_timer = Timer_Create(luat_timer_callback, timer, NULL);
+    //LLOGD("timer id=%ld, osTimerNew=%p", timerIndex, os_timer);
+    if (!os_timer) {
+        return -1;
+    }
+    timers[timerIndex] = timer;
+    
+    timer->os_timer = os_timer;
+    return Timer_StartMS(os_timer, timer->timeout, timer->repeat);
+}
+
+int luat_timer_stop(luat_timer_t* timer) {
+    if (!timer)
+        return 1;
+    for (size_t i = 0; i < FREERTOS_TIMER_COUNT; i++)
+    {
+        if (timers[i] == timer) {
+            timers[i] = NULL;
+            break;
+        }
+    }
+    Timer_Release(timer->os_timer);
+    return 0;
+};
+
+luat_timer_t* luat_timer_get(size_t timer_id) {
+    for (size_t i = 0; i < FREERTOS_TIMER_COUNT; i++)
+    {
+        if (timers[i] && timers[i]->id == timer_id) {
+            return timers[i];
+        }
+    }
+    return NULL;
+}
+
+
+int luat_timer_mdelay(size_t ms) {
+    Task_DelayMS(ms);
+    return 0;
+}
+
+
+void luat_timer_us_delay(size_t time){
+	Task_DelayUS(time);
+}

+ 226 - 0
application/src/luat_uart_air105.c

@@ -0,0 +1,226 @@
+#include "luat_base.h"
+#include "luat_malloc.h"
+#include "luat_msgbus.h"
+#include "luat_uart.h"
+
+#include "core_uart.h"
+#include "platform_define.h"
+
+#define LUAT_LOG_TAG "luat.uart"
+#include "luat_log.h"
+
+// #define UART_RX_USE_DMA
+
+//串口数量,编号从0开始
+#define MAX_DEVICE_COUNT UART_MAX
+//存放串口设备句柄
+static uint8_t serials_marks[MAX_DEVICE_COUNT+1] ={0};
+
+
+int luat_uart_exist(int uartid){
+    if (uartid < 1 || uartid > MAX_DEVICE_COUNT){
+        return 0;
+    }
+    return 1;
+}
+
+static int32_t luat_uart_cb(void *pData, void *pParam){
+    rtos_msg_t msg;
+    uint32_t uartid = (uint32_t)pData;
+    uint32_t State = (uint32_t)pParam;
+    uint32_t len;
+    // LLOGD("luat_uart_cb pData:%d pParam:%d ",uartid,State);
+    switch (State){
+        case UART_CB_TX_BUFFER_DONE:
+            break;
+        case UART_CB_TX_ALL_DONE:
+            msg.handler = l_uart_handler;
+            msg.arg1 = uartid;
+            msg.arg2 = 0;
+            msg.ptr = NULL;
+            luat_msgbus_put(&msg, 1);
+            break;
+        case UART_CB_RX_BUFFER_FULL:
+            break;
+        case UART_CB_RX_TIMEOUT:
+            if (serials_marks[uartid]) return 0;
+            serials_marks[uartid] = 1;
+            len = Uart_RxBufferRead(uartid, NULL, 0);
+            msg.handler = l_uart_handler;
+            msg.ptr = NULL;
+            msg.arg1 = uartid;
+            msg.arg2 = len;
+            luat_msgbus_put(&msg, 1);
+            break;
+        case UART_CB_RX_NEW:
+            break;
+        case DMA_CB_DONE:
+            break;
+        case UART_CB_ERROR:
+            break;
+        case DMA_CB_ERROR:
+            LLOGD("%x", Uart_GetLastError(uartid));
+            break;
+	}
+}
+
+static int usb_uart_handler(lua_State *L, void* ptr,int arg1) {
+    rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
+    lua_pop(L, 1);
+    int uart_id = msg->arg1;
+    // LLOGD("msg->arg1: %d,msg->arg2: %d",msg->arg1,msg->arg2);
+    if (msg->arg2 == 1) {
+        lua_getglobal(L, "sys_pub");
+        lua_pushstring(L, "USB_UART_INC");
+        lua_pushinteger(L, uart_id);
+        lua_pushinteger(L, 1);
+        lua_call(L, 3, 0);
+    }
+    else if(msg->arg2 == 2){
+        lua_getglobal(L, "sys_pub");
+        lua_pushstring(L, "USB_UART_INC");
+        lua_pushinteger(L, uart_id);
+        lua_pushinteger(L, 0);
+        lua_call(L, 3, 0);
+    }
+    // 给rtos.recv方法返回个空数据
+    // lua_pushinteger(L, 0);
+    return 0;
+}
+
+static int32_t luat_uart_usb_cb(void *pData, void *pParam){
+    rtos_msg_t msg = {0};
+    uint32_t uartid = (uint32_t)pData;
+    uint32_t State = (uint32_t)pParam;
+    uint32_t len;
+    // LLOGD("luat_uart_cb pData:%d pParam:%d ",uartid,State);
+    switch (State){
+        case UART_CB_TX_BUFFER_DONE:
+            break;
+        case UART_CB_TX_ALL_DONE:
+            msg.handler = l_uart_handler;
+            msg.arg1 = 4;
+            msg.arg2 = 0;
+            msg.ptr = NULL;
+            luat_msgbus_put(&msg, 1);
+            break;
+        case UART_CB_RX_BUFFER_FULL:
+            break;
+        case UART_CB_RX_TIMEOUT:
+            break;
+        case UART_CB_RX_NEW:
+            if (serials_marks[4]) return 0;
+            serials_marks[4] = 1;
+            len = Core_VUartRxBufferRead(VIRTUAL_UART0,NULL,0);
+            msg.handler = l_uart_handler;
+            msg.ptr = NULL;
+            msg.arg1 = 4;
+            msg.arg2 = len;
+            luat_msgbus_put(&msg, 1);
+            break;
+        case DMA_CB_DONE:
+            break;
+        case UART_CB_ERROR:
+            // LLOGI("usb disconnect");
+            Core_VUartBufferTxStop(VIRTUAL_UART0);
+            msg.handler = usb_uart_handler;
+            msg.ptr = NULL;
+            msg.arg1 = 4;
+            msg.arg2 = 2;
+            luat_msgbus_put(&msg, 1);
+            break;
+        case UART_CB_CONNECTED:
+            //对方打开串口工具
+            msg.handler = usb_uart_handler;
+            msg.ptr = NULL;
+            msg.arg1 = 4;
+            msg.arg2 = 1;
+            luat_msgbus_put(&msg, 1);
+		    break;
+	}
+}
+
+int luat_uart_setup(luat_uart_t *uart){
+    int parity = 0;
+    if (uart->id > MAX_DEVICE_COUNT){
+        return -1;
+    }
+    switch (uart->id){
+        case UART_ID0:
+            break;
+        case UART_ID1:
+            GPIO_Iomux(GPIOC_01, 3);
+            GPIO_Iomux(GPIOC_00, 3);
+            break;
+        case UART_ID2:
+            GPIO_Iomux(GPIOD_13, 0);
+            GPIO_Iomux(GPIOD_12, 0);
+            break;
+        case UART_ID3:
+            GPIO_Iomux(GPIOE_08, 2);
+            GPIO_Iomux(GPIOE_09, 2);
+            break;
+        default:
+            break;
+    }
+    if (uart->parity == 1)parity = UART_PARITY_ODD;
+    else if (uart->parity == 2)parity = UART_PARITY_EVEN;
+    int stop_bits = (uart->stop_bits)==1?UART_STOP_BIT1:UART_STOP_BIT2;
+    if (uart->id == 4)
+        Core_VUartInit(VIRTUAL_UART0, uart->baud_rate, 1, (uart->data_bits), parity, stop_bits, NULL);
+    else
+        Uart_BaseInit(uart->id, uart->baud_rate, 1, (uart->data_bits), parity, stop_bits, NULL);
+    return 0;
+}
+
+
+int luat_uart_write(int uartid, void *data, size_t length){
+    //printf("uid:%d,data:%s,length = %d\r\n",uartid, (char *)data, length);
+    if (!luat_uart_exist(uartid)){
+        return 0;
+    }
+    if (uartid == 4)
+        Core_VUartBufferTx(VIRTUAL_UART0, (const uint8_t *)data, length);
+    else
+        Uart_BufferTx(uartid, (const uint8_t *)data, length);
+    return length;
+}
+
+int luat_uart_read(int uartid, void *buffer, size_t length){
+    int ret = 0;
+    if (!luat_uart_exist(uartid)){
+        return 0;
+    }
+    serials_marks[uartid] = 0;
+    if (uartid == 4)
+        ret = Core_VUartRxBufferRead(VIRTUAL_UART0, (uint8_t *)buffer,length);
+    else
+        ret = Uart_RxBufferRead(uartid, (uint8_t *)buffer,length);
+    // LLOGD("uartid:%d buffer:%s ",uartid,buffer);
+    return ret;
+}
+
+int luat_uart_close(int uartid){
+    if (!luat_uart_exist(uartid)){
+        return 0;
+    }
+    if (uartid == 4)
+        Core_VUartDeInit(VIRTUAL_UART0);
+    else
+        Uart_DeInit(uartid);
+    return 0;
+}
+
+int luat_setup_cb(int uartid, int received, int sent){
+    if (!luat_uart_exist(uartid)){
+        return -1;
+    }
+    if (uartid == 4)
+        Core_VUartSetCb(VIRTUAL_UART0, luat_uart_usb_cb);
+    else
+        Uart_SetCb(uartid, luat_uart_cb);
+#ifndef UART_RX_USE_DMA
+    Uart_EnableRxIrq(uartid);
+#endif
+    return 0;
+}

+ 24 - 0
application/src/luat_wdt_air105.c

@@ -0,0 +1,24 @@
+
+#include "luat_base.h"
+#include "luat_wdt.h"
+#include "app_interface.h"
+extern uint8_t gMainWDTEnable;
+int luat_wdt_init(size_t timeout) {
+	gMainWDTEnable = 0;
+    return 0;
+}
+
+int luat_wdt_set_timeout(size_t timeout) {
+	WDT_SetTimeout(timeout);
+    return 0;
+}
+
+int luat_wdt_feed(void) {
+	WDT_Feed();
+    return 0;
+}
+
+int luat_wdt_close(void) {
+	gMainWDTEnable = 1;
+    return 0;
+}

+ 13 - 0
application/src/readme.txt

@@ -0,0 +1,13 @@
+把需要适配luatos的接口源码放在本目录,比如luat_air105_xxx.c
+
+
+# C_SRC_LIST_EX =$(wildcard $(LUATOS_PATH)/lua/src/*.c)
+
+C_SRC_LIST_EX = $(LUATOS_PATH)/luat/packages/lfs/lfs.c $(LUATOS_PATH)/lua/src/bget.c $(LUATOS_PATH)/lua/src/printf.c
+
+# C_SRC_LIST_EX +=$(wildcard $(LUATOS_PATH)/luat/module/*.c)
+# C_SRC_LIST_EX +=$(wildcard $(LUATOS_PATH)/luat/packages/lfs/*.c)
+# C_SRC_LIST_EX +=$(wildcard $(LUATOS_PATH)/luat/packages/vfs/*.c)
+# C_SRC_LIST_EX +=$(wildcard $(LUATOS_PATH)/luat/packages/weak/*.c)
+
+

+ 2087 - 0
bsp/air105/chip/include/air105.h

@@ -0,0 +1,2087 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef __AIR105_H__
+#define __AIR105_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* ToDo: replace '<Device>' with your device name; add your doxyGen comment   */
+/** @addtogroup <Device>_Definitions <Device> Definitions
+  This file defines all structures and symbols for <Device>:
+    - registers and bitfields
+    - peripheral base address
+    - peripheral ID
+    - Peripheral definitions
+  @{
+*/
+
+
+/******************************************************************************/
+/*                Processor and Core Peripherals                              */
+/******************************************************************************/
+/** @addtogroup <Device>_CMSIS Device CMSIS Definitions
+  Configuration of the Cortex-M# Processor and Core Peripherals
+  @{
+*/
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+typedef enum IRQn
+{
+/******  Cortex-M# Processor Exceptions Numbers ***************************************************/
+
+/* ToDo: use this Cortex interrupt numbers if your device is a CORTEX-M3 / Cortex-M4 device       */
+	NonMaskableInt_IRQn           = -14,      /*!<  2 Non Maskable Interrupt                      */
+	MemoryManagement_IRQn         = -12,      /*!<  4 Memory Management Interrupt                 */
+	BusFault_IRQn                 = -11,      /*!<  5 Bus Fault Interrupt                         */
+	UsageFault_IRQn               = -10,      /*!<  6 Usage Fault Interrupt                       */
+	SVCall_IRQn                   = -5,       /*!< 11 SV Call Interrupt                           */
+	DebugMonitor_IRQn             = -4,       /*!< 12 Debug Monitor Interrupt                     */
+	PendSV_IRQn                   = -2,       /*!< 14 Pend SV Interrupt                           */
+	SysTick_IRQn                  = -1,       /*!< 15 System Tick Interrupt                       */
+
+/******  Device Specific Interrupt Numbers ********************************************************/
+/* ToDo: add here your device specific external interrupt numbers
+         according the interrupt handlers defined in startup_Device.s
+         eg.: Interrupt for Timer#1       TIM1_IRQHandler   ->   TIM1_IRQn                        */
+    DMA_IRQn                                        = 0,
+    USB_IRQn                                        = 1,
+    USBDMA_IRQn                                     = 2,
+    LCD_IRQn                                        = 3,
+    SCI0_IRQn                                       = 4,
+    UART0_IRQn                                      = 5,
+    UART1_IRQn                                      = 6,
+    SPI0_IRQn                                       = 7,
+    CRYPT0_IRQn                                     = 8,
+    TIM0_0_IRQn                                     = 9,
+    TIM0_1_IRQn                                     = 10,
+    TIM0_2_IRQn                                     = 11,
+    TIM0_3_IRQn                                     = 12,
+    EXTI0_IRQn                                      = 13,
+    EXTI1_IRQn                                      = 14,
+    EXTI2_IRQn                                      = 15,
+    RTC_IRQn                                        = 16,
+    SENSOR_IRQn                                     = 17,
+    TRNG_IRQn                                       = 18,
+    ADC0_IRQn                                       = 19,
+    SSC_IRQn                                        = 20,
+    TIM0_4_IRQn                                     = 21,
+    TIM0_5_IRQn                                     = 22,
+    KBD_IRQn                                        = 23,
+    MSR_IRQn                                        = 24,
+    EXTI3_IRQn                                      = 25,
+    SPI1_IRQn                                       = 26,
+    SPI2_IRQn                                       = 27,
+    
+    SCI2_IRQn                                       = 29,
+   
+    UART2_IRQn                                      = 32,
+    UART3_IRQn                                      = 33,
+    QSPI_IRQn                                       = 35,
+    I2C0_IRQn                                       = 36,
+    EXTI4_IRQn                                      = 37,
+    EXTI5_IRQn                                      = 38,
+    TIM0_6_IRQn                                     = 39,
+    TIM0_7_IRQn                                     = 40,
+    DCMI_IRQn                                       = 42,
+   
+    QR_IRQn                                         = 46,
+	GPU_IRQn										= 47,
+
+	AWD_IRQn										= 49,
+	DAC_IRQn										= 50,
+	SPI5_IRQn										= 51
+} IRQn_Type;
+
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the Cortex-M# Processor and Core Peripherals */
+/* ToDo: set the defines according your Device                                                    */
+/* ToDo: define the correct core revision
+         __CM0_REV if your device is a CORTEX-M0 device
+         __CM3_REV if your device is a CORTEX-M3 device
+         __CM4_REV if your device is a CORTEX-M4 device                                           */
+//#define __CM3_REV                 0x0201    /*!< Core Revision r2p1                               */
+//#define __CM3_REV                 0x0200    /*!< Core Revision r2p0                               */
+#define __CM4_REV                   0x0001    /*!< Core Revision r2p0                               */
+#define __NVIC_PRIO_BITS          3         /*!< Number of Bits used for Priority Levels          */
+#define __Vendor_SysTickConfig    0         /*!< Set to 1 if different SysTick Config is used     */
+#define __MPU_PRESENT             1         /*!< MPU present or not                               */
+/* ToDo: define __FPU_PRESENT if your devise is a CORTEX-M4                                       */
+#define __FPU_PRESENT             1        /*!< FPU present or not                                */
+
+/*@}*/ /* end of group <Device>_CMSIS */
+
+
+/* ToDo: include the correct core_cm#.h file
+         core_cm0.h if your device is a CORTEX-M0 device
+         core_cm3.h if your device is a CORTEX-M3 device
+         core_cm4.h if your device is a CORTEX-M4 device                                          */
+#include "core_cm4.h"                       /* Cortex-M# processor and core peripherals           */
+/* ToDo: include your system_<Device>.h file
+         replace '<Device>' with your device name                                                 */
+#include "system_air105.h"                /* <Device> System  include file                      */
+
+
+/******************************************************************************/
+/*                Device Specific Peripheral registers structures             */
+/******************************************************************************/
+/** @addtogroup <Device>_Peripherals <Device> Peripherals
+  <Device> Device Specific Peripheral registers structures
+  @{
+*/
+
+#if defined ( __CC_ARM   )
+#pragma anon_unions
+#endif
+
+#include <stdint.h>
+
+/** @addtogroup Exported_types
+  * @{
+  */  
+
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
+
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
+#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
+
+typedef enum {FALSE = 0, TRUE = !FALSE} Boolean;
+
+typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
+
+/* ToDo: add here your device specific peripheral access structure typedefs
+         following is an example for a timer                                  */
+#define BIT0        (0x00000001U)
+#define BIT1        (0x00000002U)
+#define BIT2        (0x00000004U)
+#define BIT3        (0x00000008U)
+#define BIT4        (0x00000010U)
+#define BIT5        (0x00000020U)
+#define BIT6        (0x00000040U)
+#define BIT7        (0x00000080U)
+#define BIT8        (0x00000100U)
+#define BIT9        (0x00000200U)
+#define BIT10       (0x00000400U)
+#define BIT11       (0x00000800U)
+#define BIT12       (0x00001000U)
+#define BIT13       (0x00002000U)
+#define BIT14       (0x00004000U)
+#define BIT15       (0x00008000U)
+#define BIT16       (0x00010000U)
+#define BIT17       (0x00020000U)
+#define BIT18       (0x00040000U)
+#define BIT19       (0x00080000U)
+#define BIT20       (0x00100000U)
+#define BIT21       (0x00200000U)
+#define BIT22       (0x00400000U)
+#define BIT23       (0x00800000U)
+#define BIT24       (0x01000000U)
+#define BIT25       (0x02000000U)
+#define BIT26       (0x04000000U)
+#define BIT27       (0x08000000U)
+#define BIT28       (0x10000000U)
+#define BIT29       (0x20000000U)
+#define BIT30       (0x40000000U)
+#define BIT31       (0x80000000U)
+
+#define BIT(n)      (1UL << (n))
+
+typedef struct
+{
+    __IO uint32_t FREQ_SEL;
+    __IO uint32_t CG_CTRL1;
+    __IO uint32_t CG_CTRL2;
+    __O uint32_t  SOFT_RST1;
+    __O uint32_t  SOFT_RST2;
+    __IO uint32_t LOCK_R;
+    __IO uint32_t PHER_CTRL;
+	__I uint32_t  SYS_RSVD[(0x2C-0x1C) >> 2];
+    __I uint32_t  HCLK_1MS_VAL;
+    __I uint32_t  PCLK_1MS_VAL;
+    __IO uint32_t ANA_CTRL;
+    __IO uint32_t DMA_CHAN;
+    __IO uint32_t SCI0_GLF;
+    __IO uint32_t SW_RSV1;
+    __IO uint32_t SW_RSV2;
+    __IO uint32_t CARD_RSVD;
+    __IO uint32_t LDO25_CR;
+	__IO uint32_t DMA_CHAN1;
+    __I uint32_t  SYS_RSVD2[(0x100-0x54) >> 2];
+    __IO uint32_t MSR_CR1;
+    __IO uint32_t MSR_CR2;
+    __IO uint32_t USBPHY_CR1;
+    __IO uint32_t USBPHY_CR2;
+    __IO uint32_t USBPHY_CR3;
+	__IO uint32_t ISO7816_CR;
+	__IO uint32_t LDO_CR;
+	__IO uint32_t CHG_CSR;
+    __I uint32_t  SYS_RSVD3[(0x204-0x120) >> 2];
+    __IO uint32_t RSVD_POR;
+    __I uint32_t  SYS_RSVD4[(0x3EC-0x208) >> 2];
+    __IO uint32_t PM2_WK_FLAG;
+    __IO uint32_t CALIB_CSR;
+    __IO uint32_t DBG_CR;
+    __IO uint32_t CHIP_ID;
+} SYSCTRL_TypeDef;
+
+typedef struct
+{
+    union
+    {
+        __I  uint32_t RBR;
+        __O  uint32_t THR;
+        __IO uint32_t DLL;
+    } OFFSET_0;
+    union
+    {
+        __IO uint32_t DLH;
+        __IO uint32_t IER;
+    } OFFSET_4;
+    union
+    {
+        __I uint32_t IIR;
+        __O uint32_t FCR;
+    } OFFSET_8;
+    __IO uint32_t LCR;
+    __IO uint32_t MCR;
+    __I  uint32_t LSR;
+    __I  uint32_t MSR;
+    __IO uint32_t SCR;
+    __IO uint32_t LPDLL;
+    __IO uint32_t LPDLH;
+    __I  uint32_t RES0[2];
+    union
+    {
+        __I  uint32_t SRBR[16];
+        __O  uint32_t STHR[16];
+    } OFFSET_48;
+    __IO uint32_t FAR;
+    __I  uint32_t TFR;
+    __O  uint32_t RFW;
+    __I  uint32_t USR;
+    __I  uint32_t TFL;
+    __I  uint32_t RFL;
+    __O  uint32_t SRR;
+    __IO uint32_t SRTS;
+    __IO uint32_t SBCR;
+    __IO uint32_t SDMAM;
+    __IO uint32_t SFE;
+    __IO uint32_t SRT;
+    __IO uint32_t STET;
+    __IO uint32_t HTX;
+    __O uint32_t DMASA;
+    __I  uint32_t RES1[18];
+    __I  uint32_t CPR;
+    __I  uint32_t UCV;
+    __I  uint32_t CTR;
+    
+} UART_TypeDef;
+
+typedef struct
+{
+    __IO uint16_t CTRLR0;
+    uint16_t RESERVED0;
+    __IO uint16_t CTRLR1;
+    uint16_t RESERVED1;
+    __IO uint32_t SSIENR;
+    __IO uint32_t MWCR;
+    __IO uint32_t SER;
+    __IO uint32_t BAUDR;
+    __IO uint32_t TXFTLR;
+    __IO uint32_t RXFTLR;
+    __I  uint32_t TXFLR;
+    __I  uint32_t RXFLR;
+    __I  uint32_t SR;
+    __IO uint32_t IMR;
+    __I  uint32_t ISR;
+    __I  uint32_t RISR;
+    __I  uint32_t TXOICR;
+    __I  uint32_t RXOICR;
+    __I  uint32_t RXUICR;
+    __I  uint32_t MSTICR;
+    __IO uint32_t ICR;
+    __IO uint32_t DMACR;
+    __IO uint32_t DMATDLR;
+    __IO uint32_t DMARDLR;
+    __I  uint32_t IDR;
+    __I  uint32_t SSI_COMP_VERSION;
+    __IO uint32_t DR;
+    __IO uint32_t DR_Array[35];
+    __IO uint32_t RX_SAMPLE_DLY;    
+} SPI_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t FCU_CMD;
+    __O  uint32_t ADDRES;
+    __IO uint32_t BYTE_NUM;
+    __O  uint32_t WR_FIFO;
+    __I  uint32_t RD_FIFO;
+    __IO uint32_t DEVICE_PARA;
+    __IO uint32_t REG_WDATA;
+    __O  uint32_t REG_RDATA;
+    __IO uint32_t INT_MASK;
+    __IO uint32_t INT_UMASK;
+    __IO uint32_t INT_MASK_STATUS;
+    __IO uint32_t INT_STATUS;
+    __IO uint32_t INT_RAWSTATUS;
+    __IO uint32_t INT_CLEAR;
+    __IO uint32_t CACHE_INTF_CMD;
+    __IO uint32_t DMA_CNTL;
+    __IO uint32_t FIFO_CNTL;
+} QSPI_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t CACHE_I0;
+    __IO uint32_t CACHE_I1;
+    __IO uint32_t CACHE_I2;
+    __IO uint32_t CACHE_I3;
+    __IO uint32_t CACHE_K0;
+    __IO uint32_t CACHE_K1;
+    __IO uint32_t CACHE_K2;
+    __IO uint32_t CACHE_K3;
+    __IO uint32_t CACHE_CS;
+    __IO uint32_t CACHE_REF;
+    __I  uint32_t CACHE_RSVD0[(0x40-0x28) >> 2];
+    __IO uint32_t CACHE_CONFIG;
+	__I  uint32_t CACHE_RSVD1[(0x74-0x44) >> 2];
+    __IO uint32_t CACHE_SADDR;
+    __IO uint32_t CACHE_EADDR;		
+	
+} CACHE_TypeDef;
+
+typedef struct
+{
+	__IO uint32_t CR0;				/*!< HSPIM Control register0		 		*/
+	__IO uint32_t FLCR;				/*!< HSPIM Flow Control register	 		*/
+	__IO uint32_t FLSR;  			/*!< HSPIM Flow Status register 			*/
+	__IO uint32_t FCR;				/*!< HSPIM FIFO Control register 			*/
+	__I  uint32_t RDR;				/*!< HSPIM Read Data register 				*/
+	__O  uint32_t WDR;				/*!< HSPIM Write Data register 				*/
+	__I  uint32_t SR;				/*!< HSPIM Status register 					*/
+	__IO uint32_t CR1;				/*!< HSPIM Control register1 				*/
+	__IO uint32_t FSR;				/*!< HSPIM FIFO Status register				*/
+	__IO uint32_t DCR;				/*!< HSPIM DMA Control register 			*/	
+	__I  uint32_t TISR;				/*!< HSPIM TX Interrput Status register		*/	
+	__I  uint32_t RISR;				/*!< HSPIM RX Interrput Status register		*/	
+}HSPIM_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t SMU_CTRL;
+    __IO uint32_t FPM_CTRL;
+    __O  uint32_t INTR_STAT;
+    __IO uint32_t INTR_CTRL;
+	__IO uint32_t RESERVED1[12];
+    __IO uint32_t SMU_OP1;
+    __IO uint32_t SMU_OP2;
+    __O  uint32_t SMU_RES;
+	__IO uint32_t RESERVED2[13];
+    __IO float    MATRIX1_00;
+    __IO float    MATRIX1_01;
+    __IO float    MATRIX1_02;
+    __IO float    MATRIX1_10;
+    __IO float    MATRIX1_11;
+    __IO float    MATRIX1_12;
+    __IO float    MATRIX1_20;
+    __IO float    MATRIX1_21;
+    __IO float    MATRIX1_22;
+	__IO uint32_t RESERVED3[7];
+    __IO float    MATRIX2_00;
+    __IO float    MATRIX2_01;
+    __IO float    MATRIX2_02;
+	__IO uint32_t RESERVED4[13];
+    __IO uint32_t TABLE1_LEN;
+    __IO uint32_t TABLE2_LEN;
+    __IO uint32_t ACC;
+    __IO uint32_t POSITION;
+	__IO uint32_t VAL3;
+	__IO uint32_t RESERVED5[443];
+	__IO uint32_t TABLE1_RAM;
+	__IO uint32_t RESERVED6[255];
+	__IO uint32_t TABLE2_RAM;
+	__IO uint32_t RESERVED7[63];    
+}QRCODE_TypeDef;
+
+
+typedef struct
+{
+    __IO uint32_t WDT_CR;
+    __IO uint32_t RESERVED0;
+    __I  uint32_t WDT_CCVR;
+    __O  uint32_t WDT_CRR;
+    __I  uint32_t WDT_STAT;
+    __I  uint32_t WDT_EOI;  
+    __I  uint32_t RESERVED1;
+    __IO uint32_t WDT_RLD;
+    __I  uint32_t RESERVED[53];
+    __I  uint32_t WDT_COMP_PARAMS_1;
+    __I  uint32_t WDT_COMP_VERSION;
+    __I  uint32_t WDT_COMP_TYPE;
+} WDT_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t CRC_CSR;
+    __O  uint32_t CRC_INI;
+    union
+    {
+        __I uint32_t DOUT;
+        __O uint8_t  DIN;
+    } CRC_DATA;
+} CRC_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t LoadCount;
+    __I  uint32_t CurrentValue;
+    __IO uint32_t ControlReg;
+    __IO  uint32_t EOI;
+    __I  uint32_t IntStatus;
+} TIM_TypeDef;
+
+#define TIM_NUM      8
+typedef struct
+{
+    TIM_TypeDef TIM[TIM_NUM];
+    __I  uint32_t TIM_IntStatus;
+    __I  uint32_t TIM_EOI;
+    __I  uint32_t TIM_RawIntStatus;
+    __I  uint32_t TIM_Comp;
+    __IO uint32_t TIM_ReloadCount[TIM_NUM];
+} TIM_Module_TypeDef;
+
+typedef struct 
+{
+    __IO uint32_t ADC_CR1;
+    __I  uint32_t ADC_SR;
+    __IO uint32_t ADC_FIFO;
+    __I  uint32_t ADC_DATA;
+    __I  uint32_t ADC_FIFO_FL;
+    __IO uint32_t ADC_FIFO_THR;
+    __IO uint32_t ADC_CR2;
+} ADC_TypeDef;
+
+typedef struct 
+{
+    __IO uint32_t DAC_CR1;
+    __IO uint32_t DAC_DATA;
+    __IO uint32_t DAC_TIMER;
+    __I  uint32_t DAC_FIFO_FL;
+    __IO uint32_t DAC_FIFO_THR;	
+} DAC_TypeDef;
+
+typedef struct 
+{
+    __IO uint32_t AWD_CR1;
+    __IO uint32_t AWD_CR2;
+    __I  uint32_t AWD_SR;
+} AWD_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t IODR;
+    __IO uint32_t BSRR;
+    __IO uint32_t OEN;
+    __IO uint32_t PUE;
+} GPIO_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t INTP_TYPE;
+    __IO uint32_t INTP_STA;
+} GPIO_INTP_TypeDef;
+
+#define GPIO_GROUP_NUM   6
+typedef struct
+{
+    GPIO_TypeDef GPIO[GPIO_GROUP_NUM];
+    __I  uint32_t RSVD0[(0x114 - 0x060)>>2];
+    __I  uint32_t INTP[GPIO_GROUP_NUM];
+    __I  uint32_t RSVD1[(0x180 - 0x12C)>>2];
+    __IO uint32_t ALT[GPIO_GROUP_NUM];
+    __I  uint32_t RSVD2[(0x200 - 0x198)>>2];
+    __IO uint32_t SYS_CR1;
+    __I  uint32_t RSVD3[(0x220 - 0x204)>>2];
+    __IO uint32_t WAKE_TYPE_EN;
+    __IO uint32_t WAKE_P0_EN;
+    __IO uint32_t WAKE_P1_EN;
+    __IO uint32_t WAKE_P2_EN;
+    __IO uint32_t WAKE_P3_EN;
+    __I  uint32_t RSVD5[(0x800 - 0x234)>>2];
+    GPIO_INTP_TypeDef INTP_TYPE_STA[GPIO_GROUP_NUM];
+} GPIO_MODULE_TypeDef;
+
+
+typedef struct
+{
+    __IO uint32_t FLAG[(0x0174 - 0x00164) >> 2];
+} FLAG_TypeDef;
+
+#define BPK_KEY_NUM      16
+typedef struct
+{
+    __IO uint32_t KEY[BPK_KEY_NUM];
+	__I  uint32_t BPK_RSVD0[(0x80-0x40)>>2];	
+    __IO uint32_t BPK_RDY;
+    __IO uint32_t BPK_CLR;
+    __IO uint32_t BPK_LRA;
+    __IO uint32_t BPK_LWA;
+    __I  uint32_t BPK_RSVD1;	
+    __IO uint32_t BPK_LR;
+	__IO uint32_t BPK_SCR;
+	__IO uint32_t BPK_POWER;
+   
+    __IO uint32_t RTC_CS;
+    __IO uint32_t RTC_REF;
+    __IO uint32_t RTC_ARM;
+    __I  uint32_t RTC_TIM;
+    __O  uint32_t RTC_INTCLR;
+    __IO uint32_t OSC32K_CR;
+    __IO uint32_t RTC_ATTA_TIM;	
+
+	__IO uint32_t BPK_RR;	
+    __IO uint32_t SEN_EXT_TYPE;
+    __IO uint32_t SEN_EXT_CFG;
+    __IO uint32_t SEN_SOFT_EN;
+    __IO uint32_t SEN_STATE;
+    __IO uint32_t SEN_BRIDGE;
+    __IO uint32_t SEN_SOFT_ATTACK;
+    __IO uint32_t SEN_SOFT_LOCK;
+    __IO uint32_t SEN_ATTACK_CNT;
+    __IO uint32_t SEN_ATTACK_TYP;
+    __IO uint32_t SEN_VG_DETECT;
+    __IO uint32_t SEN_RNG_INI;
+    __IO uint32_t RESERVED3[(0x0104 - 0x00EC) >> 2];
+    __IO uint32_t SEN_EN[19];
+    __IO uint32_t SEN_EXTS_START;
+    __IO uint32_t SEN_LOCK;
+    __IO uint32_t SEN_ANA0;
+    __IO uint32_t SEN_ANA1;
+    __IO uint32_t SEN_ATTCLR;
+    FLAG_TypeDef  SEN_FLAG;
+    __IO uint32_t SEN_DEBUG;
+    __I  uint32_t BPU_RSVD4[(0x200- 0x178) >> 2];	
+	__IO uint32_t BPK_RAM[(0x600-0x200) >> 2];
+} BPU_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t KEY[BPK_KEY_NUM];
+	__I  uint32_t BPK_RSVD0[(0x80-0x40) >> 2];	
+    __IO uint32_t BPK_RDY;
+    __IO uint32_t BPK_CLR;
+    __IO uint32_t BPK_LRA;
+    __IO uint32_t BPK_LWA;
+    __I  uint32_t BPK_RSVD1;
+    __IO uint32_t BPK_LR;
+	__IO uint32_t BPK_SCR;
+    __IO uint32_t BPK_POWER;
+} BPK_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t RTC_CS;
+    __IO uint32_t RTC_REF;
+    __IO uint32_t RTC_ARM;
+    __I  uint32_t RTC_TIM;
+    __O  uint32_t RTC_INTCLR;
+    __IO uint32_t OSC32K_CR;
+    __IO uint32_t RTC_ATTA_TIM;
+} RTC_TypeDef;
+
+#define EXT_SENSOR_NUM         8
+#define INNER_SENSOR_NUM       7
+typedef struct
+{
+	__IO uint32_t BPK_RR;	
+    __IO uint32_t SEN_EXT_TYPE;
+    __IO uint32_t SEN_EXT_CFG;
+    __IO uint32_t SEN_SOFT_EN;
+    __IO uint32_t SEN_STATE;
+    __IO uint32_t SEN_BRIDGE;
+    __IO uint32_t SEN_SOFT_ATTACK;
+    __IO uint32_t SEN_SOFT_LOCK;
+    __IO uint32_t SEN_ATTACK_CNT;
+    __IO uint32_t SEN_ATTACK_TYP;
+    __IO uint32_t SEN_VG_DETECT;
+    __IO uint32_t SEN_RNG_INI;
+    __IO uint32_t RESERVED3[(0x0104-0x00EC) >> 2];
+    __IO uint32_t SEN_EN[19];
+    __IO uint32_t SEN_EXTS_START;
+    __IO uint32_t SEN_LOCK;
+    __IO uint32_t SEN_ANA0;
+    __IO uint32_t SEN_ANA1;
+    __IO uint32_t SEN_ATTCLR;
+    FLAG_TypeDef  SEN_FLAG;
+    __IO uint32_t SEN_DEBUG;
+    __I  uint32_t RESERVED4[(0x200- 0x178) >> 2];	
+	__IO uint32_t BPK_RAM[(0x600-0x200) >> 2];
+} SEN_TypeDef;
+
+
+typedef struct
+{
+    __IO uint32_t RNG_CSR;
+    __IO uint32_t RNG_DATA[1];
+    __I  uint32_t RES;
+    __IO uint32_t RNG_ANA;
+    __IO uint32_t RNG_PN;
+    __IO uint32_t RNG_INDEX;
+} TRNG_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t IC_CON;
+    __IO uint32_t IC_TAR;
+    __IO uint32_t IC_SAR;
+    __IO uint32_t IC_HS_MADDR;
+    __IO uint32_t IC_DATA_CMD;
+    __IO uint32_t IC_SS_SCL_HCNT;
+    __IO uint32_t IC_SS_SCL_LCNT;
+    __IO uint32_t IC_FS_SCL_HCNT;
+    __IO uint32_t IC_FS_SCL_LCNT;
+    __IO uint32_t IC_HS_SCL_HCNT;
+    __IO uint32_t IC_HS_SCL_LCNT;
+    __I  uint32_t IC_INTR_STAT;
+    __IO uint32_t IC_INTR_MASK;
+    __I  uint32_t IC_RAW_INTR_STAT;
+    __IO uint32_t IC_RX_TL;
+    __IO uint32_t IC_TX_TL;
+    __I  uint32_t IC_CLR_INTR;
+    __I  uint32_t IC_CLR_RX_UNDER;
+    __I  uint32_t IC_CLR_RX_OVER;
+    __I  uint32_t IC_CLR_TX_OVER;
+    __I  uint32_t IC_CLR_RD_REQ;
+    __I  uint32_t IC_CLR_TX_ABRT;
+    __I  uint32_t IC_CLR_RX_DONE;
+    __I  uint32_t IC_CLR_ACTIVITY;
+    __I  uint32_t IC_CLR_STOP_DET;
+    __I  uint32_t IC_CLR_START_DET;
+    __I  uint32_t IC_CLR_GEN_CALL;
+    __IO uint32_t IC_ENABLE;
+    __I  uint32_t IC_STATUS;
+    __I  uint32_t IC_TXFLR;
+    __I  uint32_t IC_RXFLR;
+    __IO uint32_t IC_SDA_HOLD;
+    __I  uint32_t IC_TX_ABRT_SOURCE;
+    __IO uint32_t IC_SLV_DATA_NACK_ONLY;
+    __IO uint32_t IC_DMA_CR;
+    __IO uint32_t IC_DMA_TDLR;
+    __IO uint32_t IC_DMA_RDLR;
+    __IO uint32_t IC_SDA_SETUP;
+    __IO uint32_t IC_ACK_GENERAL_CALL;
+    __I  uint32_t IC_ENABLE_STATUS;
+    __IO uint32_t IC_FS_SPKLEN;
+    __IO uint32_t IC_HS_SPKLEN; 
+} I2C_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t KCU_CTRL0;
+    __IO uint32_t KCU_CTRL1;
+    __I  uint32_t KCU_STATUS;
+    __I  uint32_t KCU_EVENT;
+    __IO uint32_t KCU_RNG;
+} KCU_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t SAR_L;
+    __IO uint32_t SAR_H;
+    __IO uint32_t DAR_L;
+    __IO uint32_t DAR_H;
+    __IO uint32_t LLP_L;
+    __IO uint32_t LLP_H;
+    __IO uint32_t CTL_L;
+    __IO uint32_t CTL_H;
+    __IO uint32_t SSTAT_L;
+    __IO uint32_t SSTAT_H;
+    __IO uint32_t DSTAT_L;
+    __IO uint32_t DSTAT_H;
+    __IO uint32_t SSTATAR_L;
+    __IO uint32_t SSTATAR_H;
+    __IO uint32_t DSTATAR_L;
+    __IO uint32_t DSTATAR_H;
+    __IO uint32_t CFG_L;
+    __IO uint32_t CFG_H;
+    __IO uint32_t SGR_L;
+    __IO uint32_t SGR_H;
+    __IO uint32_t DSR_L;
+    __IO uint32_t DSR_H;
+} DMA_TypeDef;
+
+typedef struct
+{
+    DMA_TypeDef DMA_Channel[8];
+
+    __I  uint32_t RawTfr_L;
+    __I  uint32_t RawTfr_H;
+    __I  uint32_t RawBlock_L;
+    __I  uint32_t RawBlock_H;
+    __I  uint32_t RawSrcTran_L;
+    __I  uint32_t RawSrcTran_H;
+    __I  uint32_t RawDstTran_L;
+    __I  uint32_t RawDstTran_H;
+    __I  uint32_t RawErr_L;
+    __I  uint32_t RawErr_H;
+    
+    __I  uint32_t StatusTfr_L;
+    __I  uint32_t StatusTfr_H;
+    __I  uint32_t StatusBlock_L;
+    __I  uint32_t StatusBlock_H;
+    __I  uint32_t StatusSrcTran_L;
+    __I  uint32_t StatusSrcTran_H;
+    __I  uint32_t StatusDstTran_L;
+    __I  uint32_t StatusDstTran_H;
+    __I  uint32_t StatusErr_L;
+    __I  uint32_t StatusErr_H;
+
+    __IO uint32_t MaskTfr_L;
+    __IO uint32_t MaskTfr_H;
+    __IO uint32_t MaskBlock_L;
+    __IO uint32_t MaskBlock_H;
+    __IO uint32_t MaskSrcTran_L;
+    __IO uint32_t MaskSrcTran_H;
+    __IO uint32_t MaskDstTran_L;
+    __IO uint32_t MaskDstTran_H;
+    __IO uint32_t MaskErr_L;
+    __IO uint32_t MaskErr_H;
+    
+    __O  uint32_t ClearTfr_L;
+    __O  uint32_t ClearTfr_H;
+    __O  uint32_t ClearBlock_L;
+    __O  uint32_t ClearBlock_H;
+    __O  uint32_t ClearSrcTran_L;
+    __O  uint32_t ClearSrcTran_H;
+    __O  uint32_t ClearDstTran_L;
+    __O  uint32_t ClearDstTran_H;
+    __O  uint32_t ClearErr_L;
+    __O  uint32_t ClearErr_H;
+    
+    __I  uint32_t StatusInt_L;
+    __I  uint32_t StatusInt_H;
+    
+    __IO uint32_t ReqSrcReg_L;
+    __IO uint32_t ReqSrcReg_H;
+    __IO uint32_t ReqDstReg_L;
+    __IO uint32_t ReqDstReg_H;
+    __IO uint32_t SglReqSrcReg_L;
+    __IO uint32_t SglReqSrcReg_H;
+    __IO uint32_t SglReqDstReg_L;
+    __IO uint32_t SglReqDstReg_H;
+    __IO uint32_t LstSrcReg_L;
+    __IO uint32_t LstSrcReg_H;
+    __IO uint32_t LstDstReg_L;
+    __IO uint32_t LstDstReg_H;
+    
+    __IO uint32_t DmaCfgReg_L;
+    __IO uint32_t DmaCfgReg_H;
+    __IO uint32_t ChEnReg_L;
+    __IO uint32_t ChEnReg_H;
+    __I  uint32_t DmaIdReg_L;
+    __I  uint32_t DmaIdReg_H;
+    __IO uint32_t DmaTestReg_L;
+    __IO uint32_t DmaTestReg_H;
+    
+    __IO uint32_t RESERVED2[4];
+    
+    __I  uint32_t DMA_COMP_PARAMS_6_L;
+    __I  uint32_t DMA_COMP_PARAMS_6_H;
+    __I  uint32_t DMA_COMP_PARAMS_5_L;
+    __I  uint32_t DMA_COMP_PARAMS_5_H;
+    __I  uint32_t DMA_COMP_PARAMS_4_L;
+    __I  uint32_t DMA_COMP_PARAMS_4_H;
+    __I  uint32_t DMA_COMP_PARAMS_3_L;
+    __I  uint32_t DMA_COMP_PARAMS_3_H;
+    __I  uint32_t DMA_COMP_PARAMS_2_L;
+    __I  uint32_t DMA_COMP_PARAMS_2_H;
+    __I  uint32_t DMA_COMP_PARAMS_1_L;
+    __I  uint32_t DMA_COMP_PARAMS_1_H;
+    __I  uint32_t DMA_Component_ID_Register_L;
+    __I  uint32_t DMA_Component_ID_Register_H;
+
+} DMA_MODULE_TypeDef;
+
+typedef struct
+{
+        __IO uint32_t lcdi_ctrl;
+        __IO uint32_t lcdi_cycle;
+        __IO uint32_t lcdi_status;
+        __IO uint32_t lcdi_data;
+        __IO uint32_t lcdi_fifolevel;
+        __IO uint32_t lcdi_fifothr;
+} LCD_TypeDef;
+
+typedef struct
+{
+	__IO uint32_t SCI_DATA;
+	__IO uint32_t SCI_CR0;
+	__IO uint32_t SCI_CR1;
+	__IO uint32_t SCI_CR2;
+	__IO uint32_t SCI_IER;
+	__IO uint32_t SCI_RETRY;
+	__IO uint32_t SCI_TIDE;
+	__IO uint32_t SCI_TXCOUNT;
+	__IO uint32_t SCI_RXCOUNT;
+	__I  uint32_t SCI_FR;
+	__IO uint32_t SCI_RXTIME;
+	__IO uint32_t SCI_ISTAT;
+	__IO uint32_t SCI_STABLE;
+	__IO uint32_t SCI_ATIME;
+	__IO uint32_t SCI_DTIME;
+
+	__IO uint32_t SCI_ATRSTIME;
+	__IO uint32_t SCI_ATRDTIME;
+	__IO uint32_t SCI_BLKTIME;
+	__IO uint32_t SCI_CHTIME;
+	__IO uint32_t SCI_CLKICC;
+	__IO uint32_t SCI_BAUD;
+	__IO uint32_t SCI_VALUE;
+	__IO uint32_t SCI_CHGUARD;
+	__IO uint32_t SCI_BLKGUARD;
+	__IO uint32_t SCI_SYNCCR;
+	__IO uint32_t SCI_SYNCDATA;
+	__IO uint32_t SCI_RAWSTAT;
+	__IO uint32_t SCI_IIR;
+	__I  uint32_t SCI_RES1[4];
+	__I  uint32_t SCI_RES2[32];
+} SCI_TypeDef;
+
+
+
+/** 
+  * @brief DCMI&IMG COP
+  */
+
+typedef struct
+{
+	__IO uint32_t CR;       /*!< DCMI control register 1,                       Address offset: 0x00 */
+	__IO uint32_t SR;       /*!< DCMI status register,                          Address offset: 0x04 */
+	__IO uint32_t RISR;     /*!< DCMI raw interrupt status register,            Address offset: 0x08 */
+	__IO uint32_t IER;      /*!< DCMI interrupt enable register,                Address offset: 0x0C */
+	__IO uint32_t MISR;     /*!< DCMI masked interrupt status register,         Address offset: 0x10 */
+	__IO uint32_t ICR;      /*!< DCMI interrupt clear register,                 Address offset: 0x14 */
+	__IO uint32_t RESERVED1[2];
+	__IO uint32_t CWSTRTR;  /*!< DCMI crop window start,                        Address offset: 0x20 */
+	__IO uint32_t CWSIZER;  /*!< DCMI crop window size,                         Address offset: 0x24 */
+	__IO uint32_t DR;       /*!< DCMI data register,                            Address offset: 0x28 */
+} DCMI_TypeDef;
+typedef struct
+{
+    __IO uint32_t  RESERVED[(0x2000-0x0000)/4];
+    __IO uint32_t  CFG;
+    __IO uint32_t  CS;
+    __IO uint32_t  PROT;
+    __IO uint32_t  ADDR;
+    __IO uint32_t  PDATA;
+    __IO uint32_t  RO;
+    __IO uint32_t  ROL;
+    __IO uint32_t  RSVD;
+    __IO uint32_t  TIM;
+    __IO uint32_t  TIM_EN;
+} OTP_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t  RESERVED0[(0x0008-0x0000) >> 2];
+    __IO uint32_t  SSC_CR3;
+    __O  uint32_t  RESERVED1[(0x0104-0x000C) >> 2];
+    __IO uint32_t  SSC_SR;
+    __IO uint32_t  SSC_SR_CLR;
+    __IO uint32_t  SSC_ACK;	
+    __O  uint32_t  RESERVED2[(0x0184-0x0110) >> 2];
+    __IO uint32_t  DATARAM_SCR;
+    __O  uint32_t  RESERVED3[(0x01FC-0x0188) >> 2];
+    __IO uint32_t  BPU_RWC;
+    __O  uint32_t  RESERVED4[(0x03EC-0x0200) >> 2];
+    __IO uint32_t  MAIN_SEN_LOCK;
+    __IO uint32_t  MAIN_SEN_EN;
+} SSC_TypeDef;
+
+typedef struct
+{
+    __IO uint32_t  TST_JTAG;
+    __IO uint32_t  TST_ROM;
+    __IO uint32_t  TST_FLASH;
+} MH_SMCU_TST_TypeDef;
+
+
+#if defined ( __CC_ARM   )
+#pragma no_anon_unions
+#endif
+
+/*@}*/ /* end of group <Device>_Peripherals */
+
+
+/******************************************************************************/
+/*                         Peripheral memory map                              */
+/******************************************************************************/
+/* ToDo: add here your device peripherals base addresses
+         following is an example for timer                                    */
+/** @addtogroup <Device>_MemoryMap <Device> Memory Mapping
+  @{
+*/
+
+/* Peripheral and SRAM base address */
+#define AIR105_FLASH_BASE                       (0x01000000UL)                /*!< (FLASH     ) Base Address */
+#define AIR105_SRAM_BASE                        (0x20000000UL)                /*!< (SRAM      ) Base Address */
+#define AIR105_PERIPH_BASE                      (0x40000000UL)                /*!< (Peripheral) Base Address */
+
+#define AIR105_SRAM_SIZE                        (0xA0000)
+
+#define AIR105_OTP_BASE                         (0x40008000UL)
+#define AIR105_OTP_SIZE                         (1UL << 13)
+
+/* Peripheral memory map */
+#define AIR105_AHB_BASE                         (AIR105_PERIPH_BASE)
+#define AIR105_APB0_BASE                        (AIR105_PERIPH_BASE + 0x10000)
+#define AIR105_APB1_BASE                        (AIR105_PERIPH_BASE + 0x20000)
+#define AIR105_APB2_BASE                        (AIR105_PERIPH_BASE + 0x30000)
+#define AIR105_APB3_BASE                        (AIR105_PERIPH_BASE + 0x40000)
+
+#define SSC_BASE                                (AIR105_AHB_BASE + 0x0000)
+#define TST_BASE                                (AIR105_AHB_BASE + 0x03F4)
+#define DMA_BASE                                (AIR105_AHB_BASE + 0x0800)
+#define USB_BASE                                (AIR105_AHB_BASE + 0x0C00)
+#define LCD_BASE                                (AIR105_AHB_BASE + 0x1000)
+#define OTP_BASE                                (AIR105_AHB_BASE + 0x8000)
+#define DCMI_BASE                               (AIR105_AHB_BASE + 0x60000)
+#define CACHE_BASE                              (AIR105_AHB_BASE + 0x80000)
+#define QRCODE_BASE                             (AIR105_AHB_BASE + 0x90000)
+#define GPU_BASE                                (AIR105_AHB_BASE + 0xA1000)
+#define QSPI_BASE                               (AIR105_AHB_BASE + 0xA2000)
+#define HSPI_BASE                              	(AIR105_AHB_BASE + 0xA3000)
+
+#define SCI0_BASE                               (AIR105_APB0_BASE)
+#define CRC_BASE                                (AIR105_APB0_BASE + 0x2000)
+#define TIMM0_BASE                              (AIR105_APB0_BASE + 0x3000)
+#define ADC_BASE                                (AIR105_APB0_BASE + 0x4000)
+#define DAC_BASE                                (AIR105_APB0_BASE + 0x4100)
+#define AWD_BASE                                (AIR105_APB0_BASE + 0x4200)
+#define SCI2_BASE                               (AIR105_APB0_BASE + 0x5000)
+#define UART0_BASE                              (AIR105_APB0_BASE + 0x6000)
+#define UART1_BASE                              (AIR105_APB0_BASE + 0x7000)
+#define SPIM1_BASE                              (AIR105_APB0_BASE + 0x8000)
+#define SPIM2_BASE                              (AIR105_APB0_BASE + 0x9000)
+#define SPIM0_BASE                              (AIR105_APB0_BASE + 0xA000)
+#define SPIS0_BASE                              (AIR105_APB0_BASE + 0xB000)
+#define WDG_BASE                                (AIR105_APB0_BASE + 0xC000)
+#define GPIO_BASE                               (AIR105_APB0_BASE + 0xD000)
+#define TRNG_BASE                               (AIR105_APB0_BASE + 0xE000)
+#define SYSCTRL_BASE                            (AIR105_APB0_BASE + 0xF000)
+
+#define MSR_BASE                                (AIR105_APB1_BASE)
+
+#define BPU_BASE                                (AIR105_APB2_BASE)
+
+
+#define UART2_BASE                              (AIR105_APB3_BASE + 0x4000)
+#define UART3_BASE                              (AIR105_APB3_BASE + 0x5000)
+#define KEYBOARD_BASE                           (AIR105_APB3_BASE + 0x8000)
+#define I2C0_BASE                               (AIR105_APB3_BASE + 0x9000)
+
+#define HSPIM_BASE								(AIR105_AHB_BASE + 0xA3020)	
+
+/*@}*/ /* end of group <Device>_MemoryMap */
+
+
+/******************************************************************************/
+/*                         Peripheral declaration                             */
+/******************************************************************************/
+/* ToDo: add here your device peripherals pointer definitions
+         following is an example for timer                                    */
+
+/** @addtogroup <Device>_PeripheralDecl <Device> Peripheral Declaration
+  @{
+*/
+#define SYSCTRL                                 ((SYSCTRL_TypeDef *) SYSCTRL_BASE)
+
+#define UART0                                   ((UART_TypeDef *) UART0_BASE)
+#define UART1                                   ((UART_TypeDef *) UART1_BASE)
+#define UART2                                   ((UART_TypeDef *) UART2_BASE)
+#define UART3                                   ((UART_TypeDef *) UART3_BASE)
+
+#define SPIM0                                   ((SPI_TypeDef *) SPIM0_BASE)
+#define SPIM1                                   ((SPI_TypeDef *) SPIM1_BASE)
+#define SPIM2                                   ((SPI_TypeDef *) SPIM2_BASE)
+
+#define SPIS0                                   ((SPI_TypeDef *) SPIS0_BASE)
+
+#define QSPI                                    ((QSPI_TypeDef *) QSPI_BASE)
+
+#define HSPIM                                   ((HSPIM_TypeDef *) HSPIM_BASE)
+#define CACHE                                   ((CACHE_TypeDef *)CACHE_BASE)
+#define QRCODE                                  ((QRCODE_TypeDef *)QRCODE_BASE)
+#define GPU                                     ((GPU_TypeDef *)GPU_BASE)
+#define SCI0                                    ((SCI_TypeDef *) SCI0_BASE)
+#define SCI2                                    ((SCI_TypeDef *) SCI2_BASE)
+
+#define TIMM0                                   ((TIM_Module_TypeDef *)TIMM0_BASE)
+
+#define ADC0                                    ((ADC_TypeDef *)ADC_BASE)
+#define DAC                                     ((DAC_TypeDef *)DAC_BASE)
+#define AWD                                     ((AWD_TypeDef *)AWD_BASE)
+
+#define TRNG                                    ((TRNG_TypeDef *)TRNG_BASE)
+#define LCD                                     ((LCD_TypeDef *)LCD_BASE)
+#define KCU                                     ((KCU_TypeDef *)KEYBOARD_BASE)   
+#define CRC                                     ((CRC_TypeDef *)CRC_BASE)
+#define OTP                                     ((OTP_TypeDef *)OTP_BASE)
+
+#define I2C0                                    ((I2C_TypeDef *)I2C0_BASE)
+
+#define DMA                                     ((DMA_MODULE_TypeDef *)DMA_BASE)
+#define DMA_Channel_0                           ((DMA_TypeDef *)DMA_BASE)
+#define DMA_Channel_1                           ((DMA_TypeDef *)(DMA_BASE + 0x58))
+#define DMA_Channel_2                           ((DMA_TypeDef *)(DMA_BASE + 0x58*2))
+#define DMA_Channel_3                           ((DMA_TypeDef *)(DMA_BASE + 0x58*3))
+#define DMA_Channel_4                           ((DMA_TypeDef *)(DMA_BASE + 0x58*4))
+#define DMA_Channel_5                           ((DMA_TypeDef *)(DMA_BASE + 0x58*5))
+#define DMA_Channel_6                           ((DMA_TypeDef *)(DMA_BASE + 0x58*6))
+#define DMA_Channel_7                           ((DMA_TypeDef *)(DMA_BASE + 0x58*7))
+
+
+#define GPIO                                    ((GPIO_MODULE_TypeDef *)GPIO_BASE)
+#define GPIOA                                   ((GPIO_TypeDef *)GPIO_BASE)
+#define GPIOB                                   ((GPIO_TypeDef *)(GPIO_BASE + 0x0010))
+#define GPIOC                                   ((GPIO_TypeDef *)(GPIO_BASE + 0x0020))
+#define GPIOD                                   ((GPIO_TypeDef *)(GPIO_BASE + 0x0030))
+#define GPIOE                                   ((GPIO_TypeDef *)(GPIO_BASE + 0x0040))
+#define GPIOF                                   ((GPIO_TypeDef *)(GPIO_BASE + 0x0050))
+#define GPIO_GROUP                              ((GPIO_TypeDef *)GPIO_BASE)
+#define GPIO_ALT_GROUP                          ((__IO uint32_t *)(GPIO_BASE + 0x180))
+#define GPIO_WKEN_TYPE_EN                       ((__IO uint32_t *)(GPIO_BASE + 0x220))
+#define GPIO_WKEN_P0_EN                         ((__IO uint32_t *)(GPIO_BASE + 0x224))
+#define GPIO_WKEN_P1_EN                         ((__IO uint32_t *)(GPIO_BASE + 0x228))
+#define GPIO_WKEN_P2_EN                         ((__IO uint32_t *)(GPIO_BASE + 0x22C))
+
+#define WDT                                     ((WDT_TypeDef *)WDG_BASE)
+#define SSC                                     ((SSC_TypeDef *)SSC_BASE)   
+#define TST                                     ((MH_SMCU_TST_TypeDef *)TST_BASE)
+
+#define DCMI                                    ((DCMI_TypeDef *)DCMI_BASE)
+#define BPU                                     ((BPU_TypeDef *)BPU_BASE)
+#define BPK                                     ((BPK_TypeDef *)BPU_BASE)
+#define RTC                                     ((RTC_TypeDef *)(BPU_BASE + 0xA0))
+#define SENSOR                                  ((SEN_TypeDef *)(BPU_BASE + 0xBC))    
+#define SEN_FLAG                                ((FLAG_TypeDef*)(BPU_BASE + 0x164))
+
+
+/** @addtogroup Exported_constants
+  * @{
+  */
+  
+  /** @addtogroup Peripheral_Registers_Bits_Definition
+  * @{
+  */
+    
+/******************************************************************************/
+/*                         Peripheral Registers_Bits_Definition               */
+/******************************************************************************/
+
+/******************************************************************************/
+/*                                                                            */
+/*                             System Control Unit                            */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for FREQ_SEL register  *******************/
+#define SYSCTRL_FREQ_SEL_XTAL_Pos                   (16)
+#define SYSCTRL_FREQ_SEL_XTAL_Mask                  (0x1F << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_108Mhz                (0x08 << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_120Mhz                (0x09 << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_132Mhz                (0x0a << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_144Mhz                (0x0b << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_156Mhz                (0x0c << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_168Mhz                (0x0d << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_180Mhz                (0x0e << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_192Mhz                (0x0f << SYSCTRL_FREQ_SEL_XTAL_Pos)
+#define SYSCTRL_FREQ_SEL_XTAL_204Mhz                (0x10 << SYSCTRL_FREQ_SEL_XTAL_Pos)
+
+#define SYSCTRL_FREQ_SEL_CLOCK_SOURCE_Pos           (12)
+#define SYSCTRL_FREQ_SEL_CLOCK_SOURCE_Mask          (0x01 << SYSCTRL_FREQ_SEL_CLOCK_SOURCE_Pos)
+#define SYSCTRL_FREQ_SEL_CLOCK_SOURCE_EXT           (0x00 << SYSCTRL_FREQ_SEL_CLOCK_SOURCE_Pos)
+#define SYSCTRL_FREQ_SEL_CLOCK_SOURCE_INC           (0x01 << SYSCTRL_FREQ_SEL_CLOCK_SOURCE_Pos)
+
+#define SYSCTRL_FREQ_SEL_PLL_DIV_Pos               	(8)
+#define SYSCTRL_FREQ_SEL_PLL_DIV_Mask              	(0x03 << SYSCTRL_FREQ_SEL_PLL_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_PLL_DIV_1_0                (0x00 << SYSCTRL_FREQ_SEL_PLL_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_PLL_DIV_1_2                (0x01 << SYSCTRL_FREQ_SEL_PLL_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_PLL_DIV_1_4                (0x02 << SYSCTRL_FREQ_SEL_PLL_DIV_Pos)
+
+#define SYSCTRL_FREQ_SEL_HCLK_DIV_Pos               (4)
+#define SYSCTRL_FREQ_SEL_HCLK_DIV_Mask              (0x01 << SYSCTRL_FREQ_SEL_HCLK_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_HCLK_DIV_1_0               (0x00 << SYSCTRL_FREQ_SEL_HCLK_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_HCLK_DIV_1_2               (0x01 << SYSCTRL_FREQ_SEL_HCLK_DIV_Pos)
+
+#define SYSCTRL_FREQ_SEL_PCLK_DIV_Pos               (0)
+#define SYSCTRL_FREQ_SEL_PCLK_DIV_Mask              (0x01 << SYSCTRL_FREQ_SEL_PCLK_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_PCLK_DIV_1_2               (0x00 << SYSCTRL_FREQ_SEL_PCLK_DIV_Pos)
+#define SYSCTRL_FREQ_SEL_PCLK_DIV_1_4               (0x01 << SYSCTRL_FREQ_SEL_PCLK_DIV_Pos)
+
+/*******************  Bit definition for CG_CTRL2 register  *******************/
+#define SYSCTRL_AHBPeriph_DMA                       ((uint32_t)0x20000000)
+#define SYSCTRL_AHBPeriph_USB                       ((uint32_t)0x10000000)
+#define SYSCTRL_AHBPeriph_QR                        ((uint32_t)0x00000020)
+#define SYSCTRL_AHBPeriph_OTP                       ((uint32_t)0x00000008)
+#define SYSCTRL_AHBPeriph_GPU                       ((uint32_t)0x00000004)
+#define SYSCTRL_AHBPeriph_LCD                       ((uint32_t)0x00000002)
+#define SYSCTRL_AHBPeriph_CRYPT                     ((uint32_t)0x00000001)
+#define SYSCTRL_AHBPeriph_ALL                       ((uint32_t)0x3000002F)
+#define IS_SYSCTRL_AHB_PERIPH(PERIPH)               ((((PERIPH) & ~SYSCTRL_AHBPeriph_ALL) == 0x00) && ((PERIPH) != 0x00))
+ 
+/*******************  Bit definition for CG_CTRL1 register  *******************/
+#define SYSCTRL_APBPeriph_TRNG                      ((uint32_t)0x80000000)
+#define SYSCTRL_APBPeriph_ADC                       ((uint32_t)0x40000000)
+#define SYSCTRL_APBPeriph_CRC                       ((uint32_t)0x20000000)
+#define SYSCTRL_APBPeriph_KBD						((uint32_t)0x08000000)
+#define SYSCTRL_APBPeriph_BPU			            ((uint32_t)0x04000000)
+#define SYSCTRL_APBPeriph_DCMIS	                    ((uint32_t)0x00800000)
+#define SYSCTRL_APBPeriph_TIMM0                     ((uint32_t)0x00200000)
+#define SYSCTRL_APBPeriph_GPIO                      ((uint32_t)0x00100000)
+#define SYSCTRL_APBPeriph_I2C0                      ((uint32_t)0x00040000)
+#define SYSCTRL_APBPeriph_SCI2                      ((uint32_t)0x00010000)
+#define SYSCTRL_APBPeriph_SCI0                      ((uint32_t)0x00004000)
+#define SYSCTRL_APBPeriph_HSPI						((uint32_t)0x00002000)
+#define SYSCTRL_APBPeriph_SPI2						((uint32_t)0x00000400)
+#define SYSCTRL_APBPeriph_SPI1						((uint32_t)0x00000200)
+#define SYSCTRL_APBPeriph_SPI0						((uint32_t)0x00000100)
+#define SYSCTRL_APBPeriph_UART3						((uint32_t)0x00000008)
+#define SYSCTRL_APBPeriph_UART2						((uint32_t)0x00000004)
+#define SYSCTRL_APBPeriph_UART1                     ((uint32_t)0x00000002)
+#define SYSCTRL_APBPeriph_UART0                     ((uint32_t)0x00000001)
+#define SYSCTRL_APBPeriph_ALL                       ((uint32_t)0xECB5670F)
+#define IS_SYSCTRL_APB_PERIPH(PERIPH)               ((((PERIPH) & ~SYSCTRL_APBPeriph_ALL) == 0x00) && ((PERIPH) != 0x00))
+
+/*******************  Bit definition for SOFT_RST2 register  *******************/
+#define SYSCTRL_GLB_RESET                           ((uint32_t)0x80000000)
+#define SYSCTRL_CM3_RESET                           ((uint32_t)0x40000000)
+#define SYSCTRL_DMA_RESET                           ((uint32_t)0x20000000)
+#define SYSCTRL_USB_RESET                           ((uint32_t)0x10000000)
+#define SYSCTRL_QR_RESET                            ((uint32_t)0x00000020)
+#define SYSCTRL_OTP_RESET                           ((uint32_t)0x00000008)
+#define SYSCTRL_GPU_RESET                           ((uint32_t)0x00000004)
+#define SYSCTRL_LCD_RESET							((uint32_t)0x00000002)
+#define SYSCTRL_CRYPT_RESET							((uint32_t)0x00000001)
+#define SYSCTRL_AHBPeriph_RESET_ALL					((uint32_t)0xF000002F)
+#define IS_SYSCTRL_AHB_PERIPH_RESET(PERIPH)         ((((PERIPH) & ~SYSCTRL_AHBPeriph_RESET_ALL) == 0x00) && ((PERIPH) != 0x00))
+                                                                               
+/*******************  Bit definition for PHER_CTRL register  *******************/
+#define SYSCTRL_PHER_CTRL_SPI0_SLV_EN               ((uint32_t)0x01000000)      /* 0:MASTER  1:SLAVE */
+#define SYSCTRL_PHER_CTRL_SCI2_VCCEN_INV            ((uint32_t)0x00400000)
+#define SYSCTRL_PHER_CTRL_SCI0_VCCEN_INV            ((uint32_t)0x00100000)
+#define SYSCTRL_PHER_CTRL_SCI2_CDET_INV             ((uint32_t)0x00040000)
+#define SYSCTRL_PHER_CTRL_SCI0_CDET_INV             ((uint32_t)0x00010000)
+
+/*******************  Bit definition for DMA_CHAN REGISTER  ********************/
+#define SYSCTRL_PHER_CTRL_DMA_CH0_IF_Pos                    (0)
+#define SYSCTRL_PHER_CTRL_DMA_CH0_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH0_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH1_IF_Pos                    (8)
+#define SYSCTRL_PHER_CTRL_DMA_CH1_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH1_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH2_IF_Pos                    (16)
+#define SYSCTRL_PHER_CTRL_DMA_CH2_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH2_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH3_IF_Pos                    (24)
+#define SYSCTRL_PHER_CTRL_DMA_CH3_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH3_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH4_IF_Pos                    (0)
+#define SYSCTRL_PHER_CTRL_DMA_CH4_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH4_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH5_IF_Pos                    (8)
+#define SYSCTRL_PHER_CTRL_DMA_CH5_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH5_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH6_IF_Pos                    (16)
+#define SYSCTRL_PHER_CTRL_DMA_CH6_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH6_IF_Pos)
+
+#define SYSCTRL_PHER_CTRL_DMA_CH7_IF_Pos                    (24)
+#define SYSCTRL_PHER_CTRL_DMA_CH7_IF_Mask                   (0x3FU<<SYSCTRL_PHER_CTRL_DMA_CH7_IF_Pos)
+
+
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_DCMI_TX                (0x00)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_LCD                    (0x01)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART0_TX               (0x02)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART0_RX               (0x03)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART1_TX               (0x04)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART1_RX               (0x05)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_DAC                    (0x06)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_TX                (0x0A)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_RX                (0x0B)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_TX                (0x0C)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_RX                (0x0D)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_TX                (0x0E)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_RX                (0x0F)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART2_TX               (0x14)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART2_RX               (0x15)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART3_TX               (0x16)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART3_RX               (0x17)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_I2C_TX                 (0x18)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_I2C_RX                 (0x19)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_QSPI_TX                (0x1A)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_RX                (0x20)
+#define SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_TX                (0x21)
+
+/******************************************************************************/
+/*                                                                            */
+/*                Universal Asynchronous Receiver Transmitter                 */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for UART_RBR register  *******************/
+#define UART_RBR_RBR                         ((uint32_t)0x01FF)            /*!< Data value */
+
+/*******************  Bit definition for UART_THR register  *******************/
+#define UART_THR_THR                         ((uint32_t)0x01FF)            /*!< Data value */
+
+/*******************  Bit definition for UART_DLH register  *******************/
+#define UART_DLH_DLH                         ((uint32_t)0x0FF)
+
+/*******************  Bit definition for UART_DLL register  *******************/
+#define UART_DLL_DLL                         ((uint32_t)0x0FF)
+
+/*******************  Bit definition for UART_IER register  *******************/
+#define UART_IER_ERBFI                          ((uint32_t)0x0001)
+#define UART_IER_ETBEI                          ((uint32_t)0x0002)
+#define UART_IER_ELSI                           ((uint32_t)0x0004)
+#define UART_IER_EDSSI                          ((uint32_t)0x0008)
+#define UART_IER_PTIME                          ((uint32_t)0x0080)
+
+/*******************  Bit definition for UART_IIR register  *******************/
+#define UART_IIR_IID                            ((uint32_t)0x0007)
+#define UART_IIR_IID_0                          ((uint32_t)0x0001)
+#define UART_IIR_IID_1                          ((uint32_t)0x0002)
+#define UART_IIR_IID_2                          ((uint32_t)0x0004)
+#define UART_IIR_IID_3                          ((uint32_t)0x0008)
+#define UART_IIR_FIFOSE                         ((uint32_t)0x0060)
+#define UART_IIR_FIFOSE_0                       ((uint32_t)0x0020)
+#define UART_IIR_FIFOSE_1                       ((uint32_t)0x0040)
+
+/*******************  Bit definition for UART_FCR register  *******************/
+#define UART_FCR_FIFOE                          ((uint32_t)0x0001)
+#define UART_FCR_RFIFOR                         ((uint32_t)0x0002)
+#define UART_FCR_XFIFOR                         ((uint32_t)0x0004)
+#define UART_FCR_DMAM                           ((uint32_t)0x0008)
+#define UART_FCR_TET                            ((uint32_t)0x0030)
+#define UART_FCR_TET_0                          ((uint32_t)0x0010)
+#define UART_FCR_TET_1                          ((uint32_t)0x0020)
+#define UART_FCR_RCVER                          ((uint32_t)0x00C0)
+#define UART_FCR_RCVER_0                        ((uint32_t)0x0040)
+#define UART_FCR_RCVER_1                        ((uint32_t)0x0080)
+
+/*******************  Bit definition for UART_LCR register  *******************/
+#define UART_LCR_DLS                            ((uint32_t)0x0003)
+#define UART_LCR_DLS_0                          ((uint32_t)0x0001)
+#define UART_LCR_DLS_1                          ((uint32_t)0x0002)
+#define UART_LCR_STOP                           ((uint32_t)0x0004)
+#define UART_LCR_PEN                            ((uint32_t)0x0008)
+#define UART_LCR_EPS                            ((uint32_t)0x0010)
+#define UART_LCR_SP                             ((uint32_t)0x0020)
+#define UART_LCR_BC                             ((uint32_t)0x0040)
+#define UART_LCR_DLAB                           ((uint32_t)0x0080)
+
+/*******************  Bit definition for UART_MCR register  *******************/
+#define UART_MCR_DTR                            ((uint32_t)0x0001)
+#define UART_MCR_RTS                            ((uint32_t)0x0002)
+#define UART_MCR_OUT1                           ((uint32_t)0x0004)
+#define UART_MCR_OUT2                           ((uint32_t)0x0008)
+#define UART_MCR_LB                             ((uint32_t)0x0010)
+#define UART_MCR_AFCE                           ((uint32_t)0x0020)
+#define UART_MCR_SIRE                           ((uint32_t)0x0040)
+
+/*******************  Bit definition for UART_LSR register  *******************/
+#define UART_LSR_DR                             ((uint32_t)0x0001)
+#define UART_LSR_OE                             ((uint32_t)0x0002)
+#define UART_LSR_PE                             ((uint32_t)0x0004)
+#define UART_LSR_FE                             ((uint32_t)0x0008)
+#define UART_LSR_BI                             ((uint32_t)0x0010)
+#define UART_LSR_THRE                           ((uint32_t)0x0020)
+#define UART_LSR_TEMT                           ((uint32_t)0x0040)
+#define UART_LSR_PFE                            ((uint32_t)0x0080)
+
+/*******************  Bit definition for UART_MSR register  *******************/
+#define UART_MSR_DCTS                               ((uint32_t)0x0001)
+#define UART_MSR_DDSR                               ((uint32_t)0x0002)
+#define UART_MSR_TERI                               ((uint32_t)0x0004)
+#define UART_MSR_DDCD                               ((uint32_t)0x0008)
+#define UART_MSR_CTS                                ((uint32_t)0x0010)
+#define UART_MSR_DSR                                ((uint32_t)0x0020)
+#define UART_MSR_RI                                 ((uint32_t)0x0040)
+#define UART_MSR_DCD                                ((uint32_t)0x0080)
+
+/*******************  Bit definition for UART_SRBR register  *******************/
+#define UART_SRBR_SRBR                          ((uint32_t)0x01FF)            /*!< Data value */
+
+/*******************  Bit definition for UART_STHR register  *******************/
+#define UART_STHR_STHR                          ((uint32_t)0x01FF)            /*!< Data value */
+
+/*******************  Bit definition for UART_FAR register  *******************/
+#define UART_FAR_FAR                            ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_TFR register  *******************/
+#define UART_TFR_TFR                            ((uint32_t)0x00FF)
+
+/*******************  Bit definition for UART_RFW register  *******************/
+#define UART_RFW_RFWD                           ((uint32_t)0x00FF)
+#define UART_RFW_RFPE                           ((uint32_t)0x0100)
+#define UART_RFW_RFFE                           ((uint32_t)0x0200)
+
+/*******************  Bit definition for UART_USR register  *******************/
+#define UART_USR_BUSY                               ((uint32_t)0x0001)
+#define UART_USR_TFNF                               ((uint32_t)0x0002)
+#define UART_USR_TFE                                ((uint32_t)0x0004)
+#define UART_USR_RFNE                               ((uint32_t)0x0008)
+#define UART_USR_RFF                                ((uint32_t)0x0010)
+
+/*******************  Bit definition for UART_TFL register  *******************/
+#define UART_TFL_TFL                                ((uint32_t)0x000F)
+
+/*******************  Bit definition for UART_RFL register  *******************/
+#define UART_RFL_RFL                                ((uint32_t)0x000F)
+
+/*******************  Bit definition for UART_SRR register  *******************/
+#define UART_SRR_UR                                 ((uint32_t)0x0001)
+#define UART_SRR_RFR                                ((uint32_t)0x0002)
+#define UART_SRR_XFR                                ((uint32_t)0x0004)
+
+/*******************  Bit definition for UART_SRR register  *******************/
+#define UART_SRR_UR                                 ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_SRTS register  *******************/
+#define UART_SRTS_SRTS                              ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_SBCR register  *******************/
+#define UART_SBCR_SBCR                              ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_SDMAM register  *******************/
+#define UART_SDMAM_SDMAM                            ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_SFE register  *******************/
+#define UART_SFE_SFE                                ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_SRT register  *******************/
+#define UART_SRT_SRT                                ((uint32_t)0x0003)
+#define UART_SRT_SRT_0                              ((uint32_t)0x0001)
+#define UART_SRT_SRT_1                              ((uint32_t)0x0002)
+
+/*******************  Bit definition for UART_STET register  *******************/
+#define UART_STET_STET                              ((uint32_t)0x0003)
+#define UART_STET_STET_0                            ((uint32_t)0x0001)
+#define UART_STET_STET_1                            ((uint32_t)0x0002)
+
+/*******************  Bit definition for UART_HTX register  *******************/
+#define UART_HTX_HTX                                ((uint32_t)0x0001)
+
+/*******************  Bit definition for UART_DMASA register  *******************/
+#define UART_DMASA_DMASA                            ((uint32_t)0x0001)
+
+/******************************************************************************/
+/*                                                                            */
+/*                General Purpose and Alternate Function I/O                  */
+/*                                                                            */
+/******************************************************************************/
+
+/*!<******************  Bit definition for GPIO_IODR register  *******************/
+#define DEEP_SLEEP_WKUP_EN_SENSOR           (BIT14)
+#define DEEP_SLEEP_WKUP_EN_MSR              (BIT13)
+#define DEEP_SLEEP_WKUP_EN_RTC              (BIT12)
+#define DEEP_SLEEP_WKUP_EN_KBD              (BIT11)
+#define DEEP_SLEEP_WKUP_EN_GPIO             (BIT0)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                        Serial Peripheral Interface                         */
+/*                                                                            */
+/******************************************************************************/
+
+/*****************  Bit definition for SPI_CTRLR0 register  *******************/
+#define SPI_CTRLR0_DFS                      ((uint32_t)0x000F)
+#define SPI_CTRLR0_DFS_0                    ((uint32_t)0x0001)
+#define SPI_CTRLR0_DFS_1                    ((uint32_t)0x0002)
+#define SPI_CTRLR0_DFS_2                    ((uint32_t)0x0004)
+#define SPI_CTRLR0_DFS_3                    ((uint32_t)0x0008)
+#define SPI_CTRLR0_FRF                      ((uint32_t)0x0030)
+#define SPI_CTRLR0_FRF_0                    ((uint32_t)0x0010)
+#define SPI_CTRLR0_FRF_1                    ((uint32_t)0x0020)
+#define SPI_CTRLR0_SCPH                     ((uint32_t)0x0040)
+#define SPI_CTRLR0_SCPOL                    ((uint32_t)0x0080)
+#define SPI_CTRLR0_TMOD                     ((uint32_t)0x0300)
+#define SPI_CTRLR0_TMOD_0                   ((uint32_t)0x0100)
+#define SPI_CTRLR0_TMOD_1                   ((uint32_t)0x0200)
+#define SPI_CTRLR0_SLV_OE                   ((uint32_t)0x0400)
+#define SPI_CTRLR0_SRL                      ((uint32_t)0x0800)
+#define SPI_CTRLR0_CFS                      ((uint32_t)0xF000)
+
+/*****************  Bit definition for SPI_CTRLR1 register  *******************/
+#define SPI_CTRLR0_NDF                      ((uint32_t)0xFFFF)
+
+/*****************  Bit definition for SPI_SSIENR register  *******************/
+#define SPI_SSIENR_SSIENR                   ((uint32_t)0x0001)
+
+/*****************  Bit definition for SPI_MWCR register  *********************/
+#define SPI_MWCR_MWMOD                      ((uint32_t)0x0001)
+#define SPI_MWCR_MDD                        ((uint32_t)0x0002)
+#define SPI_MWCR_MHS                        ((uint32_t)0x0004)
+
+/*****************  Bit definition for SPI_SER register  **********************/
+#define SPI_SER_SER                         ((uint32_t)0x000F)
+#define SPI_SER_0                           ((uint32_t)0x0001)
+#define SPI_SER_1                           ((uint32_t)0x0002)
+#define SPI_SER_2                           ((uint32_t)0x0004)
+#define SPI_SER_3                           ((uint32_t)0x0008)
+
+/*****************  Bit definition for SPI_BAUDR register  ********************/
+#define SPI_BAUDR_BAUDR                     ((uint32_t)0xFFFF)
+
+/*****************  Bit definition for SPI_TXFTLR register  *******************/
+#define SPI_TXFTLR_TFT                      ((uint32_t)0x000F)
+/*****************  Bit definition for SPI_RXFTLR register  *******************/
+#define SPI_RXFTLR_RFT                      ((uint32_t)0x000F)
+/*****************  Bit definition for SPI_TXFLR register  ********************/
+#define SPI_TXFLR_TXTFL                     ((uint32_t)0x001F)
+/*****************  Bit definition for SPI_RXFLR register  ********************/
+#define SPI_RXFLR_RXTFL                     ((uint32_t)0x001F)
+
+/*****************  Bit definition for SPI_SR register  ***********************/
+#define SPI_SR_BUSY                         ((uint32_t)0x0001)
+#define SPI_SR_TFNF                         ((uint32_t)0x0002)
+#define SPI_SR_TFE                          ((uint32_t)0x0004)
+#define SPI_SR_RFNE                         ((uint32_t)0x0008)
+#define SPI_SR_RFF                          ((uint32_t)0x0010)
+#define SPI_SR_TXE                          ((uint32_t)0x0020)
+#define SPI_SR_DCOL                         ((uint32_t)0x0040)
+/*****************  Bit definition for SPI_IMR register  **********************/
+#define SPI_IMR_TXEIM                       ((uint32_t)0x0001)
+#define SPI_IMR_TXOIM                       ((uint32_t)0x0002)
+#define SPI_IMR_RXUIM                       ((uint32_t)0x0004)
+#define SPI_IMR_RXOIM                       ((uint32_t)0x0008)
+#define SPI_IMR_RXFIM                       ((uint32_t)0x0010)
+#define SPI_IMR_MSTIM                       ((uint32_t)0x0020)
+/*****************  Bit definition for SPI_ISR register  **********************/
+#define SPI_ISR_TXEIS                       ((uint32_t)0x0001)
+#define SPI_ISR_TXOIS                       ((uint32_t)0x0002)
+#define SPI_ISR_RXUIS                       ((uint32_t)0x0004)
+#define SPI_ISR_RXOIS                       ((uint32_t)0x0008)
+#define SPI_ISR_RXFIS                       ((uint32_t)0x0010)
+#define SPI_ISR_MSTIS                       ((uint32_t)0x0020)
+/*****************  Bit definition for SPI_RISR register  *********************/
+#define SPI_RISR_TXEIR                      ((uint32_t)0x0001)
+#define SPI_RISR_TXOIR                      ((uint32_t)0x0002)
+#define SPI_RISR_RXUIR                      ((uint32_t)0x0004)
+#define SPI_RISR_RXOIR                      ((uint32_t)0x0008)
+#define SPI_RISR_RXFIR                      ((uint32_t)0x0010)
+#define SPI_RISR_MSTIR                      ((uint32_t)0x0020)
+/*****************  Bit definition for SPI_TXOICR register  *******************/
+#define SPI_TXOICR_TXOICR                   ((uint32_t)0x0001)
+/*****************  Bit definition for SPI_RXOICR register  *******************/
+#define SPI_RXOICR_RXOICR                   ((uint32_t)0x0001)
+/*****************  Bit definition for SPI_RXUICR register  *******************/
+#define SPI_RXUICR_RXUICR                   ((uint32_t)0x0001)
+/*****************  Bit definition for SPI_MSTICR register  *******************/
+#define SPI_MSTICR_MSTICR                   ((uint32_t)0x0001)
+
+/*****************  Bit definition for SPI_DMACR register  ********************/
+#define SPI_DMACR_RDMAE                     ((uint32_t)0x0001)
+#define SPI_DMACR_TDMAE                     ((uint32_t)0x0002)
+/*****************  Bit definition for SPI_DMATDLR register  ******************/
+#define SPI_DMATDLR_DMATDLR                 ((uint32_t)0x000F)
+/*****************  Bit definition for SPI_DMARDLR register  ******************/
+#define SPI_DMATDLR_DMARDLR                 ((uint32_t)0x000F)
+/*****************  Bit definition for SPI_DMARDLR register  ******************/
+#define SPI_DMATDLR_DMARDLR                 ((uint32_t)0x000F)
+
+/*****************  Bit definition for SPI_DR register  ***********************/
+#define SPI_DR_DR                           ((uint32_t)0xFFFF)
+/**************  Bit definition for SPI_RX_SAMPLE_DLY register  ***************/
+#define SPI_RX_SAMPLE_DLY                   ((uint32_t)0xFFFF)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                      Inter-integrated Circuit Interface                    */
+/*                                                                            */
+/******************************************************************************/
+
+/*******************  Bit definition for IC_CON register  *********************/
+#define I2C_IC_CON_MASTER_MODE                  ((uint32_t)0x0001)
+#define I2C_IC_CON_SPEED                        ((uint32_t)0x0006)
+#define I2C_IC_CON_SPEED_0                      ((uint32_t)0x0002)
+#define I2C_IC_CON_SPEED_1                      ((uint32_t)0x0004)
+#define I2C_IC_CON_10BITADDR_SLAVE              ((uint32_t)0x0008)
+#define I2C_IC_CON_10BITADDR_MASTER             ((uint32_t)0x0010)
+#define I2C_IC_CON_RESTART_EN                   ((uint32_t)0x0020)
+#define I2C_IC_CON_SLAVE_DISABLE                ((uint32_t)0x0040)
+
+/*******************  Bit definition for IC_TAR register  *********************/
+#define I2C_IC_TAR_TAR                          ((uint32_t)0x03FF)
+#define I2C_IC_TAR_GC_OR_START                  ((uint32_t)0x0400)
+#define I2C_IC_TAR_SPECIAL                      ((uint32_t)0x0800)
+#define I2C_IC_TAR_10BITADDR_MASTER             ((uint32_t)0x1000)
+
+/*******************  Bit definition for IC_SAR register  *********************/
+#define I2C_IC_SAR_SAR                          ((uint32_t)0x03FF)
+
+/*******************  Bit definition for IC_HS_MADDR register  ****************/
+#define I2C_IC_HS_MADDR_MAR                     ((uint32_t)0x0007)
+#define I2C_IC_HS_MADDR_MAR_0                   ((uint32_t)0x0001)
+#define I2C_IC_HS_MADDR_MAR_1                   ((uint32_t)0x0002)
+#define I2C_IC_HS_MADDR_MAR_2                   ((uint32_t)0x0004)
+
+/*******************  Bit definition for IC_DATA_CMD register  ****************/
+#define I2C_IC_DATA_CMD_DAT                     ((uint32_t)0x00FF)
+#define I2C_IC_DATA_CMD_CMD                     ((uint32_t)0x0100)
+#define I2C_IC_DATA_CMD_STOP                    ((uint32_t)0x0200)
+#define I2C_IC_DATA_CMD_RESTART                 ((uint32_t)0x0400)
+
+/*******************  Bit definition for IC_SS_SCL_HCNT register  *************/
+#define I2C_IC_SS_SCL_HCNT_HCNT                     ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_SS_SCL_LCNT register  *************/
+#define I2C_IC_SS_SCL_LCNT_LCNT                     ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_FS_SCL_HCNT register  *************/
+#define I2C_IC_FS_SCL_HCNT_HCNT                     ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_FS_SCL_LCNT register  *************/
+#define I2C_IC_FS_SCL_LCNT_LCNT                     ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_HS_SCL_HCNT register  *************/
+#define I2C_IC_HS_SCL_HCNT_HCNT                     ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_HS_SCL_LCNT register  *************/
+#define I2C_IC_HS_SCL_LCNT_LCNT                     ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_INTR_STAT register  ***************/
+#define I2C_IC_INTR_STAT_R_RX_UNDER                 ((uint32_t)0x0001)
+#define I2C_IC_INTR_STAT_R_RX_OVER                  ((uint32_t)0x0002)
+#define I2C_IC_INTR_STAT_R_RX_FULL                  ((uint32_t)0x0004)
+#define I2C_IC_INTR_STAT_R_TX_OVER                  ((uint32_t)0x0008)
+#define I2C_IC_INTR_STAT_R_TX_EMPTY                 ((uint32_t)0x0010)
+#define I2C_IC_INTR_STAT_R_RD_REQ                   ((uint32_t)0x0020)
+#define I2C_IC_INTR_STAT_R_TX_ABRT                  ((uint32_t)0x0040)
+#define I2C_IC_INTR_STAT_R_RX_DONE                  ((uint32_t)0x0080)
+#define I2C_IC_INTR_STAT_R_ACTIVITY                 ((uint32_t)0x0100)
+#define I2C_IC_INTR_STAT_R_STOP_DET                 ((uint32_t)0x0200)
+#define I2C_IC_INTR_STAT_R_START_DET                ((uint32_t)0x0400)
+#define I2C_IC_INTR_STAT_R_GEN_CALL                 ((uint32_t)0x0800)
+
+/*******************  Bit definition for IC_INTR_MASK register  ***************/
+#define I2C_IC_INTR_MASK_M_RX_UNDER                 ((uint32_t)0x0001)
+#define I2C_IC_INTR_MASK_M_RX_OVER                  ((uint32_t)0x0002)
+#define I2C_IC_INTR_MASK_M_RX_FULL                  ((uint32_t)0x0004)
+#define I2C_IC_INTR_MASK_M_TX_OVER                  ((uint32_t)0x0008)
+#define I2C_IC_INTR_MASK_M_TX_EMPTY                 ((uint32_t)0x0010)
+#define I2C_IC_INTR_MASK_M_RD_REQ                   ((uint32_t)0x0020)
+#define I2C_IC_INTR_MASK_M_TX_ABRT                  ((uint32_t)0x0040)
+#define I2C_IC_INTR_MASK_M_RX_DONE                  ((uint32_t)0x0080)
+#define I2C_IC_INTR_MASK_M_ACTIVITY                 ((uint32_t)0x0100)
+#define I2C_IC_INTR_MASK_M_STOP_DET                 ((uint32_t)0x0200)
+#define I2C_IC_INTR_MASK_M_START_DET                ((uint32_t)0x0400)
+#define I2C_IC_INTR_MASK_M_GEN_CALL                 ((uint32_t)0x0800)
+
+/*******************  Bit definition for IC_RAW_INTR_STAT register  ***********/
+#define I2C_IC_RAW_INTR_STAT_RX_UNDER               ((uint32_t)0x0001)
+#define I2C_IC_RAW_INTR_STAT_RX_OVER                ((uint32_t)0x0002)
+#define I2C_IC_RAW_INTR_STAT_RX_FULL                ((uint32_t)0x0004)
+#define I2C_IC_RAW_INTR_STAT_TX_OVER                ((uint32_t)0x0008)
+#define I2C_IC_RAW_INTR_STAT_TX_EMPTY               ((uint32_t)0x0010)
+#define I2C_IC_RAW_INTR_STAT_RD_REQ                 ((uint32_t)0x0020)
+#define I2C_IC_RAW_INTR_STAT_TX_ABRT                ((uint32_t)0x0040)
+#define I2C_IC_RAW_INTR_STAT_RX_DONE                ((uint32_t)0x0080)
+#define I2C_IC_RAW_INTR_STAT_ACTIVITY               ((uint32_t)0x0100)
+#define I2C_IC_RAW_INTR_STAT_STOP_DET               ((uint32_t)0x0200)
+#define I2C_IC_RAW_INTR_STAT_START_DET              ((uint32_t)0x0400)
+#define I2C_IC_RAW_INTR_STAT_GEN_CALL               ((uint32_t)0x0800)
+
+/*******************  Bit definition for IC_RX_TL register  *******************/
+#define I2C_IC_RX_TL_TL                             ((uint32_t)0x00FF)
+
+/*******************  Bit definition for IC_TX_TL register  *******************/
+#define I2C_IC_TX_TL_TL                             ((uint32_t)0x00FF)
+
+/*******************  Bit definition for IC_CLR_INTR register  ****************/
+#define I2C_IC_CLR_INTR                             ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_RX_UNDER register  ************/
+#define I2C_IC_CLR_RX_UNDER                         ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_RX_OVER register  *************/
+#define I2C_IC_CLR_RX_OVER                          ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_TX_OVER register  *************/
+#define I2C_IC_CLR_TX_OVER                          ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_RD_REQ register  **************/
+#define I2C_IC_CLR_RD_REQ                           ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_TX_ABRT register  *************/
+#define I2C_IC_CLR_TX_ABRT                          ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_RX_DONE register  *************/
+#define I2C_IC_CLR_RX_DONE                          ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_ACTIVITY register  ************/
+#define I2C_IC_CLR_ACTIVITY                         ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_STOP_DET register  ************/
+#define I2C_IC_CLR_STOP_DET                         ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_START_DET register  ***********/
+#define I2C_IC_CLR_START_DET                        ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_CLR_GEN_CALL register  ************/
+#define I2C_IC_CLR_GEN_CALL                         ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_ENABLE  register  *****************/
+#define I2C_IC_ENABLE_ENABLE                        ((uint32_t)0x0001)
+#define I2C_IC_ENABLE_ABORT                         ((uint32_t)0x0002)
+
+/*******************  Bit definition for IC_STATUS  register  *****************/
+#define I2C_IC_STATUS_ACTIVITY                      ((uint32_t)0x0001)
+#define I2C_IC_STATUS_TFNF                          ((uint32_t)0x0002)
+#define I2C_IC_STATUS_TFE                           ((uint32_t)0x0004)
+#define I2C_IC_STATUS_RFNE                          ((uint32_t)0x0008)
+#define I2C_IC_STATUS_RFF                           ((uint32_t)0x0010)
+#define I2C_IC_STATUS_MST_ACTIVITY                  ((uint32_t)0x0020)
+#define I2C_IC_STATUS_SLV_ACTIVITY                  ((uint32_t)0x0040)
+/*******************  Bit definition for IC_TXFLR  register  ******************/
+#define I2C_IC_TXFLR_TXFLR                          (8)
+
+/*******************  Bit definition for IC_RXFLR  register  ******************/
+#define I2C_IC_RXFLR_RXFLR                          (8)
+
+/*******************  Bit definition for IC_SDA_HOLD  register  ***************/
+#define I2C_IC_SDA_HOLD                             ((uint32_t)0xFFFF)
+
+/*******************  Bit definition for IC_TX_ABRT_SOURCE  register  *********/
+#define I2C_IC_TX_ABRT_SOURCE_7B_ADDR_NOACK         ((uint32_t)0x00000001)
+#define I2C_IC_TX_ABRT_SOURCE_10ADDR1_NOACK         ((uint32_t)0x00000002)
+#define I2C_IC_TX_ABRT_SOURCE_10ADDR2_NOACK         ((uint32_t)0x00000004)
+#define I2C_IC_TX_ABRT_SOURCE_TXDATA_NOACK          ((uint32_t)0x00000008)
+#define I2C_IC_TX_ABRT_SOURCE_GCALL_NOACK           ((uint32_t)0x00000010)
+#define I2C_IC_TX_ABRT_SOURCE_GCALL_READ            ((uint32_t)0x00000020)
+#define I2C_IC_TX_ABRT_SOURCE_HS_ACKDET             ((uint32_t)0x00000040)
+#define I2C_IC_TX_ABRT_SOURCE_SBYTE_ACKDET          ((uint32_t)0x00000080)
+#define I2C_IC_TX_ABRT_SOURCE_HS_NORSTRT            ((uint32_t)0x00000100)
+#define I2C_IC_TX_ABRT_SOURCE_SBYTE_NORSTRT         ((uint32_t)0x00000200)
+#define I2C_IC_TX_ABRT_SOURCE_10B_RD_NORSTRT        ((uint32_t)0x00000400)
+#define I2C_IC_TX_ABRT_SOURCE_MASTER_DIS            ((uint32_t)0x00000800)
+#define I2C_IC_TX_ABRT_SOURCE_LOST                  ((uint32_t)0x00001000)
+#define I2C_IC_TX_ABRT_SOURCE_SLVFLUSH_TXFIFO       ((uint32_t)0x00002000)
+#define I2C_IC_TX_ABRT_SOURCE_SLV_ARBLOST           ((uint32_t)0x00004000)
+#define I2C_IC_TX_ABRT_SOURCE_SLVRD_INTX            ((uint32_t)0x00008000)
+#define I2C_IC_TX_ABRT_SOURCE_USER_ABRT             ((uint32_t)0x00010000)
+#define I2C_IC_TX_ABRT_SOURCE_TX_FLUSH_CNT          ((uint32_t)0xFF000000)
+
+/*******************  Bit definition for IC_SLV_DATA_NACK_ONLY  register  *****/
+#define I2C_IC_SLV_DATA_NACK_ONLY                   ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_DMA_TDLR  register  ***************/
+#define I2C_IC_DMA_TDLR_TDLR                        ((uint32_t)0x000F)
+
+/*******************  Bit definition for IC_DMA_RDLR  register  ***************/
+#define I2C_IC_DMA_TDLR_TDLR                        ((uint32_t)0x000F)
+
+/*******************  Bit definition for IC_SDA_SETUP  register  **************/
+#define I2C_IC_SDA_SETUP                            ((uint32_t)0x00FF)
+
+/*******************  Bit definition for IC_ACK_GENERAL_CALL  register  *******/
+#define I2C_IC_ACK_GENERAL_CALL                     ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_ENABLE_STATUS  register  **********/
+#define I2C_IC_ENABLE_STATUS_IC_EN                  ((uint32_t)0x0001)
+#define I2C_IC_ENABLE_STATUS_SLV_RX_ABORTED         ((uint32_t)0x0001)
+#define I2C_IC_ENABLE_STATUS_SLV_FIFO_FILLED_AND_FLUSHED        ((uint32_t)0x0001)
+
+/*******************  Bit definition for IC_FS_SPKLEN  register  **************/
+#define I2C_IC_FS_SPKLEN_SPKLEN                     ((uint32_t)0x00FF)
+
+/*******************  Bit definition for IC_HS_SPKLEN  register  **************/
+#define I2C_IC_HS_SPKLEN_SPKLEN                     ((uint32_t)0x00FF)
+
+/*******************  Bit definition for IC_COMP_PARAM_1  register  ***********/
+#define I2C_IC_COMP_PARAM_1_APB_DATA_WIDTH          ((uint32_t)0x0003)
+#define I2C_IC_COMP_PARAM_1_APB_DATA_WIDTH_0        ((uint32_t)0x0001)
+#define I2C_IC_COMP_PARAM_1_APB_DATA_WIDTH_1        ((uint32_t)0x0002)
+#define I2C_IC_COMP_PARAM_1_MAX_SPEED_MODE          ((uint32_t)0x000C)
+#define I2C_IC_COMP_PARAM_1_MAX_SPEED_MODE_0        ((uint32_t)0x0004)
+#define I2C_IC_COMP_PARAM_1_MAX_SPEED_MODE_1        ((uint32_t)0x0008)
+#define I2C_IC_COMP_PARAM_1_HC_COUNT_VALUES         ((uint32_t)0x0010)
+#define I2C_IC_COMP_PARAM_1_INTR_IO                 ((uint32_t)0x0020)
+#define I2C_IC_COMP_PARAM_1_HAS_DMA                 ((uint32_t)0x0040)
+#define I2C_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS      ((uint32_t)0x0080)
+#define I2C_IC_COMP_PARAM_1_RX_BUFFER_DEPTH         ((uint32_t)0x0000FF00)
+#define I2C_IC_COMP_PARAM_1_TX_BUFFER_DEPTH         ((uint32_t)0x00FF0000)
+
+/*******************  Bit definition for IC_COMP_VERSION  register  ***********/
+#define I2C_IC_COMP_VERSION                         ((uint32_t)0xFFFFFFFF)
+
+/*******************  Bit definition for IC_COMP_TYPE  register  **************/
+#define I2C_IC_COMP_TYPE                            ((uint32_t)0xFFFFFFFF)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                      Backup Register Unit Block                            */
+/*                                                                            */
+/******************************************************************************/
+/*******************  Bit definition for BPK_RDY register  ********************/
+#define BPK_RDY_POR                                 ((uint32_t)0x0002) 
+#define BPK_RDY_READY                               ((uint32_t)0x0001) 
+
+/*******************  Bit definition for BPK_RR register  *********************/
+#define BPK_RR_RESET                                ((uint32_t)0x0001) 
+
+/*******************  Bit definition for BPK_LR register  *********************/
+#define BPK_LR_LOCK_SELF                            ((uint32_t)0x0001) 
+#define BPK_LR_LOCK_RESET                           ((uint32_t)0x0002) 
+#define BPK_LR_LOCK_KEYWRITE                        ((uint32_t)0x0004) 
+#define BPK_LR_LOCK_KEYREAD                         ((uint32_t)0x0008) 
+#define BPK_LR_LOCK_KEYCLEAR                        ((uint32_t)0x0010)    
+#define BPK_LR_LOCK_SCRAMBER				  		((uint32_t)0x0020)
+#define BPK_LR_LOCK_ALL				                ((uint32_t)0x003F)
+
+/******************************************************************************/
+/*                                                                            */
+/*                               RTC Unit Block                               */
+/*                                                                            */
+/******************************************************************************/
+/*******************  Bit definition for RTC_CS register  *********************/
+#define RTC_CS_ALARM_IT                            ((uint32_t)0x01)
+#define RTC_CS_LOCK_TIM                            ((uint32_t)0x02)
+#define RTC_CS_ALARM_EN                            ((uint32_t)0x04)
+#define RTC_CS_READY                               ((uint32_t)0x08)
+#define RTC_CS_CLR                                 ((uint32_t)0x10)
+
+/******************************************************************************/
+/*                                                                            */
+/*                      Keyboard Control Unit Block                           */
+/*                                                                            */
+/******************************************************************************/
+/*****************  Bit definition for KCU_CTRL0 register  ********************/
+#define KCU_PORT_0                                  ((uint32_t)0x0001)
+#define KCU_PORT_1                                  ((uint32_t)0x0002)
+#define KCU_PORT_2                                  ((uint32_t)0x0004)
+#define KCU_PORT_3                                  ((uint32_t)0x0008)
+#define KCU_PORT_4                                  ((uint32_t)0x0010)
+#define KCU_PORT_5                                  ((uint32_t)0x0020)
+#define KCU_PORT_6                                  ((uint32_t)0x0040)
+#define KCU_PORT_7                                  ((uint32_t)0x0080)
+#define KCU_PORT_8                                  ((uint32_t)0x0100)
+#define KCU_PORT_ALL_Mask                           ((uint32_t)0x001F)
+
+#define KCU_DEBOUNCETIMELEVEL_0                     ((uint32_t)0x0000)
+#define KCU_DEBOUNCETIMELEVEL_1                     ((uint32_t)0x0001)
+#define KCU_DEBOUNCETIMELEVEL_2                     ((uint32_t)0x0002)
+#define KCU_DEBOUNCETIMELEVEL_3                     ((uint32_t)0x0003)
+#define KCU_DEBOUNCETIMELEVEL_4                     ((uint32_t)0x0004)
+#define KCU_DEBOUNCETIMELEVEL_5                     ((uint32_t)0x0005)
+#define KCU_DEBOUNCETIMELEVEL_6                     ((uint32_t)0x0006)
+#define KCU_DEBOUNCETIMELEVEL_7                     ((uint32_t)0x0007)
+#define KCU_DEBOUNCETIMELEVEL_POS                   (9)
+
+/*****************  Bit definition for KCU_CTRL1 register  ********************/
+#define KCU_CTRL1_KBD_EN                            ((uint32_t)0x0001)
+#define KCU_CTRL1_PUSH_IT                           ((uint32_t)0x0002)
+#define KCU_CTRL1_RELEASE_IT                        ((uint32_t)0x0004)
+#define KCU_CTRL1_OVERRUN_IT                        ((uint32_t)0x0008)
+#define KCU_CTRL1_KCU_RUNING                        ((uint32_t)0x80000000)
+
+/*****************  Bit definition for KCU_STATUS register  *******************/
+#define KCU_STATUS_IT                               ((uint32_t)0x0001)
+#define KCU_STATUS_OVERRUN_IT                       ((uint32_t)0x0002)
+#define KCU_STATUS_PUSH_IT                          ((uint32_t)0x0004)
+#define KCU_STATUS_RELEASE_IT                       ((uint32_t)0x0008)
+#define KCU_STATUS_EVENT_0_PUSH                     ((uint32_t)0x0010)
+#define KCU_STATUS_EVENT_0_NEW                      ((uint32_t)0x0020)
+#define KCU_STATUS_EVENT_1_PUSH                     ((uint32_t)0x0040)
+#define KCU_STATUS_EVENT_1_NEW                      ((uint32_t)0x0080)
+#define KCU_STATUS_EVENT_2_PUSH                     ((uint32_t)0x0100)
+#define KCU_STATUS_EVENT_2_NEW                      ((uint32_t)0x0200)
+#define KCU_STATUS_EVENT_3_PUSH                     ((uint32_t)0x0400)
+#define KCU_STATUS_EVENT_3_NEW                      ((uint32_t)0x0800)
+
+/*****************  Bit definition for KCU_EVENT register  ********************/
+#define KCU_EVENT_EVENT_0_INPUT_NUM                 ((uint32_t)0x0000000F)
+#define KCU_EVENT_EVENT_0_OUTPUT_NUM                ((uint32_t)0x000000F0)
+#define KCU_EVENT_EVENT_1_INPUT_NUM                 ((uint32_t)0x00000F00)
+#define KCU_EVENT_EVENT_1_OUTPUT_NUM                ((uint32_t)0x0000F000)
+#define KCU_EVENT_EVENT_2_INPUT_NUM                 ((uint32_t)0x000F0000)
+#define KCU_EVENT_EVENT_2_OUTPUT_NUM                ((uint32_t)0x00F00000)
+#define KCU_EVENT_EVENT_3_INPUT_NUM                 ((uint32_t)0x0F000000)
+#define KCU_EVENT_EVENT_3_OUTPUT_NUM                ((uint32_t)0xF0000000)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                      Timer Control Unit Block                              */
+/*                                                                            */
+/******************************************************************************/
+/**********  Bit definition for TIMER_CONTROL_REG register  *******************/
+#define TIMER_CONTROL_REG_TIMER_ENABLE              (0x0001U)
+#define TIMER_CONTROL_REG_TIMER_MODE                (0x0002U) 
+#define TIMER_CONTROL_REG_TIMER_INTERRUPT           (0x0004U)
+#define TIMER_CONTROL_REG_TIMER_PWM                 (0x0008U)
+#define TIMER_CONTROL_REG_PWM_SINGLE_PULSE          (0x0010U)
+#define TIMER_CONTROL_REG_PWM_RELOAD_SINGLE_PULSE   (0x0020U)
+
+/*****************  Bit definition for IntStatus register  ********************/
+#define TIMER_INT_STATUS_INTERRUPT                  (0x0001U)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                          WDT Control Unit Block                            */
+/*                                                                            */
+/******************************************************************************/
+/*****************  Bit definition for WDT_CR register  ***********************/
+#define WDT_CR_WDT_EN                               ((uint32_t)0x0001)
+#define WDT_CR_RMOD                                 ((uint32_t)0x0002)
+/*****************  Bit definition for WDT_CCVR register  *********************/
+#define WDT_CCVR_CCVR                               ((uint32_t)0xFFFFFFFF)
+/*****************  Bit definition for WDT_CRR register  **********************/
+#define WDT_CRR_CRR                                 ((uint32_t)0x00FF)
+/*****************  Bit definition for WDT_STAT register  *********************/
+#define WDT_STAT_INT                                ((uint32_t)0x0001)
+/*****************  Bit definition for WDT_EOI register  **********************/
+#define WDT_EOI_EOI                                 ((uint32_t)0x0001)
+/*****************  Bit definition for WDT_RLD register  **********************/
+#define WDT_RLD_RLD                                 ((uint32_t)0xFFFFFFFF)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                          RNG Control Unit Block                            */
+/*                                                                            */
+/******************************************************************************/
+/************ bit definition for TRNG RNG_INDEX REGISTER ************/
+
+#define RNG_FIFO_INDEX_Mask                         BIT(31)
+/************ bit definition for TRNG RNG_CSR REGISTER ************/
+#define TRNG_RNG_CSR_INTP_EN_Mask                   ((uint32_t)0x0010)
+#define TRNG_RNG_CSR_ATTACK_TRNG0_Mask              ((uint32_t)0x0004)
+#define TRNG_RNG_CSR_S128_TRNG0_Mask                ((uint32_t)0x0001)
+
+/************ bit definition for TRNG RNG_AMA REGISTER ************/
+#define TRNG_RNG_AMA_ANA_OUT_TRNG0_Mask             ((uint32_t)0x10000000)
+#define TRNG_RNG_AMA_PD_TRNG0_Mask                  ((uint32_t)0x00001000)
+#define TRNG_RNG_AMA_PD_TRNG1_Mask                  ((uint32_t)0x00002000)
+#define TRNG_RNG_AMA_PD_TRNG2_Mask                  ((uint32_t)0x00004000)
+#define TRNG_RNG_AMA_PD_TRNG3_Mask                  ((uint32_t)0x00008000)
+#define TRNG_RNG_AMA_PD_ALL_Mask                    ((uint32_t)0x0000F000)
+
+
+/******************************************************************************/
+/*                                                                            */
+/*                                    DCMI                                    */
+/*                                                                            */
+/******************************************************************************/
+/**************  Bit definition for DCMI SYSCTRL DBG_CR register  *************/
+#define DCMI_DBG_CR_INPUTSEL                        ((uint32_t)0x00002000)
+
+/********************  Bits definition for DCMI_CR register  ******************/
+#define DCMI_CR_CAPTURE                             ((uint32_t)0x00000001)
+#define DCMI_CR_CM                                  ((uint32_t)0x00000002)
+#define DCMI_CR_CROP                                ((uint32_t)0x00000004)
+#define DCMI_CR_JPEG                                ((uint32_t)0x00000008)
+#define DCMI_CR_ESS                                 ((uint32_t)0x00000010)
+#define DCMI_CR_PCKPOL                              ((uint32_t)0x00000020)
+#define DCMI_CR_HSPOL                               ((uint32_t)0x00000040)
+#define DCMI_CR_VSPOL                               ((uint32_t)0x00000080)
+#define DCMI_CR_FCRC_0                              ((uint32_t)0x00000100)
+#define DCMI_CR_FCRC_1                              ((uint32_t)0x00000200)
+#define DCMI_CR_EDM_0                               ((uint32_t)0x00000400)
+#define DCMI_CR_EDM_1                               ((uint32_t)0x00000800)
+#define DCMI_CR_CRE                                 ((uint32_t)0x00001000)
+#define DCMI_CR_ENABLE                              ((uint32_t)0x00004000)
+#define DCMI_CR_BSM_0                               ((uint32_t)0x00010000)
+#define DCMI_CR_BSM_1                               ((uint32_t)0x00020000)
+#define DCMI_CR_OEBS                                ((uint32_t)0x00040000)
+#define DCMI_CR_LSM	                                ((uint32_t)0x00080000)
+#define DCMI_CR_OELS                                ((uint32_t)0x00100000)
+#define DCMI_CR_DMAS                                ((uint32_t)0xE0000000)
+
+/********************  Bits definition for DCMI_SR register  ******************/
+#define DCMI_SR_HSYNC                               ((uint32_t)0x00000001)
+#define DCMI_SR_VSYNC                               ((uint32_t)0x00000002)
+#define DCMI_SR_FNE                                 ((uint32_t)0x00000004)
+
+/********************  Bits definition for DCMI_RISR register  ****************/
+#define DCMI_RISR_FRAME_RIS                         ((uint32_t)0x00000001)
+#define DCMI_RISR_OVF_RIS                           ((uint32_t)0x00000002)
+#define DCMI_RISR_ERR_RIS                           ((uint32_t)0x00000004)
+#define DCMI_RISR_VSYNC_RIS                         ((uint32_t)0x00000008)
+#define DCMI_RISR_LINE_RIS                          ((uint32_t)0x00000010)
+
+/********************  Bits definition for DCMI_IER register  *****************/
+#define DCMI_IER_FRAME_IE                           ((uint32_t)0x00000001)
+#define DCMI_IER_OVF_IE                             ((uint32_t)0x00000002)
+#define DCMI_IER_ERR_IE                             ((uint32_t)0x00000004)
+#define DCMI_IER_VSYNC_IE                           ((uint32_t)0x00000008)
+#define DCMI_IER_LINE_IE                            ((uint32_t)0x00000010)
+
+/********************  Bits definition for DCMI_MISR register  ****************/
+#define DCMI_MISR_FRAME_MIS                         ((uint32_t)0x00000001)
+#define DCMI_MISR_OVF_MIS                           ((uint32_t)0x00000002)
+#define DCMI_MISR_ERR_MIS                           ((uint32_t)0x00000004)
+#define DCMI_MISR_VSYNC_MIS                         ((uint32_t)0x00000008)
+#define DCMI_MISR_LINE_MIS                          ((uint32_t)0x00000010)
+
+/********************  Bits definition for DCMI_ICR register  *****************/
+#define DCMI_ICR_FRAME_ISC                          ((uint32_t)0x00000001)
+#define DCMI_ICR_OVF_ISC                            ((uint32_t)0x00000002)
+#define DCMI_ICR_ERR_ISC                            ((uint32_t)0x00000004)
+#define DCMI_ICR_VSYNC_ISC                          ((uint32_t)0x00000008)
+#define DCMI_ICR_LINE_ISC                           ((uint32_t)0x00000010)
+
+
+/******************  Bit definition for QUADSPI_FCU_CMD register  ******************/
+#define QUADSPI_FCU_CMD_CODE                            ((uint32_t)0xFF000000U)
+#define QUADSPI_FCU_CMD_BUS_MODE                        ((uint32_t)0x00000300U)
+#define QUADSPI_FCU_CMD_CMD_FORMAT                      ((uint32_t)0x000000F0U)
+#define QUADSPI_FCU_CMD_DONE                            ((uint32_t)0x00000008U)
+#define QUADSPI_FCU_CMD_BUSY                            ((uint32_t)0x00000004U)
+#define QUADSPI_FCU_CMD_ACCESS_ACK                      ((uint32_t)0x00000002U)
+#define QUADSPI_FCU_CMD_ACCESS_REQ                      ((uint32_t)0x00000001U)
+
+#define QUADSPI_ADDRESS_ADR                             ((uint32_t)0xFFFFFF00U)
+#define QUADSPI_ADDRESS_M8                              ((uint32_t)0x000000FFU) 
+
+#define QUADSPI_BYTE_NUM_WR_BYTE                        ((uint32_t)0x00001FFFU) 
+#define QUADSPI_BYTE_NUM_RD_BYTE                        ((uint32_t)0x1FFF0000U) 
+
+#define QUADSPI_WR_FIFO_WR_DATA                         ((uint32_t)0xFFFFFFFFU) 
+#define QUADSPI_RD_FIFO_RD_DATA                         ((uint32_t)0xFFFFFFFFU) 
+
+#define QUADSPI_DEVICE_PARA_SAMPLE_DLY                  ((uint32_t)0x00008000U)
+#define QUADSPI_DEVICE_PARA_SAMPLE_PHA                  ((uint32_t)0x00004000U)
+#define QUADSPI_DEVICE_PARA_PROTOCOL                    ((uint32_t)0x00000300U)
+#define QUADSPI_DEVICE_PARA_DUMMY_CYCLE                 ((uint32_t)0x000000F0U)
+#define QUADSPI_DEVICE_PARA_FLASH_READY                 ((uint32_t)0x00000008U)
+#define QUADSPI_DEVICE_PARA_FREQ_SEL                    ((uint32_t)0x00000003U)
+
+#define QUADSPI_REG_WDATA                               ((uint32_t)0xFFFFFFFFU)
+#define QUADSPI_REG_RDATA                               ((uint32_t)0xFFFFFFFFU)
+
+#define QUADSPI_INT_MASK_TFDM                           ((uint32_t)0x00000040U)
+#define QUADSPI_INT_MASK_RFDM                           ((uint32_t)0x00000020U)
+#define QUADSPI_INT_MASK_TFOM                           ((uint32_t)0x00000010U)
+#define QUADSPI_INT_MASK_TFUM                           ((uint32_t)0x00000008U)
+#define QUADSPI_INT_MASK_RFOM                           ((uint32_t)0x00000004U)
+#define QUADSPI_INT_MASK_RFUM                           ((uint32_t)0x00000002U)
+#define QUADSPI_INT_MASK_DONE_IM                        ((uint32_t)0x00000001U)
+
+#define QUADSPI_INT_UMSAK_TFDU                          ((uint32_t)0x00000040U)
+#define QUADSPI_INT_UMSAK_RFDU                          ((uint32_t)0x00000020U)
+#define QUADSPI_INT_UMSAK_TFOU                          ((uint32_t)0x00000010U)
+#define QUADSPI_INT_UMSAK_TFUU                          ((uint32_t)0x00000008U)
+#define QUADSPI_INT_UMSAK_RFOU                          ((uint32_t)0x00000004U)
+#define QUADSPI_INT_UMSAK_RFUU                          ((uint32_t)0x00000002U)
+#define QUADSPI_INT_UMSAK_DONE_IU                       ((uint32_t)0x00000001U)
+
+#define QUADSPI_INT_MASK_STATUS_TFDM                    ((uint32_t)0x00000040U)
+#define QUADSPI_INT_MASK_STATUS_RFDM                    ((uint32_t)0x00000020U)
+#define QUADSPI_INT_MASK_STATUS_TFOM                    ((uint32_t)0x00000010U)
+#define QUADSPI_INT_MASK_STATUS_TFUM                    ((uint32_t)0x00000008U)
+#define QUADSPI_INT_MASK_STATUS_RFOM                    ((uint32_t)0x00000004U)
+#define QUADSPI_INT_MASK_STATUS_RFUM                    ((uint32_t)0x00000002U)
+#define QUADSPI_INT_MASK_STATUS_DONE_IM                 ((uint32_t)0x00000001U)
+
+#define QUADSPI_INT_STATUS_TFDS                         ((uint32_t)0x00000040U)
+#define QUADSPI_INT_STATUS_RFDS                         ((uint32_t)0x00000020U)
+#define QUADSPI_INT_STATUS_TFOS                         ((uint32_t)0x00000010U)
+#define QUADSPI_INT_STATUS_TFUS                         ((uint32_t)0x00000008U)
+#define QUADSPI_INT_STATUS_RFOS                         ((uint32_t)0x00000004U)
+#define QUADSPI_INT_STATUS_RFUS                         ((uint32_t)0x00000002U)
+#define QUADSPI_INT_STATUS_DONE_IS                      ((uint32_t)0x00000001U)
+
+#define QUADSPI_INT_RAWSTATUS_TFDR                      ((uint32_t)0x00000040U)
+#define QUADSPI_INT_RAWSTATUS_RFDR                      ((uint32_t)0x00000020U)
+#define QUADSPI_INT_RAWSTATUS_TFOR                      ((uint32_t)0x00000010U)
+#define QUADSPI_INT_RAWSTATUS_TFUR                      ((uint32_t)0x00000008U)
+#define QUADSPI_INT_RAWSTATUS_RFOR                      ((uint32_t)0x00000004U)
+#define QUADSPI_INT_RAWSTATUS_RFUR                      ((uint32_t)0x00000002U)
+#define QUADSPI_INT_RAWSTATUS_DONE_IR                   ((uint32_t)0x00000001U)
+
+#define QUADSPI_INT_CLEAR_CTFD                          ((uint32_t)0x00000040U)
+#define QUADSPI_INT_CLEAR_CRFD                          ((uint32_t)0x00000020U)
+#define QUADSPI_INT_CLEAR_CTFO                          ((uint32_t)0x00000010U)
+#define QUADSPI_INT_CLEAR_CTFU                          ((uint32_t)0x00000008U)
+#define QUADSPI_INT_CLEAR_CRFO                          ((uint32_t)0x00000004U)
+#define QUADSPI_INT_CLEAR_CRFU                          ((uint32_t)0x00000002U)
+#define QUADSPI_INT_CLEAR_DONE                          ((uint32_t)0x00000001U)
+
+#define QUADSPI_CACHE_INTF_CMD_RELDS                    ((uint32_t)0xFF000000U)
+#define QUADSPI_CACHE_INTF_CMD_DS                       ((uint32_t)0x00FF0000U)
+#define QUADSPI_CACHE_INTF_CMD_RD_BUS_MODE              ((uint32_t)0x00003000U)
+#define QUADSPI_CACHE_INTF_CMD_RD_FORMAT                ((uint32_t)0x00000F00U)
+#define QUADSPI_CACHE_INTF_CMD_RDCMD                    ((uint32_t)0x000000FFU)
+
+#define QUADSPI_DMA_CNTL_TX_EN                          ((uint32_t)0x00000001U)
+
+#define QUADSPI_FIFO_CNTL_TFFH                          ((uint32_t)0x80000000U)
+#define QUADSPI_FIFO_CNTL_TFE                           ((uint32_t)0x00200000U)
+#define QUADSPI_FIFO_CNTL_TFFL                          ((uint32_t)0x00100000U)
+#define QUADSPI_FIFO_CNTL_TFL                           ((uint32_t)0x000F0000U)
+#define QUADSPI_FIFO_CNTL_RFFH                          ((uint32_t)0x00008000U)
+#define QUADSPI_FIFO_CNTL_RFE                           ((uint32_t)0x00000020U)
+#define QUADSPI_FIFO_CNTL_RFFL                          ((uint32_t)0x00000010U)
+#define QUADSPI_FIFO_CNTL_RFL                           ((uint32_t)0x0000000FU)
+
+
+#define AIR105_READ_REG8(reg)                       (*(__IO uint8_t *) reg)
+#define AIR105_READ_REG16(reg)                      (*(__IO uint16_t *) reg)
+#define AIR105_READ_REG32(reg)                      (*(__IO uint32_t *) reg)
+#define AIR105_WRITE_REG8(reg, value)               (*(__IO uint8_t *) reg = value)
+#define AIR105_WRITE_REG16(reg, value)              (*(__IO uint16_t *) reg = value)
+#define AIR105_WRITE_REG32(reg, value)              (*(__IO uint32_t *) reg = value)
+#define AIR105_MODIFY_REG8(reg, clear_mask, set_mask)   \
+        AIR105_WRITE_REG8(reg, (((AIR105_READ_REG8(reg)) & ~clear_mask) | set_mask))
+#define AIR105_MODIFY_REG16(reg, clear_mask, set_mask)   \
+        AIR105_WRITE_REG16(reg, (((AIR105_READ_REG16(reg)) & ~clear_mask) | set_mask))
+#define AIR105_MODIFY_REG32(reg, clear_mask, set_mask)   \
+        AIR105_WRITE_REG32(reg, (((AIR105_READ_REG32(reg)) & ~clear_mask) | set_mask))
+
+
+#include "air105_conf.h"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* AIR105_H */

+ 147 - 0
bsp/air105/chip/include/air105_adc.h

@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __AIR105_ADC_H__
+#define __AIR105_ADC_H__
+ 
+ 
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+/* Include ------------------------------------------------------------------*/
+#include "air105.h"	
+    
+#define IS_ADC_PERIPH(PERIPH) ((PERIPH) == ADC0)
+
+#define ADC_CR1_CHANNEL_MASK           ((uint32_t)0x07)	
+#define ADC_CR1_SAMPLE_RATE_Pos         3 
+#define ADC_CR1_SAMPLE_RATE_MASK       (0x3 << ADC_CR1_SAMPLE_RATE_Pos)
+#define ADC_CR1_SAMP_ENABLE             BIT(6)
+#define ADC_CR1_POWER_DOWN              BIT(8)
+#define ADC_CR1_IRQ_ENABLE              BIT(5)
+	
+#define ADC_SR_DONE_FLAG                BIT(0)
+#define ADC_SR_FIFO_OV_FLAG             BIT(1)
+
+#define ADC_FIFO_OV_INT_ENABLE          BIT(2)
+#define ADC_FIFO_RESET                  BIT(1)
+	
+#define ADC_FIFO_ENABLE                 BIT(0)    
+
+#define ADC_CR2_BUFF_ENABLE             BIT(14)    
+#define ADC_DIV_RESISTOR_EN_BIT         BIT(13) 
+
+    
+typedef enum
+{
+    ADC_Overflow = 0,
+    ADC_NoOverflow = 1,
+}ADC_OverflowTypeDef;
+
+/* ADC Channel select */  
+typedef enum
+{
+    ADC_CHANNEL_CHARGE_VBAT =0,
+    ADC_CHANNEL_1,
+    ADC_CHANNEL_2,
+    ADC_CHANNEL_3,
+    ADC_CHANNEL_4,
+    ADC_CHANNEL_5,
+    ADC_CHANNEL_6,
+}ADC_ChxTypeDef;
+#define IS_ADC_CHANNEL(CHANNEL_NUM) (((CHANNEL_NUM) == ADC_CHANNEL_CHARGE_VBAT) || \
+                                     ((CHANNEL_NUM) == ADC_CHANNEL_1) || \
+                                     ((CHANNEL_NUM) == ADC_CHANNEL_2) || \
+                                     ((CHANNEL_NUM) == ADC_CHANNEL_3) || \
+                                     ((CHANNEL_NUM) == ADC_CHANNEL_4) || \
+                                     ((CHANNEL_NUM) == ADC_CHANNEL_5) || \
+                                     ((CHANNEL_NUM) == ADC_CHANNEL_6))
+                                    
+/* ADC Samp Select */
+typedef enum
+{
+    ADC_SpeedPrescaler_None = 0,
+    ADC_SpeedPrescaler_2,
+    ADC_SpeedPrescaler_4,
+    ADC_SpeedPrescaler_8,
+}ADC_SampTypeDef;
+
+#define IS_ADC_SAMP(SAMP)           (((SAMP) == ADC_SpeedPrescaler_None)  || \
+                                     ((SAMP) == ADC_SpeedPrescaler_2) || \
+                                     ((SAMP) == ADC_SpeedPrescaler_4) || \
+                                     ((SAMP) == ADC_SpeedPrescaler_8))
+                                     
+
+typedef struct _ADC_InitTypeDef
+{
+    ADC_ChxTypeDef              ADC_Channel;            /* ADC Channel select */
+    ADC_SampTypeDef             ADC_SampSpeed;          /* ADC sampspeed select */
+    FunctionalState             ADC_IRQ_EN;             /* ADC IRQ/Polling Select */
+    FunctionalState             ADC_FIFO_EN;            /* ADC FIFO Enable Select */
+} ADC_InitTypeDef;  
+
+/* Exported constants -------------------------------------------------------*/	
+/* Exported macro -----------------------------------------------------------*/	
+/* Exported functions -------------------------------------------------------*/	
+void ADC_Init(ADC_InitTypeDef *ADC_InitStruct);
+
+void ADC_StartCmd(FunctionalState NewState);
+
+void ADC_FIFODeepth(uint32_t FIFO_Deepth);
+
+void ADC_FIFOReset(void);
+
+void ADC_ITCmd(FunctionalState NewState);
+
+void ADC_FIFOOverflowITcmd(FunctionalState NewState);
+
+void ADC_BuffCmd(FunctionalState NewState);
+
+void ADC_DivResistorCmd(FunctionalState NewState);
+
+int32_t ADC_GetFIFOCount(void);
+
+int32_t ADC_GetResult(void);
+
+int32_t ADC_GetFIFOResult(uint16_t *ADCdata, uint32_t len);
+
+uint32_t ADC_CalVoltage(uint32_t u32ADC_Value, uint32_t u32ADC_Ref_Value);
+
+ADC_ChxTypeDef ADC_GetChannel(void);
+
+FunctionalState ADC_IsDivResistorEnable(void);
+
+ADC_OverflowTypeDef ADC_IsFIFOOverflow(void);
+
+void ADC_ChannelSwitch(ADC_ChxTypeDef Channelx);
+
+/* Exported variables -------------------------------------------------------*/
+    
+/* Exported types -----------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif	 
+
+#endif	/* __AIR105_ADC_H__ */
+

+ 66 - 0
bsp/air105/chip/include/air105_bpk.h

@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __AIR105_BPK_H
+#define __AIR105_BPK_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "air105.h"
+
+	 
+/** @defgroup BPK_Exported_Types
+  * @{
+  */
+	 
+#define BPK_KEY_REGION_0                      ((uint32_t)0x0001)
+#define BPK_KEY_REGION_1                      ((uint32_t)0x0002)
+#define BPK_KEY_REGION_ALL                    ((uint32_t)0x0003)
+#define IS_BPK_KEY_REGION(REGION)			  ((((REGION) & ~BPK_KEY_REGION_ALL) == 0x00) && ((REGION) != 0x00))
+	 
+
+#define IS_BPK_LOCK(LOCK)					  ((((LOCK) & ~BPK_LR_LOCK_ALL) == 0x00) && ((LOCK) != (uint32_t)0x00))
+
+
+FlagStatus BPK_IsReady(void);
+ErrorStatus BPK_WriteKey(uint32_t *Key,uint32_t Key_Len, uint32_t Key_Offset);
+ErrorStatus BPK_ReadKey(uint32_t *Key,uint32_t Key_Len, uint32_t Key_Offset);
+void BPK_KeyWriteLock(uint16_t BPK_KEY_Region, FunctionalState NewState);
+void BPK_KeyReadLock(uint16_t BPK_KEY_Region, FunctionalState NewState);
+void BPK_KeyClear(uint16_t BPK_KEY_Region);
+
+void BPK_SetScramber(uint32_t Scram);
+void BPK_Lock(uint32_t BPK_LOCK, FunctionalState NewState);
+void BPK_LockSelf(void);
+FlagStatus BPK_GetLockStatus(uint32_t BPK_LOCK);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
+
+/**************************      (C) COPYRIGHT Megahunt    *****END OF FILE****/

+ 114 - 0
bsp/air105/chip/include/air105_cache.h

@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef __AIR105_CACHE_H
+#define __AIR105_CACHE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "air105.h"
+
+	
+#define CACHE_REFRESH		                  ((uint32_t)0x80000000)
+#define CACHE_REFRESH_ALLTAG	              ((uint32_t)0x40000000)
+
+#define CACHE_KEY_GEN_START		              ((uint32_t)0x80000000)	
+
+#define CACHE_IS_BUSY			              ((uint32_t)0x20000000)
+	
+#define CACHE_SIZE                            ((uint32_t)0x8000)
+#define CACHE_PARTICLE_SIZE                   (0x20)
+#define CACHE_ADDRESS_START                   ((uint32_t)0x01000000)	
+#define CACHE_ADDRESS_MAX                     ((uint32_t)0x00FFFFFF)
+#define IS_CACHE_ADDR_VALID(addr)             (((addr) & CACHE_ADDRESS_START) == CACHE_ADDRESS_START)
+		
+#define CACHE_AES_BYPASS		              (0xA5)
+#define CACHE_KEY_GEN			              (0xA5)
+#define CACHE_WRAP_ENABLE				 	  (0xA5)
+
+#define CACHE_ZONE_ENCRYPT			          ((uint32_t)0xA5000000)
+	
+#define CACHE_CODE_BUS_OFFSET_POS               (0)
+#define CACHE_CODE_BUS_OFFSET_WIDTH             (5)
+#define CACHE_CODE_BUS_OFFSET_MASK              ((uint32_t)0x001F)
+
+#define CACHE_CODE_BUS_SET_POS                  (5)
+#define CACHE_CODE_BUS_SET_WIDTH                (8)
+#define CACHE_CODE_BUS_SET_MASK                 ((uint32_t)0x00FF)
+
+#define CACHE_CODE_BUS_TAG_POS                  (13)
+#define CACHE_CODE_BUS_TAG_WIDTH                (11)
+#define CACHE_CODE_BUS_TAG_MASK                 ((uint32_t)0x07FF)
+
+#define CHCHE_ALGORITHM_SET_POS					(28)
+
+#define CACHE_BUILD_INDEX_OFFSET(x)				(((x) & CACHE_CODE_BUS_OFFSET_MASK) << CACHE_CODE_BUS_OFFSET_POS)
+#define CACHE_BUILD_INDEX_SET(x)				(((x) & CACHE_CODE_BUS_SET_MASK) << CACHE_CODE_BUS_SET_POS)
+#define CACHE_BUILD_INDEX_TAG(x)				(((x) & CACHE_CODE_BUS_TAG_MASK) << CACHE_CODE_BUS_TAG_POS)
+#define CACHE_ADDRESS_BUILD(base,index_set,tag_way,offset)   ((base) | CACHE_BUILD_INDEX_SET(index_set) | CACHE_BUILD_INDEX_TAG(tag_way) | CACHE_BUILD_INDEX_OFFSET(offset))
+
+#define CACHE_TAG_NUM(x)						((x >> CACHE_CODE_BUS_TAG_POS) & CACHE_CODE_BUS_TAG_MASK)
+#define CACHE_SET_NUM(x)						((x >> CACHE_CODE_BUS_SET_POS) & CACHE_CODE_BUS_SET_MASK)
+#define CACHE_OFF_NUM(x)						((x >> CACHE_CODE_BUS_OFFSET_POS) & CACHE_CODE_BUS_OFFSET_MASK)
+
+typedef enum
+{
+	CACHE_Encrypt_Mode_All = 0x0,
+	CACHE_Encrypt_Mode_Zone,
+}CACHE_EncryptModeTypeDef;
+#define IS_CACHE_ENCRYPT_MODE(MODE)		(((MODE) == CACHE_Encrypt_Mode_All) || \
+										((MODE) == CACHE_Encrypt_Mode_Zone))
+
+typedef struct                        
+{      
+	uint32_t I[4];
+	uint32_t K[4];   
+	uint32_t AES_CS;
+	uint32_t CONFIG;
+
+	uint32_t aes_enable;
+	uint32_t Address;                 
+	uint32_t size;
+	uint32_t algorithm;
+	
+	uint32_t encrypt_mode; 
+	uint32_t encrypt_saddr; 
+	uint32_t encrypt_eaddr; 	
+}CACHE_InitTypeDef;
+
+void CACHE_Init(CACHE_TypeDef *Cache, CACHE_InitTypeDef *CACHE_InitStruct);
+void CACHE_Clean(CACHE_TypeDef *Cache, CACHE_InitTypeDef *CACHE_InitStruct);
+void CACHE_CleanAll(CACHE_TypeDef *Cache);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
+
+
+/**************************      (C) COPYRIGHT Megahunt    *****END OF FILE****/

+ 51 - 0
bsp/air105/chip/include/air105_conf.h

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AIR105_CONF_H
+#define __AIR105_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Uncomment the line below to enable peripheral header file inclusion */
+#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
+
+#include "string.h"
+
+#include "air105_cache.h"
+#include "air105_dcmi.h"
+#include "air105_dma.h"
+#include "air105_gpio.h"
+#include "air105_i2c.h"
+#include "air105_qspi.h"
+#include "air105_sysctrl.h"
+#include "air105_timer.h"
+#include "air105_uart.h"
+#include "air105_wdt.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Uncomment the line below to expanse the "assert_param" macro in the 
+   Standard Peripheral Library drivers code */
+/* #define USE_FULL_ASSERT    1 */
+
+
+#endif 
+

+ 74 - 0
bsp/air105/chip/include/air105_crc.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __AIR105_CRC_H
+#define __AIR105_CRC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "air105.h"
+
+/* Exported types ------------------------------------------------------------*/
+typedef enum
+{
+	CRC_16 = 0x01,
+	CRC_16_Modbus = 0x02,
+	CRC_CCITT_0xffff = 0x03,
+	CRC_CCITT_XModem = 0x04,
+	CRC_32 = 0x05
+}CRC_Param_TypeDef;
+	 
+typedef enum
+{
+	CRC_Poly_16_1021 = 0x01,
+	CRC_Poly_16_8005 = 0x02,
+	CRC_Poly_32_04C11DB7 = 0x03
+}CRC_Poly_TypeDef;
+
+typedef enum
+{
+	CRC_PolyMode_Normal = 0x01,
+	CRC_PolyMode_Reversed = 0x02,
+}CRC_PolyMode_TypeDef;
+
+typedef struct
+{
+	CRC_Poly_TypeDef CRC_Poly;
+	CRC_PolyMode_TypeDef CRC_PolyMode;
+	uint32_t CRC_Init_Value;
+	uint32_t CRC_Xor_Value;
+}CRC_ConfigTypeDef;
+
+ 
+uint32_t CRC_CalcBlockCRC(uint32_t CRC_type, uint8_t *pData, uint32_t len);
+uint32_t CRC_Calc(CRC_ConfigTypeDef *CRC_Config, uint8_t *pData, uint32_t len);
+	 
+	 
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 98 - 0
bsp/air105/chip/include/air105_dac.h

@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+ 
+#ifndef __AIR105_DAC_H__
+#define __AIR105_DAC_H__
+ 
+ 
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+/* Include ------------------------------------------------------------------*/
+#include "air105.h"	
+
+
+#define DAC_CR1_IS_RUNNING              ((uint32_t)0x20000000)	
+#define DAC_CR1_POWER_DOWN              ((uint32_t)0x00000010)		
+#define DAC_CR1_FIFO_RESET              ((uint32_t)0x00000008)	
+#define DAC_CR1_DMA_ENABLE              ((uint32_t)0x00000004)
+
+
+#define IS_DAC_DATA(DATA)               ((DATA) <= 0x3FF)	
+	
+
+#define DAC_CURR_SEL_MASK               ((uint32_t)0x00000020)		
+#define DAC_CURR_SEL_20K                ((uint32_t)0x00000000)	
+#define DAC_CURR_SEL_2K                 ((uint32_t)0x00000020)
+#define IS_DAC_CURR_SEL(CURR)           (((CURR) == DAC_CURR_SEL_20K) || \
+	                                     ((CURR) == DAC_CURR_SEL_2K))
+
+#define IS_DAC_FIFO_THR(THR)            ((THR) <= 0xF)
+
+
+typedef struct _DAC_InitTypeDef
+{
+    uint32_t DAC_CurrSel;            /* DAC mode select */
+    uint32_t DAC_TimerExp;           /* DAC timer expectation */
+    uint32_t DAC_FIFOThr;            /* DAC FIFO Threshold */
+} DAC_InitTypeDef;  
+
+
+#define DAC_FIFO_DEPTH		            (16)
+#define DAC_IT_STATUS_SHIFT             (30)
+
+#define DAC_IT_FIFO_THR                 ((uint32_t)0x0002)
+#define DAC_IT_FIFO_OVERFLOW            ((uint32_t)0x0001)
+#define IS_DAC_IT(IT)                   (((IT) == DAC_IT_FIFO_THR) || \
+                                         ((IT) == DAC_IT_FIFO_OVERFLOW))
+
+#define DAC_FLAG_RUNNING                (DAC_CR1_IS_RUNNING)
+#define DAC_FLAG_OVERFLOW               ((uint32_t)0x40000000)
+#define IS_DAC_FLAG(FLAG)               (((FLAG) == DAC_FLAG_RUNNING) || \
+                                         ((FLAG) == DAC_FLAG_OVERFLOW))
+
+
+/* Exported functions -------------------------------------------------------*/
+void DAC_Init(DAC_InitTypeDef *DAC_InitStruct);
+void DAC_StructInit(DAC_InitTypeDef *DAC_InitStruct);
+void DAC_FIFOReset(void);
+
+void DAC_Cmd(FunctionalState NewState);
+void DAC_DMACmd(FunctionalState NewState);
+
+void DAC_SetData(uint16_t Data);
+
+FlagStatus DAC_GetFlagStatus(uint32_t DAC_Flag);
+void DAC_ClearFlag(uint32_t DAC_Flag);
+
+void DAC_ITConfig(uint32_t DAC_IT, FunctionalState NewState);
+ITStatus DAC_GetITStatus(uint32_t DAC_IT);
+void DAC_ClearITPendingBit(uint32_t DAC_IT);
+
+
+#ifdef __cplusplus
+}
+#endif	 
+
+#endif	/* __AIR105_DAC_H__ */

+ 360 - 0
bsp/air105/chip/include/air105_dcmi.h

@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __AIR105_DCMI_H
+#define __AIR105_DCMI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "air105.h"
+
+
+/* Exported types ------------------------------------------------------------*/
+/** 
+  * @brief   DCMI Init structure definition  
+  */ 
+typedef struct
+{
+	uint16_t DCMI_CaptureMode;      /*!< Specifies the Capture Mode: Continuous or Snapshot.
+									   This parameter can be a value of @ref DCMI_Capture_Mode */
+
+	uint16_t DCMI_SynchroMode;      /*!< Specifies the Synchronization Mode: Hardware or Embedded.
+									   This parameter can be a value of @ref DCMI_Synchronization_Mode */
+
+	uint16_t DCMI_PCKPolarity;      /*!< Specifies the Pixel clock polarity: Falling or Rising.
+									   This parameter can be a value of @ref DCMI_PIXCK_Polarity */
+
+	uint16_t DCMI_VSPolarity;       /*!< Specifies the Vertical synchronization polarity: High or Low.
+									   This parameter can be a value of @ref DCMI_VSYNC_Polarity */
+
+	uint16_t DCMI_HSPolarity;       /*!< Specifies the Horizontal synchronization polarity: High or Low.
+									   This parameter can be a value of @ref DCMI_HSYNC_Polarity */
+
+	uint16_t DCMI_CaptureRate;      /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4.
+									   This parameter can be a value of @ref DCMI_Capture_Rate */
+
+	uint16_t DCMI_ExtendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit.
+									   This parameter can be a value of @ref DCMI_Extended_Data_Mode */
+	uint32_t DCMI_ByteSelectMode;   /*!< Specifies the Capture Select Byte Mode: Select All Bytes, 1 of 2, 1 of 4 or 2 of 4
+									   This parameter can be a value of @ref DCMI_ByteSelect_Mode */
+	uint32_t DCMI_LineSelectMode;   /*!< Specifies the Capture Select Line Mode: Select All Lines, Odd Line or Even Line
+									   This parameter can be a value of @ref DCMI_ByteLine_Mode */
+	uint32_t DCMI_ClockDiv;		/*!< Specifies the DCMI Slave Clock Div: 2~16 from HCLK
+									   This parameter can be a value of @ref DCMI_Clock_Div */
+} DCMI_InitTypeDef;
+
+/** 
+  * @brief   DCMI CROP Init structure definition  
+  */ 
+typedef struct
+{
+	uint16_t DCMI_VerticalStartLine;      /*!< Specifies the Vertical start line count from which the image capture
+											 will start. This parameter can be a value between 0x00 and 0x1FFF */
+
+	uint16_t DCMI_HorizontalOffsetCount;  /*!< Specifies the number of pixel clocks to count before starting a capture.
+											 This parameter can be a value between 0x00 and 0x3FFF */
+
+	uint16_t DCMI_VerticalLineCount;      /*!< Specifies the number of lines to be captured from the starting point.
+											 This parameter can be a value between 0x00 and 0x3FFF */
+
+	uint16_t DCMI_CaptureCount;           /*!< Specifies the number of pixel clocks to be captured from the starting
+											 point on the same line.
+											 This parameter can be a value between 0x00 and 0x3FFF */
+} DCMI_CROPInitTypeDef;
+
+/** 
+  * @brief   DCMI Embedded Synchronisation CODE Init structure definition  
+  */ 
+typedef struct
+{
+	uint8_t DCMI_FrameStartCode; /*!< Specifies the code of the frame start delimiter. */
+	uint8_t DCMI_LineStartCode;  /*!< Specifies the code of the line start delimiter. */
+	uint8_t DCMI_LineEndCode;    /*!< Specifies the code of the line end delimiter. */
+	uint8_t DCMI_FrameEndCode;   /*!< Specifies the code of the frame end delimiter. */
+} DCMI_CodesInitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DCMI_Exported_Constants
+  * @{
+  */
+
+/** @defgroup DCMI_Capture_Mode 
+  * @{
+  */ 
+#define DCMI_CaptureMode_Continuous    ((uint16_t)0x0000) /*!< The received data are transferred continuously 
+                                                               into the destination memory through the DMA */
+#define DCMI_CaptureMode_SnapShot      ((uint16_t)0x0002) /*!< Once activated, the interface waits for the start of 
+                                                               frame and then transfers a single frame through the DMA */
+#define IS_DCMI_CAPTURE_MODE(MODE)(((MODE) == DCMI_CaptureMode_Continuous) || \
+                                   ((MODE) == DCMI_CaptureMode_SnapShot))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_Synchronization_Mode
+  * @{
+  */ 
+#define DCMI_SynchroMode_Hardware    ((uint16_t)0x0000) /*!< Hardware synchronization data capture (frame/line start/stop)
+                                                             is synchronized with the HSYNC/VSYNC signals */
+#define DCMI_SynchroMode_Embedded    ((uint16_t)0x0010) /*!< Embedded synchronization data capture is synchronized with 
+                                                             synchronization codes embedded in the data flow */
+#define IS_DCMI_SYNCHRO(MODE)(((MODE) == DCMI_SynchroMode_Hardware) || \
+                              ((MODE) == DCMI_SynchroMode_Embedded))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_PIXCK_Polarity 
+  * @{
+  */ 
+#define DCMI_PCKPolarity_Falling    ((uint16_t)0x0000) /*!< Pixel clock active on Falling edge */
+#define DCMI_PCKPolarity_Rising     ((uint16_t)0x0020) /*!< Pixel clock active on Rising edge */
+#define IS_DCMI_PCKPOLARITY(POLARITY)(((POLARITY) == DCMI_PCKPolarity_Falling) || \
+                                      ((POLARITY) == DCMI_PCKPolarity_Rising))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_VSYNC_Polarity 
+  * @{
+  */ 
+#define DCMI_VSPolarity_Low     ((uint16_t)0x0000) /*!< Vertical synchronization active Low */
+#define DCMI_VSPolarity_High    ((uint16_t)0x0080) /*!< Vertical synchronization active High */
+#define IS_DCMI_VSPOLARITY(POLARITY)(((POLARITY) == DCMI_VSPolarity_Low) || \
+                                     ((POLARITY) == DCMI_VSPolarity_High))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_HSYNC_Polarity 
+  * @{
+  */ 
+#define DCMI_HSPolarity_Low     ((uint16_t)0x0000) /*!< Horizontal synchronization active Low */
+#define DCMI_HSPolarity_High    ((uint16_t)0x0040) /*!< Horizontal synchronization active High */
+#define IS_DCMI_HSPOLARITY(POLARITY)(((POLARITY) == DCMI_HSPolarity_Low) || \
+                                     ((POLARITY) == DCMI_HSPolarity_High))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_Capture_Rate 
+  * @{
+  */ 
+#define DCMI_CaptureRate_All_Frame     ((uint16_t)0x0000) /*!< All frames are captured */
+#define DCMI_CaptureRate_1of2_Frame    ((uint16_t)0x0100) /*!< Every alternate frame captured */
+#define DCMI_CaptureRate_1of4_Frame    ((uint16_t)0x0200) /*!< One frame in 4 frames captured */
+#define IS_DCMI_CAPTURE_RATE(RATE) (((RATE) == DCMI_CaptureRate_All_Frame) || \
+                                    ((RATE) == DCMI_CaptureRate_1of2_Frame) ||\
+                                    ((RATE) == DCMI_CaptureRate_1of4_Frame))
+
+/** @defgroup DCMI_Clock_Div 
+  * @{
+  */ 
+#define DCMI_Clock_Div2		((uint32_t)0x00000000)
+#define DCMI_Clock_Div4		((uint32_t)0x20000000)
+#define DCMI_Clock_Div6		((uint32_t)0x40000000)
+#define DCMI_Clock_Div8		((uint32_t)0x60000000)
+#define DCMI_Clock_Div10		((uint32_t)0x80000000)
+#define DCMI_Clock_Div12		((uint32_t)0xA0000000)
+#define DCMI_Clock_Div14		((uint32_t)0xC0000000)
+#define DCMI_Clock_Div16		((uint32_t)0xE0000000)
+#define IS_DCMI_CLOCK_DIV(DIV)	(((DIV) == DCMI_Clock_Div2) ||\
+								 ((DIV) == DCMI_Clock_Div4) ||\
+								 ((DIV) == DCMI_Clock_Div6) ||\
+								 ((DIV) == DCMI_Clock_Div8) ||\
+								 ((DIV) == DCMI_Clock_Div10) ||\
+								 ((DIV) == DCMI_Clock_Div12) ||\
+								 ((DIV) == DCMI_Clock_Div14) ||\
+								 ((DIV) == DCMI_Clock_Div16))
+#define DCMI_Clock_Div_MSK		((uint32_t)0xE0000000)
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_Extended_Data_Mode 
+  * @{
+  */ 
+#define DCMI_ExtendedDataMode_8b     ((uint16_t)0x0000) /*!< Interface captures 8-bit data on every pixel clock */
+#define DCMI_ExtendedDataMode_10b    ((uint16_t)0x0400) /*!< Interface captures 10-bit data on every pixel clock */
+#define DCMI_ExtendedDataMode_12b    ((uint16_t)0x0800) /*!< Interface captures 12-bit data on every pixel clock */
+#define DCMI_ExtendedDataMode_14b    ((uint16_t)0x0C00) /*!< Interface captures 14-bit data on every pixel clock */
+#define IS_DCMI_EXTENDED_DATA(DATA) (((DATA) == DCMI_ExtendedDataMode_8b) || \
+                                     ((DATA) == DCMI_ExtendedDataMode_10b) ||\
+                                     ((DATA) == DCMI_ExtendedDataMode_12b) ||\
+                                     ((DATA) == DCMI_ExtendedDataMode_14b))
+
+/** @defgroup DCMI_ByteSelectMode 
+  * @{
+  */ 
+#define DCMI_ByteSelect_Mode_AllByte 		((uint32_t)0x00000000)
+#define DCMI_ByteSelect_Mode_1of2_OddStart	((uint32_t)0x00010000)
+#define DCMI_ByteSelect_Mode_1of4_OddStart	((uint32_t)0x00020000)
+#define DCMI_ByteSelect_Mode_2of4_OddStart	((uint32_t)0x00030000)
+#define DCMI_ByteSelect_Mode_1of2_EvenStart	((uint32_t)0x00050000)
+#define DCMI_ByteSelect_Mode_1of4_EvenStart	((uint32_t)0x00060000)
+#define DCMI_ByteSelect_Mode_2of4_EvenStart	((uint32_t)0x00070000)
+#define IS_DCMI_BYTESELECT_MODE(MODE)	   (((MODE) == DCMI_ByteSelect_Mode_AllByte) ||\
+											((MODE) == DCMI_ByteSelect_Mode_1of2_OddStart) ||\
+											((MODE) == DCMI_ByteSelect_Mode_1of4_OddStart) ||\
+											((MODE) == DCMI_ByteSelect_Mode_2of4_OddStart) ||\
+											((MODE) == DCMI_ByteSelect_Mode_1of2_EvenStart) ||\
+											((MODE) == DCMI_ByteSelect_Mode_1of4_EvenStart) ||\
+											((MODE) == DCMI_ByteSelect_Mode_2of4_EvenStart))
+
+/** @defgroup DCMI_ByteSelectMode 
+  * @{
+  */ 
+#define DCMI_LineSelect_Mode_AllLine		((uint32_t)0x00000000)
+#define DCMI_LineSelect_Mode_OddLine		((uint32_t)0x00080000)
+#define DCMI_LineSelect_Mode_EvenLine	    ((uint32_t)0x00180000)
+#define IS_DCMI_LINESELECT_MODE(MODE)	   (((MODE) == DCMI_LineSelect_Mode_AllLine) ||\
+											((MODE) == DCMI_LineSelect_Mode_OddLine) ||\
+											((MODE) == DCMI_LineSelect_Mode_EvenLine))
+											
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_DMA_Request_FIFO_Size 
+  * @{
+  */
+#define DCMI_DMARequestFIFOSize_1Word     ((uint32_t)0x20000000) /*!< DCMI FIFO����һ���־ͻ����һ��DMARequest*/
+#define DCMI_DMARequestFIFOSize_2Word     ((uint32_t)0x40000000) /*!< DCMI FIFO���������־ͻ����һ��DMARequest*/
+#define DCMI_DMARequestFIFOSize_4Word     ((uint32_t)0x80000000) /*!< DCMI FIFO�����ĸ��־ͻ����һ��DMARequest*/
+#define DCMI_DMARequestFIFOSize_MSK       ((uint32_t)0xE0000000)
+#define IS_DCMI_DMAREQUESTFIFO_SIZE(SIZE) (((SIZE) == DCMI_DMARequestFIFOSize_1Word) ||\
+										   ((SIZE) == DCMI_DMARequestFIFOSize_2Word) ||\
+										   ((SIZE) == DCMI_DMARequestFIFOSize_4Word))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_interrupt_sources 
+  * @{
+  */ 
+#define DCMI_IT_FRAME    ((uint16_t)0x0001)
+#define DCMI_IT_OVF      ((uint16_t)0x0002)
+#define DCMI_IT_ERR      ((uint16_t)0x0004)
+#define DCMI_IT_VSYNC    ((uint16_t)0x0008)
+#define DCMI_IT_LINE     ((uint16_t)0x0010)
+#define IS_DCMI_CONFIG_IT(IT) ((((IT) & (uint16_t)0xFFE0) == 0x0000) && ((IT) != 0x0000))
+#define IS_DCMI_GET_IT(IT) (((IT) == DCMI_IT_FRAME) || \
+                            ((IT) == DCMI_IT_OVF) || \
+                            ((IT) == DCMI_IT_ERR) || \
+                            ((IT) == DCMI_IT_VSYNC) || \
+                            ((IT) == DCMI_IT_LINE))
+/**
+  * @}
+  */ 
+
+
+/** @defgroup DCMI_Flags 
+  * @{
+  */ 
+/** 
+  * @brief   DCMI SR register  
+  */ 
+#define DCMI_FLAG_HSYNC     ((uint16_t)0x2001)
+#define DCMI_FLAG_VSYNC     ((uint16_t)0x2002)
+#define DCMI_FLAG_FNE       ((uint16_t)0x2004)
+/** 
+  * @brief   DCMI RISR register  
+  */ 
+#define DCMI_FLAG_FRAMERI    ((uint16_t)0x0001)
+#define DCMI_FLAG_OVFRI      ((uint16_t)0x0002)
+#define DCMI_FLAG_ERRRI      ((uint16_t)0x0004)
+#define DCMI_FLAG_VSYNCRI    ((uint16_t)0x0008)
+#define DCMI_FLAG_LINERI     ((uint16_t)0x0010)
+/** 
+  * @brief   DCMI MISR register  
+  */ 
+#define DCMI_FLAG_FRAMEMI    ((uint16_t)0x1001)
+#define DCMI_FLAG_OVFMI      ((uint16_t)0x1002)
+#define DCMI_FLAG_ERRMI      ((uint16_t)0x1004)
+#define DCMI_FLAG_VSYNCMI    ((uint16_t)0x1008)
+#define DCMI_FLAG_LINEMI     ((uint16_t)0x1010)
+#define IS_DCMI_GET_FLAG(FLAG) (((FLAG) == DCMI_FLAG_HSYNC) || \
+                                ((FLAG) == DCMI_FLAG_VSYNC) || \
+                                ((FLAG) == DCMI_FLAG_FNE) || \
+                                ((FLAG) == DCMI_FLAG_FRAMERI) || \
+                                ((FLAG) == DCMI_FLAG_OVFRI) || \
+                                ((FLAG) == DCMI_FLAG_ERRRI) || \
+                                ((FLAG) == DCMI_FLAG_VSYNCRI) || \
+                                ((FLAG) == DCMI_FLAG_LINERI) || \
+                                ((FLAG) == DCMI_FLAG_FRAMEMI) || \
+                                ((FLAG) == DCMI_FLAG_OVFMI) || \
+                                ((FLAG) == DCMI_FLAG_ERRMI) || \
+                                ((FLAG) == DCMI_FLAG_VSYNCMI) || \
+                                ((FLAG) == DCMI_FLAG_LINEMI))
+                                
+#define IS_DCMI_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFE0) == 0x0000) && ((FLAG) != 0x0000))
+
+/**
+  * @brief  set dcmi input from out signal
+  */
+#define DCMI_FROM_OUT 	(0x1<<13)
+
+/*  Function used to set the DCMI configuration to the default reset state ****/ 
+void DCMI_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct);
+void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct);
+void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct);
+void DCMI_CROPCmd(FunctionalState NewState);
+void DCMI_JPEGCmd(FunctionalState NewState);
+void DCMI_SetDMARequsetFIFOSize(uint32_t NewFIFOSize);
+void DCMI_SetExtInput(void);
+
+/* Image capture functions ****************************************************/
+void DCMI_Cmd(FunctionalState NewState);
+void DCMI_CaptureCmd(FunctionalState NewState);
+uint32_t DCMI_ReadData(void);
+uint32_t DCMI_GetFIFODataWordNum(void);
+
+/* Interrupts and flags management functions **********************************/
+void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState);
+FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG);
+void DCMI_ClearFlag(uint16_t DCMI_FLAG);
+ITStatus DCMI_GetITStatus(uint16_t DCMI_IT);
+void DCMI_ClearITPendingBit(uint16_t DCMI_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__AIR105_DCMI_H */
+
+

+ 219 - 0
bsp/air105/chip/include/air105_dma.h

@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2022 OpenLuat & AirM2M
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __AIR105_DMA_H
+#define __AIR105_DMA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "air105.h"
+
+typedef struct
+{
+  uint32_t DMA_Peripheral;
+
+  uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */
+
+  uint32_t DMA_MemoryBaseAddr;     /*!< Specifies the memory base address for DMAy Channelx. */
+
+  uint32_t DMA_DIR;                /*!< Specifies if the peripheral is the source or destination.
+                                        This parameter can be a value of @ref DMA_data_transfer_direction */
+
+  uint32_t DMA_PeripheralInc;      /*!< Specifies whether the Peripheral address register is incremented or not.
+                                        This parameter can be a value of @ref DMA_incremented_mode */
+
+  uint32_t DMA_MemoryInc;          /*!< Specifies whether the memory address register is incremented or not.
+                                        This parameter can be a value of @ref DMA_incremented_mode */
+
+  uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data item width.
+                                        This parameter can be a value of @ref DMA_data_size */
+
+  uint32_t DMA_MemoryDataSize;     /*!< Specifies the Memory data item width.
+								   This parameter can be a value of @ref DMA_data_size */
+
+  uint32_t DMA_PeripheralBurstSize; /*!< Specifies the Peripheral Number of data items during per burst transaction.
+									read or write from the Peripheral every time a burst transaction request 
+									This parameter can be a value of @ref DMA_burst_size */
+
+  uint32_t DMA_MemoryBurstSize;     /*!< Specifies the Memory Number of data items during per burst transaction.
+									read or write from the Memory every time a burst transaction request 
+									This parameter can be a value of @ref DMA_burst_size */
+
+  uint32_t DMA_PeripheralHandShake;	/*!< Specifies the HandShake to control the DMA transacation.
+									This parameter can be a value of @ref DMA_peripheral_handshake */
+
+  uint32_t DMA_BlockSize;			/*!< Specifies the Total Number of data items during the transaction. */
+
+  uint32_t DMA_Priority;           /*!< Specifies the software priority for the DMAy Channelx.
+										This parameter can be a value of @ref DMA_priority_level */
+}DMA_InitTypeDef;
+
+/**
+ * DMA多块传输内存表
+ *
+ */
+typedef struct _lli
+{
+	uint32_t SAR;
+	uint32_t DAR;
+	uint32_t LLP;
+	uint32_t CTL_L;
+	uint32_t CTL_H;
+	uint32_t DSTAT;
+}LLI;
+
+/**多块传输模式
+  * @}
+  */
+#define  Multi_Block_MODE01        (uint8_t)0x00	/*Single-block or last transfer of multi-block*/
+#define  Multi_Block_MODE02        (uint8_t)0x01	/*Auto-reload multi-block transfer with contiguous SAR*/
+#define  Multi_Block_MODE03        (uint8_t)0x02	/*Auto-reload multi-block transfer with contiguous DAR*/
+#define  Multi_Block_MODE04        (uint8_t)0x03	/*Auto-reload multi-block transfer*/
+#define  Multi_Block_MODE05        (uint8_t)0x04	/*Single-block or last transfer of multi-block*/
+#define  Multi_Block_MODE06        (uint8_t)0x05	/*Linked list multi-block transfer with contiguous SAR*/
+#define  Multi_Block_MODE07        (uint8_t)0x06	/*Linked list multi-block transfer with auto-reload SAR*/
+#define  Multi_Block_MODE08        (uint8_t)0x07	/*Linked list multi-block transfer with contiguous DAR*/
+#define  Multi_Block_MODE09        (uint8_t)0x08	/*Linked list multi-block transfer with auto-reload DAR*/
+#define  Multi_Block_MODE10        (uint8_t)0x09	/*Linked list multi-block transfer*/
+
+/** @defgroup DMA_data_transfer_direction 
+  * @{
+  */
+  
+#define DMA_DIR_Memory_To_Memory								((uint32_t)0x0000)
+#define DMA_DIR_Memory_To_Peripheral							((uint32_t)0x0001)
+#define DMA_DIR_Peripheral_To_Memory							((uint32_t)0x0002)
+
+/**
+  * @}
+  */
+
+/** @defgroup DMA_incremented_mode 
+  * @{
+  */
+
+#define DMA_Inc_Increment						((uint32_t)0x00000000)
+#define DMA_Inc_Decrement						((uint32_t)0x00000001)
+#define DMA_Inc_Nochange						((uint32_t)0x00000002)
+#define IS_DMA_INC_STATE(STATE) (((STATE) == DMA_Inc_Increment) || \
+                                            ((STATE) == DMA_Inc_Decrement) || \
+                                            ((STATE) == DMA_Inc_Nochange))
+/**
+  * @}
+  */
+
+/** @defgroup DMA_data_size 
+  * @{
+  */
+
+#define DMA_DataSize_Byte									((uint32_t)0x0000)
+#define DMA_DataSize_HalfWord								((uint32_t)0x0001)
+#define DMA_DataSize_Word									((uint32_t)0x0002)
+#define IS_DMA_DATA_SIZE(SIZE)								(((SIZE) == DMA_DataSize_Byte) || \
+														    ((SIZE) == DMA_DataSize_HalfWord) || \
+														    ((SIZE) == DMA_DataSize_Word))
+/**
+  * @}
+  */
+
+/** @defgroup DMA_burst_size
+  * @{
+  */
+#define DMA_BurstSize_1										((uint32_t)0x00)
+#define DMA_BurstSize_4										((uint32_t)0x01)
+#define DMA_BurstSize_8										((uint32_t)0x02)
+#define DMA_BurstSize_16									((uint32_t)0x03)
+#define DMA_BurstSize_32									((uint32_t)0x04)
+/**
+  * @}
+  */
+
+/** @defgroup DMA_peripheral_handshake
+  * @{
+  */
+#define DMA_PeripheralHandShake_Hardware						((uint32_t)0x0000)
+#define DMA_PeripheralHandShake_Software						((uint32_t)0x0001)
+/**
+  * @}
+  */
+
+/** @defgroup DMA_Priority
+  * @{
+  */
+#define DMA_Priority_0											((uint32_t)0x00000000)
+#define DMA_Priority_1											((uint32_t)0x00000020)
+#define DMA_Priority_2											((uint32_t)0x00000040)
+#define DMA_Priority_3											((uint32_t)0x00000060)
+#define DMA_Priority_4											((uint32_t)0x00000080)
+#define DMA_Priority_5											((uint32_t)0x000000A0)
+#define DMA_Priority_6											((uint32_t)0x000000C0)
+
+/**
+  * @}
+  */
+
+/** @defgroup DMA_IT
+  * @{
+  */
+#define DMA_IT_BlockTransferComplete					((uint32_t)0x01)
+#define DMA_IT_DestinationTransactionComplete			((uint32_t)0x02)
+#define DMA_IT_Error									((uint32_t)0x04)
+#define DMA_IT_SourceTransactionComplete				((uint32_t)0x08)
+#define DMA_IT_DMATransferComplete						((uint32_t)0x10)
+/**
+  * @}
+  */
+
+void DMA_Init(DMA_TypeDef* DMA_Channelx, DMA_InitTypeDef* DMA_InitStruct);
+void DMA_ChannelCmd(DMA_TypeDef* DMA_Channelx, FunctionalState NewState);
+void DMA_Cmd(FunctionalState NewState);
+void DMA_ChannelConfig(DMA_TypeDef* DMA_Channelx, uint32_t DMA_Peripheral, uint32_t DMA_DIR);
+void DMA_SetSRCAddress(DMA_TypeDef* DMA_Channelx, uint32_t Address);
+void DMA_SetDSRAddress(DMA_TypeDef* DMA_Channelx, uint32_t Address);
+	 
+void DMA_ITConfig(DMA_TypeDef* DMA_Channelx, uint32_t DMA_IT, FunctionalState NewState);
+	 
+FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG);	 
+void DMA_ClearFlag(uint32_t DMA_FLAG);
+
+FunctionalState DMA_IsChannelEnabled(DMA_TypeDef* DMA_Channelx);
+	 
+ITStatus DMA_GetITStatus(DMA_TypeDef* DMA_Channelx,uint32_t DMA_IT);
+FlagStatus DMA_GetRawStatus(DMA_TypeDef* DMA_Channelx,uint32_t DMA_IT);
+void DMA_ClearITPendingBit(DMA_TypeDef* DMA_Channelx,uint32_t DMA_IT);
+
+void DMA_MultiBlockInit(DMA_TypeDef* DMA_Channelx, DMA_InitTypeDef* DMA_InitStruct ,\
+								LLI *first_lli,uint8_t Multi_Block_Mode);
+void DMA_InitLLI(DMA_TypeDef* DMA_Channelx,LLI *lli,LLI *next_lli,
+							void *src_addr,void *dest_addr,uint16_t btsize);
+uint32_t DMA_GetTransferNum(DMA_TypeDef* DMA_Channelx, uint32_t first_adr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
+
+/**************************      (C) COPYRIGHT Megahunt    *****END OF FILE****/

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff