├── .editorconfig ├── .gitattributes ├── .github ├── auto-comment.yml ├── stale.yml └── workflows │ ├── pr_audit.yml │ └── push_audit.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── component.mk ├── example ├── demo_jpg_sjpg.c └── images │ ├── info.txt │ ├── small_image.sjpg │ ├── small_image_sjpg.c │ ├── wallpaper.jpg │ ├── wallpaper.sjpg │ ├── wallpaper_jpg.c │ └── wallpaper_sjpg.c ├── lv_sjpg.c ├── lv_sjpg.h ├── scripts ├── jpg_to_sjpg.py ├── small_image.jpg └── wallpaper.jpg ├── tjpgd.c ├── tjpgd.h └── tjpgdcnf.h /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | 7 | # CRLF breaks shebang. 8 | [*.{sh}] 9 | end_of_line = lf 10 | 11 | [*.{js,py}] 12 | charset = utf-8 13 | 14 | [*.{cc,c,h,txt}] 15 | indent_style = space 16 | indent_size = unset 17 | 18 | [*.py] 19 | indent_style = space 20 | indent_size = 4 21 | 22 | [Makefile] 23 | indent_style = tab 24 | indent_size = 8 25 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | # CRLF breaks shebang. 4 | *.sh text eol=lf 5 | 6 | # Known binary file types. 7 | *.png binary 8 | *.jpg binary 9 | *.sjpg binary 10 | -------------------------------------------------------------------------------- /.github/auto-comment.yml: -------------------------------------------------------------------------------- 1 | # Comment to a new issue. 2 | pullRequestOpened: | 3 | Thank you for raising your pull request. 4 | 5 | To ensure that all licensing criteria is met all repositories of the LVGL project apply a process called DCO (Developer's Certificate of Origin). 6 | 7 | The text of DCO can be read here: https://developercertificate.org/ 8 | For a more detailed description see the [Documentation](https://docs.lvgl.io/latest/en/html/contributing/index.html#developer-certification-of-origin-dco) site. 9 | 10 | By contributing to any repositories of the LVGL project you state that your contribution corresponds with the DCO. 11 | 12 | No further action is required if your contribution fulfills the DCO. If you are not sure about it feel free to ask us in a comment. 13 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 21 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - architecture 8 | - pinned 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue or pull request has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.github/workflows/pr_audit.yml: -------------------------------------------------------------------------------- 1 | name: Pull CI 2 | on: pull_request 3 | 4 | jobs: 5 | textformat: 6 | name: EditorConfig audit 7 | runs-on: ubuntu-latest 8 | env: 9 | ALWAYS_LINT_ALL_FILES: false 10 | EC_FIX_ERROR: false 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | - name: EditorConfig-Action 17 | uses: zbeekman/EditorConfig-Action@master 18 | env: 19 | ALWAYS_LINT_ALL_FILES: false 20 | EC_FIX_ERROR: false 21 | 22 | build: 23 | runs-on: ubuntu-latest 24 | env: 25 | CMAKE_BUILD_DIR: ${{ github.workspace }}/build/ 26 | CMAKE_BUILD_TYPE: Debug 27 | steps: 28 | - name: Get source 29 | uses: actions/checkout@v2 30 | with: 31 | submodules: recursive 32 | - name: Setup cmake 33 | uses: jwlawson/actions-setup-cmake@v1.9 34 | with: 35 | cmake-version: '3.16.x' 36 | - name: Install dependencies and generate project files 37 | run: | 38 | cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} -DCONFIG_LV_CONF_SKIP=1 39 | - name: Build 40 | run: | 41 | cmake --build "${{ env.CMAKE_BUILD_DIR }}" 42 | -------------------------------------------------------------------------------- /.github/workflows/push_audit.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: push 3 | 4 | jobs: 5 | textformat: 6 | name: EditorConfig audit 7 | runs-on: ubuntu-latest 8 | env: 9 | ALWAYS_LINT_ALL_FILES: false 10 | EC_FIX_ERROR: false 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | - name: EditorConfig-Action 17 | uses: zbeekman/EditorConfig-Action@master 18 | env: 19 | ALWAYS_LINT_ALL_FILES: false 20 | EC_FIX_ERROR: false 21 | 22 | build: 23 | name: Build-debug 24 | runs-on: ubuntu-latest 25 | env: 26 | CMAKE_BUILD_DIR: ${{ github.workspace }}/build-asan/ 27 | CMAKE_BUILD_TYPE: Debug 28 | 29 | steps: 30 | - uses: actions/checkout@v2 31 | with: 32 | submodules: true 33 | - name: Setup cmake 34 | uses: jwlawson/actions-setup-cmake@v1.9 35 | with: 36 | cmake-version: '3.16.x' 37 | - name: Install dependencies and generate project files 38 | run: | 39 | cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} -DCONFIG_LV_CONF_SKIP=1 40 | - name: Build 41 | run: | 42 | cmake --build "${{ env.CMAKE_BUILD_DIR }}" 43 | - name: Show content of workspace at its completion 44 | run: find $RUNNER_WORKSPACE 45 | shell: bash 46 | - name: Run debug tests 47 | run: '${{ env.CMAKE_BUILD_DIR }}\demo_jpg_sjpg' 48 | 49 | asan: 50 | name: ${{ matrix.os }}-ASAN 51 | runs-on: ${{ matrix.os }} 52 | strategy: 53 | fail-fast: false 54 | matrix: 55 | os: [ubuntu-latest, macos-latest] 56 | include: 57 | - os: ubuntu-latest 58 | triplet: x64-linux 59 | - os: macos-latest 60 | triplet: x64-osx 61 | env: 62 | CMAKE_BUILD_DIR: ${{ github.workspace }}/build-asan/ 63 | CMAKE_BUILD_TYPE: Debug 64 | 65 | steps: 66 | - uses: actions/checkout@v2 67 | with: 68 | submodules: true 69 | - name: Setup cmake 70 | uses: jwlawson/actions-setup-cmake@v1.9 71 | with: 72 | cmake-version: '3.16.x' 73 | - name: Install dependencies and generate project files 74 | run: | 75 | cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} -DSJPEG_ASAN=1 -DCONFIG_LV_CONF_SKIP=1 76 | - name: Build 77 | run: | 78 | cmake --build "${{ env.CMAKE_BUILD_DIR }}" 79 | - name: Show content of workspace at its completion 80 | run: find $RUNNER_WORKSPACE 81 | shell: bash 82 | - name: Run ASAN tests 83 | run: '${{ env.CMAKE_BUILD_DIR }}\demo_jpg_sjpg' 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Editor temporary files 46 | *.swp 47 | 48 | # Kernel Module Compile Results 49 | *.mod* 50 | *.cmd 51 | .tmp_versions/ 52 | modules.order 53 | Module.symvers 54 | Mkfile.old 55 | dkms.conf 56 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | if(ESP_PLATFORM) 4 | 5 | ############################################### 6 | # A library component for buiding in ESP-IDF. # 7 | ############################################### 8 | 9 | file(GLOB SOURCES *.c) 10 | 11 | idf_component_register(SRCS ${SOURCES} 12 | INCLUDE_DIRS . 13 | REQUIRES lvgl) 14 | 15 | else(ESP_PLATFORM) 16 | 17 | ############################## 18 | # Desktop build definitions. # 19 | ############################## 20 | 21 | set(CMAKE_C_COMPILER clang) 22 | 23 | project(lv_lib_split_jpg LANGUAGES C) 24 | 25 | set(CMAKE_C_STANDARD 99) 26 | 27 | if(NOT CMAKE_BUILD_TYPE) 28 | set(CMAKE_BUILD_TYPE "Release") 29 | endif() 30 | 31 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 32 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-strict-aliasing") 33 | endif() 34 | 35 | if (SJPEG_FUZZING) 36 | add_definitions(-DSJPEG_FUZZING) 37 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer,address") 38 | set(SJPEG_ASAN 1) 39 | set(SJPEG_LLVM_CODE_COVERAGE 1) 40 | endif() 41 | 42 | if (SJPEG_LLVM_CODE_COVERAGE) 43 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-instr-generate -fcoverage-mapping") 44 | endif() 45 | 46 | if (SJPEG_ASAN) 47 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer") 48 | endif() 49 | 50 | if (SJPEG_MSAN) 51 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -fno-omit-frame-pointer") 52 | endif() 53 | 54 | set(LVGL_SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}/lvgl-prefix/src") 55 | 56 | include(ExternalProject) 57 | ExternalProject_Add(lvgl 58 | GIT_REPOSITORY https://github.com/lvgl/lvgl.git 59 | CMAKE_ARGS "-DCMAKE_C_FLAGS=-DLV_CONF_SKIP -I${PROJECT_SOURCE_DIR}/example -I${LVGL_SRC_DIR}" 60 | INSTALL_COMMAND "" 61 | ) 62 | 63 | include_directories( 64 | "." 65 | ".." 66 | "${LVGL_SRC_DIR}" 67 | ) 68 | 69 | add_library(${PROJECT_NAME} "") 70 | target_sources(${PROJECT_NAME} 71 | PRIVATE 72 | "lv_sjpg.c" 73 | "lv_sjpg.h" 74 | "tjpgd.c" 75 | "tjpgd.h" 76 | ) 77 | 78 | add_dependencies(${PROJECT_NAME} lvgl) 79 | add_definitions(-DLV_CONF_SKIP -DLV_LIB_SJPG_TEST) 80 | 81 | add_executable(demo_jpg_sjpg 82 | "example/demo_jpg_sjpg.c" 83 | "example/images/small_image_sjpg.c" 84 | "example/images/wallpaper_jpg.c" 85 | "example/images/wallpaper_sjpg.c" 86 | ) 87 | 88 | add_dependencies(demo_jpg_sjpg lvgl) 89 | 90 | set(LVGL_BUILD_DIR ${LVGL_SRC_DIR}/lvgl-build) 91 | set(LVGL_LIBRARY ${CMAKE_STATIC_LIBRARY_PREFIX}lvgl${CMAKE_STATIC_LIBRARY_SUFFIX}) 92 | if (WIN32) 93 | set(LVGL_LIBRARY_PATH ${LVGL_BUILD_DIR}/${CMAKE_BUILD_TYPE}/${LVGL_LIBRARY}) 94 | else (WIN32) 95 | set(LVGL_LIBRARY_PATH ${LVGL_BUILD_DIR}/${LVGL_LIBRARY}) 96 | endif (WIN32) 97 | 98 | target_link_libraries(demo_jpg_sjpg 99 | ${PROJECT_NAME} 100 | "${LVGL_LIBRARY_PATH}" 101 | ) 102 | 103 | endif() 104 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 LVGL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JPG decoder for LVGL 2 | 3 | **This repository is merged into the lvgl repository. See https://docs.lvgl.io/master/libs/sjpg.html** 4 | 5 | ![Status](https://github.com/lvgl/lv_lib_split_jpg/actions/workflows/push_audit.yml/badge.svg) 6 | 7 | ## Overview 8 | - lv_lib_split_jpg supports both normal jpg and the custom sjpg formats. 9 | - Decoding normal jpg consumes RAM with the site fo the whole uncompressed image (recommended only for devices with more RAM) 10 | - sjpg is a custom format based on "normal" JPG and specially made for lvgl. 11 | - sjpg is 'split-jpeg' which is a bundle of small jpeg fragments with an sjpg header. 12 | - sjpg size will be almost comparable to the jpg file or might be a slightly larger. 13 | - lv_sjpg can open and handle multiple files at same time. 14 | - File read from disk (fread) and c-array is implemented. 15 | - SJPEG frame fragment cache enables fast fetching of lines if availble in cache. 16 | - By default the sjpg image cache will be xres * 2 * 16 bytes (can be modified) 17 | - Currently only 16 bit image format is supported (to do) 18 | 19 | ## Getting started 20 | - Clone this repository next to lvgl with `git clone https://github.com/lvgl/lv_lib_split_jpg.git` 21 | - If you need to open (S)JPG files use [lv_fs_if](https://github.com/lvgl/lv_fs_if) or add your own [file system drivers](https://docs.lvgl.io/latest/en/html/overview/file-system.html). 22 | - With `lv_fs_if` add these line to the end of `lv_conf.h` to enable "PC file system" handling 23 | ```c 24 | #define LV_USE_FS_IF 1 25 | #if LV_USE_FS_IF 26 | # define LV_FS_IF_FATFS '\0' 27 | # define LV_FS_IF_PC 'S' 28 | #endif 29 | ``` 30 | - For fast simulatneous multi jpg/sjpg rendering in expense of additional RAM, you can modify `LV_IMG_CACHE_DEF_SIZE` to 2 or above if testing in simulator or using it in devices like raspberry pi etc. 31 | - To open large JPG image a lot of dymaic memory is required. Be sure to set `LV_MEM_SIZE` to large enough value. In simulator `(4 * 1024 * 1024)` shiuld be a good start. 32 | 33 | ## Example code 34 | ```c 35 | #include 36 | #include "lv_lib_split_jpg/lv_sjpg.h" 37 | 38 | LV_IMG_DECLARE( small_image_sjpg ); 39 | LV_IMG_DECLARE( wallpaper_jpg ); 40 | 41 | void demo_jpg_sjpg( void ) 42 | { 43 | lv_fs_if_init(); 44 | lv_obj_t * img1; 45 | lv_obj_t * img2; 46 | 47 | lv_split_jpeg_init(); 48 | img1 = lv_img_create(lv_scr_act(), NULL); 49 | img2 = lv_img_create(lv_scr_act(), NULL); 50 | 51 | //jpg from c array 52 | lv_img_set_src( img1, &wallpaper_jpg); 53 | 54 | //sjpg from file (with lv_fs) 55 | //On Windows 56 | lv_img_set_src(img2, "S.\\lv_lib_split_jpg\\example\\images\\small_image.sjpg"); 57 | 58 | //On Linux 59 | //lv_img_set_src(img2, "S/lv_lib_split_jpg/example/images/small_image.sjpg"); 60 | } 61 | ``` 62 | ## Converter 63 | 64 | # Converting JPG to C array 65 | - Use lvgl online tool https://lvgl.io/tools/imageconverter 66 | - Color format = RAW, output format = C Array 67 | 68 | # Converting JPG to SJPG 69 | python3 and PIL library required 70 | 71 | To create SJPG from JPG: 72 | 1. Drag and drop a jpeg image on top of the jpg_to_sjpg.py 73 | 2. Run the python script on shell with jpeg filename as argument. It should generate filename.c and filename.sjpg files. 74 | ```sh 75 | python3 jpg_to_sjpg.py wallpaper.jpg 76 | ``` 77 | Expected result: 78 | ```sh 79 | Conversion started... 80 | 81 | Input: 82 | walpaper.jpg 83 | RES = 640 x 480 84 | 85 | Output: 86 | Time taken = 1.66 sec 87 | bin size = 77.1 KB 88 | walpaper.sjpg (bin file) 89 | walpaper.c (c array) 90 | 91 | All good! 92 | ``` 93 | 94 | -------------------------------------------------------------------------------- /component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Component Makefile 3 | # 4 | 5 | CFLAGS += -DLV_LVGL_H_INCLUDE_SIMPLE 6 | 7 | COMPONENT_SRCDIRS := . 8 | 9 | COMPONENT_ADD_INCLUDEDIRS := $(COMPONENT_SRCDIRS) . 10 | -------------------------------------------------------------------------------- /example/demo_jpg_sjpg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "lv_lib_split_jpg/lv_sjpg.h" 3 | 4 | LV_IMG_DECLARE( small_image_sjpg ); 5 | LV_IMG_DECLARE( wallpaper_jpg ); 6 | 7 | #if defined(_WIN32) 8 | #define OS_WINDOWS 9 | #endif 10 | 11 | #if defined(OS_WINDOWS) 12 | static const char kTestFile[] = "S.\\lv_lib_split_jpg\\example\\images\\small_image.sjpg"; 13 | #else 14 | static const char kTestFile[] = "S/lv_lib_split_jpg/example/images/small_image.sjpg"; 15 | #endif 16 | 17 | /*Change to your screen resolution*/ 18 | #define screenWidth 320 19 | #define screenHeight 240 20 | 21 | static lv_disp_draw_buf_t draw_buf; 22 | static lv_color_t buf[ screenWidth * 10 ]; 23 | 24 | static void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) 25 | { 26 | lv_disp_flush_ready(disp); 27 | } 28 | 29 | void demo_jpg_sjpg( void ) 30 | { 31 | lv_obj_t * img1; 32 | lv_obj_t * img2; 33 | 34 | lv_split_jpeg_init(); 35 | img1 = lv_img_create(lv_scr_act()); 36 | img2 = lv_img_create(lv_scr_act()); 37 | 38 | //jpg from c array 39 | lv_img_set_src(img1, &wallpaper_jpg); 40 | 41 | //sjpg from file (with lv_fs) 42 | lv_img_set_src(img2, kTestFile); 43 | } 44 | 45 | #if defined(LV_LIB_SJPG_TEST) 46 | 47 | int main(int argc, const char **argv) 48 | { 49 | lv_init(); 50 | 51 | //Initialize the display. 52 | static lv_disp_drv_t disp_drv; 53 | lv_disp_drv_init(&disp_drv); 54 | 55 | disp_drv.hor_res = screenWidth; 56 | disp_drv.ver_res = screenHeight; 57 | disp_drv.flush_cb = my_disp_flush; 58 | disp_drv.draw_buf = &draw_buf; 59 | lv_disp_drv_register(&disp_drv); 60 | 61 | demo_jpg_sjpg(); 62 | } 63 | 64 | #endif // defined(LV_LIB_SJPG_TEST) 65 | 66 | -------------------------------------------------------------------------------- /example/images/info.txt: -------------------------------------------------------------------------------- 1 | small_image = 320 x 240 - 565 2 | walpaper = 640 x 480 - 565 3 | -------------------------------------------------------------------------------- /example/images/small_image.sjpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvgl/lv_lib_split_jpg/c292bfd196fdae251069efb5f1c2f0c1040d764f/example/images/small_image.sjpg -------------------------------------------------------------------------------- /example/images/small_image_sjpg.c: -------------------------------------------------------------------------------- 1 | //LVGL SJPG C ARRAY 2 | #include "lvgl/lvgl.h" 3 | 4 | const uint8_t small_image_sjpg_map[] = { 5 | 0x5f, 0x53, 0x4a, 0x50, 0x47, 0x5f, 0x5f, 0x0, 0x56, 0x31, 0x2e, 0x30, 0x30, 0x0, 0x40, 0x1, 6 | 0xf0, 0x0, 0xf, 0x0, 0x10, 0x0, 0xd3, 0x3, 0x1c, 0x4, 0x47, 0x4, 0x8b, 0x4, 0x76, 0x5, 7 | 0xfd, 0x5, 0x90, 0x5, 0xad, 0x5, 0x5d, 0x5, 0x21, 0x5, 0x57, 0x4, 0x53, 0x4, 0xfc, 0x3, 8 | 0xd0, 0x3, 0x91, 0x3, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 9 | 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 10 | 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 11 | 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 12 | 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 13 | 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 14 | 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 15 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 16 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 17 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 18 | 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 19 | 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 20 | 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 21 | 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 22 | 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 23 | 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 24 | 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 25 | 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 26 | 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 27 | 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 28 | 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 29 | 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 30 | 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 31 | 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 32 | 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 33 | 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 34 | 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 35 | 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 36 | 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 37 | 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 38 | 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 39 | 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 40 | 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 41 | 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 42 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 43 | 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 44 | 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 45 | 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 46 | 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 47 | 0x0, 0x3f, 0x0, 0xf7, 0x5c, 0x52, 0x14, 0x6, 0x9c, 0x38, 0xa7, 0xa, 0xf2, 0x55, 0x34, 0xf7, 48 | 0x35, 0xb9, 0x5a, 0x5b, 0x65, 0x95, 0x70, 0xc3, 0x3e, 0x84, 0x75, 0x15, 0x42, 0x44, 0x9a, 0xd1, 49 | 0xb7, 0x72, 0xc8, 0x3f, 0x8c, 0x76, 0xfa, 0xd6, 0xc6, 0x29, 0xa, 0x83, 0xd4, 0x57, 0x26, 0x23, 50 | 0x2d, 0x85, 0x4f, 0x7a, 0x3a, 0x3e, 0xe5, 0xc6, 0xab, 0x5b, 0x90, 0xdb, 0x5c, 0x2d, 0xc4, 0x7b, 51 | 0x81, 0x19, 0xee, 0x2a, 0x43, 0x54, 0xa5, 0xb1, 0x78, 0x64, 0xf3, 0xad, 0x8, 0x56, 0xef, 0x19, 52 | 0xe8, 0xdf, 0xe1, 0x52, 0x3d, 0xc8, 0x36, 0xe5, 0xb0, 0x55, 0xcf, 0x1b, 0x4f, 0x50, 0x6a, 0xa9, 53 | 0xce, 0xa2, 0x5c, 0x95, 0x96, 0xab, 0xee, 0x60, 0xe2, 0x9b, 0xbc, 0x46, 0x41, 0x2e, 0xfb, 0xd9, 54 | 0xf, 0xf0, 0xa8, 0xda, 0x2a, 0xfa, 0x80, 0xd5, 0x95, 0x6f, 0xfb, 0xb2, 0x7d, 0xea, 0xf4, 0x72, 55 | 0x57, 0x66, 0x1e, 0x7c, 0xaa, 0xcc, 0x75, 0x61, 0xae, 0x85, 0xc0, 0x38, 0xa5, 0xa6, 0x23, 0xe6, 56 | 0x9f, 0x5e, 0x8c, 0x5a, 0x6b, 0x43, 0x9d, 0x91, 0x38, 0xcb, 0x52, 0x85, 0xa7, 0xe3, 0x26, 0x94, 57 | 0xa, 0xbb, 0x88, 0x68, 0x5e, 0x2a, 0xa4, 0x89, 0xe5, 0xbe, 0x3b, 0x76, 0xab, 0xdd, 0xaa, 0x29, 58 | 0x63, 0xde, 0x9c, 0x75, 0x1d, 0x28, 0x4c, 0x8, 0x61, 0x97, 0x67, 0xca, 0xdd, 0x3f, 0x95, 0x5a, 59 | 0xeb, 0x54, 0x2a, 0x68, 0x64, 0x20, 0xed, 0xea, 0x28, 0x68, 0x9b, 0x96, 0xa, 0xe6, 0x98, 0xd1, 60 | 0xd4, 0xbd, 0xa8, 0xed, 0x48, 0xa2, 0xab, 0x47, 0x51, 0x14, 0x20, 0xf1, 0xc1, 0xab, 0xa5, 0x41, 61 | 0xa6, 0x95, 0x5f, 0x4a, 0x0, 0xac, 0xb3, 0xc8, 0x9d, 0x7e, 0x61, 0xef, 0x53, 0x25, 0xca, 0x31, 62 | 0xc1, 0xca, 0x9f, 0x7a, 0x46, 0xa, 0x3b, 0xa, 0x58, 0xd7, 0x71, 0xcf, 0x61, 0x40, 0x3, 0xdc, 63 | 0x22, 0x9c, 0xf, 0x98, 0xfb, 0x54, 0x46, 0x46, 0x73, 0xcf, 0x4f, 0x4a, 0x5b, 0x98, 0xb0, 0xdb, 64 | 0xc7, 0x43, 0xd6, 0xa3, 0x5a, 0x62, 0x26, 0x5a, 0x99, 0x6a, 0x25, 0xa9, 0x56, 0x90, 0xc7, 0x13, 65 | 0x8a, 0x7, 0x4a, 0x8f, 0x76, 0xe6, 0xcd, 0x3f, 0x76, 0x28, 0x1, 0x68, 0xa6, 0xef, 0xa4, 0xdf, 66 | 0x40, 0xf, 0xa3, 0x35, 0x11, 0x7a, 0x50, 0x49, 0xa0, 0x7, 0xe6, 0x8d, 0xd4, 0x81, 0x7d, 0x69, 67 | 0xd8, 0x2, 0x80, 0xe, 0x68, 0xa5, 0xa6, 0x96, 0x2, 0x80, 0x16, 0x8a, 0x41, 0xcd, 0x2d, 0x0, 68 | 0x56, 0xb9, 0xe5, 0x80, 0xf4, 0xa6, 0x9e, 0x63, 0x43, 0xf8, 0x53, 0xe4, 0x19, 0x26, 0x91, 0x46, 69 | 0x61, 0x3e, 0xc6, 0x98, 0x8f, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 70 | 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 71 | 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 72 | 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 73 | 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 74 | 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 75 | 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 76 | 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 77 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 78 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 79 | 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 80 | 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 81 | 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 82 | 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 83 | 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 84 | 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 85 | 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 86 | 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 87 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 88 | 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 89 | 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 90 | 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 91 | 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 92 | 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 93 | 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 94 | 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 95 | 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 96 | 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 97 | 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 98 | 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 99 | 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 100 | 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 101 | 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 102 | 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 103 | 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 104 | 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 105 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 106 | 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 107 | 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 108 | 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xf4, 0x64, 0xf1, 0x45, 0xf3, 0xff, 0x0, 0xc, 0x23, 0xe8, 109 | 0xa7, 0xfc, 0x6a, 0xc2, 0xeb, 0xb7, 0xaf, 0xfc, 0x48, 0x3e, 0x8b, 0x5c, 0xb4, 0xf, 0xd2, 0xb4, 110 | 0x61, 0x7a, 0xf9, 0xf9, 0x54, 0x9f, 0x73, 0xe9, 0x67, 0x84, 0xa5, 0x1d, 0xa2, 0x74, 0x31, 0x6b, 111 | 0x17, 0x24, 0xfc, 0xef, 0xc7, 0xa8, 0x2, 0xae, 0xa5, 0xe4, 0xae, 0x33, 0xe6, 0x64, 0x57, 0x3d, 112 | 0x1b, 0x55, 0xc8, 0x64, 0x2a, 0x72, 0xd, 0x67, 0xed, 0xe6, 0xb7, 0x67, 0x1d, 0x4c, 0x3c, 0x7a, 113 | 0x23, 0x68, 0x4e, 0xf8, 0xc9, 0x73, 0x55, 0x5a, 0x4f, 0xb5, 0x4b, 0x82, 0x4e, 0x3f, 0x86, 0xa8, 114 | 0xcb, 0xa8, 0x23, 0xbf, 0x90, 0xe, 0xf, 0xf1, 0x1e, 0xdf, 0x4a, 0xb3, 0x1, 0xda, 0xc0, 0xfa, 115 | 0x57, 0x65, 0x28, 0x73, 0x2b, 0xcb, 0xa9, 0x8f, 0xb2, 0xe4, 0xd4, 0x56, 0x98, 0xc3, 0x36, 0xc6, 116 | 0xe9, 0x8a, 0xb5, 0x14, 0xa1, 0x86, 0x41, 0xc8, 0xaa, 0x97, 0xa5, 0x5a, 0xe5, 0xd7, 0xb0, 0xc6, 117 | 0x3f, 0x2a, 0x81, 0x59, 0xe2, 0x6f, 0xeb, 0x5c, 0xbe, 0xd2, 0x50, 0xa8, 0xd6, 0xe8, 0xae, 0x45, 118 | 0x28, 0xa6, 0x6e, 0xc7, 0x25, 0x5a, 0x49, 0x32, 0x30, 0x7a, 0xd6, 0x12, 0x5f, 0x60, 0x60, 0xf0, 119 | 0x7d, 0x6a, 0x55, 0x99, 0xa4, 0x75, 0x5d, 0xd9, 0x4, 0x8a, 0xef, 0xa3, 0x5f, 0xb1, 0xcb, 0x3a, 120 | 0xf, 0x73, 0x72, 0x8a, 0xaf, 0xbb, 0x14, 0x6f, 0x6f, 0x5a, 0xf4, 0x39, 0xd1, 0xcd, 0xca, 0x4e, 121 | 0x58, 0xe, 0xa6, 0x9a, 0x65, 0x41, 0xde, 0xa1, 0x2e, 0x7b, 0xe2, 0xa4, 0x8d, 0x41, 0x1, 0x88, 122 | 0xe6, 0x97, 0x33, 0x7b, 0x3, 0x8d, 0xb7, 0x18, 0xd1, 0x7, 0x6d, 0xfc, 0x80, 0x6a, 0x45, 0xa, 123 | 0x83, 0xa, 0x31, 0x52, 0x11, 0x91, 0x55, 0xcb, 0x60, 0xd6, 0xa8, 0xcd, 0xe8, 0x58, 0x7, 0x23, 124 | 0x34, 0xbd, 0xaa, 0x38, 0xce, 0x52, 0x95, 0x9a, 0x93, 0x28, 0x9, 0xa8, 0xd9, 0xa9, 0x19, 0xaa, 125 | 0x22, 0xdb, 0x8e, 0x5, 0x0, 0x3c, 0xd, 0xed, 0x81, 0xd2, 0xac, 0xa8, 0xc0, 0xc5, 0x45, 0x1a, 126 | 0xed, 0x15, 0x28, 0xa0, 0x0, 0x80, 0xc0, 0x83, 0xd0, 0xd5, 0x32, 0x9b, 0x1f, 0x6d, 0x5c, 0xa6, 127 | 0x48, 0x9b, 0xd7, 0xdc, 0x50, 0x4, 0x6b, 0x44, 0x8f, 0x81, 0xb7, 0xd6, 0x9b, 0xb8, 0x2a, 0xe4, 128 | 0xd4, 0x6, 0x4c, 0x92, 0x4f, 0x5a, 0x62, 0x27, 0xdf, 0x8a, 0xc, 0x95, 0x6, 0xe2, 0x69, 0x47, 129 | 0xb9, 0xa0, 0x9, 0x77, 0xe6, 0x94, 0x64, 0xd3, 0x5, 0x48, 0xa3, 0xd2, 0x80, 0x15, 0x46, 0x2a, 130 | 0x41, 0x4d, 0xa, 0x7d, 0x29, 0xc1, 0x4d, 0x21, 0x8e, 0x14, 0xb4, 0x82, 0xab, 0x5e, 0xdc, 0x9b, 131 | 0x58, 0x3c, 0xc0, 0xb9, 0xe7, 0x7, 0xda, 0x84, 0xaf, 0xa0, 0x9b, 0x49, 0x5d, 0x93, 0x49, 0x28, 132 | 0x4e, 0x3a, 0x9a, 0x8d, 0x49, 0x63, 0x93, 0x54, 0x62, 0xbb, 0x8a, 0x5e, 0x77, 0xe0, 0x9f, 0x5a, 133 | 0xba, 0x9c, 0xd5, 0x38, 0xb5, 0xb8, 0x94, 0x94, 0xb6, 0x2c, 0x2f, 0x4a, 0x5a, 0x45, 0xe9, 0x4e, 134 | 0xa9, 0x28, 0x89, 0xd6, 0xa3, 0x51, 0xf7, 0xc7, 0xa8, 0xa9, 0xc8, 0xcd, 0x47, 0x8c, 0x38, 0xa0, 135 | 0xf, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 136 | 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 137 | 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 138 | 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 139 | 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 140 | 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 141 | 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 142 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 143 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 144 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 145 | 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 146 | 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 147 | 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 148 | 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 149 | 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 150 | 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 151 | 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 152 | 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 153 | 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 154 | 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 155 | 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 156 | 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 157 | 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 158 | 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 159 | 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 160 | 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 161 | 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 162 | 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 163 | 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 164 | 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 165 | 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 166 | 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 167 | 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 168 | 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 169 | 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 170 | 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 171 | 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 172 | 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 173 | 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 174 | 0x3f, 0x0, 0xdd, 0x82, 0x4f, 0x7a, 0xd2, 0x81, 0xeb, 0x84, 0xb0, 0xd7, 0x1a, 0xda, 0x40, 0x92, 175 | 0xe5, 0xa1, 0xf5, 0xee, 0xb5, 0xd7, 0xda, 0x5c, 0x24, 0xd1, 0xac, 0x91, 0xb8, 0x64, 0x6e, 0x84, 176 | 0x57, 0x81, 0x24, 0x7d, 0xce, 0x2b, 0xf, 0x2a, 0x7b, 0x9b, 0x51, 0xb5, 0x3a, 0xe2, 0xef, 0xc9, 177 | 0x8f, 0xa, 0x7e, 0x76, 0xe9, 0xed, 0xef, 0x55, 0x3e, 0xd0, 0xb0, 0xc4, 0x5d, 0xba, 0xf, 0xd6, 178 | 0xb3, 0x65, 0xbe, 0x50, 0xe6, 0x49, 0x9f, 0xe6, 0x3d, 0x14, 0x52, 0xa7, 0x47, 0x99, 0xdd, 0xec, 179 | 0x70, 0x46, 0x8b, 0x93, 0x35, 0x20, 0xe4, 0xe7, 0x35, 0x75, 0x75, 0x55, 0xb6, 0xf9, 0x41, 0xde, 180 | 0x7d, 0x3d, 0x2b, 0x98, 0x6d, 0x45, 0xe5, 0xe0, 0x1d, 0xa9, 0xe8, 0x29, 0x52, 0x7a, 0xed, 0xb3, 181 | 0x46, 0x92, 0xc2, 0xf3, 0x7c, 0x47, 0x67, 0x6b, 0x79, 0x15, 0xd6, 0x5c, 0x63, 0x7f, 0x7f, 0x5a, 182 | 0xb0, 0xc4, 0x30, 0xc1, 0xae, 0x3a, 0xda, 0xec, 0xc3, 0x2a, 0xb8, 0x3f, 0x95, 0x6f, 0x45, 0x7e, 183 | 0xa, 0x8d, 0xe4, 0x60, 0xff, 0x0, 0x10, 0xac, 0xac, 0x91, 0xc5, 0x57, 0xc, 0xe0, 0xf4, 0x26, 184 | 0x98, 0x34, 0x67, 0xd4, 0x7a, 0xd4, 0xba, 0x74, 0xac, 0x6f, 0x63, 0x50, 0x4e, 0xde, 0x4e, 0x3f, 185 | 0xa, 0x61, 0x75, 0x75, 0xec, 0x41, 0xa7, 0xe9, 0xb1, 0x79, 0x77, 0x8c, 0xfd, 0x50, 0x2d, 0x25, 186 | 0xb, 0x49, 0x34, 0x63, 0x3f, 0x81, 0xdc, 0xe8, 0x43, 0x83, 0x4b, 0x9a, 0xa2, 0xd3, 0xd4, 0x4f, 187 | 0x78, 0x53, 0xe5, 0x1c, 0x93, 0x5d, 0x4a, 0xad, 0xdd, 0x8e, 0xf, 0x64, 0xde, 0xc5, 0xe2, 0xfb, 188 | 0x9b, 0x68, 0xe9, 0x56, 0x95, 0xb0, 0xa2, 0xa8, 0x5b, 0x30, 0x7c, 0x55, 0xa2, 0xd8, 0xae, 0x88, 189 | 0xbb, 0x23, 0x39, 0xc7, 0xa1, 0x67, 0xcd, 0x18, 0xf7, 0xaa, 0xf2, 0xb0, 0x2d, 0x91, 0x49, 0xba, 190 | 0xab, 0xc8, 0xe5, 0x4d, 0x68, 0xa7, 0x63, 0x37, 0x4b, 0x99, 0x58, 0xb7, 0x3, 0xfc, 0xa4, 0x52, 191 | 0xb3, 0x55, 0x68, 0x64, 0xf9, 0xbe, 0xa2, 0x9e, 0xcd, 0x5a, 0xbd, 0xcc, 0x63, 0xb0, 0xac, 0xd4, 192 | 0xe8, 0xc6, 0x39, 0xef, 0x51, 0x2f, 0x27, 0x35, 0x3a, 0xf4, 0xa4, 0x32, 0x55, 0xa9, 0x5, 0x46, 193 | 0xb4, 0x34, 0x81, 0x7a, 0x73, 0x48, 0x64, 0x95, 0x1b, 0xcc, 0x91, 0xfd, 0xe6, 0xe7, 0xd0, 0x54, 194 | 0xf, 0x23, 0xb7, 0x7c, 0xf, 0x6a, 0x80, 0x8c, 0x9a, 0xa, 0xb1, 0x34, 0x81, 0xa6, 0x4f, 0x31, 195 | 0x46, 0x17, 0xd2, 0xa2, 0x54, 0x15, 0x79, 0x30, 0xa8, 0x17, 0xd2, 0xa2, 0x92, 0x20, 0x7e, 0x65, 196 | 0xfc, 0xaa, 0x93, 0x21, 0xae, 0xc4, 0x41, 0x45, 0x48, 0x14, 0x7a, 0x53, 0x5, 0x48, 0x3a, 0x8a, 197 | 0x6c, 0x94, 0x3d, 0x40, 0xa9, 0x5, 0x46, 0xb5, 0x20, 0xa9, 0x65, 0xb, 0x45, 0x19, 0xc0, 0xe6, 198 | 0xa1, 0x79, 0x73, 0xd3, 0xa5, 0x9, 0x5c, 0x1b, 0xb0, 0xf6, 0x93, 0x1d, 0x2a, 0xad, 0xda, 0xf9, 199 | 0xd6, 0xd2, 0x27, 0xaa, 0xf1, 0xf5, 0xa5, 0x2f, 0x4c, 0x2f, 0x5a, 0x28, 0xd8, 0xca, 0x52, 0xba, 200 | 0xb1, 0x8b, 0xf, 0x5a, 0xd0, 0x81, 0x99, 0x7a, 0x12, 0x2a, 0x99, 0x4d, 0x93, 0xba, 0xf6, 0xcd, 201 | 0x5b, 0x86, 0xb6, 0x9e, 0xa8, 0xe4, 0xa5, 0xa3, 0x34, 0xe1, 0x91, 0x88, 0xe7, 0x9a, 0x98, 0x36, 202 | 0x6a, 0xb4, 0x3d, 0x2a, 0x5c, 0xe3, 0x9a, 0xe6, 0x68, 0xee, 0x8b, 0xd0, 0x96, 0x9a, 0xc2, 0x90, 203 | 0x48, 0x3a, 0x13, 0x4f, 0x3c, 0xd4, 0x96, 0x7f, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 204 | 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 205 | 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 206 | 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 207 | 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 208 | 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 209 | 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 210 | 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 211 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 212 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 213 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 214 | 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 215 | 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 216 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 217 | 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 218 | 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 219 | 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 220 | 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 221 | 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 222 | 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 223 | 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 224 | 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 225 | 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 226 | 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 227 | 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 228 | 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 229 | 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 230 | 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 231 | 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 232 | 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 233 | 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 234 | 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 235 | 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 236 | 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 237 | 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 238 | 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 239 | 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 240 | 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 241 | 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 242 | 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xe6, 0x73, 0x57, 0x74, 0xed, 0x56, 0x7d, 243 | 0x36, 0x6d, 0xd1, 0x9d, 0xd1, 0x9f, 0xbd, 0x19, 0xe8, 0x6a, 0x85, 0x0, 0x6e, 0x60, 0x7, 0x53, 244 | 0x5e, 0x35, 0x8f, 0xd4, 0x2a, 0xc9, 0x49, 0x59, 0x9d, 0x9d, 0xed, 0xe6, 0xa3, 0x73, 0x14, 0x72, 245 | 0x5b, 0x5b, 0x91, 0xb, 0x28, 0x60, 0x77, 0x2, 0x79, 0x1e, 0x95, 0x97, 0xe6, 0x5c, 0x21, 0xcc, 246 | 0xb1, 0xc9, 0x9e, 0xe4, 0x8a, 0xe8, 0x6d, 0xdb, 0x64, 0x68, 0x83, 0xa2, 0x80, 0x2a, 0xd6, 0xc8, 247 | 0xa5, 0xfb, 0xea, 0x33, 0xeb, 0xde, 0x9a, 0x76, 0xd0, 0xf3, 0x63, 0x59, 0x53, 0x56, 0xe5, 0x39, 248 | 0xa8, 0xee, 0xfd, 0xea, 0xdc, 0x77, 0x39, 0xef, 0x5a, 0xd2, 0x69, 0x8b, 0x27, 0x2b, 0xb1, 0xfd, 249 | 0x9c, 0x55, 0x49, 0x34, 0xf8, 0xe3, 0xff, 0x0, 0x59, 0x1, 0x4f, 0x70, 0x78, 0xad, 0x22, 0xc7, 250 | 0xed, 0xa9, 0xc8, 0x44, 0xb8, 0xf4, 0x35, 0xa5, 0x65, 0x76, 0xa, 0xf9, 0x64, 0xfb, 0x8a, 0xcc, 251 | 0x16, 0x51, 0x1f, 0xb9, 0x2b, 0x8f, 0xaf, 0x35, 0x22, 0x5a, 0x4c, 0x8c, 0x19, 0x25, 0x42, 0x47, 252 | 0xaf, 0x15, 0x4d, 0x5d, 0x18, 0xd4, 0x8c, 0x24, 0x8d, 0xc8, 0xee, 0x9e, 0x23, 0xf2, 0x9e, 0x3d, 253 | 0x2b, 0x73, 0x49, 0xba, 0x59, 0x56, 0x43, 0x8c, 0x1e, 0x6, 0xd, 0x73, 0x21, 0x26, 0x64, 0xd, 254 | 0xb3, 0x3f, 0x4e, 0x6b, 0x4b, 0x4f, 0x2d, 0x15, 0xb1, 0x2c, 0x8, 0x25, 0x89, 0xe6, 0xb0, 0xa9, 255 | 0x27, 0x4e, 0x37, 0x3c, 0xda, 0xf4, 0xa2, 0xe3, 0xa1, 0xbd, 0x70, 0xc6, 0x35, 0x2e, 0xf, 0x1e, 256 | 0x95, 0x5a, 0x12, 0x5d, 0xf7, 0x1e, 0xa6, 0xab, 0x45, 0x78, 0xcc, 0xf8, 0x6f, 0x99, 0x2b, 0x46, 257 | 0x28, 0x95, 0xbe, 0x78, 0xfa, 0x77, 0x15, 0x74, 0x63, 0xf6, 0x8e, 0x26, 0xb9, 0x15, 0x99, 0x7e, 258 | 0xd4, 0x74, 0xa4, 0x6b, 0xad, 0xae, 0xc3, 0xaf, 0x35, 0x2d, 0xaa, 0xd6, 0x1c, 0xf7, 0x3f, 0xbe, 259 | 0x93, 0x9f, 0xe2, 0x35, 0xd1, 0x52, 0x7c, 0x91, 0x47, 0x35, 0x38, 0x7b, 0x49, 0xb3, 0x64, 0x5d, 260 | 0x23, 0x77, 0xc1, 0xa1, 0xe4, 0xc, 0xb8, 0x35, 0x80, 0x6e, 0x7d, 0xe9, 0xcb, 0x7a, 0xeb, 0xd0, 261 | 0x93, 0xed, 0x59, 0x2a, 0xe6, 0xdf, 0x56, 0xec, 0x6c, 0x41, 0x26, 0xc9, 0x76, 0x1f, 0xc0, 0xd5, 262 | 0xac, 0xe4, 0xd6, 0x12, 0xdf, 0xa6, 0x41, 0x6f, 0x95, 0x87, 0x35, 0xd1, 0xda, 0xc9, 0x6e, 0xe8, 263 | 0x18, 0x72, 0x7d, 0xeb, 0xb6, 0x8d, 0x5e, 0x65, 0x66, 0x70, 0x57, 0xa0, 0xe1, 0x2b, 0xf7, 0x8, 264 | 0xe3, 0x66, 0xe8, 0x38, 0xab, 0x2b, 0x16, 0x7, 0x26, 0x9e, 0x18, 0x1e, 0x87, 0x34, 0xbd, 0xab, 265 | 0x63, 0x9c, 0x61, 0x18, 0xa8, 0xd8, 0x54, 0xc4, 0x53, 0x18, 0x50, 0x32, 0x2, 0x29, 0x9d, 0x18, 266 | 0x1a, 0x95, 0x85, 0x57, 0x91, 0xf0, 0xf8, 0xf4, 0xaa, 0x5a, 0x8d, 0xb2, 0x71, 0x25, 0x3c, 0x3d, 267 | 0x54, 0xf, 0x4e, 0xf, 0x55, 0x62, 0x2e, 0x4e, 0x40, 0x3c, 0xf7, 0xa0, 0x54, 0x41, 0xe9, 0xc1, 268 | 0xe9, 0x1, 0x3a, 0xd3, 0xcb, 0x5, 0x5c, 0x93, 0xc5, 0x45, 0xe6, 0x2a, 0xae, 0x49, 0xaa, 0xd2, 269 | 0x4c, 0x5c, 0xe4, 0xfe, 0x54, 0x28, 0xb6, 0x4c, 0xa7, 0x62, 0x59, 0x26, 0xdd, 0xec, 0x2a, 0x12, 270 | 0xf5, 0x19, 0x7a, 0x61, 0x7a, 0xd5, 0x44, 0xe7, 0x73, 0x24, 0x2f, 0x4c, 0x2f, 0x50, 0xb4, 0xa0, 271 | 0x54, 0xf, 0x71, 0x8a, 0xd1, 0x40, 0xcd, 0xd4, 0x1f, 0x37, 0xfa, 0xe0, 0xde, 0xa2, 0xa7, 0x86, 272 | 0xa8, 0x2c, 0xdb, 0xa5, 0x2, 0xaf, 0xc3, 0x44, 0xd5, 0x89, 0xa6, 0xee, 0xcb, 0x8b, 0x26, 0xc5, 273 | 0xa6, 0xb4, 0xfe, 0xf5, 0x46, 0x5b, 0x8f, 0x98, 0xe0, 0xf1, 0x50, 0xb4, 0xf5, 0x8d, 0x8e, 0x9e, 274 | 0x62, 0xfb, 0x5c, 0x7b, 0xd3, 0xe1, 0xd4, 0x36, 0x1d, 0xaf, 0xca, 0xfa, 0xfa, 0x56, 0x4b, 0x4d, 275 | 0xef, 0x55, 0x66, 0xbf, 0x8e, 0x2c, 0x82, 0xd9, 0x6f, 0x41, 0x54, 0xa9, 0xf3, 0x68, 0x44, 0xab, 276 | 0x28, 0x6a, 0xd9, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 277 | 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 278 | 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 279 | 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 280 | 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 281 | 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 282 | 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 283 | 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 284 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 285 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 286 | 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 287 | 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 288 | 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 289 | 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 290 | 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 291 | 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 292 | 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 293 | 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 294 | 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 295 | 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 296 | 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 297 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 298 | 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 299 | 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 300 | 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 301 | 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 302 | 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 303 | 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 304 | 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 305 | 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 306 | 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 307 | 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 308 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 309 | 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 310 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 311 | 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 312 | 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 313 | 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 314 | 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 315 | 0x11, 0x0, 0x3f, 0x0, 0xe5, 0xb3, 0x52, 0xda, 0xd, 0xf7, 0x90, 0x8f, 0xf6, 0xc5, 0x2d, 0xd5, 316 | 0x8d, 0xcd, 0x9b, 0x62, 0x78, 0x59, 0x7, 0xaf, 0x6f, 0xce, 0x8b, 0x13, 0x8b, 0xb5, 0x6f, 0x4e, 317 | 0x6b, 0xca, 0xb1, 0xfa, 0x3f, 0x3f, 0x36, 0x88, 0xec, 0x22, 0x96, 0xae, 0xc5, 0x2d, 0x61, 0xc3, 318 | 0x36, 0x6b, 0x42, 0x29, 0x6a, 0x2c, 0x61, 0x52, 0x99, 0xb1, 0x1c, 0x95, 0x72, 0x39, 0x32, 0x30, 319 | 0x79, 0x15, 0x8f, 0x14, 0xb5, 0x72, 0x39, 0x29, 0x1c, 0x33, 0x81, 0x6d, 0xf4, 0xfb, 0x69, 0xf9, 320 | 0xb, 0xe5, 0xb7, 0xaa, 0xff, 0x0, 0x85, 0x57, 0x93, 0x4a, 0xba, 0x8f, 0x98, 0x88, 0x95, 0x7d, 321 | 0xb8, 0x35, 0x66, 0x29, 0x6a, 0xc3, 0x5f, 0x43, 0x6c, 0x9b, 0xe6, 0x95, 0x51, 0x7d, 0xcd, 0x5c, 322 | 0x5b, 0x30, 0x53, 0xa9, 0x17, 0x65, 0xa9, 0x99, 0x6d, 0x3b, 0xc3, 0x2f, 0x95, 0x2a, 0xb2, 0x13, 323 | 0xd9, 0x86, 0x2b, 0x7a, 0x6, 0xfd, 0xca, 0x2f, 0xb5, 0x72, 0x9a, 0xbf, 0x8b, 0xa2, 0x31, 0x98, 324 | 0x6d, 0xad, 0x96, 0x4f, 0xf6, 0xe5, 0x19, 0xfc, 0x85, 0x5e, 0xf0, 0xf7, 0x88, 0x56, 0xf2, 0xdb, 325 | 0xca, 0x9d, 0x57, 0xed, 0x31, 0xf, 0x9b, 0xb6, 0xe1, 0xeb, 0x5b, 0xba, 0x2e, 0x49, 0x39, 0x74, 326 | 0x2b, 0x11, 0x87, 0xac, 0xe9, 0xf3, 0xf2, 0xd8, 0xe9, 0xa3, 0x89, 0xf, 0x54, 0x1f, 0x95, 0x5f, 327 | 0x82, 0x15, 0x52, 0xa, 0xf1, 0x58, 0xe2, 0xfe, 0x26, 0xe0, 0x36, 0xd3, 0xe8, 0x78, 0xa4, 0x79, 328 | 0xc9, 0xe7, 0x75, 0x68, 0xa2, 0x79, 0xae, 0x94, 0xda, 0xb1, 0xd5, 0x44, 0xd1, 0x28, 0xcb, 0x3a, 329 | 0xaf, 0xd4, 0xd7, 0x2c, 0xf6, 0x17, 0x52, 0x4a, 0xcc, 0x36, 0x85, 0x2c, 0x4e, 0x49, 0xaa, 0xcf, 330 | 0x37, 0xbd, 0x6c, 0x5b, 0x4d, 0xe6, 0xda, 0x46, 0xd9, 0xfe, 0x1c, 0x54, 0xd6, 0x82, 0x9a, 0x57, 331 | 0x22, 0x34, 0xe5, 0x43, 0xde, 0x5d, 0x4a, 0x3f, 0x62, 0x31, 0xfd, 0xfd, 0xcc, 0x7f, 0x4a, 0x8d, 332 | 0xce, 0xce, 0x31, 0x8a, 0xd3, 0x66, 0xaa, 0xee, 0xd9, 0xeb, 0xcd, 0x66, 0xa9, 0x25, 0xb1, 0x6a, 333 | 0xa4, 0x9e, 0xe6, 0x54, 0x8f, 0xd0, 0x7a, 0x9a, 0xd4, 0xb4, 0xb9, 0x64, 0x55, 0xc3, 0x62, 0xab, 334 | 0xb4, 0x51, 0x3c, 0x83, 0x28, 0x3f, 0xa, 0x9c, 0x40, 0x8a, 0xdc, 0x12, 0x29, 0x57, 0x8b, 0x8c, 335 | 0x14, 0x90, 0x4d, 0xc6, 0x4a, 0xc6, 0xbc, 0x77, 0x8c, 0x47, 0xa9, 0xf6, 0xa9, 0x93, 0x53, 0x20, 336 | 0xe3, 0x70, 0x3e, 0xcd, 0x59, 0x71, 0x21, 0x1d, 0x1e, 0xa7, 0x7b, 0x71, 0x3a, 0x61, 0xb8, 0x6e, 337 | 0xcc, 0x2b, 0x5a, 0x18, 0x86, 0xf4, 0x91, 0xc7, 0x28, 0x42, 0xfa, 0x9a, 0xe9, 0xa8, 0xc2, 0xdc, 338 | 0x3e, 0x57, 0xf5, 0xa9, 0xd6, 0x44, 0x94, 0x65, 0x1c, 0x37, 0xd2, 0xb8, 0xeb, 0xaf, 0xb5, 0xd8, 339 | 0x37, 0xce, 0x18, 0xa7, 0x66, 0x1c, 0x8a, 0x85, 0x35, 0xa0, 0xa7, 0x9e, 0xf, 0xaa, 0x9a, 0xee, 340 | 0x56, 0x7b, 0xf, 0xea, 0x5c, 0xea, 0xf0, 0x67, 0x6a, 0xfc, 0x2, 0x4f, 0x41, 0x59, 0x46, 0x4d, 341 | 0xcc, 0x5b, 0xd6, 0xab, 0xe9, 0x7a, 0x99, 0xd4, 0x5d, 0xa1, 0xf3, 0x4b, 0x20, 0x5c, 0xb6, 0x47, 342 | 0x23, 0xf1, 0xad, 0x3, 0x4, 0x6b, 0xd1, 0x6a, 0xa3, 0xa1, 0xc9, 0x52, 0x94, 0xa1, 0x2e, 0x56, 343 | 0x40, 0x1e, 0x83, 0x30, 0x5a, 0x73, 0x8c, 0x53, 0x16, 0x25, 0x63, 0x93, 0xcd, 0x37, 0x22, 0x55, 344 | 0x35, 0xd4, 0x68, 0xb9, 0x91, 0xdb, 0x6c, 0x51, 0x64, 0xfb, 0xd3, 0xa6, 0x76, 0xb6, 0x80, 0xcf, 345 | 0x75, 0x36, 0x7, 0x68, 0xe3, 0xe3, 0x71, 0xf4, 0xcd, 0x59, 0x5d, 0xb1, 0xaf, 0x4c, 0x1, 0xe9, 346 | 0x58, 0xfa, 0x91, 0x79, 0x77, 0x4a, 0xff, 0x0, 0x75, 0x47, 0x3, 0xd2, 0xa5, 0x37, 0x26, 0x6b, 347 | 0x8, 0x26, 0xcc, 0xd8, 0xf5, 0xb, 0xa9, 0x6e, 0xa5, 0x93, 0xcc, 0x2a, 0x7b, 0x28, 0x3c, 0x1, 348 | 0xe9, 0x57, 0x53, 0x58, 0x91, 0x78, 0x95, 0x41, 0xac, 0xeb, 0x24, 0xf9, 0xc7, 0xbd, 0x58, 0x96, 349 | 0xa, 0xeb, 0x85, 0xb6, 0x67, 0x36, 0x32, 0x95, 0xa7, 0x78, 0x9a, 0x3, 0x54, 0x85, 0x87, 0xcd, 350 | 0x95, 0xfd, 0x45, 0x6, 0xed, 0x1c, 0x7c, 0xae, 0xf, 0xd0, 0xd6, 0x1b, 0xa3, 0x27, 0x4a, 0x81, 351 | 0x98, 0x8f, 0x63, 0x5b, 0x28, 0x44, 0xf3, 0x64, 0xa4, 0x8d, 0xc9, 0x2e, 0x7d, 0xea, 0xac, 0x97, 352 | 0x5e, 0xf5, 0x92, 0xd7, 0x32, 0xaf, 0xf1, 0xe7, 0xeb, 0x50, 0x3d, 0xd3, 0x13, 0xc8, 0xad, 0xa3, 353 | 0x4, 0x72, 0x55, 0x55, 0x7a, 0x2b, 0x9a, 0x9f, 0x6e, 0xf2, 0xe5, 0x56, 0xcf, 0x43, 0x9a, 0xe9, 354 | 0xc, 0xa2, 0x3b, 0x76, 0x93, 0x3d, 0xb8, 0xae, 0xc, 0xcc, 0xf, 0x7a, 0xd9, 0x9f, 0x5d, 0xb4, 355 | 0xb7, 0xd1, 0xad, 0x8d, 0xc5, 0xc2, 0x21, 0xc6, 0x8, 0xce, 0x49, 0xc7, 0x1d, 0x2a, 0x31, 0x14, 356 | 0xae, 0x93, 0x89, 0x18, 0x5a, 0xce, 0x32, 0x6a, 0xa6, 0x86, 0x8b, 0x4f, 0x55, 0x6e, 0xb5, 0x18, 357 | 0x6d, 0x50, 0xb4, 0xb2, 0x5, 0xf6, 0xae, 0x46, 0xef, 0xc5, 0x92, 0xdc, 0x3f, 0x95, 0x61, 0x9, 358 | 0x5c, 0xf0, 0x1d, 0xfa, 0x9f, 0xa0, 0xa6, 0xdb, 0xd9, 0x49, 0x23, 0x7d, 0xa2, 0xfe, 0x42, 0xed, 359 | 0xd7, 0xc, 0x78, 0x15, 0x30, 0xc3, 0x3d, 0xe4, 0x4d, 0x7c, 0xcd, 0x2d, 0x29, 0x6a, 0xff, 0x0, 360 | 0x3, 0x69, 0xb5, 0x59, 0xaf, 0x73, 0xe4, 0xfe, 0xea, 0xe, 0xf2, 0x1e, 0xa7, 0xe9, 0x4c, 0x53, 361 | 0xe6, 0x9d, 0xab, 0x9d, 0x9e, 0xfd, 0x5b, 0xeb, 0x55, 0x3c, 0xe5, 0x94, 0x81, 0xb9, 0x56, 0x31, 362 | 0xd0, 0x13, 0x57, 0xa0, 0x9e, 0xd2, 0x31, 0xf3, 0xdc, 0xc2, 0xbf, 0x57, 0x15, 0xd1, 0xc9, 0xca, 363 | 0xb4, 0x47, 0x9f, 0x1a, 0xb2, 0xad, 0x2b, 0xce, 0x47, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 364 | 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 365 | 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 366 | 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 367 | 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 368 | 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 369 | 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 370 | 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 371 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 372 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 373 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 374 | 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 375 | 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 376 | 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 377 | 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 378 | 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 379 | 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 380 | 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 381 | 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 382 | 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 383 | 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 384 | 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 385 | 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 386 | 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 387 | 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 388 | 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 389 | 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 390 | 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 391 | 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 392 | 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 393 | 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 394 | 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 395 | 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 396 | 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 397 | 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 398 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 399 | 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 400 | 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 401 | 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 402 | 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xed, 0x23, 0xd3, 0xed, 0xa7, 0x18, 403 | 0x90, 0x92, 0xf, 0x51, 0x50, 0x5d, 0x78, 0x13, 0x4a, 0xba, 0x89, 0x9e, 0xd4, 0xbd, 0xbd, 0xc7, 404 | 0x66, 0x53, 0x91, 0xf8, 0xad, 0x2c, 0x13, 0xb2, 0x91, 0x9e, 0x2b, 0x5e, 0xd6, 0xe7, 0xa7, 0x35, 405 | 0xe7, 0x1f, 0x4f, 0x39, 0x55, 0xa6, 0xef, 0x19, 0x1e, 0x73, 0x7b, 0xa4, 0x5f, 0xe9, 0xe, 0x7c, 406 | 0xf8, 0xf7, 0x45, 0xda, 0x54, 0xe5, 0x7f, 0xfa, 0xd4, 0x90, 0xcd, 0x9a, 0xf4, 0xab, 0xd4, 0xf, 407 | 0x19, 0x90, 0x28, 0x2a, 0x78, 0x61, 0x5c, 0xa5, 0xfe, 0x85, 0x6f, 0x23, 0x19, 0x2d, 0x7f, 0x72, 408 | 0xff, 0x0, 0xdd, 0x1f, 0x74, 0xff, 0x0, 0x85, 0x43, 0x57, 0x3d, 0x1a, 0x18, 0xf5, 0x55, 0x5a, 409 | 0xa2, 0xd4, 0xcf, 0x8a, 0x5a, 0xb8, 0x93, 0x5, 0x19, 0x26, 0xab, 0x25, 0xb2, 0x40, 0x3e, 0x66, 410 | 0xdc, 0xdf, 0xa5, 0x45, 0x34, 0xbc, 0x55, 0xc6, 0x85, 0xf7, 0x35, 0x69, 0x4d, 0xe8, 0x5a, 0x9b, 411 | 0x53, 0x74, 0x18, 0x8b, 0xe5, 0xf7, 0x35, 0x87, 0x79, 0x76, 0xee, 0xc5, 0x9d, 0xcb, 0x1f, 0x52, 412 | 0x68, 0xb9, 0xb8, 0xc6, 0x79, 0xac, 0x89, 0xe6, 0x2e, 0xd8, 0xae, 0xba, 0x74, 0x92, 0xd8, 0xec, 413 | 0xc3, 0xe1, 0xd2, 0xd4, 0x91, 0x18, 0xcf, 0x76, 0x89, 0xef, 0x9a, 0xba, 0x1e, 0x5b, 0x4b, 0x85, 414 | 0x9e, 0x23, 0xb5, 0xd4, 0xd5, 0x7d, 0x22, 0x2d, 0xf7, 0x2e, 0xdd, 0x95, 0x6b, 0x42, 0x68, 0xb3, 415 | 0x9a, 0xdb, 0xc8, 0xd6, 0xa4, 0xd7, 0x37, 0x2f, 0x43, 0x76, 0xd, 0x49, 0x2e, 0xed, 0xc4, 0xa9, 416 | 0xc6, 0x7e, 0xf0, 0xfe, 0xe9, 0xa3, 0xed, 0xf2, 0x45, 0xf7, 0x1c, 0x8f, 0x6e, 0xd5, 0xcc, 0x45, 417 | 0x33, 0xd9, 0xcc, 0x58, 0x7d, 0xc6, 0xfb, 0xc2, 0xa7, 0x9a, 0xf8, 0x63, 0x20, 0x83, 0x58, 0xca, 418 | 0x9d, 0x9e, 0x87, 0x23, 0xc1, 0xae, 0x6d, 0x36, 0x3a, 0x1, 0xae, 0x81, 0xc4, 0xc9, 0xf8, 0xad, 419 | 0x74, 0x7a, 0x6, 0xa5, 0xd, 0xe5, 0xac, 0x89, 0x1c, 0x81, 0x8a, 0x37, 0x4e, 0xe3, 0x3f, 0xe4, 420 | 0xd7, 0x96, 0x3d, 0xd3, 0xcc, 0xdb, 0x53, 0x9a, 0xe8, 0x7c, 0x23, 0x2f, 0x95, 0x7f, 0x2c, 0x25, 421 | 0xbf, 0xd6, 0xc7, 0x9f, 0xc4, 0x7f, 0x93, 0x44, 0xa0, 0xd4, 0x6e, 0x73, 0xe3, 0x70, 0x30, 0x54, 422 | 0x5b, 0xea, 0x7a, 0x2b, 0x35, 0x42, 0xcd, 0x59, 0xa6, 0xee, 0x58, 0x8e, 0x37, 0x64, 0x7a, 0x1a, 423 | 0x5f, 0xed, 0x18, 0xf1, 0xfb, 0xc1, 0xb7, 0xdf, 0xa8, 0xac, 0x13, 0x3c, 0x1f, 0x64, 0xcb, 0x91, 424 | 0x1d, 0xd2, 0x1a, 0xb7, 0x2f, 0x1b, 0xf, 0xa8, 0xaa, 0x16, 0x72, 0x2c, 0x80, 0x32, 0xb0, 0x61, 425 | 0xed, 0x57, 0xee, 0x38, 0x81, 0x1b, 0xd0, 0xe2, 0xae, 0xb4, 0x6f, 0x4e, 0xc4, 0x35, 0xef, 0x58, 426 | 0x72, 0x49, 0x8e, 0xf5, 0x6e, 0x29, 0x6b, 0x31, 0x5a, 0x9d, 0xf6, 0xd8, 0x61, 0x3f, 0x3c, 0x8a, 427 | 0xf, 0xa7, 0x7a, 0xe0, 0x84, 0x66, 0x9d, 0x92, 0x22, 0xa4, 0xd, 0xc4, 0x75, 0x91, 0xa, 0xb8, 428 | 0xc, 0xa7, 0xa8, 0x35, 0x8d, 0xaa, 0x68, 0x2c, 0x55, 0xa6, 0xb2, 0x5f, 0x30, 0x75, 0x31, 0x1e, 429 | 0x4f, 0xe1, 0x42, 0x6a, 0xc9, 0xff, 0x0, 0x2c, 0xd4, 0x9f, 0x73, 0x56, 0xe1, 0xbf, 0x77, 0xea, 430 | 0xd8, 0xfa, 0x57, 0xa7, 0x4a, 0x33, 0x5b, 0xa3, 0x28, 0x46, 0xa4, 0x1f, 0x34, 0x8, 0x7c, 0x36, 431 | 0x90, 0xd9, 0xe9, 0xf2, 0x5c, 0x4a, 0xbe, 0x5c, 0x92, 0xbe, 0x36, 0xe3, 0x9c, 0x2f, 0x1d, 0x3e, 432 | 0xb9, 0xab, 0x93, 0x5c, 0xb4, 0xbc, 0x46, 0x4a, 0xf, 0x5e, 0xf5, 0x89, 0x71, 0x72, 0x4d, 0xe4, 433 | 0xcc, 0x1b, 0x1f, 0x31, 0xef, 0x52, 0xc7, 0x7d, 0x8e, 0xb2, 0x2f, 0xe2, 0x6b, 0xaf, 0x94, 0x89, 434 | 0xc1, 0xce, 0x4e, 0x4f, 0xa9, 0xa4, 0xab, 0x28, 0xff, 0x0, 0x96, 0x9b, 0xbe, 0xb5, 0x66, 0x3f, 435 | 0x34, 0x90, 0x36, 0x64, 0xfb, 0x55, 0x8, 0xaf, 0xe2, 0x38, 0x1b, 0x94, 0xfd, 0xd, 0x6a, 0xdb, 436 | 0x5e, 0x5a, 0xc4, 0xbc, 0xb1, 0x2c, 0x7d, 0xab, 0x36, 0x99, 0x94, 0xe3, 0x25, 0xd0, 0x9b, 0xcb, 437 | 0xda, 0xbc, 0x8e, 0x6b, 0xb, 0xc4, 0x57, 0x11, 0x5b, 0x5b, 0x47, 0x19, 0xc8, 0x69, 0x5b, 0x18, 438 | 0xf6, 0x1f, 0xe4, 0x56, 0xeb, 0x6a, 0x36, 0x9b, 0x4b, 0x19, 0x30, 0x0, 0xc9, 0x24, 0x57, 0x7, 439 | 0xae, 0xf8, 0xab, 0x49, 0xbc, 0xd4, 0xb6, 0xc4, 0xdf, 0x68, 0x8e, 0x21, 0xb4, 0x32, 0x2f, 0x4, 440 | 0xf7, 0xc1, 0xab, 0xa7, 0x16, 0xde, 0xc5, 0x51, 0x8c, 0x9c, 0xb6, 0x34, 0x2c, 0xa5, 0x89, 0xb1, 441 | 0x86, 0xfd, 0x2b, 0x46, 0x65, 0x4c, 0x75, 0xae, 0x6e, 0xd7, 0x5c, 0xb5, 0xe3, 0xca, 0xb3, 0x7f, 442 | 0xc5, 0xf1, 0x57, 0x1b, 0xc4, 0xd1, 0x47, 0x20, 0x49, 0xec, 0xb7, 0x29, 0x19, 0x5, 0x64, 0xc7, 443 | 0xf4, 0xad, 0xe3, 0x4e, 0x6d, 0xe8, 0x8c, 0xf1, 0x92, 0x8c, 0x2d, 0xcc, 0x4f, 0x3b, 0x44, 0x3f, 444 | 0x8b, 0xf4, 0xac, 0xf9, 0xa5, 0x88, 0x67, 0x86, 0x3f, 0x45, 0xad, 0x38, 0xf5, 0xad, 0x1a, 0x7e, 445 | 0xa9, 0x24, 0x47, 0xfd, 0xb5, 0xdd, 0xfc, 0xaa, 0x5c, 0x69, 0xd7, 0x3f, 0xea, 0xae, 0x61, 0x3e, 446 | 0xc4, 0xed, 0x3f, 0xad, 0x74, 0x43, 0x4f, 0x89, 0x1e, 0x35, 0x5a, 0x97, 0xf8, 0xe, 0x4e, 0xe2, 447 | 0xf0, 0x2f, 0xdd, 0x85, 0xcf, 0xd7, 0x8a, 0xcf, 0x92, 0xfe, 0x4e, 0xf1, 0x71, 0xec, 0x6b, 0xb4, 448 | 0x9f, 0x46, 0x57, 0x19, 0x0, 0x11, 0xea, 0x2b, 0x2a, 0xe3, 0x43, 0xeb, 0x85, 0xae, 0xea, 0x52, 449 | 0xa2, 0xf7, 0x3c, 0x3c, 0x44, 0xb1, 0xc9, 0xfb, 0xaf, 0xf0, 0x39, 0x87, 0xbe, 0xcf, 0x58, 0x3, 450 | 0x7f, 0xbe, 0xe4, 0xfe, 0x83, 0x2, 0x96, 0x19, 0x2e, 0x2e, 0x58, 0x24, 0x50, 0xc2, 0x8a, 0x3b, 451 | 0x84, 0xe1, 0x6b, 0x6b, 0xfe, 0x11, 0xa6, 0x76, 0xdc, 0xf9, 0x55, 0xf6, 0xea, 0x69, 0xf2, 0xda, 452 | 0xfd, 0x8a, 0x13, 0x94, 0xb, 0x1a, 0xf7, 0x15, 0xd3, 0xcf, 0x4f, 0x68, 0x1e, 0x7b, 0x8d, 0x79, 453 | 0xeb, 0x59, 0xb2, 0xac, 0x7f, 0xe8, 0x91, 0x17, 0x67, 0x19, 0x3, 0x97, 0x20, 0xa, 0xc6, 0xbe, 454 | 0xd4, 0x26, 0xba, 0x7c, 0x6, 0x65, 0x8c, 0x74, 0x5c, 0xf5, 0xa7, 0xde, 0x5d, 0x35, 0xcb, 0xe3, 455 | 0x91, 0x18, 0xe8, 0x2a, 0xa1, 0x5a, 0xda, 0x14, 0xed, 0xab, 0xdc, 0xe7, 0xa9, 0x55, 0x3f, 0x76, 456 | 0x3b, 0x11, 0x36, 0x4f, 0x52, 0x4d, 0x49, 0x6d, 0x67, 0x2d, 0xed, 0xca, 0x5b, 0xc0, 0xbb, 0xa4, 457 | 0x73, 0x80, 0x28, 0x8, 0x58, 0x80, 0x6, 0x49, 0xed, 0x5d, 0x8e, 0x83, 0x64, 0x9a, 0x74, 0x3e, 458 | 0x63, 0xe0, 0xdc, 0x48, 0x3e, 0x63, 0xfd, 0xd1, 0xe9, 0x4a, 0xb5, 0x4e, 0x48, 0xdd, 0x6e, 0x56, 459 | 0x1e, 0x9f, 0xb5, 0x9d, 0xba, 0x1f, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 460 | 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 461 | 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 462 | 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 463 | 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 464 | 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 465 | 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 466 | 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 467 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 468 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 469 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 470 | 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 471 | 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 472 | 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 473 | 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 474 | 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 475 | 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 476 | 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 477 | 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 478 | 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 479 | 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 480 | 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 481 | 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 482 | 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 483 | 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 484 | 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 485 | 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 486 | 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 487 | 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 488 | 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 489 | 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 490 | 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 491 | 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 492 | 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 493 | 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 494 | 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 495 | 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 496 | 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 497 | 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 498 | 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xe8, 0xed, 0xee, 0x33, 0xc1, 0xad, 0x28, 0x58, 0x7f, 499 | 0x9, 0xc5, 0x73, 0x91, 0x4a, 0xf, 0x2a, 0xc0, 0xfd, 0x2b, 0x46, 0xde, 0xe2, 0xb8, 0x9a, 0xb9, 500 | 0xf6, 0x55, 0x69, 0x5f, 0x63, 0xa3, 0x86, 0x5f, 0x97, 0x6b, 0x8c, 0xa9, 0xe2, 0xb2, 0xef, 0xe3, 501 | 0x36, 0xf2, 0x63, 0xaa, 0x37, 0x2a, 0x6a, 0x7b, 0x7b, 0x8e, 0x95, 0x6e, 0x58, 0xa3, 0xbc, 0xb7, 502 | 0x31, 0x31, 0xc1, 0xfe, 0x13, 0xe8, 0x6a, 0x2c, 0x70, 0xaf, 0xdd, 0xca, 0xef, 0x63, 0x8d, 0xbe, 503 | 0x6d, 0x92, 0x93, 0xd9, 0xb9, 0xac, 0x9b, 0x89, 0xf1, 0x9e, 0x6b, 0x5f, 0x57, 0xb7, 0x9a, 0x4, 504 | 0x70, 0xcb, 0xf3, 0x46, 0x79, 0xc5, 0x72, 0x57, 0x17, 0x4, 0x9e, 0xd, 0x75, 0x53, 0x57, 0x47, 505 | 0xd0, 0xe1, 0x20, 0xa7, 0x1b, 0xa1, 0xb7, 0x13, 0x96, 0x38, 0x15, 0x5a, 0x83, 0xf5, 0xa4, 0x26, 506 | 0xb7, 0xd8, 0xee, 0x9c, 0xd4, 0x55, 0x91, 0xbf, 0xa0, 0xc3, 0xfe, 0x8b, 0x34, 0xbf, 0xde, 0x7d, 507 | 0xbf, 0x97, 0xff, 0x0, 0xae, 0xae, 0xcb, 0x1f, 0xb5, 0x4b, 0xa4, 0x5b, 0xf9, 0x7a, 0x44, 0x1c, 508 | 0x72, 0xc3, 0x77, 0xe7, 0x52, 0x4b, 0x1d, 0x49, 0xe6, 0x7b, 0x4b, 0xcd, 0xb3, 0x1a, 0x78, 0xb3, 509 | 0x59, 0xcf, 0x6e, 0xec, 0xdc, 0x7d, 0xd1, 0x5d, 0x1, 0xb7, 0xde, 0x7d, 0xaa, 0x9, 0xa1, 0xa, 510 | 0x30, 0x7, 0x15, 0x51, 0x67, 0x5c, 0x2b, 0x5b, 0x43, 0x2d, 0x10, 0x22, 0xe0, 0x55, 0xdd, 0x26, 511 | 0x7f, 0xb3, 0xea, 0xb6, 0xd2, 0x67, 0x3, 0x7e, 0xd3, 0xf4, 0x3c, 0x7f, 0x5a, 0xab, 0x2a, 0x6c, 512 | 0x6f, 0x6a, 0x8f, 0x71, 0x7, 0x23, 0xa8, 0xa2, 0x4a, 0xea, 0xc7, 0x2d, 0x79, 0xbd, 0x62, 0xcf, 513 | 0x46, 0x94, 0x86, 0x15, 0x99, 0x74, 0xe5, 0x50, 0xaf, 0x72, 0x71, 0x56, 0x62, 0xb8, 0xf3, 0xed, 514 | 0xe2, 0x97, 0xfb, 0xe8, 0x1a, 0xaa, 0x5d, 0x11, 0x24, 0x88, 0x9e, 0x9c, 0xd7, 0x1c, 0x63, 0xef, 515 | 0x1e, 0x3c, 0x15, 0x99, 0x72, 0xc0, 0x95, 0x20, 0x83, 0x83, 0xed, 0x5b, 0xb3, 0x4b, 0x34, 0x96, 516 | 0xf, 0x1c, 0x72, 0x46, 0xb3, 0x11, 0x94, 0x69, 0x17, 0x23, 0x3e, 0xf8, 0xae, 0x7e, 0x19, 0x5, 517 | 0xb4, 0x7b, 0xdf, 0xb7, 0xeb, 0x4d, 0x3a, 0xa1, 0x27, 0x39, 0xae, 0x98, 0x43, 0x98, 0x99, 0x51, 518 | 0x75, 0x1d, 0xd1, 0xcf, 0xea, 0x9a, 0xde, 0xbf, 0x65, 0x72, 0x60, 0xbe, 0xb, 0x18, 0x3f, 0x74, 519 | 0xa0, 0xf9, 0x18, 0x7b, 0x1a, 0x82, 0xd, 0x6e, 0xe9, 0xbf, 0xe5, 0xa0, 0x1f, 0x45, 0x15, 0xd0, 520 | 0xdc, 0xdc, 0xc3, 0x77, 0xb, 0x43, 0x71, 0x1a, 0xc9, 0x1b, 0x76, 0x6a, 0xe5, 0xef, 0x34, 0xa6, 521 | 0xb6, 0x63, 0x25, 0xa9, 0x32, 0x45, 0xfd, 0xc3, 0xf7, 0x97, 0xfc, 0x6b, 0xd2, 0xa4, 0xe9, 0xda, 522 | 0xd6, 0xb1, 0x94, 0xf0, 0xd2, 0x8e, 0xbb, 0x9b, 0x76, 0xfa, 0xac, 0xed, 0x8c, 0xcc, 0xd5, 0xb1, 523 | 0x6b, 0xa8, 0x39, 0xc6, 0x64, 0x63, 0xf8, 0xd7, 0x13, 0x6d, 0x73, 0x8a, 0xd8, 0xb5, 0xba, 0xc7, 524 | 0x7a, 0x2a, 0x53, 0x44, 0xc5, 0xa2, 0x77, 0xba, 0x2f, 0x73, 0x2b, 0x13, 0x9c, 0xb9, 0x3f, 0xad, 525 | 0x5b, 0x86, 0x7f, 0x7a, 0xe7, 0x63, 0xb8, 0xcb, 0x67, 0x3d, 0x6a, 0xfc, 0x37, 0x1b, 0x71, 0xdc, 526 | 0xd3, 0x70, 0xd0, 0xce, 0x5a, 0x1d, 0x3d, 0xbd, 0xc8, 0x8c, 0x67, 0x3f, 0x35, 0x25, 0xde, 0xbf, 527 | 0xd, 0x94, 0x7b, 0xa4, 0x7c, 0xb7, 0x64, 0x5e, 0xa6, 0xb9, 0xd9, 0x2e, 0xa6, 0xdb, 0x84, 0xe0, 528 | 0xfa, 0xd6, 0x7b, 0xc2, 0xce, 0xc5, 0x9b, 0x2c, 0x4f, 0x52, 0x6a, 0x55, 0x38, 0xf5, 0x14, 0x68, 529 | 0xb9, 0x6b, 0x21, 0x75, 0x9d, 0x7a, 0xff, 0x0, 0x56, 0x6, 0x37, 0x73, 0x15, 0xb7, 0xfc, 0xf2, 530 | 0x43, 0xc1, 0xfa, 0xfa, 0xd5, 0x1b, 0x21, 0x8c, 0x52, 0xde, 0xaf, 0x93, 0x7, 0xbb, 0x1d, 0xa2, 531 | 0x96, 0xc9, 0x78, 0xdc, 0x7a, 0x56, 0xf1, 0x8a, 0xe5, 0xb2, 0x2e, 0xa4, 0xe3, 0x49, 0x7a, 0x1b, 532 | 0xd6, 0xb2, 0x6d, 0x0, 0x54, 0xba, 0x93, 0xe2, 0x8, 0xa5, 0x1d, 0x8e, 0xd3, 0x54, 0x61, 0x7c, 533 | 0x35, 0x5b, 0xba, 0xfd, 0xf6, 0x9b, 0x32, 0x8e, 0xa1, 0x77, 0xf, 0xc3, 0x9a, 0xd6, 0xb, 0x96, 534 | 0xc7, 0xcc, 0xe3, 0x24, 0xea, 0xc9, 0xc9, 0x95, 0xe2, 0xbb, 0xf7, 0xab, 0x91, 0xdd, 0x67, 0xbd, 535 | 0x73, 0x11, 0x5d, 0x7b, 0xd6, 0xad, 0x8a, 0x4b, 0x72, 0xdf, 0x2f, 0xca, 0x9d, 0xd8, 0xd6, 0xf2, 536 | 0x49, 0x6e, 0x79, 0xbc, 0xb7, 0x3a, 0xb, 0x6b, 0x99, 0x77, 0x81, 0xb, 0x38, 0x63, 0xfd, 0xd3, 537 | 0x8a, 0xde, 0xb5, 0xb8, 0xb8, 0x8d, 0x47, 0x9b, 0x2e, 0xf6, 0xf4, 0x6e, 0x71, 0x58, 0xb6, 0xa1, 538 | 0x2d, 0xd7, 0x9, 0xf8, 0x93, 0xd4, 0xd5, 0xa3, 0x76, 0xb1, 0x21, 0x77, 0x6c, 0x1, 0x5c, 0xd3, 539 | 0xd4, 0xd1, 0x42, 0xc6, 0xd9, 0xbf, 0x50, 0x85, 0xa5, 0x45, 0xc0, 0xef, 0x54, 0x27, 0x9e, 0xde, 540 | 0xef, 0xaa, 0x95, 0x1d, 0x85, 0x64, 0x3d, 0xd4, 0xb7, 0x2d, 0xc2, 0x90, 0xbd, 0x85, 0x58, 0x8a, 541 | 0x29, 0x1b, 0xda, 0x88, 0xc5, 0x47, 0x53, 0x39, 0xd2, 0x75, 0x34, 0xb6, 0x84, 0x57, 0x5a, 0x15, 542 | 0xb5, 0xc6, 0x5a, 0x26, 0xd8, 0xfe, 0xa2, 0xb0, 0xaf, 0x34, 0xab, 0x9b, 0x3c, 0x97, 0x4d, 0xc9, 543 | 0xfd, 0xf5, 0xe4, 0x57, 0x63, 0xd, 0xb9, 0xc6, 0x59, 0xb8, 0xac, 0x2d, 0x73, 0x5d, 0x9, 0x1b, 544 | 0xdb, 0xd9, 0x9e, 0x31, 0x87, 0x97, 0xd7, 0xe9, 0x5d, 0x54, 0x31, 0x13, 0x6e, 0xcb, 0x53, 0xcb, 545 | 0xc5, 0x65, 0xd4, 0xa3, 0x1e, 0x67, 0xa3, 0x32, 0xac, 0x55, 0x23, 0x7f, 0x35, 0xb9, 0x61, 0xf7, 546 | 0x7d, 0xab, 0x66, 0xb, 0xa2, 0xcc, 0x14, 0x1e, 0x49, 0xc5, 0x72, 0x76, 0x77, 0x6c, 0xf1, 0x80, 547 | 0x4f, 0xcc, 0xb5, 0xb1, 0xa6, 0x4c, 0x5e, 0xed, 0x7, 0x65, 0xe6, 0xba, 0xea, 0x2b, 0xab, 0xb3, 548 | 0xc7, 0xa6, 0xe5, 0x9, 0x72, 0xa3, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 549 | 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 550 | 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 551 | 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 552 | 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 553 | 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 554 | 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 555 | 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 556 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 557 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 558 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 559 | 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 560 | 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 561 | 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 562 | 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 563 | 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 564 | 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 565 | 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 566 | 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 567 | 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 568 | 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 569 | 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 570 | 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 571 | 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 572 | 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 573 | 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 574 | 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 575 | 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 576 | 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 577 | 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 578 | 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 579 | 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 580 | 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 581 | 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 582 | 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 583 | 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 584 | 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 585 | 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 586 | 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 587 | 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xaf, 0x1c, 0x95, 0x6e, 0x2b, 0x99, 0x14, 0xf0, 0xe6, 588 | 0xb2, 0xa3, 0x92, 0xad, 0x23, 0xd7, 0x2, 0x67, 0xe8, 0x8d, 0x23, 0xa0, 0xb4, 0xd4, 0x5f, 0x8c, 589 | 0xe0, 0xd6, 0xd5, 0xb6, 0xa1, 0x9c, 0x64, 0x57, 0x1b, 0x1c, 0x98, 0x35, 0xa3, 0x6f, 0x7a, 0xab, 590 | 0xf7, 0x9c, 0xf, 0xa9, 0xaa, 0xb3, 0x7b, 0x1c, 0x75, 0xf0, 0xf1, 0x96, 0xa8, 0xe8, 0xf5, 0x48, 591 | 0x92, 0xf2, 0xd8, 0xca, 0x9f, 0xeb, 0x14, 0x72, 0x3f, 0xbc, 0x2b, 0xce, 0x6e, 0x21, 0x81, 0xe5, 592 | 0x75, 0xdc, 0x37, 0x3, 0xd4, 0x1a, 0xed, 0xa1, 0xd6, 0x2d, 0x23, 0xfb, 0xd7, 0x31, 0xf, 0xf8, 593 | 0x15, 0x73, 0x1a, 0xd5, 0x84, 0x17, 0xfa, 0x9f, 0x99, 0xa6, 0x4a, 0x8c, 0x24, 0x19, 0x74, 0x27, 594 | 0x1b, 0x4d, 0x6d, 0x47, 0x99, 0x6e, 0x8a, 0xc1, 0x39, 0x52, 0xbc, 0x1e, 0xc6, 0x24, 0xb6, 0x92, 595 | 0x27, 0x2b, 0xf3, 0xf, 0x6a, 0xae, 0x14, 0xb3, 0x84, 0x3, 0xe6, 0x27, 0x18, 0xad, 0xf8, 0x7c, 596 | 0x39, 0x38, 0xff, 0x0, 0x59, 0x78, 0xa9, 0xec, 0x80, 0x9f, 0xf0, 0xab, 0xf6, 0xfa, 0x3d, 0xa4, 597 | 0x33, 0x47, 0x24, 0x8f, 0x24, 0xae, 0x8c, 0x18, 0x16, 0xc0, 0xe9, 0xf4, 0xad, 0x79, 0x91, 0xbd, 598 | 0x4a, 0xda, 0x77, 0x36, 0x56, 0x1, 0xc, 0x9, 0x10, 0xe8, 0x8a, 0x14, 0x7e, 0x15, 0x11, 0x83, 599 | 0x77, 0x27, 0xa5, 0x5e, 0xdd, 0x1b, 0x72, 0xdf, 0x95, 0x35, 0xca, 0x1e, 0x86, 0xb5, 0x70, 0x67, 600 | 0x98, 0xab, 0xab, 0x99, 0xd2, 0x47, 0x8a, 0xa7, 0x2c, 0x79, 0x15, 0xab, 0x22, 0xe6, 0xa9, 0xcb, 601 | 0x1d, 0x67, 0x66, 0x8e, 0xba, 0x55, 0x53, 0xd9, 0x98, 0xb7, 0x10, 0xe7, 0x35, 0x99, 0x22, 0x94, 602 | 0x6c, 0x1a, 0xdf, 0x9a, 0x3c, 0xd6, 0x65, 0xcc, 0x1b, 0x81, 0xab, 0x4e, 0xe7, 0x4d, 0x48, 0x7b, 603 | 0x58, 0x69, 0xb9, 0xbb, 0xa2, 0xdc, 0x79, 0x9a, 0x52, 0x2e, 0x79, 0x8c, 0x95, 0xff, 0x0, 0x3f, 604 | 0x9d, 0x3c, 0x49, 0xba, 0xe9, 0xce, 0x78, 0x5e, 0x2b, 0x23, 0x42, 0x9f, 0xcb, 0x17, 0x31, 0x3f, 605 | 0x18, 0xf9, 0xff, 0x0, 0xc7, 0xfa, 0x52, 0x4f, 0x7b, 0xb5, 0x76, 0x3, 0xf3, 0x37, 0x2c, 0x6a, 606 | 0x29, 0xd1, 0x73, 0xa8, 0xd2, 0x3c, 0x8b, 0xf2, 0xa7, 0x29, 0x1a, 0x37, 0x57, 0x82, 0x63, 0xb4, 607 | 0x1c, 0x2a, 0xfd, 0xda, 0xa0, 0xd7, 0x25, 0x4e, 0xd, 0x54, 0xfb, 0x45, 0x31, 0xe4, 0xf3, 0x6, 608 | 0x3b, 0xf6, 0xaf, 0x52, 0x34, 0x52, 0x56, 0x32, 0x55, 0xec, 0x5c, 0xfb, 0x5d, 0x1f, 0x6b, 0xac, 609 | 0xa6, 0x33, 0x2b, 0x60, 0xa3, 0xf, 0xad, 0x31, 0xa6, 0x65, 0xeb, 0x55, 0xec, 0x86, 0xf1, 0x9, 610 | 0x75, 0x2f, 0xce, 0xb1, 0xca, 0xdb, 0xc7, 0xca, 0xfe, 0xa3, 0xbd, 0x31, 0x26, 0x68, 0x95, 0xb7, 611 | 0x76, 0x15, 0x95, 0x25, 0xfb, 0x2f, 0xdd, 0x1c, 0xd4, 0x46, 0xee, 0xe0, 0xf2, 0xcd, 0x81, 0xfd, 612 | 0xdc, 0x56, 0xaa, 0x94, 0xac, 0x73, 0x4e, 0xb4, 0x24, 0xee, 0x8d, 0xfd, 0x2f, 0x4f, 0xbb, 0xbf, 613 | 0x1, 0xd1, 0xa, 0xc5, 0xff, 0x0, 0x3d, 0x1b, 0xa7, 0xe1, 0xeb, 0x5d, 0x1c, 0x3a, 0x5a, 0x40, 614 | 0xb8, 0x3, 0x27, 0xbb, 0x1a, 0xc1, 0xb4, 0xd6, 0xf5, 0x19, 0x2d, 0xd1, 0xa2, 0xb9, 0xc2, 0x8e, 615 | 0x36, 0xec, 0x5e, 0x3d, 0xba, 0x55, 0x81, 0xad, 0xea, 0x83, 0xac, 0x88, 0xdf, 0x58, 0xc5, 0x61, 616 | 0x38, 0x4d, 0xb2, 0x63, 0x56, 0x1b, 0x9b, 0x6, 0xcf, 0xda, 0x98, 0x6c, 0xfd, 0xab, 0x21, 0xfc, 617 | 0x4f, 0x77, 0x0, 0xcc, 0xbf, 0x66, 0xff, 0x0, 0x81, 0x2f, 0xff, 0x0, 0x5e, 0xaa, 0x49, 0xe3, 618 | 0xb7, 0x4e, 0x16, 0xd2, 0x39, 0xf, 0xb6, 0x54, 0x54, 0x2a, 0x35, 0xa, 0x78, 0x9a, 0x6b, 0x76, 619 | 0x26, 0xb6, 0x37, 0x6a, 0x11, 0xdb, 0x2f, 0x48, 0xd7, 0x73, 0x7e, 0x34, 0xb1, 0x10, 0xaa, 0x0, 620 | 0xe9, 0x59, 0xf, 0xaa, 0xc9, 0x7b, 0x79, 0x2c, 0xee, 0x8b, 0x13, 0x48, 0xd9, 0xf5, 0xc5, 0x68, 621 | 0xc1, 0x14, 0xb2, 0x0, 0x7c, 0xcc, 0x83, 0xe9, 0x5d, 0x7c, 0xae, 0x11, 0x49, 0x9c, 0x53, 0x7f, 622 | 0x58, 0x77, 0x8b, 0x34, 0x63, 0x6a, 0xbd, 0x4, 0xe8, 0x6, 0x19, 0x87, 0xe3, 0x54, 0xa0, 0xb0, 623 | 0x2e, 0x46, 0xe6, 0x27, 0xeb, 0x5a, 0x7f, 0x62, 0x4b, 0x4b, 0x7f, 0x31, 0xb1, 0xbd, 0xb8, 0x41, 624 | 0xfd, 0x6b, 0x27, 0x55, 0x5e, 0xc8, 0xca, 0x58, 0x5, 0x6b, 0xc9, 0x98, 0x16, 0x3a, 0x46, 0xfb, 625 | 0xa7, 0xf3, 0xa4, 0x40, 0x8a, 0xe4, 0x2a, 0x96, 0xc6, 0xe1, 0x9a, 0xea, 0xad, 0xec, 0x48, 0x55, 626 | 0x1b, 0xc0, 0x51, 0xd0, 0x28, 0xac, 0x63, 0x0, 0x12, 0x67, 0xd6, 0xac, 0x87, 0x5b, 0x58, 0xfc, 627 | 0xc2, 0xe5, 0x47, 0xb1, 0xeb, 0x55, 0x3a, 0x92, 0x91, 0xc0, 0xb0, 0xb0, 0x8b, 0xb1, 0xbc, 0xb6, 628 | 0xf1, 0x42, 0x9b, 0xdf, 0x38, 0x1e, 0xb5, 0x9, 0x53, 0x3b, 0xe7, 0x6e, 0x14, 0x74, 0x2, 0xb9, 629 | 0xff, 0x0, 0xed, 0x1b, 0xd9, 0xa5, 0xdd, 0xe7, 0x10, 0xbd, 0x94, 0xf3, 0x8a, 0xd4, 0xb5, 0xd4, 630 | 0xae, 0x57, 0x1, 0xd2, 0x37, 0xfc, 0x31, 0x51, 0x66, 0xb7, 0x2d, 0xd2, 0x6b, 0xe1, 0x46, 0xc4, 631 | 0x16, 0xde, 0xd5, 0xa0, 0x90, 0xa4, 0x48, 0x5e, 0x42, 0x15, 0x17, 0xa9, 0x35, 0x94, 0x75, 0xeb, 632 | 0x6b, 0x1b, 0x49, 0x6e, 0x6e, 0xe1, 0x64, 0x8a, 0x25, 0xdc, 0xc5, 0x4e, 0x6a, 0xb, 0x9d, 0x5e, 633 | 0x3d, 0x4e, 0xda, 0x39, 0xed, 0xe4, 0xd, 0x6e, 0xe3, 0x72, 0x63, 0xa7, 0xff, 0x0, 0xae, 0xaa, 634 | 0x10, 0x73, 0x67, 0x9b, 0x8a, 0xab, 0x2a, 0x2b, 0x54, 0x37, 0x57, 0xd5, 0x9a, 0x65, 0x68, 0x61, 635 | 0xf9, 0x21, 0xef, 0xea, 0xdf, 0x5a, 0xe4, 0xaf, 0x65, 0xf9, 0x1f, 0xe9, 0x5a, 0x17, 0x72, 0xf5, 636 | 0xac, 0x4b, 0xb9, 0x32, 0x8, 0xaf, 0x4a, 0x94, 0x14, 0x55, 0x91, 0xe0, 0x56, 0xa8, 0xe6, 0xee, 637 | 0xc6, 0x5b, 0x1c, 0x35, 0x74, 0x3a, 0x37, 0x59, 0x5c, 0xf6, 0xf9, 0x6b, 0x9e, 0xb7, 0xea, 0x2b, 638 | 0xaa, 0xb2, 0x80, 0xa6, 0x9c, 0x92, 0x28, 0xe4, 0xfc, 0xcd, 0x57, 0x59, 0xda, 0x27, 0x35, 0x18, 639 | 0x73, 0x4e, 0xe7, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 640 | 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 641 | 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 642 | 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 643 | 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 644 | 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 645 | 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 646 | 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 647 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 648 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 649 | 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 650 | 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 651 | 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 652 | 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 653 | 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 654 | 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 655 | 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 656 | 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 657 | 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 658 | 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 659 | 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 660 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 661 | 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 662 | 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 663 | 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 664 | 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 665 | 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 666 | 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 667 | 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 668 | 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 669 | 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 670 | 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 671 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 672 | 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 673 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 674 | 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 675 | 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 676 | 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 677 | 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 678 | 0x11, 0x0, 0x3f, 0x0, 0xe6, 0xc5, 0xcb, 0xff, 0x0, 0x7a, 0x9e, 0x2e, 0x24, 0xfe, 0xfb, 0x7e, 679 | 0x75, 0x9a, 0x25, 0x65, 0xeb, 0xcd, 0x48, 0xb3, 0xa9, 0xef, 0x8f, 0xad, 0x6f, 0xec, 0x94, 0x7a, 680 | 0x1f, 0x61, 0x1c, 0x4d, 0xf7, 0x65, 0xff, 0x0, 0x39, 0x8f, 0x56, 0x27, 0xf1, 0xa7, 0x9, 0x2a, 681 | 0x98, 0x7a, 0x78, 0x7a, 0xa5, 0x64, 0x6f, 0x1a, 0xc5, 0xd0, 0xf5, 0x34, 0x37, 0x2f, 0xc, 0x8a, 682 | 0xea, 0x7e, 0x65, 0x39, 0xac, 0xf0, 0xf5, 0x2a, 0x33, 0x31, 0xc0, 0xe4, 0xd5, 0x5d, 0x58, 0xdd, 683 | 0x55, 0x56, 0x3a, 0xa8, 0xef, 0x4, 0xd1, 0xab, 0xaf, 0xf1, 0x76, 0xa9, 0x55, 0xf6, 0xf2, 0xdd, 684 | 0x6b, 0x12, 0xce, 0x5f, 0xb3, 0x82, 0x9, 0xce, 0x6a, 0x67, 0xbc, 0xf7, 0xae, 0x29, 0x53, 0xb4, 685 | 0xb4, 0x2a, 0x30, 0x53, 0x5e, 0xe9, 0xa8, 0x6f, 0xbd, 0xe9, 0xd, 0xf7, 0xbd, 0x73, 0xcf, 0x72, 686 | 0xfb, 0x9b, 0x9e, 0xf4, 0xcf, 0xb4, 0x3f, 0xad, 0x7a, 0x91, 0xa7, 0x74, 0x79, 0x52, 0xa4, 0x93, 687 | 0xb1, 0xd1, 0x1b, 0xef, 0x7a, 0x69, 0xbe, 0xf5, 0x35, 0xcf, 0x7d, 0xa1, 0xfd, 0x69, 0x3c, 0xe6, 688 | 0xfe, 0xf5, 0x3f, 0x64, 0x84, 0xa0, 0x8d, 0xe6, 0xbb, 0x46, 0x1c, 0xe2, 0xa0, 0x91, 0xe1, 0x7f, 689 | 0x6f, 0xa5, 0x67, 0x5b, 0x43, 0x71, 0x79, 0x26, 0xc8, 0x54, 0xb7, 0xa9, 0xec, 0x2b, 0x7e, 0xd7, 690 | 0x4b, 0x86, 0xd0, 0x7, 0x99, 0xbc, 0xd9, 0x7d, 0xfa, 0xa, 0xce, 0x70, 0xa7, 0x1d, 0xcd, 0xa1, 691 | 0x29, 0x47, 0xe1, 0x65, 0x2b, 0x5d, 0x2e, 0x59, 0x65, 0xdf, 0x1c, 0x82, 0x30, 0xea, 0x53, 0x73, 692 | 0x8e, 0xd5, 0x67, 0xfe, 0x11, 0xc8, 0x23, 0xe6, 0x6b, 0xa9, 0x24, 0x3f, 0xec, 0x80, 0xbf, 0xe3, 693 | 0x56, 0x65, 0x9c, 0xe7, 0x83, 0x4c, 0x96, 0xef, 0x72, 0xe7, 0x35, 0x34, 0xee, 0x9f, 0xba, 0x73, 694 | 0x62, 0xa4, 0xdf, 0xbc, 0xc8, 0xd, 0x8d, 0x94, 0x3f, 0x76, 0x1d, 0xc7, 0xd5, 0x89, 0x35, 0x4, 695 | 0x92, 0xa2, 0xc, 0x22, 0xaa, 0x8f, 0x61, 0x8a, 0x64, 0xf7, 0x38, 0xcf, 0x35, 0x99, 0x3d, 0xe2, 696 | 0x8e, 0xf9, 0xae, 0x98, 0xc5, 0xbd, 0xcf, 0x3a, 0x73, 0xb1, 0x25, 0xd4, 0x82, 0x45, 0x20, 0x9e, 697 | 0x7d, 0x6b, 0x12, 0x56, 0x90, 0xc9, 0xb0, 0xc, 0xb5, 0x5b, 0x12, 0x3c, 0xe7, 0x8e, 0x17, 0xd6, 698 | 0x96, 0x5d, 0x8b, 0x16, 0xde, 0x87, 0xd6, 0xb6, 0x4d, 0x44, 0x88, 0xae, 0x6d, 0x5e, 0xc5, 0x2f, 699 | 0x2d, 0x21, 0x19, 0x63, 0x97, 0xa8, 0x24, 0x99, 0x7e, 0xb4, 0xd1, 0x1d, 0xcd, 0xcd, 0xd0, 0x82, 700 | 0x28, 0xda, 0x49, 0x5b, 0xa0, 0x5a, 0xeb, 0xf4, 0x7f, 0xe, 0x43, 0xa7, 0xe2, 0xe2, 0xef, 0x6c, 701 | 0xd7, 0x3d, 0x40, 0xfe, 0x14, 0xfa, 0x7a, 0x9f, 0x7a, 0xd1, 0x3e, 0xe6, 0x38, 0x9c, 0x4c, 0x29, 702 | 0x47, 0x43, 0x2e, 0xca, 0xce, 0xfa, 0xc3, 0x4c, 0x9f, 0x50, 0x91, 0x42, 0x21, 0x3, 0x6c, 0x4e, 703 | 0x39, 0x3c, 0xfd, 0xef, 0x6a, 0xcc, 0x9f, 0x54, 0xba, 0x9b, 0x39, 0x97, 0x68, 0xf4, 0x5e, 0x2b, 704 | 0xb6, 0xd4, 0xff, 0x0, 0x7f, 0x61, 0x71, 0x1f, 0x52, 0xd1, 0xb6, 0x3e, 0xb8, 0xaf, 0x3b, 0x6a, 705 | 0x1a, 0x57, 0xb9, 0xc5, 0x86, 0xaf, 0x3a, 0x89, 0xf3, 0x3, 0x39, 0x27, 0x24, 0xf3, 0x44, 0x4b, 706 | 0xbd, 0xf3, 0xd8, 0x54, 0x47, 0xaf, 0x4a, 0xd0, 0xb7, 0x87, 0x62, 0x1, 0xdf, 0xbd, 0x34, 0x55, 707 | 0x57, 0x64, 0x3a, 0x34, 0xad, 0xb, 0x59, 0x64, 0x81, 0x81, 0x8d, 0xf1, 0xed, 0xda, 0xa0, 0x8d, 708 | 0x3d, 0xaa, 0xec, 0x10, 0xef, 0x6e, 0x78, 0x5e, 0xe6, 0x89, 0x6b, 0xb9, 0x82, 0x93, 0x4f, 0xdd, 709 | 0x3a, 0x4d, 0x22, 0xfe, 0x39, 0x79, 0xb9, 0x4f, 0x2d, 0x57, 0xab, 0x8e, 0x95, 0x3d, 0xdd, 0xcf, 710 | 0xda, 0xae, 0xb, 0xaf, 0xfa, 0xb1, 0xf2, 0xa7, 0xd2, 0xb0, 0x9c, 0x96, 0x50, 0x8b, 0xf2, 0xc6, 711 | 0x3a, 0x1, 0x56, 0x6d, 0xae, 0x52, 0x18, 0xb6, 0xc8, 0x79, 0x1f, 0x77, 0xde, 0xb9, 0x1d, 0x34, 712 | 0x9d, 0xd1, 0xd7, 0xed, 0xa6, 0xd7, 0xbc, 0xcb, 0x77, 0x12, 0xa4, 0x10, 0xf9, 0x8e, 0x78, 0x1f, 713 | 0xad, 0x64, 0xc9, 0x72, 0xf7, 0x32, 0x6e, 0x6e, 0x0, 0xfb, 0xa3, 0xd2, 0x9d, 0x71, 0x33, 0x5c, 714 | 0x64, 0xb7, 0xe0, 0x3d, 0x2a, 0x28, 0x96, 0xb4, 0x84, 0xc, 0xa7, 0x52, 0xcc, 0xb9, 0xd, 0x69, 715 | 0xdb, 0xf6, 0xac, 0xf8, 0x56, 0xae, 0x99, 0x56, 0xda, 0xdd, 0xe6, 0x7e, 0x88, 0x33, 0xf5, 0xa6, 716 | 0xe2, 0x62, 0xeb, 0xd8, 0xc5, 0xf1, 0x7d, 0xfb, 0x48, 0x91, 0xe9, 0xd1, 0x9f, 0x97, 0x87, 0x97, 717 | 0x1f, 0xa0, 0xfe, 0xbf, 0x95, 0x64, 0xe8, 0xda, 0x8c, 0xda, 0x69, 0x31, 0xe4, 0xb5, 0xbb, 0xfd, 718 | 0xe4, 0xf4, 0x3e, 0xa2, 0x9d, 0x2a, 0xbd, 0xcc, 0xef, 0x34, 0x9c, 0xbb, 0xb6, 0xe3, 0x4a, 0xb6, 719 | 0xde, 0xd5, 0xd1, 0x8, 0x72, 0xab, 0x1c, 0x35, 0xaa, 0x2a, 0xb7, 0x52, 0x35, 0x67, 0xbc, 0x57, 720 | 0x1b, 0x81, 0xc8, 0x35, 0x97, 0x34, 0xc1, 0xe4, 0xa7, 0xb5, 0xbb, 0xf9, 0x44, 0x27, 0x5f, 0x4a, 721 | 0xcb, 0xf3, 0xf, 0x98, 0x41, 0xe0, 0x8e, 0xb5, 0xd7, 0xd, 0x4f, 0xe, 0xb5, 0x1e, 0x57, 0x63, 722 | 0x66, 0xd7, 0xe6, 0x70, 0x7, 0x53, 0x5d, 0xf5, 0x9a, 0x4, 0x8d, 0x23, 0xea, 0x2, 0xe2, 0xb8, 723 | 0xd, 0x23, 0xf7, 0xb7, 0xf0, 0xaf, 0x60, 0x77, 0x7e, 0x55, 0xd9, 0xbe, 0xa3, 0x15, 0x95, 0xb3, 724 | 0xcd, 0x34, 0xa9, 0x18, 0x51, 0xd5, 0x8e, 0x2b, 0x1c, 0x46, 0xb6, 0x44, 0xe1, 0xa1, 0x66, 0xd9, 725 | 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 726 | 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 727 | 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 728 | 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 729 | 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 730 | 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 731 | 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 732 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 733 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 734 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 735 | 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 736 | 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 737 | 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 738 | 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 739 | 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 740 | 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 741 | 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 742 | 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 743 | 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 744 | 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 745 | 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 746 | 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 747 | 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 748 | 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 749 | 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 750 | 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 751 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 752 | 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 753 | 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 754 | 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 755 | 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 756 | 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 757 | 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 758 | 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 759 | 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 760 | 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 761 | 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 762 | 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 763 | 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 764 | 0x0, 0xe3, 0x19, 0x6a, 0x36, 0x5a, 0xbd, 0x2c, 0x35, 0x5d, 0x97, 0x1c, 0x57, 0xa2, 0x7d, 0x2c, 765 | 0xa1, 0x72, 0xb8, 0x67, 0x4f, 0xba, 0x7f, 0xa, 0x91, 0x6e, 0xb1, 0xf7, 0xc7, 0xe2, 0x29, 0x19, 766 | 0x68, 0x48, 0xc, 0xa7, 0xd0, 0x77, 0x35, 0x2e, 0x29, 0x99, 0x73, 0x4a, 0x1b, 0x16, 0xa1, 0x7f, 767 | 0x38, 0xe1, 0xe, 0x6b, 0x46, 0x20, 0xb1, 0xae, 0x7, 0x5f, 0x5a, 0xcd, 0x58, 0x84, 0x63, 0xb, 768 | 0xc5, 0x48, 0xb3, 0xba, 0x75, 0x3b, 0x87, 0xbd, 0x66, 0xe1, 0xd8, 0xa5, 0x8b, 0x7d, 0x4d, 0x40, 769 | 0xf4, 0xb9, 0xaa, 0x9, 0x74, 0x87, 0xaf, 0xca, 0x7d, 0xea, 0xc2, 0xc9, 0x9e, 0x73, 0x91, 0xed, 770 | 0x59, 0x49, 0x33, 0xbb, 0xd, 0x8b, 0x51, 0x96, 0x8f, 0x42, 0x39, 0x5f, 0x6c, 0x8c, 0x29, 0x9e, 771 | 0x65, 0x36, 0xe9, 0xb1, 0x37, 0xd4, 0x55, 0xdd, 0x37, 0x45, 0xbb, 0xd4, 0x30, 0xf8, 0x31, 0x43, 772 | 0xff, 0x0, 0x3d, 0x18, 0x75, 0xfa, 0xe, 0xf5, 0xdd, 0x9, 0x25, 0x4, 0xd9, 0xc9, 0x56, 0x6e, 773 | 0x55, 0x64, 0xa3, 0xdc, 0xaa, 0x85, 0x9d, 0xc2, 0x20, 0x2c, 0xc7, 0xa2, 0x81, 0x92, 0x6b, 0x7f, 774 | 0x4f, 0xf0, 0xf3, 0xbe, 0x24, 0xbd, 0x3b, 0x47, 0xfc, 0xf3, 0x5e, 0xbf, 0x89, 0xad, 0x7b, 0x1d, 775 | 0x2e, 0xd7, 0x4f, 0x4f, 0xdd, 0x26, 0x5f, 0xbc, 0x8d, 0xd4, 0xd4, 0xf2, 0xca, 0x10, 0x75, 0xac, 776 | 0x67, 0x59, 0xbd, 0x22, 0x6f, 0xa, 0x56, 0xd6, 0x42, 0x1, 0x15, 0xb4, 0x42, 0x38, 0x90, 0x22, 777 | 0x8e, 0xc2, 0xaa, 0x4d, 0x37, 0xbd, 0x41, 0x73, 0x7c, 0x8b, 0x9c, 0x1c, 0xd6, 0x45, 0xc5, 0xf3, 778 | 0xbf, 0x4f, 0xd2, 0xb3, 0x49, 0x95, 0x29, 0xa4, 0x5e, 0x9e, 0xe9, 0x17, 0xbd, 0x66, 0xcd, 0xa8, 779 | 0xe0, 0x10, 0x2a, 0x9c, 0x8f, 0x3c, 0x87, 0xe5, 0x8d, 0xcf, 0xe1, 0x50, 0x35, 0x9d, 0xec, 0xa3, 780 | 0xe5, 0x84, 0xfe, 0x24, 0xa, 0xd6, 0x9e, 0x8c, 0xe2, 0xaf, 0x3e, 0x68, 0xb4, 0x13, 0xde, 0x96, 781 | 0xee, 0x69, 0x91, 0xc4, 0xce, 0x77, 0xcb, 0xc0, 0xfe, 0xed, 0x2c, 0x56, 0xbe, 0x4b, 0x66, 0x4e, 782 | 0x64, 0xf7, 0xed, 0x52, 0xb3, 0x5, 0x4, 0x9e, 0x95, 0xd2, 0xe7, 0xd1, 0x1c, 0x11, 0xa7, 0xd6, 783 | 0x42, 0xb3, 0x84, 0x5f, 0x40, 0x3b, 0x53, 0xf4, 0xfd, 0x36, 0xeb, 0x57, 0x9b, 0x11, 0x8d, 0xb1, 784 | 0xf, 0xbd, 0x21, 0xe8, 0xbf, 0xe2, 0x6a, 0xe6, 0x9d, 0xa1, 0xbd, 0xe3, 0x9, 0xef, 0x33, 0x1c, 785 | 0x1d, 0x55, 0x3a, 0x16, 0xff, 0x0, 0xa, 0xea, 0x23, 0x31, 0xc1, 0x10, 0x8e, 0x24, 0x54, 0x45, 786 | 0xe0, 0x28, 0xe9, 0x41, 0x8d, 0x6a, 0xf6, 0xd2, 0x23, 0x2c, 0xf4, 0xbb, 0x5d, 0x3a, 0xd, 0x90, 787 | 0xae, 0x5c, 0xfd, 0xe9, 0xf, 0xde, 0x6a, 0x64, 0xa4, 0xa9, 0xc1, 0xa9, 0xcc, 0xd5, 0x14, 0x85, 788 | 0x64, 0x18, 0x35, 0x51, 0x6c, 0xf3, 0x2a, 0x2e, 0x6d, 0x59, 0x51, 0xdb, 0x35, 0xc2, 0xdc, 0x41, 789 | 0xe5, 0xcd, 0x22, 0x7f, 0x75, 0x88, 0xae, 0xda, 0x4c, 0xab, 0x60, 0xd7, 0x33, 0xa9, 0x45, 0x8b, 790 | 0xd9, 0x3d, 0xf9, 0xad, 0x77, 0x26, 0x8b, 0xe4, 0x6c, 0xcc, 0x86, 0xd, 0xf2, 0x83, 0xd9, 0x79, 791 | 0xad, 0x24, 0x8e, 0x88, 0x20, 0xda, 0xa3, 0x8e, 0x4d, 0x5f, 0x86, 0xdb, 0xbb, 0x7e, 0x55, 0x68, 792 | 0x2a, 0x55, 0xbb, 0x21, 0x8e, 0x26, 0x62, 0x15, 0x46, 0x49, 0xad, 0x28, 0xe0, 0xf2, 0xd7, 0x1d, 793 | 0x4f, 0x73, 0x53, 0x43, 0x2, 0xc6, 0xbf, 0xed, 0x1a, 0x7b, 0x94, 0x8d, 0x72, 0x7f, 0x2a, 0x86, 794 | 0xae, 0x42, 0xa8, 0x96, 0xa5, 0x69, 0x4a, 0xc2, 0x9b, 0x9b, 0xf0, 0x1e, 0xb5, 0x95, 0x23, 0x49, 795 | 0x24, 0xc2, 0x42, 0x79, 0x1d, 0x7, 0xa5, 0x68, 0x48, 0x3c, 0xd6, 0xdc, 0xc6, 0x99, 0xe4, 0x8f, 796 | 0x6a, 0xb5, 0x4e, 0xc6, 0x6f, 0x12, 0x35, 0x1f, 0x2a, 0xd, 0x59, 0x85, 0x73, 0x8a, 0xae, 0xd1, 797 | 0x6d, 0x19, 0x15, 0x6a, 0xc8, 0x86, 0x43, 0xec, 0x69, 0xf2, 0x58, 0xca, 0x78, 0x8b, 0xab, 0x97, 798 | 0xa1, 0x4a, 0xa7, 0xab, 0xcf, 0x92, 0xb6, 0xcb, 0xd0, 0x7c, 0xcd, 0xf5, 0xab, 0x6f, 0x70, 0xb0, 799 | 0x44, 0xcf, 0xe8, 0x2b, 0xd, 0x99, 0xa4, 0x76, 0x76, 0x39, 0x2c, 0x72, 0x6a, 0xa1, 0xd, 0x6e, 800 | 0x73, 0x3a, 0xf7, 0x11, 0x56, 0xa5, 0x51, 0x4d, 0x2, 0x94, 0x13, 0xfc, 0x23, 0x26, 0xb6, 0x51, 801 | 0x6c, 0xca, 0x55, 0x62, 0xb7, 0x1e, 0x4a, 0xa2, 0xee, 0x62, 0x0, 0xf7, 0xac, 0x7b, 0xe3, 0x14, 802 | 0xd7, 0x1, 0xe1, 0x43, 0xbb, 0xa1, 0x3f, 0xde, 0xad, 0x36, 0xb6, 0x69, 0xe, 0x64, 0x7f, 0xc0, 803 | 0x52, 0x8, 0x12, 0x31, 0x85, 0x50, 0x2a, 0xb9, 0x5a, 0x31, 0x95, 0x5e, 0x6d, 0x6, 0x68, 0x76, 804 | 0xb3, 0x99, 0xa4, 0x95, 0x98, 0xa2, 0x85, 0xc0, 0xfc, 0x7f, 0xfd, 0x55, 0x3e, 0xb6, 0x15, 0x62, 805 | 0x48, 0x47, 0x25, 0x8e, 0xe2, 0x4d, 0x68, 0xe9, 0xd1, 0x6c, 0xb5, 0xce, 0x39, 0x66, 0xcd, 0x65, 806 | 0x6a, 0x2d, 0xe7, 0xdd, 0xb9, 0xec, 0xbf, 0x28, 0xac, 0x79, 0x5b, 0x9d, 0xd9, 0xa5, 0xd2, 0x85, 807 | 0x91, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 808 | 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 809 | 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 810 | 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 811 | 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 812 | 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 813 | 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 814 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 815 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 816 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 817 | 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 818 | 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 819 | 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 820 | 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 821 | 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 822 | 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 823 | 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 824 | 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 825 | 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 826 | 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 827 | 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 828 | 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 829 | 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 830 | 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 831 | 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 832 | 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 833 | 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 834 | 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 835 | 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 836 | 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 837 | 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 838 | 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 839 | 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 840 | 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 841 | 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 842 | 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 843 | 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 844 | 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 845 | 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 846 | 0x3f, 0x0, 0xc8, 0x9a, 0xa, 0xa1, 0x2c, 0x35, 0xd1, 0x4f, 0x6f, 0x82, 0x41, 0x6, 0xab, 0x7d, 847 | 0x8b, 0x3f, 0x33, 0x8e, 0x3d, 0x2b, 0xb5, 0x48, 0xfa, 0x7b, 0x98, 0x29, 0x6a, 0x5c, 0xe5, 0xb8, 848 | 0x5a, 0xb1, 0xb0, 0x2a, 0xe0, 0xc, 0xa, 0xd1, 0x96, 0xc, 0x76, 0xaa, 0x8f, 0x1e, 0x2a, 0xaf, 849 | 0x73, 0x39, 0x6a, 0x56, 0x2b, 0x51, 0x95, 0xab, 0x5, 0x6a, 0x36, 0x2, 0x9a, 0x57, 0x31, 0x74, 850 | 0x9b, 0xd8, 0xae, 0x56, 0x90, 0x6f, 0x4e, 0x55, 0xb6, 0xfb, 0xd4, 0xac, 0x40, 0xa8, 0xe1, 0x46, 851 | 0xbc, 0xb8, 0x58, 0xf9, 0xf2, 0xc7, 0x2d, 0x57, 0xc9, 0xdc, 0x16, 0x1e, 0xcf, 0x57, 0xa9, 0x7e, 852 | 0xc6, 0x4d, 0xa5, 0x27, 0x96, 0x18, 0xe5, 0x6c, 0x7c, 0xbe, 0x60, 0x38, 0xc7, 0xae, 0x2b, 0x63, 853 | 0xfb, 0x76, 0xf4, 0x8e, 0xb1, 0xa8, 0xf6, 0x5a, 0xcd, 0xb8, 0x2b, 0x9, 0x55, 0xff, 0x0, 0x66, 854 | 0xaa, 0xb4, 0xd9, 0xac, 0xae, 0x8d, 0x2e, 0xe2, 0xec, 0x99, 0xae, 0xfa, 0xdd, 0xd9, 0xeb, 0x37, 855 | 0xe4, 0x0, 0xaa, 0xb2, 0x6a, 0x73, 0x49, 0xf7, 0xa4, 0x63, 0xff, 0x0, 0x2, 0xac, 0xe3, 0x25, 856 | 0x37, 0x7d, 0x17, 0x13, 0xa9, 0x2e, 0xe5, 0xd3, 0x76, 0x4f, 0x51, 0x9f, 0xc6, 0x8f, 0xb5, 0xfb, 857 | 0x1a, 0xa3, 0xba, 0x97, 0x75, 0x32, 0x5c, 0xd9, 0x7c, 0x5e, 0x1, 0xd4, 0x1a, 0x99, 0x6f, 0xd0, 858 | 0x75, 0xd, 0x59, 0x3b, 0xc0, 0xf7, 0x3e, 0x82, 0xac, 0x47, 0x6d, 0x34, 0x9c, 0xc8, 0x7c, 0xb5, 859 | 0xf4, 0x1d, 0x4d, 0x52, 0x46, 0x53, 0xa9, 0xdc, 0xbb, 0x35, 0xc5, 0xb5, 0xc7, 0x4, 0x30, 0x93, 860 | 0xb1, 0x2, 0xaf, 0x69, 0xfa, 0x74, 0x28, 0x12, 0x79, 0xb1, 0x23, 0xfd, 0xe5, 0x1d, 0x97, 0xff, 861 | 0x0, 0xaf, 0x59, 0xa9, 0x12, 0x46, 0xbf, 0x2a, 0xe0, 0x7f, 0x3a, 0xd4, 0xb4, 0x97, 0xfd, 0x1d, 862 | 0x47, 0xa7, 0x15, 0xac, 0x51, 0xc5, 0x5a, 0xa3, 0xb5, 0x91, 0xa4, 0x65, 0xa6, 0x99, 0x6a, 0xaf, 863 | 0x99, 0x48, 0x64, 0xad, 0x12, 0x38, 0x9d, 0xcb, 0x26, 0x4a, 0x4f, 0x33, 0xde, 0xaa, 0xb4, 0xc0, 864 | 0x75, 0x60, 0x2a, 0x16, 0xbb, 0x41, 0xd3, 0x9a, 0xa4, 0x8c, 0x64, 0x5c, 0x72, 0x1c, 0x60, 0xd6, 865 | 0x3d, 0xec, 0x5, 0xee, 0x17, 0x23, 0xb5, 0x4e, 0xd7, 0x8c, 0x7a, 0x60, 0x54, 0x46, 0x62, 0xc7, 866 | 0x93, 0x9a, 0xd2, 0x28, 0xc5, 0xe8, 0x11, 0xc6, 0xa9, 0xee, 0x6a, 0xdc, 0x4b, 0x8f, 0x98, 0xf5, 867 | 0xaa, 0xf1, 0xf3, 0xf3, 0x1a, 0x95, 0xa6, 0x8, 0x39, 0xeb, 0x55, 0xe4, 0x65, 0x6e, 0xac, 0x9d, 868 | 0xa5, 0x11, 0xae, 0x4f, 0x5f, 0x4a, 0xa8, 0xf2, 0x33, 0xb6, 0x5a, 0xa2, 0x69, 0x4b, 0x1c, 0x9a, 869 | 0x4d, 0xf5, 0x71, 0x8a, 0x47, 0x35, 0x49, 0xb6, 0x4b, 0x9a, 0x33, 0xef, 0x51, 0x6f, 0xa5, 0xdd, 870 | 0x5a, 0x58, 0xe6, 0x94, 0x99, 0x2e, 0x69, 0x21, 0x3e, 0x5c, 0xa4, 0xe, 0x8d, 0x51, 0xee, 0xa0, 871 | 0xb6, 0x29, 0xd8, 0xc6, 0x53, 0x24, 0xb9, 0x94, 0xb9, 0x9, 0xd8, 0x75, 0xa8, 0x2, 0xd2, 0x9, 872 | 0x93, 0x3c, 0x83, 0x9a, 0x77, 0x98, 0xa7, 0xbd, 0x5a, 0xb1, 0x8b, 0x9b, 0x43, 0x82, 0x81, 0xd4, 873 | 0xd3, 0xb3, 0x8e, 0x95, 0x1e, 0xea, 0x33, 0x56, 0x8c, 0x5c, 0xc9, 0x37, 0x51, 0xbb, 0x35, 0x1e, 874 | 0x69, 0xf0, 0x8d, 0xd3, 0x20, 0xc7, 0x7a, 0xab, 0x68, 0x4a, 0x9e, 0xa6, 0xb1, 0x61, 0x5, 0x9f, 875 | 0xba, 0xaf, 0xeb, 0x58, 0xac, 0x95, 0x7e, 0xf6, 0x5f, 0x95, 0x53, 0x3d, 0x79, 0x35, 0x4b, 0x35, 876 | 0x10, 0x86, 0x97, 0x34, 0xa9, 0x59, 0xde, 0xc7, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 877 | 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 878 | 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 879 | 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 880 | 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 881 | 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 882 | 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 883 | 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 884 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 885 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 886 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 887 | 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 888 | 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 889 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 890 | 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 891 | 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 892 | 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 893 | 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 894 | 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 895 | 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 896 | 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 897 | 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 898 | 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 899 | 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 900 | 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 901 | 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 902 | 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 903 | 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 904 | 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 905 | 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 906 | 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 907 | 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 908 | 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 909 | 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 910 | 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 911 | 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 912 | 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 913 | 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 914 | 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 915 | 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xde, 0xd4, 0x74, 0xe1, 0x15, 0xc9, 0x72, 916 | 0x38, 0x6f, 0x98, 0x56, 0x6c, 0xb0, 0xd4, 0x3a, 0x6f, 0x8a, 0xda, 0x6b, 0x41, 0x69, 0xac, 0x29, 917 | 0x13, 0x47, 0xfe, 0xae, 0x71, 0xc9, 0x71, 0xe8, 0xc3, 0xd7, 0xde, 0xaa, 0x5e, 0xeb, 0xa5, 0xc9, 918 | 0x5b, 0x68, 0xf6, 0xf, 0xef, 0x37, 0x26, 0xba, 0xe1, 0x4e, 0x7b, 0x33, 0xe9, 0xa9, 0xd3, 0x9d, 919 | 0x4e, 0x83, 0xa7, 0x45, 0x45, 0x25, 0xc8, 0x51, 0xef, 0x59, 0x53, 0xcf, 0x1e, 0x7e, 0x41, 0x9f, 920 | 0x7a, 0x86, 0x69, 0xde, 0x46, 0xdc, 0xee, 0x58, 0xfb, 0xd5, 0x66, 0x7a, 0xe8, 0x8d, 0x3b, 0x6e, 921 | 0x6f, 0xec, 0xa3, 0xd, 0xf5, 0x1e, 0xf2, 0x54, 0xf, 0x25, 0x35, 0x9e, 0xa1, 0x77, 0xc5, 0x69, 922 | 0xa2, 0x33, 0x94, 0xef, 0xa2, 0x9, 0x1b, 0x3f, 0x4a, 0xd1, 0xb1, 0x4f, 0x2a, 0x3f, 0xf6, 0x9b, 923 | 0x93, 0x59, 0xb0, 0xaf, 0x99, 0x2e, 0x4f, 0x41, 0x5a, 0xd1, 0x76, 0xac, 0x2a, 0x54, 0xbe, 0x88, 924 | 0x54, 0xe3, 0xad, 0xd9, 0x15, 0xf4, 0x9f, 0xbe, 0x1f, 0xee, 0xd5, 0x4d, 0xd5, 0x36, 0xa1, 0xc5, 925 | 0xc0, 0xff, 0x0, 0x74, 0x55, 0x74, 0x57, 0x90, 0xe1, 0x14, 0x93, 0x59, 0xa4, 0x61, 0x53, 0xe2, 926 | 0x62, 0xee, 0xa5, 0xce, 0x78, 0xa9, 0xd2, 0xd0, 0xf5, 0x91, 0xbf, 0x1, 0x56, 0x21, 0xb7, 0x2c, 927 | 0x76, 0xc4, 0x9f, 0x8d, 0x5a, 0x46, 0x4c, 0xa8, 0xb1, 0x36, 0x39, 0xe2, 0xac, 0x43, 0x65, 0x24, 928 | 0xdc, 0x8f, 0x95, 0x3f, 0xbc, 0x6b, 0x4a, 0x2b, 0x38, 0xe2, 0xf9, 0xa4, 0xf9, 0xdb, 0xf4, 0x14, 929 | 0xe9, 0x66, 0xa, 0x39, 0x20, 0xa, 0xd1, 0x40, 0xc6, 0x53, 0xec, 0x41, 0x1d, 0xb4, 0x36, 0xe3, 930 | 0xe5, 0x19, 0x6f, 0xef, 0x1e, 0xb4, 0x13, 0xb8, 0xfb, 0x54, 0x12, 0x5d, 0xa1, 0x6c, 0x3, 0x93, 931 | 0xed, 0x51, 0x3d, 0xe1, 0xc6, 0x14, 0x62, 0xb4, 0x51, 0x30, 0x77, 0x2d, 0x93, 0x8a, 0x74, 0x37, 932 | 0x29, 0x18, 0x65, 0x2c, 0x3d, 0x6b, 0x25, 0xe7, 0x76, 0xfb, 0xcc, 0x4d, 0x46, 0xb2, 0xed, 0x6a, 933 | 0xb5, 0x13, 0x39, 0x46, 0xe8, 0xdb, 0x6b, 0xf1, 0xfc, 0x23, 0xf3, 0xa8, 0x9a, 0xf1, 0xdb, 0xf8, 934 | 0xb1, 0xf4, 0xac, 0xbf, 0x3e, 0x93, 0xce, 0xf7, 0xad, 0x12, 0x31, 0x70, 0x34, 0x4c, 0xd9, 0xef, 935 | 0x4d, 0xf3, 0x6a, 0x87, 0x9f, 0xef, 0x47, 0x9d, 0x54, 0x99, 0x9b, 0xa6, 0x5e, 0xf3, 0x7d, 0xe9, 936 | 0xf1, 0xb6, 0xe3, 0xed, 0x59, 0xc8, 0xe5, 0xdb, 0x15, 0x60, 0xce, 0x23, 0x5f, 0x7e, 0xc2, 0x8b, 937 | 0x99, 0x3a, 0x65, 0xf6, 0x9c, 0x20, 0xfe, 0x95, 0x1, 0x9b, 0x71, 0xc9, 0xaa, 0x26, 0x72, 0xc7, 938 | 0x24, 0xd1, 0xe6, 0xd3, 0x46, 0x33, 0xa7, 0x72, 0xf7, 0x99, 0x4b, 0xbe, 0xa9, 0x9, 0x69, 0xc2, 939 | 0x5a, 0xb4, 0xce, 0x59, 0xd2, 0x2e, 0x7, 0xa5, 0xdf, 0x55, 0x4, 0xb4, 0xe1, 0x2d, 0x5a, 0x91, 940 | 0xcd, 0x3a, 0x45, 0xad, 0xf4, 0xdf, 0x33, 0x73, 0xfb, 0x55, 0x76, 0x9b, 0x1c, 0x52, 0xa3, 0xf3, 941 | 0x56, 0x99, 0xc9, 0x3a, 0x64, 0xd2, 0xc, 0xfc, 0xc2, 0x9a, 0xa6, 0x8d, 0xf9, 0xa6, 0xf4, 0x35, 942 | 0x47, 0x34, 0x93, 0x26, 0x53, 0x4f, 0x6, 0xa1, 0x6, 0x9e, 0x1a, 0xad, 0x1c, 0xb3, 0x26, 0xe3, 943 | 0xd0, 0x55, 0x8b, 0x55, 0x5f, 0x33, 0x76, 0x3a, 0xa, 0xa6, 0x1a, 0xac, 0xc4, 0xdb, 0x21, 0x66, 944 | 0xaa, 0x7b, 0x19, 0x47, 0x7b, 0x8b, 0x36, 0x24, 0x94, 0x9c, 0x9f, 0x4a, 0x8f, 0xca, 0xff, 0x0, 945 | 0x6a, 0x90, 0x1a, 0x70, 0x34, 0xd6, 0x88, 0x87, 0x37, 0x7b, 0x9f, 0xff, 0xd9, 0xff, 0xd8, 0xff, 946 | 0xe0, 0x0, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 947 | 0x0, 0xff, 0xdb, 0x0, 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 948 | 0x9, 0x9, 0x8, 0xa, 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 949 | 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 950 | 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 951 | 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 952 | 0xc, 0x18, 0xd, 0xd, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 953 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 954 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 955 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 956 | 0x0, 0x10, 0x1, 0x40, 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 957 | 0x0, 0x1f, 0x0, 0x0, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 958 | 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 959 | 0xc4, 0x0, 0xb5, 0x10, 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 960 | 0x0, 0x0, 0x1, 0x7d, 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 961 | 0x13, 0x51, 0x61, 0x7, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 962 | 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 963 | 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 964 | 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 965 | 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 966 | 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 967 | 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 968 | 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 969 | 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 970 | 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 971 | 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 972 | 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 973 | 0x4, 0x4, 0x3, 0x4, 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 974 | 0x11, 0x4, 0x5, 0x21, 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 975 | 0x8, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 976 | 0xa, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 977 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 978 | 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 979 | 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 980 | 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 981 | 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 982 | 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 983 | 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 984 | 0x0, 0xc, 0x3, 0x1, 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xe4, 0xa2, 0x6c, 0x4c, 985 | 0xa4, 0x9a, 0xb2, 0x65, 0xc8, 0xaa, 0x5b, 0xb0, 0xd9, 0xa4, 0x32, 0xd7, 0xa9, 0x39, 0xf2, 0xb3, 986 | 0xea, 0x21, 0x53, 0x95, 0x16, 0x5d, 0xea, 0x7, 0x92, 0xa3, 0x69, 0x81, 0x1e, 0xa7, 0xd2, 0x80, 987 | 0x8, 0xe5, 0xba, 0xff, 0x0, 0x2a, 0x6e, 0x69, 0x21, 0x5e, 0x55, 0x1e, 0x82, 0x93, 0x8e, 0xbd, 988 | 0x6a, 0x16, 0x39, 0xa7, 0xb1, 0xa5, 0x89, 0x72, 0xd9, 0xac, 0x65, 0x32, 0xf9, 0x2c, 0x59, 0xb7, 989 | 0x4d, 0xaa, 0x5, 0x5e, 0x8d, 0x92, 0x35, 0xde, 0xe4, 0x5, 0x1d, 0xcd, 0x54, 0x52, 0x10, 0x64, 990 | 0xd5, 0x6b, 0x89, 0xc3, 0x9f, 0x99, 0xf3, 0x8e, 0x8a, 0x2b, 0x34, 0xae, 0xcb, 0xd9, 0x1a, 0x4a, 991 | 0xb0, 0xde, 0xb1, 0xb8, 0x2a, 0x71, 0xf7, 0x40, 0x3e, 0xd5, 0x28, 0x0, 0x0, 0x88, 0xbf, 0x80, 992 | 0x15, 0x46, 0xd2, 0x62, 0xb6, 0xe1, 0x4f, 0xc8, 0x32, 0x7a, 0xf5, 0xa9, 0x8d, 0xe2, 0xa8, 0x21, 993 | 0x5a, 0xba, 0x23, 0x4e, 0xe7, 0x14, 0xf4, 0x65, 0xc5, 0x85, 0x17, 0x99, 0x9c, 0xf, 0xf6, 0x45, 994 | 0x3d, 0xaf, 0xa3, 0x8d, 0x76, 0xc6, 0xbc, 0x7e, 0x55, 0x90, 0xf7, 0x60, 0xf7, 0xa8, 0x5a, 0xe3, 995 | 0x35, 0xb2, 0x82, 0x46, 0x12, 0xd4, 0xd2, 0x96, 0xfd, 0xdb, 0x38, 0x20, 0x7d, 0x2a, 0x84, 0xb7, 996 | 0x5, 0x8f, 0x5c, 0x9a, 0xae, 0xd3, 0x66, 0xa2, 0x12, 0x7c, 0xc7, 0xd6, 0xae, 0xc4, 0x58, 0xb6, 997 | 0x24, 0xda, 0x3a, 0xf3, 0x4d, 0x32, 0xd5, 0x53, 0x25, 0x34, 0xbd, 0x32, 0x1a, 0x2c, 0x99, 0x29, 998 | 0x85, 0xea, 0xb9, 0x7a, 0x42, 0xf4, 0x10, 0xd1, 0x37, 0x9b, 0x49, 0xe6, 0xd5, 0x62, 0xf8, 0xa3, 999 | 0x7d, 0x6, 0x6d, 0x16, 0x7c, 0xdf, 0x7a, 0x51, 0x21, 0x63, 0x81, 0x55, 0x37, 0x7a, 0x54, 0xc2, 1000 | 0x41, 0xa, 0xfa, 0xb1, 0xa6, 0x4b, 0x45, 0xc3, 0x28, 0x85, 0x31, 0xd5, 0xaa, 0x13, 0x31, 0x63, 1001 | 0x92, 0x79, 0xaa, 0x86, 0x52, 0xc7, 0x27, 0xad, 0x1b, 0xe8, 0x33, 0x71, 0x2d, 0x89, 0x69, 0xc2, 1002 | 0x5a, 0xa4, 0x1e, 0x9c, 0x24, 0xa1, 0x33, 0x37, 0x2, 0xe8, 0x96, 0x9c, 0x25, 0xaa, 0x22, 0x4a, 1003 | 0x70, 0x92, 0x9d, 0xcc, 0x65, 0x2, 0xf0, 0x96, 0x9d, 0xe7, 0x62, 0xa8, 0x79, 0xb4, 0x79, 0xb9, 1004 | 0x3d, 0x6a, 0xb9, 0x8e, 0x79, 0xd3, 0x2e, 0x89, 0x9, 0xa9, 0x56, 0x4c, 0x55, 0x5, 0x92, 0xa6, 1005 | 0x59, 0x2a, 0x94, 0x8e, 0x5a, 0x94, 0x8b, 0xc2, 0x5a, 0x7f, 0x99, 0xda, 0xa8, 0x89, 0x29, 0xe2, 1006 | 0x4a, 0xd5, 0x4c, 0xe1, 0xa9, 0x44, 0xba, 0x1f, 0xde, 0x9e, 0x1e, 0xa8, 0x89, 0x2a, 0x41, 0x25, 1007 | 0x6a, 0xa4, 0x70, 0xd4, 0xa4, 0x5c, 0xd, 0x56, 0x19, 0xf1, 0x1a, 0xaf, 0xe3, 0x59, 0xe9, 0x26, 1008 | 0x58, 0xa, 0x98, 0xc9, 0xb9, 0xaa, 0xd3, 0x39, 0x9c, 0x6c, 0x59, 0x6, 0x9e, 0xd, 0x57, 0x57, 1009 | 0xa9, 0x3, 0x66, 0xaa, 0xe6, 0xe, 0x27, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 1010 | 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 1011 | 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 1012 | 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 1013 | 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 1014 | 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 1015 | 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 1016 | 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 1017 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 1018 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 1019 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 1020 | 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 1021 | 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 1022 | 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 1023 | 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 1024 | 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 1025 | 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 1026 | 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 1027 | 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 1028 | 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 1029 | 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 1030 | 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 1031 | 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 1032 | 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 1033 | 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 1034 | 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 1035 | 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 1036 | 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 1037 | 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 1038 | 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 1039 | 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 1040 | 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 1041 | 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 1042 | 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 1043 | 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 1044 | 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 1045 | 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 1046 | 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 1047 | 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 1048 | 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xe2, 0x65, 0x6d, 0xab, 0x9a, 0xa9, 0x25, 0xc0, 1049 | 0x5e, 0xf4, 0xed, 0x5e, 0x64, 0xb4, 0x52, 0x85, 0xb3, 0xcf, 0x18, 0xac, 0x58, 0xae, 0x4c, 0xd2, 1050 | 0x7c, 0xab, 0xf2, 0x8e, 0xa4, 0xd7, 0x65, 0x79, 0x7b, 0xd6, 0x47, 0xbd, 0x76, 0xdd, 0x91, 0xab, 1051 | 0x1c, 0xae, 0xad, 0xe6, 0x7e, 0x86, 0xad, 0x8b, 0x98, 0xd8, 0x72, 0xc1, 0x5b, 0xd0, 0xd6, 0x3b, 1052 | 0xcb, 0x2b, 0xff, 0x0, 0x16, 0x7, 0xa0, 0xa8, 0x18, 0xed, 0x39, 0x27, 0x6, 0xb3, 0x8d, 0xd1, 1053 | 0xd5, 0x4e, 0xf4, 0xf7, 0xd8, 0xda, 0x7b, 0xa4, 0x1f, 0x77, 0x2d, 0x53, 0xc2, 0xd2, 0xb2, 0xee, 1054 | 0xc6, 0xc5, 0xfe, 0x75, 0x91, 0x63, 0x79, 0x13, 0x4d, 0xb6, 0x61, 0xcf, 0xf0, 0x93, 0xd3, 0x35, 1055 | 0xac, 0xd3, 0x67, 0xbd, 0x6d, 0x18, 0xf3, 0x17, 0x2a, 0xb1, 0xe8, 0x48, 0xc3, 0x77, 0xde, 0x63, 1056 | 0x48, 0x19, 0x13, 0xee, 0x8e, 0x7d, 0x6a, 0x3, 0x26, 0x69, 0x37, 0x66, 0xba, 0x23, 0x3, 0x9a, 1057 | 0x75, 0x1b, 0x27, 0x69, 0xaa, 0x36, 0x90, 0xd4, 0x25, 0xb9, 0xa4, 0xdd, 0x5a, 0xa4, 0x61, 0x72, 1058 | 0x42, 0xe6, 0x9b, 0xbe, 0x98, 0xd4, 0xc2, 0xd5, 0x44, 0xb2, 0x42, 0xfd, 0xea, 0x2d, 0xe7, 0x39, 1059 | 0xa6, 0xb3, 0x71, 0x4d, 0xcd, 0x4, 0xb2, 0x62, 0xf9, 0xe6, 0x93, 0x75, 0x45, 0xba, 0x90, 0xb5, 1060 | 0x4, 0x92, 0x16, 0xa4, 0xdf, 0x51, 0x6e, 0xa4, 0x2d, 0x41, 0x23, 0x99, 0xb9, 0xa6, 0xee, 0xf7, 1061 | 0xa8, 0xd9, 0xa8, 0xc, 0x7, 0x3d, 0xfb, 0xa, 0xc, 0xda, 0x2c, 0x7, 0xf2, 0xc6, 0x4f, 0xde, 1062 | 0xec, 0x29, 0x85, 0xc9, 0x35, 0x16, 0xe2, 0x79, 0x26, 0x93, 0x75, 0x2, 0xb1, 0x2e, 0xea, 0x50, 1063 | 0xf5, 0x6, 0xfa, 0x37, 0xd0, 0x4b, 0x45, 0x8d, 0xf4, 0xbb, 0xea, 0xb6, 0xfa, 0x5d, 0xf4, 0x19, 1064 | 0xb4, 0x58, 0xf3, 0x29, 0x7c, 0xca, 0xab, 0xbe, 0x8d, 0xf4, 0x19, 0xb4, 0x59, 0xf3, 0x29, 0xea, 1065 | 0xf5, 0x54, 0x35, 0x38, 0x35, 0x23, 0x27, 0x12, 0xe2, 0xbd, 0x3c, 0x49, 0x55, 0x3, 0xe2, 0x9d, 1066 | 0xbe, 0xaa, 0xe6, 0x32, 0x81, 0x70, 0x49, 0x4f, 0x12, 0x55, 0x15, 0x92, 0x9e, 0x24, 0xa6, 0xa4, 1067 | 0x73, 0x4e, 0x99, 0x74, 0x49, 0x4f, 0x12, 0x55, 0x31, 0x25, 0x3c, 0x3d, 0x6a, 0xa6, 0x70, 0xd4, 1068 | 0xa0, 0x5e, 0x49, 0x48, 0x39, 0xa9, 0x16, 0x6f, 0x7a, 0xcf, 0xf3, 0x70, 0x29, 0x56, 0x5a, 0xd5, 1069 | 0x4c, 0xe0, 0x9d, 0x3, 0x59, 0x25, 0xa9, 0x96, 0x4a, 0xcb, 0x49, 0xb1, 0xc9, 0x35, 0x32, 0xdc, 1070 | 0xfa, 0x55, 0xa9, 0x9c, 0xd2, 0xa4, 0xcf, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10, 0x4a, 1071 | 0x46, 0x49, 0x46, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0xff, 0xdb, 0x0, 1072 | 0x43, 0x0, 0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7, 0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 1073 | 0xc, 0x14, 0xd, 0xc, 0xb, 0xb, 0xc, 0x19, 0x12, 0x13, 0xf, 0x14, 0x1d, 0x1a, 0x1f, 0x1e, 1074 | 0x1d, 0x1a, 0x1c, 0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c, 0x23, 0x1c, 0x1c, 0x28, 0x37, 1075 | 0x29, 0x2c, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d, 0x38, 0x32, 0x3c, 0x2e, 0x33, 1076 | 0x34, 0x32, 0xff, 0xdb, 0x0, 0x43, 0x1, 0x9, 0x9, 0x9, 0xc, 0xb, 0xc, 0x18, 0xd, 0xd, 1077 | 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 1078 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 1079 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 1080 | 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xff, 0xc0, 0x0, 0x11, 0x8, 0x0, 0x10, 0x1, 0x40, 1081 | 0x3, 0x1, 0x22, 0x0, 0x2, 0x11, 0x1, 0x3, 0x11, 0x1, 0xff, 0xc4, 0x0, 0x1f, 0x0, 0x0, 1082 | 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 1083 | 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x10, 1084 | 0x0, 0x2, 0x1, 0x3, 0x3, 0x2, 0x4, 0x3, 0x5, 0x5, 0x4, 0x4, 0x0, 0x0, 0x1, 0x7d, 1085 | 0x1, 0x2, 0x3, 0x0, 0x4, 0x11, 0x5, 0x12, 0x21, 0x31, 0x41, 0x6, 0x13, 0x51, 0x61, 0x7, 1086 | 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x8, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 1087 | 0x24, 0x33, 0x62, 0x72, 0x82, 0x9, 0xa, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 1088 | 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 1089 | 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 1090 | 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 1091 | 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 1092 | 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 1093 | 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 1094 | 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 1095 | 0xf9, 0xfa, 0xff, 0xc4, 0x0, 0x1f, 0x1, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 1096 | 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 1097 | 0x9, 0xa, 0xb, 0xff, 0xc4, 0x0, 0xb5, 0x11, 0x0, 0x2, 0x1, 0x2, 0x4, 0x4, 0x3, 0x4, 1098 | 0x7, 0x5, 0x4, 0x4, 0x0, 0x1, 0x2, 0x77, 0x0, 0x1, 0x2, 0x3, 0x11, 0x4, 0x5, 0x21, 1099 | 0x31, 0x6, 0x12, 0x41, 0x51, 0x7, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x8, 0x14, 0x42, 0x91, 1100 | 0xa1, 0xb1, 0xc1, 0x9, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0xa, 0x16, 0x24, 0x34, 1101 | 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 1102 | 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 1103 | 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 1104 | 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 1105 | 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 1106 | 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 1107 | 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 1108 | 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x0, 0xc, 0x3, 0x1, 1109 | 0x0, 0x2, 0x11, 0x3, 0x11, 0x0, 0x3f, 0x0, 0xf3, 0xbd, 0x42, 0xdf, 0xed, 0x90, 0x88, 0xc0, 1110 | 0xf9, 0xf3, 0xf2, 0x9a, 0xa7, 0x1d, 0xa1, 0x81, 0x3c, 0xbd, 0xbc, 0x8e, 0xbf, 0x5a, 0xd9, 0x86, 1111 | 0x19, 0x15, 0x83, 0x8e, 0x1a, 0x96, 0xee, 0x39, 0x19, 0x3c, 0xcd, 0xa0, 0xb0, 0xeb, 0xef, 0x5b, 1112 | 0xa9, 0x45, 0xcb, 0x53, 0xea, 0x30, 0xf4, 0xed, 0xef, 0x49, 0x18, 0xad, 0x19, 0xc5, 0x40, 0xd1, 1113 | 0xd5, 0xf6, 0x21, 0xbd, 0xaa, 0x33, 0x1e, 0x6b, 0xa2, 0x31, 0x8b, 0xd8, 0x75, 0x5f, 0x91, 0x9c, 1114 | 0x63, 0xab, 0xd6, 0x97, 0x47, 0x88, 0xe5, 0x3c, 0xf6, 0x34, 0x18, 0xa9, 0xa6, 0x2a, 0xd2, 0x30, 1115 | 0xb6, 0xc7, 0x2b, 0x65, 0xfc, 0xd2, 0xe6, 0xab, 0x43, 0x21, 0x1f, 0x23, 0xfe, 0x6, 0xa7, 0xce, 1116 | 0x2b, 0xa2, 0x24, 0xdc, 0x42, 0x7e, 0x6a, 0x4c, 0xd3, 0x9, 0xe4, 0xd1, 0x9a, 0xa2, 0x7, 0x16, 1117 | 0xa6, 0x93, 0x4d, 0x2d, 0x4c, 0x26, 0x81, 0xa, 0x4d, 0x26, 0x69, 0xb9, 0xa6, 0x96, 0xa0, 0x86, 1118 | 0x3c, 0xb5, 0x30, 0xb5, 0x34, 0xb5, 0x34, 0xb5, 0x2, 0x1c, 0x5a, 0x90, 0xb5, 0x30, 0xb5, 0x34, 1119 | 0xb5, 0x4, 0x8e, 0x2d, 0x9a, 0x6f, 0x99, 0xed, 0x4d, 0xdd, 0x4d, 0x26, 0x91, 0x23, 0xfc, 0xca, 1120 | 0x3c, 0xcf, 0x7a, 0x8f, 0xad, 0x36, 0x82, 0x49, 0x77, 0xd1, 0xbe, 0xa2, 0xcd, 0x26, 0xea, 0x62, 1121 | 0x25, 0xf3, 0x29, 0x3c, 0xca, 0x8f, 0x34, 0xda, 0x44, 0xb4, 0x4d, 0xe6, 0x52, 0x87, 0xaa, 0xff, 1122 | 0x0, 0x8d, 0x19, 0x22, 0x82, 0x1c, 0x4b, 0x41, 0xfd, 0x6a, 0x40, 0xf5, 0x48, 0x3d, 0x3c, 0x49, 1123 | 0x41, 0xe, 0x5, 0xd0, 0xfe, 0xf4, 0x17, 0xe9, 0x55, 0x4, 0x94, 0xa6, 0x4a, 0x19, 0x94, 0xa0, 1124 | 0x5b, 0xf, 0x4f, 0xf, 0x54, 0x84, 0x95, 0x2a, 0xbe, 0x69, 0x5c, 0xc6, 0x51, 0x2d, 0x7, 0xa9, 1125 | 0x15, 0xea, 0xa0, 0x7f, 0x4a, 0x78, 0x6a, 0xa4, 0xce, 0x69, 0xc0, 0xb8, 0x24, 0xa7, 0xab, 0xd5, 1126 | 0x30, 0xf5, 0x20, 0x7a, 0xb5, 0x23, 0x96, 0x74, 0x8b, 0x65, 0xf8, 0xa7, 0x2b, 0xd5, 0x5d, 0xfc, 1127 | 0x53, 0x96, 0x4a, 0xa5, 0x23, 0x96, 0x74, 0x8f, 0xff, 0xd9, 1128 | }; 1129 | 1130 | lv_img_dsc_t small_image_sjpg = { 1131 | .header.always_zero = 0, 1132 | .header.w = 320, 1133 | .header.h = 240, 1134 | .data_size = 17962, 1135 | .header.cf = LV_IMG_CF_RAW, 1136 | .data = small_image_sjpg_map, 1137 | }; 1138 | 1139 | -------------------------------------------------------------------------------- /example/images/wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvgl/lv_lib_split_jpg/c292bfd196fdae251069efb5f1c2f0c1040d764f/example/images/wallpaper.jpg -------------------------------------------------------------------------------- /example/images/wallpaper.sjpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvgl/lv_lib_split_jpg/c292bfd196fdae251069efb5f1c2f0c1040d764f/example/images/wallpaper.sjpg -------------------------------------------------------------------------------- /lv_sjpg.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lv_sjpg.c 3 | * 4 | */ 5 | 6 | /*---------------------------------------------------------------------------------------------------------------------------------- 7 | / Added normal JPG support [7/10/2020] 8 | / ---------- 9 | / SJPEG is a custom created modified JPEG file format for small embedded platforms. 10 | / It will contain multiple JPEG fragments all embedded into a single file with a custom header. 11 | / This makes JPEG decoding easier using any JPEG library. Overall file size will be almost 12 | / similar to the parent jpeg file. We can generate sjpeg from any jpeg using a python script 13 | / provided along with this project. 14 | / (by vinodstanur | 2020 ) 15 | / SJPEG FILE STRUCTURE 16 | / -------------------------------------------------------------------------------------------------------------------------------- 17 | / Bytes | Value | 18 | / -------------------------------------------------------------------------------------------------------------------------------- 19 | / 20 | / 0 - 7 | "_SJPG__" followed by '\0' 21 | / 22 | / 8 - 13 | "V1.00" followed by '\0' [VERSION OF SJPG FILE for future compatibiliby] 23 | / 24 | / 14 - 15 | X_RESOLUTION (width) [little endian] 25 | / 26 | / 16 - 17 | Y_RESOLUTION (height) [little endian] 27 | / 28 | / 18 - 19 | TOTAL_FRAMES inside sjpeg [little endian] 29 | / 30 | / 20 - 21 | JPEG BLOCK WIDTH (16 normally) [little endian] 31 | / 32 | / 22 - [(TOTAL_FRAMES*2 )] | SIZE OF EACH JPEG SPLIT FRAGMENTS (FRAME_INFO_ARRAY) 33 | / 34 | / SJPEG data | Each JPEG frame can be extracted from SJPEG data by parsing the FRAME_INFO_ARRAY one time. 35 | / 36 | /---------------------------------------------------------------------------------------------------------------------------------- 37 | / JPEG DECODER 38 | / ------------ 39 | / We are using TJpgDec - Tiny JPEG Decompressor library from ELM-CHAN for decoding each split-jpeg fragments. 40 | / The tjpgd.c and tjpgd.h is not modified and those are used as it is. So if any update comes for the tiny-jpeg, 41 | / just replace those files with updated files. 42 | /---------------------------------------------------------------------------------------------------------------------------------*/ 43 | 44 | /********************* 45 | * INCLUDES 46 | *********************/ 47 | 48 | #include "tjpgd.h" 49 | #include "lv_sjpg.h" 50 | #include 51 | #include 52 | 53 | #ifdef LV_LVGL_H_INCLUDE_SIMPLE 54 | #include 55 | #else 56 | #include 57 | #endif 58 | 59 | /********************* 60 | * DEFINES 61 | *********************/ 62 | #define TJPGD_WORKBUFF_SIZE 4096 //Recommended by TJPGD libray 63 | 64 | //NEVER EDIT THESE OFFSET VALUES 65 | #define SJPEG_VERSION_OFFSET 8 66 | #define SJPEG_X_RES_OFFSET 14 67 | #define SJPEG_y_RES_OFFSET 16 68 | #define SJPEG_TOTAL_FRAMES_OFFSET 18 69 | #define SJPEG_BLOCK_WIDTH_OFFSET 20 70 | #define SJPEG_FRAME_INFO_ARRAY_OFFSET 22 71 | 72 | /********************** 73 | * TYPEDEFS 74 | **********************/ 75 | 76 | /********************** 77 | * STATIC PROTOTYPES 78 | **********************/ 79 | static lv_res_t decoder_info( lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header ); 80 | static lv_res_t decoder_open( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc ); 81 | static lv_res_t decoder_read_line( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,lv_coord_t y, lv_coord_t len, uint8_t * buf ); 82 | static void decoder_close( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc ); 83 | static size_t input_func ( JDEC* jd, uint8_t* buff, size_t ndata ); 84 | static int is_jpg( const uint8_t *raw_data ); 85 | static void lv_sjpg_cleanup( SJPEG* sjpeg ); 86 | static void lv_sjpg_free( SJPEG* sjpeg ); 87 | 88 | /********************** 89 | * STATIC VARIABLES 90 | **********************/ 91 | 92 | /********************** 93 | * MACROS 94 | **********************/ 95 | 96 | /********************** 97 | * GLOBAL FUNCTIONS 98 | **********************/ 99 | void lv_split_jpeg_init( void ) 100 | { 101 | lv_img_decoder_t* dec = lv_img_decoder_create( ); 102 | lv_img_decoder_set_info_cb( dec, decoder_info ); 103 | lv_img_decoder_set_open_cb( dec, decoder_open ); 104 | lv_img_decoder_set_close_cb( dec, decoder_close ); 105 | lv_img_decoder_set_read_line_cb( dec, decoder_read_line ); 106 | } 107 | 108 | /********************** 109 | * STATIC FUNCTIONS 110 | **********************/ 111 | /** 112 | * Get info about an SJPG / JPG image 113 | * @param decoder pointer to the decoder where this function belongs 114 | * @param src can be file name or pointer to a C array 115 | * @param header store the info here 116 | * @return LV_RES_OK: no error; LV_RES_INV: can't get the info 117 | */ 118 | static lv_res_t decoder_info( lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header ) 119 | { 120 | /*Check whether the type `src` is known by the decoder*/ 121 | /* Read the SJPG/JPG header and find `width` and `height` */ 122 | 123 | lv_img_src_t src_type = lv_img_src_get_type(src); /*Get the source type*/ 124 | 125 | lv_res_t ret = LV_RES_OK; 126 | 127 | if(src_type == LV_IMG_SRC_VARIABLE) { 128 | uint8_t *raw_sjpeg_data = (uint8_t *)((lv_img_dsc_t * )src)->data; 129 | const uint32_t raw_sjpeg_data_size = ((lv_img_dsc_t *)src)->data_size; 130 | 131 | if(!strncmp((char *)raw_sjpeg_data, "_SJPG__", strlen("_SJPG__") )) { 132 | 133 | raw_sjpeg_data += 14; //seek to res info ... refer sjpeg format 134 | header->always_zero = 0; 135 | header->cf = LV_IMG_CF_RAW; 136 | 137 | header->w = *raw_sjpeg_data++; 138 | header->w |= *raw_sjpeg_data++ << 8; 139 | 140 | header->h = *raw_sjpeg_data++; 141 | header->h |= *raw_sjpeg_data++ << 8; 142 | 143 | return ret; 144 | 145 | } else if( is_jpg( raw_sjpeg_data ) == true ) { 146 | header->always_zero = 0; 147 | header->cf = LV_IMG_CF_RAW; 148 | 149 | uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 150 | if(!workb_temp) return LV_RES_INV; 151 | 152 | io_source_t io_source_temp; 153 | io_source_temp.type = SJPEG_IO_SOURCE_C_ARRAY; 154 | io_source_temp.raw_sjpg_data = raw_sjpeg_data; 155 | io_source_temp.raw_sjpg_data_size = raw_sjpeg_data_size; 156 | io_source_temp.raw_sjpg_data_next_read_pos = 0; 157 | 158 | JDEC jd_tmp; 159 | 160 | JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp); 161 | if(rc == JDR_OK ) { 162 | header->w = jd_tmp.width; 163 | header->h = jd_tmp.height; 164 | 165 | } else { 166 | ret = LV_RES_INV; 167 | goto end; 168 | } 169 | 170 | end: 171 | lv_mem_free(workb_temp); 172 | 173 | return ret; 174 | 175 | } 176 | } 177 | else if( src_type == LV_IMG_SRC_FILE ) { 178 | const char * fn = src; 179 | if(!strcmp(&fn[strlen(fn) - 5], ".sjpg")) { 180 | 181 | uint8_t buff[22]; 182 | memset(buff, 0, sizeof(buff)); 183 | 184 | lv_fs_file_t file; 185 | lv_fs_res_t res = lv_fs_open(&file , fn, LV_FS_MODE_RD); 186 | if(res != LV_FS_RES_OK) return 78; 187 | 188 | uint32_t rn; 189 | res = lv_fs_read(&file, buff, 8, &rn); 190 | if(res != LV_FS_RES_OK || rn != 8) { 191 | lv_fs_close(&file); 192 | return LV_RES_INV; 193 | } 194 | 195 | if(strcmp((char *)buff, "_SJPG__") == 0 ) { 196 | lv_fs_seek(&file, 14, LV_FS_SEEK_SET); 197 | res = lv_fs_read(&file, buff, 4, &rn); 198 | if(res != LV_FS_RES_OK || rn != 4 ) { 199 | lv_fs_close(&file); 200 | return LV_RES_INV; 201 | } 202 | header->always_zero = 0; 203 | header->cf = LV_IMG_CF_RAW; 204 | uint8_t *raw_sjpeg_data = buff; 205 | header->w = *raw_sjpeg_data++; 206 | header->w |= *raw_sjpeg_data++ << 8; 207 | header->h = *raw_sjpeg_data++; 208 | header->h |= *raw_sjpeg_data++ << 8; 209 | lv_fs_close(&file); 210 | return LV_RES_OK; 211 | 212 | } 213 | } else if(!strcmp(&fn[strlen(fn) - 4], ".jpg")) { 214 | lv_fs_file_t file; 215 | lv_fs_res_t res = lv_fs_open(&file , fn, LV_FS_MODE_RD); 216 | if(res != LV_FS_RES_OK) return 78; 217 | 218 | uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 219 | if(!workb_temp) { 220 | lv_fs_close(&file); 221 | return LV_RES_INV; 222 | } 223 | 224 | io_source_t io_source_temp; 225 | io_source_temp.type = SJPEG_IO_SOURCE_DISK; 226 | io_source_temp.raw_sjpg_data_next_read_pos = 0; 227 | io_source_temp.img_cache_buff = NULL; 228 | io_source_temp.lv_file = file; 229 | JDEC jd_tmp; 230 | 231 | JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp); 232 | lv_mem_free(workb_temp); 233 | lv_fs_close(&file); 234 | 235 | if(rc == JDR_OK ) { 236 | header->always_zero = 0; 237 | header->cf = LV_IMG_CF_RAW; 238 | header->w = jd_tmp.width; 239 | header->h = jd_tmp.height; 240 | return LV_RES_OK; 241 | } 242 | } 243 | } 244 | return LV_RES_INV; 245 | } 246 | 247 | static int img_data_cb( JDEC* jd, void* data, JRECT* rect ) 248 | { 249 | io_source_t *io = jd->device; 250 | uint8_t *cache = io->img_cache_buff; 251 | const int xres = io->img_cache_x_res; 252 | uint8_t *buf = data; 253 | const int INPUT_PIXEL_SIZE = 3; 254 | const int row_width = rect->right - rect->left + 1; // Row width in pixels. 255 | const int row_size = row_width * INPUT_PIXEL_SIZE; // Row size (bytes). 256 | 257 | for( int y = rect->top; y <= rect->bottom; y++ ) { 258 | int row_offset = y * xres * INPUT_PIXEL_SIZE + rect->left * INPUT_PIXEL_SIZE; 259 | memcpy( cache + row_offset, buf, row_size ); 260 | buf += row_size; 261 | } 262 | 263 | return 1; 264 | } 265 | 266 | static size_t input_func ( JDEC* jd, uint8_t* buff, size_t ndata ) 267 | { 268 | io_source_t *io = jd->device; 269 | 270 | if(!io) return 0; 271 | 272 | if(io->type == SJPEG_IO_SOURCE_C_ARRAY) { 273 | const uint32_t bytes_left = io->raw_sjpg_data_size - io->raw_sjpg_data_next_read_pos; 274 | const uint32_t to_read = ndata <= bytes_left ? (uint32_t)ndata : bytes_left; 275 | if (to_read == 0) 276 | return 0; 277 | if(buff) { 278 | memcpy(buff, io->raw_sjpg_data + io->raw_sjpg_data_next_read_pos, to_read); 279 | } 280 | io->raw_sjpg_data_next_read_pos += to_read; 281 | return to_read; 282 | } 283 | else if(io->type == SJPEG_IO_SOURCE_DISK) { 284 | 285 | lv_fs_file_t* lv_file_p = &(io->lv_file); 286 | 287 | if( buff ) { 288 | uint32_t rn = 0; 289 | lv_fs_read(lv_file_p, buff, (uint32_t)ndata, &rn); 290 | return rn; 291 | } else { 292 | uint32_t pos; 293 | lv_fs_tell(lv_file_p, &pos); 294 | lv_fs_seek(lv_file_p, (uint32_t)(ndata + pos), LV_FS_SEEK_SET); 295 | return ndata; 296 | } 297 | } 298 | return 0; 299 | } 300 | 301 | /** 302 | * Open SJPG image and return the decided image 303 | * @param decoder pointer to the decoder where this function belongs 304 | * @param dsc pointer to a descriptor which describes this decoding session 305 | * @return LV_RES_OK: no error; LV_RES_INV: can't get the info 306 | */ 307 | static lv_res_t decoder_open( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc ) 308 | { 309 | lv_res_t lv_ret = LV_RES_OK; 310 | 311 | if(dsc->src_type == LV_IMG_SRC_VARIABLE) { 312 | uint8_t *data; 313 | SJPEG* sjpeg = ( SJPEG* ) dsc->user_data; 314 | if( sjpeg == NULL ) { 315 | sjpeg = lv_mem_alloc( sizeof( SJPEG ) ); 316 | if( !sjpeg ) return LV_RES_INV; 317 | 318 | memset(sjpeg, 0, sizeof(SJPEG)); 319 | 320 | dsc->user_data = sjpeg; 321 | sjpeg->sjpeg_data = (uint8_t *)( ( lv_img_dsc_t* )(dsc->src) )->data; 322 | sjpeg->sjpeg_data_size = ( ( lv_img_dsc_t* )(dsc->src) )->data_size; 323 | } 324 | 325 | if( !strncmp( ( char * ) sjpeg->sjpeg_data, "_SJPG__", strlen("_SJPG__") ) ) { 326 | 327 | data = sjpeg->sjpeg_data; 328 | data += 14; 329 | 330 | sjpeg->sjpeg_x_res = *data++; 331 | sjpeg->sjpeg_x_res |= *data++ << 8; 332 | 333 | sjpeg->sjpeg_y_res = *data++; 334 | sjpeg->sjpeg_y_res |= *data++ << 8; 335 | 336 | sjpeg->sjpeg_total_frames = *data++; 337 | sjpeg->sjpeg_total_frames |= *data++ << 8; 338 | 339 | sjpeg->sjpeg_single_frame_height = *data++; 340 | sjpeg->sjpeg_single_frame_height |= *data++ << 8; 341 | 342 | sjpeg->frame_base_array = lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames ); 343 | if( ! sjpeg->frame_base_array ) { 344 | lv_sjpg_cleanup( sjpeg ); 345 | sjpeg = NULL; 346 | return LV_RES_INV; 347 | } 348 | 349 | sjpeg->frame_base_offset = NULL; 350 | 351 | uint8_t *img_frame_base = data + sjpeg->sjpeg_total_frames *2; 352 | sjpeg->frame_base_array[0] = img_frame_base; 353 | 354 | for( int i = 1; i < sjpeg->sjpeg_total_frames; i++ ) { 355 | int offset = *data++; 356 | offset |= *data++ <<8; 357 | sjpeg->frame_base_array[i] = sjpeg->frame_base_array[i-1] + offset; 358 | } 359 | sjpeg->sjpeg_cache_frame_index = -1; 360 | sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3/*2*/ ); 361 | if( ! sjpeg->frame_cache ) { 362 | lv_sjpg_cleanup( sjpeg ); 363 | sjpeg = NULL; 364 | return LV_RES_INV; 365 | } 366 | sjpeg->io.img_cache_buff = sjpeg->frame_cache; 367 | sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res; 368 | sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 369 | if( ! sjpeg->workb ) { 370 | lv_sjpg_cleanup( sjpeg ); 371 | sjpeg = NULL; 372 | return LV_RES_INV; 373 | } 374 | 375 | sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) ); 376 | if( ! sjpeg->tjpeg_jd ) { 377 | lv_sjpg_cleanup( sjpeg ); 378 | sjpeg = NULL; 379 | return LV_RES_INV; 380 | } 381 | sjpeg->io.type = SJPEG_IO_SOURCE_C_ARRAY; 382 | sjpeg->io.lv_file.file_d = NULL; 383 | dsc->img_data = NULL; 384 | return lv_ret; 385 | } 386 | 387 | else if( is_jpg( sjpeg->sjpeg_data ) == true ) { 388 | 389 | uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 390 | if( ! workb_temp ) { 391 | lv_sjpg_cleanup( sjpeg ); 392 | sjpeg = NULL; 393 | return LV_RES_INV; 394 | } 395 | io_source_t io_source_temp; 396 | io_source_temp.type = SJPEG_IO_SOURCE_C_ARRAY; 397 | io_source_temp.raw_sjpg_data = sjpeg->sjpeg_data; 398 | io_source_temp.raw_sjpg_data_size = sjpeg->sjpeg_data_size; 399 | io_source_temp.raw_sjpg_data_next_read_pos = 0; 400 | 401 | JDEC jd_tmp; 402 | JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp); 403 | lv_mem_free(workb_temp); 404 | 405 | 406 | if(rc == JDR_OK ) { 407 | sjpeg->sjpeg_x_res = jd_tmp.width; 408 | sjpeg->sjpeg_y_res = jd_tmp.height; 409 | sjpeg->sjpeg_total_frames = 1; 410 | sjpeg->sjpeg_single_frame_height = jd_tmp.height; 411 | 412 | sjpeg->frame_base_array = lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames ); 413 | if( ! sjpeg->frame_base_array ) { 414 | lv_sjpg_cleanup( sjpeg ); 415 | sjpeg = NULL; 416 | return LV_RES_INV; 417 | } 418 | sjpeg->frame_base_offset = NULL; 419 | 420 | uint8_t *img_frame_base = sjpeg->sjpeg_data; 421 | sjpeg->frame_base_array[0] = img_frame_base; 422 | 423 | sjpeg->sjpeg_cache_frame_index = -1; 424 | sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3 ); 425 | if( ! sjpeg->frame_cache ) { 426 | lv_sjpg_cleanup( sjpeg ); 427 | sjpeg = NULL; 428 | return LV_RES_INV; 429 | } 430 | 431 | sjpeg->io.img_cache_buff = sjpeg->frame_cache; 432 | sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res; 433 | sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 434 | if( ! sjpeg->workb ) { 435 | lv_sjpg_cleanup( sjpeg ); 436 | sjpeg = NULL; 437 | return LV_RES_INV; 438 | } 439 | 440 | sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) ); 441 | if( ! sjpeg->tjpeg_jd ) { 442 | lv_sjpg_cleanup( sjpeg ); 443 | sjpeg = NULL; 444 | return LV_RES_INV; 445 | } 446 | 447 | sjpeg->io.type = SJPEG_IO_SOURCE_C_ARRAY; 448 | sjpeg->io.lv_file.file_d = NULL; 449 | dsc->img_data = NULL; 450 | return lv_ret; 451 | } else { 452 | lv_ret = LV_RES_INV; 453 | goto end; 454 | } 455 | 456 | end: 457 | lv_mem_free(workb_temp); 458 | 459 | return lv_ret; 460 | } 461 | } 462 | else if(dsc->src_type == LV_IMG_SRC_FILE) { 463 | /* If all fine, then the file will be kept open */ 464 | const char * fn = dsc->src; 465 | uint8_t *data; 466 | 467 | if(!strcmp(&fn[strlen(fn) - 5], ".sjpg")) { 468 | 469 | uint8_t buff[22]; 470 | memset(buff, 0, sizeof(buff)); 471 | 472 | 473 | lv_fs_file_t lv_file; 474 | lv_fs_res_t res = lv_fs_open(&lv_file , fn, LV_FS_MODE_RD); 475 | if(res != LV_FS_RES_OK) { 476 | return 78; 477 | } 478 | 479 | 480 | uint32_t rn; 481 | res = lv_fs_read(&lv_file, buff, 22, &rn); 482 | if(res != LV_FS_RES_OK || rn != 22 ) { 483 | lv_fs_close(&lv_file); 484 | return LV_RES_INV; 485 | } 486 | 487 | if(strcmp((char *)buff, "_SJPG__") == 0 ) { 488 | 489 | SJPEG* sjpeg = ( SJPEG* ) dsc->user_data; 490 | if(sjpeg == NULL) { 491 | sjpeg = lv_mem_alloc(sizeof(SJPEG)); 492 | 493 | if( ! sjpeg ) { 494 | lv_fs_close(&lv_file); 495 | return LV_RES_INV; 496 | } 497 | memset(sjpeg, 0, sizeof(SJPEG)); 498 | 499 | dsc->user_data = sjpeg; 500 | sjpeg->sjpeg_data = (uint8_t *)( (lv_img_dsc_t* )(dsc->src) )->data; 501 | sjpeg->sjpeg_data_size = ( (lv_img_dsc_t* )(dsc->src) )->data_size; 502 | } 503 | data = buff; 504 | data += 14; 505 | 506 | sjpeg->sjpeg_x_res = *data++; 507 | sjpeg->sjpeg_x_res |= *data++ << 8; 508 | 509 | sjpeg->sjpeg_y_res = *data++; 510 | sjpeg->sjpeg_y_res |= *data++ << 8; 511 | 512 | sjpeg->sjpeg_total_frames = *data++; 513 | sjpeg->sjpeg_total_frames |= *data++ << 8; 514 | 515 | sjpeg->sjpeg_single_frame_height = *data++; 516 | sjpeg->sjpeg_single_frame_height |= *data++ << 8; 517 | 518 | sjpeg->frame_base_array = NULL;//lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames ); 519 | sjpeg->frame_base_offset = lv_mem_alloc( sizeof(int) * sjpeg->sjpeg_total_frames ); 520 | if( ! sjpeg->frame_base_offset ) { 521 | lv_fs_close(&lv_file); 522 | lv_sjpg_cleanup(sjpeg); 523 | return LV_RES_INV; 524 | } 525 | int img_frame_start_offset = (SJPEG_FRAME_INFO_ARRAY_OFFSET + sjpeg->sjpeg_total_frames *2); 526 | sjpeg->frame_base_offset[0] = img_frame_start_offset; //pointer used to save integer for now... 527 | 528 | for( int i = 1; i < sjpeg->sjpeg_total_frames; i++ ) { 529 | uint32_t rn; 530 | res = lv_fs_read(&lv_file, buff, 2, &rn); 531 | if(res != LV_FS_RES_OK || rn != 2 ) { 532 | lv_fs_close(&lv_file); 533 | return LV_RES_INV; 534 | } 535 | 536 | data = buff; 537 | int offset = *data++; 538 | offset |= *data++ <<8; 539 | sjpeg->frame_base_offset[i] = sjpeg->frame_base_offset[i-1] + offset; 540 | } 541 | 542 | sjpeg->sjpeg_cache_frame_index = -1; //INVALID AT BEGINNING for a forced compare mismatch at first time. 543 | sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3 ); 544 | if( ! sjpeg->frame_cache ) { 545 | lv_fs_close(&lv_file); 546 | lv_sjpg_cleanup(sjpeg); 547 | return LV_RES_INV; 548 | } 549 | sjpeg->io.img_cache_buff = sjpeg->frame_cache; 550 | sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res; 551 | sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 552 | if( ! sjpeg->workb ) { 553 | lv_fs_close(&lv_file); 554 | lv_sjpg_cleanup(sjpeg); 555 | return LV_RES_INV; 556 | } 557 | 558 | sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) ); 559 | if( ! sjpeg->tjpeg_jd ) { 560 | lv_fs_close(&lv_file); 561 | lv_sjpg_cleanup(sjpeg); 562 | return LV_RES_INV; 563 | } 564 | 565 | sjpeg->io.type = SJPEG_IO_SOURCE_DISK; 566 | sjpeg->io.lv_file = lv_file; 567 | dsc->img_data = NULL; 568 | return LV_RES_OK; 569 | } 570 | } 571 | else if( !strcmp(&fn[strlen(fn) - 4], ".jpg" ) ) { 572 | 573 | lv_fs_file_t lv_file; 574 | lv_fs_res_t res = lv_fs_open( &lv_file , fn, LV_FS_MODE_RD ); 575 | if(res != LV_FS_RES_OK) { 576 | return LV_RES_INV; 577 | } 578 | 579 | SJPEG* sjpeg = ( SJPEG* ) dsc->user_data; 580 | if(sjpeg == NULL) { 581 | sjpeg = lv_mem_alloc( sizeof( SJPEG ) ); 582 | if( ! sjpeg ) { 583 | lv_fs_close( &lv_file ); 584 | return LV_RES_INV; 585 | } 586 | 587 | memset(sjpeg, 0, sizeof(SJPEG)); 588 | dsc->user_data = sjpeg; 589 | sjpeg->sjpeg_data = (uint8_t *)( (lv_img_dsc_t* )(dsc->src) )->data; 590 | sjpeg->sjpeg_data_size = ( (lv_img_dsc_t *)(dsc->src) )->data_size; 591 | } 592 | 593 | uint8_t *workb_temp = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 594 | if( ! workb_temp ) { 595 | lv_fs_close(&lv_file); 596 | lv_sjpg_cleanup(sjpeg); 597 | return LV_RES_INV; 598 | } 599 | 600 | io_source_t io_source_temp; 601 | io_source_temp.type = SJPEG_IO_SOURCE_DISK; 602 | io_source_temp.raw_sjpg_data_next_read_pos = 0; 603 | io_source_temp.img_cache_buff = NULL; 604 | io_source_temp.lv_file = lv_file; 605 | 606 | JDEC jd_tmp; 607 | 608 | JRESULT rc = jd_prepare( &jd_tmp, input_func, workb_temp, (size_t)TJPGD_WORKBUFF_SIZE, &io_source_temp); 609 | 610 | lv_mem_free(workb_temp); 611 | 612 | 613 | if(rc == JDR_OK ) { 614 | sjpeg->sjpeg_x_res = jd_tmp.width; 615 | sjpeg->sjpeg_y_res = jd_tmp.height; 616 | sjpeg->sjpeg_total_frames = 1; 617 | sjpeg->sjpeg_single_frame_height = jd_tmp.height; 618 | 619 | sjpeg->frame_base_array = NULL; 620 | sjpeg->frame_base_offset = lv_mem_alloc( sizeof(uint8_t *) * sjpeg->sjpeg_total_frames ); 621 | if( ! sjpeg->frame_base_offset ) { 622 | lv_fs_close(&lv_file); 623 | lv_sjpg_cleanup(sjpeg); 624 | return LV_RES_INV; 625 | } 626 | 627 | int img_frame_start_offset = 0; 628 | sjpeg->frame_base_offset[0] = img_frame_start_offset; 629 | 630 | sjpeg->sjpeg_cache_frame_index = -1; 631 | sjpeg->frame_cache = (void *)lv_mem_alloc( sjpeg->sjpeg_x_res * sjpeg->sjpeg_single_frame_height * 3 ); 632 | if( ! sjpeg->frame_cache ) { 633 | lv_fs_close(&lv_file); 634 | lv_sjpg_cleanup(sjpeg); 635 | return LV_RES_INV; 636 | } 637 | 638 | sjpeg->io.img_cache_buff = sjpeg->frame_cache; 639 | sjpeg->io.img_cache_x_res = sjpeg->sjpeg_x_res; 640 | sjpeg->workb = lv_mem_alloc( TJPGD_WORKBUFF_SIZE ); 641 | if( ! sjpeg->workb ) { 642 | lv_fs_close(&lv_file); 643 | lv_sjpg_cleanup(sjpeg); 644 | return LV_RES_INV; 645 | } 646 | 647 | sjpeg->tjpeg_jd = lv_mem_alloc( sizeof( JDEC ) ); 648 | if( ! sjpeg->tjpeg_jd ) { 649 | lv_fs_close(&lv_file); 650 | lv_sjpg_cleanup(sjpeg); 651 | return LV_RES_INV; 652 | } 653 | 654 | sjpeg->io.type = SJPEG_IO_SOURCE_DISK; 655 | sjpeg->io.lv_file = lv_file; 656 | dsc->img_data = NULL; 657 | return LV_RES_OK; 658 | 659 | } else { 660 | if(dsc->user_data) lv_mem_free(dsc->user_data); 661 | lv_fs_close(&lv_file); 662 | return LV_RES_INV; 663 | } 664 | } 665 | } 666 | 667 | return LV_RES_INV; 668 | } 669 | 670 | /** 671 | * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`. 672 | * Required only if the "open" function can't open the whole decoded pixel array. (dsc->img_data == NULL) 673 | * @param decoder pointer to the decoder the function associated with 674 | * @param dsc pointer to decoder descriptor 675 | * @param x start x coordinate 676 | * @param y start y coordinate 677 | * @param len number of pixels to decode 678 | * @param buf a buffer to store the decoded pixels 679 | * @return LV_RES_OK: ok; LV_RES_INV: failed 680 | */ 681 | 682 | static lv_res_t decoder_read_line( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf ) 683 | { 684 | if(dsc->src_type == LV_IMG_SRC_VARIABLE) { 685 | SJPEG* sjpeg = ( SJPEG* ) dsc->user_data; 686 | JRESULT rc; 687 | 688 | int sjpeg_req_frame_index = y / sjpeg->sjpeg_single_frame_height; 689 | 690 | /*If line not from cache, refresh cache */ 691 | if(sjpeg_req_frame_index != sjpeg->sjpeg_cache_frame_index) { 692 | sjpeg->io.raw_sjpg_data = sjpeg->frame_base_array[ sjpeg_req_frame_index ]; 693 | if (sjpeg_req_frame_index == (sjpeg->sjpeg_total_frames - 1)) { 694 | /*This is the last frame. */ 695 | const uint32_t frame_offset = (uint32_t)(sjpeg->io.raw_sjpg_data - sjpeg->sjpeg_data); 696 | sjpeg->io.raw_sjpg_data_size = sjpeg->sjpeg_data_size - frame_offset; 697 | } else { 698 | sjpeg->io.raw_sjpg_data_size = 699 | (uint32_t)(sjpeg->frame_base_array[sjpeg_req_frame_index + 1] - sjpeg->io.raw_sjpg_data); 700 | } 701 | sjpeg->io.raw_sjpg_data_next_read_pos = 0; 702 | rc = jd_prepare( sjpeg->tjpeg_jd, input_func, sjpeg->workb, (size_t)TJPGD_WORKBUFF_SIZE, &(sjpeg->io)); 703 | if(rc != JDR_OK ) return LV_RES_INV; 704 | rc = jd_decomp ( sjpeg->tjpeg_jd, img_data_cb, 0); 705 | if(rc != JDR_OK ) return LV_RES_INV; 706 | sjpeg->sjpeg_cache_frame_index = sjpeg_req_frame_index; 707 | } 708 | 709 | int offset = 0; 710 | uint8_t *cache = (uint8_t *)sjpeg->frame_cache + x*3 + ( y % sjpeg->sjpeg_single_frame_height ) * sjpeg->sjpeg_x_res*3; 711 | 712 | #if LV_COLOR_DEPTH == 32 713 | for( int i = 0; i < len; i++ ) { 714 | buf[offset + 3] = 0xff; 715 | buf[offset + 2] = *cache++; 716 | buf[offset + 1] = *cache++; 717 | buf[offset + 0] = *cache++; 718 | offset += 4; 719 | } 720 | 721 | #elif LV_COLOR_DEPTH == 16 722 | 723 | for( int i = 0; i < len; i++ ) { 724 | uint16_t col_16bit = (*cache++ & 0xf8) << 8; 725 | col_16bit |= (*cache++ & 0xFC) << 3; 726 | col_16bit |= (*cache++ >> 3); 727 | #if LV_BIG_ENDIAN_SYSTEM == 1 728 | buf[offset++] = col_16bit >> 8; 729 | buf[offset++] = col_16bit & 0xff; 730 | #else 731 | buf[offset++] = col_16bit & 0xff; 732 | buf[offset++] = col_16bit >> 8; 733 | #endif // LV_BIG_ENDIAN_SYSTEM 734 | } 735 | 736 | #elif LV_COLOR_DEPTH == 8 737 | 738 | for( int i = 0; i < len; i++ ) { 739 | uint8_t col_8bit = (*cache++ & 0xC0); 740 | col_8bit |= (*cache++ & 0xe0) >> 2; 741 | col_8bit |= (*cache++ & 0xe0) >> 5; 742 | buf[offset++] = col_8bit; 743 | } 744 | #else 745 | #error Unsupported LV_COLOR_DEPTH 746 | 747 | 748 | #endif // LV_COLOR_DEPTH 749 | return LV_RES_OK; 750 | } 751 | else if(dsc->src_type == LV_IMG_SRC_FILE) { 752 | SJPEG* sjpeg = ( SJPEG* ) dsc->user_data; 753 | JRESULT rc; 754 | int sjpeg_req_frame_index = y / sjpeg->sjpeg_single_frame_height; 755 | 756 | lv_fs_file_t* lv_file_p = &(sjpeg->io.lv_file); 757 | if(!lv_file_p) goto end; 758 | 759 | /*If line not from cache, refresh cache */ 760 | if(sjpeg_req_frame_index != sjpeg->sjpeg_cache_frame_index) { 761 | sjpeg->io.raw_sjpg_data_next_read_pos = (int)(sjpeg->frame_base_offset [ sjpeg_req_frame_index ]); 762 | lv_fs_seek( &(sjpeg->io.lv_file), sjpeg->io.raw_sjpg_data_next_read_pos, LV_FS_SEEK_SET); 763 | 764 | rc = jd_prepare( sjpeg->tjpeg_jd, input_func, sjpeg->workb, (size_t)TJPGD_WORKBUFF_SIZE, &(sjpeg->io)); 765 | if(rc != JDR_OK ) return LV_RES_INV; 766 | 767 | rc = jd_decomp ( sjpeg->tjpeg_jd, img_data_cb, 0); 768 | if(rc != JDR_OK ) return LV_RES_INV; 769 | 770 | sjpeg->sjpeg_cache_frame_index = sjpeg_req_frame_index; 771 | } 772 | 773 | int offset = 0; 774 | uint8_t *cache = (uint8_t *)sjpeg->frame_cache + x*3 + ( y % sjpeg->sjpeg_single_frame_height ) * sjpeg->sjpeg_x_res*3; 775 | 776 | #if LV_COLOR_DEPTH == 32 777 | for( int i = 0; i < len; i++ ) { 778 | buf[offset + 3] = 0xff; 779 | buf[offset + 2] = *cache++; 780 | buf[offset + 1] = *cache++; 781 | buf[offset + 0] = *cache++; 782 | offset += 4; 783 | } 784 | #elif LV_COLOR_DEPTH == 16 785 | 786 | for( int i = 0; i < len; i++ ) { 787 | uint16_t col_8bit = (*cache++ & 0xf8) << 8; 788 | col_8bit |= (*cache++ & 0xFC) << 3; 789 | col_8bit |= (*cache++ >> 3); 790 | #if LV_BIG_ENDIAN_SYSTEM == 1 791 | buf[offset++] = col_8bit >> 8; 792 | buf[offset++] = col_8bit & 0xff; 793 | #else 794 | buf[offset++] = col_8bit & 0xff; 795 | buf[offset++] = col_8bit >> 8; 796 | #endif // LV_BIG_ENDIAN_SYSTEM 797 | } 798 | 799 | #elif LV_COLOR_DEPTH == 8 800 | 801 | for( int i = 0; i < len; i++ ) { 802 | uint8_t col_8bit = (*cache++ & 0xC0); 803 | col_8bit |= (*cache++ & 0xe0) >> 2; 804 | col_8bit |= (*cache++ & 0xe0) >> 5; 805 | buf[offset++] = col_8bit; 806 | } 807 | 808 | #else 809 | #error Unsupported LV_COLOR_DEPTH 810 | 811 | 812 | #endif // LV_COLOR_DEPTH 813 | 814 | return LV_RES_OK; 815 | } 816 | end: 817 | return LV_RES_INV; 818 | } 819 | 820 | /** 821 | * Free the allocated resources 822 | * @param decoder pointer to the decoder where this function belongs 823 | * @param dsc pointer to a descriptor which describes this decoding session 824 | */ 825 | static void decoder_close( lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc ) 826 | { 827 | /*Free all allocated data*/ 828 | SJPEG* sjpeg = ( SJPEG* ) dsc->user_data; 829 | if(!sjpeg) return; 830 | 831 | switch(dsc->src_type) { 832 | case LV_IMG_SRC_FILE: 833 | if(sjpeg->io.lv_file.file_d) { 834 | lv_fs_close(&(sjpeg->io.lv_file)); 835 | } 836 | lv_sjpg_cleanup(sjpeg); 837 | break; 838 | 839 | case LV_IMG_SRC_VARIABLE: 840 | lv_sjpg_cleanup(sjpeg); 841 | break; 842 | 843 | default: 844 | ; 845 | } 846 | } 847 | 848 | static int is_jpg( const uint8_t *raw_data ) 849 | { 850 | const uint8_t jpg_signature[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46};//JFIF 851 | return memcmp( jpg_signature, raw_data, sizeof( jpg_signature ) ) == 0; 852 | } 853 | 854 | static void lv_sjpg_free( SJPEG* sjpeg ) 855 | { 856 | if(sjpeg->frame_cache) lv_mem_free(sjpeg->frame_cache); 857 | if(sjpeg->frame_base_array) lv_mem_free(sjpeg->frame_base_array); 858 | if(sjpeg->frame_base_offset) lv_mem_free(sjpeg->frame_base_offset); 859 | if(sjpeg->tjpeg_jd) lv_mem_free(sjpeg->tjpeg_jd); 860 | if(sjpeg->workb) lv_mem_free(sjpeg->workb); 861 | } 862 | 863 | static void lv_sjpg_cleanup( SJPEG* sjpeg ) 864 | { 865 | if(! sjpeg ) return; 866 | 867 | lv_sjpg_free( sjpeg ); 868 | lv_mem_free( sjpeg ); 869 | } 870 | -------------------------------------------------------------------------------- /lv_sjpg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lv_sjpg.h 3 | * 4 | */ 5 | 6 | #ifndef _LV_SJPEG_ 7 | #define _LV_SJPEG_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | /********************* 14 | * INCLUDES 15 | *********************/ 16 | 17 | #include 18 | #include "tjpgd.h" 19 | 20 | #ifdef LV_LVGL_H_INCLUDE_SIMPLE 21 | #include 22 | #else 23 | #include 24 | #endif 25 | 26 | /********************* 27 | * DEFINES 28 | *********************/ 29 | 30 | 31 | /********************** 32 | * TYPEDEFS 33 | **********************/ 34 | enum io_source_type { 35 | SJPEG_IO_SOURCE_C_ARRAY, 36 | SJPEG_IO_SOURCE_DISK, 37 | }; 38 | 39 | typedef struct { 40 | enum io_source_type type; 41 | lv_fs_file_t lv_file; 42 | uint8_t* img_cache_buff; 43 | int img_cache_x_res; 44 | int img_cache_y_res; 45 | uint8_t *raw_sjpg_data; //Used when type==SJPEG_IO_SOURCE_C_ARRAY. 46 | uint32_t raw_sjpg_data_size; //Num bytes pointed to by raw_sjpg_data. 47 | uint32_t raw_sjpg_data_next_read_pos; //Used for all types. 48 | } io_source_t; 49 | 50 | 51 | typedef struct { 52 | uint8_t *sjpeg_data; 53 | uint32_t sjpeg_data_size; 54 | int sjpeg_x_res; 55 | int sjpeg_y_res; 56 | int sjpeg_total_frames; 57 | int sjpeg_single_frame_height; 58 | int sjpeg_cache_frame_index; 59 | uint8_t **frame_base_array; //to save base address of each split frames upto sjpeg_total_frames. 60 | int *frame_base_offset; //to save base offset for fseek 61 | uint8_t *frame_cache; 62 | uint8_t* workb; //JPG work buffer for jpeg library 63 | JDEC *tjpeg_jd; 64 | io_source_t io; 65 | } SJPEG; 66 | 67 | 68 | /********************** 69 | * GLOBAL PROTOTYPES 70 | **********************/ 71 | 72 | void lv_split_jpeg_init(void); 73 | 74 | /********************** 75 | * MACROS 76 | **********************/ 77 | 78 | 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif /* _LV_JPEG_WRAPPER */ 85 | -------------------------------------------------------------------------------- /scripts/jpg_to_sjpg.py: -------------------------------------------------------------------------------- 1 | ################################################################## 2 | # sjpeg converter script version 1.0 3 | # Dependencies: (PYTHON-3) 4 | ################################################################## 5 | SJPG_FILE_FORMAT_VERSION = "V1.00" # 6 | JPEG_SPLIT_HEIGHT = 16 7 | ################################################################## 8 | import math, os, sys, time 9 | from PIL import Image 10 | 11 | 12 | OUTPUT_FILE_NAME = "" 13 | INPUT_FILE = "" 14 | 15 | 16 | if len(sys.argv) == 2: 17 | INPUT_FILE = sys.argv[1] 18 | OUTPUT_FILE_NAME = INPUT_FILE.split("/")[-1].split("\\")[-1].split(".")[0] 19 | else: 20 | print("usage:\n\t python " + sys.argv[0] + " input_file.jpg") 21 | sys.exit(0) 22 | 23 | try: 24 | im = Image.open(INPUT_FILE) 25 | except: 26 | print("\nFile not found!") 27 | sys.exit(0) 28 | 29 | 30 | print("\nConversion started...\n") 31 | start_time = time.time() 32 | width, height = im.size 33 | 34 | print("Input:") 35 | print("\t" + INPUT_FILE) 36 | print("\tRES = " + str(width) + " x " + str(height) + '\n') 37 | 38 | 39 | lenbuf = [] 40 | block_size = JPEG_SPLIT_HEIGHT; 41 | spilts = math.ceil(height/block_size) 42 | 43 | c_code = '''//LVGL SJPG C ARRAY\n#include "lvgl/lvgl.h"\n\nconst uint8_t ''' + OUTPUT_FILE_NAME + '''_map[] = {\n''' 44 | 45 | sjpeg_data = bytearray() 46 | sjpeg = bytearray() 47 | 48 | 49 | row_remaining = height; 50 | for i in range(spilts): 51 | if row_remaining < block_size: 52 | crop = im.crop((0, i*block_size, width, row_remaining + i*block_size)) 53 | else: 54 | crop = im.crop((0, i*block_size, width, block_size + i*block_size)) 55 | 56 | row_remaining = row_remaining - block_size; 57 | crop.save(str(i)+".jpg", quality=90) 58 | 59 | 60 | 61 | 62 | for i in range(spilts): 63 | f = open(str(i)+".jpg", "rb") 64 | a = f.read() 65 | f.close() 66 | sjpeg_data = sjpeg_data + a 67 | lenbuf.append(len(a)) 68 | 69 | header = bytearray() 70 | 71 | #4 BYTES 72 | header = header + bytearray("_SJPG__".encode("UTF-8")); 73 | 74 | #6 BYTES VERSION 75 | header = header + bytearray(("\x00" + SJPG_FILE_FORMAT_VERSION + "\x00").encode("UTF-8")); 76 | 77 | #WIDTH 2 BYTES 78 | header = header + width.to_bytes(2, byteorder='little'); 79 | 80 | #HEIGHT 2 BYTES 81 | header = header + height.to_bytes(2, byteorder='little'); 82 | 83 | #NUMBER OF ITEMS 2 BYTES 84 | header = header + spilts.to_bytes(2, byteorder='little'); 85 | 86 | #NUMBER OF ITEMS 2 BYTES 87 | header = header + int(JPEG_SPLIT_HEIGHT).to_bytes(2, byteorder='little'); 88 | 89 | for item_len in lenbuf: 90 | # WIDTH 2 BYTES 91 | header = header + item_len.to_bytes(2, byteorder='little'); 92 | 93 | 94 | data = bytearray() 95 | 96 | sjpeg = header + sjpeg_data; 97 | 98 | if 1: 99 | for i in range(len(lenbuf)): 100 | os.remove(str(i) + ".jpg") 101 | 102 | 103 | f = open(OUTPUT_FILE_NAME+".sjpg","wb"); 104 | f.write(sjpeg) 105 | f.close() 106 | 107 | new_line_threshold = 0 108 | for i in range(len(sjpeg)): 109 | c_code = c_code + "\t" + str(hex(sjpeg[i])) + "," 110 | new_line_threshold = new_line_threshold + 1 111 | if (new_line_threshold >= 16): 112 | c_code = c_code + "\n" 113 | new_line_threshold = 0 114 | 115 | 116 | c_code = c_code + "\n};\n\nlv_img_dsc_t " 117 | c_code = c_code + OUTPUT_FILE_NAME + " = {\n" 118 | c_code = c_code + "\t.header.always_zero = 0,\n" 119 | c_code = c_code + "\t.header.w = " + str(width) + ",\n" 120 | c_code = c_code + "\t.header.h = " + str(height) + ",\n" 121 | c_code = c_code + "\t.data_size = " + str(len(sjpeg)) + ",\n" 122 | c_code = c_code + "\t.header.cf = LV_IMG_CF_RAW,\n" 123 | c_code = c_code + "\t.data = " + OUTPUT_FILE_NAME+"_map" + ",\n};" 124 | 125 | 126 | f = open(OUTPUT_FILE_NAME + '.c', 'w') 127 | f.write(c_code) 128 | f.close() 129 | 130 | 131 | time_taken = (time.time() - start_time) 132 | 133 | print("Output:") 134 | print("\tTime taken = " + str(round(time_taken,2)) + " sec") 135 | print("\tbin size = " + str(round(len(sjpeg)/1024, 1)) + " KB" ) 136 | print("\t" + OUTPUT_FILE_NAME + ".sjpg\t(bin file)" + "\n\t" + OUTPUT_FILE_NAME + ".c\t\t(c array)") 137 | 138 | print("\nAll good!") 139 | -------------------------------------------------------------------------------- /scripts/small_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvgl/lv_lib_split_jpg/c292bfd196fdae251069efb5f1c2f0c1040d764f/scripts/small_image.jpg -------------------------------------------------------------------------------- /scripts/wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvgl/lv_lib_split_jpg/c292bfd196fdae251069efb5f1c2f0c1040d764f/scripts/wallpaper.jpg -------------------------------------------------------------------------------- /tjpgd.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------/ 2 | / TJpgDec - Tiny JPEG Decompressor R0.03 (C)ChaN, 2021 3 | /-----------------------------------------------------------------------------/ 4 | / The TJpgDec is a generic JPEG decompressor module for tiny embedded systems. 5 | / This is a free software that opened for education, research and commercial 6 | / developments under license policy of following terms. 7 | / 8 | / Copyright (C) 2021, ChaN, all right reserved. 9 | / 10 | / * The TJpgDec module is a free software and there is NO WARRANTY. 11 | / * No restriction on use. You can use, modify and redistribute it for 12 | / personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. 13 | / * Redistributions of source code must retain the above copyright notice. 14 | / 15 | /-----------------------------------------------------------------------------/ 16 | / Oct 04, 2011 R0.01 First release. 17 | / Feb 19, 2012 R0.01a Fixed decompression fails when scan starts with an escape seq. 18 | / Sep 03, 2012 R0.01b Added JD_TBLCLIP option. 19 | / Mar 16, 2019 R0.01c Supprted stdint.h. 20 | / Jul 01, 2020 R0.01d Fixed wrong integer type usage. 21 | / May 08, 2021 R0.02 Supprted grayscale image. Separated configuration options. 22 | / Jun 11, 2021 R0.02a Some performance improvement. 23 | / Jul 01, 2021 R0.03 Added JD_FASTDECODE option. 24 | / Some performance improvement. 25 | /----------------------------------------------------------------------------*/ 26 | 27 | #include "tjpgd.h" 28 | 29 | 30 | #if JD_FASTDECODE == 2 31 | #define HUFF_BIT 10 /* Bit length to apply fast huffman decode */ 32 | #define HUFF_LEN (1 << HUFF_BIT) 33 | #define HUFF_MASK (HUFF_LEN - 1) 34 | #endif 35 | 36 | 37 | /*-----------------------------------------------*/ 38 | /* Zigzag-order to raster-order conversion table */ 39 | /*-----------------------------------------------*/ 40 | 41 | static const uint8_t Zig[64] = { /* Zigzag-order to raster-order conversion table */ 42 | 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 43 | 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 44 | 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 45 | 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 46 | }; 47 | 48 | 49 | 50 | /*-------------------------------------------------*/ 51 | /* Input scale factor of Arai algorithm */ 52 | /* (scaled up 16 bits for fixed point operations) */ 53 | /*-------------------------------------------------*/ 54 | 55 | static const uint16_t Ipsf[64] = { /* See also aa_idct.png */ 56 | (uint16_t)(1.00000*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.17588*8192), (uint16_t)(1.00000*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.27590*8192), 57 | (uint16_t)(1.38704*8192), (uint16_t)(1.92388*8192), (uint16_t)(1.81226*8192), (uint16_t)(1.63099*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.08979*8192), (uint16_t)(0.75066*8192), (uint16_t)(0.38268*8192), 58 | (uint16_t)(1.30656*8192), (uint16_t)(1.81226*8192), (uint16_t)(1.70711*8192), (uint16_t)(1.53636*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.02656*8192), (uint16_t)(0.70711*8192), (uint16_t)(0.36048*8192), 59 | (uint16_t)(1.17588*8192), (uint16_t)(1.63099*8192), (uint16_t)(1.53636*8192), (uint16_t)(1.38268*8192), (uint16_t)(1.17588*8192), (uint16_t)(0.92388*8192), (uint16_t)(0.63638*8192), (uint16_t)(0.32442*8192), 60 | (uint16_t)(1.00000*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.17588*8192), (uint16_t)(1.00000*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.27590*8192), 61 | (uint16_t)(0.78570*8192), (uint16_t)(1.08979*8192), (uint16_t)(1.02656*8192), (uint16_t)(0.92388*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.61732*8192), (uint16_t)(0.42522*8192), (uint16_t)(0.21677*8192), 62 | (uint16_t)(0.54120*8192), (uint16_t)(0.75066*8192), (uint16_t)(0.70711*8192), (uint16_t)(0.63638*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.42522*8192), (uint16_t)(0.29290*8192), (uint16_t)(0.14932*8192), 63 | (uint16_t)(0.27590*8192), (uint16_t)(0.38268*8192), (uint16_t)(0.36048*8192), (uint16_t)(0.32442*8192), (uint16_t)(0.27590*8192), (uint16_t)(0.21678*8192), (uint16_t)(0.14932*8192), (uint16_t)(0.07612*8192) 64 | }; 65 | 66 | 67 | 68 | /*---------------------------------------------*/ 69 | /* Conversion table for fast clipping process */ 70 | /*---------------------------------------------*/ 71 | 72 | #if JD_TBLCLIP 73 | 74 | #define BYTECLIP(v) Clip8[(unsigned int)(v) & 0x3FF] 75 | 76 | static const uint8_t Clip8[1024] = { 77 | /* 0..255 */ 78 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 79 | 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 80 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 81 | 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 82 | 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 83 | 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 84 | 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 85 | 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 86 | /* 256..511 */ 87 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 88 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 89 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 90 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 91 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 92 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 93 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 94 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 95 | /* -512..-257 */ 96 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104 | /* -256..-1 */ 105 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 113 | }; 114 | 115 | #else /* JD_TBLCLIP */ 116 | 117 | static uint8_t BYTECLIP (int val) 118 | { 119 | if (val < 0) return 0; 120 | if (val > 255) return 255; 121 | return (uint8_t)val; 122 | } 123 | 124 | #endif 125 | 126 | 127 | 128 | /*-----------------------------------------------------------------------*/ 129 | /* Allocate a memory block from memory pool */ 130 | /*-----------------------------------------------------------------------*/ 131 | 132 | static void* alloc_pool ( /* Pointer to allocated memory block (NULL:no memory available) */ 133 | JDEC* jd, /* Pointer to the decompressor object */ 134 | size_t ndata /* Number of bytes to allocate */ 135 | ) 136 | { 137 | char *rp = 0; 138 | 139 | 140 | ndata = (ndata + 3) & ~3; /* Align block size to the word boundary */ 141 | 142 | if (jd->sz_pool >= ndata) { 143 | jd->sz_pool -= ndata; 144 | rp = (char*)jd->pool; /* Get start of available memory pool */ 145 | jd->pool = (void*)(rp + ndata); /* Allocate requierd bytes */ 146 | } 147 | 148 | return (void*)rp; /* Return allocated memory block (NULL:no memory to allocate) */ 149 | } 150 | 151 | 152 | 153 | 154 | /*-----------------------------------------------------------------------*/ 155 | /* Create de-quantization and prescaling tables with a DQT segment */ 156 | /*-----------------------------------------------------------------------*/ 157 | 158 | static JRESULT create_qt_tbl ( /* 0:OK, !0:Failed */ 159 | JDEC* jd, /* Pointer to the decompressor object */ 160 | const uint8_t* data, /* Pointer to the quantizer tables */ 161 | size_t ndata /* Size of input data */ 162 | ) 163 | { 164 | unsigned int i, zi; 165 | uint8_t d; 166 | int32_t *pb; 167 | 168 | 169 | while (ndata) { /* Process all tables in the segment */ 170 | if (ndata < 65) return JDR_FMT1; /* Err: table size is unaligned */ 171 | ndata -= 65; 172 | d = *data++; /* Get table property */ 173 | if (d & 0xF0) return JDR_FMT1; /* Err: not 8-bit resolution */ 174 | i = d & 3; /* Get table ID */ 175 | pb = alloc_pool(jd, 64 * sizeof (int32_t));/* Allocate a memory block for the table */ 176 | if (!pb) return JDR_MEM1; /* Err: not enough memory */ 177 | jd->qttbl[i] = pb; /* Register the table */ 178 | for (i = 0; i < 64; i++) { /* Load the table */ 179 | zi = Zig[i]; /* Zigzag-order to raster-order conversion */ 180 | pb[zi] = (int32_t)((uint32_t)*data++ * Ipsf[zi]); /* Apply scale factor of Arai algorithm to the de-quantizers */ 181 | } 182 | } 183 | 184 | return JDR_OK; 185 | } 186 | 187 | 188 | 189 | 190 | /*-----------------------------------------------------------------------*/ 191 | /* Create huffman code tables with a DHT segment */ 192 | /*-----------------------------------------------------------------------*/ 193 | 194 | static JRESULT create_huffman_tbl ( /* 0:OK, !0:Failed */ 195 | JDEC* jd, /* Pointer to the decompressor object */ 196 | const uint8_t* data, /* Pointer to the packed huffman tables */ 197 | size_t ndata /* Size of input data */ 198 | ) 199 | { 200 | unsigned int i, j, b, cls, num; 201 | size_t np; 202 | uint8_t d, *pb, *pd; 203 | uint16_t hc, *ph; 204 | 205 | 206 | while (ndata) { /* Process all tables in the segment */ 207 | if (ndata < 17) return JDR_FMT1; /* Err: wrong data size */ 208 | ndata -= 17; 209 | d = *data++; /* Get table number and class */ 210 | if (d & 0xEE) return JDR_FMT1; /* Err: invalid class/number */ 211 | cls = d >> 4; num = d & 0x0F; /* class = dc(0)/ac(1), table number = 0/1 */ 212 | pb = alloc_pool(jd, 16); /* Allocate a memory block for the bit distribution table */ 213 | if (!pb) return JDR_MEM1; /* Err: not enough memory */ 214 | jd->huffbits[num][cls] = pb; 215 | for (np = i = 0; i < 16; i++) { /* Load number of patterns for 1 to 16-bit code */ 216 | np += (pb[i] = *data++); /* Get sum of code words for each code */ 217 | } 218 | ph = alloc_pool(jd, np * sizeof (uint16_t));/* Allocate a memory block for the code word table */ 219 | if (!ph) return JDR_MEM1; /* Err: not enough memory */ 220 | jd->huffcode[num][cls] = ph; 221 | hc = 0; 222 | for (j = i = 0; i < 16; i++) { /* Re-build huffman code word table */ 223 | b = pb[i]; 224 | while (b--) ph[j++] = hc++; 225 | hc <<= 1; 226 | } 227 | 228 | if (ndata < np) return JDR_FMT1; /* Err: wrong data size */ 229 | ndata -= np; 230 | pd = alloc_pool(jd, np); /* Allocate a memory block for the decoded data */ 231 | if (!pd) return JDR_MEM1; /* Err: not enough memory */ 232 | jd->huffdata[num][cls] = pd; 233 | for (i = 0; i < np; i++) { /* Load decoded data corresponds to each code word */ 234 | d = *data++; 235 | if (!cls && d > 11) return JDR_FMT1; 236 | pd[i] = d; 237 | } 238 | #if JD_FASTDECODE == 2 239 | { /* Create fast huffman decode table */ 240 | unsigned int span, td, ti; 241 | uint16_t *tbl_ac = 0; 242 | uint8_t *tbl_dc = 0; 243 | 244 | if (cls) { 245 | tbl_ac = alloc_pool(jd, HUFF_LEN * sizeof (uint16_t)); /* LUT for AC elements */ 246 | if (!tbl_ac) return JDR_MEM1; /* Err: not enough memory */ 247 | jd->hufflut_ac[num] = tbl_ac; 248 | memset(tbl_ac, 0xFF, HUFF_LEN * sizeof (uint16_t)); /* Default value (0xFFFF: may be long code) */ 249 | } else { 250 | tbl_dc = alloc_pool(jd, HUFF_LEN * sizeof (uint8_t)); /* LUT for AC elements */ 251 | if (!tbl_dc) return JDR_MEM1; /* Err: not enough memory */ 252 | jd->hufflut_dc[num] = tbl_dc; 253 | memset(tbl_dc, 0xFF, HUFF_LEN * sizeof (uint8_t)); /* Default value (0xFF: may be long code) */ 254 | } 255 | for (i = b = 0; b < HUFF_BIT; b++) { /* Create LUT */ 256 | for (j = pb[b]; j; j--) { 257 | ti = ph[i] << (HUFF_BIT - 1 - b) & HUFF_MASK; /* Index of input pattern for the code */ 258 | if (cls) { 259 | td = pd[i++] | ((b + 1) << 8); /* b15..b8: code length, b7..b0: zero run and data length */ 260 | for (span = 1 << (HUFF_BIT - 1 - b); span; span--, tbl_ac[ti++] = (uint16_t)td) ; 261 | } else { 262 | td = pd[i++] | ((b + 1) << 4); /* b7..b4: code length, b3..b0: data length */ 263 | for (span = 1 << (HUFF_BIT - 1 - b); span; span--, tbl_dc[ti++] = (uint8_t)td) ; 264 | } 265 | } 266 | } 267 | jd->longofs[num][cls] = i; /* Code table offset for long code */ 268 | } 269 | #endif 270 | } 271 | 272 | return JDR_OK; 273 | } 274 | 275 | 276 | 277 | 278 | /*-----------------------------------------------------------------------*/ 279 | /* Extract a huffman decoded data from input stream */ 280 | /*-----------------------------------------------------------------------*/ 281 | 282 | static int huffext ( /* >=0: decoded data, <0: error code */ 283 | JDEC* jd, /* Pointer to the decompressor object */ 284 | unsigned int id, /* Table ID (0:Y, 1:C) */ 285 | unsigned int cls /* Table class (0:DC, 1:AC) */ 286 | ) 287 | { 288 | size_t dc = jd->dctr; 289 | uint8_t *dp = jd->dptr; 290 | unsigned int d, flg = 0; 291 | 292 | #if JD_FASTDECODE == 0 293 | uint8_t bm, nd, bl; 294 | const uint8_t *hb = jd->huffbits[id][cls]; /* Bit distribution table */ 295 | const uint16_t *hc = jd->huffcode[id][cls]; /* Code word table */ 296 | const uint8_t *hd = jd->huffdata[id][cls]; /* Data table */ 297 | 298 | 299 | bm = jd->dbit; /* Bit mask to extract */ 300 | d = 0; bl = 16; /* Max code length */ 301 | do { 302 | if (!bm) { /* Next byte? */ 303 | if (!dc) { /* No input data is available, re-fill input buffer */ 304 | dp = jd->inbuf; /* Top of input buffer */ 305 | dc = jd->infunc(jd, dp, JD_SZBUF); 306 | if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */ 307 | } else { 308 | dp++; /* Next data ptr */ 309 | } 310 | dc--; /* Decrement number of available bytes */ 311 | if (flg) { /* In flag sequence? */ 312 | flg = 0; /* Exit flag sequence */ 313 | if (*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */ 314 | *dp = 0xFF; /* The flag is a data 0xFF */ 315 | } else { 316 | if (*dp == 0xFF) { /* Is start of flag sequence? */ 317 | flg = 1; continue; /* Enter flag sequence, get trailing byte */ 318 | } 319 | } 320 | bm = 0x80; /* Read from MSB */ 321 | } 322 | d <<= 1; /* Get a bit */ 323 | if (*dp & bm) d++; 324 | bm >>= 1; 325 | 326 | for (nd = *hb++; nd; nd--) { /* Search the code word in this bit length */ 327 | if (d == *hc++) { /* Matched? */ 328 | jd->dbit = bm; jd->dctr = dc; jd->dptr = dp; 329 | return *hd; /* Return the decoded data */ 330 | } 331 | hd++; 332 | } 333 | bl--; 334 | } while (bl); 335 | 336 | #else 337 | const uint8_t *hb, *hd; 338 | const uint16_t *hc; 339 | unsigned int nc, bl, wbit = jd->dbit % 32; 340 | uint32_t w = jd->wreg & ((1UL << wbit) - 1); 341 | 342 | 343 | while (wbit < 16) { /* Prepare 16 bits into the working register */ 344 | if (jd->marker) { 345 | d = 0xFF; /* Input stream has stalled for a marker. Generate stuff bits */ 346 | } else { 347 | if (!dc) { /* Buffer empty, re-fill input buffer */ 348 | dp = jd->inbuf; /* Top of input buffer */ 349 | dc = jd->infunc(jd, dp, JD_SZBUF); 350 | if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */ 351 | } 352 | d = *dp++; dc--; 353 | if (flg) { /* In flag sequence? */ 354 | flg = 0; /* Exit flag sequence */ 355 | if (d != 0) jd->marker = d; /* Not an escape of 0xFF but a marker */ 356 | d = 0xFF; 357 | } else { 358 | if (d == 0xFF) { /* Is start of flag sequence? */ 359 | flg = 1; continue; /* Enter flag sequence, get trailing byte */ 360 | } 361 | } 362 | } 363 | w = w << 8 | d; /* Shift 8 bits in the working register */ 364 | wbit += 8; 365 | } 366 | jd->dctr = dc; jd->dptr = dp; 367 | jd->wreg = w; 368 | 369 | #if JD_FASTDECODE == 2 370 | /* Table serch for the short codes */ 371 | d = (unsigned int)(w >> (wbit - HUFF_BIT)); /* Short code as table index */ 372 | if (cls) { /* AC element */ 373 | d = jd->hufflut_ac[id][d]; /* Table decode */ 374 | if (d != 0xFFFF) { /* It is done if hit in short code */ 375 | jd->dbit = wbit - (d >> 8); /* Snip the code length */ 376 | return d & 0xFF; /* b7..0: zero run and following data bits */ 377 | } 378 | } else { /* DC element */ 379 | d = jd->hufflut_dc[id][d]; /* Table decode */ 380 | if (d != 0xFF) { /* It is done if hit in short code */ 381 | jd->dbit = wbit - (d >> 4); /* Snip the code length */ 382 | return d & 0xF; /* b3..0: following data bits */ 383 | } 384 | } 385 | 386 | /* Incremental serch for the codes longer than HUFF_BIT */ 387 | hb = jd->huffbits[id][cls] + HUFF_BIT; /* Bit distribution table */ 388 | hc = jd->huffcode[id][cls] + jd->longofs[id][cls]; /* Code word table */ 389 | hd = jd->huffdata[id][cls] + jd->longofs[id][cls]; /* Data table */ 390 | bl = HUFF_BIT + 1; 391 | #else 392 | /* Incremental serch for all codes */ 393 | hb = jd->huffbits[id][cls]; /* Bit distribution table */ 394 | hc = jd->huffcode[id][cls]; /* Code word table */ 395 | hd = jd->huffdata[id][cls]; /* Data table */ 396 | bl = 1; 397 | #endif 398 | for ( ; bl <= 16; bl++) { /* Incremental search */ 399 | nc = *hb++; 400 | if (nc) { 401 | d = w >> (wbit - bl); 402 | do { /* Search the code word in this bit length */ 403 | if (d == *hc++) { /* Matched? */ 404 | jd->dbit = wbit - bl; /* Snip the huffman code */ 405 | return *hd; /* Return the decoded data */ 406 | } 407 | hd++; 408 | } while (--nc); 409 | } 410 | } 411 | #endif 412 | 413 | return 0 - (int)JDR_FMT1; /* Err: code not found (may be collapted data) */ 414 | } 415 | 416 | 417 | 418 | 419 | /*-----------------------------------------------------------------------*/ 420 | /* Extract N bits from input stream */ 421 | /*-----------------------------------------------------------------------*/ 422 | 423 | static int bitext ( /* >=0: extracted data, <0: error code */ 424 | JDEC* jd, /* Pointer to the decompressor object */ 425 | unsigned int nbit /* Number of bits to extract (1 to 16) */ 426 | ) 427 | { 428 | size_t dc = jd->dctr; 429 | uint8_t *dp = jd->dptr; 430 | unsigned int d, flg = 0; 431 | 432 | #if JD_FASTDECODE == 0 433 | uint8_t mbit = jd->dbit; 434 | 435 | d = 0; 436 | do { 437 | if (!mbit) { /* Next byte? */ 438 | if (!dc) { /* No input data is available, re-fill input buffer */ 439 | dp = jd->inbuf; /* Top of input buffer */ 440 | dc = jd->infunc(jd, dp, JD_SZBUF); 441 | if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */ 442 | } else { 443 | dp++; /* Next data ptr */ 444 | } 445 | dc--; /* Decrement number of available bytes */ 446 | if (flg) { /* In flag sequence? */ 447 | flg = 0; /* Exit flag sequence */ 448 | if (*dp != 0) return 0 - (int)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */ 449 | *dp = 0xFF; /* The flag is a data 0xFF */ 450 | } else { 451 | if (*dp == 0xFF) { /* Is start of flag sequence? */ 452 | flg = 1; continue; /* Enter flag sequence */ 453 | } 454 | } 455 | mbit = 0x80; /* Read from MSB */ 456 | } 457 | d <<= 1; /* Get a bit */ 458 | if (*dp & mbit) d |= 1; 459 | mbit >>= 1; 460 | nbit--; 461 | } while (nbit); 462 | 463 | jd->dbit = mbit; jd->dctr = dc; jd->dptr = dp; 464 | return (int)d; 465 | 466 | #else 467 | unsigned int wbit = jd->dbit % 32; 468 | uint32_t w = jd->wreg & ((1UL << wbit) - 1); 469 | 470 | 471 | while (wbit < nbit) { /* Prepare nbit bits into the working register */ 472 | if (jd->marker) { 473 | d = 0xFF; /* Input stream stalled, generate stuff bits */ 474 | } else { 475 | if (!dc) { /* Buffer empty, re-fill input buffer */ 476 | dp = jd->inbuf; /* Top of input buffer */ 477 | dc = jd->infunc(jd, dp, JD_SZBUF); 478 | if (!dc) return 0 - (int)JDR_INP; /* Err: read error or wrong stream termination */ 479 | } 480 | d = *dp++; dc--; 481 | if (flg) { /* In flag sequence? */ 482 | flg = 0; /* Exit flag sequence */ 483 | if (d != 0) jd->marker = d; /* Not an escape of 0xFF but a marker */ 484 | d = 0xFF; 485 | } else { 486 | if (d == 0xFF) { /* Is start of flag sequence? */ 487 | flg = 1; continue; /* Enter flag sequence, get trailing byte */ 488 | } 489 | } 490 | } 491 | w = w << 8 | d; /* Get 8 bits into the working register */ 492 | wbit += 8; 493 | } 494 | jd->wreg = w; jd->dbit = wbit - nbit; 495 | jd->dctr = dc; jd->dptr = dp; 496 | 497 | return (int)(w >> ((wbit - nbit) % 32)); 498 | #endif 499 | } 500 | 501 | 502 | 503 | 504 | /*-----------------------------------------------------------------------*/ 505 | /* Process restart interval */ 506 | /*-----------------------------------------------------------------------*/ 507 | 508 | static JRESULT restart ( 509 | JDEC* jd, /* Pointer to the decompressor object */ 510 | uint16_t rstn /* Expected restert sequense number */ 511 | ) 512 | { 513 | unsigned int i; 514 | uint8_t *dp = jd->dptr; 515 | size_t dc = jd->dctr; 516 | 517 | #if JD_FASTDECODE == 0 518 | uint16_t d = 0; 519 | 520 | /* Get two bytes from the input stream */ 521 | for (i = 0; i < 2; i++) { 522 | if (!dc) { /* No input data is available, re-fill input buffer */ 523 | dp = jd->inbuf; 524 | dc = jd->infunc(jd, dp, JD_SZBUF); 525 | if (!dc) return JDR_INP; 526 | } else { 527 | dp++; 528 | } 529 | dc--; 530 | d = d << 8 | *dp; /* Get a byte */ 531 | } 532 | jd->dptr = dp; jd->dctr = dc; jd->dbit = 0; 533 | 534 | /* Check the marker */ 535 | if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7)) { 536 | return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be collapted data) */ 537 | } 538 | 539 | #else 540 | uint16_t marker; 541 | 542 | 543 | if (jd->marker) { /* Generate a maker if it has been detected */ 544 | marker = 0xFF00 | jd->marker; 545 | jd->marker = 0; 546 | } else { 547 | marker = 0; 548 | for (i = 0; i < 2; i++) { /* Get a restart marker */ 549 | if (!dc) { /* No input data is available, re-fill input buffer */ 550 | dp = jd->inbuf; 551 | dc = jd->infunc(jd, dp, JD_SZBUF); 552 | if (!dc) return JDR_INP; 553 | } 554 | marker = (marker << 8) | *dp++; /* Get a byte */ 555 | dc--; 556 | } 557 | jd->dptr = dp; jd->dctr = dc; 558 | } 559 | 560 | /* Check the marker */ 561 | if ((marker & 0xFFD8) != 0xFFD0 || (marker & 7) != (rstn & 7)) { 562 | return JDR_FMT1; /* Err: expected RSTn marker was not detected (may be collapted data) */ 563 | } 564 | 565 | jd->dbit = 0; /* Discard stuff bits */ 566 | #endif 567 | 568 | jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Reset DC offset */ 569 | return JDR_OK; 570 | } 571 | 572 | 573 | 574 | 575 | /*-----------------------------------------------------------------------*/ 576 | /* Apply Inverse-DCT in Arai Algorithm (see also aa_idct.png) */ 577 | /*-----------------------------------------------------------------------*/ 578 | 579 | static void block_idct ( 580 | int32_t* src, /* Input block data (de-quantized and pre-scaled for Arai Algorithm) */ 581 | jd_yuv_t* dst /* Pointer to the destination to store the block as byte array */ 582 | ) 583 | { 584 | const int32_t M13 = (int32_t)(1.41421*4096), M2 = (int32_t)(1.08239*4096), M4 = (int32_t)(2.61313*4096), M5 = (int32_t)(1.84776*4096); 585 | int32_t v0, v1, v2, v3, v4, v5, v6, v7; 586 | int32_t t10, t11, t12, t13; 587 | int i; 588 | 589 | /* Process columns */ 590 | for (i = 0; i < 8; i++) { 591 | v0 = src[8 * 0]; /* Get even elements */ 592 | v1 = src[8 * 2]; 593 | v2 = src[8 * 4]; 594 | v3 = src[8 * 6]; 595 | 596 | t10 = v0 + v2; /* Process the even elements */ 597 | t12 = v0 - v2; 598 | t11 = (v1 - v3) * M13 >> 12; 599 | v3 += v1; 600 | t11 -= v3; 601 | v0 = t10 + v3; 602 | v3 = t10 - v3; 603 | v1 = t11 + t12; 604 | v2 = t12 - t11; 605 | 606 | v4 = src[8 * 7]; /* Get odd elements */ 607 | v5 = src[8 * 1]; 608 | v6 = src[8 * 5]; 609 | v7 = src[8 * 3]; 610 | 611 | t10 = v5 - v4; /* Process the odd elements */ 612 | t11 = v5 + v4; 613 | t12 = v6 - v7; 614 | v7 += v6; 615 | v5 = (t11 - v7) * M13 >> 12; 616 | v7 += t11; 617 | t13 = (t10 + t12) * M5 >> 12; 618 | v4 = t13 - (t10 * M2 >> 12); 619 | v6 = t13 - (t12 * M4 >> 12) - v7; 620 | v5 -= v6; 621 | v4 -= v5; 622 | 623 | src[8 * 0] = v0 + v7; /* Write-back transformed values */ 624 | src[8 * 7] = v0 - v7; 625 | src[8 * 1] = v1 + v6; 626 | src[8 * 6] = v1 - v6; 627 | src[8 * 2] = v2 + v5; 628 | src[8 * 5] = v2 - v5; 629 | src[8 * 3] = v3 + v4; 630 | src[8 * 4] = v3 - v4; 631 | 632 | src++; /* Next column */ 633 | } 634 | 635 | /* Process rows */ 636 | src -= 8; 637 | for (i = 0; i < 8; i++) { 638 | v0 = src[0] + (128L << 8); /* Get even elements (remove DC offset (-128) here) */ 639 | v1 = src[2]; 640 | v2 = src[4]; 641 | v3 = src[6]; 642 | 643 | t10 = v0 + v2; /* Process the even elements */ 644 | t12 = v0 - v2; 645 | t11 = (v1 - v3) * M13 >> 12; 646 | v3 += v1; 647 | t11 -= v3; 648 | v0 = t10 + v3; 649 | v3 = t10 - v3; 650 | v1 = t11 + t12; 651 | v2 = t12 - t11; 652 | 653 | v4 = src[7]; /* Get odd elements */ 654 | v5 = src[1]; 655 | v6 = src[5]; 656 | v7 = src[3]; 657 | 658 | t10 = v5 - v4; /* Process the odd elements */ 659 | t11 = v5 + v4; 660 | t12 = v6 - v7; 661 | v7 += v6; 662 | v5 = (t11 - v7) * M13 >> 12; 663 | v7 += t11; 664 | t13 = (t10 + t12) * M5 >> 12; 665 | v4 = t13 - (t10 * M2 >> 12); 666 | v6 = t13 - (t12 * M4 >> 12) - v7; 667 | v5 -= v6; 668 | v4 -= v5; 669 | 670 | /* Descale the transformed values 8 bits and output a row */ 671 | #if JD_FASTDECODE >= 1 672 | dst[0] = (int16_t)((v0 + v7) >> 8); 673 | dst[7] = (int16_t)((v0 - v7) >> 8); 674 | dst[1] = (int16_t)((v1 + v6) >> 8); 675 | dst[6] = (int16_t)((v1 - v6) >> 8); 676 | dst[2] = (int16_t)((v2 + v5) >> 8); 677 | dst[5] = (int16_t)((v2 - v5) >> 8); 678 | dst[3] = (int16_t)((v3 + v4) >> 8); 679 | dst[4] = (int16_t)((v3 - v4) >> 8); 680 | #else 681 | dst[0] = BYTECLIP((v0 + v7) >> 8); 682 | dst[7] = BYTECLIP((v0 - v7) >> 8); 683 | dst[1] = BYTECLIP((v1 + v6) >> 8); 684 | dst[6] = BYTECLIP((v1 - v6) >> 8); 685 | dst[2] = BYTECLIP((v2 + v5) >> 8); 686 | dst[5] = BYTECLIP((v2 - v5) >> 8); 687 | dst[3] = BYTECLIP((v3 + v4) >> 8); 688 | dst[4] = BYTECLIP((v3 - v4) >> 8); 689 | #endif 690 | 691 | dst += 8; src += 8; /* Next row */ 692 | } 693 | } 694 | 695 | 696 | 697 | 698 | /*-----------------------------------------------------------------------*/ 699 | /* Load all blocks in an MCU into working buffer */ 700 | /*-----------------------------------------------------------------------*/ 701 | 702 | static JRESULT mcu_load ( 703 | JDEC* jd /* Pointer to the decompressor object */ 704 | ) 705 | { 706 | int32_t *tmp = (int32_t*)jd->workbuf; /* Block working buffer for de-quantize and IDCT */ 707 | int d, e; 708 | unsigned int blk, nby, i, bc, z, id, cmp; 709 | jd_yuv_t *bp; 710 | const int32_t *dqf; 711 | 712 | 713 | nby = jd->msx * jd->msy; /* Number of Y blocks (1, 2 or 4) */ 714 | bp = jd->mcubuf; /* Pointer to the first block of MCU */ 715 | 716 | for (blk = 0; blk < nby + 2; blk++) { /* Get nby Y blocks and two C blocks */ 717 | cmp = (blk < nby) ? 0 : blk - nby + 1; /* Component number 0:Y, 1:Cb, 2:Cr */ 718 | 719 | if (cmp && jd->ncomp != 3) { /* Clear C blocks if not exist (monochrome image) */ 720 | for (i = 0; i < 64; bp[i++] = 128) ; 721 | 722 | } else { /* Load Y/C blocks from input stream */ 723 | id = cmp ? 1 : 0; /* Huffman table ID of this component */ 724 | 725 | /* Extract a DC element from input stream */ 726 | d = huffext(jd, id, 0); /* Extract a huffman coded data (bit length) */ 727 | if (d < 0) return (JRESULT)(0 - d); /* Err: invalid code or input */ 728 | bc = (unsigned int)d; 729 | d = jd->dcv[cmp]; /* DC value of previous block */ 730 | if (bc) { /* If there is any difference from previous block */ 731 | e = bitext(jd, bc); /* Extract data bits */ 732 | if (e < 0) return (JRESULT)(0 - e); /* Err: input */ 733 | bc = 1 << (bc - 1); /* MSB position */ 734 | if (!(e & bc)) e -= (bc << 1) - 1; /* Restore negative value if needed */ 735 | d += e; /* Get current value */ 736 | jd->dcv[cmp] = (int16_t)d; /* Save current DC value for next block */ 737 | } 738 | dqf = jd->qttbl[jd->qtid[cmp]]; /* De-quantizer table ID for this component */ 739 | tmp[0] = d * dqf[0] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */ 740 | 741 | /* Extract following 63 AC elements from input stream */ 742 | memset(&tmp[1], 0, 63 * sizeof (int32_t)); /* Initialize all AC elements */ 743 | z = 1; /* Top of the AC elements (in zigzag-order) */ 744 | do { 745 | d = huffext(jd, id, 1); /* Extract a huffman coded value (zero runs and bit length) */ 746 | if (d == 0) break; /* EOB? */ 747 | if (d < 0) return (JRESULT)(0 - d); /* Err: invalid code or input error */ 748 | bc = (unsigned int)d; 749 | z += bc >> 4; /* Skip leading zero run */ 750 | if (z >= 64) return JDR_FMT1; /* Too long zero run */ 751 | if (bc &= 0x0F) { /* Bit length? */ 752 | d = bitext(jd, bc); /* Extract data bits */ 753 | if (d < 0) return (JRESULT)(0 - d); /* Err: input device */ 754 | bc = 1 << (bc - 1); /* MSB position */ 755 | if (!(d & bc)) d -= (bc << 1) - 1; /* Restore negative value if needed */ 756 | i = Zig[z]; /* Get raster-order index */ 757 | tmp[i] = d * dqf[i] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */ 758 | } 759 | } while (++z < 64); /* Next AC element */ 760 | 761 | if (JD_FORMAT != 2 || !cmp) { /* C components may not be processed if in grayscale output */ 762 | if (z == 1 || (JD_USE_SCALE && jd->scale == 3)) { /* If no AC element or scale ratio is 1/8, IDCT can be ommited and the block is filled with DC value */ 763 | d = (jd_yuv_t)((*tmp / 256) + 128); 764 | if (JD_FASTDECODE >= 1) { 765 | for (i = 0; i < 64; bp[i++] = d) ; 766 | } else { 767 | memset(bp, d, 64); 768 | } 769 | } else { 770 | block_idct(tmp, bp); /* Apply IDCT and store the block to the MCU buffer */ 771 | } 772 | } 773 | } 774 | 775 | bp += 64; /* Next block */ 776 | } 777 | 778 | return JDR_OK; /* All blocks have been loaded successfully */ 779 | } 780 | 781 | 782 | 783 | 784 | /*-----------------------------------------------------------------------*/ 785 | /* Output an MCU: Convert YCrCb to RGB and output it in RGB form */ 786 | /*-----------------------------------------------------------------------*/ 787 | 788 | static JRESULT mcu_output ( 789 | JDEC* jd, /* Pointer to the decompressor object */ 790 | int (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ 791 | unsigned int x, /* MCU location in the image */ 792 | unsigned int y /* MCU location in the image */ 793 | ) 794 | { 795 | const int CVACC = (sizeof (int) > 2) ? 1024 : 128; /* Adaptive accuracy for both 16-/32-bit systems */ 796 | unsigned int ix, iy, mx, my, rx, ry; 797 | int yy, cb, cr; 798 | jd_yuv_t *py, *pc; 799 | uint8_t *pix; 800 | JRECT rect; 801 | 802 | 803 | mx = jd->msx * 8; my = jd->msy * 8; /* MCU size (pixel) */ 804 | rx = (x + mx <= jd->width) ? mx : jd->width - x; /* Output rectangular size (it may be clipped at right/bottom end of image) */ 805 | ry = (y + my <= jd->height) ? my : jd->height - y; 806 | if (JD_USE_SCALE) { 807 | rx >>= jd->scale; ry >>= jd->scale; 808 | if (!rx || !ry) return JDR_OK; /* Skip this MCU if all pixel is to be rounded off */ 809 | x >>= jd->scale; y >>= jd->scale; 810 | } 811 | rect.left = x; rect.right = x + rx - 1; /* Rectangular area in the frame buffer */ 812 | rect.top = y; rect.bottom = y + ry - 1; 813 | 814 | 815 | if (!JD_USE_SCALE || jd->scale != 3) { /* Not for 1/8 scaling */ 816 | pix = (uint8_t*)jd->workbuf; 817 | 818 | if (JD_FORMAT != 2) { /* RGB output (build an RGB MCU from Y/C component) */ 819 | for (iy = 0; iy < my; iy++) { 820 | pc = py = jd->mcubuf; 821 | if (my == 16) { /* Double block height? */ 822 | pc += 64 * 4 + (iy >> 1) * 8; 823 | if (iy >= 8) py += 64; 824 | } else { /* Single block height */ 825 | pc += mx * 8 + iy * 8; 826 | } 827 | py += iy * 8; 828 | for (ix = 0; ix < mx; ix++) { 829 | cb = pc[0] - 128; /* Get Cb/Cr component and remove offset */ 830 | cr = pc[64] - 128; 831 | if (mx == 16) { /* Double block width? */ 832 | if (ix == 8) py += 64 - 8; /* Jump to next block if double block heigt */ 833 | pc += ix & 1; /* Step forward chroma pointer every two pixels */ 834 | } else { /* Single block width */ 835 | pc++; /* Step forward chroma pointer every pixel */ 836 | } 837 | yy = *py++; /* Get Y component */ 838 | *pix++ = /*R*/ BYTECLIP(yy + ((int)(1.402 * CVACC) * cr) / CVACC); 839 | *pix++ = /*G*/ BYTECLIP(yy - ((int)(0.344 * CVACC) * cb + (int)(0.714 * CVACC) * cr) / CVACC); 840 | *pix++ = /*B*/ BYTECLIP(yy + ((int)(1.772 * CVACC) * cb) / CVACC); 841 | } 842 | } 843 | } else { /* Monochrome output (build a grayscale MCU from Y comopnent) */ 844 | for (iy = 0; iy < my; iy++) { 845 | py = jd->mcubuf + iy * 8; 846 | if (my == 16) { /* Double block height? */ 847 | if (iy >= 8) py += 64; 848 | } 849 | for (ix = 0; ix < mx; ix++) { 850 | if (mx == 16) { /* Double block width? */ 851 | if (ix == 8) py += 64 - 8; /* Jump to next block if double block height */ 852 | } 853 | *pix++ = (uint8_t)*py++; /* Get and store a Y value as grayscale */ 854 | } 855 | } 856 | } 857 | 858 | /* Descale the MCU rectangular if needed */ 859 | if (JD_USE_SCALE && jd->scale) { 860 | unsigned int x, y, r, g, b, s, w, a; 861 | uint8_t *op; 862 | 863 | /* Get averaged RGB value of each square correcponds to a pixel */ 864 | s = jd->scale * 2; /* Number of shifts for averaging */ 865 | w = 1 << jd->scale; /* Width of square */ 866 | a = (mx - w) * (JD_FORMAT != 2 ? 3 : 1); /* Bytes to skip for next line in the square */ 867 | op = (uint8_t*)jd->workbuf; 868 | for (iy = 0; iy < my; iy += w) { 869 | for (ix = 0; ix < mx; ix += w) { 870 | pix = (uint8_t*)jd->workbuf + (iy * mx + ix) * (JD_FORMAT != 2 ? 3 : 1); 871 | r = g = b = 0; 872 | for (y = 0; y < w; y++) { /* Accumulate RGB value in the square */ 873 | for (x = 0; x < w; x++) { 874 | r += *pix++; /* Accumulate R or Y (monochrome output) */ 875 | if (JD_FORMAT != 2) { /* RGB output? */ 876 | g += *pix++; /* Accumulate G */ 877 | b += *pix++; /* Accumulate B */ 878 | } 879 | } 880 | pix += a; 881 | } /* Put the averaged pixel value */ 882 | *op++ = (uint8_t)(r >> s); /* Put R or Y (monochrome output) */ 883 | if (JD_FORMAT != 2) { /* RGB output? */ 884 | *op++ = (uint8_t)(g >> s); /* Put G */ 885 | *op++ = (uint8_t)(b >> s); /* Put B */ 886 | } 887 | } 888 | } 889 | } 890 | 891 | } else { /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */ 892 | 893 | /* Build a 1/8 descaled RGB MCU from discrete comopnents */ 894 | pix = (uint8_t*)jd->workbuf; 895 | pc = jd->mcubuf + mx * my; 896 | cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */ 897 | cr = pc[64] - 128; 898 | for (iy = 0; iy < my; iy += 8) { 899 | py = jd->mcubuf; 900 | if (iy == 8) py += 64 * 2; 901 | for (ix = 0; ix < mx; ix += 8) { 902 | yy = *py; /* Get Y component */ 903 | py += 64; 904 | if (JD_FORMAT != 2) { 905 | *pix++ = /*R*/ BYTECLIP(yy + ((int)(1.402 * CVACC) * cr / CVACC)); 906 | *pix++ = /*G*/ BYTECLIP(yy - ((int)(0.344 * CVACC) * cb + (int)(0.714 * CVACC) * cr) / CVACC); 907 | *pix++ = /*B*/ BYTECLIP(yy + ((int)(1.772 * CVACC) * cb / CVACC)); 908 | } else { 909 | *pix++ = yy; 910 | } 911 | } 912 | } 913 | } 914 | 915 | /* Squeeze up pixel table if a part of MCU is to be truncated */ 916 | mx >>= jd->scale; 917 | if (rx < mx) { /* Is the MCU spans rigit edge? */ 918 | uint8_t *s, *d; 919 | unsigned int x, y; 920 | 921 | s = d = (uint8_t*)jd->workbuf; 922 | for (y = 0; y < ry; y++) { 923 | for (x = 0; x < rx; x++) { /* Copy effective pixels */ 924 | *d++ = *s++; 925 | if (JD_FORMAT != 2) { 926 | *d++ = *s++; 927 | *d++ = *s++; 928 | } 929 | } 930 | s += (mx - rx) * (JD_FORMAT != 2 ? 3 : 1); /* Skip truncated pixels */ 931 | } 932 | } 933 | 934 | /* Convert RGB888 to RGB565 if needed */ 935 | if (JD_FORMAT == 1) { 936 | uint8_t *s = (uint8_t*)jd->workbuf; 937 | uint16_t w, *d = (uint16_t*)s; 938 | unsigned int n = rx * ry; 939 | 940 | do { 941 | w = (*s++ & 0xF8) << 8; /* RRRRR----------- */ 942 | w |= (*s++ & 0xFC) << 3; /* -----GGGGGG----- */ 943 | w |= *s++ >> 3; /* -----------BBBBB */ 944 | *d++ = w; 945 | } while (--n); 946 | } 947 | 948 | /* Output the rectangular */ 949 | return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR; 950 | } 951 | 952 | 953 | 954 | 955 | /*-----------------------------------------------------------------------*/ 956 | /* Analyze the JPEG image and Initialize decompressor object */ 957 | /*-----------------------------------------------------------------------*/ 958 | 959 | #define LDB_WORD(ptr) (uint16_t)(((uint16_t)*((uint8_t*)(ptr))<<8)|(uint16_t)*(uint8_t*)((ptr)+1)) 960 | 961 | 962 | JRESULT jd_prepare ( 963 | JDEC* jd, /* Blank decompressor object */ 964 | size_t (*infunc)(JDEC*, uint8_t*, size_t), /* JPEG strem input function */ 965 | void* pool, /* Working buffer for the decompression session */ 966 | size_t sz_pool, /* Size of working buffer */ 967 | void* dev /* I/O device identifier for the session */ 968 | ) 969 | { 970 | uint8_t *seg, b; 971 | uint16_t marker; 972 | unsigned int n, i, ofs; 973 | size_t len; 974 | JRESULT rc; 975 | 976 | 977 | memset(jd, 0, sizeof (JDEC)); /* Clear decompression object (this might be a problem if machine's null pointer is not all bits zero) */ 978 | jd->pool = pool; /* Work memroy */ 979 | jd->sz_pool = sz_pool; /* Size of given work memory */ 980 | jd->infunc = infunc; /* Stream input function */ 981 | jd->device = dev; /* I/O device identifier */ 982 | 983 | jd->inbuf = seg = alloc_pool(jd, JD_SZBUF); /* Allocate stream input buffer */ 984 | if (!seg) return JDR_MEM1; 985 | 986 | ofs = marker = 0; /* Find SOI marker */ 987 | do { 988 | if (jd->infunc(jd, seg, 1) != 1) return JDR_INP; /* Err: SOI was not detected */ 989 | ofs++; 990 | marker = marker << 8 | seg[0]; 991 | } while (marker != 0xFFD8); 992 | 993 | for (;;) { /* Parse JPEG segments */ 994 | /* Get a JPEG marker */ 995 | if (jd->infunc(jd, seg, 4) != 4) return JDR_INP; 996 | marker = LDB_WORD(seg); /* Marker */ 997 | len = LDB_WORD(seg + 2); /* Length field */ 998 | if (len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1; 999 | len -= 2; /* Segent content size */ 1000 | ofs += 4 + len; /* Number of bytes loaded */ 1001 | 1002 | switch (marker & 0xFF) { 1003 | case 0xC0: /* SOF0 (baseline JPEG) */ 1004 | if (len > JD_SZBUF) return JDR_MEM2; 1005 | if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */ 1006 | 1007 | jd->width = LDB_WORD(&seg[3]); /* Image width in unit of pixel */ 1008 | jd->height = LDB_WORD(&seg[1]); /* Image height in unit of pixel */ 1009 | jd->ncomp = seg[5]; /* Number of color components */ 1010 | if (jd->ncomp != 3 && jd->ncomp != 1) return JDR_FMT3; /* Err: Supports only Grayscale and Y/Cb/Cr */ 1011 | 1012 | /* Check each image component */ 1013 | for (i = 0; i < jd->ncomp; i++) { 1014 | b = seg[7 + 3 * i]; /* Get sampling factor */ 1015 | if (i == 0) { /* Y component */ 1016 | if (b != 0x11 && b != 0x22 && b != 0x21) { /* Check sampling factor */ 1017 | return JDR_FMT3; /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */ 1018 | } 1019 | jd->msx = b >> 4; jd->msy = b & 15; /* Size of MCU [blocks] */ 1020 | } else { /* Cb/Cr component */ 1021 | if (b != 0x11) return JDR_FMT3; /* Err: Sampling factor of Cb/Cr must be 1 */ 1022 | } 1023 | jd->qtid[i] = seg[8 + 3 * i]; /* Get dequantizer table ID for this component */ 1024 | if (jd->qtid[i] > 3) return JDR_FMT3; /* Err: Invalid ID */ 1025 | } 1026 | break; 1027 | 1028 | case 0xDD: /* DRI - Define Restart Interval */ 1029 | if (len > JD_SZBUF) return JDR_MEM2; 1030 | if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */ 1031 | 1032 | jd->nrst = LDB_WORD(seg); /* Get restart interval (MCUs) */ 1033 | break; 1034 | 1035 | case 0xC4: /* DHT - Define Huffman Tables */ 1036 | if (len > JD_SZBUF) return JDR_MEM2; 1037 | if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */ 1038 | 1039 | rc = create_huffman_tbl(jd, seg, len); /* Create huffman tables */ 1040 | if (rc) return rc; 1041 | break; 1042 | 1043 | case 0xDB: /* DQT - Define Quaitizer Tables */ 1044 | if (len > JD_SZBUF) return JDR_MEM2; 1045 | if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */ 1046 | 1047 | rc = create_qt_tbl(jd, seg, len); /* Create de-quantizer tables */ 1048 | if (rc) return rc; 1049 | break; 1050 | 1051 | case 0xDA: /* SOS - Start of Scan */ 1052 | if (len > JD_SZBUF) return JDR_MEM2; 1053 | if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */ 1054 | 1055 | if (!jd->width || !jd->height) return JDR_FMT1; /* Err: Invalid image size */ 1056 | if (seg[0] != jd->ncomp) return JDR_FMT3; /* Err: Wrong color components */ 1057 | 1058 | /* Check if all tables corresponding to each components have been loaded */ 1059 | for (i = 0; i < jd->ncomp; i++) { 1060 | b = seg[2 + 2 * i]; /* Get huffman table ID */ 1061 | if (b != 0x00 && b != 0x11) return JDR_FMT3; /* Err: Different table number for DC/AC element */ 1062 | n = i ? 1 : 0; /* Component class */ 1063 | if (!jd->huffbits[n][0] || !jd->huffbits[n][1]) { /* Check huffman table for this component */ 1064 | return JDR_FMT1; /* Err: Nnot loaded */ 1065 | } 1066 | if (!jd->qttbl[jd->qtid[i]]) { /* Check dequantizer table for this component */ 1067 | return JDR_FMT1; /* Err: Not loaded */ 1068 | } 1069 | } 1070 | 1071 | /* Allocate working buffer for MCU and pixel output */ 1072 | n = jd->msy * jd->msx; /* Number of Y blocks in the MCU */ 1073 | if (!n) return JDR_FMT1; /* Err: SOF0 has not been loaded */ 1074 | len = n * 64 * 2 + 64; /* Allocate buffer for IDCT and RGB output */ 1075 | if (len < 256) len = 256; /* but at least 256 byte is required for IDCT */ 1076 | jd->workbuf = alloc_pool(jd, len); /* and it may occupy a part of following MCU working buffer for RGB output */ 1077 | if (!jd->workbuf) return JDR_MEM1; /* Err: not enough memory */ 1078 | jd->mcubuf = alloc_pool(jd, (n + 2) * 64 * sizeof (jd_yuv_t)); /* Allocate MCU working buffer */ 1079 | if (!jd->mcubuf) return JDR_MEM1; /* Err: not enough memory */ 1080 | 1081 | /* Align stream read offset to JD_SZBUF */ 1082 | if (ofs %= JD_SZBUF) { 1083 | jd->dctr = jd->infunc(jd, seg + ofs, (size_t)(JD_SZBUF - ofs)); 1084 | } 1085 | jd->dptr = seg + ofs - (JD_FASTDECODE ? 0 : 1); 1086 | 1087 | return JDR_OK; /* Initialization succeeded. Ready to decompress the JPEG image. */ 1088 | 1089 | case 0xC1: /* SOF1 */ 1090 | case 0xC2: /* SOF2 */ 1091 | case 0xC3: /* SOF3 */ 1092 | case 0xC5: /* SOF5 */ 1093 | case 0xC6: /* SOF6 */ 1094 | case 0xC7: /* SOF7 */ 1095 | case 0xC9: /* SOF9 */ 1096 | case 0xCA: /* SOF10 */ 1097 | case 0xCB: /* SOF11 */ 1098 | case 0xCD: /* SOF13 */ 1099 | case 0xCE: /* SOF14 */ 1100 | case 0xCF: /* SOF15 */ 1101 | case 0xD9: /* EOI */ 1102 | return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */ 1103 | 1104 | default: /* Unknown segment (comment, exif or etc..) */ 1105 | /* Skip segment data (null pointer specifies to remove data from the stream) */ 1106 | if (jd->infunc(jd, 0, len) != len) return JDR_INP; 1107 | } 1108 | } 1109 | } 1110 | 1111 | 1112 | 1113 | 1114 | /*-----------------------------------------------------------------------*/ 1115 | /* Start to decompress the JPEG picture */ 1116 | /*-----------------------------------------------------------------------*/ 1117 | 1118 | JRESULT jd_decomp ( 1119 | JDEC* jd, /* Initialized decompression object */ 1120 | int (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ 1121 | uint8_t scale /* Output de-scaling factor (0 to 3) */ 1122 | ) 1123 | { 1124 | unsigned int x, y, mx, my; 1125 | uint16_t rst, rsc; 1126 | JRESULT rc; 1127 | 1128 | 1129 | if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR; 1130 | jd->scale = scale; 1131 | 1132 | mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */ 1133 | 1134 | jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */ 1135 | rst = rsc = 0; 1136 | 1137 | rc = JDR_OK; 1138 | for (y = 0; y < jd->height; y += my) { /* Vertical loop of MCUs */ 1139 | for (x = 0; x < jd->width; x += mx) { /* Horizontal loop of MCUs */ 1140 | if (jd->nrst && rst++ == jd->nrst) { /* Process restart interval if enabled */ 1141 | rc = restart(jd, rsc++); 1142 | if (rc != JDR_OK) return rc; 1143 | rst = 1; 1144 | } 1145 | rc = mcu_load(jd); /* Load an MCU (decompress huffman coded stream, dequantize and apply IDCT) */ 1146 | if (rc != JDR_OK) return rc; 1147 | rc = mcu_output(jd, outfunc, x, y); /* Output the MCU (YCbCr to RGB, scaling and output) */ 1148 | if (rc != JDR_OK) return rc; 1149 | } 1150 | } 1151 | 1152 | return rc; 1153 | } 1154 | -------------------------------------------------------------------------------- /tjpgd.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------/ 2 | / TJpgDec - Tiny JPEG Decompressor R0.03 include file (C)ChaN, 2021 3 | /----------------------------------------------------------------------------*/ 4 | #ifndef DEF_TJPGDEC 5 | #define DEF_TJPGDEC 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "tjpgdcnf.h" 12 | #include 13 | 14 | #if defined(_WIN32) /* VC++ or some compiler without stdint.h */ 15 | typedef unsigned char uint8_t; 16 | typedef unsigned short uint16_t; 17 | typedef short int16_t; 18 | typedef unsigned long uint32_t; 19 | typedef long int32_t; 20 | #else /* Embedded platform */ 21 | #include 22 | #endif 23 | 24 | #if JD_FASTDECODE >= 1 25 | typedef int16_t jd_yuv_t; 26 | #else 27 | typedef uint8_t jd_yuv_t; 28 | #endif 29 | 30 | 31 | /* Error code */ 32 | typedef enum { 33 | JDR_OK = 0, /* 0: Succeeded */ 34 | JDR_INTR, /* 1: Interrupted by output function */ 35 | JDR_INP, /* 2: Device error or wrong termination of input stream */ 36 | JDR_MEM1, /* 3: Insufficient memory pool for the image */ 37 | JDR_MEM2, /* 4: Insufficient stream input buffer */ 38 | JDR_PAR, /* 5: Parameter error */ 39 | JDR_FMT1, /* 6: Data format error (may be broken data) */ 40 | JDR_FMT2, /* 7: Right format but not supported */ 41 | JDR_FMT3 /* 8: Not supported JPEG standard */ 42 | } JRESULT; 43 | 44 | 45 | 46 | /* Rectangular region in the output image */ 47 | typedef struct { 48 | uint16_t left; /* Left end */ 49 | uint16_t right; /* Right end */ 50 | uint16_t top; /* Top end */ 51 | uint16_t bottom; /* Bottom end */ 52 | } JRECT; 53 | 54 | 55 | 56 | /* Decompressor object structure */ 57 | typedef struct JDEC JDEC; 58 | struct JDEC { 59 | size_t dctr; /* Number of bytes available in the input buffer */ 60 | uint8_t* dptr; /* Current data read ptr */ 61 | uint8_t* inbuf; /* Bit stream input buffer */ 62 | uint8_t dbit; /* Number of bits availavble in wreg or reading bit mask */ 63 | uint8_t scale; /* Output scaling ratio */ 64 | uint8_t msx, msy; /* MCU size in unit of block (width, height) */ 65 | uint8_t qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */ 66 | uint8_t ncomp; /* Number of color components 1:grayscale, 3:color */ 67 | int16_t dcv[3]; /* Previous DC element of each component */ 68 | uint16_t nrst; /* Restart inverval */ 69 | uint16_t width, height; /* Size of the input image (pixel) */ 70 | uint8_t* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ 71 | uint16_t* huffcode[2][2]; /* Huffman code word tables [id][dcac] */ 72 | uint8_t* huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */ 73 | int32_t* qttbl[4]; /* Dequantizer tables [id] */ 74 | #if JD_FASTDECODE >= 1 75 | uint32_t wreg; /* Working shift register */ 76 | uint8_t marker; /* Detected marker (0:None) */ 77 | #if JD_FASTDECODE == 2 78 | uint8_t longofs[2][2]; /* Table offset of long code [id][dcac] */ 79 | uint16_t* hufflut_ac[2]; /* Fast huffman decode tables for AC short code [id] */ 80 | uint8_t* hufflut_dc[2]; /* Fast huffman decode tables for DC short code [id] */ 81 | #endif 82 | #endif 83 | void* workbuf; /* Working buffer for IDCT and RGB output */ 84 | jd_yuv_t* mcubuf; /* Working buffer for the MCU */ 85 | void* pool; /* Pointer to available memory pool */ 86 | size_t sz_pool; /* Size of momory pool (bytes available) */ 87 | size_t (*infunc)(JDEC*, uint8_t*, size_t); /* Pointer to jpeg stream input function */ 88 | void* device; /* Pointer to I/O device identifiler for the session */ 89 | }; 90 | 91 | 92 | 93 | /* TJpgDec API functions */ 94 | JRESULT jd_prepare (JDEC* jd, size_t (*infunc)(JDEC*,uint8_t*,size_t), void* pool, size_t sz_pool, void* dev); 95 | JRESULT jd_decomp (JDEC* jd, int (*outfunc)(JDEC*,void*,JRECT*), uint8_t scale); 96 | 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif /* _TJPGDEC */ 103 | -------------------------------------------------------------------------------- /tjpgdcnf.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------*/ 2 | /* TJpgDec System Configurations R0.03 */ 3 | /*----------------------------------------------*/ 4 | 5 | #define JD_SZBUF 512 6 | /* Specifies size of stream input buffer */ 7 | 8 | #define JD_FORMAT 0 9 | /* Specifies output pixel format. 10 | / 0: RGB888 (24-bit/pix) 11 | / 1: RGB565 (16-bit/pix) 12 | / 2: Grayscale (8-bit/pix) 13 | */ 14 | 15 | #define JD_USE_SCALE 1 16 | /* Switches output descaling feature. 17 | / 0: Disable 18 | / 1: Enable 19 | */ 20 | 21 | #define JD_TBLCLIP 1 22 | /* Use table conversion for saturation arithmetic. A bit faster, but increases 1 KB of code size. 23 | / 0: Disable 24 | / 1: Enable 25 | */ 26 | 27 | #define JD_FASTDECODE 0 28 | /* Optimization level 29 | / 0: Basic optimization. Suitable for 8/16-bit MCUs. 30 | / 1: + 32-bit barrel shifter. Suitable for 32-bit MCUs. 31 | / 2: + Table conversion for huffman decoding (wants 6 << HUFF_BIT bytes of RAM) 32 | */ 33 | 34 | --------------------------------------------------------------------------------