Full Code of FeiGeChuanShu/ncnn_paddleocr for AI

main 3e66eb7df5d8 cached
29 files
318.6 KB
107.4k tokens
180 symbols
1 requests
Download .txt
Showing preview only (345K chars total). Download the full file or copy to clipboard to get everything.
Repository: FeiGeChuanShu/ncnn_paddleocr
Branch: main
Commit: 3e66eb7df5d8
Files: 29
Total size: 318.6 KB

Directory structure:
gitextract_zxhxyjoe/

├── README.md
├── app/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── assets/
│           │   ├── ch_PP-OCRv3_det.param
│           │   ├── ch_PP-OCRv3_rec.param
│           │   ├── cls-sim-op.param
│           │   ├── det-sim-op.param
│           │   ├── paddleocr_keys.txt
│           │   ├── pdocrv2.0_det-op.param
│           │   ├── pdocrv2.0_rec-op.param
│           │   └── rec-sim-op.param
│           ├── java/
│           │   └── com/
│           │       └── tencent/
│           │           └── paddleocrncnn/
│           │               ├── MainActivity.java
│           │               └── PaddleOCRNcnn.java
│           ├── jni/
│           │   ├── CMakeLists.txt
│           │   ├── clipper.cpp
│           │   ├── clipper.hpp
│           │   ├── common.cpp
│           │   ├── common.h
│           │   └── paddleocr_ncnn.cpp
│           └── res/
│               ├── layout/
│               │   └── main.xml
│               ├── values/
│               │   └── strings.xml
│               └── xml/
│                   └── file_paths.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# ncnn_paddleocr
This is a sample paddleocr ncnn android project, it depends on ncnn library and opencv  
https://github.com/Tencent/ncnn  
https://github.com/nihui/opencv-mobile

convert paddleocr light model to ncnn,you can use it by ncnn.  
the infer code you can use chineseocr_lite project.  
PS:if you use angle model plz change the input shape dstHeight from 32 to 48  
# model support  
## text detection  
1.mv3dbnet-sim-op(paddleocr_mobile)  
2.pdocrv2.0_det-op(PP-OCRv2)  
3.ch_PP-OCRv3_det(PP-OCRv3)  
4.ch_PP-OCRv4_det(PP-OCRv4)  [model](https://github.com/FeiGeChuanShu/ncnn_ppstructure)  
## text angle cls  
1.angle-sim-op  
## text recognition  
1.mv3rec-sim-op(paddleocr_mobile)  
2.pdocrv2.0_rec-op(PP-OCRv2)  
3.ch_PP-OCRv3_rec(PP-OCRv3)  
4.ch_PP-OCRv4_rec(PP-OCRv4)  [model](https://github.com/FeiGeChuanShu/ncnn_ppstructure)  
## how to build and run
### step1
https://github.com/Tencent/ncnn/releases

* Download ncnn-YYYYMMDD-android-vulkan.zip or build ncnn for android yourself
* Extract ncnn-YYYYMMDD-android-vulkan.zip into **app/src/main/jni** and change the **ncnn_DIR** path to yours in **app/src/main/jni/CMakeLists.txt**

### step2
https://github.com/nihui/opencv-mobile

* Download opencv-mobile-XYZ-android.zip
* Extract opencv-mobile-XYZ-android.zip into **app/src/main/jni** and change the **OpenCV_DIR** path to yours in **app/src/main/jni/CMakeLists.txt**

### step3
* Open this project with Android Studio, build it and enjoy!  

## screenshot  
![](screenshot.png)  
1.https://github.com/DayBreak-u/chineseocr_lite/tree/onnx/cpp_projects/OcrLiteNcnn  
2.https://github.com/frotms/PaddleOCR2Pytorch  
3.https://github.com/PaddlePaddle/PaddleOCR#PP-OCRv2  
4.https://github.com/nihui/ncnn-android-yolov5  
5.https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.5  


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "com.tencent.paddleocrncnn"
        archivesBaseName = "$applicationId"

        ndk {
            moduleName "ncnn"
            abiFilters "armeabi-v7a", "arm64-v8a"
        }
        minSdkVersion 24
    }

    externalNativeBuild {
        cmake {
            version "3.10.2"
            path file('src/main/jni/CMakeLists.txt')
        }
    }
    dependencies {
        implementation 'com.android.support:support-v4:24.0.0'
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.tencent.paddleocrncnn"
      android:versionCode="1"
      android:versionName="1.1">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application android:label="@string/app_name" >
        <activity android:name="MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.tencent.paddleocrncnn.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>
</manifest> 


================================================
FILE: app/src/main/assets/ch_PP-OCRv3_det.param
================================================
7767517
153 185
Input                    x                        0 1 input
Convolution              Conv_0                   1 1 input hardswish_0.tmp_0 0=8 1=3 3=2 4=1 5=1 6=216 9=6 -23310=2,1.666667e-01,5.000000e-01
Split                    splitncnn_0              1 2 hardswish_0.tmp_0 hardswish_0.tmp_0_splitncnn_0 hardswish_0.tmp_0_splitncnn_1
Convolution              Conv_1                   1 1 hardswish_0.tmp_0_splitncnn_1 relu_0.tmp_0 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise     Conv_2                   1 1 relu_0.tmp_0 relu_1.tmp_0 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Convolution              Conv_3                   1 1 relu_1.tmp_0 conv2d_213.tmp_0 0=8 1=1 5=1 6=64
BinaryOp                 Add_1                    2 1 hardswish_0.tmp_0_splitncnn_0 conv2d_213.tmp_0 elementwise_add_0
Convolution              Conv_4                   1 1 elementwise_add_0 relu_2.tmp_0 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise     Conv_5                   1 1 relu_2.tmp_0 relu_3.tmp_0 0=32 1=3 3=2 4=1 5=1 6=288 7=32 9=1
Convolution              Conv_6                   1 1 relu_3.tmp_0 conv2d_215.tmp_0 0=16 1=1 5=1 6=512
Split                    splitncnn_1              1 2 conv2d_215.tmp_0 conv2d_215.tmp_0_splitncnn_0 conv2d_215.tmp_0_splitncnn_1
Convolution              Conv_7                   1 1 conv2d_215.tmp_0_splitncnn_1 relu_4.tmp_0 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise     Conv_8                   1 1 relu_4.tmp_0 relu_5.tmp_0 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution              Conv_9                   1 1 relu_5.tmp_0 conv2d_217.tmp_0 0=16 1=1 5=1 6=640
BinaryOp                 Add_2                    2 1 conv2d_215.tmp_0_splitncnn_0 conv2d_217.tmp_0 elementwise_add_1
Split                    splitncnn_2              1 2 elementwise_add_1 elementwise_add_1_splitncnn_0 elementwise_add_1_splitncnn_1
Convolution              Conv_10                  1 1 elementwise_add_1_splitncnn_1 relu_6.tmp_0 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise     Conv_11                  1 1 relu_6.tmp_0 relu_7.tmp_0 0=40 1=5 3=2 4=2 5=1 6=1000 7=40 9=1
Convolution              Conv_12                  1 1 relu_7.tmp_0 conv2d_219.tmp_0 0=24 1=1 5=1 6=960
Split                    splitncnn_3              1 2 conv2d_219.tmp_0 conv2d_219.tmp_0_splitncnn_0 conv2d_219.tmp_0_splitncnn_1
Convolution              Conv_13                  1 1 conv2d_219.tmp_0_splitncnn_1 relu_8.tmp_0 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise     Conv_14                  1 1 relu_8.tmp_0 relu_9.tmp_0 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution              Conv_15                  1 1 relu_9.tmp_0 conv2d_221.tmp_0 0=24 1=1 5=1 6=1536
BinaryOp                 Add_3                    2 1 conv2d_219.tmp_0_splitncnn_0 conv2d_221.tmp_0 elementwise_add_2
Split                    splitncnn_4              1 2 elementwise_add_2 elementwise_add_2_splitncnn_0 elementwise_add_2_splitncnn_1
Convolution              Conv_16                  1 1 elementwise_add_2_splitncnn_1 relu_10.tmp_0 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise     Conv_17                  1 1 relu_10.tmp_0 relu_11.tmp_0 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution              Conv_18                  1 1 relu_11.tmp_0 conv2d_223.tmp_0 0=24 1=1 5=1 6=1536
BinaryOp                 Add_4                    2 1 elementwise_add_2_splitncnn_0 conv2d_223.tmp_0 elementwise_add_3
Split                    splitncnn_5              1 2 elementwise_add_3 elementwise_add_3_splitncnn_0 elementwise_add_3_splitncnn_1
Convolution              Conv_19                  1 1 elementwise_add_3_splitncnn_1 hardswish_1.tmp_0 0=120 1=1 5=1 6=2880 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_20                  1 1 hardswish_1.tmp_0 hardswish_2.tmp_0 0=120 1=3 3=2 4=1 5=1 6=1080 7=120 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_21                  1 1 hardswish_2.tmp_0 conv2d_225.tmp_0 0=40 1=1 5=1 6=4800
Split                    splitncnn_6              1 2 conv2d_225.tmp_0 conv2d_225.tmp_0_splitncnn_0 conv2d_225.tmp_0_splitncnn_1
Convolution              Conv_22                  1 1 conv2d_225.tmp_0_splitncnn_1 hardswish_3.tmp_0 0=104 1=1 5=1 6=4160 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_23                  1 1 hardswish_3.tmp_0 hardswish_4.tmp_0 0=104 1=3 4=1 5=1 6=936 7=104 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_24                  1 1 hardswish_4.tmp_0 conv2d_227.tmp_0 0=40 1=1 5=1 6=4160
BinaryOp                 Add_9                    2 1 conv2d_225.tmp_0_splitncnn_0 conv2d_227.tmp_0 elementwise_add_4
Split                    splitncnn_7              1 2 elementwise_add_4 elementwise_add_4_splitncnn_0 elementwise_add_4_splitncnn_1
Convolution              Conv_25                  1 1 elementwise_add_4_splitncnn_1 hardswish_5.tmp_0 0=96 1=1 5=1 6=3840 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_26                  1 1 hardswish_5.tmp_0 hardswish_6.tmp_0 0=96 1=3 4=1 5=1 6=864 7=96 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_27                  1 1 hardswish_6.tmp_0 conv2d_229.tmp_0 0=40 1=1 5=1 6=3840
BinaryOp                 Add_12                   2 1 elementwise_add_4_splitncnn_0 conv2d_229.tmp_0 elementwise_add_5
Split                    splitncnn_8              1 2 elementwise_add_5 elementwise_add_5_splitncnn_0 elementwise_add_5_splitncnn_1
Convolution              Conv_28                  1 1 elementwise_add_5_splitncnn_1 hardswish_7.tmp_0 0=96 1=1 5=1 6=3840 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_29                  1 1 hardswish_7.tmp_0 hardswish_8.tmp_0 0=96 1=3 4=1 5=1 6=864 7=96 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_30                  1 1 hardswish_8.tmp_0 conv2d_231.tmp_0 0=40 1=1 5=1 6=3840
BinaryOp                 Add_15                   2 1 elementwise_add_5_splitncnn_0 conv2d_231.tmp_0 elementwise_add_6
Convolution              Conv_31                  1 1 elementwise_add_6 hardswish_9.tmp_0 0=240 1=1 5=1 6=9600 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_32                  1 1 hardswish_9.tmp_0 hardswish_10.tmp_0 0=240 1=3 4=1 5=1 6=2160 7=240 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_33                  1 1 hardswish_10.tmp_0 conv2d_233.tmp_0 0=56 1=1 5=1 6=13440
Split                    splitncnn_9              1 2 conv2d_233.tmp_0 conv2d_233.tmp_0_splitncnn_0 conv2d_233.tmp_0_splitncnn_1
Convolution              Conv_34                  1 1 conv2d_233.tmp_0_splitncnn_1 hardswish_11.tmp_0 0=336 1=1 5=1 6=18816 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_35                  1 1 hardswish_11.tmp_0 hardswish_12.tmp_0 0=336 1=3 4=1 5=1 6=3024 7=336 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_36                  1 1 hardswish_12.tmp_0 conv2d_235.tmp_0 0=56 1=1 5=1 6=18816
BinaryOp                 Add_20                   2 1 conv2d_233.tmp_0_splitncnn_0 conv2d_235.tmp_0 elementwise_add_7
Split                    splitncnn_10             1 2 elementwise_add_7 elementwise_add_7_splitncnn_0 elementwise_add_7_splitncnn_1
Convolution              Conv_37                  1 1 elementwise_add_7_splitncnn_1 hardswish_13.tmp_0 0=336 1=1 5=1 6=18816 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_38                  1 1 hardswish_13.tmp_0 hardswish_14.tmp_0 0=336 1=5 3=2 4=2 5=1 6=8400 7=336 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_39                  1 1 hardswish_14.tmp_0 conv2d_237.tmp_0 0=80 1=1 5=1 6=26880
Split                    splitncnn_11             1 2 conv2d_237.tmp_0 conv2d_237.tmp_0_splitncnn_0 conv2d_237.tmp_0_splitncnn_1
Convolution              Conv_40                  1 1 conv2d_237.tmp_0_splitncnn_1 hardswish_15.tmp_0 0=480 1=1 5=1 6=38400 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_41                  1 1 hardswish_15.tmp_0 hardswish_16.tmp_0 0=480 1=5 4=2 5=1 6=12000 7=480 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_42                  1 1 hardswish_16.tmp_0 conv2d_239.tmp_0 0=80 1=1 5=1 6=38400
BinaryOp                 Add_25                   2 1 conv2d_237.tmp_0_splitncnn_0 conv2d_239.tmp_0 elementwise_add_8
Split                    splitncnn_12             1 2 elementwise_add_8 elementwise_add_8_splitncnn_0 elementwise_add_8_splitncnn_1
Convolution              Conv_43                  1 1 elementwise_add_8_splitncnn_1 hardswish_17.tmp_0 0=480 1=1 5=1 6=38400 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_44                  1 1 hardswish_17.tmp_0 hardswish_18.tmp_0 0=480 1=5 4=2 5=1 6=12000 7=480 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_45                  1 1 hardswish_18.tmp_0 conv2d_241.tmp_0 0=80 1=1 5=1 6=38400
BinaryOp                 Add_28                   2 1 elementwise_add_8_splitncnn_0 conv2d_241.tmp_0 elementwise_add_9
Convolution              Conv_46                  1 1 elementwise_add_9 hardswish_19.tmp_0 0=480 1=1 5=1 6=38400 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_47                  1 1 hardswish_19.tmp_0 conv2d_243.tmp_0 0=96 1=1 6=46080
Split                    splitncnn_13             1 3 conv2d_243.tmp_0 conv2d_243.tmp_0_splitncnn_0 conv2d_243.tmp_0_splitncnn_1 conv2d_243.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_0      1 1 conv2d_243.tmp_0_splitncnn_2 pool2d_0.tmp_0 0=1 4=1
InnerProduct             Conv_48                  1 1 pool2d_0.tmp_0 relu_12.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct             Conv_49                  1 1 relu_12.tmp_0 conv2d_245.tmp_0 0=96 1=1 2=2304
HardSigmoid              HardSigmoid_0            1 1 conv2d_245.tmp_0 hardsigmoid_0.tmp_0
BinaryOp                 Mul_20                   2 1 conv2d_243.tmp_0_splitncnn_1 hardsigmoid_0.tmp_0 tmp_0 0=2
BinaryOp                 Add_32                   2 1 conv2d_243.tmp_0_splitncnn_0 tmp_0 tmp_1
Split                    splitncnn_14             1 2 tmp_1 tmp_1_splitncnn_0 tmp_1_splitncnn_1
Convolution              Conv_50                  1 1 elementwise_add_7_splitncnn_0 conv2d_246.tmp_0 0=96 1=1 6=5376
Split                    splitncnn_15             1 3 conv2d_246.tmp_0 conv2d_246.tmp_0_splitncnn_0 conv2d_246.tmp_0_splitncnn_1 conv2d_246.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_1      1 1 conv2d_246.tmp_0_splitncnn_2 pool2d_1.tmp_0 0=1 4=1
InnerProduct             Conv_51                  1 1 pool2d_1.tmp_0 relu_13.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct             Conv_52                  1 1 relu_13.tmp_0 conv2d_248.tmp_0 0=96 1=1 2=2304
HardSigmoid              HardSigmoid_1            1 1 conv2d_248.tmp_0 hardsigmoid_1.tmp_0
BinaryOp                 Mul_21                   2 1 conv2d_246.tmp_0_splitncnn_1 hardsigmoid_1.tmp_0 tmp_2 0=2
BinaryOp                 Add_35                   2 1 conv2d_246.tmp_0_splitncnn_0 tmp_2 tmp_3
Convolution              Conv_53                  1 1 elementwise_add_3_splitncnn_0 conv2d_249.tmp_0 0=96 1=1 6=2304
Split                    splitncnn_16             1 3 conv2d_249.tmp_0 conv2d_249.tmp_0_splitncnn_0 conv2d_249.tmp_0_splitncnn_1 conv2d_249.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_2      1 1 conv2d_249.tmp_0_splitncnn_2 pool2d_2.tmp_0 0=1 4=1
InnerProduct             Conv_54                  1 1 pool2d_2.tmp_0 relu_14.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct             Conv_55                  1 1 relu_14.tmp_0 conv2d_251.tmp_0 0=96 1=1 2=2304
HardSigmoid              HardSigmoid_2            1 1 conv2d_251.tmp_0 hardsigmoid_2.tmp_0
BinaryOp                 Mul_22                   2 1 conv2d_249.tmp_0_splitncnn_1 hardsigmoid_2.tmp_0 tmp_4 0=2
BinaryOp                 Add_38                   2 1 conv2d_249.tmp_0_splitncnn_0 tmp_4 tmp_5
Convolution              Conv_56                  1 1 elementwise_add_1_splitncnn_0 conv2d_252.tmp_0 0=96 1=1 6=1536
Split                    splitncnn_17             1 3 conv2d_252.tmp_0 conv2d_252.tmp_0_splitncnn_0 conv2d_252.tmp_0_splitncnn_1 conv2d_252.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_3      1 1 conv2d_252.tmp_0_splitncnn_2 pool2d_3.tmp_0 0=1 4=1
InnerProduct             Conv_57                  1 1 pool2d_3.tmp_0 relu_15.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct             Conv_58                  1 1 relu_15.tmp_0 conv2d_254.tmp_0 0=96 1=1 2=2304
HardSigmoid              HardSigmoid_3            1 1 conv2d_254.tmp_0 hardsigmoid_3.tmp_0
BinaryOp                 Mul_23                   2 1 conv2d_252.tmp_0_splitncnn_1 hardsigmoid_3.tmp_0 tmp_6 0=2
BinaryOp                 Add_41                   2 1 conv2d_252.tmp_0_splitncnn_0 tmp_6 tmp_7
Interp                   Resize_0                 1 1 tmp_1_splitncnn_1 nearest_interp_v2_0.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_42                   2 1 tmp_3 nearest_interp_v2_0.tmp_0 tmp_8
Split                    splitncnn_18             1 2 tmp_8 tmp_8_splitncnn_0 tmp_8_splitncnn_1
Interp                   Resize_1                 1 1 tmp_8_splitncnn_1 nearest_interp_v2_1.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_43                   2 1 tmp_5 nearest_interp_v2_1.tmp_0 tmp_9
Split                    splitncnn_19             1 2 tmp_9 tmp_9_splitncnn_0 tmp_9_splitncnn_1
Interp                   Resize_2                 1 1 tmp_9_splitncnn_1 nearest_interp_v2_2.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_44                   2 1 tmp_7 nearest_interp_v2_2.tmp_0 tmp_10
Convolution              Conv_59                  1 1 tmp_1_splitncnn_0 conv2d_255.tmp_0 0=24 1=3 4=1 6=20736
Split                    splitncnn_20             1 3 conv2d_255.tmp_0 conv2d_255.tmp_0_splitncnn_0 conv2d_255.tmp_0_splitncnn_1 conv2d_255.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_4      1 1 conv2d_255.tmp_0_splitncnn_2 pool2d_4.tmp_0 0=1 4=1
InnerProduct             Conv_60                  1 1 pool2d_4.tmp_0 relu_16.tmp_0 0=6 1=1 2=144 9=1
InnerProduct             Conv_61                  1 1 relu_16.tmp_0 conv2d_257.tmp_0 0=24 1=1 2=144
HardSigmoid              HardSigmoid_4            1 1 conv2d_257.tmp_0 hardsigmoid_4.tmp_0
BinaryOp                 Mul_24                   2 1 conv2d_255.tmp_0_splitncnn_1 hardsigmoid_4.tmp_0 tmp_11 0=2
BinaryOp                 Add_47                   2 1 conv2d_255.tmp_0_splitncnn_0 tmp_11 tmp_12
Convolution              Conv_62                  1 1 tmp_8_splitncnn_0 conv2d_258.tmp_0 0=24 1=3 4=1 6=20736
Split                    splitncnn_21             1 3 conv2d_258.tmp_0 conv2d_258.tmp_0_splitncnn_0 conv2d_258.tmp_0_splitncnn_1 conv2d_258.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_5      1 1 conv2d_258.tmp_0_splitncnn_2 pool2d_5.tmp_0 0=1 4=1
InnerProduct             Conv_63                  1 1 pool2d_5.tmp_0 relu_17.tmp_0 0=6 1=1 2=144 9=1
InnerProduct             Conv_64                  1 1 relu_17.tmp_0 conv2d_260.tmp_0 0=24 1=1 2=144
HardSigmoid              HardSigmoid_5            1 1 conv2d_260.tmp_0 hardsigmoid_5.tmp_0
BinaryOp                 Mul_25                   2 1 conv2d_258.tmp_0_splitncnn_1 hardsigmoid_5.tmp_0 tmp_13 0=2
BinaryOp                 Add_50                   2 1 conv2d_258.tmp_0_splitncnn_0 tmp_13 tmp_14
Convolution              Conv_65                  1 1 tmp_9_splitncnn_0 conv2d_261.tmp_0 0=24 1=3 4=1 6=20736
Split                    splitncnn_22             1 3 conv2d_261.tmp_0 conv2d_261.tmp_0_splitncnn_0 conv2d_261.tmp_0_splitncnn_1 conv2d_261.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_6      1 1 conv2d_261.tmp_0_splitncnn_2 pool2d_6.tmp_0 0=1 4=1
InnerProduct             Conv_66                  1 1 pool2d_6.tmp_0 relu_18.tmp_0 0=6 1=1 2=144 9=1
InnerProduct             Conv_67                  1 1 relu_18.tmp_0 conv2d_263.tmp_0 0=24 1=1 2=144
HardSigmoid              HardSigmoid_6            1 1 conv2d_263.tmp_0 hardsigmoid_6.tmp_0
BinaryOp                 Mul_26                   2 1 conv2d_261.tmp_0_splitncnn_1 hardsigmoid_6.tmp_0 tmp_15 0=2
BinaryOp                 Add_53                   2 1 conv2d_261.tmp_0_splitncnn_0 tmp_15 tmp_16
Convolution              Conv_68                  1 1 tmp_10 conv2d_264.tmp_0 0=24 1=3 4=1 6=20736
Split                    splitncnn_23             1 3 conv2d_264.tmp_0 conv2d_264.tmp_0_splitncnn_0 conv2d_264.tmp_0_splitncnn_1 conv2d_264.tmp_0_splitncnn_2
Pooling                  GlobalAveragePool_7      1 1 conv2d_264.tmp_0_splitncnn_2 pool2d_7.tmp_0 0=1 4=1
InnerProduct             Conv_69                  1 1 pool2d_7.tmp_0 relu_19.tmp_0 0=6 1=1 2=144 9=1
InnerProduct             Conv_70                  1 1 relu_19.tmp_0 conv2d_266.tmp_0 0=24 1=1 2=144
HardSigmoid              HardSigmoid_7            1 1 conv2d_266.tmp_0 hardsigmoid_7.tmp_0
BinaryOp                 Mul_27                   2 1 conv2d_264.tmp_0_splitncnn_1 hardsigmoid_7.tmp_0 tmp_17 0=2
BinaryOp                 Add_56                   2 1 conv2d_264.tmp_0_splitncnn_0 tmp_17 tmp_18
Interp                   Resize_3                 1 1 tmp_12 nearest_interp_v2_3.tmp_0 0=1 1=8.000000e+00 2=8.000000e+00
Interp                   Resize_4                 1 1 tmp_14 nearest_interp_v2_4.tmp_0 0=1 1=4.000000e+00 2=4.000000e+00
Interp                   Resize_5                 1 1 tmp_16 nearest_interp_v2_5.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
Concat                   Concat_0                 4 1 nearest_interp_v2_3.tmp_0 nearest_interp_v2_4.tmp_0 nearest_interp_v2_5.tmp_0 tmp_18 concat_0.tmp_0
Convolution              Conv_71                  1 1 concat_0.tmp_0 batch_norm_47.tmp_4 0=24 1=3 4=1 5=1 6=20736 9=1
Deconvolution            ConvTranspose_0          1 1 batch_norm_47.tmp_4 elementwise_add_10.tmp_0 0=24 1=2 3=2 5=1 6=2304
BatchNorm                BatchNormalization_48    1 1 elementwise_add_10.tmp_0 batch_norm_48.tmp_3 0=24
ReLU                     Relu_21                  1 1 batch_norm_48.tmp_3 batch_norm_48.tmp_4
Deconvolution            ConvTranspose_1          1 1 batch_norm_48.tmp_4 output 0=1 1=2 3=2 5=1 6=96 9=4


================================================
FILE: app/src/main/assets/ch_PP-OCRv3_rec.param
================================================
7767517
116 127
Input                    input                    0 1 input
Convolution              Conv_0                   1 1 input batch_norm_27.tmp_4 0=16 1=3 3=2 4=1 5=1 6=432 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_1                   1 1 batch_norm_27.tmp_4 batch_norm_28.tmp_4 0=16 1=3 4=1 5=1 6=144 7=16 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_2                   1 1 batch_norm_28.tmp_4 batch_norm_29.tmp_4 0=32 1=1 5=1 6=512 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_3                   1 1 batch_norm_29.tmp_4 batch_norm_30.tmp_4 0=32 1=3 4=1 5=1 6=288 7=32 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_4                   1 1 batch_norm_30.tmp_4 batch_norm_31.tmp_4 0=64 1=1 5=1 6=2048 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_5                   1 1 batch_norm_31.tmp_4 batch_norm_32.tmp_4 0=64 1=3 4=1 5=1 6=576 7=64 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_6                   1 1 batch_norm_32.tmp_4 batch_norm_33.tmp_4 0=64 1=1 5=1 6=4096 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_7                   1 1 batch_norm_33.tmp_4 batch_norm_34.tmp_4 0=64 1=3 13=2 4=1 5=1 6=576 7=64 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_8                   1 1 batch_norm_34.tmp_4 batch_norm_35.tmp_4 0=128 1=1 5=1 6=8192 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_9                   1 1 batch_norm_35.tmp_4 batch_norm_36.tmp_4 0=128 1=3 4=1 5=1 6=1152 7=128 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_10                  1 1 batch_norm_36.tmp_4 batch_norm_37.tmp_4 0=128 1=1 5=1 6=16384 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_11                  1 1 batch_norm_37.tmp_4 batch_norm_38.tmp_4 0=128 1=3 13=2 4=1 5=1 6=1152 7=128 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_12                  1 1 batch_norm_38.tmp_4 batch_norm_39.tmp_4 0=256 1=1 5=1 6=32768 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_13                  1 1 batch_norm_39.tmp_4 batch_norm_40.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_14                  1 1 batch_norm_40.tmp_4 batch_norm_41.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_15                  1 1 batch_norm_41.tmp_4 batch_norm_42.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_16                  1 1 batch_norm_42.tmp_4 batch_norm_43.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_17                  1 1 batch_norm_43.tmp_4 batch_norm_44.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_18                  1 1 batch_norm_44.tmp_4 batch_norm_45.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_19                  1 1 batch_norm_45.tmp_4 batch_norm_46.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_20                  1 1 batch_norm_46.tmp_4 batch_norm_47.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_21                  1 1 batch_norm_47.tmp_4 batch_norm_48.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution              Conv_22                  1 1 batch_norm_48.tmp_4 batch_norm_49.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_23                  1 1 batch_norm_49.tmp_4 batch_norm_50.tmp_4 0=256 1=5 13=2 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Split                    splitncnn_0              1 2 batch_norm_50.tmp_4 batch_norm_50.tmp_4_splitncnn_0 batch_norm_50.tmp_4_splitncnn_1
Pooling                  GlobalAveragePool_0      1 1 batch_norm_50.tmp_4_splitncnn_1 pool2d_3.tmp_0 0=1 4=1
InnerProduct             Conv_24                  1 1 pool2d_3.tmp_0 relu_2.tmp_0 0=64 1=1 2=16384 9=1
InnerProduct             Conv_25                  1 1 relu_2.tmp_0 conv2d_110.tmp_0 0=256 1=1 2=16384
HardSigmoid              HardSigmoid_0            1 1 conv2d_110.tmp_0 hardsigmoid_2.tmp_0 0=1.666667e-01
BinaryOp                 Mul_24                   2 1 batch_norm_50.tmp_4_splitncnn_0 hardsigmoid_2.tmp_0 elementwise_mul_2 0=2
Convolution              Conv_26                  1 1 elementwise_mul_2 batch_norm_51.tmp_4 0=512 1=1 5=1 6=131072 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise     Conv_27                  1 1 batch_norm_51.tmp_4 batch_norm_52.tmp_4 0=512 1=5 3=2 13=1 4=2 5=1 6=12800 7=512 9=6 -23310=2,1.666667e-01,5.000000e-01
Split                    splitncnn_1              1 2 batch_norm_52.tmp_4 batch_norm_52.tmp_4_splitncnn_0 batch_norm_52.tmp_4_splitncnn_1
Pooling                  GlobalAveragePool_1      1 1 batch_norm_52.tmp_4_splitncnn_1 pool2d_4.tmp_0 0=1 4=1
InnerProduct             Conv_28                  1 1 pool2d_4.tmp_0 relu_3.tmp_0 0=128 1=1 2=65536 9=1
InnerProduct             Conv_29                  1 1 relu_3.tmp_0 conv2d_113.tmp_0 0=512 1=1 2=65536
HardSigmoid              HardSigmoid_1            1 1 conv2d_113.tmp_0 hardsigmoid_3.tmp_0 0=1.666667e-01
BinaryOp                 Mul_27                   2 1 batch_norm_52.tmp_4_splitncnn_0 hardsigmoid_3.tmp_0 elementwise_mul_3 0=2
Convolution              Conv_30                  1 1 elementwise_mul_3 batch_norm_53.tmp_4 0=512 1=1 5=1 6=262144 9=6 -23310=2,1.666667e-01,5.000000e-01
Pooling                  AveragePool_0            1 1 batch_norm_53.tmp_4 pool2d_5.tmp_0 0=1 1=2 2=2 5=1
Split                    splitncnn_2              1 2 pool2d_5.tmp_0 pool2d_5.tmp_0_splitncnn_0 pool2d_5.tmp_0_splitncnn_1
Convolution              Conv_31                  1 1 pool2d_5.tmp_0_splitncnn_1 conv2d_115.tmp_0 0=64 1=3 4=1 5=1 6=294912
Swish                    Mul_29                   1 1 conv2d_115.tmp_0 swish_21.tmp_0
Convolution              Conv_32                  1 1 swish_21.tmp_0 conv2d_116.tmp_0 0=120 1=1 5=1 6=7680
Swish                    Mul_30                   1 1 conv2d_116.tmp_0 swish_22.tmp_0
Reshape                  Reshape_4                1 1 swish_22.tmp_0 flatten_1.tmp_0 0=-1 1=120
Permute                  Transpose_0              1 1 flatten_1.tmp_0 transpose_9.tmp_0 0=1
Split                    splitncnn_3              1 2 transpose_9.tmp_0 transpose_9.tmp_0_splitncnn_0 transpose_9.tmp_0_splitncnn_1
LayerNorm                Add_32                   1 1 transpose_9.tmp_0_splitncnn_1 layer_norm_15.tmp_2 0=120 1=1.000000e-05
InnerProduct             MatMul_0                 1 1 layer_norm_15.tmp_2 linear_35.tmp_1 0=360 1=1 2=43200
Reshape                  Reshape_7                1 1 linear_35.tmp_1 reshape2_5.tmp_0 0=15 1=8 2=-1 11=3
Permute                  Transpose_1              1 1 reshape2_5.tmp_0 transpose_10.tmp_0 0=8
Split                    splitncnn_4              1 3 transpose_10.tmp_0 transpose_10.tmp_0_splitncnn_0 transpose_10.tmp_0_splitncnn_1 transpose_10.tmp_0_splitncnn_2
Crop                     Slice_2                  1 1 transpose_10.tmp_0_splitncnn_2 Slice_2 -23309=1,0 -23310=1,1 -23311=1,0
Reshape                  Squeeze_0                1 1 Slice_2 transpose_10.tmp_0_slice_0 0=15 1=-1 2=8
BinaryOp                 Mul_32                   1 1 transpose_10.tmp_0_slice_0 Mul_32 0=2 1=1 2=2.581989e-01
Crop                     Slice_3                  1 1 transpose_10.tmp_0_splitncnn_1 Slice_3 -23309=1,1 -23310=1,2 -23311=1,0
Reshape                  Squeeze_1                1 1 Slice_3 transpose_10.tmp_0_slice_1 0=15 1=-1 2=8
Crop                     Slice_4                  1 1 transpose_10.tmp_0_splitncnn_0 Slice_4 -23309=1,2 -23310=1,3 -23311=1,0
Reshape                  Squeeze_2                1 1 Slice_4 transpose_10.tmp_0_slice_2 0=15 1=-1 2=8
Permute                  Transpose_2              1 1 transpose_10.tmp_0_slice_1 transpose_11.tmp_0 0=1
MatMul                   MatMul_1                 2 1 Mul_32 transpose_11.tmp_0 matmul_v2_4.tmp_0
Softmax                  Softmax_0                1 1 matmul_v2_4.tmp_0 softmax_3.tmp_0 0=-1 1=1
MatMul                   MatMul_2                 2 1 softmax_3.tmp_0 transpose_10.tmp_0_slice_2 matmul_v2_5.tmp_0
Permute                  Transpose_3              1 1 matmul_v2_5.tmp_0 transpose_12.tmp_0 0=2
Reshape                  Reshape_8                1 1 transpose_12.tmp_0 reshape2_6.tmp_0 0=120 1=-1
InnerProduct             MatMul_3                 1 1 reshape2_6.tmp_0 linear_36.tmp_1 0=120 1=1 2=14400
BinaryOp                 Add_36                   2 1 transpose_9.tmp_0_splitncnn_0 linear_36.tmp_1 tmp_7
Split                    splitncnn_5              1 2 tmp_7 tmp_7_splitncnn_0 tmp_7_splitncnn_1
LayerNorm                Add_38                   1 1 tmp_7_splitncnn_1 layer_norm_16.tmp_2 0=120 1=1.000000e-05
InnerProduct             MatMul_4                 1 1 layer_norm_16.tmp_2 linear_37.tmp_1 0=240 1=1 2=28800
Swish                    Mul_34                   1 1 linear_37.tmp_1 swish_23.tmp_0
InnerProduct             MatMul_5                 1 1 swish_23.tmp_0 linear_38.tmp_1 0=120 1=1 2=28800
BinaryOp                 Add_41                   2 1 tmp_7_splitncnn_0 linear_38.tmp_1 tmp_8
Split                    splitncnn_6              1 2 tmp_8 tmp_8_splitncnn_0 tmp_8_splitncnn_1
LayerNorm                Add_43                   1 1 tmp_8_splitncnn_1 layer_norm_17.tmp_2 0=120 1=1.000000e-05
InnerProduct             MatMul_6                 1 1 layer_norm_17.tmp_2 linear_39.tmp_1 0=360 1=1 2=43200
Reshape                  Reshape_13               1 1 linear_39.tmp_1 reshape2_7.tmp_0 0=15 1=8 2=-1 11=3
Permute                  Transpose_4              1 1 reshape2_7.tmp_0 transpose_13.tmp_0 0=8
Split                    splitncnn_7              1 3 transpose_13.tmp_0 transpose_13.tmp_0_splitncnn_0 transpose_13.tmp_0_splitncnn_1 transpose_13.tmp_0_splitncnn_2
Crop                     Slice_7                  1 1 transpose_13.tmp_0_splitncnn_2 Slice_7 -23309=1,0 -23310=1,1 -23311=1,0
Reshape                  Squeeze_3                1 1 Slice_7 transpose_13.tmp_0_slice_0 0=15 1=-1 2=8
BinaryOp                 Mul_36                   1 1 transpose_13.tmp_0_slice_0 Mul_36 0=2 1=1 2=2.581989e-01
Crop                     Slice_8                  1 1 transpose_13.tmp_0_splitncnn_1 Slice_8 -23309=1,1 -23310=1,2 -23311=1,0
Reshape                  Squeeze_4                1 1 Slice_8 transpose_13.tmp_0_slice_1 0=15 1=-1 2=8
Crop                     Slice_9                  1 1 transpose_13.tmp_0_splitncnn_0 Slice_9 -23309=1,2 -23310=1,3 -23311=1,0
Reshape                  Squeeze_5                1 1 Slice_9 transpose_13.tmp_0_slice_2 0=15 1=-1 2=8
Permute                  Transpose_5              1 1 transpose_13.tmp_0_slice_1 transpose_14.tmp_0 0=1
MatMul                   MatMul_7                 2 1 Mul_36 transpose_14.tmp_0 matmul_v2_6.tmp_0
Softmax                  Softmax_1                1 1 matmul_v2_6.tmp_0 softmax_4.tmp_0 0=2 1=1
MatMul                   MatMul_8                 2 1 softmax_4.tmp_0 transpose_13.tmp_0_slice_2 matmul_v2_7.tmp_0
Permute                  Transpose_6              1 1 matmul_v2_7.tmp_0 transpose_15.tmp_0 0=2
Reshape                  Reshape_14               1 1 transpose_15.tmp_0 reshape2_8.tmp_0 0=120 1=-1
InnerProduct             MatMul_9                 1 1 reshape2_8.tmp_0 linear_40.tmp_1 0=120 1=1 2=14400
BinaryOp                 Add_47                   2 1 tmp_8_splitncnn_0 linear_40.tmp_1 tmp_10
Split                    splitncnn_8              1 2 tmp_10 tmp_10_splitncnn_0 tmp_10_splitncnn_1
LayerNorm                Add_49                   1 1 tmp_10_splitncnn_1 layer_norm_18.tmp_2 0=120 1=1.000000e-05
InnerProduct             MatMul_10                1 1 layer_norm_18.tmp_2 linear_41.tmp_1 0=240 1=1 2=28800
Swish                    Mul_38                   1 1 linear_41.tmp_1 swish_24.tmp_0
InnerProduct             MatMul_11                1 1 swish_24.tmp_0 linear_42.tmp_1 0=120 1=1 2=28800
BinaryOp                 Add_52                   2 1 tmp_10_splitncnn_0 linear_42.tmp_1 tmp_11
LayerNorm                Add_54                   1 1 tmp_11 layer_norm_19.tmp_2 0=120 1=1.000000e-06
Reshape                  Reshape_19               1 1 layer_norm_19.tmp_2 reshape2_9.tmp_0 0=120 1=-1 2=1
Permute                  Transpose_7              1 1 reshape2_9.tmp_0 transpose_16.tmp_0 0=4
Convolution              Conv_33                  1 1 transpose_16.tmp_0 conv2d_117.tmp_0 0=512 1=1 5=1 6=61440
Swish                    Mul_40                   1 1 conv2d_117.tmp_0 swish_25.tmp_0
Concat                   Concat_1                 2 1 pool2d_5.tmp_0_splitncnn_0 swish_25.tmp_0 concat_1.tmp_0
Convolution              Conv_34                  1 1 concat_1.tmp_0 conv2d_118.tmp_0 0=64 1=3 4=1 5=1 6=589824
Swish                    Mul_41                   1 1 conv2d_118.tmp_0 swish_26.tmp_0
Convolution              Conv_35                  1 1 swish_26.tmp_0 conv2d_119.tmp_0 0=64 1=1 5=1 6=4096
Swish                    Mul_42                   1 1 conv2d_119.tmp_0 swish_27.tmp_0
Permute                  Transpose_8              1 1 swish_27.tmp_0 squeeze_1.tmp_0 0=3
Squeeze                  Squeeze_6                1 1 squeeze_1.tmp_0 transpose_17.tmp_0 -23303=1,0
InnerProduct             MatMul_12                1 1 transpose_17.tmp_0 linear_43.tmp_1 0=6625 1=1 2=424000
Softmax                  Softmax_2                1 1 linear_43.tmp_1 out 0=-1 1=1


================================================
FILE: app/src/main/assets/cls-sim-op.param
================================================
7767517
135 151
Input                    input                    0 1 input
Convolution              Conv_0                   1 1 input 250 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish                Div_9                    1 1 250 258 0=1.666667e-01
Convolution              Conv_10                  1 1 258 261 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise     Conv_13                  1 1 261 264 0=8 1=3 13=2 4=1 5=1 6=72 7=8 9=1
Split                    splitncnn_0              1 2 264 264_splitncnn_0 264_splitncnn_1
Pooling                  GlobalAveragePool_16     1 1 264_splitncnn_1 265 0=1 4=1
InnerProduct             Conv_17                  1 1 265 267 0=2 1=1 2=16 9=1
InnerProduct             Conv_19                  1 1 267 268 0=8 1=1 2=16
BinaryOp                 Mul_21                   1 1 268 270 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_28                   1 1 270 277 0=1.666667e-01
BinaryOp                 Mul_29                   2 1 264_splitncnn_0 277 278 0=2
Convolution              Conv_30                  1 1 278 280 0=8 1=1 5=1 6=64
Convolution              Conv_32                  1 1 280 283 0=24 1=1 5=1 6=192 9=1
ConvolutionDepthWise     Conv_35                  1 1 283 286 0=24 1=3 13=2 4=1 5=1 6=216 7=24 9=1
Convolution              Conv_38                  1 1 286 288 0=8 1=1 5=1 6=192
Split                    splitncnn_1              1 2 288 288_splitncnn_0 288_splitncnn_1
Convolution              Conv_40                  1 1 288_splitncnn_1 291 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise     Conv_43                  1 1 291 294 0=32 1=3 4=1 5=1 6=288 7=32 9=1
Convolution              Conv_46                  1 1 294 296 0=8 1=1 5=1 6=256
BinaryOp                 Add_48                   2 1 288_splitncnn_0 296 297
Convolution              Conv_49                  1 1 297 299 0=32 1=1 5=1 6=256
HardSwish                Div_58                   1 1 299 307 0=1.666667e-01
ConvolutionDepthWise     Conv_59                  1 1 307 309 0=32 1=5 13=2 4=2 5=1 6=800 7=32
HardSwish                Div_68                   1 1 309 317 0=1.666667e-01
Split                    splitncnn_2              1 2 317 317_splitncnn_0 317_splitncnn_1
Pooling                  GlobalAveragePool_69     1 1 317_splitncnn_1 318 0=1 4=1
InnerProduct             Conv_70                  1 1 318 320 0=8 1=1 2=256 9=1
InnerProduct             Conv_72                  1 1 320 321 0=32 1=1 2=256
BinaryOp                 Mul_74                   1 1 321 323 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_81                   1 1 323 330 0=1.666667e-01
BinaryOp                 Mul_82                   2 1 317_splitncnn_0 330 331 0=2
Convolution              Conv_83                  1 1 331 333 0=16 1=1 5=1 6=512
Split                    splitncnn_3              1 2 333 333_splitncnn_0 333_splitncnn_1
Convolution              Conv_85                  1 1 333_splitncnn_1 335 0=88 1=1 5=1 6=1408
HardSwish                Div_94                   1 1 335 343 0=1.666667e-01
ConvolutionDepthWise     Conv_95                  1 1 343 345 0=88 1=5 4=2 5=1 6=2200 7=88
HardSwish                Div_104                  1 1 345 353 0=1.666667e-01
Split                    splitncnn_4              1 2 353 353_splitncnn_0 353_splitncnn_1
Pooling                  GlobalAveragePool_105    1 1 353_splitncnn_1 354 0=1 4=1
InnerProduct             Conv_106                 1 1 354 356 0=22 1=1 2=1936 9=1
InnerProduct             Conv_108                 1 1 356 357 0=88 1=1 2=1936
BinaryOp                 Mul_110                  1 1 357 359 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_117                  1 1 359 366 0=1.666667e-01
BinaryOp                 Mul_118                  2 1 353_splitncnn_0 366 367 0=2
Convolution              Conv_119                 1 1 367 369 0=16 1=1 5=1 6=1408
BinaryOp                 Add_121                  2 1 333_splitncnn_0 369 370
Split                    splitncnn_5              1 2 370 370_splitncnn_0 370_splitncnn_1
Convolution              Conv_122                 1 1 370_splitncnn_1 372 0=88 1=1 5=1 6=1408
HardSwish                Div_131                  1 1 372 380 0=1.666667e-01
ConvolutionDepthWise     Conv_132                 1 1 380 382 0=88 1=5 4=2 5=1 6=2200 7=88
HardSwish                Div_141                  1 1 382 390 0=1.666667e-01
Split                    splitncnn_6              1 2 390 390_splitncnn_0 390_splitncnn_1
Pooling                  GlobalAveragePool_142    1 1 390_splitncnn_1 391 0=1 4=1
InnerProduct             Conv_143                 1 1 391 393 0=22 1=1 2=1936 9=1
InnerProduct             Conv_145                 1 1 393 394 0=88 1=1 2=1936
BinaryOp                 Mul_147                  1 1 394 396 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_154                  1 1 396 403 0=1.666667e-01
BinaryOp                 Mul_155                  2 1 390_splitncnn_0 403 404 0=2
Convolution              Conv_156                 1 1 404 406 0=16 1=1 5=1 6=1408
BinaryOp                 Add_158                  2 1 370_splitncnn_0 406 407
Split                    splitncnn_7              1 2 407 407_splitncnn_0 407_splitncnn_1
Convolution              Conv_159                 1 1 407_splitncnn_1 409 0=40 1=1 5=1 6=640
HardSwish                Div_168                  1 1 409 417 0=1.666667e-01
ConvolutionDepthWise     Conv_169                 1 1 417 419 0=40 1=5 4=2 5=1 6=1000 7=40
HardSwish                Div_178                  1 1 419 427 0=1.666667e-01
Split                    splitncnn_8              1 2 427 427_splitncnn_0 427_splitncnn_1
Pooling                  GlobalAveragePool_179    1 1 427_splitncnn_1 428 0=1 4=1
InnerProduct             Conv_180                 1 1 428 430 0=10 1=1 2=400 9=1
InnerProduct             Conv_182                 1 1 430 431 0=40 1=1 2=400
BinaryOp                 Mul_184                  1 1 431 433 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_191                  1 1 433 440 0=1.666667e-01
BinaryOp                 Mul_192                  2 1 427_splitncnn_0 440 441 0=2
Convolution              Conv_193                 1 1 441 443 0=16 1=1 5=1 6=640
BinaryOp                 Add_195                  2 1 407_splitncnn_0 443 444
Split                    splitncnn_9              1 2 444 444_splitncnn_0 444_splitncnn_1
Convolution              Conv_196                 1 1 444_splitncnn_1 446 0=48 1=1 5=1 6=768
HardSwish                Div_205                  1 1 446 454 0=1.666667e-01
ConvolutionDepthWise     Conv_206                 1 1 454 456 0=48 1=5 4=2 5=1 6=1200 7=48
HardSwish                Div_215                  1 1 456 464 0=1.666667e-01
Split                    splitncnn_10             1 2 464 464_splitncnn_0 464_splitncnn_1
Pooling                  GlobalAveragePool_216    1 1 464_splitncnn_1 465 0=1 4=1
InnerProduct             Conv_217                 1 1 465 467 0=12 1=1 2=576 9=1
InnerProduct             Conv_219                 1 1 467 468 0=48 1=1 2=576
BinaryOp                 Mul_221                  1 1 468 470 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_228                  1 1 470 477 0=1.666667e-01
BinaryOp                 Mul_229                  2 1 464_splitncnn_0 477 478 0=2
Convolution              Conv_230                 1 1 478 480 0=16 1=1 5=1 6=768
BinaryOp                 Add_232                  2 1 444_splitncnn_0 480 481
Convolution              Conv_233                 1 1 481 483 0=104 1=1 5=1 6=1664
HardSwish                Div_242                  1 1 483 491 0=1.666667e-01
ConvolutionDepthWise     Conv_243                 1 1 491 493 0=104 1=5 13=2 4=2 5=1 6=2600 7=104
HardSwish                Div_252                  1 1 493 501 0=1.666667e-01
Split                    splitncnn_11             1 2 501 501_splitncnn_0 501_splitncnn_1
Pooling                  GlobalAveragePool_253    1 1 501_splitncnn_1 502 0=1 4=1
InnerProduct             Conv_254                 1 1 502 504 0=26 1=1 2=2704 9=1
InnerProduct             Conv_256                 1 1 504 505 0=104 1=1 2=2704
BinaryOp                 Mul_258                  1 1 505 507 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_265                  1 1 507 514 0=1.666667e-01
BinaryOp                 Mul_266                  2 1 501_splitncnn_0 514 515 0=2
Convolution              Conv_267                 1 1 515 517 0=32 1=1 5=1 6=3328
Split                    splitncnn_12             1 2 517 517_splitncnn_0 517_splitncnn_1
Convolution              Conv_269                 1 1 517_splitncnn_1 519 0=200 1=1 5=1 6=6400
HardSwish                Div_278                  1 1 519 527 0=1.666667e-01
ConvolutionDepthWise     Conv_279                 1 1 527 529 0=200 1=5 4=2 5=1 6=5000 7=200
HardSwish                Div_288                  1 1 529 537 0=1.666667e-01
Split                    splitncnn_13             1 2 537 537_splitncnn_0 537_splitncnn_1
Pooling                  GlobalAveragePool_289    1 1 537_splitncnn_1 538 0=1 4=1
InnerProduct             Conv_290                 1 1 538 540 0=50 1=1 2=10000 9=1
InnerProduct             Conv_292                 1 1 540 541 0=200 1=1 2=10000
BinaryOp                 Mul_294                  1 1 541 543 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_301                  1 1 543 550 0=1.666667e-01
BinaryOp                 Mul_302                  2 1 537_splitncnn_0 550 551 0=2
Convolution              Conv_303                 1 1 551 553 0=32 1=1 5=1 6=6400
BinaryOp                 Add_305                  2 1 517_splitncnn_0 553 554
Split                    splitncnn_14             1 2 554 554_splitncnn_0 554_splitncnn_1
Convolution              Conv_306                 1 1 554_splitncnn_1 556 0=200 1=1 5=1 6=6400
HardSwish                Div_315                  1 1 556 564 0=1.666667e-01
ConvolutionDepthWise     Conv_316                 1 1 564 566 0=200 1=5 4=2 5=1 6=5000 7=200
HardSwish                Div_325                  1 1 566 574 0=1.666667e-01
Split                    splitncnn_15             1 2 574 574_splitncnn_0 574_splitncnn_1
Pooling                  GlobalAveragePool_326    1 1 574_splitncnn_1 575 0=1 4=1
InnerProduct             Conv_327                 1 1 575 577 0=50 1=1 2=10000 9=1
InnerProduct             Conv_329                 1 1 577 578 0=200 1=1 2=10000
BinaryOp                 Mul_331                  1 1 578 580 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_338                  1 1 580 587 0=1.666667e-01
BinaryOp                 Mul_339                  2 1 574_splitncnn_0 587 588 0=2
Convolution              Conv_340                 1 1 588 590 0=32 1=1 5=1 6=6400
BinaryOp                 Add_342                  2 1 554_splitncnn_0 590 591
Convolution              Conv_343                 1 1 591 593 0=200 1=1 5=1 6=6400
HardSwish                Div_352                  1 1 593 601 0=1.666667e-01
Pooling                  MaxPool_353              1 1 601 602 1=2 2=2 5=1
Pooling                  GlobalAveragePool_354    1 1 602 613 0=1 4=1
InnerProduct             Gemm_365                 1 1 613 614 0=2 1=1 2=400
Softmax                  Softmax_366              1 1 614 out


================================================
FILE: app/src/main/assets/det-sim-op.param
================================================
7767517
115 131
Input                    input                    0 1 input0
Convolution              Conv_0                   1 1 input0 322 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish                Div_9                    1 1 322 330 0=1.666667e-01
Split                    splitncnn_0              1 2 330 330_splitncnn_0 330_splitncnn_1
Convolution              Conv_10                  1 1 330_splitncnn_1 333 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise     Conv_13                  1 1 333 336 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Convolution              Conv_16                  1 1 336 338 0=8 1=1 5=1 6=64
BinaryOp                 Add_18                   2 1 330_splitncnn_0 338 339
Convolution              Conv_19                  1 1 339 342 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise     Conv_22                  1 1 342 345 0=32 1=3 3=2 4=1 5=1 6=288 7=32 9=1
Convolution              Conv_25                  1 1 345 347 0=16 1=1 5=1 6=512
Split                    splitncnn_1              1 2 347 347_splitncnn_0 347_splitncnn_1
Convolution              Conv_27                  1 1 347_splitncnn_1 350 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise     Conv_30                  1 1 350 353 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution              Conv_33                  1 1 353 355 0=16 1=1 5=1 6=640
BinaryOp                 Add_35                   2 1 347_splitncnn_0 355 356
Split                    splitncnn_2              1 2 356 356_splitncnn_0 356_splitncnn_1
Convolution              Conv_36                  1 1 356_splitncnn_1 359 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise     Conv_39                  1 1 359 362 0=40 1=5 3=2 4=2 5=1 6=1000 7=40 9=1
Convolution              Conv_42                  1 1 362 364 0=24 1=1 5=1 6=960
Split                    splitncnn_3              1 2 364 364_splitncnn_0 364_splitncnn_1
Convolution              Conv_44                  1 1 364_splitncnn_1 367 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise     Conv_47                  1 1 367 370 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution              Conv_50                  1 1 370 372 0=24 1=1 5=1 6=1536
BinaryOp                 Add_52                   2 1 364_splitncnn_0 372 373
Split                    splitncnn_4              1 2 373 373_splitncnn_0 373_splitncnn_1
Convolution              Conv_53                  1 1 373_splitncnn_1 376 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise     Conv_56                  1 1 376 379 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution              Conv_59                  1 1 379 381 0=24 1=1 5=1 6=1536
BinaryOp                 Add_61                   2 1 373_splitncnn_0 381 382
Split                    splitncnn_5              1 2 382 382_splitncnn_0 382_splitncnn_1
Convolution              Conv_62                  1 1 382_splitncnn_1 384 0=120 1=1 5=1 6=2880
HardSwish                Div_71                   1 1 384 392 0=1.666667e-01
ConvolutionDepthWise     Conv_72                  1 1 392 394 0=120 1=3 3=2 4=1 5=1 6=1080 7=120
HardSwish                Div_81                   1 1 394 402 0=1.666667e-01
Convolution              Conv_82                  1 1 402 404 0=40 1=1 5=1 6=4800
Split                    splitncnn_6              1 2 404 404_splitncnn_0 404_splitncnn_1
Convolution              Conv_84                  1 1 404_splitncnn_1 406 0=104 1=1 5=1 6=4160
HardSwish                Div_93                   1 1 406 414 0=1.666667e-01
ConvolutionDepthWise     Conv_94                  1 1 414 416 0=104 1=3 4=1 5=1 6=936 7=104
HardSwish                Div_103                  1 1 416 424 0=1.666667e-01
Convolution              Conv_104                 1 1 424 426 0=40 1=1 5=1 6=4160
BinaryOp                 Add_106                  2 1 404_splitncnn_0 426 427
Split                    splitncnn_7              1 2 427 427_splitncnn_0 427_splitncnn_1
Convolution              Conv_107                 1 1 427_splitncnn_1 429 0=96 1=1 5=1 6=3840
HardSwish                Div_116                  1 1 429 437 0=1.666667e-01
ConvolutionDepthWise     Conv_117                 1 1 437 439 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish                Div_126                  1 1 439 447 0=1.666667e-01
Convolution              Conv_127                 1 1 447 449 0=40 1=1 5=1 6=3840
BinaryOp                 Add_129                  2 1 427_splitncnn_0 449 450
Split                    splitncnn_8              1 2 450 450_splitncnn_0 450_splitncnn_1
Convolution              Conv_130                 1 1 450_splitncnn_1 452 0=96 1=1 5=1 6=3840
HardSwish                Div_139                  1 1 452 460 0=1.666667e-01
ConvolutionDepthWise     Conv_140                 1 1 460 462 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish                Div_149                  1 1 462 470 0=1.666667e-01
Convolution              Conv_150                 1 1 470 472 0=40 1=1 5=1 6=3840
BinaryOp                 Add_152                  2 1 450_splitncnn_0 472 473
Convolution              Conv_153                 1 1 473 475 0=240 1=1 5=1 6=9600
HardSwish                Div_162                  1 1 475 483 0=1.666667e-01
ConvolutionDepthWise     Conv_163                 1 1 483 485 0=240 1=3 4=1 5=1 6=2160 7=240
HardSwish                Div_172                  1 1 485 493 0=1.666667e-01
Convolution              Conv_173                 1 1 493 495 0=56 1=1 5=1 6=13440
Split                    splitncnn_9              1 2 495 495_splitncnn_0 495_splitncnn_1
Convolution              Conv_175                 1 1 495_splitncnn_1 497 0=336 1=1 5=1 6=18816
HardSwish                Div_184                  1 1 497 505 0=1.666667e-01
ConvolutionDepthWise     Conv_185                 1 1 505 507 0=336 1=3 4=1 5=1 6=3024 7=336
HardSwish                Div_194                  1 1 507 515 0=1.666667e-01
Convolution              Conv_195                 1 1 515 517 0=56 1=1 5=1 6=18816
BinaryOp                 Add_197                  2 1 495_splitncnn_0 517 518
Split                    splitncnn_10             1 2 518 518_splitncnn_0 518_splitncnn_1
Convolution              Conv_198                 1 1 518_splitncnn_1 520 0=336 1=1 5=1 6=18816
HardSwish                Div_207                  1 1 520 528 0=1.666667e-01
ConvolutionDepthWise     Conv_208                 1 1 528 530 0=336 1=5 3=2 4=2 5=1 6=8400 7=336
HardSwish                Div_217                  1 1 530 538 0=1.666667e-01
Convolution              Conv_218                 1 1 538 540 0=80 1=1 5=1 6=26880
Split                    splitncnn_11             1 2 540 540_splitncnn_0 540_splitncnn_1
Convolution              Conv_220                 1 1 540_splitncnn_1 542 0=480 1=1 5=1 6=38400
HardSwish                Div_229                  1 1 542 550 0=1.666667e-01
ConvolutionDepthWise     Conv_230                 1 1 550 552 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish                Div_239                  1 1 552 560 0=1.666667e-01
Convolution              Conv_240                 1 1 560 562 0=80 1=1 5=1 6=38400
BinaryOp                 Add_242                  2 1 540_splitncnn_0 562 563
Split                    splitncnn_12             1 2 563 563_splitncnn_0 563_splitncnn_1
Convolution              Conv_243                 1 1 563_splitncnn_1 565 0=480 1=1 5=1 6=38400
HardSwish                Div_252                  1 1 565 573 0=1.666667e-01
ConvolutionDepthWise     Conv_253                 1 1 573 575 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish                Div_262                  1 1 575 583 0=1.666667e-01
Convolution              Conv_263                 1 1 583 585 0=80 1=1 5=1 6=38400
BinaryOp                 Add_265                  2 1 563_splitncnn_0 585 586
Convolution              Conv_266                 1 1 586 588 0=480 1=1 5=1 6=38400
HardSwish                Div_275                  1 1 588 596 0=1.666667e-01
Convolution              Conv_276                 1 1 596 597 0=96 1=1 6=46080
Split                    splitncnn_13             1 2 597 597_splitncnn_0 597_splitncnn_1
Convolution              Conv_277                 1 1 518_splitncnn_0 598 0=96 1=1 6=5376
Convolution              Conv_278                 1 1 382_splitncnn_0 599 0=96 1=1 6=2304
Convolution              Conv_279                 1 1 356_splitncnn_0 600 0=96 1=1 6=1536
Interp                   Resize_281               1 1 597_splitncnn_1 610 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_282                  2 1 598 610 611
Split                    splitncnn_14             1 2 611 611_splitncnn_0 611_splitncnn_1
Interp                   Resize_284               1 1 611_splitncnn_1 621 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_285                  2 1 599 621 622
Split                    splitncnn_15             1 2 622 622_splitncnn_0 622_splitncnn_1
Interp                   Resize_287               1 1 622_splitncnn_1 632 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_288                  2 1 600 632 633
Convolution              Conv_289                 1 1 597_splitncnn_0 634 0=24 1=3 4=1 6=20736
Convolution              Conv_290                 1 1 611_splitncnn_0 635 0=24 1=3 4=1 6=20736
Convolution              Conv_291                 1 1 622_splitncnn_0 636 0=24 1=3 4=1 6=20736
Convolution              Conv_292                 1 1 633 637 0=24 1=3 4=1 6=20736
Interp                   Resize_294               1 1 634 647 0=1 1=8.000000e+00 2=8.000000e+00
Interp                   Resize_296               1 1 635 657 0=1 1=4.000000e+00 2=4.000000e+00
Interp                   Resize_298               1 1 636 667 0=1 1=2.000000e+00 2=2.000000e+00
Concat                   Concat_299               4 1 647 657 667 637 668
Convolution              Conv_300                 1 1 668 671 0=24 1=3 4=1 5=1 6=20736 9=1
Deconvolution            ConvTranspose_303        1 1 671 674 0=24 1=2 3=2 5=1 6=2304 9=1
Deconvolution            ConvTranspose_306        1 1 674 out1 0=1 1=2 3=2 5=1 6=96 9=4


================================================
FILE: app/src/main/assets/paddleocr_keys.txt
================================================
'
疗
绚
诚
娇
溜
题
贿
者
廖
更
纳
加
奉
公
一
就
汴
计
与
路
房
原
妇
2
0
8
-
7
其
>
:
]
,
,
骑
刈
全
消
昏
傈
安
久
钟
嗅
不
影
处
驽
蜿
资
关
椤
地
瘸
专
问
忖
票
嫉
炎
韵
要
月
田
节
陂
鄙
捌
备
拳
伺
眼
网
盎
大
傍
心
东
愉
汇
蹿
科
每
业
里
航
晏
字
平
录
先
1
3
彤
鲶
产
稍
督
腴
有
象
岳
注
绍
在
泺
文
定
核
名
水
过
理
让
偷
率
等
这
发
”
为
含
肥
酉
相
鄱
七
编
猥
锛
日
镀
蒂
掰
倒
辆
栾
栗
综
涩
州
雌
滑
馀
了
机
块
司
宰
甙
兴
矽
抚
保
用
沧
秩
如
收
息
滥
页
疑
埠
!
!
姥
异
橹
钇
向
下
跄
的
椴
沫
国
绥
獠
报
开
民
蜇
何
分
凇
长
讥
藏
掏
施
羽
中
讲
派
嘟
人
提
浼
间
世
而
古
多
倪
唇
饯
控
庚
首
赛
蜓
味
断
制
觉
技
替
艰
溢
潮
夕
钺
外
摘
枋
动
双
单
啮
户
枇
确
锦
曜
杜
或
能
效
霜
盒
然
侗
电
晁
放
步
鹃
新
杖
蜂
吒
濂
瞬
评
总
隍
对
独
合
也
是
府
青
天
诲
墙
组
滴
级
邀
帘
示
已
时
骸
仄
泅
和
遨
店
雇
疫
持
巍
踮
境
只
亨
目
鉴
崤
闲
体
泄
杂
作
般
轰
化
解
迂
诿
蛭
璀
腾
告
版
服
省
师
小
规
程
线
海
办
引
二
桧
牌
砺
洄
裴
修
图
痫
胡
许
犊
事
郛
基
柴
呼
食
研
奶
律
蛋
因
葆
察
戏
褒
戒
再
李
骁
工
貂
油
鹅
章
啄
休
场
给
睡
纷
豆
器
捎
说
敏
学
会
浒
设
诊
格
廓
查
来
霓
室
溆
¢
诡
寥
焕
舜
柒
狐
回
戟
砾
厄
实
翩
尿
五
入
径
惭
喹
股
宇
篝
|
;
美
期
云
九
祺
扮
靠
锝
槌
系
企
酰
阊
暂
蚕
忻
豁
本
羹
执
条
钦
H
獒
限
进
季
楦
于
芘
玖
铋
茯
未
答
粘
括
样
精
欠
矢
甥
帷
嵩
扣
令
仔
风
皈
行
支
部
蓉
刮
站
蜡
救
钊
汗
松
嫌
成
可
.
鹤
院
从
交
政
怕
活
调
球
局
验
髌
第
韫
谗
串
到
圆
年
米
/
*
友
忿
检
区
看
自
敢
刃
个
兹
弄
流
留
同
没
齿
星
聆
轼
湖
什
三
建
蛔
儿
椋
汕
震
颧
鲤
跟
力
情
璺
铨
陪
务
指
族
训
滦
鄣
濮
扒
商
箱
十
召
慷
辗
所
莞
管
护
臭
横
硒
嗓
接
侦
六
露
党
馋
驾
剖
高
侬
妪
幂
猗
绺
骐
央
酐
孝
筝
课
徇
缰
门
男
西
项
句
谙
瞒
秃
篇
教
碲
罚
声
呐
景
前
富
嘴
鳌
稀
免
朋
啬
睐
去
赈
鱼
住
肩
愕
速
旁
波
厅
健
茼
厥
鲟
谅
投
攸
炔
数
方
击
呋
谈
绩
别
愫
僚
躬
鹧
胪
炳
招
喇
膨
泵
蹦
毛
结
5
4
谱
识
陕
粽
婚
拟
构
且
搜
任
潘
比
郢
妨
醪
陀
桔
碘
扎
选
哈
骷
楷
亿
明
缆
脯
监
睫
逻
婵
共
赴
淝
凡
惦
及
达
揖
谩
澹
减
焰
蛹
番
祁
柏
员
禄
怡
峤
龙
白
叽
生
闯
起
细
装
谕
竟
聚
钙
上
导
渊
按
艾
辘
挡
耒
盹
饪
臀
记
邮
蕙
受
各
医
搂
普
滇
朗
茸
带
翻
酚
(
光
堤
墟
蔷
万
幻
〓
瑙
辈
昧
盏
亘
蛀
吉
铰
请
子
假
闻
税
井
诩
哨
嫂
好
面
琐
校
馊
鬣
缂
营
访
炖
占
农
缀
否
经
钚
棵
趟
张
亟
吏
茶
谨
捻
论
迸
堂
玉
信
吧
瞠
乡
姬
寺
咬
溏
苄
皿
意
赉
宝
尔
钰
艺
特
唳
踉
都
荣
倚
登
荐
丧
奇
涵
批
炭
近
符
傩
感
道
着
菊
虹
仲
众
懈
濯
颞
眺
南
释
北
缝
标
既
茗
整
撼
迤
贲
挎
耱
拒
某
妍
卫
哇
英
矶
藩
治
他
元
领
膜
遮
穗
蛾
飞
荒
棺
劫
么
市
火
温
拈
棚
洼
转
果
奕
卸
迪
伸
泳
斗
邡
侄
涨
屯
萋
胭
氡
崮
枞
惧
冒
彩
斜
手
豚
随
旭
淑
妞
形
菌
吲
沱
争
驯
歹
挟
兆
柱
传
至
包
内
响
临
红
功
弩
衡
寂
禁
老
棍
耆
渍
织
害
氵
渑
布
载
靥
嗬
虽
苹
咨
娄
库
雉
榜
帜
嘲
套
瑚
亲
簸
欧
边
6
腿
旮
抛
吹
瞳
得
镓
梗
厨
继
漾
愣
憨
士
策
窑
抑
躯
襟
脏
参
贸
言
干
绸
鳄
穷
藜
音
折
详
)
举
悍
甸
癌
黎
谴
死
罩
迁
寒
驷
袖
媒
蒋
掘
模
纠
恣
观
祖
蛆
碍
位
稿
主
澧
跌
筏
京
锏
帝
贴
证
糠
才
黄
鲸
略
炯
饱
四
出
园
犀
牧
容
汉
杆
浈
汰
瑷
造
虫
瘩
怪
驴
济
应
花
沣
谔
夙
旅
价
矿
以
考
s
u
呦
晒
巡
茅
准
肟
瓴
詹
仟
褂
译
桌
混
宁
怦
郑
抿
些
余
鄂
饴
攒
珑
群
阖
岔
琨
藓
预
环
洮
岌
宀
杲
瀵
最
常
囡
周
踊
女
鼓
袭
喉
简
范
薯
遐
疏
粱
黜
禧
法
箔
斤
遥
汝
奥
直
贞
撑
置
绱
集
她
馅
逗
钧
橱
魉
[
恙
躁
唤
9
旺
膘
待
脾
惫
购
吗
依
盲
度
瘿
蠖
俾
之
镗
拇
鲵
厝
簧
续
款
展
啃
表
剔
品
钻
腭
损
清
锶
统
涌
寸
滨
贪
链
吠
冈
伎
迥
咏
吁
览
防
迅
失
汾
阔
逵
绀
蔑
列
川
凭
努
熨
揪
利
俱
绉
抢
鸨
我
即
责
膦
易
毓
鹊
刹
玷
岿
空
嘞
绊
排
术
估
锷
违
们
苟
铜
播
肘
件
烫
审
鲂
广
像
铌
惰
铟
巳
胍
鲍
康
憧
色
恢
想
拷
尤
疳
知
S
Y
F
D
A
峄
裕
帮
握
搔
氐
氘
难
墒
沮
雨
叁
缥
悴
藐
湫
娟
苑
稠
颛
簇
后
阕
闭
蕤
缚
怎
佞
码
嘤
蔡
痊
舱
螯
帕
赫
昵
升
烬
岫
、
疵
蜻
髁
蕨
隶
烛
械
丑
盂
梁
强
鲛
由
拘
揉
劭
龟
撤
钩
呕
孛
费
妻
漂
求
阑
崖
秤
甘
通
深
补
赃
坎
床
啪
承
吼
量
暇
钼
烨
阂
擎
脱
逮
称
P
神
属
矗
华
届
狍
葑
汹
育
患
窒
蛰
佼
静
槎
运
鳗
庆
逝
曼
疱
克
代
官
此
麸
耧
蚌
晟
例
础
榛
副
测
唰
缢
迹
灬
霁
身
岁
赭
扛
又
菡
乜
雾
板
读
陷
徉
贯
郁
虑
变
钓
菜
圾
现
琢
式
乐
维
渔
浜
左
吾
脑
钡
警
T
啵
拴
偌
漱
湿
硕
止
骼
魄
积
燥
联
踢
玛
则
窿
见
振
畿
送
班
钽
您
赵
刨
印
讨
踝
籍
谡
舌
崧
汽
蔽
沪
酥
绒
怖
财
帖
肱
私
莎
勋
羔
霸
励
哼
帐
将
帅
渠
纪
婴
娩
岭
厘
滕
吻
伤
坝
冠
戊
隆
瘁
介
涧
物
黍
并
姗
奢
蹑
掣
垸
锴
命
箍
捉
病
辖
琰
眭
迩
艘
绌
繁
寅
若
毋
思
诉
类
诈
燮
轲
酮
狂
重
反
职
筱
县
委
磕
绣
奖
晋
濉
志
徽
肠
呈
獐
坻
口
片
碰
几
村
柿
劳
料
获
亩
惕
晕
厌
号
罢
池
正
鏖
煨
家
棕
复
尝
懋
蜥
锅
岛
扰
队
坠
瘾
钬
@
卧
疣
镇
譬
冰
彷
频
黯
据
垄
采
八
缪
瘫
型
熹
砰
楠
襁
箐
但
嘶
绳
啤
拍
盥
穆
傲
洗
盯
塘
怔
筛
丿
台
恒
喂
葛
永
¥
烟
酒
桦
书
砂
蚝
缉
态
瀚
袄
圳
轻
蛛
超
榧
遛
姒
奘
铮
右
荽
望
偻
卡
丶
氰
附
做
革
索
戚
坨
桷
唁
垅
榻
岐
偎
坛
莨
山
殊
微
骇
陈
爨
推
嗝
驹
澡
藁
呤
卤
嘻
糅
逛
侵
郓
酌
德
摇
※
鬃
被
慨
殡
羸
昌
泡
戛
鞋
河
宪
沿
玲
鲨
翅
哽
源
铅
语
照
邯
址
荃
佬
顺
鸳
町
霭
睾
瓢
夸
椁
晓
酿
痈
咔
侏
券
噎
湍
签
嚷
离
午
尚
社
锤
背
孟
使
浪
缦
潍
鞅
军
姹
驶
笑
鳟
鲁
》
孽
钜
绿
洱
礴
焯
椰
颖
囔
乌
孔
巴
互
性
椽
哞
聘
昨
早
暮
胶
炀
隧
低
彗
昝
铁
呓
氽
藉
喔
癖
瑗
姨
权
胱
韦
堑
蜜
酋
楝
砝
毁
靓
歙
锲
究
屋
喳
骨
辨
碑
武
鸠
宫
辜
烊
适
坡
殃
培
佩
供
走
蜈
迟
翼
况
姣
凛
浔
吃
飘
债
犟
金
促
苛
崇
坂
莳
畔
绂
兵
蠕
斋
根
砍
亢
欢
恬
崔
剁
餐
榫
快
扶
‖
濒
缠
鳜
当
彭
驭
浦
篮
昀
锆
秸
钳
弋
娣
瞑
夷
龛
苫
拱
致
%
嵊
障
隐
弑
初
娓
抉
汩
累
蓖
"
唬
助
苓
昙
押
毙
破
城
郧
逢
嚏
獭
瞻
溱
婿
赊
跨
恼
璧
萃
姻
貉
灵
炉
密
氛
陶
砸
谬
衔
点
琛
沛
枳
层
岱
诺
脍
榈
埂
征
冷
裁
打
蹴
素
瘘
逞
蛐
聊
激
腱
萘
踵
飒
蓟
吆
取
咙
簋
涓
矩
曝
挺
揣
座
你
史
舵
焱
尘
苏
笈
脚
溉
榨
诵
樊
邓
焊
义
庶
儋
蟋
蒲
赦
呷
杞
诠
豪
还
试
颓
茉
太
除
紫
逃
痴
草
充
鳕
珉
祗
墨
渭
烩
蘸
慕
璇
镶
穴
嵘
恶
骂
险
绋
幕
碉
肺
戳
刘
潞
秣
纾
潜
銮
洛
须
罘
销
瘪
汞
兮
屉
r
林
厕
质
探
划
狸
殚
善
煊
烹
〒
锈
逯
宸
辍
泱
柚
袍
远
蹋
嶙
绝
峥
娥
缍
雀
徵
认
镱
谷
=
贩
勉
撩
鄯
斐
洋
非
祚
泾
诒
饿
撬
威
晷
搭
芍
锥
笺
蓦
候
琊
档
礁
沼
卵
荠
忑
朝
凹
瑞
头
仪
弧
孵
畏
铆
突
衲
车
浩
气
茂
悖
厢
枕
酝
戴
湾
邹
飚
攘
锂
写
宵
翁
岷
无
喜
丈
挑
嗟
绛
殉
议
槽
具
醇
淞
笃
郴
阅
饼
底
壕
砚
弈
询
缕
庹
翟
零
筷
暨
舟
闺
甯
撞
麂
茌
蔼
很
珲
捕
棠
角
阉
媛
娲
诽
剿
尉
爵
睬
韩
诰
匣
危
糍
镯
立
浏
阳
少
盆
舔
擘
匪
申
尬
铣
旯
抖
赘
瓯
居
ˇ
哮
游
锭
茏
歌
坏
甚
秒
舞
沙
仗
劲
潺
阿
燧
郭
嗖
霏
忠
材
奂
耐
跺
砀
输
岖
媳
氟
极
摆
灿
今
扔
腻
枝
奎
药
熄
吨
话
q
额
慑
嘌
协
喀
壳
埭
视
著
於
愧
陲
翌
峁
颅
佛
腹
聋
侯
咎
叟
秀
颇
存
较
罪
哄
岗
扫
栏
钾
羌
己
璨
枭
霉
煌
涸
衿
键
镝
益
岢
奏
连
夯
睿
冥
均
糖
狞
蹊
稻
爸
刿
胥
煜
丽
肿
璃
掸
跚
灾
垂
樾
濑
乎
莲
窄
犹
撮
战
馄
软
络
显
鸢
胸
宾
妲
恕
埔
蝌
份
遇
巧
瞟
粒
恰
剥
桡
博
讯
凯
堇
阶
滤
卖
斌
骚
彬
兑
磺
樱
舷
两
娱
福
仃
差
找
桁
÷
净
把
阴
污
戬
雷
碓
蕲
楚
罡
焖
抽
妫
咒
仑
闱
尽
邑
菁
爱
贷
沥
鞑
牡
嗉
崴
骤
塌
嗦
订
拮
滓
捡
锻
次
坪
杩
臃
箬
融
珂
鹗
宗
枚
降
鸬
妯
阄
堰
盐
毅
必
杨
崃
俺
甬
状
莘
货
耸
菱
腼
铸
唏
痤
孚
澳
懒
溅
翘
疙
杷
淼
缙
骰
喊
悉
砻
坷
艇
赁
界
谤
纣
宴
晃
茹
归
饭
梢
铡
街
抄
肼
鬟
苯
颂
撷
戈
炒
咆
茭
瘙
负
仰
客
琉
铢
封
卑
珥
椿
镧
窨
鬲
寿
御
袤
铃
萎
砖
餮
脒
裳
肪
孕
嫣
馗
嵇
恳
氯
江
石
褶
冢
祸
阻
狈
羞
银
靳
透
咳
叼
敷
芷
啥
它
瓤
兰
痘
懊
逑
肌
往
捺
坊
甩
呻
〃
沦
忘
膻
祟
菅
剧
崆
智
坯
臧
霍
墅
攻
眯
倘
拢
骠
铐
庭
岙
瓠
′
缺
泥
迢
捶
?
?
郏
喙
掷
沌
纯
秘
种
听
绘
固
螨
团
香
盗
妒
埚
蓝
拖
旱
荞
铀
血
遏
汲
辰
叩
拽
幅
硬
惶
桀
漠
措
泼
唑
齐
肾
念
酱
虚
屁
耶
旗
砦
闵
婉
馆
拭
绅
韧
忏
窝
醋
葺
顾
辞
倜
堆
辋
逆
玟
贱
疾
董
惘
倌
锕
淘
嘀
莽
俭
笏
绑
鲷
杈
择
蟀
粥
嗯
驰
逾
案
谪
褓
胫
哩
昕
颚
鲢
绠
躺
鹄
崂
儒
俨
丝
尕
泌
啊
萸
彰
幺
吟
骄
苣
弦
脊
瑰
〈
诛
镁
析
闪
剪
侧
哟
框
螃
守
嬗
燕
狭
铈
缮
概
迳
痧
鲲
俯
售
笼
痣
扉
挖
满
咋
援
邱
扇
歪
便
玑
绦
峡
蛇
叨
〖
泽
胃
斓
喋
怂
坟
猪
该
蚬
炕
弥
赞
棣
晔
娠
挲
狡
创
疖
铕
镭
稷
挫
弭
啾
翔
粉
履
苘
哦
楼
秕
铂
土
锣
瘟
挣
栉
习
享
桢
袅
磨
桂
谦
延
坚
蔚
噗
署
谟
猬
钎
恐
嬉
雒
倦
衅
亏
璩
睹
刻
殿
王
算
雕
麻
丘
柯
骆
丸
塍
谚
添
鲈
垓
桎
蚯
芥
予
飕
镦
谌
窗
醚
菀
亮
搪
莺
蒿
羁
足
J
真
轶
悬
衷
靛
翊
掩
哒
炅
掐
冼
妮
l
谐
稚
荆
擒
犯
陵
虏
浓
崽
刍
陌
傻
孜
千
靖
演
矜
钕
煽
杰
酗
渗
伞
栋
俗
泫
戍
罕
沾
疽
灏
煦
芬
磴
叱
阱
榉
湃
蜀
叉
醒
彪
租
郡
篷
屎
良
垢
隗
弱
陨
峪
砷
掴
颁
胎
雯
绵
贬
沐
撵
隘
篙
暖
曹
陡
栓
填
臼
彦
瓶
琪
潼
哪
鸡
摩
啦
俟
锋
域
耻
蔫
疯
纹
撇
毒
绶
痛
酯
忍
爪
赳
歆
嘹
辕
烈
册
朴
钱
吮
毯
癜
娃
谀
邵
厮
炽
璞
邃
丐
追
词
瓒
忆
轧
芫
谯
喷
弟
半
冕
裙
掖
墉
绮
寝
苔
势
顷
褥
切
衮
君
佳
嫒
蚩
霞
佚
洙
逊
镖
暹
唛
&
殒
顶
碗
獗
轭
铺
蛊
废
恹
汨
崩
珍
那
杵
曲
纺
夏
薰
傀
闳
淬
姘
舀
拧
卷
楂
恍
讪
厩
寮
篪
赓
乘
灭
盅
鞣
沟
慎
挂
饺
鼾
杳
树
缨
丛
絮
娌
臻
嗳
篡
侩
述
衰
矛
圈
蚜
匕
筹
匿
濞
晨
叶
骋
郝
挚
蚴
滞
增
侍
描
瓣
吖
嫦
蟒
匾
圣
赌
毡
癞
恺
百
曳
需
篓
肮
庖
帏
卿
驿
遗
蹬
鬓
骡
歉
芎
胳
屐
禽
烦
晌
寄
媾
狄
翡
苒
船
廉
终
痞
殇
々
畦
饶
改
拆
悻
萄
£
瓿
乃
訾
桅
匮
溧
拥
纱
铍
骗
蕃
龋
缬
父
佐
疚
栎
醍
掳
蓄
x
惆
颜
鲆
榆
〔
猎
敌
暴
谥
鲫
贾
罗
玻
缄
扦
芪
癣
落
徒
臾
恿
猩
托
邴
肄
牵
春
陛
耀
刊
拓
蓓
邳
堕
寇
枉
淌
啡
湄
兽
酷
萼
碚
濠
萤
夹
旬
戮
梭
琥
椭
昔
勺
蜊
绐
晚
孺
僵
宣
摄
冽
旨
萌
忙
蚤
眉
噼
蟑
付
契
瓜
悼
颡
壁
曾
窕
颢
澎
仿
俑
浑
嵌
浣
乍
碌
褪
乱
蔟
隙
玩
剐
葫
箫
纲
围
伐
决
伙
漩
瑟
刑
肓
镳
缓
蹭
氨
皓
典
畲
坍
铑
檐
塑
洞
倬
储
胴
淳
戾
吐
灼
惺
妙
毕
珐
缈
虱
盖
羰
鸿
磅
谓
髅
娴
苴
唷
蚣
霹
抨
贤
唠
犬
誓
逍
庠
逼
麓
籼
釉
呜
碧
秧
氩
摔
霄
穸
纨
辟
妈
映
完
牛
缴
嗷
炊
恩
荔
茆
掉
紊
慌
莓
羟
阙
萁
磐
另
蕹
辱
鳐
湮
吡
吩
唐
睦
垠
舒
圜
冗
瞿
溺
芾
囱
匠
僳
汐
菩
饬
漓
黑
霰
浸
濡
窥
毂
蒡
兢
驻
鹉
芮
诙
迫
雳
厂
忐
臆
猴
鸣
蚪
栈
箕
羡
渐
莆
捍
眈
哓
趴
蹼
埕
嚣
骛
宏
淄
斑
噜
严
瑛
垃
椎
诱
压
庾
绞
焘
廿
抡
迄
棘
夫
纬
锹
眨
瞌
侠
脐
竞
瀑
孳
骧
遁
姜
颦
荪
滚
萦
伪
逸
粳
爬
锁
矣
役
趣
洒
颔
诏
逐
奸
甭
惠
攀
蹄
泛
尼
拼
阮
鹰
亚
颈
惑
勒
〉
际
肛
爷
刚
钨
丰
养
冶
鲽
辉
蔻
画
覆
皴
妊
麦
返
醉
皂
擀
〗
酶
凑
粹
悟
诀
硖
港
卜
z
杀
涕
±
舍
铠
抵
弛
段
敝
镐
奠
拂
轴
跛
袱
e
t
沉
菇
俎
薪
峦
秭
蟹
历
盟
菠
寡
液
肢
喻
染
裱
悱
抱
氙
赤
捅
猛
跑
氮
谣
仁
尺
辊
窍
烙
衍
架
擦
倏
璐
瑁
币
楞
胖
夔
趸
邛
惴
饕
虔
蝎
§
哉
贝
宽
辫
炮
扩
饲
籽
魏
菟
锰
伍
猝
末
琳
哚
蛎
邂
呀
姿
鄞
却
歧
仙
恸
椐
森
牒
寤
袒
婆
虢
雅
钉
朵
贼
欲
苞
寰
故
龚
坭
嘘
咫
礼
硷
兀
睢
汶
’
铲
烧
绕
诃
浃
钿
哺
柜
讼
颊
璁
腔
洽
咐
脲
簌
筠
镣
玮
鞠
谁
兼
姆
挥
梯
蝴
谘
漕
刷
躏
宦
弼
b
垌
劈
麟
莉
揭
笙
渎
仕
嗤
仓
配
怏
抬
错
泯
镊
孰
猿
邪
仍
秋
鼬
壹
歇
吵
炼
<
尧
射
柬
廷
胧
霾
凳
隋
肚
浮
梦
祥
株
堵
退
L
鹫
跎
凶
毽
荟
炫
栩
玳
甜
沂
鹿
顽
伯
爹
赔
蛴
徐
匡
欣
狰
缸
雹
蟆
疤
默
沤
啜
痂
衣
禅
w
i
h
辽
葳
黝
钗
停
沽
棒
馨
颌
肉
吴
硫
悯
劾
娈
马
啧
吊
悌
镑
峭
帆
瀣
涉
咸
疸
滋
泣
翦
拙
癸
钥
蜒
+
尾
庄
凝
泉
婢
渴
谊
乞
陆
锉
糊
鸦
淮
I
B
N
晦
弗
乔
庥
葡
尻
席
橡
傣
渣
拿
惩
麋
斛
缃
矮
蛏
岘
鸽
姐
膏
催
奔
镒
喱
蠡
摧
钯
胤
柠
拐
璋
鸥
卢
荡
倾
^
_
珀
逄
萧
塾
掇
贮
笆
聂
圃
冲
嵬
M
滔
笕
值
炙
偶
蜱
搐
梆
汪
蔬
腑
鸯
蹇
敞
绯
仨
祯
谆
梧
糗
鑫
啸
豺
囹
猾
巢
柄
瀛
筑
踌
沭
暗
苁
鱿
蹉
脂
蘖
牢
热
木
吸
溃
宠
序
泞
偿
拜
檩
厚
朐
毗
螳
吞
媚
朽
担
蝗
橘
畴
祈
糟
盱
隼
郜
惜
珠
裨
铵
焙
琚
唯
咚
噪
骊
丫
滢
勤
棉
呸
咣
淀
隔
蕾
窈
饨
挨
煅
短
匙
粕
镜
赣
撕
墩
酬
馁
豌
颐
抗
酣
氓
佑
搁
哭
递
耷
涡
桃
贻
碣
截
瘦
昭
镌
蔓
氚
甲
猕
蕴
蓬
散
拾
纛
狼
猷
铎
埋
旖
矾
讳
囊
糜
迈
粟
蚂
紧
鲳
瘢
栽
稼
羊
锄
斟
睁
桥
瓮
蹙
祉
醺
鼻
昱
剃
跳
篱
跷
蒜
翎
宅
晖
嗑
壑
峻
癫
屏
狠
陋
袜
途
憎
祀
莹
滟
佶
溥
臣
约
盛
峰
磁
慵
婪
拦
莅
朕
鹦
粲
裤
哎
疡
嫖
琵
窟
堪
谛
嘉
儡
鳝
斩
郾
驸
酊
妄
胜
贺
徙
傅
噌
钢
栅
庇
恋
匝
巯
邈
尸
锚
粗
佟
蛟
薹
纵
蚊
郅
绢
锐
苗
俞
篆
淆
膀
鲜
煎
诶
秽
寻
涮
刺
怀
噶
巨
褰
魅
灶
灌
桉
藕
谜
舸
薄
搀
恽
借
牯
痉
渥
愿
亓
耘
杠
柩
锔
蚶
钣
珈
喘
蹒
幽
赐
稗
晤
莱
泔
扯
肯
菪
裆
腩
豉
疆
骜
腐
倭
珏
唔
粮
亡
润
慰
伽
橄
玄
誉
醐
胆
龊
粼
塬
陇
彼
削
嗣
绾
芽
妗
垭
瘴
爽
薏
寨
龈
泠
弹
赢
漪
猫
嘧
涂
恤
圭
茧
烽
屑
痕
巾
赖
荸
凰
腮
畈
亵
蹲
偃
苇
澜
艮
换
骺
烘
苕
梓
颉
肇
哗
悄
氤
涠
葬
屠
鹭
植
竺
佯
诣
鲇
瘀
鲅
邦
移
滁
冯
耕
癔
戌
茬
沁
巩
悠
湘
洪
痹
锟
循
谋
腕
鳃
钠
捞
焉
迎
碱
伫
急
榷
奈
邝
卯
辄
皲
卟
醛
畹
忧
稳
雄
昼
缩
阈
睑
扌
耗
曦
涅
捏
瞧
邕
淖
漉
铝
耦
禹
湛
喽
莼
琅
诸
苎
纂
硅
始
嗨
傥
燃
臂
赅
嘈
呆
贵
屹
壮
肋
亍
蚀
卅
豹
腆
邬
迭
浊
}
童
螂
捐
圩
勐
触
寞
汊
壤
荫
膺
渌
芳
懿
遴
螈
泰
蓼
蛤
茜
舅
枫
朔
膝
眙
避
梅
判
鹜
璜
牍
缅
垫
藻
黔
侥
惚
懂
踩
腰
腈
札
丞
唾
慈
顿
摹
荻
琬
~
斧
沈
滂
胁
胀
幄
莜
Z
匀
鄄
掌
绰
茎
焚
赋
萱
谑
汁
铒
瞎
夺
蜗
野
娆
冀
弯
篁
懵
灞
隽
芡
脘
俐
辩
芯
掺
喏
膈
蝈
觐
悚
踹
蔗
熠
鼠
呵
抓
橼
峨
畜
缔
禾
崭
弃
熊
摒
凸
拗
穹
蒙
抒
祛
劝
闫
扳
阵
醌
踪
喵
侣
搬
仅
荧
赎
蝾
琦
买
婧
瞄
寓
皎
冻
赝
箩
莫
瞰
郊
笫
姝
筒
枪
遣
煸
袋
舆
痱
涛
母
〇
启
践
耙
绲
盘
遂
昊
搞
槿
诬
纰
泓
惨
檬
亻
越
C
o
憩
熵
祷
钒
暧
塔
阗
胰
咄
娶
魔
琶
钞
邻
扬
杉
殴
咽
弓
〆
髻
】
吭
揽
霆
拄
殖
脆
彻
岩
芝
勃
辣
剌
钝
嘎
甄
佘
皖
伦
授
徕
憔
挪
皇
庞
稔
芜
踏
溴
兖
卒
擢
饥
鳞
煲
‰
账
颗
叻
斯
捧
鳍
琮
讹
蛙
纽
谭
酸
兔
莒
睇
伟
觑
羲
嗜
宜
褐
旎
辛
卦
诘
筋
鎏
溪
挛
熔
阜
晰
鳅
丢
奚
灸
呱
献
陉
黛
鸪
甾
萨
疮
拯
洲
疹
辑
叙
恻
谒
允
柔
烂
氏
逅
漆
拎
惋
扈
湟
纭
啕
掬
擞
哥
忽
涤
鸵
靡
郗
瓷
扁
廊
怨
雏
钮
敦
E
懦
憋
汀
拚
啉
腌
岸
f
痼
瞅
尊
咀
眩
飙
忌
仝
迦
熬
毫
胯
篑
茄
腺
凄
舛
碴
锵
诧
羯
後
漏
汤
宓
仞
蚁
壶
谰
皑
铄
棰
罔
辅
晶
苦
牟
闽
\
烃
饮
聿
丙
蛳
朱
煤
涔
鳖
犁
罐
荼
砒
淦
妤
黏
戎
孑
婕
瑾
戢
钵
枣
捋
砥
衩
狙
桠
稣
阎
肃
梏
诫
孪
昶
婊
衫
嗔
侃
塞
蜃
樵
峒
貌
屿
欺
缫
阐
栖
诟
珞
荭
吝
萍
嗽
恂
啻
蜴
磬
峋
俸
豫
谎
徊
镍
韬
魇
晴
U
囟
猜
蛮
坐
囿
伴
亭
肝
佗
蝠
妃
胞
滩
榴
氖
垩
苋
砣
扪
馏
姓
轩
厉
夥
侈
禀
垒
岑
赏
钛
辐
痔
披
纸
碳
“
坞
蠓
挤
荥
沅
悔
铧
帼
蒌
蝇
a
p
y
n
g
哀
浆
瑶
凿
桶
馈
皮
奴
苜
佤
伶
晗
铱
炬
优
弊
氢
恃
甫
攥
端
锌
灰
稹
炝
曙
邋
亥
眶
碾
拉
萝
绔
捷
浍
腋
姑
菖
凌
涞
麽
锢
桨
潢
绎
镰
殆
锑
渝
铬
困
绽
觎
匈
糙
暑
裹
鸟
盔
肽
迷
綦
『
亳
佝
俘
钴
觇
骥
仆
疝
跪
婶
郯
瀹
唉
脖
踞
针
晾
忒
扼
瞩
叛
椒
疟
嗡
邗
肆
跆
玫
忡
捣
咧
唆
艄
蘑
潦
笛
阚
沸
泻
掊
菽
贫
斥
髂
孢
镂
赂
麝
鸾
屡
衬
苷
恪
叠
希
粤
爻
喝
茫
惬
郸
绻
庸
撅
碟
宄
妹
膛
叮
饵
崛
嗲
椅
冤
搅
咕
敛
尹
垦
闷
蝉
霎
勰
败
蓑
泸
肤
鹌
幌
焦
浠
鞍
刁
舰
乙
竿
裔
。
茵
函
伊
兄
丨
娜
匍
謇
莪
宥
似
蝽
翳
酪
翠
粑
薇
祢
骏
赠
叫
Q
噤
噻
竖
芗
莠
潭
俊
羿
耜
O
郫
趁
嗪
囚
蹶
芒
洁
笋
鹑
敲
硝
啶
堡
渲
揩
』
携
宿
遒
颍
扭
棱
割
萜
蔸
葵
琴
捂
饰
衙
耿
掠
募
岂
窖
涟
蔺
瘤
柞
瞪
怜
匹
距
楔
炜
哆
秦
缎
幼
茁
绪
痨
恨
楸
娅
瓦
桩
雪
嬴
伏
榔
妥
铿
拌
眠
雍
缇
‘
卓
搓
哌
觞
噩
屈
哧
髓
咦
巅
娑
侑
淫
膳
祝
勾
姊
莴
胄
疃
薛
蜷
胛
巷
芙
芋
熙
闰
勿
窃
狱
剩
钏
幢
陟
铛
慧
靴
耍
k
浙
浇
飨
惟
绗
祜
澈
啼
咪
磷
摞
诅
郦
抹
跃
壬
吕
肖
琏
颤
尴
剡
抠
凋
赚
泊
津
宕
殷
倔
氲
漫
邺
涎
怠
$
垮
荬
遵
俏
叹
噢
饽
蜘
孙
筵
疼
鞭
羧
牦
箭
潴
c
眸
祭
髯
啖
坳
愁
芩
驮
倡
巽
穰
沃
胚
怒
凤
槛
剂
趵
嫁
v
邢
灯
鄢
桐
睽
檗
锯
槟
婷
嵋
圻
诗
蕈
颠
遭
痢
芸
怯
馥
竭
锗
徜
恭
遍
籁
剑
嘱
苡
龄
僧
桑
潸
弘
澶
楹
悲
讫
愤
腥
悸
谍
椹
呢
桓
葭
攫
阀
翰
躲
敖
柑
郎
笨
橇
呃
魁
燎
脓
葩
磋
垛
玺
狮
沓
砜
蕊
锺
罹
蕉
翱
虐
闾
巫
旦
茱
嬷
枯
鹏
贡
芹
汛
矫
绁
拣
禺
佃
讣
舫
惯
乳
趋
疲
挽
岚
虾
衾
蠹
蹂
飓
氦
铖
孩
稞
瑜
壅
掀
勘
妓
畅
髋
W
庐
牲
蓿
榕
练
垣
唱
邸
菲
昆
婺
穿
绡
麒
蚱
掂
愚
泷
涪
漳
妩
娉
榄
讷
觅
旧
藤
煮
呛
柳
腓
叭
庵
烷
阡
罂
蜕
擂
猖
咿
媲
脉
【
沏
貅
黠
熏
哲
烁
坦
酵
兜
×
潇
撒
剽
珩
圹
乾
摸
樟
帽
嗒
襄
魂
轿
憬
锡
〕
喃
皆
咖
隅
脸
残
泮
袂
鹂
珊
囤
捆
咤
误
徨
闹
淙
芊
淋
怆
囗
拨
梳
渤
R
G
绨
蚓
婀
幡
狩
麾
谢
唢
裸
旌
伉
纶
裂
驳
砼
咛
澄
樨
蹈
宙
澍
倍
貔
操
勇
蟠
摈
砧
虬
够
缁
悦
藿
撸
艹
摁
淹
豇
虎
榭
ˉ
吱
d
°
喧
荀
踱
侮
奋
偕
饷
犍
惮
坑
璎
徘
宛
妆
袈
倩
窦
昂
荏
乖
K
怅
撰
鳙
牙
袁
酞
X
痿
琼
闸
雁
趾
荚
虻
涝
《
杏
韭
偈
烤
绫
鞘
卉
症
遢
蓥
诋
杭
荨
匆
竣
簪
辙
敕
虞
丹
缭
咩
黟
m
淤
瑕
咂
铉
硼
茨
嶂
痒
畸
敬
涿
粪
窘
熟
叔
嫔
盾
忱
裘
憾
梵
赡
珙
咯
娘
庙
溯
胺
葱
痪
摊
荷
卞
乒
髦
寐
铭
坩
胗
枷
爆
溟
嚼
羚
砬
轨
惊
挠
罄
竽
菏
氧
浅
楣
盼
枢
炸
阆
杯
谏
噬
淇
渺
俪
秆
墓
泪
跻
砌
痰
垡
渡
耽
釜
讶
鳎
煞
呗
韶
舶
绷
鹳
缜
旷
铊
皱
龌
檀
霖
奄
槐
艳
蝶
旋
哝
赶
骞
蚧
腊
盈
丁
`
蜚
矸
蝙
睨
嚓
僻
鬼
醴
夜
彝
磊
笔
拔
栀
糕
厦
邰
纫
逭
纤
眦
膊
馍
躇
烯
蘼
冬
诤
暄
骶
哑
瘠
」
臊
丕
愈
咱
螺
擅
跋
搏
硪
谄
笠
淡
嘿
骅
谧
鼎
皋
姚
歼
蠢
驼
耳
胬
挝
涯
狗
蒽
孓
犷
凉
芦
箴
铤
孤
嘛
坤
V
茴
朦
挞
尖
橙
诞
搴
碇
洵
浚
帚
蜍
漯
柘
嚎
讽
芭
荤
咻
祠
秉
跖
埃
吓
糯
眷
馒
惹
娼
鲑
嫩
讴
轮
瞥
靶
褚
乏
缤
宋
帧
删
驱
碎
扑
俩
俄
偏
涣
竹
噱
皙
佰
渚
唧
斡
#
镉
刀
崎
筐
佣
夭
贰
肴
峙
哔
艿
匐
牺
镛
缘
仡
嫡
劣
枸
堀
梨
簿
鸭
蒸
亦
稽
浴
{
衢
束
槲
j
阁
揍
疥
棋
潋
聪
窜
乓
睛
插
冉
阪
苍
搽
「
蟾
螟
幸
仇
樽
撂
慢
跤
幔
俚
淅
覃
觊
溶
妖
帛
侨
曰
妾
泗
·
:
瀘
風
Ë
(
)
∶
紅
紗
瑭
雲
頭
鶏
財
許
•
¥
樂
焗
麗
—
;
滙
東
榮
繪
興
…
門
業
π
楊
國
顧
é
盤
寳
Λ
龍
鳳
島
誌
緣
結
銭
萬
勝
祎
璟
優
歡
臨
時
購
=
★
藍
昇
鐵
觀
勅
農
聲
畫
兿
術
發
劉
記
專
耑
園
書
壴
種
Ο
●
褀
號
銀
匯
敟
锘
葉
橪
廣
進
蒄
鑽
阝
祙
貢
鍋
豊
夬
喆
團
閣
開
燁
賓
館
酡
沔
順
+
硚
劵
饸
陽
車
湓
復
萊
氣
軒
華
堃
迮
纟
戶
馬
學
裡
電
嶽
獨
マ
シ
サ
ジ
燘
袪
環
❤
臺
灣
専
賣
孖
聖
攝
線
▪
α
傢
俬
夢
達
莊
喬
貝
薩
劍
羅
壓
棛
饦
尃
璈
囍
醫
G
I
A
#
N
鷄
髙
嬰
啓
約
隹
潔
賴
藝
~
寶
籣
麺
 
嶺
√
義
網
峩
長
∧
魚
機
構
②
鳯
偉
L
B
㙟
畵
鴿
'
詩
溝
嚞
屌
藔
佧
玥
蘭
織
1
3
9
0
7
點
砭
鴨
鋪
銘
廳
弍
‧
創
湯
坶
℃
卩
骝
&
烜
荘
當
潤
扞
係
懷
碶
钅
蚨
讠
☆
叢
爲
埗
涫
塗
→
楽
現
鯨
愛
瑪
鈺
忄
悶
藥
飾
樓
視
孬
ㆍ
燚
苪
師
①
丼
锽
│
韓
標
è
兒
閏
匋
張
漢
Ü
髪
會
閑
檔
習
裝
の
峯
菘
輝
И
雞
釣
億
浐
K
O
R
8
H
E
P
T
W
D
S
C
M
F
姌
饹
»
晞
廰
ä
嵯
鷹
負
飲
絲
冚
楗
澤
綫
區
❋
←
質
靑
揚
③
滬
統
産
協
﹑
乸
畐
經
運
際
洺
岽
為
粵
諾
崋
豐
碁
ɔ
V
2
6
齋
誠
訂
´
勑
雙
陳
無
í
泩
媄
夌
刂
i
c
t
o
r
a
嘢
耄
燴
暃
壽
媽
靈
抻
體
唻
É
冮
甹
鎮
錦
ʌ
蜛
蠄
尓
駕
戀
飬
逹
倫
貴
極
Я
Й
寬
磚
嶪
郎
職
|
間
n
d
剎
伈
課
飛
橋
瘊
№
譜
骓
圗
滘
縣
粿
咅
養
濤
彳
®
%
Ⅱ
啰
㴪
見
矞
薬
糁
邨
鲮
顔
罱
З
選
話
贏
氪
俵
競
瑩
繡
枱
β
綉
á
獅
爾
™
麵
戋
淩
徳
個
劇
場
務
簡
寵
h
實
膠
轱
圖
築
嘣
樹
㸃
營
耵
孫
饃
鄺
飯
麯
遠
輸
坫
孃
乚
閃
鏢
㎡
題
廠
關
↑
爺
將
軍
連
篦
覌
參
箸
-
窠
棽
寕
夀
爰
歐
呙
閥
頡
熱
雎
垟
裟
凬
勁
帑
馕
夆
疌
枼
馮
貨
蒤
樸
彧
旸
靜
龢
暢
㐱
鳥
珺
鏡
灡
爭
堷
廚
Ó
騰
診
┅
蘇
褔
凱
頂
豕
亞
帥
嘬
⊥
仺
桖
複
饣
絡
穂
顏
棟
納
▏
濟
親
設
計
攵
埌
烺
ò
頤
燦
蓮
撻
節
講
濱
濃
娽
洳
朿
燈
鈴
護
膚
铔
過
補
Z
U
5
4
坋
闿
䖝
餘
缐
铞
貿
铪
桼
趙
鍊
[
㐂
垚
菓
揸
捲
鐘
滏
𣇉
爍
輪
燜
鴻
鮮
動
鹞
鷗
丄
慶
鉌
翥
飮
腸
⇋
漁
覺
來
熘
昴
翏
鲱
圧
鄉
萭
頔
爐
嫚
г
貭
類
聯
幛
輕
訓
鑒
夋
锨
芃
珣
䝉
扙
嵐
銷
處
ㄱ
語
誘
苝
歸
儀
燒
楿
內
粢
葒
奧
麥
礻
滿
蠔
穵
瞭
態
鱬
榞
硂
鄭
黃
煙
祐
奓
逺
*
瑄
獲
聞
薦
讀
這
樣
決
問
啟
們
執
説
轉
單
隨
唘
帶
倉
庫
還
贈
尙
皺
■
餅
產
○
∈
報
狀
楓
賠
琯
嗮
禮
`
傳
>
≤
嗞
Φ
≥
換
咭
∣
↓
曬
ε
応
寫
″
終
様
純
費
療
聨
凍
壐
郵
ü
黒
∫
製
塊
調
軽
確
撃
級
馴
Ⅲ
涇
繹
數
碼
證
狒
処
劑
<
晧
賀
衆
]
櫥
兩
陰
絶
對
鯉
憶
◎
p
e
Y
蕒
煖
頓
測
試
鼽
僑
碩
妝
帯
≈
鐡
舖
權
喫
倆
ˋ
該
悅
ā
俫
.
f
s
b
m
k
g
u
j
貼
淨
濕
針
適
備
l
/
給
謢
強
觸
衛
與
⊙
$
緯
變
⑴
⑵
⑶
㎏
殺
∩
幚
─
價
▲
離
ú
ó
飄
烏
関
閟
﹝
﹞
邏
輯
鍵
驗
訣
導
歷
屆
層
▼
儱
錄
熳
ē
艦
吋
錶
辧
飼
顯
④
禦
販
気
対
枰
閩
紀
幹
瞓
貊
淚
△
眞
墊
Ω
獻
褲
縫
緑
亜
鉅
餠
{
}
◆
蘆
薈
█
◇
溫
彈
晳
粧
犸
穩
訊
崬
凖
熥
П
舊
條
紋
圍
Ⅳ
筆
尷
難
雜
錯
綁
識
頰
鎖
艶
□
殁
殼
⑧
├
▕
鵬
ǐ
ō
ǒ
糝
綱
▎
μ
盜
饅
醬
籤
蓋
釀
鹽
據
à
ɡ
辦
◥
彐
┌
婦
獸
鲩
伱
ī
蒟
蒻
齊
袆
腦
寧
凈
妳
煥
詢
偽
謹
啫
鯽
騷
鱸
損
傷
鎻
髮
買
冏
儥
両
﹢
∞
載
喰
z
羙
悵
燙
曉
員
組
徹
艷
痠
鋼
鼙
縮
細
嚒
爯
≠
維
"
鱻
壇
厍
帰
浥
犇
薡
軎
²
應
醜
刪
緻
鶴
賜
噁
軌
尨
镔
鷺
槗
彌
葚
濛
請
溇
緹
賢
訪
獴
瑅
資
縤
陣
蕟
栢
韻
祼
恁
伢
謝
劃
涑
總
衖
踺
砋
凉
籃
駿
苼
瘋
昽
紡
驊
腎
﹗
響
杋
剛
嚴
禪
歓
槍
傘
檸
檫
炣
勢
鏜
鎢
銑
尐
減
奪
惡
θ
僮
婭
臘
ū
ì
殻
鉄
∑
蛲
焼
緖
續
紹
懮

================================================
FILE: app/src/main/assets/pdocrv2.0_det-op.param
================================================
7767517
115 131
Input                    input                    0 1 input0
Convolution              Conv_0                   1 1 input0 647 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish                Div_8                    1 1 647 330 0=1.666667e-01
Split                    splitncnn_0              1 2 330 330_splitncnn_0 330_splitncnn_1
Convolution              Conv_9                   1 1 330_splitncnn_1 333 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise     Conv_11                  1 1 333 336 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Convolution              Conv_13                  1 1 336 656 0=8 1=1 5=1 6=64
BinaryOp                 Add_14                   2 1 330_splitncnn_0 656 339
Convolution              Conv_15                  1 1 339 342 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise     Conv_17                  1 1 342 345 0=32 1=3 3=2 4=1 5=1 6=288 7=32 9=1
Convolution              Conv_19                  1 1 345 665 0=16 1=1 5=1 6=512
Split                    splitncnn_1              1 2 665 665_splitncnn_0 665_splitncnn_1
Convolution              Conv_20                  1 1 665_splitncnn_1 350 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise     Conv_22                  1 1 350 353 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution              Conv_24                  1 1 353 674 0=16 1=1 5=1 6=640
BinaryOp                 Add_25                   2 1 665_splitncnn_0 674 356
Split                    splitncnn_2              1 2 356 356_splitncnn_0 356_splitncnn_1
Convolution              Conv_26                  1 1 356_splitncnn_1 359 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise     Conv_28                  1 1 359 362 0=40 1=5 3=2 4=2 5=1 6=1000 7=40 9=1
Convolution              Conv_30                  1 1 362 683 0=24 1=1 5=1 6=960
Split                    splitncnn_3              1 2 683 683_splitncnn_0 683_splitncnn_1
Convolution              Conv_31                  1 1 683_splitncnn_1 367 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise     Conv_33                  1 1 367 370 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution              Conv_35                  1 1 370 692 0=24 1=1 5=1 6=1536
BinaryOp                 Add_36                   2 1 683_splitncnn_0 692 373
Split                    splitncnn_4              1 2 373 373_splitncnn_0 373_splitncnn_1
Convolution              Conv_37                  1 1 373_splitncnn_1 376 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise     Conv_39                  1 1 376 379 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution              Conv_41                  1 1 379 701 0=24 1=1 5=1 6=1536
BinaryOp                 Add_42                   2 1 373_splitncnn_0 701 382
Split                    splitncnn_5              1 2 382 382_splitncnn_0 382_splitncnn_1
Convolution              Conv_43                  1 1 382_splitncnn_1 704 0=120 1=1 5=1 6=2880
HardSwish                Div_51                   1 1 704 392 0=1.666667e-01
ConvolutionDepthWise     Conv_52                  1 1 392 707 0=120 1=3 3=2 4=1 5=1 6=1080 7=120
HardSwish                Div_60                   1 1 707 402 0=1.666667e-01
Convolution              Conv_61                  1 1 402 710 0=40 1=1 5=1 6=4800
Split                    splitncnn_6              1 2 710 710_splitncnn_0 710_splitncnn_1
Convolution              Conv_62                  1 1 710_splitncnn_1 713 0=104 1=1 5=1 6=4160
HardSwish                Div_70                   1 1 713 414 0=1.666667e-01
ConvolutionDepthWise     Conv_71                  1 1 414 716 0=104 1=3 4=1 5=1 6=936 7=104
HardSwish                Div_79                   1 1 716 424 0=1.666667e-01
Convolution              Conv_80                  1 1 424 719 0=40 1=1 5=1 6=4160
BinaryOp                 Add_81                   2 1 710_splitncnn_0 719 427
Split                    splitncnn_7              1 2 427 427_splitncnn_0 427_splitncnn_1
Convolution              Conv_82                  1 1 427_splitncnn_1 722 0=96 1=1 5=1 6=3840
HardSwish                Div_90                   1 1 722 437 0=1.666667e-01
ConvolutionDepthWise     Conv_91                  1 1 437 725 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish                Div_99                   1 1 725 447 0=1.666667e-01
Convolution              Conv_100                 1 1 447 728 0=40 1=1 5=1 6=3840
BinaryOp                 Add_101                  2 1 427_splitncnn_0 728 450
Split                    splitncnn_8              1 2 450 450_splitncnn_0 450_splitncnn_1
Convolution              Conv_102                 1 1 450_splitncnn_1 731 0=96 1=1 5=1 6=3840
HardSwish                Div_110                  1 1 731 460 0=1.666667e-01
ConvolutionDepthWise     Conv_111                 1 1 460 734 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish                Div_119                  1 1 734 470 0=1.666667e-01
Convolution              Conv_120                 1 1 470 737 0=40 1=1 5=1 6=3840
BinaryOp                 Add_121                  2 1 450_splitncnn_0 737 473
Convolution              Conv_122                 1 1 473 740 0=240 1=1 5=1 6=9600
HardSwish                Div_130                  1 1 740 483 0=1.666667e-01
ConvolutionDepthWise     Conv_131                 1 1 483 743 0=240 1=3 4=1 5=1 6=2160 7=240
HardSwish                Div_139                  1 1 743 493 0=1.666667e-01
Convolution              Conv_140                 1 1 493 746 0=56 1=1 5=1 6=13440
Split                    splitncnn_9              1 2 746 746_splitncnn_0 746_splitncnn_1
Convolution              Conv_141                 1 1 746_splitncnn_1 749 0=336 1=1 5=1 6=18816
HardSwish                Div_149                  1 1 749 505 0=1.666667e-01
ConvolutionDepthWise     Conv_150                 1 1 505 752 0=336 1=3 4=1 5=1 6=3024 7=336
HardSwish                Div_158                  1 1 752 515 0=1.666667e-01
Convolution              Conv_159                 1 1 515 755 0=56 1=1 5=1 6=18816
BinaryOp                 Add_160                  2 1 746_splitncnn_0 755 518
Split                    splitncnn_10             1 2 518 518_splitncnn_0 518_splitncnn_1
Convolution              Conv_161                 1 1 518_splitncnn_1 758 0=336 1=1 5=1 6=18816
HardSwish                Div_169                  1 1 758 528 0=1.666667e-01
ConvolutionDepthWise     Conv_170                 1 1 528 761 0=336 1=5 3=2 4=2 5=1 6=8400 7=336
HardSwish                Div_178                  1 1 761 538 0=1.666667e-01
Convolution              Conv_179                 1 1 538 764 0=80 1=1 5=1 6=26880
Split                    splitncnn_11             1 2 764 764_splitncnn_0 764_splitncnn_1
Convolution              Conv_180                 1 1 764_splitncnn_1 767 0=480 1=1 5=1 6=38400
HardSwish                Div_188                  1 1 767 550 0=1.666667e-01
ConvolutionDepthWise     Conv_189                 1 1 550 770 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish                Div_197                  1 1 770 560 0=1.666667e-01
Convolution              Conv_198                 1 1 560 773 0=80 1=1 5=1 6=38400
BinaryOp                 Add_199                  2 1 764_splitncnn_0 773 563
Split                    splitncnn_12             1 2 563 563_splitncnn_0 563_splitncnn_1
Convolution              Conv_200                 1 1 563_splitncnn_1 776 0=480 1=1 5=1 6=38400
HardSwish                Div_208                  1 1 776 573 0=1.666667e-01
ConvolutionDepthWise     Conv_209                 1 1 573 779 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish                Div_217                  1 1 779 583 0=1.666667e-01
Convolution              Conv_218                 1 1 583 782 0=80 1=1 5=1 6=38400
BinaryOp                 Add_219                  2 1 563_splitncnn_0 782 586
Convolution              Conv_220                 1 1 586 785 0=480 1=1 5=1 6=38400
HardSwish                Div_228                  1 1 785 596 0=1.666667e-01
Convolution              Conv_229                 1 1 596 597 0=96 1=1 6=46080
Split                    splitncnn_13             1 2 597 597_splitncnn_0 597_splitncnn_1
Convolution              Conv_230                 1 1 518_splitncnn_0 598 0=96 1=1 6=5376
Convolution              Conv_231                 1 1 382_splitncnn_0 599 0=96 1=1 6=2304
Convolution              Conv_232                 1 1 356_splitncnn_0 600 0=96 1=1 6=1536
Interp                   Resize_234               1 1 597_splitncnn_1 605 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_235                  2 1 598 605 606
Split                    splitncnn_14             1 2 606 606_splitncnn_0 606_splitncnn_1
Interp                   Resize_237               1 1 606_splitncnn_1 611 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_238                  2 1 599 611 612
Split                    splitncnn_15             1 2 612 612_splitncnn_0 612_splitncnn_1
Interp                   Resize_240               1 1 612_splitncnn_1 617 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp                 Add_241                  2 1 600 617 618
Convolution              Conv_242                 1 1 597_splitncnn_0 619 0=24 1=3 4=1 6=20736
Convolution              Conv_243                 1 1 606_splitncnn_0 620 0=24 1=3 4=1 6=20736
Convolution              Conv_244                 1 1 612_splitncnn_0 621 0=24 1=3 4=1 6=20736
Convolution              Conv_245                 1 1 618 622 0=24 1=3 4=1 6=20736
Interp                   Resize_247               1 1 619 627 0=1 1=8.000000e+00 2=8.000000e+00
Interp                   Resize_249               1 1 620 632 0=1 1=4.000000e+00 2=4.000000e+00
Interp                   Resize_251               1 1 621 637 0=1 1=2.000000e+00 2=2.000000e+00
Concat                   Concat_252               4 1 627 632 637 622 638
Convolution              Conv_253                 1 1 638 641 0=24 1=3 4=1 5=1 6=20736 9=1
Deconvolution            ConvTranspose_255        1 1 641 644 0=24 1=2 3=2 5=1 6=2304 9=1
Deconvolution            ConvTranspose_258        1 1 644 out1 0=1 1=2 3=2 5=1 6=96 9=4


================================================
FILE: app/src/main/assets/pdocrv2.0_rec-op.param
================================================
7767517
75 77
Input                    input                    0 1 input
Convolution              Conv_0                   1 1 input 779 0=16 1=3 3=2 4=1 5=1 6=432
HardSwish                Div_8                    1 1 779 200 0=1.666667e-01
ConvolutionDepthWise     Conv_9                   1 1 200 782 0=16 1=3 4=1 5=1 6=144 7=16
HardSwish                Div_17                   1 1 782 210 0=1.666667e-01
Convolution              Conv_18                  1 1 210 785 0=32 1=1 5=1 6=512
HardSwish                Div_26                   1 1 785 220 0=1.666667e-01
ConvolutionDepthWise     Conv_27                  1 1 220 788 0=32 1=3 4=1 5=1 6=288 7=32
HardSwish                Div_35                   1 1 788 230 0=1.666667e-01
Convolution              Conv_36                  1 1 230 791 0=64 1=1 5=1 6=2048
HardSwish                Div_44                   1 1 791 240 0=1.666667e-01
ConvolutionDepthWise     Conv_45                  1 1 240 794 0=64 1=3 4=1 5=1 6=576 7=64
HardSwish                Div_53                   1 1 794 250 0=1.666667e-01
Convolution              Conv_54                  1 1 250 797 0=64 1=1 5=1 6=4096
HardSwish                Div_62                   1 1 797 260 0=1.666667e-01
ConvolutionDepthWise     Conv_63                  1 1 260 800 0=64 1=3 13=2 4=1 5=1 6=576 7=64
HardSwish                Div_71                   1 1 800 270 0=1.666667e-01
Convolution              Conv_72                  1 1 270 803 0=128 1=1 5=1 6=8192
HardSwish                Div_80                   1 1 803 280 0=1.666667e-01
ConvolutionDepthWise     Conv_81                  1 1 280 806 0=128 1=3 4=1 5=1 6=1152 7=128
HardSwish                Div_89                   1 1 806 290 0=1.666667e-01
Convolution              Conv_90                  1 1 290 809 0=128 1=1 5=1 6=16384
HardSwish                Div_98                   1 1 809 300 0=1.666667e-01
ConvolutionDepthWise     Conv_99                  1 1 300 812 0=128 1=3 13=2 4=1 5=1 6=1152 7=128
HardSwish                Div_107                  1 1 812 310 0=1.666667e-01
Convolution              Conv_108                 1 1 310 815 0=256 1=1 5=1 6=32768
HardSwish                Div_116                  1 1 815 320 0=1.666667e-01
ConvolutionDepthWise     Conv_117                 1 1 320 818 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish                Div_125                  1 1 818 330 0=1.666667e-01
Convolution              Conv_126                 1 1 330 821 0=256 1=1 5=1 6=65536
HardSwish                Div_134                  1 1 821 340 0=1.666667e-01
ConvolutionDepthWise     Conv_135                 1 1 340 824 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish                Div_143                  1 1 824 350 0=1.666667e-01
Convolution              Conv_144                 1 1 350 827 0=256 1=1 5=1 6=65536
HardSwish                Div_152                  1 1 827 360 0=1.666667e-01
ConvolutionDepthWise     Conv_153                 1 1 360 830 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish                Div_161                  1 1 830 370 0=1.666667e-01
Convolution              Conv_162                 1 1 370 833 0=256 1=1 5=1 6=65536
HardSwish                Div_170                  1 1 833 380 0=1.666667e-01
ConvolutionDepthWise     Conv_171                 1 1 380 836 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish                Div_179                  1 1 836 390 0=1.666667e-01
Convolution              Conv_180                 1 1 390 839 0=256 1=1 5=1 6=65536
HardSwish                Div_188                  1 1 839 400 0=1.666667e-01
ConvolutionDepthWise     Conv_189                 1 1 400 842 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish                Div_197                  1 1 842 410 0=1.666667e-01
Convolution              Conv_198                 1 1 410 845 0=256 1=1 5=1 6=65536
HardSwish                Div_206                  1 1 845 420 0=1.666667e-01
ConvolutionDepthWise     Conv_207                 1 1 420 848 0=256 1=5 13=2 4=2 5=1 6=6400 7=256
HardSwish                Div_215                  1 1 848 430 0=1.666667e-01
Split                    splitncnn_0              1 2 430 430_splitncnn_0 430_splitncnn_1
Pooling                  GlobalAveragePool_216    1 1 430_splitncnn_1 431 0=1 4=1
InnerProduct             Conv_217                 1 1 431 433 0=64 1=1 2=16384 9=1
InnerProduct             Conv_219                 1 1 433 434 0=256 1=1 2=16384
HardSigmoid              Div_226                  1 1 434 441 0=1.666667e-01
BinaryOp                 Mul_227                  2 1 430_splitncnn_0 441 442 0=2
Convolution              Conv_228                 1 1 442 851 0=512 1=1 5=1 6=131072
HardSwish                Div_236                  1 1 851 452 0=1.666667e-01
ConvolutionDepthWise     Conv_237                 1 1 452 854 0=512 1=5 4=2 5=1 6=12800 7=512
HardSwish                Div_245                  1 1 854 462 0=1.666667e-01
Split                    splitncnn_1              1 2 462 462_splitncnn_0 462_splitncnn_1
Pooling                  GlobalAveragePool_246    1 1 462_splitncnn_1 463 0=1 4=1
InnerProduct             Conv_247                 1 1 463 465 0=128 1=1 2=65536 9=1
InnerProduct             Conv_249                 1 1 465 466 0=512 1=1 2=65536
HardSigmoid              Div_256                  1 1 466 473 0=1.666667e-01
BinaryOp                 Mul_257                  2 1 462_splitncnn_0 473 474 0=2
Convolution              Conv_258                 1 1 474 857 0=512 1=1 5=1 6=262144
HardSwish                Div_266                  1 1 857 484 0=1.666667e-01
Pooling                  MaxPool_267              1 1 484 485 1=2 2=2 5=1
Reshape                  Reshape_281              1 1 485 499 0=-1 1=512
Permute                  Transpose_289            1 1 499 511 0=1
LSTM                     LSTM_298                 1 1 511 641 0=64 1=262144 2=2
LSTM                     LSTM_310                 1 1 641 771 0=64 1=65536 2=2
InnerProduct             MatMul_315               1 1 771 774 0=96 1=1 2=12288
InnerProduct             MatMul_317               1 1 774 777 0=6625 1=1 2=636000
Softmax                  Softmax_319              1 1 777 out 0=1 1=1


================================================
FILE: app/src/main/assets/rec-sim-op.param
================================================
7767517
138 154
Input                    input                    0 1 input
Convolution              Conv_0                   1 1 input 266 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish                Div_9                    1 1 266 274 0=1.666667e-01
Convolution              Conv_10                  1 1 274 277 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise     Conv_13                  1 1 277 280 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Split                    splitncnn_0              1 2 280 280_splitncnn_0 280_splitncnn_1
Pooling                  GlobalAveragePool_16     1 1 280_splitncnn_1 281 0=1 4=1
InnerProduct             Conv_17                  1 1 281 283 0=2 1=1 2=16 9=1
InnerProduct             Conv_19                  1 1 283 284 0=8 1=1 2=16
BinaryOp                 Mul_21                   1 1 284 286 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_28                   1 1 286 293 0=1.666667e-01
BinaryOp                 Mul_29                   2 1 280_splitncnn_0 293 294 0=2
Convolution              Conv_30                  1 1 294 296 0=8 1=1 5=1 6=64
Convolution              Conv_32                  1 1 296 299 0=40 1=1 5=1 6=320 9=1
ConvolutionDepthWise     Conv_35                  1 1 299 302 0=40 1=3 13=2 4=1 5=1 6=360 7=40 9=1
Convolution              Conv_38                  1 1 302 304 0=16 1=1 5=1 6=640
Split                    splitncnn_1              1 2 304 304_splitncnn_0 304_splitncnn_1
Convolution              Conv_40                  1 1 304_splitncnn_1 307 0=48 1=1 5=1 6=768 9=1
ConvolutionDepthWise     Conv_43                  1 1 307 310 0=48 1=3 4=1 5=1 6=432 7=48 9=1
Convolution              Conv_46                  1 1 310 312 0=16 1=1 5=1 6=768
BinaryOp                 Add_48                   2 1 304_splitncnn_0 312 313
Convolution              Conv_49                  1 1 313 315 0=48 1=1 5=1 6=768
HardSwish                Div_58                   1 1 315 323 0=1.666667e-01
ConvolutionDepthWise     Conv_59                  1 1 323 325 0=48 1=5 13=2 4=2 5=1 6=1200 7=48
HardSwish                Div_68                   1 1 325 333 0=1.666667e-01
Split                    splitncnn_2              1 2 333 333_splitncnn_0 333_splitncnn_1
Pooling                  GlobalAveragePool_69     1 1 333_splitncnn_1 334 0=1 4=1
InnerProduct             Conv_70                  1 1 334 336 0=12 1=1 2=576 9=1
InnerProduct             Conv_72                  1 1 336 337 0=48 1=1 2=576
BinaryOp                 Mul_74                   1 1 337 339 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_81                   1 1 339 346 0=1.666667e-01
BinaryOp                 Mul_82                   2 1 333_splitncnn_0 346 347 0=2
Convolution              Conv_83                  1 1 347 349 0=24 1=1 5=1 6=1152
Split                    splitncnn_3              1 2 349 349_splitncnn_0 349_splitncnn_1
Convolution              Conv_85                  1 1 349_splitncnn_1 351 0=120 1=1 5=1 6=2880
HardSwish                Div_94                   1 1 351 359 0=1.666667e-01
ConvolutionDepthWise     Conv_95                  1 1 359 361 0=120 1=5 4=2 5=1 6=3000 7=120
HardSwish                Div_104                  1 1 361 369 0=1.666667e-01
Split                    splitncnn_4              1 2 369 369_splitncnn_0 369_splitncnn_1
Pooling                  GlobalAveragePool_105    1 1 369_splitncnn_1 370 0=1 4=1
InnerProduct             Conv_106                 1 1 370 372 0=30 1=1 2=3600 9=1
InnerProduct             Conv_108                 1 1 372 373 0=120 1=1 2=3600
BinaryOp                 Mul_110                  1 1 373 375 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_117                  1 1 375 382 0=1.666667e-01
BinaryOp                 Mul_118                  2 1 369_splitncnn_0 382 383 0=2
Convolution              Conv_119                 1 1 383 385 0=24 1=1 5=1 6=2880
BinaryOp                 Add_121                  2 1 349_splitncnn_0 385 386
Split                    splitncnn_5              1 2 386 386_splitncnn_0 386_splitncnn_1
Convolution              Conv_122                 1 1 386_splitncnn_1 388 0=120 1=1 5=1 6=2880
HardSwish                Div_131                  1 1 388 396 0=1.666667e-01
ConvolutionDepthWise     Conv_132                 1 1 396 398 0=120 1=5 4=2 5=1 6=3000 7=120
HardSwish                Div_141                  1 1 398 406 0=1.666667e-01
Split                    splitncnn_6              1 2 406 406_splitncnn_0 406_splitncnn_1
Pooling                  GlobalAveragePool_142    1 1 406_splitncnn_1 407 0=1 4=1
InnerProduct             Conv_143                 1 1 407 409 0=30 1=1 2=3600 9=1
InnerProduct             Conv_145                 1 1 409 410 0=120 1=1 2=3600
BinaryOp                 Mul_147                  1 1 410 412 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_154                  1 1 412 419 0=1.666667e-01
BinaryOp                 Mul_155                  2 1 406_splitncnn_0 419 420 0=2
Convolution              Conv_156                 1 1 420 422 0=24 1=1 5=1 6=2880
BinaryOp                 Add_158                  2 1 386_splitncnn_0 422 423
Split                    splitncnn_7              1 2 423 423_splitncnn_0 423_splitncnn_1
Convolution              Conv_159                 1 1 423_splitncnn_1 425 0=64 1=1 5=1 6=1536
HardSwish                Div_168                  1 1 425 433 0=1.666667e-01
ConvolutionDepthWise     Conv_169                 1 1 433 435 0=64 1=5 4=2 5=1 6=1600 7=64
HardSwish                Div_178                  1 1 435 443 0=1.666667e-01
Split                    splitncnn_8              1 2 443 443_splitncnn_0 443_splitncnn_1
Pooling                  GlobalAveragePool_179    1 1 443_splitncnn_1 444 0=1 4=1
InnerProduct             Conv_180                 1 1 444 446 0=16 1=1 2=1024 9=1
InnerProduct             Conv_182                 1 1 446 447 0=64 1=1 2=1024
BinaryOp                 Mul_184                  1 1 447 449 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_191                  1 1 449 456 0=1.666667e-01
BinaryOp                 Mul_192                  2 1 443_splitncnn_0 456 457 0=2
Convolution              Conv_193                 1 1 457 459 0=24 1=1 5=1 6=1536
BinaryOp                 Add_195                  2 1 423_splitncnn_0 459 460
Split                    splitncnn_9              1 2 460 460_splitncnn_0 460_splitncnn_1
Convolution              Conv_196                 1 1 460_splitncnn_1 462 0=72 1=1 5=1 6=1728
HardSwish                Div_205                  1 1 462 470 0=1.666667e-01
ConvolutionDepthWise     Conv_206                 1 1 470 472 0=72 1=5 4=2 5=1 6=1800 7=72
HardSwish                Div_215                  1 1 472 480 0=1.666667e-01
Split                    splitncnn_10             1 2 480 480_splitncnn_0 480_splitncnn_1
Pooling                  GlobalAveragePool_216    1 1 480_splitncnn_1 481 0=1 4=1
InnerProduct             Conv_217                 1 1 481 483 0=18 1=1 2=1296 9=1
InnerProduct             Conv_219                 1 1 483 484 0=72 1=1 2=1296
BinaryOp                 Mul_221                  1 1 484 486 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_228                  1 1 486 493 0=1.666667e-01
BinaryOp                 Mul_229                  2 1 480_splitncnn_0 493 494 0=2
Convolution              Conv_230                 1 1 494 496 0=24 1=1 5=1 6=1728
BinaryOp                 Add_232                  2 1 460_splitncnn_0 496 497
Convolution              Conv_233                 1 1 497 499 0=144 1=1 5=1 6=3456
HardSwish                Div_242                  1 1 499 507 0=1.666667e-01
ConvolutionDepthWise     Conv_243                 1 1 507 509 0=144 1=5 13=2 4=2 5=1 6=3600 7=144
HardSwish                Div_252                  1 1 509 517 0=1.666667e-01
Split                    splitncnn_11             1 2 517 517_splitncnn_0 517_splitncnn_1
Pooling                  GlobalAveragePool_253    1 1 517_splitncnn_1 518 0=1 4=1
InnerProduct             Conv_254                 1 1 518 520 0=36 1=1 2=5184 9=1
InnerProduct             Conv_256                 1 1 520 521 0=144 1=1 2=5184
BinaryOp                 Mul_258                  1 1 521 523 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_265                  1 1 523 530 0=1.666667e-01
BinaryOp                 Mul_266                  2 1 517_splitncnn_0 530 531 0=2
Convolution              Conv_267                 1 1 531 533 0=48 1=1 5=1 6=6912
Split                    splitncnn_12             1 2 533 533_splitncnn_0 533_splitncnn_1
Convolution              Conv_269                 1 1 533_splitncnn_1 535 0=288 1=1 5=1 6=13824
HardSwish                Div_278                  1 1 535 543 0=1.666667e-01
ConvolutionDepthWise     Conv_279                 1 1 543 545 0=288 1=5 4=2 5=1 6=7200 7=288
HardSwish                Div_288                  1 1 545 553 0=1.666667e-01
Split                    splitncnn_13             1 2 553 553_splitncnn_0 553_splitncnn_1
Pooling                  GlobalAveragePool_289    1 1 553_splitncnn_1 554 0=1 4=1
InnerProduct             Conv_290                 1 1 554 556 0=72 1=1 2=20736 9=1
InnerProduct             Conv_292                 1 1 556 557 0=288 1=1 2=20736
BinaryOp                 Mul_294                  1 1 557 559 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_301                  1 1 559 566 0=1.666667e-01
BinaryOp                 Mul_302                  2 1 553_splitncnn_0 566 567 0=2
Convolution              Conv_303                 1 1 567 569 0=48 1=1 5=1 6=13824
BinaryOp                 Add_305                  2 1 533_splitncnn_0 569 570
Split                    splitncnn_14             1 2 570 570_splitncnn_0 570_splitncnn_1
Convolution              Conv_306                 1 1 570_splitncnn_1 572 0=288 1=1 5=1 6=13824
HardSwish                Div_315                  1 1 572 580 0=1.666667e-01
ConvolutionDepthWise     Conv_316                 1 1 580 582 0=288 1=5 4=2 5=1 6=7200 7=288
HardSwish                Div_325                  1 1 582 590 0=1.666667e-01
Split                    splitncnn_15             1 2 590 590_splitncnn_0 590_splitncnn_1
Pooling                  GlobalAveragePool_326    1 1 590_splitncnn_1 591 0=1 4=1
InnerProduct             Conv_327                 1 1 591 593 0=72 1=1 2=20736 9=1
InnerProduct             Conv_329                 1 1 593 594 0=288 1=1 2=20736
BinaryOp                 Mul_331                  1 1 594 596 0=2 1=1 2=1.200000e+00
HardSigmoid              Div_338                  1 1 596 603 0=1.666667e-01
BinaryOp                 Mul_339                  2 1 590_splitncnn_0 603 604 0=2
Convolution              Conv_340                 1 1 604 606 0=48 1=1 5=1 6=13824
BinaryOp                 Add_342                  2 1 570_splitncnn_0 606 607
Convolution              Conv_343                 1 1 607 609 0=288 1=1 5=1 6=13824
HardSwish                Div_352                  1 1 609 617 0=1.666667e-01
Pooling                  MaxPool_353              1 1 617 618 1=2 2=2 5=1
Reshape                  Squeeze_354              1 1 618 619 0=-1 1=288
Permute                  Transpose_362            1 1 619 631 0=1
LSTM                     LSTM_371                 1 1 631 761 0=48 1=110592 2=2
LSTM                     LSTM_383                 1 1 761 891 0=48 1=36864 2=2
InnerProduct             MatMul_388               1 1 891 894 0=6625 1=1 2=636000
Softmax                  Softmax_390              1 1 894 out 0=1 1=1


================================================
FILE: app/src/main/java/com/tencent/paddleocrncnn/MainActivity.java
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

package com.tencent.paddleocrncnn;

import android.os.Build;
import android.Manifest;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.provider.MediaStore;
import android.content.pm.PackageManager;
public class MainActivity extends Activity
{
    private static final int TAKE_PHOTO = 1;
    private static final int SELECT_IMAGE = 2;

    private ImageView imageView;
    //private Bitmap bitmap = null;
    private Bitmap yourSelectedImage = null;
    private final String filePath = Environment.getExternalStorageDirectory() + File.separator + "output_image.jpg";
    private Uri imageUri;
    private PaddleOCRNcnn paddleocrncnn = new PaddleOCRNcnn();
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults != null && grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            switch (requestCode) {
                case 1: {
                    requestCamera();
                }
                break;
            }
        }
    }
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        boolean ret_init = paddleocrncnn.Init(getAssets());
        if (!ret_init)
        {
            Log.e("MainActivity", "paddleocrncnn Init failed");
        }

        imageView = (ImageView) findViewById(R.id.imageView);

        Button buttonImage = (Button) findViewById(R.id.buttonImage);
        buttonImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent i = new Intent(Intent.ACTION_PICK);
                i.setType("image/*");
                startActivityForResult(i, SELECT_IMAGE);
            }
        });
        Button buttonCamera = (Button) findViewById(R.id.buttonCamera);
        buttonCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                requestPermission();
            }
        });
        Button buttonDetect = (Button) findViewById(R.id.buttonDetect);
        buttonDetect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (yourSelectedImage == null)
                    return;
                Bitmap bitmap = yourSelectedImage.copy(Bitmap.Config.ARGB_8888, true);
                PaddleOCRNcnn.Obj[] objects = paddleocrncnn.Detect(bitmap, false);

                showObjects(objects);
            }
        });

        Button buttonDetectGPU = (Button) findViewById(R.id.buttonDetectGPU);
        buttonDetectGPU.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (yourSelectedImage == null)
                    return;
                Bitmap bitmap = yourSelectedImage.copy(Bitmap.Config.ARGB_8888, true);
                PaddleOCRNcnn.Obj[] objects = paddleocrncnn.Detect(bitmap, true);

                showObjects(objects);
            }
        });
    }
    private void requestPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
        } else {
            requestCamera();
        }
    }
    private void requestCamera() {
        File outputImage = new File(filePath);
        try
        {
            if (!outputImage.getParentFile().exists()) {
                outputImage.getParentFile().mkdirs();
            }
            if (outputImage.exists()) {
                outputImage.delete();
            }

            outputImage.createNewFile();

            if (Build.VERSION.SDK_INT >= 24) {
                imageUri = FileProvider.getUriForFile(this,
                        "com.tencent.paddleocrncnn.fileprovider", outputImage);
            } else {
                imageUri = Uri.fromFile(outputImage);
            }
            Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(intent, TAKE_PHOTO);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    private void showObjects(PaddleOCRNcnn.Obj[] objects)
    {
        if (objects == null)
        {
            imageView.setImageBitmap(yourSelectedImage);
            return;
        }

        // draw objects on bitmap
        Bitmap rgba = yourSelectedImage.copy(Bitmap.Config.ARGB_8888, true);

        final int[] colors = new int[] {
            Color.rgb( 54,  67, 244),
            Color.rgb( 99,  30, 233),
            Color.rgb(176,  39, 156),
            Color.rgb(183,  58, 103),
            Color.rgb(181,  81,  63),
            Color.rgb(243, 150,  33),
            Color.rgb(244, 169,   3),
            Color.rgb(212, 188,   0),
            Color.rgb(136, 150,   0),
            Color.rgb( 80, 175,  76),
            Color.rgb( 74, 195, 139),
            Color.rgb( 57, 220, 205),
            Color.rgb( 59, 235, 255),
            Color.rgb(  7, 193, 255),
            Color.rgb(  0, 152, 255),
            Color.rgb( 34,  87, 255),
            Color.rgb( 72,  85, 121),
            Color.rgb(158, 158, 158),
            Color.rgb(139, 125,  96)
        };

        Canvas canvas = new Canvas(rgba);

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(4);
        Paint textbgpaint = new Paint();
        textbgpaint.setColor(Color.WHITE);
        textbgpaint.setStyle(Paint.Style.FILL);

        Paint textpaint = new Paint();
        textpaint.setColor(Color.BLACK);
        textpaint.setTextSize(56);
        textpaint.setTextAlign(Paint.Align.LEFT);

        for (int i = 0; i < objects.length; i++)
        {
            paint.setColor(colors[i % 19]);

            //canvas.drawRect(objects[i].x, objects[i].y, objects[i].x + objects[i].w, objects[i].y + objects[i].h, paint);
            canvas.drawLine(objects[i].x0,objects[i].y0,objects[i].x1,objects[i].y1,paint);
            canvas.drawLine(objects[i].x1,objects[i].y1,objects[i].x2,objects[i].y2,paint);
            canvas.drawLine(objects[i].x2,objects[i].y2,objects[i].x3,objects[i].y3,paint);
            canvas.drawLine(objects[i].x3,objects[i].y3,objects[i].x0,objects[i].y0,paint);
            // draw filled text inside image
            {
                String text = objects[i].label;// + " = " + String.format("%.1f", objects[i].prob * 100) + "%";

                float text_width = textpaint.measureText(text);
                float text_height = - textpaint.ascent() + textpaint.descent();

                float x = objects[i].x0;
                float y = objects[i].y0 - text_height;
                if (y < 0)
                    y = 0;
                if (x + text_width > rgba.getWidth())
                    x = rgba.getWidth() - text_width;

                canvas.drawRect(x, y, x + text_width, y + text_height, textbgpaint);

                canvas.drawText(text, x, y - textpaint.ascent(), textpaint);
            }
        }

        imageView.setImageBitmap(rgba);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case TAKE_PHOTO:
                if (resultCode == RESULT_OK) {
                    try {
                        yourSelectedImage = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        imageView.setImageBitmap(yourSelectedImage);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        Log.e("MainActivity", "FileNotFoundException");
                    }
                }
                break;
            case SELECT_IMAGE:
                if (resultCode == RESULT_OK && null != data) {
                    Uri selectedImage = data.getData();
                    try {
                        if (requestCode == SELECT_IMAGE) {
                            yourSelectedImage = decodeUri(selectedImage);

                            imageView.setImageBitmap(yourSelectedImage);
                        }
                    }
                    catch (FileNotFoundException e) {
                        Log.e("MainActivity", "FileNotFoundException");
                        return;
                    }
                }
            default:
                break;
        }
    }

    private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException
    {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 640;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
               || height_tmp / 2 < REQUIRED_SIZE) {
                break;
            }
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);

        // Rotate according to EXIF
        int rotate = 0;
        try
        {
            ExifInterface exif = new ExifInterface(getContentResolver().openInputStream(selectedImage));
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotate = 270;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotate = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotate = 90;
                    break;
            }
        }
        catch (IOException e)
        {
            Log.e("MainActivity", "ExifInterface IOException");
        }

        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

}


================================================
FILE: app/src/main/java/com/tencent/paddleocrncnn/PaddleOCRNcnn.java
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

package com.tencent.paddleocrncnn;

import android.content.res.AssetManager;
import android.graphics.Bitmap;

public class PaddleOCRNcnn
{
    public native boolean Init(AssetManager mgr);

    public class Obj
    {
        public float x0;
        public float y0;
        public float x1;
        public float y1;
        public float x2;
        public float y2;
        public float x3;
        public float y3;
        public String label;
        public float prob;
    }

    public native Obj[] Detect(Bitmap bitmap, boolean use_gpu);

    static {
        System.loadLibrary("paddleocrncnn");
    }
}


================================================
FILE: app/src/main/jni/CMakeLists.txt
================================================
project(paddleocrncnn)

cmake_minimum_required(VERSION 3.4.1)

set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-android/sdk/native/jni)
find_package(OpenCV REQUIRED core imgproc)

set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)

add_library(paddleocrncnn SHARED paddleocr_ncnn.cpp common.cpp clipper.cpp)

target_link_libraries(paddleocrncnn ncnn ${OpenCV_LIBS} jnigraphics)


================================================
FILE: app/src/main/jni/clipper.cpp
================================================
/*******************************************************************************
*                                                                              *
* Author    :  Angus Johnson                                                   *
* Version   :  6.4.2                                                           *
* Date      :  27 February 2017                                                *
* Website   :  http://www.angusj.com                                           *
* Copyright :  Angus Johnson 2010-2017                                         *
*                                                                              *
* License:                                                                     *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt                                         *
*                                                                              *
* Attributions:                                                                *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping"                                     *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63.             *
* http://portal.acm.org/citation.cfm?id=129906                                 *
*                                                                              *
* Computer graphics and geometric modeling: implementation and algorithms      *
* By Max K. Agoston                                                            *
* Springer; 1 edition (January 4, 2005)                                        *
* http://books.google.com/books?q=vatti+clipping+agoston                       *
*                                                                              *
* See also:                                                                    *
* "Polygon Offsetting by Computing Winding Numbers"                            *
* Paper no. DETC2005-85513 pp. 565-575                                         *
* ASME 2005 International Design Engineering Technical Conferences             *
* and Computers and Information in Engineering Conference (IDETC/CIE2005)      *
* September 24-28, 2005 , Long Beach, California, USA                          *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf              *
*                                                                              *
*******************************************************************************/

/*******************************************************************************
*                                                                              *
* This is a translation of the Delphi Clipper library and the naming style     *
* used has retained a Delphi flavour.                                          *
*                                                                              *
*******************************************************************************/

#include "clipper.hpp"
#include <cmath>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <functional>

namespace ClipperLib {

    static double const pi = 3.141592653589793238;
    static double const two_pi = pi *2;
    static double const def_arc_tolerance = 0.25;

    enum Direction { dRightToLeft, dLeftToRight };

    static int const Unassigned = -1;  //edge not currently 'owning' a solution
    static int const Skip = -2;        //edge that would otherwise close a path

#define HORIZONTAL (-1.0E+40)
#define TOLERANCE (1.0e-20)
#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))

    struct TEdge {
        IntPoint Bot;
        IntPoint Curr; //current (updated for every new scanbeam)
        IntPoint Top;
        double Dx;
        PolyType PolyTyp;
        EdgeSide Side; //side only refers to current side of solution poly
        int WindDelta; //1 or -1 depending on winding direction
        int WindCnt;
        int WindCnt2; //winding count of the opposite polytype
        int OutIdx;
        TEdge *Next;
        TEdge *Prev;
        TEdge *NextInLML;
        TEdge *NextInAEL;
        TEdge *PrevInAEL;
        TEdge *NextInSEL;
        TEdge *PrevInSEL;
    };

    struct IntersectNode {
        TEdge          *Edge1;
        TEdge          *Edge2;
        IntPoint        Pt;
    };

    struct LocalMinimum {
        cInt          Y;
        TEdge        *LeftBound;
        TEdge        *RightBound;
    };

    struct OutPt;

//OutRec: contains a path in the clipping solution. Edges in the AEL will
//carry a pointer to an OutRec when they are part of the clipping solution.
    struct OutRec {
        int       Idx;
        bool      IsHole;
        bool      IsOpen;
        OutRec   *FirstLeft;  //see comments in clipper.pas
        PolyNode *PolyNd;
        OutPt    *Pts;
        OutPt    *BottomPt;
    };

    struct OutPt {
        int       Idx;
        IntPoint  Pt;
        OutPt    *Next;
        OutPt    *Prev;
    };

    struct Join {
        OutPt    *OutPt1;
        OutPt    *OutPt2;
        IntPoint  OffPt;
    };

    struct LocMinSorter
    {
        inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2)
        {
            return locMin2.Y < locMin1.Y;
        }
    };

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

    inline cInt Round(double val)
    {
        if ((val < 0)) return static_cast<cInt>(val - 0.5);
        else return static_cast<cInt>(val + 0.5);
    }
//------------------------------------------------------------------------------

    inline cInt Abs(cInt val)
    {
        return val < 0 ? -val : val;
    }

//------------------------------------------------------------------------------
// PolyTree methods ...
//------------------------------------------------------------------------------

    void PolyTree::Clear()
    {
        for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
            delete AllNodes[i];
        AllNodes.resize(0);
        Childs.resize(0);
    }
//------------------------------------------------------------------------------

    PolyNode* PolyTree::GetFirst() const
    {
        if (!Childs.empty())
            return Childs[0];
        else
            return 0;
    }
//------------------------------------------------------------------------------

    int PolyTree::Total() const
    {
        int result = (int)AllNodes.size();
        //with negative offsets, ignore the hidden outer polygon ...
        if (result > 0 && Childs[0] != AllNodes[0]) result--;
        return result;
    }

//------------------------------------------------------------------------------
// PolyNode methods ...
//------------------------------------------------------------------------------

    PolyNode::PolyNode(): Parent(0), Index(0), m_IsOpen(false)
    {
    }
//------------------------------------------------------------------------------

    int PolyNode::ChildCount() const
    {
        return (int)Childs.size();
    }
//------------------------------------------------------------------------------

    void PolyNode::AddChild(PolyNode& child)
    {
        unsigned cnt = (unsigned)Childs.size();
        Childs.push_back(&child);
        child.Parent = this;
        child.Index = cnt;
    }
//------------------------------------------------------------------------------

    PolyNode* PolyNode::GetNext() const
    {
        if (!Childs.empty())
            return Childs[0];
        else
            return GetNextSiblingUp();
    }
//------------------------------------------------------------------------------

    PolyNode* PolyNode::GetNextSiblingUp() const
    {
        if (!Parent) //protects against PolyTree.GetNextSiblingUp()
            return 0;
        else if (Index == Parent->Childs.size() - 1)
            return Parent->GetNextSiblingUp();
        else
            return Parent->Childs[Index + 1];
    }
//------------------------------------------------------------------------------

    bool PolyNode::IsHole() const
    {
        bool result = true;
        PolyNode* node = Parent;
        while (node)
        {
            result = !result;
            node = node->Parent;
        }
        return result;
    }
//------------------------------------------------------------------------------

    bool PolyNode::IsOpen() const
    {
        return m_IsOpen;
    }
//------------------------------------------------------------------------------

#ifndef use_int32

//------------------------------------------------------------------------------
// Int128 class (enables safe math on signed 64bit integers)
// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1
//    Int128 val2((long64)9223372036854775807);
//    Int128 val3 = val1 * val2;
//    val3.AsString => "85070591730234615847396907784232501249" (8.5e+37)
//------------------------------------------------------------------------------

    class Int128
    {
    public:
        ulong64 lo;
        long64 hi;

        Int128(long64 _lo = 0)
        {
            lo = (ulong64)_lo;
            if (_lo < 0)  hi = -1; else hi = 0;
        }


        Int128(const Int128 &val): lo(val.lo), hi(val.hi){}

        Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}

        Int128& operator = (const long64 &val)
        {
            lo = (ulong64)val;
            if (val < 0) hi = -1; else hi = 0;
            return *this;
        }

        bool operator == (const Int128 &val) const
        {return (hi == val.hi && lo == val.lo);}

        bool operator != (const Int128 &val) const
        { return !(*this == val);}

        bool operator > (const Int128 &val) const
        {
            if (hi != val.hi)
                return hi > val.hi;
            else
                return lo > val.lo;
        }

        bool operator < (const Int128 &val) const
        {
            if (hi != val.hi)
                return hi < val.hi;
            else
                return lo < val.lo;
        }

        bool operator >= (const Int128 &val) const
        { return !(*this < val);}

        bool operator <= (const Int128 &val) const
        { return !(*this > val);}

        Int128& operator += (const Int128 &rhs)
        {
            hi += rhs.hi;
            lo += rhs.lo;
            if (lo < rhs.lo) hi++;
            return *this;
        }

        Int128 operator + (const Int128 &rhs) const
        {
            Int128 result(*this);
            result+= rhs;
            return result;
        }

        Int128& operator -= (const Int128 &rhs)
        {
            *this += -rhs;
            return *this;
        }

        Int128 operator - (const Int128 &rhs) const
        {
            Int128 result(*this);
            result -= rhs;
            return result;
        }

        Int128 operator-() const //unary negation
        {
            if (lo == 0)
                return Int128(-hi, 0);
            else
                return Int128(~hi, ~lo + 1);
        }

        operator double() const
        {
            const double shift64 = 18446744073709551616.0; //2^64
            if (hi < 0)
            {
                if (lo == 0) return (double)hi * shift64;
                else return -(double)(~lo + ~hi * shift64);
            }
            else
                return (double)(lo + hi * shift64);
        }

    };
//------------------------------------------------------------------------------

    Int128 Int128Mul (long64 lhs, long64 rhs)
    {
        bool negate = (lhs < 0) != (rhs < 0);

        if (lhs < 0) lhs = -lhs;
        ulong64 int1Hi = ulong64(lhs) >> 32;
        ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF);

        if (rhs < 0) rhs = -rhs;
        ulong64 int2Hi = ulong64(rhs) >> 32;
        ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF);

        //nb: see comments in clipper.pas
        ulong64 a = int1Hi * int2Hi;
        ulong64 b = int1Lo * int2Lo;
        ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi;

        Int128 tmp;
        tmp.hi = long64(a + (c >> 32));
        tmp.lo = long64(c << 32);
        tmp.lo += long64(b);
        if (tmp.lo < b) tmp.hi++;
        if (negate) tmp = -tmp;
        return tmp;
    };
#endif

//------------------------------------------------------------------------------
// Miscellaneous global functions
//------------------------------------------------------------------------------

    bool Orientation(const Path &poly)
    {
        return Area(poly) >= 0;
    }
//------------------------------------------------------------------------------

    double Area(const Path &poly)
    {
        int size = (int)poly.size();
        if (size < 3) return 0;

        double a = 0;
        for (int i = 0, j = size -1; i < size; ++i)
        {
            a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y);
            j = i;
        }
        return -a * 0.5;
    }
//------------------------------------------------------------------------------

    double Area(const OutPt *op)
    {
        const OutPt *startOp = op;
        if (!op) return 0;
        double a = 0;
        do {
            a +=  (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y);
            op = op->Next;
        } while (op != startOp);
        return a * 0.5;
    }
//------------------------------------------------------------------------------

    double Area(const OutRec &outRec)
    {
        return Area(outRec.Pts);
    }
//------------------------------------------------------------------------------

    bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
    {
        OutPt *pp2 = pp;
        do
        {
            if (pp2->Pt == Pt) return true;
            pp2 = pp2->Next;
        }
        while (pp2 != pp);
        return false;
    }
//------------------------------------------------------------------------------

//See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos
//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
    int PointInPolygon(const IntPoint &pt, const Path &path)
    {
        //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
        int result = 0;
        size_t cnt = path.size();
        if (cnt < 3) return 0;
        IntPoint ip = path[0];
        for(size_t i = 1; i <= cnt; ++i)
        {
            IntPoint ipNext = (i == cnt ? path[0] : path[i]);
            if (ipNext.Y == pt.Y)
            {
                if ((ipNext.X == pt.X) || (ip.Y == pt.Y &&
                                           ((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1;
            }
            if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y))
            {
                if (ip.X >= pt.X)
                {
                    if (ipNext.X > pt.X) result = 1 - result;
                    else
                    {
                        double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
                                   (double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
                        if (!d) return -1;
                        if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
                    }
                } else
                {
                    if (ipNext.X > pt.X)
                    {
                        double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
                                   (double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
                        if (!d) return -1;
                        if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
                    }
                }
            }
            ip = ipNext;
        }
        return result;
    }
//------------------------------------------------------------------------------

    int PointInPolygon (const IntPoint &pt, OutPt *op)
    {
        //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
        int result = 0;
        OutPt* startOp = op;
        for(;;)
        {
            if (op->Next->Pt.Y == pt.Y)
            {
                if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y &&
                                                 ((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1;
            }
            if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y))
            {
                if (op->Pt.X >= pt.X)
                {
                    if (op->Next->Pt.X > pt.X) result = 1 - result;
                    else
                    {
                        double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
                                   (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
                        if (!d) return -1;
                        if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
                    }
                } else
                {
                    if (op->Next->Pt.X > pt.X)
                    {
                        double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
                                   (double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
                        if (!d) return -1;
                        if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
                    }
                }
            }
            op = op->Next;
            if (startOp == op) break;
        }
        return result;
    }
//------------------------------------------------------------------------------

    bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
    {
        OutPt* op = OutPt1;
        do
        {
            //nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon
            int res = PointInPolygon(op->Pt, OutPt2);
            if (res >= 0) return res > 0;
            op = op->Next;
        }
        while (op != OutPt1);
        return true;
    }
//----------------------------------------------------------------------

    bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
    {
#ifndef use_int32
        if (UseFullInt64Range)
            return Int128Mul(e1.Top.Y - e1.Bot.Y, e2.Top.X - e2.Bot.X) ==
                   Int128Mul(e1.Top.X - e1.Bot.X, e2.Top.Y - e2.Bot.Y);
        else
#endif
            return (e1.Top.Y - e1.Bot.Y) * (e2.Top.X - e2.Bot.X) ==
                   (e1.Top.X - e1.Bot.X) * (e2.Top.Y - e2.Bot.Y);
    }
//------------------------------------------------------------------------------

    bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
                     const IntPoint pt3, bool UseFullInt64Range)
    {
#ifndef use_int32
        if (UseFullInt64Range)
            return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y);
        else
#endif
            return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
    }
//------------------------------------------------------------------------------

    bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
                     const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range)
    {
#ifndef use_int32
        if (UseFullInt64Range)
            return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y);
        else
#endif
            return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
    }
//------------------------------------------------------------------------------

    inline bool IsHorizontal(TEdge &e)
    {
        return e.Dx == HORIZONTAL;
    }
//------------------------------------------------------------------------------

    inline double GetDx(const IntPoint pt1, const IntPoint pt2)
    {
        return (pt1.Y == pt2.Y) ?
               HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y);
    }
//---------------------------------------------------------------------------

    inline void SetDx(TEdge &e)
    {
        cInt dy  = (e.Top.Y - e.Bot.Y);
        if (dy == 0) e.Dx = HORIZONTAL;
        else e.Dx = (double)(e.Top.X - e.Bot.X) / dy;
    }
//---------------------------------------------------------------------------

    inline void SwapSides(TEdge &Edge1, TEdge &Edge2)
    {
        EdgeSide Side =  Edge1.Side;
        Edge1.Side = Edge2.Side;
        Edge2.Side = Side;
    }
//------------------------------------------------------------------------------

    inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
    {
        int OutIdx =  Edge1.OutIdx;
        Edge1.OutIdx = Edge2.OutIdx;
        Edge2.OutIdx = OutIdx;
    }
//------------------------------------------------------------------------------

    inline cInt TopX(TEdge &edge, const cInt currentY)
    {
        return ( currentY == edge.Top.Y ) ?
               edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y));
    }
//------------------------------------------------------------------------------

    void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
    {
#ifdef use_xyz
        ip.Z = 0;
#endif

        double b1, b2;
        if (Edge1.Dx == Edge2.Dx)
        {
            ip.Y = Edge1.Curr.Y;
            ip.X = TopX(Edge1, ip.Y);
            return;
        }
        else if (Edge1.Dx == 0)
        {
            ip.X = Edge1.Bot.X;
            if (IsHorizontal(Edge2))
                ip.Y = Edge2.Bot.Y;
            else
            {
                b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx);
                ip.Y = Round(ip.X / Edge2.Dx + b2);
            }
        }
        else if (Edge2.Dx == 0)
        {
            ip.X = Edge2.Bot.X;
            if (IsHorizontal(Edge1))
                ip.Y = Edge1.Bot.Y;
            else
            {
                b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx);
                ip.Y = Round(ip.X / Edge1.Dx + b1);
            }
        }
        else
        {
            b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx;
            b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx;
            double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
            ip.Y = Round(q);
            if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
                ip.X = Round(Edge1.Dx * q + b1);
            else
                ip.X = Round(Edge2.Dx * q + b2);
        }

        if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y)
        {
            if (Edge1.Top.Y > Edge2.Top.Y)
                ip.Y = Edge1.Top.Y;
            else
                ip.Y = Edge2.Top.Y;
            if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
                ip.X = TopX(Edge1, ip.Y);
            else
                ip.X = TopX(Edge2, ip.Y);
        }
        //finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ...
        if (ip.Y > Edge1.Curr.Y)
        {
            ip.Y = Edge1.Curr.Y;
            //use the more vertical edge to derive X ...
            if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx))
                ip.X = TopX(Edge2, ip.Y); else
                ip.X = TopX(Edge1, ip.Y);
        }
    }
//------------------------------------------------------------------------------

    void ReversePolyPtLinks(OutPt *pp)
    {
        if (!pp) return;
        OutPt *pp1, *pp2;
        pp1 = pp;
        do {
            pp2 = pp1->Next;
            pp1->Next = pp1->Prev;
            pp1->Prev = pp2;
            pp1 = pp2;
        } while( pp1 != pp );
    }
//------------------------------------------------------------------------------

    void DisposeOutPts(OutPt*& pp)
    {
        if (pp == 0) return;
        pp->Prev->Next = 0;
        while( pp )
        {
            OutPt *tmpPp = pp;
            pp = pp->Next;
            delete tmpPp;
        }
    }
//------------------------------------------------------------------------------

    inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
    {
        std::memset(e, 0, sizeof(TEdge));
        e->Next = eNext;
        e->Prev = ePrev;
        e->Curr = Pt;
        e->OutIdx = Unassigned;
    }
//------------------------------------------------------------------------------

    void InitEdge2(TEdge& e, PolyType Pt)
    {
        if (e.Curr.Y >= e.Next->Curr.Y)
        {
            e.Bot = e.Curr;
            e.Top = e.Next->Curr;
        } else
        {
            e.Top = e.Curr;
            e.Bot = e.Next->Curr;
        }
        SetDx(e);
        e.PolyTyp = Pt;
    }
//------------------------------------------------------------------------------

    TEdge* RemoveEdge(TEdge* e)
    {
        //removes e from double_linked_list (but without removing from memory)
        e->Prev->Next = e->Next;
        e->Next->Prev = e->Prev;
        TEdge* result = e->Next;
        e->Prev = 0; //flag as removed (see ClipperBase.Clear)
        return result;
    }
//------------------------------------------------------------------------------

    inline void ReverseHorizontal(TEdge &e)
    {
        //swap horizontal edges' Top and Bottom x's so they follow the natural
        //progression of the bounds - ie so their xbots will align with the
        //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
        std::swap(e.Top.X, e.Bot.X);
#ifdef use_xyz
        std::swap(e.Top.Z, e.Bot.Z);
#endif
    }
//------------------------------------------------------------------------------

    void SwapPoints(IntPoint &pt1, IntPoint &pt2)
    {
        IntPoint tmp = pt1;
        pt1 = pt2;
        pt2 = tmp;
    }
//------------------------------------------------------------------------------

    bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
                           IntPoint pt2b, IntPoint &pt1, IntPoint &pt2)
    {
        //precondition: segments are Collinear.
        if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y))
        {
            if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b);
            if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b);
            if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a;
            if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b;
            return pt1.X < pt2.X;
        } else
        {
            if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b);
            if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b);
            if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a;
            if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b;
            return pt1.Y > pt2.Y;
        }
    }
//------------------------------------------------------------------------------

    bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
    {
        OutPt *p = btmPt1->Prev;
        while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev;
        double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt));
        p = btmPt1->Next;
        while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next;
        double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt));

        p = btmPt2->Prev;
        while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev;
        double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt));
        p = btmPt2->Next;
        while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
        double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));

        if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
            std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
            return Area(btmPt1) > 0; //if otherwise identical use orientation
        else
            return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
    }
//------------------------------------------------------------------------------

    OutPt* GetBottomPt(OutPt *pp)
    {
        OutPt* dups = 0;
        OutPt* p = pp->Next;
        while (p != pp)
        {
            if (p->Pt.Y > pp->Pt.Y)
            {
                pp = p;
                dups = 0;
            }
            else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X)
            {
                if (p->Pt.X < pp->Pt.X)
                {
                    dups = 0;
                    pp = p;
                } else
                {
                    if (p->Next != pp && p->Prev != pp) dups = p;
                }
            }
            p = p->Next;
        }
        if (dups)
        {
            //there appears to be at least 2 vertices at BottomPt so ...
            while (dups != p)
            {
                if (!FirstIsBottomPt(p, dups)) pp = dups;
                dups = dups->Next;
                while (dups->Pt != pp->Pt) dups = dups->Next;
            }
        }
        return pp;
    }
//------------------------------------------------------------------------------

    bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1,
                               const IntPoint pt2, const IntPoint pt3)
    {
        if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
            return false;
        else if (pt1.X != pt3.X)
            return (pt2.X > pt1.X) == (pt2.X < pt3.X);
        else
            return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y);
    }
//------------------------------------------------------------------------------

    bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
    {
        if (seg1a > seg1b) std::swap(seg1a, seg1b);
        if (seg2a > seg2b) std::swap(seg2a, seg2b);
        return (seg1a < seg2b) && (seg2a < seg1b);
    }

//------------------------------------------------------------------------------
// ClipperBase class methods ...
//------------------------------------------------------------------------------

    ClipperBase::ClipperBase() //constructor
    {
        m_CurrentLM = m_MinimaList.begin(); //begin() == end() here
        m_UseFullRange = false;
    }
//------------------------------------------------------------------------------

    ClipperBase::~ClipperBase() //destructor
    {
        Clear();
    }
//------------------------------------------------------------------------------

    void RangeTest(const IntPoint& Pt, bool& useFullRange)
    {
        if (useFullRange)
        {
            if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange)
                return;//throw clipperException("Coordinate outside allowed range");
        }
        else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
        {
            useFullRange = true;
            RangeTest(Pt, useFullRange);
        }
    }
//------------------------------------------------------------------------------

    TEdge* FindNextLocMin(TEdge* E)
    {
        for (;;)
        {
            while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next;
            if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break;
            while (IsHorizontal(*E->Prev)) E = E->Prev;
            TEdge* E2 = E;
            while (IsHorizontal(*E)) E = E->Next;
            if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz.
            if (E2->Prev->Bot.X < E->Bot.X) E = E2;
            break;
        }
        return E;
    }
//------------------------------------------------------------------------------

    TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
    {
        TEdge *Result = E;
        TEdge *Horz = 0;

        if (E->OutIdx == Skip)
        {
            //if edges still remain in the current bound beyond the skip edge then
            //create another LocMin and call ProcessBound once more
            if (NextIsForward)
            {
                while (E->Top.Y == E->Next->Bot.Y) E = E->Next;
                //don't include top horizontals when parsing a bound a second time,
                //they will be contained in the opposite bound ...
                while (E != Result && IsHorizontal(*E)) E = E->Prev;
            }
            else
            {
                while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev;
                while (E != Result && IsHorizontal(*E)) E = E->Next;
            }

            if (E == Result)
            {
                if (NextIsForward) Result = E->Next;
                else Result = E->Prev;
            }
            else
            {
                //there are more edges in the bound beyond result starting with E
                if (NextIsForward)
                    E = Result->Next;
                else
                    E = Result->Prev;
                MinimaList::value_type locMin;
                locMin.Y = E->Bot.Y;
                locMin.LeftBound = 0;
                locMin.RightBound = E;
                E->WindDelta = 0;
                Result = ProcessBound(E, NextIsForward);
                m_MinimaList.push_back(locMin);
            }
            return Result;
        }

        TEdge *EStart;

        if (IsHorizontal(*E))
        {
            //We need to be careful with open paths because this may not be a
            //true local minima (ie E may be following a skip edge).
            //Also, consecutive horz. edges may start heading left before going right.
            if (NextIsForward)
                EStart = E->Prev;
            else
                EStart = E->Next;
            if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge
            {
                if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X)
                    ReverseHorizontal(*E);
            }
            else if (EStart->Bot.X != E->Bot.X)
                ReverseHorizontal(*E);
        }

        EStart = E;
        if (NextIsForward)
        {
            while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip)
                Result = Result->Next;
            if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip)
            {
                //nb: at the top of a bound, horizontals are added to the bound
                //only when the preceding edge attaches to the horizontal's left vertex
                //unless a Skip edge is encountered when that becomes the top divide
                Horz = Result;
                while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
                if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
            }
            while (E != Result)
            {
                E->NextInLML = E->Next;
                if (IsHorizontal(*E) && E != EStart &&
                    E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
                E = E->Next;
            }
            if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X)
                ReverseHorizontal(*E);
            Result = Result->Next; //move to the edge just beyond current bound
        } else
        {
            while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip)
                Result = Result->Prev;
            if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
            {
                Horz = Result;
                while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
                if (Horz->Next->Top.X == Result->Prev->Top.X ||
                    Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next;
            }

            while (E != Result)
            {
                E->NextInLML = E->Prev;
                if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
                    ReverseHorizontal(*E);
                E = E->Prev;
            }
            if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
                ReverseHorizontal(*E);
            Result = Result->Prev; //move to the edge just beyond current bound
        }

        return Result;
    }
//------------------------------------------------------------------------------

    bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
    {
#ifdef use_lines
        if (!Closed && PolyTyp == ptClip)
            return false;//throw clipperException("AddPath: Open paths must be subject.");
#else
        if (!Closed)
    throw clipperException("AddPath: Open paths have been disabled.");
#endif

        int highI = (int)pg.size() -1;
        if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI;
        while (highI > 0 && (pg[highI] == pg[highI -1])) --highI;
        if ((Closed && highI < 2) || (!Closed && highI < 1)) return false;

        //create a new edge array ...
        TEdge *edges = new TEdge [highI +1];

        bool IsFlat = true;
        //1. Basic (first) edge initialization ...
        //try
        {
            edges[1].Curr = pg[1];
            RangeTest(pg[0], m_UseFullRange);
            RangeTest(pg[highI], m_UseFullRange);
            InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
            InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
            for (int i = highI - 1; i >= 1; --i)
            {
                RangeTest(pg[i], m_UseFullRange);
                InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
            }
        }
        //catch(...)
        //{
        //    delete [] edges;
        //    return false;//throw; //range test fails
        //}
        TEdge *eStart = &edges[0];

        //2. Remove duplicate vertices, and (when closed) collinear edges ...
        TEdge *E = eStart, *eLoopStop = eStart;
        for (;;)
        {
            //nb: allows matching start and end points when not Closed ...
            if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart))
            {
                if (E == E->Next) break;
                if (E == eStart) eStart = E->Next;
                E = RemoveEdge(E);
                eLoopStop = E;
                continue;
            }
            if (E->Prev == E->Next)
                break; //only two vertices
            else if (Closed &&
                     SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) &&
                     (!m_PreserveCollinear ||
                      !Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr)))
            {
                //Collinear edges are allowed for open paths but in closed paths
                //the default is to merge adjacent collinear edges into a single edge.
                //However, if the PreserveCollinear property is enabled, only overlapping
                //collinear edges (ie spikes) will be removed from closed paths.
                if (E == eStart) eStart = E->Next;
                E = RemoveEdge(E);
                E = E->Prev;
                eLoopStop = E;
                continue;
            }
            E = E->Next;
            if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break;
        }

        if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next)))
        {
            delete [] edges;
            return false;
        }

        if (!Closed)
        {
            m_HasOpenPaths = true;
            eStart->Prev->OutIdx = Skip;
        }

        //3. Do second stage of edge initialization ...
        E = eStart;
        do
        {
            InitEdge2(*E, PolyTyp);
            E = E->Next;
            if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false;
        }
        while (E != eStart);

        //4. Finally, add edge bounds to LocalMinima list ...

        //Totally flat paths must be handled differently when adding them
        //to LocalMinima list to avoid endless loops etc ...
        if (IsFlat)
        {
            if (Closed)
            {
                delete [] edges;
                return false;
            }
            E->Prev->OutIdx = Skip;
            MinimaList::value_type locMin;
            locMin.Y = E->Bot.Y;
            locMin.LeftBound = 0;
            locMin.RightBound = E;
            locMin.RightBound->Side = esRight;
            locMin.RightBound->WindDelta = 0;
            for (;;)
            {
                if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
                if (E->Next->OutIdx == Skip) break;
                E->NextInLML = E->Next;
                E = E->Next;
            }
            m_MinimaList.push_back(locMin);
            m_edges.push_back(edges);
            return true;
        }

        m_edges.push_back(edges);
        bool leftBoundIsForward;
        TEdge* EMin = 0;

        //workaround to avoid an endless loop in the while loop below when
        //open paths have matching start and end points ...
        if (E->Prev->Bot == E->Prev->Top) E = E->Next;

        for (;;)
        {
            E = FindNextLocMin(E);
            if (E == EMin) break;
            else if (!EMin) EMin = E;

            //E and E.Prev now share a local minima (left aligned if horizontal).
            //Compare their slopes to find which starts which bound ...
            MinimaList::value_type locMin;
            locMin.Y = E->Bot.Y;
            if (E->Dx < E->Prev->Dx)
            {
                locMin.LeftBound = E->Prev;
                locMin.RightBound = E;
                leftBoundIsForward = false; //Q.nextInLML = Q.prev
            } else
            {
                locMin.LeftBound = E;
                locMin.RightBound = E->Prev;
                leftBoundIsForward = true; //Q.nextInLML = Q.next
            }

            if (!Closed) locMin.LeftBound->WindDelta = 0;
            else if (locMin.LeftBound->Next == locMin.RightBound)
                locMin.LeftBound->WindDelta = -1;
            else locMin.LeftBound->WindDelta = 1;
            locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta;

            E = ProcessBound(locMin.LeftBound, leftBoundIsForward);
            if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward);

            TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward);
            if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward);

            if (locMin.LeftBound->OutIdx == Skip)
                locMin.LeftBound = 0;
            else if (locMin.RightBound->OutIdx == Skip)
                locMin.RightBound = 0;
            m_MinimaList.push_back(locMin);
            if (!leftBoundIsForward) E = E2;
        }
        return true;
    }
//------------------------------------------------------------------------------

    bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
    {
        bool result = false;
        for (Paths::size_type i = 0; i < ppg.size(); ++i)
            if (AddPath(ppg[i], PolyTyp, Closed)) result = true;
        return result;
    }
//------------------------------------------------------------------------------

    void ClipperBase::Clear()
    {
        DisposeLocalMinimaList();
        for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
        {
            TEdge* edges = m_edges[i];
            delete [] edges;
        }
        m_edges.clear();
        m_UseFullRange = false;
        m_HasOpenPaths = false;
    }
//------------------------------------------------------------------------------

    void ClipperBase::Reset()
    {
        m_CurrentLM = m_MinimaList.begin();
        if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process
        std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter());

        m_Scanbeam = ScanbeamList(); //clears/resets priority_queue
        //reset all edges ...
        for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
        {
            InsertScanbeam(lm->Y);
            TEdge* e = lm->LeftBound;
            if (e)
            {
                e->Curr = e->Bot;
                e->Side = esLeft;
                e->OutIdx = Unassigned;
            }

            e = lm->RightBound;
            if (e)
            {
                e->Curr = e->Bot;
                e->Side = esRight;
                e->OutIdx = Unassigned;
            }
        }
        m_ActiveEdges = 0;
        m_CurrentLM = m_MinimaList.begin();
    }
//------------------------------------------------------------------------------

    void ClipperBase::DisposeLocalMinimaList()
    {
        m_MinimaList.clear();
        m_CurrentLM = m_MinimaList.begin();
    }
//------------------------------------------------------------------------------

    bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
    {
        if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).Y != Y) return false;
        locMin = &(*m_CurrentLM);
        ++m_CurrentLM;
        return true;
    }
//------------------------------------------------------------------------------

    IntRect ClipperBase::GetBounds()
    {
        IntRect result;
        MinimaList::iterator lm = m_MinimaList.begin();
        if (lm == m_MinimaList.end())
        {
            result.left = result.top = result.right = result.bottom = 0;
            return result;
        }
        result.left = lm->LeftBound->Bot.X;
        result.top = lm->LeftBound->Bot.Y;
        result.right = lm->LeftBound->Bot.X;
        result.bottom = lm->LeftBound->Bot.Y;
        while (lm != m_MinimaList.end())
        {
            //todo - needs fixing for open paths
            result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y);
            TEdge* e = lm->LeftBound;
            for (;;) {
                TEdge* bottomE = e;
                while (e->NextInLML)
                {
                    if (e->Bot.X < result.left) result.left = e->Bot.X;
                    if (e->Bot.X > result.right) result.right = e->Bot.X;
                    e = e->NextInLML;
                }
                result.left = std::min(result.left, e->Bot.X);
                result.right = std::max(result.right, e->Bot.X);
                result.left = std::min(result.left, e->Top.X);
                result.right = std::max(result.right, e->Top.X);
                result.top = std::min(result.top, e->Top.Y);
                if (bottomE == lm->LeftBound) e = lm->RightBound;
                else break;
            }
            ++lm;
        }
        return result;
    }
//------------------------------------------------------------------------------

    void ClipperBase::InsertScanbeam(const cInt Y)
    {
        m_Scanbeam.push(Y);
    }
//------------------------------------------------------------------------------

    bool ClipperBase::PopScanbeam(cInt &Y)
    {
        if (m_Scanbeam.empty()) return false;
        Y = m_Scanbeam.top();
        m_Scanbeam.pop();
        while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
        return true;
    }
//------------------------------------------------------------------------------

    void ClipperBase::DisposeAllOutRecs(){
        for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
            DisposeOutRec(i);
        m_PolyOuts.clear();
    }
//------------------------------------------------------------------------------

    void ClipperBase::DisposeOutRec(PolyOutList::size_type index)
    {
        OutRec *outRec = m_PolyOuts[index];
        if (outRec->Pts) DisposeOutPts(outRec->Pts);
        delete outRec;
        m_PolyOuts[index] = 0;
    }
//------------------------------------------------------------------------------

    void ClipperBase::DeleteFromAEL(TEdge *e)
    {
        TEdge* AelPrev = e->PrevInAEL;
        TEdge* AelNext = e->NextInAEL;
        if (!AelPrev &&  !AelNext && (e != m_ActiveEdges)) return; //already deleted
        if (AelPrev) AelPrev->NextInAEL = AelNext;
        else m_ActiveEdges = AelNext;
        if (AelNext) AelNext->PrevInAEL = AelPrev;
        e->NextInAEL = 0;
        e->PrevInAEL = 0;
    }
//------------------------------------------------------------------------------

    OutRec* ClipperBase::CreateOutRec()
    {
        OutRec* result = new OutRec;
        result->IsHole = false;
        result->IsOpen = false;
        result->FirstLeft = 0;
        result->Pts = 0;
        result->BottomPt = 0;
        result->PolyNd = 0;
        m_PolyOuts.push_back(result);
        result->Idx = (int)m_PolyOuts.size() - 1;
        return result;
    }
//------------------------------------------------------------------------------

    void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
    {
        //check that one or other edge hasn't already been removed from AEL ...
        if (Edge1->NextInAEL == Edge1->PrevInAEL ||
            Edge2->NextInAEL == Edge2->PrevInAEL) return;

        if (Edge1->NextInAEL == Edge2)
        {
            TEdge* Next = Edge2->NextInAEL;
            if (Next) Next->PrevInAEL = Edge1;
            TEdge* Prev = Edge1->PrevInAEL;
            if (Prev) Prev->NextInAEL = Edge2;
            Edge2->PrevInAEL = Prev;
            Edge2->NextInAEL = Edge1;
            Edge1->PrevInAEL = Edge2;
            Edge1->NextInAEL = Next;
        }
        else if (Edge2->NextInAEL == Edge1)
        {
            TEdge* Next = Edge1->NextInAEL;
            if (Next) Next->PrevInAEL = Edge2;
            TEdge* Prev = Edge2->PrevInAEL;
            if (Prev) Prev->NextInAEL = Edge1;
            Edge1->PrevInAEL = Prev;
            Edge1->NextInAEL = Edge2;
            Edge2->PrevInAEL = Edge1;
            Edge2->NextInAEL = Next;
        }
        else
        {
            TEdge* Next = Edge1->NextInAEL;
            TEdge* Prev = Edge1->PrevInAEL;
            Edge1->NextInAEL = Edge2->NextInAEL;
            if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1;
            Edge1->PrevInAEL = Edge2->PrevInAEL;
            if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1;
            Edge2->NextInAEL = Next;
            if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2;
            Edge2->PrevInAEL = Prev;
            if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2;
        }

        if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1;
        else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2;
    }
//------------------------------------------------------------------------------

    void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
    {
        if (!e->NextInLML)
            return;//throw clipperException("UpdateEdgeIntoAEL: invalid call");

        e->NextInLML->OutIdx = e->OutIdx;
        TEdge* AelPrev = e->PrevInAEL;
        TEdge* AelNext = e->NextInAEL;
        if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
        else m_ActiveEdges = e->NextInLML;
        if (AelNext) AelNext->PrevInAEL = e->NextInLML;
        e->NextInLML->Side = e->Side;
        e->NextInLML->WindDelta = e->WindDelta;
        e->NextInLML->WindCnt = e->WindCnt;
        e->NextInLML->WindCnt2 = e->WindCnt2;
        e = e->NextInLML;
        e->Curr = e->Bot;
        e->PrevInAEL = AelPrev;
        e->NextInAEL = AelNext;
        if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y);
    }
//------------------------------------------------------------------------------

    bool ClipperBase::LocalMinimaPending()
    {
        return (m_CurrentLM != m_MinimaList.end());
    }

//------------------------------------------------------------------------------
// TClipper methods ...
//------------------------------------------------------------------------------

    Clipper::Clipper(int initOptions) : ClipperBase() //constructor
    {
        m_ExecuteLocked = false;
        m_UseFullRange = false;
        m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
        m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
        m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
        m_HasOpenPaths = false;
#ifdef use_xyz
        m_ZFill = 0;
#endif
    }
//------------------------------------------------------------------------------

#ifdef use_xyz
    void Clipper::ZFillFunction(ZFillCallback zFillFunc)
{
  m_ZFill = zFillFunc;
}
//------------------------------------------------------------------------------
#endif

    bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType)
    {
        return Execute(clipType, solution, fillType, fillType);
    }
//------------------------------------------------------------------------------

    bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType)
    {
        return Execute(clipType, polytree, fillType, fillType);
    }
//------------------------------------------------------------------------------

    bool Clipper::Execute(ClipType clipType, Paths &solution,
                          PolyFillType subjFillType, PolyFillType clipFillType)
    {
        if( m_ExecuteLocked ) return false;
        if (m_HasOpenPaths)
            return false;//throw clipperException("Error: PolyTree struct is needed for open path clipping.");
        m_ExecuteLocked = true;
        solution.resize(0);
        m_SubjFillType = subjFillType;
        m_ClipFillType = clipFillType;
        m_ClipType = clipType;
        m_UsingPolyTree = false;
        bool succeeded = ExecuteInternal();
        if (succeeded) BuildResult(solution);
        DisposeAllOutRecs();
        m_ExecuteLocked = false;
        return succeeded;
    }
//------------------------------------------------------------------------------

    bool Clipper::Execute(ClipType clipType, PolyTree& polytree,
                          PolyFillType subjFillType, PolyFillType clipFillType)
    {
        if( m_ExecuteLocked ) return false;
        m_ExecuteLocked = true;
        m_SubjFillType = subjFillType;
        m_ClipFillType = clipFillType;
        m_ClipType = clipType;
        m_UsingPolyTree = true;
        bool succeeded = ExecuteInternal();
        if (succeeded) BuildResult2(polytree);
        DisposeAllOutRecs();
        m_ExecuteLocked = false;
        return succeeded;
    }
//------------------------------------------------------------------------------

    void Clipper::FixHoleLinkage(OutRec &outrec)
    {
        //skip OutRecs that (a) contain outermost polygons or
        //(b) already have the correct owner/child linkage ...
        if (!outrec.FirstLeft ||
            (outrec.IsHole != outrec.FirstLeft->IsHole &&
             outrec.FirstLeft->Pts)) return;

        OutRec* orfl = outrec.FirstLeft;
        while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts))
            orfl = orfl->FirstLeft;
        outrec.FirstLeft = orfl;
    }
//------------------------------------------------------------------------------

    bool Clipper::ExecuteInternal()
    {
        bool succeeded = true;
        //try
        {
            Reset();
            m_Maxima = MaximaList();
            m_SortedEdges = 0;

            succeeded = true;
            cInt botY, topY;
            if (!PopScanbeam(botY)) return false;
            InsertLocalMinimaIntoAEL(botY);
            while (PopScanbeam(topY) || LocalMinimaPending())
            {
                ProcessHorizontals();
                ClearGhostJoins();
                if (!ProcessIntersections(topY))
                {
                    succeeded = false;
                    break;
                }
                ProcessEdgesAtTopOfScanbeam(topY);
                botY = topY;
                InsertLocalMinimaIntoAEL(botY);
            }
        }
        //catch(...)
        //{
        //    succeeded = false;
        //}

        if (succeeded)
        {
            //fix orientations ...
            for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
            {
                OutRec *outRec = m_PolyOuts[i];
                if (!outRec->Pts || outRec->IsOpen) continue;
                if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0))
                    ReversePolyPtLinks(outRec->Pts);
            }

            if (!m_Joins.empty()) JoinCommonEdges();

            //unfortunately FixupOutPolygon() must be done after JoinCommonEdges()
            for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
            {
                OutRec *outRec = m_PolyOuts[i];
                if (!outRec->Pts) continue;
                if (outRec->IsOpen)
                    FixupOutPolyline(*outRec);
                else
                    FixupOutPolygon(*outRec);
            }

            if (m_StrictSimple) DoSimplePolygons();
        }

        ClearJoins();
        ClearGhostJoins();
        return succeeded;
    }
//------------------------------------------------------------------------------

    void Clipper::SetWindingCount(TEdge &edge)
    {
        TEdge *e = edge.PrevInAEL;
        //find the edge of the same polytype that immediately preceeds 'edge' in AEL
        while (e  && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
        if (!e)
        {
            if (edge.WindDelta == 0)
            {
                PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
                edge.WindCnt = (pft == pftNegative ? -1 : 1);
            }
            else
                edge.WindCnt = edge.WindDelta;
            edge.WindCnt2 = 0;
            e = m_ActiveEdges; //ie get ready to calc WindCnt2
        }
        else if (edge.WindDelta == 0 && m_ClipType != ctUnion)
        {
            edge.WindCnt = 1;
            edge.WindCnt2 = e->WindCnt2;
            e = e->NextInAEL; //ie get ready to calc WindCnt2
        }
        else if (IsEvenOddFillType(edge))
        {
            //EvenOdd filling ...
            if (edge.WindDelta == 0)
            {
                //are we inside a subj polygon ...
                bool Inside = true;
                TEdge *e2 = e->PrevInAEL;
                while (e2)
                {
                    if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0)
                        Inside = !Inside;
                    e2 = e2->PrevInAEL;
                }
                edge.WindCnt = (Inside ? 0 : 1);
            }
            else
            {
                edge.WindCnt = edge.WindDelta;
            }
            edge.WindCnt2 = e->WindCnt2;
            e = e->NextInAEL; //ie get ready to calc WindCnt2
        }
        else
        {
            //nonZero, Positive or Negative filling ...
            if (e->WindCnt * e->WindDelta < 0)
            {
                //prev edge is 'decreasing' WindCount (WC) toward zero
                //so we're outside the previous polygon ...
                if (Abs(e->WindCnt) > 1)
                {
                    //outside prev poly but still inside another.
                    //when reversing direction of prev poly use the same WC
                    if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
                        //otherwise continue to 'decrease' WC ...
                    else edge.WindCnt = e->WindCnt + edge.WindDelta;
                }
                else
                    //now outside all polys of same polytype so set own WC ...
                    edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
            } else
            {
                //prev edge is 'increasing' WindCount (WC) away from zero
                //so we're inside the previous polygon ...
                if (edge.WindDelta == 0)
                    edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1);
                    //if wind direction is reversing prev then use same WC
                else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
                    //otherwise add to WC ...
                else edge.WindCnt = e->WindCnt + edge.WindDelta;
            }
            edge.WindCnt2 = e->WindCnt2;
            e = e->NextInAEL; //ie get ready to calc WindCnt2
        }

        //update WindCnt2 ...
        if (IsEvenOddAltFillType(edge))
        {
            //EvenOdd filling ...
            while (e != &edge)
            {
                if (e->WindDelta != 0)
                    edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0);
                e = e->NextInAEL;
            }
        } else
        {
            //nonZero, Positive or Negative filling ...
            while ( e != &edge )
            {
                edge.WindCnt2 += e->WindDelta;
                e = e->NextInAEL;
            }
        }
    }
//------------------------------------------------------------------------------

    bool Clipper::IsEvenOddFillType(const TEdge& edge) const
    {
        if (edge.PolyTyp == ptSubject)
            return m_SubjFillType == pftEvenOdd; else
            return m_ClipFillType == pftEvenOdd;
    }
//------------------------------------------------------------------------------

    bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const
    {
        if (edge.PolyTyp == ptSubject)
            return m_ClipFillType == pftEvenOdd; else
            return m_SubjFillType == pftEvenOdd;
    }
//------------------------------------------------------------------------------

    bool Clipper::IsContributing(const TEdge& edge) const
    {
        PolyFillType pft, pft2;
        if (edge.PolyTyp == ptSubject)
        {
            pft = m_SubjFillType;
            pft2 = m_ClipFillType;
        } else
        {
            pft = m_ClipFillType;
            pft2 = m_SubjFillType;
        }

        switch(pft)
        {
            case pftEvenOdd:
                //return false if a subj line has been flagged as inside a subj polygon
                if (edge.WindDelta == 0 && edge.WindCnt != 1) return false;
                break;
            case pftNonZero:
                if (Abs(edge.WindCnt) != 1) return false;
                break;
            case pftPositive:
                if (edge.WindCnt != 1) return false;
                break;
            default: //pftNegative
                if (edge.WindCnt != -1) return false;
        }

        switch(m_ClipType)
        {
            case ctIntersection:
                switch(pft2)
                {
                    case pftEvenOdd:
                    case pftNonZero:
                        return (edge.WindCnt2 != 0);
                    case pftPositive:
                        return (edge.WindCnt2 > 0);
                    default:
                        return (edge.WindCnt2 < 0);
                }
                break;
            case ctUnion:
                switch(pft2)
                {
                    case pftEvenOdd:
                    case pftNonZero:
                        return (edge.WindCnt2 == 0);
                    case pftPositive:
                        return (edge.WindCnt2 <= 0);
                    default:
                        return (edge.WindCnt2 >= 0);
                }
                break;
            case ctDifference:
                if (edge.PolyTyp == ptSubject)
                    switch(pft2)
                    {
                        case pftEvenOdd:
                        case pftNonZero:
                            return (edge.WindCnt2 == 0);
                        case pftPositive:
                            return (edge.WindCnt2 <= 0);
                        default:
                            return (edge.WindCnt2 >= 0);
                    }
                else
                    switch(pft2)
                    {
                        case pftEvenOdd:
                        case pftNonZero:
                            return (edge.WindCnt2 != 0);
                        case pftPositive:
                            return (edge.WindCnt2 > 0);
                        default:
                            return (edge.WindCnt2 < 0);
                    }
                break;
            case ctXor:
                if (edge.WindDelta == 0) //XOr always contributing unless open
                    switch(pft2)
                    {
                        case pftEvenOdd:
                        case pftNonZero:
                            return (edge.WindCnt2 == 0);
                        case pftPositive:
                            return (edge.WindCnt2 <= 0);
                        default:
                            return (edge.WindCnt2 >= 0);
                    }
                else
                    return true;
                break;
            default:
                return true;
        }
    }
//------------------------------------------------------------------------------

    OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
    {
        OutPt* result;
        TEdge *e, *prevE;
        if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx ))
        {
            result = AddOutPt(e1, Pt);
            e2->OutIdx = e1->OutIdx;
            e1->Side = esLeft;
            e2->Side = esRight;
            e = e1;
            if (e->PrevInAEL == e2)
                prevE = e2->PrevInAEL;
            else
                prevE = e->PrevInAEL;
        } else
        {
            result = AddOutPt(e2, Pt);
            e1->OutIdx = e2->OutIdx;
            e1->Side = esRight;
            e2->Side = esLeft;
            e = e2;
            if (e->PrevInAEL == e1)
                prevE = e1->PrevInAEL;
            else
                prevE = e->PrevInAEL;
        }

        if (prevE && prevE->OutIdx >= 0 && prevE->Top.Y < Pt.Y && e->Top.Y < Pt.Y)
        {
            cInt xPrev = TopX(*prevE, Pt.Y);
            cInt xE = TopX(*e, Pt.Y);
            if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
                SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange))
            {
                OutPt* outPt = AddOutPt(prevE, Pt);
                AddJoin(result, outPt, e->Top);
            }
        }
        return result;
    }
//------------------------------------------------------------------------------

    void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
    {
        AddOutPt( e1, Pt );
        if (e2->WindDelta == 0) AddOutPt(e2, Pt);
        if( e1->OutIdx == e2->OutIdx )
        {
            e1->OutIdx = Unassigned;
            e2->OutIdx = Unassigned;
        }
        else if (e1->OutIdx < e2->OutIdx)
            AppendPolygon(e1, e2);
        else
            AppendPolygon(e2, e1);
    }
//------------------------------------------------------------------------------

    void Clipper::AddEdgeToSEL(TEdge *edge)
    {
        //SEL pointers in PEdge are reused to build a list of horizontal edges.
        //However, we don't need to worry about order with horizontal edge processing.
        if( !m_SortedEdges )
        {
            m_SortedEdges = edge;
            edge->PrevInSEL = 0;
            edge->NextInSEL = 0;
        }
        else
        {
            edge->NextInSEL = m_SortedEdges;
            edge->PrevInSEL = 0;
            m_SortedEdges->PrevInSEL = edge;
            m_SortedEdges = edge;
        }
    }
//------------------------------------------------------------------------------

    bool Clipper::PopEdgeFromSEL(TEdge *&edge)
    {
        if (!m_SortedEdges) return false;
        edge = m_SortedEdges;
        DeleteFromSEL(m_SortedEdges);
        return true;
    }
//------------------------------------------------------------------------------

    void Clipper::CopyAELToSEL()
    {
        TEdge* e = m_ActiveEdges;
        m_SortedEdges = e;
        while ( e )
        {
            e->PrevInSEL = e->PrevInAEL;
            e->NextInSEL = e->NextInAEL;
            e = e->NextInAEL;
        }
    }
//------------------------------------------------------------------------------

    void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt)
    {
        Join* j = new Join;
        j->OutPt1 = op1;
        j->OutPt2 = op2;
        j->OffPt = OffPt;
        m_Joins.push_back(j);
    }
//------------------------------------------------------------------------------

    void Clipper::ClearJoins()
    {
        for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
            delete m_Joins[i];
        m_Joins.resize(0);
    }
//------------------------------------------------------------------------------

    void Clipper::ClearGhostJoins()
    {
        for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)
            delete m_GhostJoins[i];
        m_GhostJoins.resize(0);
    }
//------------------------------------------------------------------------------

    void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt)
    {
        Join* j = new Join;
        j->OutPt1 = op;
        j->OutPt2 = 0;
        j->OffPt = OffPt;
        m_GhostJoins.push_back(j);
    }
//------------------------------------------------------------------------------

    void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
    {
        const LocalMinimum *lm;
        while (PopLocalMinima(botY, lm))
        {
            TEdge* lb = lm->LeftBound;
            TEdge* rb = lm->RightBound;

            OutPt *Op1 = 0;
            if (!lb)
            {
                //nb: don't insert LB into either AEL or SEL
                InsertEdgeIntoAEL(rb, 0);
                SetWindingCount(*rb);
                if (IsContributing(*rb))
                    Op1 = AddOutPt(rb, rb->Bot);
            }
            else if (!rb)
            {
                InsertEdgeIntoAEL(lb, 0);
                SetWindingCount(*lb);
                if (IsContributing(*lb))
                    Op1 = AddOutPt(lb, lb->Bot);
                InsertScanbeam(lb->Top.Y);
            }
            else
            {
                InsertEdgeIntoAEL(lb, 0);
                InsertEdgeIntoAEL(rb, lb);
                SetWindingCount( *lb );
                rb->WindCnt = lb->WindCnt;
                rb->WindCnt2 = lb->WindCnt2;
                if (IsContributing(*lb))
                    Op1 = AddLocalMinPoly(lb, rb, lb->Bot);
                InsertScanbeam(lb->Top.Y);
            }

            if (rb)
            {
                if (IsHorizontal(*rb))
                {
                    AddEdgeToSEL(rb);
                    if (rb->NextInLML)
                        InsertScanbeam(rb->NextInLML->Top.Y);
                }
                else InsertScanbeam( rb->Top.Y );
            }

            if (!lb || !rb) continue;

            //if any output polygons share an edge, they'll need joining later ...
            if (Op1 && IsHorizontal(*rb) &&
                m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
            {
                for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
                {
                    Join* jr = m_GhostJoins[i];
                    //if the horizontal Rb and a 'ghost' horizontal overlap, then convert
                    //the 'ghost' join to a real join ready for later ...
                    if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X))
                        AddJoin(jr->OutPt1, Op1, jr->OffPt);
                }
            }

            if (lb->OutIdx >= 0 && lb->PrevInAEL &&
                lb->PrevInAEL->Curr.X == lb->Bot.X &&
                lb->PrevInAEL->OutIdx >= 0 &&
                SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
                (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
            {
                OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
                AddJoin(Op1, Op2, lb->Top);
            }

            if(lb->NextInAEL != rb)
            {

                if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
                    SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
                    (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
                {
                    OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
                    AddJoin(Op1, Op2, rb->Top);
                }

                TEdge* e = lb->NextInAEL;
                if (e)
                {
                    while( e != rb )
                    {
                        //nb: For calculating winding counts etc, IntersectEdges() assumes
                        //that param1 will be to the Right of param2 ABOVE the intersection ...
                        IntersectEdges(rb , e , lb->Curr); //order important here
                        e = e->NextInAEL;
                    }
                }
            }

        }
    }
//------------------------------------------------------------------------------

    void Clipper::DeleteFromSEL(TEdge *e)
    {
        TEdge* SelPrev = e->PrevInSEL;
        TEdge* SelNext = e->NextInSEL;
        if( !SelPrev &&  !SelNext && (e != m_SortedEdges) ) return; //already deleted
        if( SelPrev ) SelPrev->NextInSEL = SelNext;
        else m_SortedEdges = SelNext;
        if( SelNext ) SelNext->PrevInSEL = SelPrev;
        e->NextInSEL = 0;
        e->PrevInSEL = 0;
    }
//------------------------------------------------------------------------------

#ifdef use_xyz
    void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2)
{
  if (pt.Z != 0 || !m_ZFill) return;
  else if (pt == e1.Bot) pt.Z = e1.Bot.Z;
  else if (pt == e1.Top) pt.Z = e1.Top.Z;
  else if (pt == e2.Bot) pt.Z = e2.Bot.Z;
  else if (pt == e2.Top) pt.Z = e2.Top.Z;
  else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt);
}
//------------------------------------------------------------------------------
#endif

    void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
    {
        bool e1Contributing = ( e1->OutIdx >= 0 );
        bool e2Contributing = ( e2->OutIdx >= 0 );

#ifdef use_xyz
        SetZ(Pt, *e1, *e2);
#endif

#ifdef use_lines
        //if either edge is on an OPEN path ...
        if (e1->WindDelta == 0 || e2->WindDelta == 0)
        {
            //ignore subject-subject open path intersections UNLESS they
            //are both open paths, AND they are both 'contributing maximas' ...
            if (e1->WindDelta == 0 && e2->WindDelta == 0) return;

                //if intersecting a subj line with a subj poly ...
            else if (e1->PolyTyp == e2->PolyTyp &&
                     e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
            {
                if (e1->WindDelta == 0)
                {
                    if (e2Contributing)
                    {
                        AddOutPt(e1, Pt);
                        if (e1Contributing) e1->OutIdx = Unassigned;
                    }
                }
                else
                {
                    if (e1Contributing)
                    {
                        AddOutPt(e2, Pt);
                        if (e2Contributing) e2->OutIdx = Unassigned;
                    }
                }
            }
            else if (e1->PolyTyp != e2->PolyTyp)
            {
                //toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
                if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 &&
                    (m_ClipType != ctUnion || e2->WindCnt2 == 0))
                {
                    AddOutPt(e1, Pt);
                    if (e1Contributing) e1->OutIdx = Unassigned;
                }
                else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) &&
                         (m_ClipType != ctUnion || e1->WindCnt2 == 0))
                {
                    AddOutPt(e2, Pt);
                    if (e2Contributing) e2->OutIdx = Unassigned;
                }
            }
            return;
        }
#endif

        //update winding counts...
        //assumes that e1 will be to the Right of e2 ABOVE the intersection
        if ( e1->PolyTyp == e2->PolyTyp )
        {
            if ( IsEvenOddFillType( *e1) )
            {
                int oldE1WindCnt = e1->WindCnt;
                e1->WindCnt = e2->WindCnt;
                e2->WindCnt = oldE1WindCnt;
            } else
            {
                if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt;
                else e1->WindCnt += e2->WindDelta;
                if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt;
                else e2->WindCnt -= e1->WindDelta;
            }
        } else
        {
            if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta;
            else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0;
            if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta;
            else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0;
        }

        PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
        if (e1->PolyTyp == ptSubject)
        {
            e1FillType = m_SubjFillType;
            e1FillType2 = m_ClipFillType;
        } else
        {
            e1FillType = m_ClipFillType;
            e1FillType2 = m_SubjFillType;
        }
        if (e2->PolyTyp == ptSubject)
        {
            e2FillType = m_SubjFillType;
            e2FillType2 = m_ClipFillType;
        } else
        {
            e2FillType = m_ClipFillType;
            e2FillType2 = m_SubjFillType;
        }

        cInt e1Wc, e2Wc;
        switch (e1FillType)
        {
            case pftPositive: e1Wc = e1->WindCnt; break;
            case pftNegative: e1Wc = -e1->WindCnt; break;
            default: e1Wc = Abs(e1->WindCnt);
        }
        switch(e2FillType)
        {
            case pftPositive: e2Wc = e2->WindCnt; break;
            case pftNegative: e2Wc = -e2->WindCnt; break;
            default: e2Wc = Abs(e2->WindCnt);
        }

        if ( e1Contributing && e2Contributing )
        {
            if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
                (e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
            {
                AddLocalMaxPoly(e1, e2, Pt);
            }
            else
            {
                AddOutPt(e1, Pt);
                AddOutPt(e2, Pt);
                SwapSides( *e1 , *e2 );
                SwapPolyIndexes( *e1 , *e2 );
            }
        }
        else if ( e1Contributing )
        {
            if (e2Wc == 0 || e2Wc == 1)
            {
                AddOutPt(e1, Pt);
                SwapSides(*e1, *e2);
                SwapPolyIndexes(*e1, *e2);
            }
        }
        else if ( e2Contributing )
        {
            if (e1Wc == 0 || e1Wc == 1)
            {
                AddOutPt(e2, Pt);
                SwapSides(*e1, *e2);
                SwapPolyIndexes(*e1, *e2);
            }
        }
        else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1))
        {
            //neither edge is currently contributing ...

            cInt e1Wc2, e2Wc2;
            switch (e1FillType2)
            {
                case pftPositive: e1Wc2 = e1->WindCnt2; break;
                case pftNegative : e1Wc2 = -e1->WindCnt2; break;
                default: e1Wc2 = Abs(e1->WindCnt2);
            }
            switch (e2FillType2)
            {
                case pftPositive: e2Wc2 = e2->WindCnt2; break;
                case pftNegative: e2Wc2 = -e2->WindCnt2; break;
                default: e2Wc2 = Abs(e2->WindCnt2);
            }

            if (e1->PolyTyp != e2->PolyTyp)
            {
                AddLocalMinPoly(e1, e2, Pt);
            }
            else if (e1Wc == 1 && e2Wc == 1)
                switch( m_ClipType ) {
                    case ctIntersection:
                        if (e1Wc2 > 0 && e2Wc2 > 0)
                            AddLocalMinPoly(e1, e2, Pt);
                        break;
                    case ctUnion:
                        if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
                            AddLocalMinPoly(e1, e2, Pt);
                        break;
                    case ctDifference:
                        if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
                            ((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
                            AddLocalMinPoly(e1, e2, Pt);
                        break;
                    case ctXor:
                        AddLocalMinPoly(e1, e2, Pt);
                }
            else
                SwapSides( *e1, *e2 );
        }
    }
//------------------------------------------------------------------------------

    void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
    {
        TEdge *e2 = e->PrevInAEL;
        TEdge *eTmp = 0;
        while (e2)
        {
            if (e2->OutIdx >= 0 && e2->WindDelta != 0)
            {
                if (!eTmp) eTmp = e2;
                else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;
            }
            e2 = e2->PrevInAEL;
        }
        if (!eTmp)
        {
            outrec->FirstLeft = 0;
            outrec->IsHole = false;
        }
        else
        {
            outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx];
            outrec->IsHole = !outrec->FirstLeft->IsHole;
        }
    }
//------------------------------------------------------------------------------

    OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
    {
        //work out which polygon fragment has the correct hole state ...
        if (!outRec1->BottomPt)
            outRec1->BottomPt = GetBottomPt(outRec1->Pts);
        if (!outRec2->BottomPt)
            outRec2->BottomPt = GetBottomPt(outRec2->Pts);
        OutPt *OutPt1 = outRec1->BottomPt;
        OutPt *OutPt2 = outRec2->BottomPt;
        if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1;
        else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2;
        else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1;
        else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2;
        else if (OutPt1->Next == OutPt1) return outRec2;
        else if (OutPt2->Next == OutPt2) return outRec1;
        else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1;
        else return outRec2;
    }
//------------------------------------------------------------------------------

    bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
    {
        do
        {
            outRec1 = outRec1->FirstLeft;
            if (outRec1 == outRec2) return true;
        } while (outRec1);
        return false;
    }
//------------------------------------------------------------------------------

    OutRec* Clipper::GetOutRec(int Idx)
    {
        OutRec* outrec = m_PolyOuts[Idx];
        while (outrec != m_PolyOuts[outrec->Idx])
            outrec = m_PolyOuts[outrec->Idx];
        return outrec;
    }
//------------------------------------------------------------------------------

    void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
    {
        //get the start and ends of both output polygons ...
        OutRec *outRec1 = m_PolyOuts[e1->OutIdx];
        OutRec *outRec2 = m_PolyOuts[e2->OutIdx];

        OutRec *holeStateRec;
        if (OutRec1RightOfOutRec2(outRec1, outRec2))
            holeStateRec = outRec2;
        else if (OutRec1RightOfOutRec2(outRec2, outRec1))
            holeStateRec = outRec1;
        else
            holeStateRec = GetLowermostRec(outRec1, outRec2);

        //get the start and ends of both output polygons and
        //join e2 poly onto e1 poly and delete pointers to e2 ...

        OutPt* p1_lft = outRec1->Pts;
        OutPt* p1_rt = p1_lft->Prev;
        OutPt* p2_lft = outRec2->Pts;
        OutPt* p2_rt = p2_lft->Prev;

        //join e2 poly onto e1 poly and delete pointers to e2 ...
        if(  e1->Side == esLeft )
        {
            if(  e2->Side == esLeft )
            {
                //z y x a b c
                ReversePolyPtLinks(p2_lft);
                p2_lft->Next = p1_lft;
                p1_lft->Prev = p2_lft;
                p1_rt->Next = p2_rt;
                p2_rt->Prev = p1_rt;
                outRec1->Pts = p2_rt;
            } else
            {
                //x y z a b c
                p2_rt->Next = p1_lft;
                p1_lft->Prev = p2_rt;
                p2_lft->Prev = p1_rt;
                p1_rt->Next = p2_lft;
                outRec1->Pts = p2_lft;
            }
        } else
        {
            if(  e2->Side == esRight )
            {
                //a b c z y x
                ReversePolyPtLinks(p2_lft);
                p1_rt->Next = p2_rt;
                p2_rt->Prev = p1_rt;
                p2_lft->Next = p1_lft;
                p1_lft->Prev = p2_lft;
            } else
            {
                //a b c x y z
                p1_rt->Next = p2_lft;
                p2_lft->Prev = p1_rt;
                p1_lft->Prev = p2_rt;
                p2_rt->Next = p1_lft;
            }
        }

        outRec1->BottomPt = 0;
        if (holeStateRec == outRec2)
        {
            if (outRec2->FirstLeft != outRec1)
                outRec1->FirstLeft = outRec2->FirstLeft;
            outRec1->IsHole = outRec2->IsHole;
        }
        outRec2->Pts = 0;
        outRec2->BottomPt = 0;
        outRec2->FirstLeft = outRec1;

        int OKIdx = e1->OutIdx;
        int ObsoleteIdx = e2->OutIdx;

        e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly
        e2->OutIdx = Unassigned;

        TEdge* e = m_ActiveEdges;
        while( e )
        {
            if( e->OutIdx == ObsoleteIdx )
            {
                e->OutIdx = OKIdx;
                e->Side = e1->Side;
                break;
            }
            e = e->NextInAEL;
        }

        outRec2->Idx = outRec1->Idx;
    }
//------------------------------------------------------------------------------

    OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
    {
        if(  e->OutIdx < 0 )
        {
            OutRec *outRec = CreateOutRec();
            outRec->IsOpen = (e->WindDelta == 0);
            OutPt* newOp = new OutPt;
            outRec->Pts = newOp;
            newOp->Idx = outRec->Idx;
            newOp->Pt = pt;
            newOp->Next = newOp;
            newOp->Prev = newOp;
            if (!outRec->IsOpen)
                SetHoleState(e, outRec);
            e->OutIdx = outRec->Idx;
            return newOp;
        } else
        {
            OutRec *outRec = m_PolyOuts[e->OutIdx];
            //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'
            OutPt* op = outRec->Pts;

            bool ToFront = (e->Side == esLeft);
            if (ToFront && (pt == op->Pt)) return op;
          
Download .txt
gitextract_zxhxyjoe/

├── README.md
├── app/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── assets/
│           │   ├── ch_PP-OCRv3_det.param
│           │   ├── ch_PP-OCRv3_rec.param
│           │   ├── cls-sim-op.param
│           │   ├── det-sim-op.param
│           │   ├── paddleocr_keys.txt
│           │   ├── pdocrv2.0_det-op.param
│           │   ├── pdocrv2.0_rec-op.param
│           │   └── rec-sim-op.param
│           ├── java/
│           │   └── com/
│           │       └── tencent/
│           │           └── paddleocrncnn/
│           │               ├── MainActivity.java
│           │               └── PaddleOCRNcnn.java
│           ├── jni/
│           │   ├── CMakeLists.txt
│           │   ├── clipper.cpp
│           │   ├── clipper.hpp
│           │   ├── common.cpp
│           │   ├── common.h
│           │   └── paddleocr_ncnn.cpp
│           └── res/
│               ├── layout/
│               │   └── main.xml
│               ├── values/
│               │   └── strings.xml
│               └── xml/
│                   └── file_paths.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
Download .txt
SYMBOL INDEX (180 symbols across 7 files)

FILE: app/src/main/java/com/tencent/paddleocrncnn/MainActivity.java
  class MainActivity (line 43) | public class MainActivity extends Activity
    method onRequestPermissionsResult (line 54) | @Override
    method onCreate (line 67) | @Override
    method requestPermission (line 123) | private void requestPermission() {
    method requestCamera (line 130) | private void requestCamera() {
    method showObjects (line 157) | private void showObjects(PaddleOCRNcnn.Obj[] objects)
    method onActivityResult (line 236) | @Override
    method decodeUri (line 271) | private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException

FILE: app/src/main/java/com/tencent/paddleocrncnn/PaddleOCRNcnn.java
  class PaddleOCRNcnn (line 20) | public class PaddleOCRNcnn
    method Init (line 22) | public native boolean Init(AssetManager mgr);
    class Obj (line 24) | public class Obj
    method Detect (line 38) | public native Obj[] Detect(Bitmap bitmap, boolean use_gpu);

FILE: app/src/main/jni/clipper.cpp
  type ClipperLib (line 51) | namespace ClipperLib {
    type Direction (line 57) | enum Direction { dRightToLeft, dLeftToRight }
    type TEdge (line 66) | struct TEdge {
    type IntersectNode (line 86) | struct IntersectNode {
    type LocalMinimum (line 92) | struct LocalMinimum {
    type OutPt (line 98) | struct OutPt
    type OutRec (line 102) | struct OutRec {
    type OutPt (line 112) | struct OutPt {
    type Join (line 119) | struct Join {
    type LocMinSorter (line 125) | struct LocMinSorter
    function cInt (line 136) | inline cInt Round(double val)
    function cInt (line 143) | inline cInt Abs(cInt val)
    function PolyNode (line 161) | PolyNode* PolyTree::GetFirst() const
    function PolyNode (line 202) | PolyNode* PolyNode::GetNext() const
    function PolyNode (line 211) | PolyNode* PolyNode::GetNextSiblingUp() const
    class Int128 (line 251) | class Int128
      method Int128 (line 257) | Int128(long64 _lo = 0)
      method Int128 (line 264) | Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
      method Int128 (line 266) | Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
      method Int128 (line 268) | Int128& operator = (const long64 &val)
      method Int128 (line 303) | Int128& operator += (const Int128 &rhs)
      method Int128 (line 311) | Int128 operator + (const Int128 &rhs) const
      method Int128 (line 318) | Int128& operator -= (const Int128 &rhs)
      method Int128 (line 324) | Int128 operator - (const Int128 &rhs) const
      method Int128 (line 331) | Int128 operator-() const //unary negation
    function Int128 (line 354) | Int128 Int128Mul (long64 lhs, long64 rhs)
      method Int128 (line 257) | Int128(long64 _lo = 0)
      method Int128 (line 264) | Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
      method Int128 (line 266) | Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
      method Int128 (line 268) | Int128& operator = (const long64 &val)
      method Int128 (line 303) | Int128& operator += (const Int128 &rhs)
      method Int128 (line 311) | Int128 operator + (const Int128 &rhs) const
      method Int128 (line 318) | Int128& operator -= (const Int128 &rhs)
      method Int128 (line 324) | Int128 operator - (const Int128 &rhs) const
      method Int128 (line 331) | Int128 operator-() const //unary negation
    function Orientation (line 385) | bool Orientation(const Path &poly)
    function Area (line 391) | double Area(const Path &poly)
    function Area (line 406) | double Area(const OutPt *op)
    function Area (line 419) | double Area(const OutRec &outRec)
    function PointIsVertex (line 425) | bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
    function PointInPolygon (line 440) | int PointInPolygon(const IntPoint &pt, const Path &path)
    function PointInPolygon (line 484) | int PointInPolygon (const IntPoint &pt, OutPt *op)
    function Poly2ContainsPoly1 (line 526) | bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
    function SlopesEqual (line 541) | bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Ra...
    function SlopesEqual (line 554) | bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
    function SlopesEqual (line 566) | bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
    function IsHorizontal (line 578) | inline bool IsHorizontal(TEdge &e)
    function GetDx (line 584) | inline double GetDx(const IntPoint pt1, const IntPoint pt2)
    function SetDx (line 591) | inline void SetDx(TEdge &e)
    function SwapSides (line 599) | inline void SwapSides(TEdge &Edge1, TEdge &Edge2)
    function SwapPolyIndexes (line 607) | inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
    function cInt (line 615) | inline cInt TopX(TEdge &edge, const cInt currentY)
    function IntersectPoint (line 622) | void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
    function ReversePolyPtLinks (line 692) | void ReversePolyPtLinks(OutPt *pp)
    function DisposeOutPts (line 706) | void DisposeOutPts(OutPt*& pp)
    function InitEdge (line 719) | inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPo...
    function InitEdge2 (line 729) | void InitEdge2(TEdge& e, PolyType Pt)
    function TEdge (line 745) | TEdge* RemoveEdge(TEdge* e)
    function ReverseHorizontal (line 756) | inline void ReverseHorizontal(TEdge &e)
    function SwapPoints (line 768) | void SwapPoints(IntPoint &pt1, IntPoint &pt2)
    function GetOverlapSegment (line 776) | bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
    function FirstIsBottomPt (line 798) | bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
    function OutPt (line 822) | OutPt* GetBottomPt(OutPt *pp)
    function Pt2IsBetweenPt1AndPt3 (line 860) | bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1,
    function HorzSegmentsOverlap (line 872) | bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
    function RangeTest (line 896) | void RangeTest(const IntPoint& Pt, bool& useFullRange)
    function TEdge (line 911) | TEdge* FindNextLocMin(TEdge* E)
    function TEdge (line 928) | TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
    function IntRect (line 1295) | IntRect ClipperBase::GetBounds()
    function OutRec (line 1380) | OutRec* ClipperBase::CreateOutRec()
    function OutPt (line 1842) | OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
    function OutRec (line 2328) | OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
    function OutRec1RightOfOutRec2 (line 2348) | bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
    function OutRec (line 2359) | OutRec* Clipper::GetOutRec(int Idx)
    function OutPt (line 2464) | OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
    function OutPt (line 2503) | OutPt* Clipper::GetLastOutPt(TEdge *e)
    function IsMinima (line 2521) | inline bool IsMinima(TEdge *e)
    function IsMaxima (line 2527) | inline bool IsMaxima(TEdge *e, const cInt Y)
    function IsIntermediate (line 2533) | inline bool IsIntermediate(TEdge *e, const cInt Y)
    function TEdge (line 2539) | TEdge *GetMaximaPair(TEdge *e)
    function TEdge (line 2549) | TEdge *GetMaximaPairEx(TEdge *e)
    function TEdge (line 2605) | TEdge* GetNextInAEL(TEdge *e, Direction dir)
    function GetHorzDirection (line 2611) | void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cIn...
    function IntersectListSort (line 2923) | bool IntersectListSort(IntersectNode* node1, IntersectNode* node2)
    function EdgesAdjacent (line 2929) | inline bool EdgesAdjacent(const IntersectNode &inode)
    function PointCount (line 3186) | int PointCount(OutPt *Pts)
    function SwapIntersectNodes (line 3267) | void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2)
    function E2InsertsBeforeE1 (line 3280) | inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
    function GetOverlap (line 3292) | bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cIn...
    function UpdateOutPtIdxs (line 3309) | inline void UpdateOutPtIdxs(OutRec& outrec)
    function OutPt (line 3350) | OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
    function JoinHorz (line 3373) | bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
    function OutRec (line 3619) | static OutRec* ParseFirstLeft(OutRec* FirstLeft)
    function DoublePoint (line 3771) | DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
    function ReversePath (line 4285) | void ReversePath(Path& p)
    function ReversePaths (line 4291) | void ReversePaths(Paths& p)
    function SimplifyPolygon (line 4298) | void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillTy...
    function SimplifyPolygons (line 4307) | void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFil...
    function SimplifyPolygons (line 4316) | void SimplifyPolygons(Paths &polys, PolyFillType fillType)
    function DistanceSqrd (line 4322) | inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2)
    function DistanceFromLineSqrd (line 4330) | double DistanceFromLineSqrd(
    function SlopesNearCollinear (line 4347) | bool SlopesNearCollinear(const IntPoint& pt1,
    function PointsAreClose (line 4374) | bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
    function OutPt (line 4382) | OutPt* ExcludeOp(OutPt* op)
    function CleanPolygon (line 4392) | void CleanPolygon(const Path& in_poly, Path& out_poly, double distance)
    function CleanPolygon (line 4452) | void CleanPolygon(Path& poly, double distance)
    function CleanPolygons (line 4458) | void CleanPolygons(const Paths& in_polys, Paths& out_polys, double dis...
    function CleanPolygons (line 4466) | void CleanPolygons(Paths& polys, double distance)
    function Minkowski (line 4472) | void Minkowski(const Path& poly, const Path& path,
    function MinkowskiSum (line 4516) | void MinkowskiSum(const Path& pattern, const Path& path, Paths& soluti...
    function TranslatePath (line 4525) | void TranslatePath(const Path& input, Path& output, const IntPoint delta)
    function MinkowskiSum (line 4534) | void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solu...
    function MinkowskiDiff (line 4553) | void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution)
    type NodeType (line 4562) | enum NodeType {ntAny, ntOpen, ntClosed}
    function AddPolyNodeToPaths (line 4564) | void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, P...
    function PolyTreeToPaths (line 4577) | void PolyTreeToPaths(const PolyTree& polytree, Paths& paths)
    function ClosedPathsFromPolyTree (line 4585) | void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths)
    function OpenPathsFromPolyTree (line 4593) | void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths)

FILE: app/src/main/jni/clipper.hpp
  type ClipperLib (line 62) | namespace ClipperLib {
    type ClipType (line 64) | enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }
    type PolyType (line 65) | enum PolyType { ptSubject, ptClip }
    type PolyFillType (line 70) | enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }
    type IntPoint (line 85) | struct IntPoint {
      method IntPoint (line 90) | IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {}
      method IntPoint (line 92) | IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {}
    function Path (line 109) | inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_bac...
    function Paths (line 110) | inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_bac...
    type DoublePoint (line 116) | struct DoublePoint
      method DoublePoint (line 120) | DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
      method DoublePoint (line 121) | DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
    type InitOptions (line 129) | enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPrese...
    type JoinType (line 130) | enum JoinType {jtSquare, jtRound, jtMiter}
    type EndType (line 131) | enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare,...
    class PolyNode (line 133) | class PolyNode
    class PolyNode (line 136) | class PolyNode
    class PolyTree (line 160) | class PolyTree: public PolyNode
    type IntRect (line 197) | struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }
    type EdgeSide (line 200) | enum EdgeSide { esLeft = 1, esRight = 2}
    type TEdge (line 203) | struct TEdge
    type IntersectNode (line 204) | struct IntersectNode
    type LocalMinimum (line 205) | struct LocalMinimum
    type OutPt (line 206) | struct OutPt
    type OutRec (line 207) | struct OutRec
    type Join (line 208) | struct Join
    class ClipperBase (line 220) | class ClipperBase
      method PreserveCollinear (line 229) | bool PreserveCollinear() {return m_PreserveCollinear;}
      method PreserveCollinear (line 230) | void PreserveCollinear(bool value) {m_PreserveCollinear = value;}
    class Clipper (line 263) | class Clipper : public virtual ClipperBase
      method ReverseSolution (line 281) | bool ReverseSolution() { return m_ReverseOutput; }
      method ReverseSolution (line 282) | void ReverseSolution(bool value) {m_ReverseOutput = value;}
      method StrictlySimple (line 283) | bool StrictlySimple() {return m_StrictSimple;}
      method StrictlySimple (line 284) | void StrictlySimple(bool value) {m_StrictSimple = value;}
    class ClipperOffset (line 360) | class ClipperOffset
    class clipperException (line 391) | class clipperException : public std::exception
      method clipperException (line 394) | clipperException(const char* description): m_descr(description) {}

FILE: app/src/main/jni/common.cpp
  function cvPointCompare (line 4) | bool cvPointCompare(const cv::Point& a, const cv::Point& b) {
  function compareBoxWidth (line 7) | bool compareBoxWidth(const TextBox &a, const TextBox& b)
  function getMinBoxes (line 12) | std::vector<cv::Point> getMinBoxes(const std::vector<cv::Point>& inVec, ...
  function boxScoreFast (line 60) | float boxScoreFast(const cv::Mat & inMat, const std::vector<cv::Point> &...
  function unClip (line 93) | std::vector<cv::Point> unClip(const std::vector<cv::Point> & inBox, floa...
  function getRotateCropImage (line 120) | cv::Mat getRotateCropImage(const cv::Mat& src, std::vector<cv::Point> bo...
  function getPartImages (line 175) | std::vector<cv::Mat> getPartImages(const cv::Mat& src, std::vector<TextB...
  function matRotateClockWise180 (line 190) | cv::Mat matRotateClockWise180(cv::Mat src) {
  function makePadding (line 196) | cv::Mat makePadding(cv::Mat& src, const int padding) {

FILE: app/src/main/jni/common.h
  type TextBox (line 7) | struct TextBox {
  type TextLine (line 12) | struct TextLine {
  type Angle (line 17) | struct Angle {

FILE: app/src/main/jni/paddleocr_ncnn.cpp
  function findRsBoxes (line 58) | std::vector<TextBox> findRsBoxes(const cv::Mat& fMapMat, const cv::Mat& ...
  function getTextBoxes (line 99) | std::vector<TextBox> getTextBoxes(const cv::Mat & src, float boxScoreThr...
  function argmax (line 163) | inline static size_t argmax(ForwardIterator first, ForwardIterator last) {
  function TextLine (line 167) | TextLine scoreToTextLine(const std::vector<float>& outputData, int h, in...
  function TextLine (line 192) | TextLine getTextLine(const cv::Mat & src)
  function getTextLines (line 217) | std::vector<TextLine> getTextLines(std::vector<cv::Mat> & partImg) {
  function JNIEXPORT (line 244) | JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
  function JNIEXPORT (line 253) | JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
  function JNIEXPORT (line 261) | JNIEXPORT jboolean JNICALL Java_com_tencent_paddleocrncnn_PaddleOCRNcnn_...
  function JNIEXPORT (line 352) | JNIEXPORT jobjectArray JNICALL Java_com_tencent_paddleocrncnn_PaddleOCRN...
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (356K chars).
[
  {
    "path": "README.md",
    "chars": 1809,
    "preview": "# ncnn_paddleocr\nThis is a sample paddleocr ncnn android project, it depends on ncnn library and opencv  \nhttps://github"
  },
  {
    "path": "app/build.gradle",
    "chars": 589,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"29.0.2\"\n\n    defaultC"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 1184,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      packag"
  },
  {
    "path": "app/src/main/assets/ch_PP-OCRv3_det.param",
    "chars": 18203,
    "preview": "7767517\n153 185\nInput                    x                        0 1 input\nConvolution              Conv_0             "
  },
  {
    "path": "app/src/main/assets/ch_PP-OCRv3_rec.param",
    "chars": 13790,
    "preview": "7767517\n116 127\nInput                    input                    0 1 input\nConvolution              Conv_0             "
  },
  {
    "path": "app/src/main/assets/cls-sim-op.param",
    "chars": 11188,
    "preview": "7767517\n135 151\nInput                    input                    0 1 input\nConvolution              Conv_0             "
  },
  {
    "path": "app/src/main/assets/det-sim-op.param",
    "chars": 9938,
    "preview": "7767517\n115 131\nInput                    input                    0 1 input0\nConvolution              Conv_0            "
  },
  {
    "path": "app/src/main/assets/paddleocr_keys.txt",
    "chars": 13245,
    "preview": "'\n疗\n绚\n诚\n娇\n溜\n题\n贿\n者\n廖\n更\n纳\n加\n奉\n公\n一\n就\n汴\n计\n与\n路\n房\n原\n妇\n2\n0\n8\n-\n7\n其\n>\n:\n]\n,\n,\n骑\n刈\n全\n消\n昏\n傈\n安\n久\n钟\n嗅\n不\n影\n处\n驽\n蜿\n资\n关\n椤\n地\n瘸\n专\n问\n忖\n票\n嫉\n"
  },
  {
    "path": "app/src/main/assets/pdocrv2.0_det-op.param",
    "chars": 9938,
    "preview": "7767517\n115 131\nInput                    input                    0 1 input0\nConvolution              Conv_0            "
  },
  {
    "path": "app/src/main/assets/pdocrv2.0_rec-op.param",
    "chars": 6135,
    "preview": "7767517\n75 77\nInput                    input                    0 1 input\nConvolution              Conv_0               "
  },
  {
    "path": "app/src/main/assets/rec-sim-op.param",
    "chars": 11451,
    "preview": "7767517\n138 154\nInput                    input                    0 1 input\nConvolution              Conv_0             "
  },
  {
    "path": "app/src/main/java/com/tencent/paddleocrncnn/MainActivity.java",
    "chars": 12406,
    "preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2020 THL A29 Li"
  },
  {
    "path": "app/src/main/java/com/tencent/paddleocrncnn/PaddleOCRNcnn.java",
    "chars": 1322,
    "preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2020 THL A29 Li"
  },
  {
    "path": "app/src/main/jni/CMakeLists.txt",
    "chars": 454,
    "preview": "project(paddleocrncnn)\n\ncmake_minimum_required(VERSION 3.4.1)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-an"
  },
  {
    "path": "app/src/main/jni/clipper.cpp",
    "chars": 167441,
    "preview": "/*******************************************************************************\n*                                      "
  },
  {
    "path": "app/src/main/jni/clipper.hpp",
    "chars": 16486,
    "preview": "/*******************************************************************************\n*                                      "
  },
  {
    "path": "app/src/main/jni/common.cpp",
    "chars": 6462,
    "preview": "#include \"common.h\"\n#include <jni.h>\n#include <android/log.h>\nbool cvPointCompare(const cv::Point& a, const cv::Point& b"
  },
  {
    "path": "app/src/main/jni/common.h",
    "chars": 918,
    "preview": "#ifndef __COMMON_H_\n#define __COMMON_H_\n#include <opencv2/opencv.hpp>\n#include <vector>\n#include \"clipper.hpp\"\n#include "
  },
  {
    "path": "app/src/main/jni/paddleocr_ncnn.cpp",
    "chars": 13358,
    "preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2020 THL A29 Li"
  },
  {
    "path": "app/src/main/res/layout/main.xml",
    "chars": 1276,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 116,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">paddleocr_ncnn</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/xml/file_paths.xml",
    "chars": 177,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <external-"
  },
  {
    "path": "build.gradle",
    "chars": 335,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n    re"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 232,
    "preview": "#Sun Aug 25 10:34:48 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradlew",
    "chars": 5296,
    "preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up"
  },
  {
    "path": "gradlew.bat",
    "chars": 2176,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "local.properties",
    "chars": 325,
    "preview": "## This file must *NOT* be checked into Version Control Systems,\n# as it contains information specific to your local con"
  },
  {
    "path": "settings.gradle",
    "chars": 15,
    "preview": "include ':app'\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the FeiGeChuanShu/ncnn_paddleocr GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (318.6 KB), approximately 107.4k tokens, and a symbol index with 180 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!