Compare commits

...

386 Commits
onereq ... main

Author SHA1 Message Date
Matthew dcd1d20a75 先移除fps的设置 2 days ago
Matthew f9b79e67fd Update version to 1.3.196
Based Core Version to 1.4.106
5 days ago
Matthew 024d7f73b8 Update MpMaster version to 1.1.36 5 days ago
Matthew 476fa0ab7c 优化代码 5 days ago
Matthew 9ea9043a0e 优化代码 5 days ago
Matthew 8acd884797 改成常量 5 days ago
Matthew bbcd2691ed 增加flag 6 days ago
Matthew c65ffab9dd 加注释 6 days ago
Matthew 99d08c30ef 增加异常捕获 6 days ago
Matthew a38e3801ae 对于旧版本,直接注册重启设备的延迟广播来保活 6 days ago
Matthew a9ac0743f7 优化服务的返回值 6 days ago
Matthew a7c4356d93 移除不需要的代码和功能 6 days ago
Matthew 2baf96fe67 移除不需要的代码和功能 6 days ago
Matthew 913747e6c3 Update version to 1.3.195
Based Core Version to 1.4.105
6 days ago
Matthew 0b1aa8a13a Update version to 1.3.194
Based Core Version to 1.4.104
1 week ago
Matthew b5aec7ae17 增加清除缓存的拍照计划功能 1 week ago
Matthew 6f3cae9d02 根据新的接口调整实现 1 week ago
Matthew 7a67a142cb Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 1 week ago
XI.CHEN 0a6850d92b 调整名字 1 week ago
Matthew 42dab55bc4 Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 1 week ago
Matthew 662d3307b0 Update version to 1.3.193
Based Core Version to 1.4.103
1 week ago
XI.CHEN 2b9c1feae5 增加查询当日流量 1 week ago
Matthew aa04fca845 Update version to 1.3.192
Based Core Version to 1.4.101
1 week ago
Matthew a72118a5a6 优化回车换行的处理 1 week ago
Matthew d50b21d0d6 Update version to 1.3.191
Based Core Version to 1.4.101
1 week ago
Matthew 6255fa932c 增加最小fps控制 1 week ago
Matthew 8aec5f30ef 处理资源未释放的问题 2 weeks ago
Matthew c23f30ce71 增加山西智洋主站的规约实现 2 weeks ago
Matthew 118ffdc638 Update version to 1.3.190
Based Core Version to 1.4.100
2 weeks ago
Matthew 058e4b2f46 增加几个报文的手动触发 2 weeks ago
Matthew 48d61baf6f 调整配置目录结构 2 weeks ago
Matthew 9ff07b8c12 Update version to 1.3.189
Based Core Version to 1.4.99
2 weeks ago
Matthew 69958ba1d2 对于需要曝光补偿的场景,设置更明亮模式 2 weeks ago
Matthew 3979e03882 预览request上设置算法 2 weeks ago
Matthew b96fe6bbfd Update version to 1.3.188
Based Core Version to 1.4.98
3 weeks ago
Matthew 94edf1324f Update version to 1.3.187
Based Core Version to 1.4.97
3 weeks ago
Matthew 18efb1e439 错误处理 3 weeks ago
Matthew b2a1a5cde3 Update MpRes version to 1.0.14 3 weeks ago
Matthew cdf664b448 更新配置 3 weeks ago
Matthew e549126563 Update MpRes version to 1.0.13 3 weeks ago
Matthew 1322ddd8b2 更改默认配置 3 weeks ago
Matthew 139a6a5fde Update MpMaster version to 1.1.35 3 weeks ago
Matthew 9721eced21 网络信号信息优化 3 weeks ago
Matthew b425713f63 Update version to 1.3.186
Based Core Version to 1.4.96
3 weeks ago
Matthew 7e3ff1b741 Update version to 1.3.185
Based Core Version to 1.4.95
3 weeks ago
Matthew 284f61a86e Update version to 1.3.184
Based Core Version to 1.4.95
3 weeks ago
Matthew aa4ca70d07 优化脚本和日志 3 weeks ago
Matthew 6e1655813d Update version to 1.3.183
Based Core Version to 1.4.94
3 weeks ago
Matthew 8468978f19 以太网启用之后,多等一段时间,避免未生效 3 weeks ago
Matthew ce2b36422c Update version to 1.3.182
Based Core Version to 1.4.94
3 weeks ago
Matthew 38bfd44bcd 优化脚本,避免938下面ip丢失问题
更好的方法是固件优化
3 weeks ago
Matthew 5ac7838839 优化脚本,网卡启用之后,先等待1s 3 weeks ago
Matthew 86b7e63849 Update version to 1.3.181
Based Core Version to 1.4.94
3 weeks ago
Matthew adb24119ef 优化以太网网络设置 3 weeks ago
Matthew 436058fefa Update version to 1.3.180
Based Core Version to 1.4.94
3 weeks ago
Matthew 7a6497ee40 调整函数的使用 3 weeks ago
Matthew 03110ac486 优化以太网处理 3 weeks ago
Matthew 8612c66ed3 优化脚本 3 weeks ago
Matthew 60989b5c40 优化信号获取的实现 4 weeks ago
Matthew 4df8d72c42 调整移动信号的获取 4 weeks ago
Matthew f3e5cda1da Update version to 1.3.179
Based Core Version to 1.4.93
4 weeks ago
Matthew 6d68a33224 优化脚本 4 weeks ago
Matthew 9d0f93b6ff Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 4 weeks ago
Matthew 789547b503 调整以太网络的设置 4 weeks ago
Matthew 514fc054a7 增加函数 4 weeks ago
XI.CHEN afc69b9dff Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 4 weeks ago
XI.CHEN d29fb0280c 修复微拍网络拍照显示网络不存在问题 4 weeks ago
Matthew eca28cd6f7 Update version to 1.3.178
Based Core Version to 1.4.93
4 weeks ago
Matthew 9efab780cf Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 4 weeks ago
Matthew c60587661b 修复bug 4 weeks ago
liuguijing 1b40738b71 修复微拍副机拍照缺少路由的bug 4 weeks ago
Matthew 8bff5f0741 获取信号强度并存储 4 weeks ago
Matthew 3c58e63c6a Update MpRes version to 1.0.12 4 weeks ago
Matthew 450556375e 根据全景平台调整packet size 4 weeks ago
Matthew 4cb359d0fd 增加河南统一 4 weeks ago
Matthew a39614c581 调整规约
65290名称改成河南全景 65285增加为河南统一
4 weeks ago
XI.CHEN 8c702f86c6 Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 4 weeks ago
XI.CHEN 81d4cd700c vendorctrl保护 4 weeks ago
Matthew 15873ca510 Update version to 1.3.177
Based Core Version to 1.4.92
4 weeks ago
Matthew f06a7dfcff Update MpMaster version to 1.1.34 4 weeks ago
XI.CHEN 1fbb9ffe51 Revert "网络拍照在子类构造函数中调用updatetime"
This reverts commit 1772027e9e.
4 weeks ago
XI.CHEN 1772027e9e 网络拍照在子类构造函数中调用updatetime 4 weeks ago
XI.CHEN 8ff8a4bb1e 移除updatetime,云台视频流使用云台线程控制 4 weeks ago
XI.CHEN c071d8ec71 云台短视频录制 4 weeks ago
XI.CHEN e47acced9b 修复编译错误 4 weeks ago
XI.CHEN 4bc9005ebb 云台拍摄短视频、推流网络处理 4 weeks ago
XI.CHEN 5eb8e630c6 云台问题修复 4 weeks ago
Matthew 02e66332ea 优先用大写的名字 4 weeks ago
XI.CHEN bd3451f47c Merge branch 'main' of http://61.169.135.146:41230/xymp/TermApp 4 weeks ago
XI.CHEN 812688ae68 云台ip地址设置问题 4 weeks ago
Matthew 5de3b6e73e Update version to 1.3.176
Based Core Version to 1.4.92
4 weeks ago
Matthew c34a649fa5 允许和运维同时启动mpres。并增加异常处理 4 weeks ago
Matthew cf557a599a Update MpMaster version to 1.1.33 4 weeks ago
Matthew fd15553e70 通过MpRes来初始化配置 4 weeks ago
Matthew deb8b06820 Update MpRes version to 1.0.11 4 weeks ago
Matthew 740dc120f6 增加异常处理 4 weeks ago
Matthew f66955ba99 延迟操作 4 weeks ago
Matthew fed87bc421 主动退出 4 weeks ago
Matthew 3bec3c924b 加日志 4 weeks ago
Matthew 0d97a04da0 MpApp和MpMaster各自初始化 4 weeks ago
Matthew 0a88e9b918 初始化MpAPP和MpMaster 4 weeks ago
Matthew e5fd96efce 修复路径错误 4 weeks ago
Matthew 621bbb9c78 Update MpMaster version to 1.1.32 1 month ago
Matthew c7351b8000 改为2分钟之后再发送广播 1 month ago
Matthew d27321974f 显式指定参数值 1 month ago
Matthew 75864122c5 增加日志 1 month ago
Matthew 4eb14e755c 增加一种保活机制
心跳时设置一个系统服务延迟启动运维app的闹钟,并在下一次心跳时重置闹钟时间。
1 month ago
Matthew a22f41d537 增加日志 1 month ago
Matthew a58544eab1 Update version to 1.3.175
Based Core Version to 1.4.92
1 month ago
Matthew ebf8312f6f 移除调试日志 1 month ago
Matthew 46ec0a4f39 修复电压获取的错误处理 1 month ago
Matthew 189ebe3f41 Update version to 1.3.174
Based Core Version to 1.4.91
1 month ago
Matthew ba42b72744 优化938网络的处理 1 month ago
Matthew 92ce03d2e8 优化代码 1 month ago
Matthew 553bae38d9 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
Matthew d3b493efbc 编译条件写反 1 month ago
Matthew 90df33d1f7 调试时全部打印 1 month ago
liuguijing 38edbefcda 修复短信带su的时候,部分命令不执行的bug,只要短信中出现su,就切换到su模式 1 month ago
liuguijing 707aa9bd94 修复短信带su的时候,部分命令不执行的bug 1 month ago
Matthew 6239916828 Update version to 1.3.173
Based Core Version to 1.4.91
1 month ago
Matthew 3f4531ecd6 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
liuguijing 5945fc1d1c 修复短信带su的时候,部分命令不执行的bug 1 month ago
Matthew 0f54876da8 通过命令行的方式重启系统 1 month ago
Matthew f433903745 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
Matthew f216640381 统一日志函数,方便问题排查 1 month ago
Matthew afae4794d3 优化网络电控 1 month ago
Matthew d96f337162 优化权限 1 month ago
liuguijing ba500120b4 修改运维删除文件时 文件夹不删除的问题 1 month ago
Matthew 6b8e477ed1 Update version to 1.3.172
Based Core Version to 1.4.90
1 month ago
Matthew f7ae9d42d2 Update MpRes version to 1.0.10 1 month ago
Matthew 31d65ea586 使用SN作为CMDID 1 month ago
Matthew 911a39a22f 把序列号传给MpRes 1 month ago
Matthew 1f07b07004 Update version to 1.3.171
Based Core Version to 1.4.90
1 month ago
Matthew 6bc8849d3c N938需要设置ip和路由 1 month ago
Matthew c67bebed88 优化云台相关的代码 1 month ago
Matthew f7912c8882 Update MpRes version to 1.0.9 1 month ago
Matthew 35b31577b2 更新拍照时间表 1 month ago
Matthew f8e627abc5 Update version to 1.3.170
Based Core Version to 1.4.90
1 month ago
Matthew 92412cf7d7 修复编译错误 1 month ago
Matthew 4222c6ff8a Update MpRes version to 1.0.8 1 month ago
Matthew 2bba3867e9 更新默认配置 1 month ago
Matthew 5df43d28d6 Update MpRes version to 1.0.7
HeNan 2024
1 month ago
Matthew 724db375ca Update MpMaster version to 1.1.31 1 month ago
Matthew 2b416c3f0d Update version to 1.3.169
Based Core Version to 1.4.90
1 month ago
Matthew 713f69048f Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
Matthew c85a5b9371 增加新的重启方式 1 month ago
Matthew 031dc97548 增加新的重启方式 1 month ago
liuguijing 456268c682 默认切换到sh,收到su的时候切换到su 1 month ago
Matthew cc55b5aa4d Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
liuguijing 7558b79c5e 删除之前测试的日志
删除MpMaster中的读取电压的代码
1 month ago
liuguijing 0d2090153f 修复短信adb命令执行的bug 1 month ago
liuguijing 024cca3104 测试getInt锁住的问题 1 month ago
Matthew be9f65d3a3 Update version to 1.3.168
Based Core Version to 1.4.89
1 month ago
Matthew 792a694f66 移除这个调用,直接关电,避免系统卡死 1 month ago
Matthew b916e63a00 修复命令错误以及优化判断规则 1 month ago
Matthew eb5af62ad3 换一种命令 1 month ago
Matthew 67479e0acc Update version to 1.3.167
Based Core Version to 1.4.89
1 month ago
Matthew 05b9a7a5e5 网络可用时直接设置路由 1 month ago
Matthew c1a06203e3 Update version to 1.3.166
Based Core Version to 1.4.89
1 month ago
Matthew 02fc11fc22 修正错误的判断条件
Based Core Version to 1.4.89
1 month ago
Matthew 026bd1a022 Update version to 1.3.165
Based Core Version to 1.4.89
1 month ago
Matthew 200131ec67 当网络异常时,通过直接关电来关闭网络 1 month ago
Matthew 0b08c08d81 Update version to 1.3.164
Based Core Version to 1.4.89
1 month ago
Matthew 75f0fdc73c 增加日志 1 month ago
Matthew a7f4866ac8 Update version to 1.3.163
Based Core Version to 1.4.89
1 month ago
Matthew bc823212aa Update MpMaster version to 1.1.30 1 month ago
Matthew 7e23d09814 修复运维修改配置文件的bug 1 month ago
Matthew 5e869d0f92 优化下载参数 1 month ago
Matthew c6dbc278da 调整下载参数 1 month ago
Matthew a248c9e297 调整下载参数 1 month ago
Matthew 185ed0abff 换一种实现 1 month ago
Matthew 3a0ae0ab75 电压调整精度 1 month ago
Matthew 69bc6dced9 Update version to 1.3.162
Based Core Version to 1.4.88
1 month ago
Matthew 6e1625b58d 优化日志 1 month ago
Matthew 115a22dd47 Update version to 1.3.161
Based Core Version to 1.4.87
1 month ago
Matthew c104f26f7d 优化网络设置 1 month ago
Matthew d36d0d916d 优化网络实现 1 month ago
Matthew 0c57bca352 修复网络问题 1 month ago
Matthew 8abeaf9e04 Update MpRes version to 1.0.6 1 month ago
Matthew f0b82e235e Update version to 1.3.160
Based Core Version to 1.4.87
1 month ago
Matthew 3db1ae1c08 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
Matthew 43148b5962 更新充电电压和电量的的对应关系 1 month ago
Matthew a58e86b519 以太网启动之后主动设置ip和路由 1 month ago
XI.CHEN a6bfbdcea2 修复宇视url错误 1 month ago
Matthew 752b5fe318 Update version to 1.3.159
Based Core Version to 1.4.86
1 month ago
Matthew 4ca40f0424 修复URL拼接错误 1 month ago
Matthew d75ad0949e Update version to 1.3.158
Based Core Version to 1.4.86
1 month ago
Matthew e3388d77c3 Update MpMaster version to 1.1.29 1 month ago
Matthew 4067f2d6ed 优化重启的实现 1 month ago
Matthew aeb8e49b81 调整电池电压信息的获取方式 1 month ago
Matthew 3bc6775f84 调整运维获取电压的方式 1 month ago
Matthew dc17a15210 调整电池电压接口和实现 1 month ago
Matthew e4e174a083 调整gpio的处理方式 1 month ago
Matthew 44d780a0ce Update MpRes version to 1.0.5 1 month ago
Matthew 0097f11b69 移除调试代码 1 month ago
Matthew b533cd645f Update version to 1.3.157
Based Core Version to 1.4.85
1 month ago
Matthew e0063691f0 Update MpRes version to 1.0.4 1 month ago
Matthew 31039c213d 更换删除目录的方法 1 month ago
Matthew 86f22853ca 更换删除目录的方法 1 month ago
Matthew b3024a934b 增加删除目录的方法 1 month ago
Matthew b1b2b0d550 Update version to 1.3.156
Based Core Version to 1.4.85
1 month ago
Matthew 0c1143d0d0 修复编译错误 1 month ago
Matthew 362a23f58d Update MpMaster version to 1.1.28 1 month ago
Matthew ce762add59 Update MpRes version to 1.0.3 1 month ago
Matthew 8e44768f7e 更新配置 1 month ago
Matthew fc7fc294eb Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 1 month ago
Matthew ee0a2b632e 增加权限 1 month ago
Matthew d94124aa3c 增加权限 1 month ago
Matthew 22b81f8c46 优化重启运维的实现 1 month ago
Matthew 2811c694b7 增加函数
获取进程id
1 month ago
Matthew 06f38f3ff0 优化杀进程的方式 1 month ago
liuguijing f8ccfbba76 增量更新功能优化,增加安装成功之后,删除老的apk包和增量更新包。只保留最新的安装包 1 month ago
liuguijing 96b07fa223 增量更新功能优化 1 month ago
liuguijing ae6d49ed99 增量更新功能优化 1 month ago
Matthew 5d57a099cd Update version to 1.3.155
Based Core Version to 1.4.83
1 month ago
Matthew c8f34e9319 触发心跳动作 1 month ago
Matthew e01b32e166 Update MpMaster version to 1.1.27 1 month ago
Matthew db2ff686c6 Update version to 1.3.154
Based Core Version to 1.4.83
1 month ago
Matthew e022748f71 实现一个闹钟覆盖心跳、拍照、采样 1 month ago
Matthew c6405cf287 增加常量定义 1 month ago
Matthew 38fe69d93b 增加对拍照闹钟的处理(其中包含心跳) 1 month ago
Matthew e75fe1648c 优化日志 1 month ago
Matthew ab438f68b8 如果getInt正常,则删除日志文件 1 month ago
Matthew ba37692f73 重启设备前刷新日志内容进flash 1 month ago
Matthew 97c8cc3038 如果http访问是超时错误,则减少重试次数
避免耗电太高
2 months ago
Matthew 5872857f8d Update MpRes version to 1.0.2 2 months ago
Matthew 9c7be4fe96 Update MpMaster version to 1.1.26 2 months ago
Matthew 4e5b1b7b2a Update version to 1.3.153
Based Core Version to 1.4.82
2 months ago
Matthew cbf60b12f6 减小package size 2 months ago
Matthew 9a88a2dcd2 优化package size 2 months ago
Matthew 00a8de5e54 优化package size 2 months ago
Matthew 1fcc231ac1 Update MpRes version to 1.0.1 2 months ago
Matthew 667ebb60c8 Update version to 1.3.152
Based Core Version to 1.4.82
2 months ago
Matthew dcf3dffe02 Update MpMaster version to 1.1.25 2 months ago
Matthew 20c5eebd20 Update version to 1.3.151
Based Core Version to 1.4.81
2 months ago
Matthew eeabd15b87 优化日志 2 months ago
Matthew d930f65393 优化 2 months ago
Matthew 3974564746 优化代码 2 months ago
Matthew 3c5f49a563 移除不必要的依赖,降低apk size 2 months ago
Matthew b1b70395c7 消除警告 2 months ago
Matthew 21aac05206 调整名字 2 months ago
Matthew e2c4e51550 启动时如果需要初始化mpapp配置,则从assets中拷贝到特定目录 2 months ago
Matthew 75a7c17d62 增加mpres相关的定义和函数 2 months ago
Matthew d9b75e2c2f 如果缺少配置文件,调用mpres app初始化 2 months ago
Matthew f90cbd0446 移除MpAPP的配置文件 2 months ago
Matthew a90617698b 移除MpApp的配置初始化 2 months ago
Matthew 738f4f230a 加回5V5的gpio值备用 2 months ago
Matthew 55bda9770e 配置文件转到新app中 2 months ago
liuguijing e580737761 运维新增 下载增量更新功能 2 months ago
Matthew c0e0b3874f Update version to 1.3.150
Based Core Version to 1.4.81
2 months ago
Matthew 31391c2bab Refactor 2 months ago
Matthew 025c9fb07f Update version to 1.3.149
Based Core Version to 1.4.80
2 months ago
Matthew 07f7744ad8 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 2 months ago
Matthew 58d8c614ab 优化网络访问代码 2 months ago
Matthew 82e8212027 移除绑定网络的代码
通过路由来控制
2 months ago
Matthew 32a1fbbeb1 网络会不定时变化,增加更新网络handle函数 2 months ago
liuguijing 2dd6cb8f31 运维新增增量更新 完善增量更新时 计算差分代码 2 months ago
liuguijing 0d8bb73f17 运维新增增量更新 调试可用 待完善 2 months ago
XI.CHEN 89b263e4de Merge branch 'main' of http://dev.xinyingpower.com:8081/git/xymp/TermApp 2 months ago
Matthew 2d600c18e4 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 2 months ago
XI.CHEN 424bd6ee88 Merge branch 'main' of http://dev.xinyingpower.com:8081/git/xymp/TermApp 2 months ago
XI.CHEN 987d2e8053 Merge branch 'main' of http://dev.xinyingpower.com:8081/git/xymp/TermApp 2 months ago
Matthew 387673bf99 修复编译错误 2 months ago
liuguijing 8bb1c53bc2 Merge remote-tracking branch 'origin/main' 2 months ago
Matthew 7ae8505809 Update version to 1.3.148
Based Core Version to 1.4.80
2 months ago
Matthew d2881112f2 修复编译错误 2 months ago
liuguijing 40d36e1577 新增系统心跳调试的日志 2 months ago
Matthew 47ff714ae5 Update version to 1.3.147
Based Core Version to 1.4.80
2 months ago
Matthew f8784c5b26 Update version to 1.3.146
Based Core Version to 1.4.80
2 months ago
Matthew ee492d0e60 修复编译错误 2 months ago
Matthew 8fd275a6e7 增加日志 2 months ago
Matthew a9fd536a8a Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 2 months ago
Matthew 142fca3dd0 实现海康接口 2 months ago
Matthew ed35d74c94 修复编译错误 2 months ago
liuguijing cd520ebefe 新增测试HeartBeat的广播 2 months ago
liuguijing 9ff79bbe1b 新增测试HeartBeat的广播 2 months ago
Matthew 6598b45d3e 修复编译错误 2 months ago
Matthew 62de685e4e Update version to 1.3.145
Based Core Version to 1.4.80
2 months ago
Matthew a0c4651e97 集成bspatch 2 months ago
Matthew 883e9f94e4 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 2 months ago
Matthew 44a5a32741 Update version to 1.3.144
Based Core Version to 1.4.79
2 months ago
jxjajs 31e33b065b 生成准确读取云台位置指令使用独立函数实现 2 months ago
Matthew 5a8be5883b 调整gpio监控 2 months ago
Matthew b734a9cc2a 优化文件名 2 months ago
Matthew be7b992bdd Update version to 1.3.143
Based Core Version to 1.4.78
2 months ago
Matthew 2b06803252 重启两个api都调用作双重保护 2 months ago
Matthew 396d20ea3f 移除HDRPlus相关的代码 2 months ago
Matthew fde6514d16 Update version to 1.3.142
Based Core Version to 1.4.77
2 months ago
Matthew f6d3ccbfa1 移除日志 2 months ago
Matthew 754d3bebb7 移除解决粉色的临时补丁 2 months ago
Matthew a04db636c6 Update version to 1.3.141
Based Core Version to 1.4.76
2 months ago
Matthew 6e379548e6 优化航煜拍照实现
如果照片太大出错,则降低图像质量后重试
2 months ago
Matthew 38a8498dbc 优化网络打开时间 2 months ago
Matthew 5dae67b03b 网络延迟打开 2 months ago
Matthew b821156ca1 Update MpMaster version to 1.1.24 2 months ago
Matthew 870cffab5c Update version to 1.3.140
Based Core Version to 1.4.76
2 months ago
Matthew 55c3776ac8 通过附件编译时间来选择不同的判断运维程序是否运行的方法 2 months ago
Matthew 126c1f5e1b 通过附件编译时间来选择不同的判断程序是否运行的方法 2 months ago
liuguijing 28be0c4c80 Update MpMaster version to 1.1.23 2 months ago
liuguijing 8c3103eef6 运维的MCU重启命令修改 2 months ago
liuguijing e59f6fbbea 运维修改重启方式 2 months ago
Matthew b216ad7546 Update version to 1.3.139
Based Core Version to 1.4.76
2 months ago
Matthew c3e4ef0847 微拍暂时不重置电源 2 months ago
Matthew 101d2b945a 微拍移除重置电源的代码 2 months ago
Matthew 7ea3b47abb Update version to 1.3.138
Based Core Version to 1.4.76
2 months ago
Matthew cf6c5c8158 网络设备的osd也临时关掉 2 months ago
Matthew b9fe6ce048 优化网络摄像头供应商的实现
移除航煜对时的实现
2 months ago
Matthew 138040baa8 增加算法的实现 2 months ago
Matthew e21e409712 实现3DNR 2 months ago
Matthew b3f3703c74 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 2 months ago
Matthew f445f5f6c8 Update version to 1.3.137
Based Core Version to 1.4.74
2 months ago
XI.CHEN cafa30c728 暂时去除航煜视频除时间外水印 2 months ago
XI.CHEN 167878de1a 暂时去除航煜视频除时间外水印 2 months ago
XI.CHEN c51fb6924b Merge branch 'main' of http://dev.xinyingpower.com:8081/git/xymp/TermApp 2 months ago
XI.CHEN ec6a27df28 航煜OSD和分辨率设置 2 months ago
Matthew 11e5b98a90 充电电压如果小于3V,就直接设置为0 2 months ago
Matthew d4c5986943 Update version to 1.3.136
Based Core Version to 1.4.74
2 months ago
Matthew 5a91bd8dcb 移除调试的功能 2 months ago
Matthew 4c42820cea 移除调试的功能 2 months ago
Matthew db78ce7728 优化http请求错误的处理 2 months ago
Matthew b5a188a5b4 Update version to 1.3.135
Based Core Version to 1.4.74
2 months ago
Matthew 90465c4ac1 Merge branch 'main' of http://61.169.135.146:8081/git/xymp/TermApp 2 months ago
Matthew 7ef6086f50 优化前台服务实现 2 months ago
Matthew 5151f9291a 优化前台服务实现 2 months ago
Matthew 7037eab930 调整id防止冲突 2 months ago
XI.CHEN 2d67c94bc9 航煜视频水印根据时间是否设置改变 2 months ago
Matthew 39b94cee90 Update version to 1.3.134
Based Core Version to 1.4.72
2 months ago
Matthew 801a9e98ba 静态抓拍强制改为预览的范围从150开始 2 months ago
Matthew 868fbebb6b Update version to 1.3.133
Based Core Version to 1.4.72
2 months ago
Matthew 1806c36148 增加更多拍照日志 2 months ago
Matthew f2f29482a0 输出照片日志信息 2 months ago
Matthew a52255e9d9 增加日志 2 months ago
Matthew 2cc92025fc Update MpMaster version to 1.1.22 2 months ago
Matthew 744057c407 Update version to 1.3.132
Based Core Version to 1.4.72
2 months ago
Matthew d23116aa57 增加长时间无心跳重启app的机制,并优化运维日志 2 months ago
Matthew 3fab6d4542 保活时判断service是否存在 2 months ago
Matthew 21c789155c 优化日志 2 months ago
Matthew 11dbea7170 Update MpMaster version to 1.1.21 2 months ago
Matthew 17ae352c31 更新默认配置 2 months ago
liuguijing 31c0d81e13 Update version to 1.3.131 2 months ago
liuguijing 18ecc420ed mpapp:修复mpapp摄像头拍视频时视角变小的bug 2 months ago
liuguijing b58969cc5e Update version to 1.3.130 2 months ago
liuguijing 9bb9b6848c 修改短视频预览摄像头不正的bug 2 months ago
liuguijing 7a557ac8fd 修改短视频预览摄像头不正的bug 2 months ago
Matthew e0a23a6c3b Update version to 1.3.129
Based Core Version to 1.4.72
2 months ago
liuguijing 2d0fe6609b 为修复宁夏短视频拍照翻转的bug 临时修改方法 2 months ago
Matthew 7e57c3cc08 Update version to 1.3.128
Based Core Version to 1.4.71
2 months ago
Matthew 0fc7ff436e 统一GPIO
N938:
#define CMD_SET_3V3_PWR_EN                      360  // 改为132

云台:
#define CMD_SET_485_ENABLE                      512 // 改成131
#define CMD_SET_3V3_PWR_EN                      516 // 改成 132

固件从20250419的版本开始
2 months ago
Matthew 2009c6d472 调整hdr的代码 2 months ago
Matthew 24333d1882 优化逻辑 2 months ago
Matthew 04abdbeb61 Update version to 1.3.127
Based Core Version to 1.4.71
2 months ago
Matthew 4106ce8cb3 优化拍照时间的注册处理,避免始时钟丢失校时成功之后的错误 2 months ago
Matthew 7ad52b042c 增加HDR的支持 2 months ago
Matthew 6925da78b1 Update version to 1.3.126
Based Core Version to 1.4.71
2 months ago
Matthew 9f00a81b8e Update MpMaster version to 1.1.20 2 months ago
Matthew 1c8372d5a2 优化调试信息的实现 2 months ago
Matthew 1782269938 Update version to 1.3.125
Based Core Version to 1.4.71
2 months ago
Matthew 8398ae8246 增加时间发生变化后的更新处理 2 months ago
Matthew 49aff958d0 移除无用代码 2 months ago
Matthew b6932b116e 移除文件锁的实现 2 months ago
Matthew 4976337878 利用共享uid的方式来判断mpapp是否正在运行
加入时间变化监控的一些定义
2 months ago
Matthew 897b53e44e 利用共享uid的方式来判断运维app是否正在运行
加入时间变化监控的一些定义
2 months ago
Matthew 621cf4f3ba Update version to 1.3.124
Based Core Version to 1.4.70
2 months ago
Matthew 476ebbd5e0 强制走预览模式的范围改成200-400 2 months ago
Matthew c54cecacf0 设置共享uid 2 months ago
Matthew 9fedc2532c Update MpMaster version to 1.1.19 2 months ago
Matthew 8e9597eaf4 Update version to 1.3.123
Based Core Version to 1.4.70
2 months ago
Matthew b94039cbd6 设置共享uid 2 months ago
Matthew 6d2f4c7535 设置共享uid 2 months ago
Matthew 252e2575f5 调整回预览+静态抓拍模式
针对iso为200-300之间的粉色问题,做了补丁,强制走预览模式,临时绕过这个问题
2 months ago
Matthew 6587298604 Update version to 1.3.122
Based Core Version to 1.4.70
2 months ago
Matthew eb96c9c6c7 实现预览到静态抓拍的主动切换 2 months ago
Matthew d1d34ebcfc Update version to 1.3.121
Based Core Version to 1.4.70
2 months ago
Matthew 3a0a8b71a0 重启设备前记录日志 2 months ago
Matthew 030ca9c7d7 修复拍照设置的bug 2 months ago
Matthew a9535f2df7 增加对AIS的支持 2 months ago
Matthew 1ba1b9d56a Update version to 1.3.120
Based Core Version to 1.4.70
2 months ago
Matthew 7a51b96100 调整拍照的实现,改成一个request实现测光和拍照 2 months ago
Matthew 8a7d571e0e Update version to 1.3.119
Based Core Version to 1.4.70
2 months ago
Matthew 2336758523 Update version to 1.3.118
Based Core Version to 1.4.69
2 months ago
Matthew 95213a4ecd 网络摄像头实现自检等待 2 months ago
Matthew 8f49d82dec 优化日志 2 months ago
Matthew 0170e21b1d 优化网络重试次数和日志 2 months ago
Matthew 94ca4f77a4 Update version to 1.3.117
Based Core Version to 1.4.69
2 months ago
jxjajs 2af459d57a 解决查询云台位置命令不下发BUg 2 months ago
jxjajs 1f3943b34b 增加log,调试 2 months ago

@ -5,7 +5,7 @@ plugins {
// 10,00,000 major-minor-build
def AppMajorVersion = 1
def AppMinorVersion = 3
def AppBuildNumber = 116
def AppBuildNumber = 196
def AppVersionName = AppMajorVersion + "." + AppMinorVersion + "." + AppBuildNumber
def AppVersionCode = AppMajorVersion * 100000 + AppMinorVersion * 1000 + AppBuildNumber
@ -98,7 +98,7 @@ android {
def abi = output.getFilter(com.android.build.OutputFile.ABI)
if (abi == null) abi = "all"
if (abi.contains("v7a")) prevFileName = "N938"
def fileName = "${prevFileName}_v${defaultConfig.versionName}_${buildTypeFlag}_${new Date(System.currentTimeMillis()).format("yyyyMMdd")}_${abi}.apk"
def fileName = "${prevFileName}_v${defaultConfig.versionName}_${buildTypeFlag}_${new Date(System.currentTimeMillis()).format("yyyyMMdd")}.apk"
outputFileName = fileName
}
}
@ -126,11 +126,10 @@ android {
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
// implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.0'
// implementation "androidx.core:core:1.10.0" // 使
implementation 'androidx.fragment:fragment:1.3.6'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.material:material:1.8.0'
implementation project(path: ':common')

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="com.xypower.mp"
tools:ignore="Deprecated">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
@ -10,9 +12,10 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
@ -55,6 +58,7 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-permission
android:name="android.permission.DEVICE_POWER"
tools:ignore="ProtectedPermissions" />
@ -63,15 +67,23 @@
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
tools:ignore="ProtectedPermissions" /> <!-- WiFi AP startTethering -->
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission
android:name="android.permission.TETHER_PRIVILEGED"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL"
tools:ignore="ProtectedPermissions" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="com.mediatek.camera.feature.mfnr" />
<uses-permission android:name="android.hardware.usb.accessory" />
<uses-feature android:name="android.hardware.usb.host" />
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<queries>
<provider
@ -87,6 +99,9 @@
<intent>
<action android:name="android.media.action.STILL_IMAGE_CAMERA" />
</intent>
<intent>
<action android:name="android.intent.action.TIME_CHANGED" />
</intent>
<package android:name="com.xypower.mplive" />
</queries>
@ -159,11 +174,10 @@
<category android:name="android.intent.category.default" />
</intent-filter>
</service>
<service android:name=".FloatingWindow" />
<receiver
android:name=".MicroPhotoService$AlarmReceiver"
android:exported="true" />
android:exported="true" >
</receiver>
<receiver
android:name=".BootBroadcastReceiver"
android:enabled="true"
@ -177,17 +191,7 @@
</intent-filter>
</receiver>
<receiver android:name=".NetworkChangedReceiver" />
<receiver
android:name=".ScreenActionReceiver"
android:exported="true">
<intent-filter android:priority="90000">
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.USER_UNLOCKED" />
</intent-filter>
</receiver>
<receiver
android:name="com.xypower.common.UpdateReceiver"
android:enabled="true"
@ -200,7 +204,14 @@
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name=".HeartBeatResponseReceiver"
android:enabled="true"
android:exported="true">
<intent-filter >
<action android:name="com.systemui.ACTION_HEARTBEAT_RESPONSE" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:exported="true"

@ -0,0 +1,227 @@
#!/system/bin/sh
# ==============================================
# Configuration parameters - modify as needed
# ==============================================
ETH_IP="192.168.68.91" # Ethernet IP address
ETH_NETMASK="24" # Subnet mask (CIDR format)
ETH_NETWORK="192.168.68.0" # Network address
ETH_BROADCAST="192.168.68.255" # Broadcast address
ETH_GATEWAY="192.168.68.1" # Default gateway
ROUTE_TABLE="20" # Routing table number
MAX_INIT_WAIT=150 # Maximum seconds to wait for ethernet interface
MAX_UP_WAIT=10 # Maximum seconds to wait for interface to come UP
MAX_ROUTE_WAIT=5 # Maximum seconds to wait for routing rules
# For debugging only - comment out in production
# set -x
ANDROID_VERSION=$(getprop ro.build.version.release 2>/dev/null | cut -d '.' -f1)
# Record script start time
SCRIPT_START=$(date +%s)
# Cleanup function - handles unexpected interruptions
cleanup() {
echo "Script interrupted, cleaning up..." >&2
# Add additional cleanup code here if needed
exit 1
}
trap cleanup INT TERM
# Get script directory for finding tools like ethtool
SCRIPT_PATH="$0"
# Ensure path is absolute
case "$SCRIPT_PATH" in
/*) ;; # Already absolute path
*) SCRIPT_PATH="$PWD/$SCRIPT_PATH" ;;
esac
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
echo "Script directory detected as: $SCRIPT_DIR"
# Only configure rp_filter for eth0 interface
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter 2>/dev/null || true
# Wait for eth0 interface to appear
WAITED=0
while [ $WAITED -lt $MAX_INIT_WAIT ]; do
if [ -d "/sys/class/net/eth0" ]; then
echo "eth0 found after $WAITED seconds"
break
fi
echo "Wait eth0... ($WAITED/$MAX_INIT_WAIT)"
sleep 0.1
WAITED=$((WAITED+1))
done
# Check if eth0 exists
if ! [ -d "/sys/class/net/eth0" ]; then
echo "Error: eth0 not exists" >&2
exit 1
fi
# Check physical connection status
if [ -f "/sys/class/net/eth0/carrier" ]; then
CARRIER=$(cat /sys/class/net/eth0/carrier)
echo "Physical connection status: $CARRIER (1=connected, 0=disconnected)"
if [ "$CARRIER" != "1" ]; then
echo "Warning: Ethernet physical connection may have issues, please check the cable" >&2
fi
fi
# Clear previous configuration
/system/bin/ip link set eth0 down
/system/bin/ip addr flush dev eth0
/system/bin/ip route flush dev eth0
/system/bin/ip route flush table $ROUTE_TABLE
/system/bin/ip rule del to $ETH_NETWORK/$ETH_NETMASK 2>/dev/null || true
# Configure physical layer with ethtool (while interface is DOWN)
if [ -x "$SCRIPT_DIR/ethtool" ]; then
echo "Using ethtool from script directory: $SCRIPT_DIR/ethtool"
"$SCRIPT_DIR/ethtool" -s eth0 speed 10 duplex full autoneg off
# Try alternative path next
elif [ -x "/data/data/com.xypower.mpapp/files/ethtool" ]; then
echo "Configuring eth0 to 10Mbps full duplex..."
/data/data/com.xypower.mpapp/files/ethtool -s eth0 speed 10 duplex full autoneg off
else
echo "Warning: ethtool not found, falling back to sysfs configuration" >&2
# Try sysfs configuration as fallback
if [ -f "/sys/class/net/eth0/speed" ]; then
echo "off" > /sys/class/net/eth0/autoneg 2>/dev/null || true
echo "10" > /sys/class/net/eth0/speed 2>/dev/null || true
echo "full" > /sys/class/net/eth0/duplex 2>/dev/null || true
fi
fi
# ====================================================
# MTK Android 9 IP configuration with loss prevention
# ====================================================
# Configure IP address first while interface is DOWN
echo "Setting IP address while interface is DOWN..."
/system/bin/ip addr add $ETH_IP/$ETH_NETMASK broadcast $ETH_BROADCAST dev eth0
PRE_UP_IP=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
echo "IP configuration before UP: $PRE_UP_IP (1=configured, 0=missing)"
# Enable interface and wait for UP
echo "Bringing up interface..."
/system/bin/ip link set eth0 up
if [ "$ANDROID_VERSION" = "9" ]; then
sleep 3
else
# Use standard configuration for other devices
sleep 1
fi
# Check if IP was lost after interface UP (common issue on MTK devices)
POST_UP_IP=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
echo "IP configuration after UP: $POST_UP_IP (1=retained, 0=lost)"
# IP address lost detection and recovery
if [ "$PRE_UP_IP" = "1" ] && [ "$POST_UP_IP" = "0" ]; then
echo "Warning: IP address was lost after bringing interface up - MTK issue detected"
echo "Reapplying IP configuration..."
/system/bin/ip addr add $ETH_IP/$ETH_NETMASK broadcast $ETH_BROADCAST dev eth0
# Check if reapplied configuration worked
FIXED_IP=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
echo "IP reapplication result: $FIXED_IP (1=success, 0=still missing)"
# If standard method fails, try MTK-specific approaches
if [ "$FIXED_IP" = "0" ]; then
echo "Standard IP configuration failed, trying MTK-specific methods"
# Try ifconfig if available (works better on some MTK devices)
if command -v ifconfig >/dev/null 2>&1; then
echo "Using ifconfig method..."
ifconfig eth0 $ETH_IP netmask 255.255.255.0 up
sleep 1
fi
# Try Android's netd service if available
if [ -x "/system/bin/ndc" ]; then
echo "Using MTK netd service..."
/system/bin/ndc network interface setcfg eth0 $ETH_IP 255.255.255.0 up
sleep 1
fi
fi
fi
# Use loop to wait for interface UP instead of fixed sleep
WAITED=0
while [ $WAITED -lt $MAX_UP_WAIT ]; do
# Check both link status and IP configuration
IF_STATUS=$(/system/bin/ip link show eth0 | grep -c ",UP")
IP_STATUS=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
if [ "$IF_STATUS" = "1" ] && [ "$IP_STATUS" = "1" ]; then
echo "Interface is UP with correct IP after $WAITED seconds"
break
fi
echo "Waiting for interface UP with IP... ($WAITED/$MAX_UP_WAIT)"
# If interface is UP but IP is missing, reapply IP
if [ "$IF_STATUS" = "1" ] && [ "$IP_STATUS" = "0" ]; then
echo "Interface UP but IP missing, reapplying IP..."
/system/bin/ip addr add $ETH_IP/$ETH_NETMASK broadcast $ETH_BROADCAST dev eth0
fi
sleep 0.5
WAITED=$((WAITED+1))
done
# Final status check
FINAL_IF_STATUS=$(/system/bin/ip link show eth0 | grep -c ",UP")
FINAL_IP_STATUS=$(/system/bin/ip addr show eth0 | grep -c "inet $ETH_IP")
if [ "$FINAL_IF_STATUS" != "1" ] || [ "$FINAL_IP_STATUS" != "1" ]; then
echo "Warning: Failed to achieve stable interface state with IP" >&2
echo "Final interface status: $FINAL_IF_STATUS (1=UP, 0=DOWN)"
echo "Final IP status: $FINAL_IP_STATUS (1=configured, 0=missing)"
/system/bin/ip addr show eth0
else
echo "Successfully configured eth0 with IP $ETH_IP"
fi
# First add to main routing table
/system/bin/ip route add $ETH_NETWORK/$ETH_NETMASK dev eth0 proto static scope link
# Then add to specified routing table
/system/bin/ip route add $ETH_NETWORK/$ETH_NETMASK dev eth0 proto static scope link table $ROUTE_TABLE
ADD_ROUTE_STATUS=$?
if [ $ADD_ROUTE_STATUS -eq 0 ]; then
echo "Add route successfully"
else
echo "Failed to add route: $ADD_ROUTE_STATUS" >&2
fi
# Only clear ARP and neighbor cache for eth0
/system/bin/ip neigh flush dev eth0
# Add routing rules - only flush cache once after rule is added
/system/bin/ip rule add from all to $ETH_NETWORK/$ETH_NETMASK lookup $ROUTE_TABLE prio 1000
/system/bin/ip route flush cache dev eth0
# Only enable forwarding for eth0 interface
echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding 2>/dev/null || true
# Wait for routing rules to take effect - using loop check instead of fixed wait
WAITED=0
while [ $WAITED -lt $MAX_ROUTE_WAIT ]; do
if /system/bin/ip rule | grep -q "$ETH_NETWORK/$ETH_NETMASK"; then
echo "Routing rules are now effective after $WAITED seconds"
break
fi
echo "Waiting for routing rules to take effect... ($WAITED/$MAX_ROUTE_WAIT)"
sleep 0.5
WAITED=$((WAITED+1))
done
# Display execution time
SCRIPT_END=$(date +%s)
TOTAL_TIME=$((SCRIPT_END - SCRIPT_START))
echo "Total script execution time: $TOTAL_TIME seconds"
exit 0

Binary file not shown.

Binary file not shown.

@ -21,7 +21,7 @@ if(ANDROID_ABI STREQUAL "armeabi-v7a")
add_definitions(-DUSING_N938)
elseif(ANDROID_ABI STREQUAL "arm64-v8a")
# add_definitions(-DUSING_N938)
add_definitions(-DUSING_PTZ)
# add_definitions(-DUSING_PTZ)
endif()
# OUTPUT_DBG_INFO:
@ -63,8 +63,8 @@ add_definitions(-DENABLE_3V3_ALWAYS)
add_definitions(-DCURL_STATICLIB)
add_definitions(-DUSING_HDRPLUS)
add_definitions(-DUSING_EXEC_HDRP=1)
set(USING_EXEC_HDRP 1)
add_definitions(-DUSING_EXEC_HDRP=0)
#set(USING_EXEC_HDRP 1)
# include_directories(${OpenCV_DIR}/include)
# add_library( lib_opencv SHARED IMPORTED )
@ -160,9 +160,9 @@ add_definitions(-DDISABLE_RTTI)
SET(STREAMING_SRCS media/RTSPToMP4.cpp media/RTSPRecorder.cpp media/Streaming.cpp )
SET(HDRPLUS_LIBS raw exiv2 exiv2-xmp expat lcms2 OpenMP::OpenMP_CXX)
#SET(HDRPLUS_LIBS raw exiv2 exiv2-xmp expat lcms2 OpenMP::OpenMP_CXX)
SET(HDRPLUS2_LIBS raw raw_r lcms2 tiff tiffxx jpeg hdrplus_pipeline)
#SET(HDRPLUS2_LIBS raw raw_r lcms2 tiff tiffxx jpeg hdrplus_pipeline)
SET(HDRPLUS_SOURCES
hdrplus/src/align.cpp
@ -180,6 +180,7 @@ SET(HDRPLUS2_SOURCES
hdrplus2/src/InputSource.cpp
hdrplus2/src/LibRaw2DngConverter.cpp
hdrplus2/${ANDROID_ABI}/hdrplus_pipeline.registration.cpp)
SET(HDRPLUS2_SOURCES )
SET(YAMC_INC_DIR ${CMAKE_SOURCE_DIR})
@ -355,6 +356,7 @@ add_library( # Sets the name of the library.
netcamera/VendorCtrl.cpp
netcamera/YuShiCtrl.cpp
netcamera/HangYuCtrl.cpp
netcamera/HikonCtrl.cpp
${STREAMING_SRCS}
@ -376,9 +378,11 @@ add_library( # Sets the name of the library.
${TERM_CORE_ROOT}/SpecData_I1_JS.cpp
${TERM_CORE_ROOT}/SpecData_I1_HN.cpp
${TERM_CORE_ROOT}/SpecData_I1_HEN.cpp
${TERM_CORE_ROOT}/SpecData_I1_HEN_TY.cpp
${TERM_CORE_ROOT}/SpecData_I1_HENZZ.cpp
${TERM_CORE_ROOT}/SpecData_I1_SHX.cpp
${TERM_CORE_ROOT}/SpecData_I1_NX.cpp
${TERM_CORE_ROOT}/SpecData_I1_SX_ZY.cpp
${TERM_CORE_ROOT}/SpecData_XY.cpp
${TERM_CORE_ROOT}/SpecData_ZJ.cpp
${TERM_CORE_ROOT}/SpecData_NW.cpp
@ -396,15 +400,17 @@ add_library( # Sets the name of the library.
${TERM_CORE_ROOT}/Client/Terminal_AH.cpp
${TERM_CORE_ROOT}/Client/Terminal_HEN_ZZ.cpp
${TERM_CORE_ROOT}/Client/Terminal_HEN.cpp
${TERM_CORE_ROOT}/Client/Terminal_HEN_TY.cpp
${TERM_CORE_ROOT}/Client/Terminal_SHX.cpp
${TERM_CORE_ROOT}/Client/Terminal_JS.cpp
${TERM_CORE_ROOT}/Client/Terminal_NX.cpp
${TERM_CORE_ROOT}/Client/Terminal_SX_ZY.cpp
${TERM_CORE_ROOT}/Client/Terminal_ZJ.cpp
${TERM_CORE_ROOT}/Client/Terminal_NW.cpp
${TERM_CORE_ROOT}/Client/DataController.cpp
${TERM_CORE_ROOT}/Client/UpgradeReceiver.cpp
${TERM_CORE_ROOT}/Client/Database.cpp
${TERM_CORE_ROOT}/Client/SimulatorDevice.cpp
# ${TERM_CORE_ROOT}/Client/SimulatorDevice.cpp
${TERM_CORE_ROOT}/Client/DataController.cpp
)

@ -23,9 +23,52 @@
#define IOT_PARAM_READ 0xAF
std::mutex GpioControl::m_locker;
std::mutex GpioControl::m_gpioLocker;
std::vector<GpioControl::ITEM> GpioControl::m_items;
bool GpioControl::m_cameraPowerStatus = false;
#define ENABLE_GPIO_TRACING
#ifdef ENABLE_GPIO_TRACING
class GpioDebugLogger
{
public:
GpioDebugLogger(int cmd, int value)
{
m_startTime = GetMicroTimeStamp();
m_path = std::string("/sdcard/com.xypower.mpapp/tmp/") + std::to_string(cmd) + std::string("_") + std::to_string(m_startTime) + "_val." + std::to_string(value);
CreateEmptyFile(m_path + ".enter");
}
GpioDebugLogger(int cmd)
{
m_startTime = GetMicroTimeStamp();
m_path = std::string("/sdcard/com.xypower.mpapp/tmp/") + std::to_string(cmd) + std::string("_") + std::to_string(m_startTime) + "_get";
CreateEmptyFile(m_path + ".enter");
}
~GpioDebugLogger()
{
uint64_t ts = (GetMicroTimeStamp() - m_startTime);
if (ts > 1000)
{
CreateEmptyFile(m_path + ".leave." + std::to_string(ts));
}
else
{
std::string path = m_path + ".enter";
std::remove(path.c_str());
}
}
private:
std::string m_path;
uint64_t m_startTime;
};
#endif
size_t GpioControl::turnOnImpl(const IOT_PARAM& param)
{
size_t oldRef = 0;
@ -60,6 +103,10 @@ size_t GpioControl::turnOnImpl(const IOT_PARAM& param)
if (oldRef == 0/* || param.cmd != CMD_SET_3V3_PWR_EN*/)
{
#ifdef ENABLE_GPIO_TRACING
GpioDebugLogger logger(param.cmd, param.value);
#endif
m_gpioLocker.lock();
fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
@ -68,9 +115,10 @@ size_t GpioControl::turnOnImpl(const IOT_PARAM& param)
#ifdef OUTPUT_DBG_INFO
// int realVal = getInt(param.cmd);
// XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d RealVal=%d",param.cmd, param.value, param.result/*, realVal*/);
XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
XYLOG(XYLOG_SEVERITY_DEBUG, "setInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
#endif
}
m_gpioLocker.unlock();
#ifdef _DEBUG
ALOGI("PWR TurnOn cmd=%d,result=%d ref=%u\r\n",param.cmd, param.result, (uint32_t)references);
#endif
@ -86,6 +134,10 @@ void GpioControl::setInt(int cmd, int value)
// param.cmd = cmd;
// param.value = value;
#ifdef ENABLE_GPIO_TRACING
GpioDebugLogger logger(cmd, value);
#endif
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
if (fd > 0)
{
@ -94,13 +146,18 @@ void GpioControl::setInt(int cmd, int value)
#ifdef OUTPUT_DBG_INFO
// int realVal = getInt(param.cmd);
// XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d RealVal=%d",param.cmd, value, param.result/*, realVal*/);
XYLOG(XYLOG_SEVERITY_INFO, "setInt cmd=%d,value=%d,result=%d",param.cmd, value, param.result);
XYLOG(XYLOG_SEVERITY_DEBUG, "setInt cmd=%d,value=%d,result=%d",param.cmd, value, param.result);
#endif
}
m_gpioLocker.unlock();
}
int GpioControl::getInt(int cmd)
{
#ifdef ENABLE_GPIO_TRACING
GpioDebugLogger logger(cmd);
#endif
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
// LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
if( fd > 0 )
@ -112,29 +169,34 @@ int GpioControl::getInt(int cmd)
ALOGI("getInt cmd=%d,value=%d,result=%d",param.cmd, param.value, param.result);
#endif
close(fd);
m_gpioLocker.unlock();
return param.value;
}
m_gpioLocker.unlock();
return -1;
}
void GpioControl::setLong(int cmd, long value)
{
int fd = open(GPIO_NODE_MP, O_RDONLY);
IOT_PARAM param;
param.cmd = cmd;
param.value2 = value;
// LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2);
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
ioctl(fd, IOT_PARAM_WRITE, &param);
// LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
close(fd);
}
m_gpioLocker.unlock();
}
long GpioControl::getLong(int cmd)
{
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
// LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd);
if( fd > 0 )
@ -144,32 +206,37 @@ long GpioControl::getLong(int cmd)
ioctl(fd, IOT_PARAM_READ, &param);
// LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
close(fd);
m_gpioLocker.unlock();
return param.value2;
}
m_gpioLocker.unlock();
return -1;
}
void GpioControl::setString(int cmd, const std::string& value)
{
IOT_PARAM param;
int fd = open(GPIO_NODE_MP, O_RDONLY);
int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
param.cmd = cmd;
memset(param.str, 0, MAX_STRING_LEN);
int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();
memcpy(param.str, value.c_str(), len);
// LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
if( fd > 0 )
{
ioctl(fd, IOT_PARAM_WRITE, &param);
// LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
close(fd);
}
m_gpioLocker.unlock();
return;
}
std::string GpioControl::getString(int cmd)
{
m_gpioLocker.lock();
int fd = open(GPIO_NODE_MP, O_RDONLY);
// LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd);
if( fd > 0 )
@ -179,8 +246,10 @@ std::string GpioControl::getString(int cmd)
ioctl(fd, IOT_PARAM_READ, &param);
// LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
close(fd);
m_gpioLocker.unlock();
return std::string(param.str);
}
m_gpioLocker.unlock();
return "";
}

@ -44,6 +44,7 @@
#define CMD_SET_PWM_BEE_STATE 126 // Removed
#define CMD_SET_ALM_MODE 128 // Removed
#define CMD_SET_SYSTEM_RESET 202
#define CMD_SET_SYSTEM_RESET2 203
#define CMD_SET_485_EN_STATE 131
#define CMD_SET_12V_EN_STATE 133
#if 1
@ -59,6 +60,9 @@
#define CMD_SET_INIT_STATUS 401
#define CMD_SET_5V_PWR_ENABLE 517
#define CMD_SET_NEW_OTG_STATE 507
#else // defined(USING_PTZ)
#define CMD_SET_OTG_STATE 107
@ -69,6 +73,7 @@
#define CMD_SET_12V_EN_STATE 0 // TO BE ADDED
#define CMD_SET_SYSTEM_RESET 202
#define CMD_SET_SYSTEM_RESET2 203
#define CMD_GET_LIGHT_ADC 101
#define CMD_SET_LIGHT_ADC 102
#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112
@ -77,8 +82,8 @@
#define CMD_SET_SPI_BITS_PER_WORD 0 // TO BE ADDED
#define CMD_SET_SPI_MAXSPEEDHZ 0 // TO BE ADDED
#define CMD_SET_485_ENABLE 512
#define CMD_SET_3V3_PWR_EN 516
#define CMD_SET_485_ENABLE 131
#define CMD_SET_3V3_PWR_EN 132
// #define CMD_SET_5V_PWR_ENABLE 517
#define CMD_SET_SENSOR_ENABLE 504
#define CMD_SET_SENSOR_PWR_ENABLE 505
@ -121,8 +126,9 @@
#else // defined(USING_N938)
#define CMD_SET_SYSTEM_RESET 202
#define CMD_SET_SYSTEM_RESET2 203
#define CMD_SET_485_EN1 302
#define CMD_SET_3V3_PWR_EN 360
#define CMD_SET_3V3_PWR_EN 132
#define CMD_SET_UART0_EN 361
#define CMD_SET_485_EN0 301
#define CMD_SET_NETWORK_POWER_EN 362
@ -182,6 +188,8 @@ private:
static std::vector<ITEM> m_items;
static bool m_cameraPowerStatus;
static std::mutex m_gpioLocker;
protected:
static size_t turnOnImpl(const IOT_PARAM& param);
static size_t turnOffImpl(const IOT_PARAM& param);
@ -306,6 +314,11 @@ public:
setInt(CMD_SET_SYSTEM_RESET, 1);
}
static void reboot2()
{
setInt(CMD_SET_SYSTEM_RESET2, 1);
}
static void setLightAdc(int i)
{
#ifndef USING_N938
@ -589,13 +602,13 @@ class NetCameraPowerCtrl : public PowerControl
public:
NetCameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_NETWORK_POWER_EN, CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
PowerControl(CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_12V_EN_STATE, closeDelayTime)
#else // USING_PTZ
// MicroPhoto
PowerControl(CMD_SET_12V_EN_STATE, CMD_SET_OTG_STATE, CMD_SET_485_EN_STATE, closeDelayTime)
PowerControl(CMD_SET_12V_EN_STATE, CMD_SET_485_EN_STATE, closeDelayTime)
#endif // USING_PTZ
#endif // USING_N938
{
@ -607,7 +620,7 @@ class PlzCameraPowerCtrl : public PowerControl
public:
PlzCameraPowerCtrl(uint32_t closeDelayTime) :
#ifdef USING_N938
PowerControl(CMD_SET_OTG_STATE, CMD_SET_NETWORK_POWER_EN, CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
PowerControl(CMD_SET_PIC1_POWER, CMD_SET_485_EN_STATE, closeDelayTime)
#else // USING_N938
#ifdef USING_PTZ
PowerControl(CMD_SET_3V3_PWR_EN, CMD_SET_OTG_STATE, CMD_SET_485_ENABLE, CMD_SET_PTZ_PWR_ENABLE, CMD_SET_12V_EN_STATE, CMD_SET_100M_SWITCH_PWR_ENABLE, closeDelayTime)

@ -428,7 +428,18 @@ Java_com_xypower_mpapp_MicroPhotoService_notifyToTakePhoto(
uint8_t type = (uint8_t)mediaType;
// std::thread th(&Runner::RequestCapture, pTerminal, (unsigned int)channel, (unsigned int)preset, type, (uint64_t)scheduleTime, 0, true);
// th.detach();
if (channel < 0x100)
if (channel == 0x200)
{
// Heartbeat
}
else if (channel >= 0x100)
{
uint32_t packetType = channel;
packetType &= 0xFF;
pTerminal->RequestSampling(packetType, (uint64_t)scheduleTime, 0);
}
else
{
if (mediaType == XY_MEDIA_TYPE_PHOTO || mediaType == XY_MEDIA_TYPE_VIDEO)
{
@ -446,12 +457,7 @@ Java_com_xypower_mpapp_MicroPhotoService_notifyToTakePhoto(
{
pTerminal->StopStream(channel, preset, 0);
}
}
else
{
uint32_t packetType = channel;
packetType &= 0xFF;
pTerminal->RequestSampling(packetType, (uint64_t)scheduleTime, 0);
}
return JNI_TRUE;
@ -527,7 +533,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_xypower_mpapp_MicroPhotoService_sendHeartbeat(
JNIEnv* env,
jobject pThis,
jlong handler, jint signalLevel) {
jlong handler, jint signalLevel, jboolean scheduled) {
CTerminal* pTerminal = reinterpret_cast<CTerminal *>(handler);
if (pTerminal == NULL)
@ -541,9 +547,10 @@ Java_com_xypower_mpapp_MicroPhotoService_sendHeartbeat(
device->UpdateSignalLevel(signalLevel);
}
pTerminal->SendHeartbeat();
pTerminal->SendHeartbeat(scheduled != JNI_FALSE);
#ifdef OUTPUT_DBG_INFO
#if 0
std::thread t([]()
{
time_t ts = time(NULL);
@ -557,6 +564,7 @@ Java_com_xypower_mpapp_MicroPhotoService_sendHeartbeat(
});
t.detach();
#endif
#endif
return JNI_TRUE;
@ -959,19 +967,21 @@ Java_com_xypower_mpapp_MicroPhotoService_recordingFinished(
extern "C" JNIEXPORT jboolean JNICALL
Java_com_xypower_mpapp_MicroPhotoService_reloadConfigs(
JNIEnv* env,
jobject pThis, jlong handler) {
jobject pThis, jlong handler, jint channelToClean) {
CTerminal* pTerminal = reinterpret_cast<CTerminal *>(handler);
if (pTerminal == NULL)
{
return JNI_FALSE;
}
bool res = pTerminal->LoadAppConfigs();
if (channelToClean != -1)
{
pTerminal->CleanCaptureSchedules((uint32_t)((int)channelToClean));
}
bool res = pTerminal->LoadAppConfigs(true);
return res ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_xypower_mpapp_MicroPhotoService_sendExternalPhoto(
JNIEnv* env, jclass cls, jlong handler, jstring path, jlong photoInfo) {
@ -1510,3 +1520,59 @@ Java_com_xypower_mpapp_MicroPhotoService_sendCameraCtrl(
pTerminal->SendCameraCtrl(channel, preset, cmd);
}
extern "C" JNIEXPORT void JNICALL
Java_com_xypower_mpapp_MicroPhotoService_notifyTimeUpdated(
JNIEnv* env, jobject pThis, jlong handle) {
CTerminal* pTerminal = reinterpret_cast<CTerminal *>(handle);
if (pTerminal == NULL)
{
return;
}
std::thread t([pTerminal]()
{
pTerminal->OnTimeUpdated();
});
t.detach();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_xypower_mpapp_MicroPhotoService_sendBasicInfo(JNIEnv *env, jobject thiz, jlong handler) {
// TODO: implement sendBasicInfo()
CTerminal* pTerminal = reinterpret_cast<CTerminal *>(handler);
if (pTerminal == NULL)
{
return JNI_FALSE;
}
pTerminal->SendBasicInfo();
return JNI_TRUE;
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_xypower_mpapp_MicroPhotoService_sendWorkStatus(JNIEnv *env, jobject thiz, jlong handler) {
// TODO: implement sendWorkStatus()
CTerminal* pTerminal = reinterpret_cast<CTerminal *>(handler);
if (pTerminal == NULL)
{
return JNI_FALSE;
}
pTerminal->SendWorkStatus();
return JNI_TRUE;
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_xypower_mpapp_MicroPhotoService_sendFault(JNIEnv *env, jobject thiz, jlong handler, jstring faultCode, jstring faultInfo) {
// TODO: implement sendFault()
CTerminal* pTerminal = reinterpret_cast<CTerminal *>(handler);
if (pTerminal == NULL)
{
return JNI_FALSE;
}
std::string faultInfoStr = jstring2string(env, faultInfo);
pTerminal->SendFaultInfo(faultInfoStr);
return JNI_TRUE;
}

File diff suppressed because it is too large Load Diff

@ -234,7 +234,7 @@ public:
virtual bool InstallAPP(const std::string& path, unsigned int delayedTime);
virtual bool Reboot(int resetType, bool manually, const std::string& reason, uint32_t timeout = 1000);
virtual bool EnableGPS(bool enabled);
virtual float QueryBattaryVoltage(int timesForAvg, bool* isCharging);
virtual int QueryBattaryVoltage(int timesForAvg, int* isCharging);
virtual uint32_t QueryLdr();
virtual bool RequestPosition();
virtual timer_uid_t RegisterHeartbeat(unsigned int timerType, unsigned int timeout, time_t tsForNextPhoto);
@ -280,20 +280,19 @@ public:
net_handle_t GetEthnetHandle() const;
VendorCtrl* MakeVendorCtrl(int vendor, uint8_t channel, const std::string& ip, const std::string& userName, const std::string& password, net_handle_t netHandle);
VendorCtrl* MakeVendorCtrl(int vendor, uint8_t channel, const std::string& ip, const std::string& userName, const std::string& password, net_handle_t netHandle, bool syncTime);
protected:
std::string GetFileName() const;
bool SendBroadcastMessage(std::string action, int value);
// bool MatchCaptureSizeRequest(ACameraManager *cameraManager, const char *selectedCameraId, unsigned int width, unsigned int height, uint32_t cameraOrientation_,
bool TakePhotoWithNetCamera(IDevice::PHOTO_INFO& localPhotoInfo, const std::string& path, std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool TakeVideoWithNetCamera(IDevice::PHOTO_INFO& localPhotoInfo, const std::string& path, std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool StartPushStreaming(IDevice::PHOTO_INFO& localPhotoInfo, const std::string& url, std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool PostProcessPhoto(const PHOTO_INFO& photoInfo, const vector<IDevice::OSD_INFO>& osds, const std::string& path, const std::string& cameraInfo, cv::Mat mat);
bool TakePhotoWithNetCamera(const IDevice::PHOTO_INFO& localPhotoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool TakeVideoWithNetCamera(const IDevice::PHOTO_INFO& localPhotoInfo, const std::string& path, const std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool StartPushStreaming(const IDevice::PHOTO_INFO& localPhotoInfo, const std::string& url, const std::vector<IDevice::OSD_INFO>& osds, std::shared_ptr<PowerControl> powerCtrlPtr);
bool PostProcessPhoto(const PHOTO_INFO& photoInfo, const vector<IDevice::OSD_INFO>& osds, const std::string& path, const std::string& cameraInfo, cv::Mat mat, time_t takingTime);
inline bool TakePhotoCb(int res, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime, const std::vector<IDevice::RECOG_OBJECT>& objects) const
{
if (m_listener != NULL)
@ -362,6 +361,10 @@ protected:
void SetStaticIp(const std::string& iface, const std::string& ip, const std::string& netmask, const std::string& gateway);
void ConvertDngToPng(const std::string& dngPath, const std::string& pngPath);
void SetStaticIp();
void ShutdownEthernet();
int ExecuteCommand(const std::string& cmd);
static std::string BuildCaptureResultInfo(ACameraMetadata* result, uint32_t ldr, uint32_t duration, bool burst);
protected:
@ -393,6 +396,7 @@ protected:
jmethodID mRequestPositionMid;
jmethodID mExecHdrplusMid;
jmethodID mSetStaticIpMid;
jmethodID mExecuteCmdMid;
jmethodID mConvertDngToPngMid;

@ -182,7 +182,12 @@ void PtzController::PtzProc()
{
//if(timeout >= CAMERA_SELF_TEST_TIME)
{
XYLOG(XYLOG_SEVERITY_INFO, "开始查询云台自检状态timeout=%d秒", timeout);
#ifndef NDEBUG
if (timeout == 1 || ((timeout % 10) == 0))
#endif
{
XYLOG(XYLOG_SEVERITY_INFO, "开始查询云台自检状态timeout=%u秒", (uint32_t)timeout);
}
if(0 == QueryPtzState(&ptz_state, QUERY_PTZ_STATE, cmd.serfile, cmd.baud, cmd.addr))
{
if(0 == ptz_state.ptz_status)
@ -346,7 +351,14 @@ void PtzController::PtzProc()
photo_move_preset_time = time(NULL);
}
}
m_pPhoneDevice->TakePhotoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
if(cmd.photoParams->mPhotoInfo.mediaType == 1)
m_pPhoneDevice->TakeVideoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
else if ((cmd.photoParams->mPhotoInfo.mediaType == XY_MEDIA_TYPE_STREAM || cmd.photoParams->mPhotoInfo.mediaType == XY_MEDIA_TYPE_STREAM_OFF))
{
m_pPhoneDevice->StartPushStreaming(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
}
else
m_pPhoneDevice->TakePhotoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl);
state = PTZS_IDLE;
}

File diff suppressed because it is too large Load Diff

@ -392,7 +392,7 @@ void Gm_OpenSerialPort(int devidx);
// 关闭串口通讯
void Gm_CloseSerialPort();
void DebugLog(int commid, const char *szbuf, char flag);
void DBG_LOG(int commid, char flag, const char* format, ...);
int SaveLogTofile(int commid, const char *szbuf);
// 功能说明:串口发送数据 返回实际发送的字节数
int GM_SerialComSend(const unsigned char * cSendBuf, size_t nSendLen, int commid);
@ -534,6 +534,8 @@ int GM_CameraSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam);
int QueryPtzState(PTZ_STATE *ptz_state, int cmdidx, const char *serfile, unsigned int baud, int addr);
void MakePtzStateQueryCommand(SIO_PARAM_SERIAL_DEF *pPortParam, uint8_t cmdidx);
int Query_BDGNSS_Data(BD_GNSS_DATA *BD_data, int samptime, const char *serfile, unsigned int baud);
int GM_BdSerialTimer(SIO_PARAM_SERIAL_DEF *pPortParam);

@ -33,80 +33,6 @@
#include "mtk_platform_metadata_tag.h"
#include "mtk_metadata_tag.h"
#define MTK_MFBMODE_TAG "com.mediatek.mfbmode"
#define MTK_MFNR_ENABLE_TAG "com.mediatek.3afeature.mfnrenable"
#define MTK_VENDOR_TAG_SECTION 0x8000
#define MTK_MFNR_FEATURE 4
#define MTK_MFNR_FEATURE_START ((MTK_MFNR_FEATURE + MTK_VENDOR_TAG_SECTION) << 16)
#define MTK_MFNR_FEATURE_MFB_MODE MTK_MFNR_FEATURE_START
#define MTK_MFNR_FEATURE_MFB_RESULT (MTK_MFNR_FEATURE_START + 1)
#define MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES (MTK_MFNR_FEATURE_START + 2)
#define MTK_MFNR_FEATURE_MFB_AUTO 0xFF
#define MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING_MFNR 1
// #define MTK_3A_MFNR_ENABLE "com.mediatek.3afeature.mfnrenable"
#define MTK_3A_MFNR_INTENSITY_TAG "com.mediatek.3afeature.mfnrintensity"
void SetupMFNR(ACameraMetadata* characteristics, ACaptureRequest* request) {
// 1. 设置基础的相机参数
// ACaptureRequest_setEntry_i32(request, ACAMERA_CONTROL_MODE, 1, ACAMERA_CONTROL_MODE_AUTO);
camera_status_t status;
// __system_property_set("vendor.mfll.force", "1");
#if 0
int32_t tagCount = 0;
const uint32_t* tags = nullptr;
ACameraMetadata_getAllTags(characteristics, &tagCount, &tags);
for (int32_t i = 0; i < tagCount; i++) {
if (MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES == tags[i])
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES Tag ID: 0x%x\n", tags[i]);
}
}
ACameraMetadata_const_entry entry;
status = ACameraMetadata_getConstEntry(characteristics, MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES: 0x%x\n", entry.data.i32[i]);
}
}
#endif
uint8_t nrMode = ACAMERA_NOISE_REDUCTION_MODE_HIGH_QUALITY;
status = ACaptureRequest_setEntry_u8(request, ACAMERA_NOISE_REDUCTION_MODE, 1, &nrMode);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set ACAMERA_NOISE_REDUCTION_MODE, status: %d", status);
}
uint8_t reqRemosaicEnable = 1;
status = ACaptureRequest_setEntry_u8(request, MTK_HAL_REQUEST_REMOSAIC_ENABLE, 1, &reqRemosaicEnable);
// int32_t ispTuning = MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING_MFNR;
// status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING, 1, &ispTuning);
uint8_t aeMode = MTK_CONTROL_AE_MODE_ON;
status = ACaptureRequest_setEntry_u8(request, MTK_CONTROL_AE_MODE, 1, &aeMode);
// 2. 设置 MediaTek 特定的 MFNR 参数
// 使用 vendor tag 描述符
// int32_t mfbMode = MTK_MFNR_FEATURE_MFB_AUTO; // 1 Enable MFNR
int32_t mfbMode = 1; // 1 Enable MFNR
status = ACaptureRequest_setEntry_i32(request, MTK_MFNR_FEATURE_MFB_MODE, 1, &mfbMode);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_MFNR_FEATURE_MFB_MODE, status: %d", status);
}
}
void saveYuvToFile(AImage* image, const std::string& filePath) {
int32_t width, height;
@ -286,6 +212,10 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA
camera_orientation = 0;
m_params = params;
if (m_params.burstCaptures == 0)
{
m_params.burstCaptures = 1;
}
m_firstFrame = true;
m_photoTaken = false;
mWidth = width;
@ -307,6 +237,8 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA
numberOfPrecaptures = 0;
m_precaptureStartTime = 0;
m_minTimestamp = 0;
activeArraySize[0] = 0;
activeArraySize[1] = 0;
@ -323,32 +255,24 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA
mPreviewOutputTarget = NULL;
mPreviewSessionOutput = NULL;
camera_device = 0;
mImageReader = NULL;
mImageWindow = NULL;
mOutputTarget = NULL;
mSessionOutput = NULL;
mImageReader2 = NULL;
mImageWindow2 = NULL;
mOutputTarget2 = NULL;
mSessionOutput2 = NULL;
camera_device = 0;
capture_session_output_container = 0;
capture_session = 0;
lightDetected = false;
mStableFrameCount = 0;
mResult = { 0 };
mLdr = ~0;
mFinalLdr = 0;
mFinalBurstCaptures = m_params.burstRawCapture == 0 ? m_params.burstCaptures : m_params.burstCaptures;
if (mFinalBurstCaptures == 0)
{
mFinalBurstCaptures = 1;
}
mFinalOutputFormat = (m_params.burstRawCapture == 0) ? AIMAGE_FORMAT_YUV_420_888 : AIMAGE_FORMAT_RAW16;
mFinalOutputFormat = AIMAGE_FORMAT_YUV_420_888;
}
NdkCamera::~NdkCamera()
@ -427,7 +351,7 @@ int NdkCamera::selfTest(const std::string& cameraId, int32_t& maxResolutionX, in
}
int NdkCamera::open(const std::string& cameraId) {
XYLOG(XYLOG_SEVERITY_DEBUG, "DBG::try open %s", cameraId.c_str());
// XYLOG(XYLOG_SEVERITY_DEBUG, "DBG::try open %s", cameraId.c_str());
// camera_facing = _camera_facing;
@ -786,7 +710,7 @@ int NdkCamera::open(const std::string& cameraId) {
}
}
XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::Open %s Orientation=%d width=%d height=%d", cameraId.c_str(), camera_orientation, foundRes.width(), foundRes.height());
XYLOG(XYLOG_SEVERITY_DEBUG, "CAM Open %s Orientation=%d width=%d height=%d", cameraId.c_str(), camera_orientation, foundRes.width(), foundRes.height());
status = ACaptureSessionOutputContainer_create(&capture_session_output_container);
@ -832,31 +756,7 @@ int NdkCamera::open(const std::string& cameraId) {
status = ACaptureSessionOutputContainer_add(capture_session_output_container, mSessionOutput);
if (m_params.burstRawCapture == 1) // Auto
{
mstatus = AImageReader_new(foundRes.org_width(), foundRes.org_height(), AIMAGE_FORMAT_YUV_420_888, burstCaptures, &mImageReader2);
if (mstatus == AMEDIA_OK)
{
AImageReader_ImageListener listener;
listener.context = this;
listener.onImageAvailable = ::onImageAvailable;
mstatus = AImageReader_setImageListener(mImageReader2, &listener);
mstatus = AImageReader_getWindow(mImageReader2, &mImageWindow2);
ANativeWindow_acquire(mImageWindow2);
}
status = ACameraOutputTarget_create(mImageWindow2, &mOutputTarget2);
status = ACaptureSessionOutput_create(mImageWindow2, &mSessionOutput2);
status = ACaptureSessionOutputContainer_add(capture_session_output_container, mSessionOutput2);
}
CaptureRequest *request = CreateRequest(true);
if (m_params.burstRawCapture == 0 && m_params.customHdr != 0)
{
// SetupMFNR(mCharacteristics.get(), request->request);
}
mCaptureRequests.push_back(request);
// capture session
@ -866,7 +766,11 @@ int NdkCamera::open(const std::string& cameraId) {
camera_capture_session_state_callbacks.onReady = ::onSessionReady;
camera_capture_session_state_callbacks.onClosed = onSessionClosed;
status = ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session);
AASSERT(status == ACAMERA_OK, "Failed to call ACameraDevice_createCaptureSession, status=%d", status);
if (status != ACAMERA_OK)
{
XYLOG(XYLOG_SEVERITY_ERROR, "Failed to call ACameraDevice_createCaptureSession, status=%d", status);
return 1;
}
ACameraCaptureSession_captureCallbacks capture_session_capture_callbacks;
capture_session_capture_callbacks.context = this;
@ -889,23 +793,36 @@ int NdkCamera::open(const std::string& cameraId) {
return status == ACAMERA_OK ? 0 : 1;
}
NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest)
NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest, int32_t sensitivity/* = -1*/)
{
camera_status_t status = ACAMERA_OK;
CaptureRequest *request = new CaptureRequest();
std::memset(request, 0, sizeof(CaptureRequest));
bool autoSwitchToOneFrame = (m_params.burstRawCapture == 1) && (mFinalOutputFormat == AIMAGE_FORMAT_YUV_420_888);
request->pThis = this;
request->imageReader = isPreviewRequest ? mPreviewImageReader : (autoSwitchToOneFrame ? mImageReader2 : mImageReader);
request->imageWindow = isPreviewRequest ? mPreviewImageWindow : (autoSwitchToOneFrame ? mImageWindow2 : mImageWindow);
request->imageTarget = isPreviewRequest ? mPreviewOutputTarget : (autoSwitchToOneFrame ? mOutputTarget2 : mOutputTarget);
request->sessionOutput = isPreviewRequest ? mPreviewSessionOutput : (autoSwitchToOneFrame ? mSessionOutput2 : mSessionOutput);
// request->templateId = isPreviewRequest ? TEMPLATE_PREVIEW : (ACameraDevice_request_template)m_params.requestTemplate;
request->templateId = (ACameraDevice_request_template)m_params.requestTemplate;
request->imageReader = isPreviewRequest ? mPreviewImageReader : mImageReader;
request->imageWindow = isPreviewRequest ? mPreviewImageWindow : mImageWindow;
request->imageTarget = isPreviewRequest ? mPreviewOutputTarget : mOutputTarget;
request->sessionOutput = isPreviewRequest ? mPreviewSessionOutput : mSessionOutput;
request->templateId = isPreviewRequest ? TEMPLATE_PREVIEW : (ACameraDevice_request_template)m_params.requestTemplate;
// request->templateId = (ACameraDevice_request_template)m_params.requestTemplate;
uint8_t captureIntent = isPreviewRequest ? ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW : GetCaptureIntent((ACameraDevice_request_template)m_params.requestTemplate);
#if 0
bool forceToPreview = false;
if (!isPreviewRequest && sensitivity >= 150 && sensitivity <= 400 && (m_params.burstRawCapture == 2 || m_params.burstRawCapture == 3))
{
if (request->templateId == TEMPLATE_STILL_CAPTURE)
{
request->templateId = TEMPLATE_PREVIEW;
captureIntent = ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW;
forceToPreview = true;
// mCaptureRequests.push_back(request);
XYLOG(XYLOG_SEVERITY_WARNING, "Force to use preview mode to avoid pink issue ISO=%d CameraId=%s", sensitivity, mCameraId.c_str());
}
}
#endif
// capture request
status = ACameraDevice_createCaptureRequest(camera_device, request->templateId, &request->request);
@ -916,7 +833,6 @@ NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest)
uint8_t ctrlMode = ACAMERA_CONTROL_MODE_AUTO;
status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_MODE, 1, &ctrlMode);
uint8_t captureIntent = isPreviewRequest ? ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW : GetCaptureIntent((ACameraDevice_request_template)m_params.requestTemplate);
status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_CAPTURE_INTENT, 1, &captureIntent);
uint8_t flashMode = ACAMERA_FLASH_MODE_OFF;
@ -987,7 +903,17 @@ NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest)
status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode);
// ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_);
if ((aeCompensationRange.min_ != 0 || aeCompensationRange.max_ != 0) && m_params.compensation != 0)
if (m_params.minFps != 0)
{
int32_t fpsRange[2] = {m_params.minFps, 60};
// status = ACaptureRequest_setEntry_i32(request->request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE, 2, fpsRange);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set ACAMERA_CONTROL_AE_TARGET_FPS_RANGE: %d", status);
}
}
if ((aeCompensationRange.min_ != 0 || aeCompensationRange.max_ != 0) && m_params.compensation != 0)
{
int32_t compensation = m_params.compensation;
if (compensation < aeCompensationRange.min_)
@ -1096,6 +1022,46 @@ NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest)
// status = ACaptureSessionOutput_create(request->imageWindow, &request->sessionOutput);
// status = ACaptureSessionOutputContainer_add(capture_session_output_container, request->sessionOutput);
{
#if 0
uint8_t colorMode = ACAMERA_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX;
status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_COLOR_CORRECTION_MODE, 1, &colorMode);
// 设置均衡的RGGB增益
float rggbGains[4] = {1.0f, 1.0f, 1.0f, 1.0f};
status = ACaptureRequest_setEntry_float(request->request, ACAMERA_COLOR_CORRECTION_GAINS, 4, rggbGains);
// 设置单位色彩变换矩阵
float colorMatrix[9] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
status = ACaptureRequest_setEntry_float(request->request, ACAMERA_COLOR_CORRECTION_TRANSFORM, 9, colorMatrix);
#endif
if (m_params.burstRawCapture == 1)
{
SetupHDR(mCharacteristics.get(), request->request, sensitivity);
}
if (m_params.burstRawCapture == 2)
{
SetupMFNR(mCharacteristics.get(), request->request, false, sensitivity);
}
else if (m_params.burstRawCapture == 3)
{
SetupMFNR(mCharacteristics.get(), request->request, true, sensitivity);
}
else if (m_params.burstRawCapture == 4)
{
Setup3DNR(mCharacteristics.get(), request->request, sensitivity);
}
else if (m_params.burstRawCapture == 5)
{
SetupTonemapCurve(mCharacteristics.get(), request->request);
}
}
return request;
}
@ -1234,25 +1200,6 @@ void NdkCamera::close()
ALOGD("After Free mImageReader");
#endif
}
if (mOutputTarget2 != NULL)
{
ACameraOutputTarget_free(mOutputTarget2);
mOutputTarget2 = 0;
}
if (mImageWindow2 != NULL)
{
ANativeWindow_release(mImageWindow2);
mImageWindow2 = 0;
}
if (mImageReader2 != NULL)
{
AImageReader_setImageListener(mImageReader2, NULL);
//XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::AImageReader_delete %s", mCameraId.c_str());
AImageReader_delete(mImageReader2);
//XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::End AImageReader_delete %s", mCameraId.c_str());
mImageReader2 = 0;
}
if (mPreviewSessionOutput != NULL)
{
if (capture_session_output_container)
@ -1272,15 +1219,6 @@ void NdkCamera::close()
ACaptureSessionOutput_free(mSessionOutput);
mSessionOutput = 0;
}
if (mSessionOutput2 != NULL)
{
if (capture_session_output_container)
{
ACaptureSessionOutputContainer_remove(capture_session_output_container, mSessionOutput2);
}
ACaptureSessionOutput_free(mSessionOutput2);
mSessionOutput2 = 0;
}
if (capture_session_output_container)
{
@ -1346,7 +1284,7 @@ void NdkCamera::onImageAvailable(AImageReader* reader)
{
burstCaptures = 1;
}
if (m_params.burstRawCapture == 0)
if (true)
{
while (1)
{
@ -1452,6 +1390,7 @@ void NdkCamera::onImageAvailable(AImageReader* reader)
mstatus = AImage_getTimestamp(image, &frameTs);
#ifdef OUTPUT_DBG_INFO
#if 0
if (mWidth == 1920)
{
std::string dt = FormatLocalDateTime("%d%02d%02d%02d%02d%02d", time(NULL));
@ -1459,6 +1398,7 @@ void NdkCamera::onImageAvailable(AImageReader* reader)
fileName += "_" + mCameraId + std::to_string(frameTs) + ".yuv";
saveYuvToFile(image, fileName.c_str());
}
#endif
#endif
AImage_delete(image);
@ -1724,6 +1664,8 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
uint8_t awbState = ACAMERA_CONTROL_AWB_STATE_INACTIVE;
uint8_t afState = ACAMERA_CONTROL_AF_STATE_INACTIVE;
int32_t sensitivity = -1;
ACameraMetadata_const_entry val = { 0 };
val = { 0 };
status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AE_STATE, &val);
@ -1737,6 +1679,11 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AF_STATE, &val);
afState = (status == ACAMERA_OK) ? *(val.data.u8) : ACAMERA_CONTROL_AF_STATE_INACTIVE;
val = {0};
status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_SENSITIVITY, &val);
sensitivity = (status == ACAMERA_OK) ? *(val.data.i32) : -1;
// XYLOG(XYLOG_SEVERITY_DEBUG, "Preview State AFS=%u AES=%u AWBS=%u Time=%u", (unsigned int)afState, (unsigned int)aeState, (unsigned int)awbState, (unsigned int)(ts - m_startTime));
// Check if timeout
@ -1854,6 +1801,17 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
#endif
}
if (readyForCapture)
{
mStableFrameCount++;
if (mStableFrameCount >= 3) { // 确保连续3帧稳定
// 进行实际的静态抓拍
mStableFrameCount = 0;
} else {
readyForCapture = false; // 继续等待
}
}
if (readyForCapture/* && mCaptureRequests.size() > 1*/)
{
// Must update mFinalLdr As getBurstCaptures getOutputFormat depends mFinalLdr
@ -1862,23 +1820,10 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
mFinalLdr = mLdr;
}
XYLOG(XYLOG_SEVERITY_INFO, "Ready for Capture AFS=%u AES=%u AWBS=%u LDR=%u Time=%u",
(unsigned int)afState, (unsigned int)aeState, (unsigned int)awbState, mFinalLdr, (unsigned int)(ts - m_startTime));
if (m_params.burstRawCapture == 1)
{
if (mFinalLdr > 50)
{
XYLOG(XYLOG_SEVERITY_WARNING, "Switch to OneFrame Capture(YUV) As LDR=%u", mFinalLdr);
mFinalOutputFormat = AIMAGE_FORMAT_YUV_420_888;
mFinalBurstCaptures = 1;
}
}
XYLOG(XYLOG_SEVERITY_INFO, "Ready for Capture AFS=%u AES=%u AWBS=%u LDR=%u ISO=%d Time=%u",
(unsigned int)afState, (unsigned int)aeState, (unsigned int)awbState, mFinalLdr, sensitivity, (unsigned int)(ts - m_startTime));
uint32_t burstCaptures = getBurstCaptures();
if (burstCaptures == 0)
{
burstCaptures = 1;
}
std::vector<ACaptureRequest*> requests;
int sequenceId = 0;
@ -1886,11 +1831,7 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
for (int idx = 0; idx < burstCaptures; idx++)
{
CaptureRequest* request = CreateRequest(false);
if (m_params.burstRawCapture == 0 && m_params.customHdr != 0)
{
SetupMFNR(mCharacteristics.get(), request->request);
}
CaptureRequest* request = CreateRequest(false, sensitivity);
mCaptureRequests.push_back(request);
// CopyPreviewRequest(mCaptureRequests[idx]->request, result);
requests.push_back(request->request);
@ -1953,7 +1894,7 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
capture_session_capture_cb.onCaptureSequenceAborted = onCaptureSequenceAborted;
capture_session_capture_cb.onCaptureBufferLost = 0;
int numberOfRequests = requests.size();
int numberOfRequests = requests.size();
status = ACameraCaptureSession_capture(capture_session, &capture_session_capture_cb,
numberOfRequests, &requests[0], &sequenceId);
AASSERT(status == ACAMERA_OK, "Failed to call ACameraCaptureSession_capture, status=%d", status);
@ -1984,7 +1925,7 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque
int64_t resultTimestamp = GetTimestamp(result);
std::shared_ptr<ACameraMetadata> captureResult(pCopy, ACameraMetadata_free);
if (m_params.burstRawCapture == 0)
if (true)
{
m_locker.lock();
mCaptureResults.push_back(captureResult);
@ -2058,6 +1999,7 @@ int64_t NdkCamera::GetTimestamp(const ACameraMetadata* result)
void NdkCamera::FireOneCapture(uint64_t ts)
{
#ifdef OUTPUT_DBG_INFO
#if 0
if (mWidth == 1920 && mOneFrame.size() > 1)
{
std::string dt = FormatLocalDateTime("%d%02d%02d%02d%02d%02d", ts / 1000);
@ -2077,10 +2019,13 @@ void NdkCamera::FireOneCapture(uint64_t ts)
cv::imwrite(fileName, it->second, params);
}
}
#endif
#endif
onOneCapture(mCharacteristics, mCaptureResults.back(), mFinalLdr, ts - m_startTime, mOneFrame.back().second);
onOneCapture(mCharacteristics, mCaptureResultMap[mOneFrame.back().first], mFinalLdr, ts - m_startTime, mOneFrame.back().second);
}
void NdkCamera::FireBurstCapture()
@ -2089,7 +2034,7 @@ void NdkCamera::FireBurstCapture()
unsigned long long ts = GetMicroTimeStamp();
size_t expectedTimes = mCaptureRequests.size() - 1;
size_t expectedTimes = getBurstCaptures();
std::vector<std::shared_ptr<ACameraMetadata> > captureResults;
uint32_t ldr;
std::vector<std::shared_ptr<AImage> > captureFrames;
@ -2168,6 +2113,16 @@ void NdkCamera::CopyPreviewRequest(ACaptureRequest* request, const ACameraMetada
focusDistance = *val.data.f;
}
*/
// 添加AWB和色彩校正参数的复制
ACameraMetadata_const_entry entry;
if (ACameraMetadata_getConstEntry(previewResult, ACAMERA_COLOR_CORRECTION_GAINS, &entry) == ACAMERA_OK) {
ACaptureRequest_setEntry_float(request, ACAMERA_COLOR_CORRECTION_GAINS, entry.count, entry.data.f);
}
if (ACameraMetadata_getConstEntry(previewResult, ACAMERA_COLOR_CORRECTION_TRANSFORM, &entry) == ACAMERA_OK) {
ACaptureRequest_setEntry_float(request, ACAMERA_COLOR_CORRECTION_TRANSFORM, entry.count, entry.data.f);
}
}
void NdkCamera::onCaptureFailed(ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure)
@ -2236,7 +2191,7 @@ int32_t NdkCamera::getOutputFormat() const
int32_t NdkCamera::getBurstCaptures() const
{
return mFinalBurstCaptures;
return m_params.burstCaptures;
}
void NdkCamera::CreateSession(ANativeWindow* previewWindow,
@ -2537,4 +2492,451 @@ void NdkCamera::EnumCameraResult(ACameraMetadata* result, CAPTURE_RESULT& captur
val = {0};
status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION, &val);
captureResult.compensation = (status == ACAMERA_OK) ? *(val.data.i32) : 0;
val = {0};
status = ACameraMetadata_getConstEntry(result, MTK_HDR_FEATURE_HDR_DETECTION_RESULT, &val);
ALOGI("HDR Detection Result: %d", val.data.i32[0]);
val = {0};
status = ACameraMetadata_getConstEntry(result, MTK_HDR_FEATURE_HDR_MODE, &val);
if (status == ACAMERA_OK && val.count > 0) {
int32_t appliedHdrMode = val.data.i32[0];
ALOGI("Applied HDR Mode: %d", appliedHdrMode);
// 判断是否与请求的HDR模式一致
if (appliedHdrMode == MTK_HDR_FEATURE_HDR_MODE_AUTO ||
appliedHdrMode == MTK_HDR_FEATURE_HDR_MODE_ON) {
ALOGI("HDR mode successfully applied");
}
}
// 检查 HDR 是否激活(最重要的指标) dd
// 从结果中获取 MTK_HDR_FEATURE_HDR_HAL_MODE
val = {0};
status = ACameraMetadata_getConstEntry(result, MTK_HDR_FEATURE_HDR_HAL_MODE, &val);
if (status == ACAMERA_OK && val.count > 0) {
int32_t hdrHalMode = val.data.i32[0];
ALOGI("HDR HAL Mode: %d", hdrHalMode);
if (hdrHalMode != MTK_HDR_FEATURE_HDR_HAL_MODE_OFF) {
ALOGI("HDR is actively working on hardware level");
}
}
val = {0};
status = ACameraMetadata_getConstEntry(result, MTK_3A_ISP_FUS_NUM, &val);
if (status == ACAMERA_OK && val.count > 0) {
int32_t fusionFrames = val.data.i32[0];
ALOGI("多帧融合数量: %d", fusionFrames);
if (fusionFrames > 1) {
ALOGI("正在使用多帧融合,这通常表明 HDR 处理正在进行");
}
}
int aa = 0;
}
void NdkCamera::SetupMFNR(ACameraMetadata* characteristics, ACaptureRequest* request, bool ais, int32_t sensitivity)
{
// 1. 设置基础的相机参数
camera_status_t status;
// __system_property_set("vendor.mfll.force", "1");
#if 0
int32_t tagCount = 0;
const uint32_t* tags = nullptr;
ACameraMetadata_getAllTags(characteristics, &tagCount, &tags);
for (int32_t i = 0; i < tagCount; i++) {
if (MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES == tags[i])
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES Tag ID: 0x%x\n", tags[i]);
}
}
ACameraMetadata_const_entry entry;
status = ACameraMetadata_getConstEntry(characteristics, MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES: 0x%x\n", entry.data.i32[i]);
}
}
ACameraMetadata_const_entry entry = { 0 };
status = ACameraMetadata_getConstEntry(characteristics, MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES: 0x%x\n", entry.data.i32[i]);
}
}
#endif
// 2. 设置 MediaTek 特定的 MFNR 参数
// 使用 vendor tag 描述符
// int32_t mfbMode = MTK_MFNR_FEATURE_MFB_AUTO; // 1 Enable MFNR
int32_t mfbMode = ais ? 2 : 1; // 1 Enable MFNR
uint8_t aeMode = MTK_CONTROL_AE_MODE_ON;
// status = ACaptureRequest_setEntry_u8(request, MTK_CONTROL_AE_MODE, 1, &aeMode);
// int32_t mfbMode = ais ? 2 : 1; // 1 Enable MFNR
status = ACaptureRequest_setEntry_i32(request, MTK_MFNR_FEATURE_MFB_MODE, 1, &mfbMode);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_MFNR_FEATURE_MFB_MODE, status: %d", status);
}
int32_t aeTargetMode = 1; //MTK_3A_FEATURE_AE_TARGET_MODE_LE_FIX;
status = ACaptureRequest_setEntry_i32(request, MTK_3A_FEATURE_AE_TARGET_MODE, 1, &aeTargetMode);
if (status != ACAMERA_OK) {
ALOGE("Failed to set MTK_3A_FEATURE_AE_TARGET_MODE: %d", status);
}
// 设置为长曝光级别(3)
int32_t exposureLevel = MTK_3A_FEATURE_AE_EXPOSURE_LEVEL_LONG; // MTK_3A_FEATURE_AE_EXPOSURE_LEVEL_LONG
status = ACaptureRequest_setEntry_i32(request, MTK_3A_FEATURE_AE_EXPOSURE_LEVEL, 1,&exposureLevel);
if (status != ACAMERA_OK) {
ALOGE("Failed to set exposure level: %d", status);
}
int32_t ispTuning = MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING_MFNR;
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING, 1, &ispTuning);
uint8_t reqRemosaicEnable = 1;
status = ACaptureRequest_setEntry_u8(request, MTK_HAL_REQUEST_REMOSAIC_ENABLE, 1, &reqRemosaicEnable);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_HAL_REQUEST_REMOSAIC_ENABLE, status: %d", status);
}
if (m_params.compensation != 0)
{
int32_t compensation = m_params.compensation;
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_AE_EXPOSURE_COMPENSATION, 1, &compensation);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_CONTROL_AE_EXPOSURE_COMPENSATION, status: %d", status);
}
}
}
void NdkCamera::Setup3DNR(ACameraMetadata* characteristics, ACaptureRequest* request, int32_t sensitivity)
{
// 1. 设置基础的相机参数
camera_status_t status;
#if 0
int32_t tagCount = 0;
const uint32_t* tags = nullptr;
ACameraMetadata_getAllTags(characteristics, &tagCount, &tags);
for (int32_t i = 0; i < tagCount; i++) {
if (MTK_NR_FEATURE_AVAILABLE_3DNR_MODES == tags[i])
{
ALOGI("MTK_NR_FEATURE_AVAILABLE_3DNR_MODES Tag ID: 0x%x\n", tags[i]);
}
}
ACameraMetadata_const_entry entry;
status = ACameraMetadata_getConstEntry(characteristics, MTK_NR_FEATURE_AVAILABLE_3DNR_MODES, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_NR_FEATURE_AVAILABLE_3DNR_MODES: 0x%x\n", entry.data.i32[i]);
}
}
#endif
int32_t nrMode = MTK_NR_FEATURE_3DNR_MODE_ON;
status = ACaptureRequest_setEntry_i32(request, MTK_NR_FEATURE_3DNR_MODE, 1, &nrMode);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_NR_FEATURE_3DNR_MODE, status: %d", status);
}
uint8_t reqRemosaicEnable = 1;
status = ACaptureRequest_setEntry_u8(request, MTK_HAL_REQUEST_REMOSAIC_ENABLE, 1, &reqRemosaicEnable);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_HAL_REQUEST_REMOSAIC_ENABLE, status: %d", status);
}
if (m_params.compensation != 0)
{
int32_t compensation = m_params.compensation;
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_AE_EXPOSURE_COMPENSATION, 1, &compensation);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_CONTROL_AE_EXPOSURE_COMPENSATION, status: %d", status);
}
}
}
void NdkCamera::SetupHDR(ACameraMetadata* characteristics, ACaptureRequest* request, int32_t sensitivity)
{
// 1. 设置基础的相机参数
camera_status_t status;
__system_property_set("vendor.forceset.hdrmode", "1");
#if 1
// 首先检查相机是否支持 HDR
ACameraMetadata_const_entry entry = { 0 };
status = ACameraMetadata_getConstEntry(characteristics, MTK_HDR_FEATURE_AVAILABLE_HDR_MODES_PHOTO, &entry);
if (status == ACAMERA_OK) {
bool hdrSupported = false;
for (int i = 0; i < entry.count; i++) {
ALOGI("支持的 HDR 模式: 0x%x", entry.data.i32[i]);
if (entry.data.i32[i] == MTK_HDR_FEATURE_HDR_MODE_AUTO ||
entry.data.i32[i] == MTK_HDR_FEATURE_HDR_MODE_ON) {
hdrSupported = true;
}
}
if (!hdrSupported) {
ALOGI("警告: 相机不支持 AUTO 或 ON 模式的 HDR");
return;
}
} else {
ALOGI("警告: 无法获取支持的 HDR 模式列表");
}
int32_t tagCount = 0;
const uint32_t* tags = nullptr;
ACameraMetadata_getAllTags(characteristics, &tagCount, &tags);
for (int32_t i = 0; i < tagCount; i++) {
if (MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES == tags[i])
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES Tag ID: 0x%x\n", tags[i]);
}
}
entry = { 0 };
status = ACameraMetadata_getConstEntry(characteristics, MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_MFNR_FEATURE_AVAILABLE_MFB_MODES: 0x%x\n", entry.data.i32[i]);
}
}
#endif
entry = { 0 };
status = ACameraMetadata_getConstEntry(characteristics, MTK_HDR_FEATURE_AVAILABLE_HDR_MODES_PHOTO, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_HDR_FEATURE_AVAILABLE_HDR_MODES_PHOTO: 0x%x\n", entry.data.i32[i]);
}
}
// 2. 设置 MediaTek 特定的 HDR 参数
// 使用 vendor tag 描述符
uint8_t aeMode = MTK_CONTROL_AE_MODE_ON;
status = ACaptureRequest_setEntry_u8(request, MTK_CONTROL_AE_MODE, 1, &aeMode);
uint8_t sceneMode = ACAMERA_CONTROL_SCENE_MODE_HDR;
status = ACaptureRequest_setEntry_u8(request, ACAMERA_CONTROL_SCENE_MODE, 1, &sceneMode);
if (status == ACAMERA_OK) {
ALOGI("已设置场景模式为 HDR");
// 启用场景模式控制
uint8_t sceneModeControl = ACAMERA_CONTROL_MODE_USE_SCENE_MODE;
ACaptureRequest_setEntry_u8(request, ACAMERA_CONTROL_MODE, 1, &sceneModeControl);
}
int32_t hdrMode = MTK_HDR_FEATURE_HDR_MODE_AUTO; // 1 Enable HDR
ALOGI("Try to set MTK_HDR_FEATURE_HDR_MODE = %d", hdrMode);
status = ACaptureRequest_setEntry_i32(request, MTK_HDR_FEATURE_HDR_MODE, 1, &hdrMode);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_HDR_FEATURE_HDR_MODE, status: %d", status);
}
int32_t halHdrMode = MTK_HDR_FEATURE_HDR_HAL_MODE_MSTREAM_CAPTURE;
status = ACaptureRequest_setEntry_i32(request, MTK_HDR_FEATURE_HDR_HAL_MODE, 1, &halHdrMode);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_HDR_FEATURE_HDR_HAL_MODE, status: %d", status);
}
// int32_t ispTuning = MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING_AIHDR;
// status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_CAPTURE_HINT_FOR_ISP_TUNING, 1, &ispTuning);
uint8_t reqRemosaicEnable = 1;
status = ACaptureRequest_setEntry_u8(request, MTK_HAL_REQUEST_REMOSAIC_ENABLE, 1, &reqRemosaicEnable);
if (status != ACAMERA_OK)
{
ALOGE("Failed to set MTK_HAL_REQUEST_REMOSAIC_ENABLE, status: %d", status);
}
// 设置HDR的AE目标模式
int32_t aeTargetMode = MTK_3A_FEATURE_AE_TARGET_MODE_NORMAL;
status = ACaptureRequest_setEntry_i32(request, MTK_3A_FEATURE_AE_TARGET_MODE, 1, &aeTargetMode);
// 设置更高的曝光等级
int32_t exposureLevel = MTK_3A_FEATURE_AE_EXPOSURE_LEVEL_LONG; // 选择长曝光模式
status = ACaptureRequest_setEntry_i32(request, MTK_3A_FEATURE_AE_EXPOSURE_LEVEL, 1, &exposureLevel);
int32_t hdrModeParam = 1; // 偏向于亮部
status = ACaptureRequest_setEntry_i32(request, MTK_3A_HDR_MODE, 1, &hdrModeParam);
if ((aeCompensationRange.min_ != 0 || aeCompensationRange.max_ != 0) && m_params.compensation != 0)
{
int32_t compensation = m_params.compensation;
if (compensation < aeCompensationRange.min_)
{
compensation = aeCompensationRange.min_;
}
if (compensation > aeCompensationRange.max_)
{
compensation = aeCompensationRange.max_;
}
ACaptureRequest_setEntry_i32(request, MTK_CONTROL_AE_EXPOSURE_COMPENSATION, 1, &compensation);
if (compensation > 0)
{
// 调整HDR混合ISO模式优化暗部
int32_t hdrMixedIso = 1; // 启用混合ISO
status = ACaptureRequest_setEntry_i32(request, MTK_3A_AE_HDR_MIXED_ISO, 1, &hdrMixedIso);
// 降低高光恢复强度,允许更多过曝 - 这个设置没有问题
float hlrRatio = 0.3f;
status = ACaptureRequest_setEntry_float(request, MTK_ISP_HLR_RATIO, 1, &hlrRatio);
int32_t aeTargetMode = MTK_3A_FEATURE_AE_TARGET_MODE_MSTREAM_VHDR; // 多帧HDR模式
status = ACaptureRequest_setEntry_i32(request, MTK_3A_FEATURE_AE_TARGET_MODE, 1, &aeTargetMode);
int32_t ispBrightness = MTK_CONTROL_ISP_BRIGHTNESS_HIGH; // 范围通常是0-10值越大越亮
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_ISP_BRIGHTNESS, 1, &ispBrightness);
}
}
int aa = 0;
}
bool NdkCamera::SetupTonemapCurve(ACameraMetadata* characteristics, ACaptureRequest* request)
{
camera_status_t status;
#if 1
int32_t tagCount = 0;
const uint32_t* tags = nullptr;
ACameraMetadata_getAllTags(characteristics, &tagCount, &tags);
for (int32_t i = 0; i < tagCount; i++) {
if (MTK_3A_FEATURE_AE_TARGET_MODE == tags[i])
{
ALOGI("MTK_3A_FEATURE_AE_TARGET_MODE Tag ID: 0x%x\n", tags[i]);
}
}
ACameraMetadata_const_entry entry;
status = ACameraMetadata_getConstEntry(characteristics, MTK_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, &entry);
if (status == ACAMERA_OK)
{
for (int i = 0; i < entry.count; i++)
{
ALOGI("MTK_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES: %d\n", entry.data.i32[i]);
}
}
#endif
// MTK_CONTROL_AE_TARGET_FPS_RANGE
// 4. 构建范围值
int32_t fpsRange[2] = {60, 60};
// 5. 设置请求参数
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_AE_TARGET_FPS_RANGE, 2, fpsRange);
if (status != ACAMERA_OK) {
ALOGE("Failed to set MTK_CONTROL_AE_TARGET_FPS_RANGE: %d", status);
}
int32_t aeTargetMode = 1; // MTK_3A_FEATURE_AE_TARGET_MODE_STAGGER_3EXP;
status = ACaptureRequest_setEntry_i32(request, MTK_3A_FEATURE_AE_TARGET_MODE, 1, &aeTargetMode);
if (status != ACAMERA_OK) {
ALOGE("Failed to set MTK_3A_FEATURE_AE_TARGET_MODE: %d", status);
}
int32_t zsl = MTK_CONTROL_ENABLE_ZSL_TRUE;
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_ENABLE_ZSL, 1, &zsl);
if (status != ACAMERA_OK) {
ALOGE("Failed to set MTK_CONTROL_ENABLE_ZSL: %d", status);
}
int32_t brightness = MTK_CONTROL_ISP_BRIGHTNESS_LOW;
status = ACaptureRequest_setEntry_i32(request, MTK_CONTROL_ISP_BRIGHTNESS, 1, &brightness);
if (status != ACAMERA_OK) {
ALOGE("Failed to set MTK_CONTROL_ISP_BRIGHTNESS_LOW: %d", status);
}
#if 0
// 创建色调映射曲线点 - 每个点包含(x,y)坐标,表示输入和输出亮度值的映射
// 这个曲线用于压制高光,减少过曝
const int numPoints = 5;
float curve[numPoints * 2] = {
0.0f, 0.0f, // 阴影部分保持不变
0.25f, 0.22f, // 稍微压暗中间调
0.5f, 0.45f, // 中间调较明显压暗
0.75f, 0.65f, // 高光部分明显压暗
1.0f, 0.85f // 最亮部分显著压暗
};
// 红色通道曲线
ACameraMetadata_const_entry entry;
int result = ACaptureRequest_setEntry_float(request,
ACAMERA_TONEMAP_CURVE_RED,
numPoints * 2,
curve);
if (result != ACAMERA_OK) {
ALOGE("Failed to set red tonemap curve: %d", result);
return false;
}
// 绿色通道曲线 (使用相同的曲线)
result = ACaptureRequest_setEntry_float(request,
ACAMERA_TONEMAP_CURVE_GREEN,
numPoints * 2,
curve);
if (result != ACAMERA_OK) {
ALOGE("Failed to set green tonemap curve: %d", result);
return false;
}
// 蓝色通道曲线 (使用相同的曲线)
result = ACaptureRequest_setEntry_float(request,
ACAMERA_TONEMAP_CURVE_BLUE,
numPoints * 2,
curve);
if (result != ACAMERA_OK) {
ALOGE("Failed to set blue tonemap curve: %d", result);
return false;
}
// 设置色调映射模式为曲线模式
uint8_t tonemapMode = ACAMERA_TONEMAP_MODE_CONTRAST_CURVE;
result = ACaptureRequest_setEntry_u8(request,
ACAMERA_TONEMAP_MODE,
1,
&tonemapMode);
if (result != ACAMERA_OK) {
ALOGE("Failed to set tonemap mode: %d", result);
return false;
}
#endif
return true;
}

@ -40,6 +40,9 @@ static const uint64_t kMaxExposureTime = static_cast<uint64_t>(250000000);
#define WAIT_AF_LOCKED 4
#define PREVIEW_REQUEST_IDX 0
#define CAPTURE_REQUEST_IDX 1
#define DEFAULT_WARMUP_TIME 250 // 250ms
class CameraManager
{
@ -82,10 +85,11 @@ public:
unsigned int orientation:3;
unsigned int zoom : 1;
unsigned int wait3ALocked : 3;
unsigned int burstRawCapture : 2;
unsigned int burstRawCapture : 3;
unsigned int customHdr : 1;
unsigned int hdrStep : 3;
unsigned int reserved : 12;
unsigned int minFps : 4;
unsigned int reserved : 7;
int64_t exposureTime;
unsigned int sensitivity;
int compensation;
@ -161,7 +165,7 @@ public:
void CreateSession(ANativeWindow* previewWindow, ANativeWindow* jpgWindow, bool manaulPreview, int32_t imageRotation, int32_t width, int32_t height);
void CreateSession(ANativeWindow* previewWindow);
CaptureRequest* CreateRequest(bool isPreviewRequest);
CaptureRequest* CreateRequest(bool isPreviewRequest, int32_t sensitivity = -1);
void DestroyRequest(CaptureRequest* request);
void DestroySession();
@ -202,6 +206,12 @@ public:
static bool convertAImageToNv21(AImage* image, uint8_t** nv21, int32_t& width, int32_t& height);
static void EnumCameraResult(ACameraMetadata* result, CAPTURE_RESULT& captureResult);
protected:
void SetupMFNR(ACameraMetadata* characteristics, ACaptureRequest* request, bool ais, int32_t sensitivity);
void Setup3DNR(ACameraMetadata* characteristics, ACaptureRequest* request, int32_t sensitivity);
void SetupHDR(ACameraMetadata* characteristics, ACaptureRequest* request, int32_t sensitivity);
bool SetupTonemapCurve(ACameraMetadata* characteristics, ACaptureRequest* request);
protected:
std::mutex m_locker;
std::set<std::string> m_availableCameras;
@ -240,6 +250,7 @@ protected:
bool mCaptureTriggered;
bool mFocusTriggered;
bool mCaptureDispatched;
uint32_t mStableFrameCount;
CAPTURE_RESULT mResult;
uint64_t m_startTime;
@ -263,11 +274,6 @@ protected:
ACameraOutputTarget* mOutputTarget;
ACaptureSessionOutput* mSessionOutput;
AImageReader* mImageReader2;
ANativeWindow* mImageWindow2;
ACameraOutputTarget* mOutputTarget2;
ACaptureSessionOutput* mSessionOutput2;
std::shared_ptr<ACameraMetadata> mCharacteristics;
std::vector<CaptureRequest*> mCaptureRequests;
@ -285,12 +291,7 @@ protected:
// cv::Mat mOneFrame;
std::vector<std::pair<int64_t, cv::Mat> > mOneFrame;
std::vector<std::vector<uint8_t> > mRawFrames;
// AImageReader* image_reader;
// ANativeWindow* image_reader_surface;
// ACameraOutputTarget* image_reader_target;
// ACaptureRequest* capture_request;
// ACaptureSessionOutput* capture_session_output;
int64_t m_minTimestamp;
};

@ -5,8 +5,12 @@
#include "HangYuCtrl.h"
#include "netcamera.h"
#include "httpclient.h"
#include <LogThread.h>
#include <SpecData_JSON.h>
#include <cstring>
#include <algorithm>
HangYuCtrl::~HangYuCtrl()
{
@ -17,7 +21,7 @@ bool HangYuCtrl::SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX,
{
//流类型范围1-4,1为主流
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Streams/%u/%u", m_ip.c_str(), (uint32_t)channel, (uint32_t)streamID);
snprintf(url, sizeof(url), "http://%s/Streams/%u/1", m_ip.c_str(), (uint32_t)channel);
std::vector<uint8_t> resData;
@ -56,11 +60,22 @@ bool HangYuCtrl::SetOsd(uint8_t channel, std::string osdstring, uint8_t pos)
{
// /LAPI/V1.0/Channels/<ID>/Media/OSDs/Contents
//左上OSD
bool hasDateTime = (osdstring.find("$$DATETIME$$") != std::string::npos);
size_t posi = osdstring.find("$$DATETIME$$");
if (posi != std::string::npos) {
size_t endPos = posi + 12;
while (endPos < osdstring.size() && (osdstring[endPos] == ' ' || osdstring[endPos] == '\n')) {
endPos++;
}
osdstring.erase(posi, endPos - posi);
}
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Pictures/%u/MultiOSDV2", m_ip.c_str(), (uint32_t)channel);
std::vector<uint8_t> resData;
std::replace(osdstring.begin(), osdstring.end(), '\n', '^');
string xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><MultiLineOSD><DisplayTime><Enable>true</Enable><PosX>8</PosX><PosY>0</PosY></DisplayTime><OSD><ID>1</ID><Enable>true</Enable><Text>"+ osdstring+ "</Text><x>8</x><y>24</y></MultiLineOSD>";
string xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><MultiLineOSD><DisplayTime><Enable>" + string(hasDateTime ? "true" : "false") + "</Enable><PosX>8</PosX><PosY>0</PosY></DisplayTime><OSD><ID>1</ID><Enable>false</Enable><Text>"+ osdstring+ "</Text><x>8</x><y>" + string(hasDateTime ? "24" : "0") + "</y></MultiLineOSD>";
int res = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, xmlString.c_str(), resData);
return res;
}
@ -102,8 +117,6 @@ void HangYuCtrl::EnableOsd(bool enable, uint8_t channel)
{
// return;
}
}
std::string HangYuCtrl::GetStreamingUrl(uint8_t channel)
@ -175,12 +188,143 @@ bool HangYuCtrl::UpdateTime(time_t ts)
return true;
}
bool HangYuCtrl::TakePhoto(std::vector<uint8_t>& img)
bool HangYuCtrl::TakePhoto(uint8_t streamID, std::vector<uint8_t>& img)
{
bool res = false;
std::vector<uint8_t> data;
// /Snapshot/%u/1/RemoteImageCaptureV2?ImageFormat=jpg
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Snapshot/%u/1/RemoteImageCaptureV2?ImageFormat=jpg", m_ip.c_str(), (uint32_t)streamID);
int nRet = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, img, &m_lastErrorCode);
if (0 == nRet)
{
bool qualityDowngraded = false;
std::string originalConfig;
if (img.size() < 1000)
{
qualityDowngraded = DowngradeQuality(originalConfig);
XYLOG(XYLOG_SEVERITY_INFO,"Reduce Img Quality");
}
nRet = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, img, &m_lastErrorCode);
if (!originalConfig.empty())
{
UpdateQuality(originalConfig);
}
std::vector<uint8_t> header = {0xFF, 0xD8, 0xFF, 0xE0}; // JPEG
std::vector<uint8_t>::iterator it = std::search(img.begin(), img.end(), header.begin(), header.end());
if (it != img.end() && it != img.begin())
{
img.erase(img.begin(), it);
#ifndef NDEBUG
int aa = 0;
#endif
}
}
return nRet == 0;
}
bool HangYuCtrl::DowngradeQuality(std::string& originalConfig)
{
bool res = false;
char url[64] = { 0 };
snprintf(url, sizeof(url), "http://%s/Snapshot/Config", m_ip.c_str());
std::vector<uint8_t> data;
int nRet = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, data);
if (0 == nRet)
{
std::string str = ByteArrayToString(&data[0], data.size());
originalConfig = str;
if (replaceAll(str, "<Quality>middle</Quality>", "<Quality>low</Quality>") == 0)
{
res = (replaceAll(str, "<Quality>high</Quality>", "<Quality>middle</Quality>") != 0);
}
else
{
res = true;
}
if (!res)
{
return res;
}
data.clear();
if (res)
{
nRet = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, str.c_str(), data);
return 0 == nRet;
}
}
return false;
}
bool HangYuCtrl::UpdateQuality(const std::string& originalConfig)
{
std::vector<uint8_t> data;
char url[64] = { 0 };
snprintf(url, sizeof(url), "http://%s/Snapshot/Config", m_ip.c_str());
int nRet = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, originalConfig.c_str(), data);
return 0 == nRet;
}
bool HangYuCtrl::UpgradeQuality()
{
bool res = false;
char url[64] = { 0 };
snprintf(url, sizeof(url), "http://%s/Snapshot/Config", m_ip.c_str());
std::vector<uint8_t> data;
int nRet = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, data);
if (0 == nRet)
{
std::string str = ByteArrayToString(&data[0], data.size());
if (replaceAll(str, "<Quality>low</Quality>", "<Quality>middle</Quality>") == 0)
{
res = (replaceAll(str, "<Quality>middle</Quality>", "<Quality>high</Quality>") != 0);
}
else
{
res = true;
}
if (!res)
{
return res;
}
data.clear();
if (res)
{
nRet = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, str.c_str(), data);
return 0 == nRet;
}
}
return false;
}
bool HangYuCtrl::TakeVideo(uint32_t duration, std::string path)
bool HangYuCtrl::QueryQuality(std::string& qualityContents)
{
char url[64] = { 0 };
snprintf(url, sizeof(url), "http://%s/Snapshot/Config", m_ip.c_str());
std::vector<uint8_t> data;
int nRet = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, data);
if (0 == nRet && !data.empty())
{
qualityContents = ByteArrayToString(&data[0], data.size());
}
return (0 == nRet);
}
bool HangYuCtrl::TakeVideo(uint8_t streamID, uint32_t duration, std::string path)
{
return false;
}

@ -17,12 +17,16 @@ public:
virtual void EnableOsd(bool enable, uint8_t channel);
virtual std::string GetStreamingUrl(uint8_t channel);
virtual bool UpdateTime(time_t ts);
virtual bool TakePhoto(std::vector<uint8_t>& img);
virtual bool TakeVideo(uint32_t duration, std::string path);
virtual bool TakePhoto(uint8_t streamID, std::vector<uint8_t>& img);
virtual bool TakeVideo(uint8_t streamID, uint32_t duration, std::string path);
virtual bool HasAuthOnStreaming() const { return true; }
virtual bool SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY);
private:
bool SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY);
bool QueryQuality(std::string& qualityContents);
bool DowngradeQuality(std::string& originalConfig);
bool UpdateQuality(const std::string& originalConfig);
bool UpgradeQuality();
};

@ -0,0 +1,204 @@
//
// Created by Matthew on 2025/3/4.
//
#include "HikonCtrl.h"
#include "netcamera.h"
#include "httpclient.h"
#include <LogThread.h>
#include <SpecData_JSON.h>
#include <cstring>
#include <algorithm>
HikonCtrl::~HikonCtrl()
{
}
bool HikonCtrl::SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY)
{
//流类型范围1-4,1为主流
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Streams/%u/1", m_ip.c_str(), (uint32_t)channel);
std::vector<uint8_t> resData;
int res = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, resData);
if (res != 0 || resData.empty())
{
return 0;
}
std::string xmlString(resData.begin(), resData.end());
size_t widthStart = xmlString.find("<ResolutionWidth>");
size_t widthEnd = xmlString.find("</ResolutionWidth>");
if (widthStart != std::string::npos && widthEnd != std::string::npos) {
widthStart += std::string("<ResolutionWidth>").length();
xmlString.replace(widthStart, widthEnd - widthStart, std::to_string(resX));
}
size_t heightStart = xmlString.find("<ResolutionHeigth>");
size_t heightEnd = xmlString.find("</ResolutionHeigth>");
if (heightStart != std::string::npos && heightEnd != std::string::npos) {
heightStart += std::string("<ResolutionHeigth>").length();
xmlString.replace(heightStart, heightEnd - heightStart, std::to_string(resY));
}
res = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, xmlString.c_str(), resData);
if (res != 0)
{
return 0;
}
return true;
}
bool HikonCtrl::SetOsd(uint8_t channel, std::string osdstring, uint8_t pos)
{
// /LAPI/V1.0/Channels/<ID>/Media/OSDs/Contents
//左上OSD
bool hasDateTime = (osdstring.find("$$DATETIME$$") != std::string::npos);
size_t posi = osdstring.find("$$DATETIME$$");
if (posi != std::string::npos) {
size_t endPos = posi + 12;
while (endPos < osdstring.size() && (osdstring[endPos] == ' ' || osdstring[endPos] == '\n')) {
endPos++;
}
osdstring.erase(posi, endPos - posi);
}
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Pictures/%u/MultiOSDV2", m_ip.c_str(), (uint32_t)channel);
std::vector<uint8_t> resData;
std::replace(osdstring.begin(), osdstring.end(), '\n', '^');
string xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><MultiLineOSD><DisplayTime><Enable>" + string(hasDateTime ? "true" : "false") + "</Enable><PosX>8</PosX><PosY>0</PosY></DisplayTime><OSD><ID>1</ID><Enable>false</Enable><Text>"+ osdstring+ "</Text><x>8</x><y>" + string(hasDateTime ? "24" : "0") + "</y></MultiLineOSD>";
int res = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, xmlString.c_str(), resData);
return res;
}
void HikonCtrl::EnableOsd(bool enable, uint8_t channel)
{
//航煜 只能显示时间和一个OSD
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Pictures/%u/MultiOSDV2", m_ip.c_str(), (uint32_t)channel);
std::vector<uint8_t> resData;
int res = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, resData);
if (res != 0 || resData.empty())
{
return;
}
std::string xmlString(resData.begin(), resData.end());
std::string enableStartTag = "<Enable>";
std::string enableEndTag = "</Enable>";
size_t pos = 0;
while ((pos = xmlString.find(enableStartTag, pos)) != std::string::npos) {
size_t startPos = pos + enableStartTag.length();
size_t endPos = xmlString.find(enableEndTag, startPos);
if (endPos == std::string::npos) {
break;
}
std::string newValue = enable ? "true" : "false";
xmlString.replace(startPos, endPos - startPos, newValue);
pos = endPos + enableEndTag.length();
}
res = DoPutRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, xmlString.c_str(), resData);
if (res != 0)
{
// return;
}
}
std::string HikonCtrl::GetStreamingUrl(uint8_t channel)
{
// /LAPI/V1.0/Channels/<ID>/Media/Video/Streams/<ID>/LiveStreamURL?TransType=<Tran
// sType>&TransProtocol=<TransProtocol>
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/Streams/%u/1/Transport", m_ip.c_str(), (uint32_t)channel);
std::vector<uint8_t> resData;
int res = 0;
for (int idx = 0; idx < 10; idx++)
{
res = DoGetRequest(url, HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, resData);
if (res == 0 && !resData.empty())
{
break;
}
}
if (res != 0 || resData.empty())
{
return "";
}
resData.push_back(0);
const char* start = strstr((const char*)&resData[0], "<RTSPURI>");
if (start == NULL)
{
return "";
}
start += 9;
const char* end = strstr(start, "</RTSPURI>");
if (end == NULL)
{
return "";
}
return std::string(start, end);
}
bool HikonCtrl::UpdateTime(time_t ts)
{
// /LAPI/V1.0/System/Time
// <?xml version="1.0" encoding="utf-8"?>
//<Time>
//<DateTimeFormat>
//<!--req,string,YYYYMMDDWhhmmss,YYYYMMDDhhmmss,MMDDYYYYWhhmmss,MMD
// DYYYYhhmmss,DDMMYYYYWhhmmss,DDMMYYYYhhmmss-->
//</DateTimeFormat>
//<TimeFormat><!--req,xs:string,12hour,24hour--></TimeFormat>
//<SystemTime><!--req,xs:datetime,” 20040503T173008+08”--></SystemTime>
//<SyncNTPFlag><!--req,xs:string,"Sync,NoSync"--></SyncNTPFlag>
//</Time>
std::string reqData = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Time><SystemTime>"
+ FormatLocalDateTime("%d%02d%02dT%02d%02d%02d") + "+08</SystemTime></Time>";
std::string url = "http://" + m_ip + "/System/Time";
std::vector<uint8_t> resData;
int res = DoPutRequest(url.c_str(), HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, reqData.c_str(), resData);
if (res != 0)
{
return false;
}
return true;
}
bool HikonCtrl::TakePhoto(uint8_t streamID, std::vector<uint8_t>& img)
{
char url[128] = { 0 };
snprintf(url, sizeof(url), "http://%s/ISAPI/Streaming/channels/1/picture?", m_ip.c_str());
int nRet = DoGetRequest(url, HTTP_AUTH_TYPE_DIGEST, m_userName.c_str(), m_password.c_str(), m_netHandle, img, &m_lastErrorCode);
return nRet == 0;
}
bool HikonCtrl::TakeVideo(uint8_t streamID, uint32_t duration, std::string path)
{
return false;
}

@ -0,0 +1,34 @@
//
// Created by Matthew on 2025/3/4.
//
#ifndef __MICROPHOTO_HIKONCTRL_H__
#define __MICROPHOTO_HIKONCTRL_H__
#include "VendorCtrl.h"
class HikonCtrl : public VendorCtrl
{
public:
using VendorCtrl::VendorCtrl;
virtual ~HikonCtrl();
virtual bool SetOsd(uint8_t channel, std::string osd, uint8_t pos);
virtual void EnableOsd(bool enable, uint8_t channel);
virtual std::string GetStreamingUrl(uint8_t channel);
virtual bool UpdateTime(time_t ts);
virtual bool TakePhoto(uint8_t streamID, std::vector<uint8_t>& img);
virtual bool TakeVideo(uint8_t streamID, uint32_t duration, std::string path);
virtual bool HasAuthOnStreaming() const { return true; }
virtual bool SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY);
private:
bool QueryQuality(std::string& qualityContents);
bool DowngradeQuality(std::string& originalConfig);
bool UpdateQuality(const std::string& originalConfig);
bool UpgradeQuality();
};
#endif //__MICROPHOTO_HIKONCTRL_H__

@ -2,10 +2,12 @@
// Created by Matthew on 2025/3/4.
//
#include "VendorCtrl.h"
#include <curl/curl.h>
VendorCtrl::VendorCtrl(const std::string& ip, const std::string& userName, const std::string& password, uint8_t channel, net_handle_t netHandle, bool syncTime/* = true*/) :
m_ip(ip), m_userName(userName), m_password(password), m_channel(channel), m_netHandle(netHandle)
{
}
std::string VendorCtrl::CvtJSONToString(const Json::Value& data)
{
@ -17,4 +19,9 @@ std::string VendorCtrl::CvtJSONToString(const Json::Value& data)
builder["indentation"] = "";
#endif
return Json::writeString(builder, data);
}
bool VendorCtrl::IsTimeout() const
{
return m_lastErrorCode == CURLE_OPERATION_TIMEDOUT;
}

@ -23,9 +23,15 @@ public:
virtual void EnableOsd(bool enable, uint8_t channel) = 0;
virtual std::string GetStreamingUrl(uint8_t channel) = 0;
virtual bool UpdateTime(time_t ts) = 0;
virtual bool TakePhoto(std::vector<uint8_t>& img) = 0;
virtual bool TakeVideo(uint32_t duration, std::string path) = 0;
virtual bool TakePhoto(uint8_t streamID, std::vector<uint8_t>& img) = 0;
virtual bool TakeVideo(uint8_t streamID, uint32_t duration, std::string path) = 0;
virtual bool HasAuthOnStreaming() const { return false; }
virtual bool SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY) = 0;
void UpdateNetHandle(net_handle_t netHandle) { m_netHandle = netHandle; }
int GetLastError() const { return m_lastErrorCode; }
bool IsTimeout() const;
protected:
@ -37,6 +43,7 @@ protected:
std::string m_password;
uint8_t m_channel;
net_handle_t m_netHandle;
int m_lastErrorCode;
};

@ -13,6 +13,11 @@ YuShiCtrl::~YuShiCtrl()
}
bool YuShiCtrl::SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY)
{
return false;
}
bool YuShiCtrl::SetOsd(uint8_t channel, std::string osd, uint8_t pos)
{
// /LAPI/V1.0/Channels/<ID>/Media/OSDs/Contents
@ -140,7 +145,7 @@ bool YuShiCtrl::UpdateTime(time_t ts)
std::string url = "http://" + m_ip + "/LAPI/V1.0/System/Time";
std::vector<uint8_t> resData;
int res = DoPutRequest(url.c_str(), HTTP_AUTH_TYPE_BASIC, m_userName.c_str(), m_password.c_str(), m_netHandle, contents.c_str(), resData);
int res = DoPutRequest(url.c_str(), HTTP_AUTH_TYPE_DIGEST, m_userName.c_str(), m_password.c_str(), m_netHandle, contents.c_str(), resData);
if (res != 0)
{
@ -150,18 +155,22 @@ bool YuShiCtrl::UpdateTime(time_t ts)
return true;
}
bool YuShiCtrl::TakePhoto(std::vector<uint8_t>& img)
bool YuShiCtrl::TakePhoto(uint8_t streamID, std::vector<uint8_t>& img)
{
return false;
}
// Yu Shi
char url[128] = { 0 };
int streamSid = 0; // should put into config
snprintf(url, sizeof(url), "http://%s/LAPI/V1.0/Channels/%u/Media/Video/Streams/%d/Snapshot", m_ip.c_str(), (uint32_t)streamID, streamSid);
int nRet = DoGetRequest(url, HTTP_AUTH_TYPE_DIGEST, m_userName.c_str(), m_password.c_str(), m_netHandle, img, &m_lastErrorCode);
return nRet == 0;
}
bool YuShiCtrl::TakeVideo(uint32_t duration, std::string path) {
bool YuShiCtrl::TakeVideo(uint8_t streamID, uint32_t duration, std::string path) {
return false;
}
void YuShiCtrl::OSDJson(int id, bool enabled, std::string osdString, int x, int y, bool timeOn, std::string& jsonString)
{
Json::Value root;

@ -15,10 +15,11 @@ public:
virtual bool SetOsd(uint8_t channel, std::string osd, uint8_t pos);
virtual void EnableOsd(bool enable, uint8_t channel);
virtual std::string GetStreamingUrl(uint8_t channel);
virtual std::string GetStreamingUrl(uint8_t streamID);
virtual bool UpdateTime(time_t ts);
virtual bool TakePhoto(std::vector<uint8_t>& img);
virtual bool TakeVideo(uint32_t duration, std::string path);
virtual bool TakePhoto(uint8_t streamID, std::vector<uint8_t>& img);
virtual bool TakeVideo(uint8_t streamID, uint32_t duration, std::string path);
virtual bool SetResolution(uint8_t channel, uint8_t streamID, uint32_t resX, uint32_t resY);
private:
void OSDJson(int id, bool enabled, std::string osdString, int x, int y, bool timeOn, std::string& jsonString);

@ -33,7 +33,7 @@ static int SockOptCallback(void *clientp, curl_socket_t curlfd, curlsocktype pur
return res == 0 ? CURL_SOCKOPT_OK : CURL_SOCKOPT_ERROR;
}
int DoGetRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, std::vector<uint8_t>& data)
int DoGetRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, std::vector<uint8_t>& data, int* curlResVal/* = NULL*/)
{
CURLcode nRet;
std::string auth;
@ -63,8 +63,10 @@ int DoGetRequest(const char* url, int authType, const char* userName, const char
if (netHandle != NETWORK_UNSPECIFIED)
{
#if 0
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, SockOptCallback);
curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, &netHandle);
#endif
}
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
@ -85,6 +87,10 @@ int DoGetRequest(const char* url, int authType, const char* userName, const char
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
nRet = curl_easy_perform(curl);
if (curlResVal != NULL)
{
*curlResVal = nRet;
}
long responseCode = 0;
if (CURLE_OK == nRet)
@ -119,7 +125,7 @@ int DoGetRequest(const char* url, int authType, const char* userName, const char
return ((0 == nRet) && (responseCode == 200)) ? 0 : 1;
}
int DoPutRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, const char* contents, std::vector<uint8_t>& data)
int DoPutRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, const char* contents, std::vector<uint8_t>& data, int* curlResVal/* = NULL*/)
{
std::string auth;
@ -148,8 +154,10 @@ int DoPutRequest(const char* url, int authType, const char* userName, const char
if (netHandle != NETWORK_UNSPECIFIED)
{
#if 0
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, SockOptCallback);
curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, &netHandle);
#endif
}
if(contents != NULL)
@ -166,6 +174,10 @@ int DoPutRequest(const char* url, int authType, const char* userName, const char
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
CURLcode nRet = curl_easy_perform(curl);
if (curlResVal != NULL)
{
*curlResVal = nRet;
}
if (CURLE_OK != nRet)
{
printf("GET err=%d", nRet);

@ -18,7 +18,7 @@
bool setIPAddress(const char *if_name, const char *ip_addr, const char *net_mask, const char *gateway_addr);
int DoGetRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, std::vector<uint8_t>& data);
int DoPutRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, const char* contents, std::vector<uint8_t>& data);
int DoGetRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, std::vector<uint8_t>& data, int* curlResVal = NULL);
int DoPutRequest(const char* url, int authType, const char* userName, const char* password, net_handle_t netHandle, const char* contents, std::vector<uint8_t>& data, int* curlResVal = NULL);
#endif // __HTTP_CLIENT__

@ -1,222 +0,0 @@
package com.xypower.mpapp;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.IBinder;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class FloatingWindow extends Service {
private Context mContext;
private WindowManager mWindowManager;
private View mView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
allAboutLayout(intent);
moveView();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
try {
if (mView != null) {
mWindowManager.removeView(mView);
}
} catch (Exception ex) {
// ex.printStackTrace();
Log.e("FW", "Exception " + ex.getMessage());
}
super.onDestroy();
}
WindowManager.LayoutParams mWindowsParams;
private void moveView() {
/*
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = (int) (metrics.widthPixels * 1f);
int height = (int) (metrics.heightPixels * 1f);
mWindowsParams = new WindowManager.LayoutParams(
width,//WindowManager.LayoutParams.WRAP_CONTENT,
height,//WindowManager.LayoutParams.WRAP_CONTENT,
//WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
(Build.VERSION.SDK_INT <= 25) ? WindowManager.LayoutParams.TYPE_PHONE : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
,
//WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN // Not displaying keyboard on bg activity's EditText
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
//WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, //Not work with EditText on keyboard
PixelFormat.TRANSLUCENT);
mWindowsParams.gravity = Gravity.TOP | Gravity.LEFT;
//params.x = 0;
mWindowsParams.y = 100;
mWindowManager.addView(mView, mWindowsParams);
mView.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
long startTime = System.currentTimeMillis();
@Override
public boolean onTouch(View v, MotionEvent event) {
if (System.currentTimeMillis() - startTime <= 300) {
return false;
}
if (isViewInBounds(mView, (int) (event.getRawX()), (int) (event.getRawY()))) {
editTextReceiveFocus();
} else {
editTextDontReceiveFocus();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = mWindowsParams.x;
initialY = mWindowsParams.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
mWindowsParams.x = initialX + (int) (event.getRawX() - initialTouchX);
mWindowsParams.y = initialY + (int) (event.getRawY() - initialTouchY);
mWindowManager.updateViewLayout(mView, mWindowsParams);
break;
}
return false;
}
});
*/
}
private boolean isViewInBounds(View view, int x, int y) {
Rect outRect = new Rect();
int[] location = new int[2];
view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains(x, y);
}
private void editTextReceiveFocus() {
if (!wasInFocus) {
mWindowsParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
mWindowManager.updateViewLayout(mView, mWindowsParams);
wasInFocus = true;
}
}
private void editTextDontReceiveFocus() {
if (wasInFocus) {
mWindowsParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
mWindowManager.updateViewLayout(mView, mWindowsParams);
wasInFocus = false;
hideKeyboard(mContext, edt1);
}
}
private boolean wasInFocus = true;
private EditText edt1;
private void allAboutLayout(Intent intent) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = layoutInflater.inflate(R.layout.ovelay_window, null);
edt1 = (EditText) mView.findViewById(R.id.edt1);
final TextView tvValue = (TextView) mView.findViewById(R.id.tvValue);
Button btnClose = (Button) mView.findViewById(R.id.btnClose);
edt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mWindowsParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
// mWindowsParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
mWindowManager.updateViewLayout(mView, mWindowsParams);
wasInFocus = true;
showSoftKeyboard(v);
}
});
edt1.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
tvValue.setText(edt1.getText());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
btnClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopSelf();
}
});
}
private void hideKeyboard(Context context, View view) {
if (view != null) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
public void showSoftKeyboard(View view) {
if (view.requestFocus()) {
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
}

@ -0,0 +1,19 @@
package com.xypower.mpapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class HeartBeatResponseReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("com.systemui.ACTION_HEARTBEAT_RESPONSE".equals(action)) {
long timestamp = intent.getLongExtra("timestamp", 0);
Log.d("MpApp","系统广播监听 timestamp:"+timestamp);
MicroPhotoService.infoLog("收到heartbeat广播 timestamp:" + timestamp);
}
}
}

@ -35,6 +35,7 @@ import android.widget.Toast;
import com.dev.devapi.api.SysApi;
import com.xypower.common.CameraUtils;
import com.xypower.common.FilesUtils;
import com.xypower.common.MicroPhotoContext;
import com.xypower.mpapp.databinding.ActivityMainBinding;
import com.xypower.mpapp.utils.LocationUtil;
@ -113,7 +114,7 @@ public class MainActivity extends AppCompatActivity {
if (!MicroPhotoContext.hasMpAppConfig(appContext)) {
String mstPath = MicroPhotoContext.buildMasterAppDir(appContext);
String mstPath = MicroPhotoContext.buildMpResAppDir(appContext);
File mstPathFile = new File(mstPath);
File mpdataFile = new File(mstPathFile, "mpdata");
@ -121,7 +122,7 @@ public class MainActivity extends AppCompatActivity {
File dataFile = new File(appPathFile, "data");
if (dataFile.exists()) {
try {
dataFile.delete();
FilesUtils.delete(dataFile);
} catch (Exception ex) {
ex.printStackTrace();
}
@ -133,6 +134,18 @@ public class MainActivity extends AppCompatActivity {
ex.printStackTrace();
}
}
else {
Intent resIntent = getPackageManager().getLaunchIntentForPackage(MicroPhotoContext.PACKAGE_NAME_MPRES);
if (resIntent != null) {
resIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
resIntent.putExtra("initres", 1);
String sn = MicroPhotoService.getSerialNumber();
if (!TextUtils.isEmpty(sn)) {
resIntent.putExtra("sn", sn);
}
startActivity(resIntent);
}
}
}
Intent intent = getIntent();
@ -422,28 +435,35 @@ public class MainActivity extends AppCompatActivity {
@Override
public void onClick(View v) {
restartSelfWithStartActivity();
// restartSelfWithAlarmManager();
}
private void restartSelfWithStartActivity() {
Context context = MainActivity.this;
final Context context = getApplicationContext();
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int noDelay = 1;
intent.putExtra("noDelay", noDelay);
intent.putExtra("reason", "Manual Restart From MainActivity");
// finish();
context.startActivity(intent);
System.exit(0);
final Handler handler = new Handler();
finish();
handler.postDelayed(new Runnable() {
@Override
public void run() {
System.exit(0);
}
}, 0);
}
private void restartSelfWithAlarmManager() {
Intent intent = new Intent(MainActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int noDelay = 1;
intent.putExtra("noDelay", noDelay);

@ -20,6 +20,10 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageDecoder;
import android.graphics.Matrix;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@ -33,7 +37,6 @@ import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@ -50,6 +53,7 @@ import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.telephony.CellSignalStrength;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@ -71,6 +75,7 @@ import com.xypower.mpapp.v2.Camera2VideoActivity;
import com.xypower.mpapp.video.RawActivity;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
@ -79,13 +84,11 @@ import java.io.Reader;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
public class MicroPhotoService extends Service {
public static final String TAG = "MPLOG";
@ -114,7 +117,7 @@ public class MicroPhotoService extends Service {
public final static int BROADCAST_REQUEST_CODE_GPS = 3;
public final static int BROADCAST_REQUEST_CODE_STOP_SERVICE = 4;
public static final int NOTIFICATION_ID_FOREGROUND_SERVICE = 8466503;
public static final int NOTIFICATION_ID_FOREGROUND_SERVICE = 8466508;
public static final String ACTION_MSG_BROADCAST = "ACT_MSG_BROADCAST";
public static final String ACTION_START = "com.xypower.mpapp.ACT_START";
@ -134,6 +137,7 @@ public class MicroPhotoService extends Service {
private static final String ACTION_HEARTBEAT_MANUALLY = "com.xypower.mpapp.ACT_HB_M";
private static final String ACTION_UPDATE_CONFIGS = "com.xypower.mpapp.ACT_UPD_CFG";
public static final String ACTION_VIDEO_FINISHED = "com.xypower.mpapp.ACT_V_FINISHED";
private static final String EXTRA_PARAM_CHANNEL = "Channel";
private static final String EXTRA_PARAM_PRESET = "Preset";
private static final String EXTRA_PARAM_PHOTO_OR_VIDEO = "PhotoOrVideo";
@ -147,6 +151,7 @@ public class MicroPhotoService extends Service {
private static final String EXTRA_PARAM_TIME = "Time";
private static final String FOREGROUND_CHANNEL_ID = "fg_mpapp";
private HeartBeatResponseReceiver mHeartBeatReceiver;
public static class STATE_SERVICE {
public static final int CONNECTED = 10;
@ -165,7 +170,6 @@ public class MicroPhotoService extends Service {
protected long mNativeHandle = 0;
private AlarmReceiver mAlarmReceiver = null;
private AlarmReceiver mLocalMsgReceiver = null;
private ScreenActionReceiver mScreenaAtionReceiver = null;
private NetworkChangedReceiver mNetworkChangedReceiver = null;
private long mGpsTimeout = 60000; // 1 minute
@ -179,9 +183,6 @@ public class MicroPhotoService extends Service {
public static boolean isRunning = false;
FileOutputStream mAppRunningFile;
FileLock mAppLock;
private ConnectivityManager mConnectivityManager = null;
private ConnectivityManager.NetworkCallback mNetworkCallback = null;
@ -196,6 +197,14 @@ public class MicroPhotoService extends Service {
public MicroPhotoService() {
}
private static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void convertDngToPng(String dngFile, String pngFile) {
ImageDecoder.Source src = ImageDecoder.createSource(new File(dngFile));
Bitmap bmp = null;
@ -260,9 +269,33 @@ public class MicroPhotoService extends Service {
public void onCreate() {
super.onCreate();
Log.i(TAG, "MicroPhotoService::onCreate");
Context context = getApplicationContext();
try {
if (usingEthernet()) {
mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
try {
File filesDir = context.getFilesDir();
File ethShellFile = new File(filesDir, "eth.sh");
if (ethShellFile.exists()) {
ethShellFile.delete();
}
FilesUtils.copyAndNormalizeTextAssetsFile(context, "eth.sh", ethShellFile.getAbsolutePath());
// sed -i 's/\r$//' eth.sh
File ethToolFile = new File(filesDir, "ethtool");
if (ethToolFile.exists()) {
ethToolFile.delete();
}
String srcFileName = android.os.Process.is64Bit() ? "ethtool" : "ethtool-v7a";
FilesUtils.copyAssetsFile(context, srcFileName, ethToolFile.getAbsolutePath());
ethToolFile.setExecutable(true);
} catch (Exception ex) {
ex.printStackTrace();
}
mConnectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] nws = mConnectivityManager.getAllNetworks();
for (Network nw : nws) {
@ -277,49 +310,17 @@ public class MicroPhotoService extends Service {
ex.printStackTrace();
}
try {
final String appPath = MicroPhotoContext.buildMpAppDir(this);
mHander = new ServiceHandler();
File lockerFile = new File(appPath);
lockerFile = new File(lockerFile, "data/alive");
try {
lockerFile.mkdirs();
} catch (Exception ex) {
ex.printStackTrace();
}
lockerFile = new File(lockerFile, "running");
mAppRunningFile = new FileOutputStream(lockerFile);
mNotificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
mStateService = STATE_SERVICE.NOT_CONNECTED;
for (int idx = 0; idx < 3; idx++) {
try {
mAppLock = mAppRunningFile.getChannel().tryLock();
if (mAppLock != null && mAppLock.isValid()) {
infoLog("App Locked");
break;
}else {
infoLog("Lock App Failed");
}
try {
Thread.sleep(16);
} catch (Exception ex) {
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
try {
DeviceUtil.getPhoneState(context);
} catch (Exception ex) {
ex.printStackTrace();
}
mHander = new ServiceHandler();
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mStateService = STATE_SERVICE.NOT_CONNECTED;
DeviceUtil.getPhoneState(this.getApplicationContext());
mScreenaAtionReceiver = new ScreenActionReceiver();
// 注册广播接受者
{
mAlarmReceiver = new AlarmReceiver(this);
@ -332,6 +333,14 @@ public class MicroPhotoService extends Service {
intentFilter.addAction(ACTION_HEARTBEAT_MANUALLY);
intentFilter.addAction(ACTION_GPS_TIMEOUT);
intentFilter.addAction(ACTION_RESTART);
intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
if (usingEthernet()) {
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
}
}
getApplicationContext().registerReceiver(mAlarmReceiver, intentFilter, Context.RECEIVER_EXPORTED | Context.RECEIVER_VISIBLE_TO_INSTANT_APPS);
}
{
@ -346,7 +355,7 @@ public class MicroPhotoService extends Service {
intentFilter.addAction(ACTION_STOP);
intentFilter.addAction(ACTION_UPDATE_CONFIGS);
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver (mLocalMsgReceiver, intentFilter);
LocalBroadcastManager.getInstance(context).registerReceiver (mLocalMsgReceiver, intentFilter);
}
{
@ -358,34 +367,22 @@ public class MicroPhotoService extends Service {
getApplicationContext().registerReceiver(mNetworkChangedReceiver, filter);
}
/*
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(ALARM_SERVICE);
while (true) {
AlarmManager.AlarmClockInfo aci = alarmManager.getNextAlarmClock();
if (aci == null) {
break;
}
{
mHeartBeatReceiver = new HeartBeatResponseReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.systemui.ACTION_HEARTBEAT_RESPONSE");
getApplicationContext().registerReceiver(mHeartBeatReceiver, filter);
}
*/
enableGps(true);
requestPosition();
}
@Override
public void onDestroy() {
try {
if (mAppLock != null) {
mAppLock.close();
}
if (mAppRunningFile != null) {
mAppRunningFile.close();
}
enableGps(true);
requestPosition();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void onDestroy() {
mStateService = STATE_SERVICE.NOT_CONNECTED;
infoLog("MicroPhotoService::onDestroy called");
@ -397,8 +394,8 @@ public class MicroPhotoService extends Service {
}
getApplicationContext().unregisterReceiver(mAlarmReceiver);
getApplicationContext().unregisterReceiver(mScreenaAtionReceiver);
getApplicationContext().unregisterReceiver(mNetworkChangedReceiver);
getApplicationContext().unregisterReceiver(mHeartBeatReceiver);
if (mConnectivityManager != null) {
if (mNetworkCallback != null) {
@ -481,7 +478,22 @@ public class MicroPhotoService extends Service {
System.exit(0);
}
private void ProcessReceivedAction(Context context, Intent intent) {
private boolean isMpMasterAlive(Context context) {
if (Build.TIME < MicroPhotoContext.BUILD_TIME_WO_SID_20250418) {
// 2025-04-18 old firmware
// Check Log file time
File file = new File(MicroPhotoContext.buildMasterAppDir(context) + "logs/mlog.txt");
if (file.exists()) {
return ((System.currentTimeMillis() - file.lastModified()) < 1800000);
} else {
return false;
}
}
return MicroPhotoContext.isAppAlive(context, MicroPhotoContext.PACKAGE_NAME_MPMASTER, MicroPhotoContext.SERVICE_NAME_MPMASTER);
}
private void ProcessReceivedAction(final Context context, final Intent intent) {
String action = intent.getAction();
if (TextUtils.equals(ACTION_HEARTBEAT, action)) {
long ts = System.currentTimeMillis();
@ -490,7 +502,7 @@ public class MicroPhotoService extends Service {
infoLog("HB Timer Fired ACTION=" + action + " ExpTS=" + Long.toString(expectedHbTime));
Runnable runnable = new Runnable() {
public void run() {
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel());
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel(), true);
}
};
Thread th = new Thread(runnable);
@ -507,25 +519,36 @@ public class MicroPhotoService extends Service {
mService.detectGpsStatus();
/*
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
if (!connectivityManager.isDefaultNetworkActive()) {
infoLog("DefaultNetwork is NOT Active");
}
}
*/
} catch (Exception ex) {
ex.printStackTrace();
}
try {
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(MicroPhotoContext.PACKAGE_NAME_MPMASTER);
// launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (launchIntent != null) {
context.startActivity(launchIntent);
boolean mpmstAlive = isMpMasterAlive(context);
if (!mpmstAlive) {
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(MicroPhotoContext.PACKAGE_NAME_MPMASTER);
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (launchIntent != null) {
context.startActivity(launchIntent);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
Intent heartintent = new Intent("com.xy.xsetting.action");
heartintent.putExtra("cmd", "heartbeat");
heartintent.setPackage("com.android.systemui");
context.sendBroadcast(heartintent);
} else if (TextUtils.equals(ACTION_TAKE_PHOTO, action)) {
long ts = intent.getLongExtra(EXTRA_PARAM_TIME, 0);
int cnt = intent.getIntExtra(EXTRA_PARAM_SCHEDULES, 0);
@ -537,7 +560,20 @@ public class MicroPhotoService extends Service {
int preset = (int) ((val & 0xFF0L) >> 4);
int mediaType = (int)(val & 0xFL);
if (channel >= 256)
if (channel == 0x200)
{
// Heartbeat
long expectedHbTime = intent.getLongExtra("HeartbeatTime", ts);
infoLog("HB Timer Fired ACTION=" + action + " ExpTS=" + Long.toString(expectedHbTime));
Runnable runnable = new Runnable() {
public void run() {
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel(), true);
}
};
Thread th = new Thread(runnable);
th.start();
}
else if (channel >= 256)
{
infoLog("SERIAL Timer Fired: CH=" + (channel - 256) + " PR=" + preset);
}
@ -546,15 +582,60 @@ public class MicroPhotoService extends Service {
infoLog("IMG Timer Fired: CH=" + channel + " PR=" + preset);
}
mService.notifyToTakePhoto(mService.mNativeHandle, channel, preset, ts, null, mediaType);
if (channel == 0x200)
{
// Try to turn off GPS
try {
mService.detectGpsStatus();
} catch (Exception ex) {
ex.printStackTrace();
}
try {
boolean mpmstAlive = isMpMasterAlive(context);
if (!mpmstAlive) {
if (Build.TIME >= MicroPhotoContext.BUILD_TIME_WO_SID_20250418) {
int pid = MicroPhotoContext.getProcessIdOfService(context, MicroPhotoContext.PACKAGE_NAME_MPMASTER, MicroPhotoContext.SERVICE_NAME_MPMASTER);
if (pid != 0) {
android.os.Process.killProcess(pid);
}
}
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(MicroPhotoContext.PACKAGE_NAME_MPMASTER);
if (launchIntent != null) {
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mService.startActivity(launchIntent);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
// Register Next Photo Timer
long startTime = (ts == 0) ? (((new Date()).getTime() + 999) / 1000 + 1) : (ts + 1); // Add one second
mService.updateCaptureSchedule(startTime);
long startTime = System.currentTimeMillis() / 1000;
if (startTime < ts) {
// if current time is earlier schedule time
// we will register schedule time after ts
startTime = ts;
}
mService.updateCaptureSchedule(startTime + 1);
} else if (TextUtils.equals(ACTION_HEARTBEAT_MANUALLY, action)) {
Log.i(TAG, "HB Timer Fired ACTION=" + action);
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel());
String actionType = intent.getStringExtra("type");
if (TextUtils.isEmpty(actionType) || TextUtils.equals(actionType, "hb")) {
Log.i(TAG, "HB Timer Fired ACTION=" + action);
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel(), false);
} else if (TextUtils.equals(actionType, "basicInfo")) {
mService.sendBasicInfo(mService.mNativeHandle);
} else if (TextUtils.equals(actionType, "workStatus")) {
mService.sendWorkStatus(mService.mNativeHandle);
} else if (TextUtils.equals(actionType, "fault")) {
String faultCode = intent.getStringExtra("faultCode");
String faultInfo = intent.getStringExtra("faultInfo");
mService.sendFault(mService.mNativeHandle, faultCode, faultInfo);
}
} else if (TextUtils.equals(ACTION_TAKE_PHOTO_MANUALLY, action)) {
int channel = intent.getIntExtra(EXTRA_PARAM_CHANNEL, 0);
int preset = intent.getIntExtra(EXTRA_PARAM_PRESET, 0xFF);
@ -578,13 +659,18 @@ public class MicroPhotoService extends Service {
int cmd = intent.getIntExtra("cmd", 0);
mService.sendCameraCtrl(mService.mNativeHandle, channel, preset, cmd);
} else if (TextUtils.equals(ACTION_UPDATE_CONFIGS, action)) {
int restart = intent.getIntExtra("restart", 0);
final int restart = intent.getIntExtra("restart", 0);
final int channelToClean = intent.getIntExtra("channelToClean", -1);
Log.i(TAG, "UPD CFG Fired ACTION=" + action + " restart=" + restart);
if (restart != 0) {
restartSelfImpl(context, "Cfg Updated");
} else if (mService.mNativeHandle != 0) {
mService.reloadConfigs(mService.mNativeHandle);
}
new Thread(new Runnable() {
@Override
public void run() {
mService.reloadConfigs(mService.mNativeHandle, channelToClean);
if (restart != 0) {
restartSelfImpl(context, "Cfg Updated");
}
}
}).start();
} else if (TextUtils.equals(ACTION_VIDEO_FINISHED, action)) {
final boolean photoOrVideo = intent.getBooleanExtra("photoOrVideo", false);
final boolean result = intent.getBooleanExtra("result", false);
@ -697,13 +783,54 @@ public class MicroPhotoService extends Service {
} else if (TextUtils.equals(ACTION_RESTART, action)) {
String reason = intent.getStringExtra("reason");
MicroPhotoService.infoLog("Recv RESTART APP cmd, reason=" + (TextUtils.isEmpty(reason) ? "" : reason));
try {
Thread.sleep(100);
} catch (Exception ex) {
ex.printStackTrace();
}
sleep(100);
restartSelfImpl(context, reason);
} else if (TextUtils.equals(Intent.ACTION_TIME_CHANGED, action)) {
mService.notifyTimeUpdated(mService.mNativeHandle);
Date date = new Date();
long startTime = (date.getTime() + 999) / 1000;
mService.updateCaptureSchedule(startTime);
} else if (TextUtils.equals(ConnectivityManager.CONNECTIVITY_ACTION, action)) {
// mService.onNetworkChanged(intent);
} else if (TextUtils.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED, action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (isEthernetAdapter(device)) {
// 尝试设置以太网IP
// mService.onNetworkChanged(intent);
}
} else if (TextUtils.equals(UsbManager.ACTION_USB_DEVICE_DETACHED, action)) {
}
}
private boolean isEthernetAdapter(UsbDevice device) {
// 根据设备VID/PID或类型判断是否为以太网适配器
// 例如常见的以太网适配器类型为USB Class 0x02 (Communications) 或 0x0a (CDC Data)
int usbDevClass = device.getDeviceClass();
if (usbDevClass == UsbConstants.USB_CLASS_COMM ||
usbDevClass == UsbConstants.USB_CLASS_CDC_DATA) {
return true;
}
int interfaceCount = device.getInterfaceCount();
for (int i = 0; i < interfaceCount; i++) {
UsbInterface usbInterface = device.getInterface(i);
// CDC通讯类 (0x02)或CDC数据类
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM ||
usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
return true;
}
// 特定CDC-ECM/NCM子类判断
if (usbInterface.getInterfaceClass() == 0x02 &&
(usbInterface.getInterfaceSubclass() == 0x06 || // ECM
usbInterface.getInterfaceSubclass() == 0x0D)) { // NCM
return true;
}
}
return false;
}
}
@ -734,6 +861,9 @@ public class MicroPhotoService extends Service {
private void registerHeartbeatTimer(long timeoutMs) {
if (true) {
return;
}
// 创建延迟意图
long triggerTime = System.currentTimeMillis() + timeoutMs;
triggerTime -= (triggerTime % 1000);
@ -765,7 +895,13 @@ public class MicroPhotoService extends Service {
val = schedules.get(idx).longValue();
channel = ((val & 0XFFFF000) >> 12);
intent.putExtra(EXTRA_PARAM_SCHEDULE + idx, schedules.get(idx).longValue());
if (channel > 0xFF)
if (channel == 0x200)
{
channelStr.append("(HB) ");
intent.putExtra("HeartbeatDuration", (int)((val & 0XFF0) >> 4) * 60000);
intent.putExtra("HeartbeatTime", scheduleTime * 1000);
}
else if (channel > 0xFF)
{
channel &= 0xFF;
channelStr.append("(" + channel + "-" + Long.toString (((val & 0XFF0) >> 4), 16).toUpperCase() + "/SERIAL) ");
@ -910,6 +1046,8 @@ public class MicroPhotoService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "MicroPhotoService::onStartCommand");
if (intent == null) {
stopForeground(true);
stopSelf();
@ -924,7 +1062,6 @@ public class MicroPhotoService extends Service {
connect();
getApplicationContext().registerReceiver(mScreenaAtionReceiver, mScreenaAtionReceiver.getFilter());
if (intent.hasExtra("messenger")) {
mMessenger = intent.getParcelableExtra("messenger");
}
@ -979,11 +1116,6 @@ public class MicroPhotoService extends Service {
break;
case ACTION_STOP:
try {
getApplicationContext().unregisterReceiver(mScreenaAtionReceiver);
} catch (Exception ex) {
}
stopForeground(true);
stopSelf();
break;
@ -1012,6 +1144,111 @@ public class MicroPhotoService extends Service {
return defaultNetHandle;
}
protected void onNetworkChanged(final Intent intent) {
try {
new Thread(new Runnable() {
@Override
public void run() {
for (int idx = 0; idx < 8; idx++) {
if (checkNetworkInterfaces("eth0")) {
break;
}
sleep(40);
}
setStaticNetwork("eth0", "192.168.68.91", "192.168.68.91", "192.168.68.0", 24);
}
private boolean checkNetworkInterfaces(String iface) {
Network[] networks = mConnectivityManager.getAllNetworks();
for (Network network : networks) {
LinkProperties lp = mConnectivityManager.getLinkProperties(network);
if (lp != null) {
if (TextUtils.equals(iface, lp.getInterfaceName())) {
return true;
}
}
}
return false;
}
}).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
protected class EhternetCallback extends ConnectivityManager.NetworkCallback {
@Override
public void onLost(Network network) {
infoLog("Network Lost " + network.toString());
updateEhernet(mNativeHandle, network.getNetworkHandle(), false);
updateDefaultNetwork();
}
@Override
public void onAvailable(final Network network) {
String ip = "";
try {
NetworkInfo ni = mConnectivityManager.getNetworkInfo(network);
LinkProperties lp = mConnectivityManager.getLinkProperties(network);
if (lp != null) {
final String iface = lp.getInterfaceName();
List<LinkAddress> addresses = lp.getLinkAddresses();
if (addresses != null && addresses.size() > 0) {
for (LinkAddress linkAddress : addresses) {
InetAddress inetAddress = linkAddress.getAddress();
if (inetAddress != null && inetAddress instanceof Inet4Address) {
ip = inetAddress.getHostAddress();
break;
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
infoLog("Network Available " + network.toString() + " IP=" + ip + " Handle=" + Long.toString(network.getNetworkHandle()));
updateEhernet(mNativeHandle, network.getNetworkHandle(), true);
updateDefaultNetwork();
}
private void updateDefaultNetwork() {
MicroPhotoService thisService = MicroPhotoService.this;
long defaultNetHandle = thisService.getDefaultNetworkHandle();
if (defaultNetHandle != 0) {
thisService.updateActiveNetwork(thisService.mNativeHandle, defaultNetHandle, true);
}
}
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
String interfaceName = linkProperties.getInterfaceName();
if (interfaceName != null &&
(interfaceName.startsWith("eth") ||
interfaceName.startsWith("usb") ||
interfaceName.startsWith("rndis"))) {
// 检测到以太网接口,可以尝试设置 IP
// configureEthernetIp(interfaceName);
Log.d("onLinkPropertiesChanged", "Ethernet hardware detected");
}
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
// 检查是否是以太网,即使没有完整的网络功能
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
// 以太网硬件检测到
Log.d("EthernetMonitor", "Ethernet hardware detected");
}
}
}
private void startTerminalService(Intent intent) {
if (MicroPhotoService.this.mNativeHandle != 0) {
@ -1080,50 +1317,9 @@ public class MicroPhotoService extends Service {
try {
if (usingEthernet()) {
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onLost(Network network) {
infoLog("Network Lost " + network.toString());
updateEhernet(mNativeHandle, network.getNetworkHandle(), false);
updateDefaultNetwork();
}
@Override
public void onAvailable(final Network network) {
String ip = "";
try {
NetworkInfo ni = mConnectivityManager.getNetworkInfo(network);
LinkProperties lp = mConnectivityManager.getLinkProperties(network);
if (lp != null) {
List<LinkAddress> addresses = lp.getLinkAddresses();
if (addresses != null && addresses.size() > 0) {
for (LinkAddress linkAddress : addresses) {
InetAddress inetAddress = linkAddress.getAddress();
if (inetAddress != null && inetAddress instanceof Inet4Address) {
ip = inetAddress.getHostAddress();
break;
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
infoLog("Network Available " + network.toString() + " IP=" + ip + " Handle=" + Long.toString(network.getNetworkHandle()));
updateEhernet(mNativeHandle, network.getNetworkHandle(), true);
updateDefaultNetwork();
}
private void updateDefaultNetwork() {
MicroPhotoService thisService = MicroPhotoService.this;
long defaultNetHandle = thisService.getDefaultNetworkHandle();
if (defaultNetHandle != 0) {
thisService.updateActiveNetwork(thisService.mNativeHandle, defaultNetHandle, true);
}
}
};
mNetworkCallback = new EhternetCallback();
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build();
@ -1190,11 +1386,6 @@ public class MicroPhotoService extends Service {
uninit(mNativeHandle);
mNativeHandle = 0;
try {
getApplicationContext().unregisterReceiver(mScreenaAtionReceiver);
} catch (Exception ex) {
}
stopForeground(true);
stopSelf();
}
@ -1277,7 +1468,7 @@ public class MicroPhotoService extends Service {
mStateService = STATE_SERVICE.CONNECTED;
startForeground(NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification());
}
}, 10000);
}, 8000);
}
@ -1438,7 +1629,21 @@ public class MicroPhotoService extends Service {
SignalStrength ss = telephonyManager.getSignalStrength();
if (ss != null) {
return ss.getLevel();
int ssVal = -1;
List<CellSignalStrength> cellSignalStrengths = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
cellSignalStrengths = ss.getCellSignalStrengths();
} else {
int asu = ss.getGsmSignalStrength();
if (asu != 99) {
ssVal = -113 + 2 * asu;
}
}
for (CellSignalStrength cellSignalStrength : cellSignalStrengths) {
ssVal = cellSignalStrength.getDbm();
break;
}
return (ssVal << 8) | (ss.getLevel() & 0xFF);
}
} catch (Exception ex) {
}
@ -1463,7 +1668,13 @@ public class MicroPhotoService extends Service {
long endTime = dt.getTime() - 1;
NetworkUtils.Usage usage = NetworkUtils.getApplicationQuerySummary(this.getApplicationContext(), startTime, endTime, getApplicationInfo().uid);
return "RX=" + Long.toString(usage.mobleRxBytes) + "&TX=" + Long.toString(usage.mobleTxBytes);
Date now = new Date();
Date todayStart = new Date(now.getYear(), now.getMonth(), now.getDate(), 0, 0, 0);
long todayStartTime = todayStart.getTime();
long todayEndTime = now.getTime();
NetworkUtils.Usage todayUsage = NetworkUtils.getApplicationQuerySummary(this.getApplicationContext(), todayStartTime, todayEndTime, getApplicationInfo().uid);
return "DRX=" + Long.toString(todayUsage.mobleRxBytes) + "&DTX=" + Long.toString(todayUsage.mobleTxBytes) + "&RX=" + Long.toString(usage.mobleRxBytes) + "&TX=" + Long.toString(usage.mobleTxBytes);
}
public boolean installApp(final String path, long delayedTime) {
@ -1495,6 +1706,22 @@ public class MicroPhotoService extends Service {
} else {
Log.w(TAG, "Recv REBOOT command");
SysApi.reboot(MicroPhotoService.this.getApplicationContext());
new Thread(new Runnable() {
@Override
public void run() {
sleep(5000);
try {
Process process = Runtime.getRuntime().exec("/system/xbin/su root");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("/system/bin/reboot\n");
os.writeBytes("exit\n"); // 重要退出su shell
os.flush();
int exitValue = process.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
}
}
};
@ -1599,26 +1826,144 @@ public class MicroPhotoService extends Service {
return exitCode;
}
public void setStaticNetwork(String iface, String ip, String netmask, String gateway)
{
if (!TextUtils.equals("0.0.0.0", ip)) {
Intent intent = new Intent();
intent.putExtra("cmd", "setnet");
intent.putExtra("staticip", true);
intent.putExtra("iface", iface);
intent.putExtra("ip", ip);
intent.putExtra("netmask", netmask);
if (!TextUtils.isEmpty(gateway)) {
intent.putExtra("gateway", gateway);
public void setStaticNetwork(String iface, String ip, String gateway, String ipPrefix, int ipPrefixLength) {
int exitValue = -1;
boolean success = false;
try {
File ethShellFile = new File(getFilesDir(), "eth.sh");
if (ethShellFile.exists()) {
Process process = null;
DataOutputStream os = null;
BufferedReader inputReader = null;
try {
process = Runtime.getRuntime().exec("/system/xbin/su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes("/system/bin/sh " + ethShellFile.getAbsolutePath() + "\n");
os.writeBytes("exit\n"); // 重要退出su shell
os.flush();
exitValue = process.waitFor();
inputReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
StringBuilder error = new StringBuilder();
while ((line = inputReader.readLine()) != null) {
error.append(line);
error.append("\n");
}
if (exitValue == 0) {
infoLog("Add route successfully Code=" + exitValue);
} else {
infoLog(error.toString());
}
} catch (Exception ex) {
} finally {
FilesUtils.closeFriendly(os);
FilesUtils.closeFriendly(inputReader);
if (process != null) {
process.destroy();
}
}
} else {
Process process = Runtime.getRuntime().exec("/system/xbin/su root");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("/system/bin/ip link set eth0 down\n");
os.writeBytes("/system/bin/sleep 1\n"); // Add delay
os.writeBytes("/system/bin/ip addr flush dev eth0\n"); // Clear existing config
os.writeBytes("/system/bin/ip addr add 192.168.68.91/24 broadcast 192.168.68.255 dev eth0\n");
os.writeBytes("/system/bin/ip link set eth0 up\n");
os.writeBytes("/system/bin/sleep 3\n");
os.writeBytes("/system/bin/ip route delete 192.168.68.0/24 table 20 2>/dev/null || true\n");
os.writeBytes("/system/bin/ip route add 192.168.68.0/24 dev eth0 proto static scope link table 20\n");
os.writeBytes("/system/bin/ip route flush cache\n");
// os.writeBytes("echo 'nameserver 8.8.8.8' > /etc/resolv.conf\n");
os.writeBytes("/system/bin/ip rule del to 192.168.68.0/24 2>/dev/null || true\n");
os.writeBytes("/system/bin/ip rule add from all to 192.168.68.0/24 lookup 20 prio 1000\n");
os.writeBytes("/system/bin/ip route flush cache\n");
// Verify routes were added
os.writeBytes("if ! /system/bin/ip rule | grep '192.168.68.0/24'; then\n");
os.writeBytes(" echo 'Route rule failed to apply, retrying...'\n");
os.writeBytes(" sleep 1\n");
os.writeBytes(" /system/bin/ip rule add from all to 192.168.68.0/24 lookup 20 prio 1000\n");
os.writeBytes(" /system/bin/ip route flush cache\n");
os.writeBytes("fi\n");
os.writeBytes("exit\n"); // 重要退出su shell
os.flush();
exitValue = process.waitFor();
if (exitValue != 0) {
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
StringBuilder error = new StringBuilder();
while ((line = reader.readLine()) != null) {
error.append(line);
error.append("\n");
}
Log.e(TAG, error.toString());
sleep(100);
for (int idx = 0; idx < 10; idx++) {
Process routeProcess3 = Runtime.getRuntime().exec("/system/xbin/su root");
DataOutputStream os3 = new DataOutputStream(routeProcess3.getOutputStream());
// os3.writeBytes("/system/bin/ip rule del to 192.168.68.0/24 2>/dev/null || true\n");
os3.writeBytes("/system/bin/ip rule add from all to 192.168.68.0/24 lookup 20 prio 1000\n");
os3.writeBytes("CMD_EXIT_CODE=$?\n"); // 保存返回值
os3.writeBytes("echo \"CMD_RESULT:$CMD_EXIT_CODE\"\n"); // 输出标记和返回值
os3.writeBytes("/system/bin/ip route flush cache\n");
os3.writeBytes("exit\n"); // 重要退出su shell
os3.flush();
int commandExitCode = -1;
BufferedReader reader2 = new BufferedReader(new InputStreamReader(routeProcess3.getErrorStream()));
StringBuilder error2 = new StringBuilder();
while ((line = reader2.readLine()) != null) {
if (line.startsWith("CMD_RESULT:")) {
commandExitCode = Integer.parseInt(line.substring(11));
Log.d("RouteConfig", "Command exit code: " + commandExitCode);
break;
}
}
exitValue = routeProcess3.waitFor();
if (exitValue == 0 || commandExitCode == 2) {
infoLog("Add route successfully Code=" + exitValue);
break;
} else {
}
sleep(500);
}
}
intent.putExtra("dns1", "0.0.0.0");
intent.putExtra("dns2", "0.0.0.0");
sendBroadcast(getApplicationContext(), intent);
} catch (Exception e) {
Log.e(TAG, "Failed to set interface down: " + e.getMessage());
}
}
public static void sendBroadcast(Context context, Intent intent)
{
public int executeCommand(String cmd) {
int resCode = -1;
try {
Process downProcess = Runtime.getRuntime().exec(cmd);
resCode = downProcess.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
return resCode;
}
public static void sendBroadcast(Context context, Intent intent) {
intent.setAction("com.xy.xsetting.action");
intent.setPackage("com.android.systemui");
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@ -1642,8 +1987,13 @@ cellSignalStrengthGsm.getDbm();
// protected native long[] getNextScheduleItem(long handler);
protected native boolean notifyToTakePhoto(long handler, int channel, int preset, long scheduleTime, String url, int mediaType);
protected native boolean sendHeartbeat(long handler, int signalLevel);
protected native boolean reloadConfigs(long handler);
protected native void notifyTimeUpdated(long handler);
protected native boolean sendHeartbeat(long handler, int signalLevel, boolean scheduled);
protected native boolean sendBasicInfo(long handler);
protected native boolean sendWorkStatus(long handler);
protected native boolean sendFault(long handler, String faultCode, String faultInfo);
protected native boolean reloadConfigs(long handler, int channelToClean);
protected native void updatePosition(long handler, double lon, double lat, double radius, long ts);
protected native boolean updateEhernet(long handler, long nativeNetworkHandle, boolean available);
protected native boolean updateActiveNetwork(long handler, long nativeNetworkHandle, boolean available);

@ -1,76 +0,0 @@
package com.xypower.mpapp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;
public class ScreenActionReceiver extends BroadcastReceiver {
private String TAG = "ScreenActionReceiver";
@Override
public void onReceive(Context context, Intent intent) {
//LOG
StringBuilder sb = new StringBuilder();
sb.append("Action: " + intent.getAction() + "\n");
// sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
String log = sb.toString();
Log.d(TAG, log);
Toast.makeText(context, log, Toast.LENGTH_SHORT).show();
String action = intent.getAction();
try {
if (Intent.ACTION_SCREEN_ON.equals(action)) {
Log.d(TAG, "screen is on...");
Toast.makeText(context, "screen ON", Toast.LENGTH_SHORT);
//Run the locker
context.startService(new Intent(context, FloatingWindow.class));
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
Log.d(TAG, "screen is off...");
Toast.makeText(context, "screen OFF", Toast.LENGTH_SHORT);
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
Log.d(TAG, "screen is unlock...");
Toast.makeText(context, "screen UNLOCK", Toast.LENGTH_SHORT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, FloatingWindow.class));
} else {
context.startService(new Intent(context, FloatingWindow.class));
}
} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Log.d(TAG, "boot completed...");
Toast.makeText(context, "BOOTED..", Toast.LENGTH_SHORT);
//Run the locker
/* Intent i = new Intent(context, FloatingWindow.class);
context.startService(i);
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// context.startForegroundService(new Intent(context, FloatingWindow.class));
} else {
// context.startService(new Intent(context, FloatingWindow.class));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public IntentFilter getFilter(){
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
return filter;
}
}

@ -769,7 +769,10 @@ public class Camera2VideoActivity extends AppCompatActivity {
@Override
public void run() {
Log.i("OSD", "Record Stop " + Long.toString(mDuration));
mGPUCameraRecorder.stop();
if (mGPUCameraRecorder != null) {
mGPUCameraRecorder.stop();
}
int aa = 0;
}
@ -809,6 +812,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
.cameraId(Integer.toString(mCameraId))
.mute(true)
.duration(mDuration * 1000)
.rotation(mOrientation)
.build();
Log.i("OSD", "mGPUCameraRecorder created");

@ -3,7 +3,6 @@ package com.xypower.mpapp.video;
import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -18,7 +17,6 @@ import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@ -36,8 +34,6 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.legacy.app.FragmentCompat;
import androidx.legacy.app.FragmentCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.os.Environment;
@ -54,7 +50,6 @@ import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.xypower.mpapp.MicroPhotoService;
import com.xypower.mpapp.R;
@ -76,7 +71,7 @@ import java.util.concurrent.TimeUnit;
* Use the {@link VideoFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class VideoFragment extends Fragment implements View.OnClickListener, MediaRecorder.OnInfoListener, FragmentCompat.OnRequestPermissionsResultCallback {
public class VideoFragment extends Fragment implements View.OnClickListener, MediaRecorder.OnInfoListener {
public static final String ACTION_FINISH = "com.xypower.mvapp.ACT_FINISH";
public static final String ACTION_MP_VIDEO_FINISHED = "com.xypower.mpapp.ACT_V_FINISHED";

@ -205,13 +205,13 @@
app:layout_constraintTop_toTopOf="@+id/btnStartServ" />
<Button
android:id="@+id/btnLogs"
android:id="@+id/btnSendHb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_send_hb"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
android:text="日志"
app:layout_constraintStart_toEndOf="@+id/btnChannels"
app:layout_constraintTop_toTopOf="@+id/btnStartServ" />
@ -260,6 +260,17 @@
app:layout_constraintStart_toEndOf="@+id/btnTakePhoto3"
app:layout_constraintTop_toTopOf="@+id/btnTakePhoto" />
<Button
android:id="@+id/btnSendWs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_send_ws"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
app:layout_constraintStart_toEndOf="@+id/btnTakePhoto4"
app:layout_constraintTop_toTopOf="@+id/btnTakePhoto" />
<Button
android:id="@+id/takeVideoBtn"
android:layout_width="wrap_content"
@ -306,14 +317,25 @@
app:layout_constraintTop_toTopOf="@+id/takeVideoBtn" />
<Button
android:id="@+id/btnSendHb"
android:id="@+id/btnSendBi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_send_hb"
android:text="@string/main_send_bi"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_spacing_small"
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
app:layout_constraintStart_toEndOf="@+id/takeVideoBtn4"
app:layout_constraintTop_toTopOf="@+id/takeVideoBtn" />
<Button
android:id="@+id/btnLogs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin_small"
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
android:text="日志"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/takeVideoBtn" />
@ -325,8 +347,8 @@
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
app:layout_constraintStart_toEndOf="@+id/btnSendHb"
app:layout_constraintTop_toTopOf="@+id/btnSendHb" />
app:layout_constraintStart_toEndOf="@+id/btnLogs"
app:layout_constraintTop_toTopOf="@+id/btnLogs" />
<Button
android:id="@+id/btnReboot"
@ -337,7 +359,7 @@
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
app:layout_constraintStart_toEndOf="@+id/btnRestartApp"
app:layout_constraintTop_toTopOf="@+id/btnSendHb" />
app:layout_constraintTop_toTopOf="@+id/btnLogs" />
<Button
android:id="@+id/btnCameraInfo"
@ -348,7 +370,18 @@
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
app:layout_constraintStart_toEndOf="@+id/btnReboot"
app:layout_constraintTop_toTopOf="@+id/btnSendHb" />
app:layout_constraintTop_toTopOf="@+id/btnLogs" />
<Button
android:id="@+id/btnSendFault"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_send_fault"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:minWidth="@dimen/activity_btn_min_width"
android:minHeight="@dimen/activity_btn_min_height"
app:layout_constraintStart_toEndOf="@+id/btnCameraInfo"
app:layout_constraintTop_toTopOf="@+id/btnLogs" />
<Button
android:id="@+id/btnDowseCamera"

@ -6,8 +6,10 @@
<item>65282-江苏</item>
<item>65283-湖南</item>
<item>65284-浙江</item>
<item>65285-河南统一</item>
<item>65286-郑州</item>
<item>65290-河南</item>
<item>65290-河南全景</item>
<item>65298-宁夏</item>
<item>65310-山西智洋</item>
</string-array>
</resources>

@ -7,6 +7,9 @@
<string name="main_packet_size_default">默认2K</string>
<string name="main_server">支持域名自动转IP</string>
<string name="main_send_hb">心跳</string>
<string name="main_send_ws">工作状态</string>
<string name="main_send_bi">基本信息</string>
<string name="main_send_fault">故障</string>
<string name="main_restart_app">重启APP</string>
<string name="main_reboot">重启设备</string>
<string name="main_camera_info">摄像头</string>

@ -30,9 +30,10 @@ android {
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.core:core:1.6.0'
// implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'com.linkedin.dexmaker:dexmaker:2.28.3'
// implementation 'com.linkedin.dexmaker:dexmaker:2.28.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

@ -33,8 +33,8 @@ public class FileDownloader {
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setConnectTimeout(5000);
connection.setReadTimeout(120000);
connection.setConnectTimeout(10000);
connection.setReadTimeout(30000);
connection.setDoInput(true);
connection.connect();
final File temp = new File(filePath);

@ -1,10 +1,14 @@
package com.xypower.common;
import android.content.Context;
import android.content.res.AssetManager;
import android.text.TextUtils;
import android.util.Log;
import org.w3c.dom.Text;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
@ -13,6 +17,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.channels.Channels;
import java.nio.channels.SeekableByteChannel;
@ -251,4 +256,217 @@ public class FilesUtils {
public static byte[] readAllBytes(String file) {
return readAllBytes(new File(file));
}
public static boolean delete(File file) {
if (!file.exists()) {
return false;
} else {
if (file.isFile())
return deleteSingleFile(file);
else
return deleteDirectory(file.getAbsolutePath());
}
}
private static boolean deleteSingleFile(File file) {
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
// Log.e("--Method--", "Copy_Delete.deleteSingleFile: 删除单个文件" + filePath$Name + "成功!");
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* @param filePath
* @return truefalse
*/
private static boolean deleteDirectory(String filePath) {
// 如果dir不以文件分隔符结尾自动添加文件分隔符
if (!filePath.endsWith(File.separator))
filePath = filePath + File.separator;
File dirFile = new File(filePath);
// 如果dir对应的文件不存在或者不是一个目录则退出
if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
return false;
}
boolean flag = true;
// 删除文件夹中的所有文件包括子目录
File[] files = dirFile.listFiles();
for (File file : files) {
// 删除子文件
if (file.isFile()) {
flag = deleteSingleFile(file);
if (!flag)
break;
}
// 删除子目录
else if (file.isDirectory()) {
flag = deleteDirectory(file
.getAbsolutePath());
if (!flag)
break;
}
}
if (!flag) {
return false;
}
// 删除当前目录
if (dirFile.delete()) {
// Log.e("--Method--", "Copy_Delete.deleteDirectory: 删除目录" + filePath + "成功!");
return true;
} else {
return false;
}
}
public static void copyAssetsDir(Context context, String directory, String destPath) {
try {
AssetManager assetManager = context.getAssets();
String[] fileList = assetManager.list(directory);
if (fileList != null && fileList.length > 0) {
File file = new File(destPath);
if (!file.exists()) {
file.mkdirs();
}
if (!directory.endsWith(File.separator)) {
directory += File.separator;
}
if (!destPath.endsWith(File.separator)) {
destPath += File.separator;
}
for (String fileName : fileList) {
copyAssetsDir(context, directory + fileName, destPath + fileName);
}
} else {
// Try to file
copyAssetsFile(context, directory, destPath);
}
} catch (Exception e) {
e.printStackTrace();
}
// else {//如果是文件
// InputStream inputStream=context.getAssets().open(filePath);
// File file=new File(context.getFilesDir().getAbsolutePath()+ File.separator+filePath);
// Log.i("copyAssets2Phone","file:"+file);
// if(!file.exists() || file.length()==0) {
// FileOutputStream fos=new FileOutputStream(file);
// int len=-1;
// byte[] buffer=new byte[1024];
// while ((len=inputStream.read(buffer))!=-1){
// fos.write(buffer,0,len);
// }
// fos.flush();
// inputStream.close();
// fos.close();
// showToast(context,"模型文件复制完毕");
// } else {
// showToast(context,"模型文件已存在,无需复制");
// }
// }
}
public static void copyAssetsFile(Context context, String fileName, String destPath) {
InputStream inputStream = null;
FileOutputStream fos = null;
try {
inputStream = context.getAssets().open(fileName);
//getFilesDir() 获得当前APP的安装路径 /data/data/包名/files 目录
File file = new File(destPath);
if (file.exists()) {
file.delete();
}
File parentDir = file.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
if (parentDir != null && !parentDir.canWrite()) {
Log.e("FilesUtils", "No write permission to directory: " + parentDir.getAbsolutePath());
return;
}
fos = new FileOutputStream(file);
int len = -1;
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) != -1) {
try {
fos.write(buffer, 0, len);
} catch (Exception ex) {
ex.printStackTrace();
}
}
fos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
FilesUtils.closeFriendly(inputStream);
FilesUtils.closeFriendly(fos);
}
}
/**
* AssetsCRLFLF
*
* @param context
* @param fileName Assets
* @param destPath
*/
public static void copyAndNormalizeTextAssetsFile(Context context, String fileName, String destPath) {
InputStream inputStream = null;
BufferedReader reader = null;
BufferedWriter writer = null;
try {
inputStream = context.getAssets().open(fileName);
reader = new BufferedReader(new InputStreamReader(inputStream));
// 创建目标文件
File file = new File(destPath);
if (file.exists()) {
file.delete();
}
File parentDir = file.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
if (parentDir != null && !parentDir.canWrite()) {
Log.e("FilesUtils", "No write permission to directory: " + parentDir.getAbsolutePath());
return;
}
// 使用BufferedWriter写入文件同时处理行尾符
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
String line;
// 逐行读取并写入由BufferedWriter自动处理行尾
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine(); // 使用平台默认的换行符在Android上是LF
}
writer.flush();
Log.d("FilesUtils", "File normalized and copied successfully: " + destPath);
} catch (Exception e) {
Log.e("FilesUtils", "Error normalizing file: " + e.getMessage(), e);
} finally {
closeFriendly(reader);
closeFriendly(writer);
closeFriendly(inputStream);
}
}
}

@ -1,248 +0,0 @@
package com.xypower.common;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import androidx.annotation.RequiresApi;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.android.dx.stock.ProxyBuilder;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HotspotManager {
@RequiresApi(api = Build.VERSION_CODES.O)
public static class OreoWifiManager {
private static final String TAG = OreoWifiManager.class.getSimpleName();
private Context mContext;
private WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
public OreoWifiManager(Context c) {
mContext = c;
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(ConnectivityManager.class);
}
/**
* This sets the Wifi SSID and password
* Call this before {@code startTethering} if app is a system/privileged app
* Requires: android.permission.TETHER_PRIVILEGED which is only granted to system apps
*/
public void configureHotspot(String name, String password) {
WifiConfiguration apConfig = new WifiConfiguration();
apConfig.SSID = name;
apConfig.preSharedKey = password;
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
try {
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
Log.d(TAG, "setWifiApConfiguration - success? " + status);
} catch (Exception e) {
Log.e(TAG, "Error in configureHotspot");
e.printStackTrace();
}
}
/**
* Checks where tethering is on.
* This is determined by the getTetheredIfaces() method,
* that will return an empty array if not devices are tethered
*
* @return true if a tethered device is found, false if not found
*/
/*public boolean isTetherActive() {
try {
Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
if (method == null) {
Log.e(TAG, "getTetheredIfaces is null");
} else {
String res[] = (String[]) method.invoke(mConnectivityManager, null);
Log.d(TAG, "getTetheredIfaces invoked");
Log.d(TAG, Arrays.toString(res));
if (res.length > 0) {
return true;
}
}
} catch (Exception e) {
Log.e(TAG, "Error in getTetheredIfaces");
e.printStackTrace();
}
return false;
}
*/
/**
* This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
* Does not require app to have system/privileged access
* Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
*/
public boolean startTethering(final OnStartTetheringCallback callback) {
// On Pie if we try to start tethering while it is already on, it will
// be disabled. This is needed when startTethering() is called programmatically.
/*if (isTetherActive()) {
Log.d(TAG, "Tether already active, returning");
return false;
}*/
File outputDir = mContext.getCodeCacheDir();
Object proxy;
try {
proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass())
.dexCache(outputDir).handler(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "onTetheringStarted":
callback.onTetheringStarted();
break;
case "onTetheringFailed":
callback.onTetheringFailed();
break;
default:
ProxyBuilder.callSuper(proxy, method, args);
}
return null;
}
}).build();
} catch (Exception e) {
Log.e(TAG, "Error in enableTethering ProxyBuilder");
e.printStackTrace();
return false;
}
Method method = null;
try {
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
Log.d(TAG, "startTethering invoked");
}
return true;
} catch (Exception e) {
Log.e(TAG, "Error in enableTethering");
e.printStackTrace();
}
return false;
}
public void stopTethering() {
try {
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
if (method == null) {
Log.e(TAG, "stopTetheringMethod is null");
} else {
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
Log.d(TAG, "stopTethering invoked");
}
} catch (Exception e) {
Log.e(TAG, "stopTethering error: " + e.toString());
e.printStackTrace();
}
}
private Class OnStartTetheringCallbackClass() {
try {
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
} catch (ClassNotFoundException e) {
Log.e(TAG, "OnStartTetheringCallbackClass error: " + e.toString());
e.printStackTrace();
}
return null;
}
}
public static abstract class OnStartTetheringCallback {
/**
* Called when tethering has been successfully started.
*/
public abstract void onTetheringStarted();
/**
* Called when starting tethering failed.
*/
public abstract void onTetheringFailed();
}
@RequiresApi(api = Build.VERSION_CODES.O)
private static void setHotspotOnPhone(Context mContext, boolean isEnable) {
OreoWifiManager mTestOreoWifiManager = null;
if (mTestOreoWifiManager ==null) {
mTestOreoWifiManager = new OreoWifiManager(mContext);
}
if (isEnable){
OnStartTetheringCallback callback = new OnStartTetheringCallback() {
@Override
public void onTetheringStarted() {
}
@Override
public void onTetheringFailed() {
}
};
mTestOreoWifiManager.startTethering(callback);
}else{
mTestOreoWifiManager.stopTethering();
}
}
/*
public static void setWiFiApEnable(Context context, boolean isEnable) {
ConnectivityManager mConnectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (isEnable) {
mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, false, new ConnectivityManager.OnStartTetheringCallback() {
@Override
public void onTetheringStarted() {
Log.d(TAG, "onTetheringStarted");
// Don't fire a callback here, instead wait for the next update from wifi.
}
@Override
public void onTetheringFailed() {
Log.d(TAG, "onTetheringFailed");
// TODO: Show error.
}
});
} else {
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
}
}
*/
public static void enableHotspot(Context context, boolean isEnable) {
// R: Adnroid 11
// O: Android 8
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Android 11
setHotspotOnPhone(context, isEnable);
}/* else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Android 8
}
*/
}
}

@ -2,6 +2,7 @@ package com.xypower.common;
import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import org.json.JSONArray;
import org.json.JSONException;
@ -132,7 +133,7 @@ public class JSONUtils {
return false;
}
File configFile = new File(Environment.getExternalStorageDirectory(), path);
File configFile = new File(path.trim());
if (!configFile.exists()) {
if (val == null) {
// Should delete the config field

@ -1,5 +1,8 @@
package com.xypower.common;
import android.content.Context;
import java.io.FileInputStream;
import java.security.MessageDigest;
/* loaded from: ds_base_2.0.9_23030112.aar:classes.jar:com/dowse/base/util/MD5Util.class */
@ -29,4 +32,25 @@ public class MD5Util {
}
return r.toString();
}
public static String getFileMd5(String filePath) {
try (FileInputStream fis = new FileInputStream(filePath)) {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[8192]; // 使用大缓冲区提升性能:ml-citation{ref="5,7" data="citationList"}
int len;
while ((len = fis.read(buffer)) != -1) {
md.update(buffer, 0, len);
}
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff)); // 处理字节转十六进制:ml-citation{ref="3,7" data="citationList"}
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}

@ -30,7 +30,13 @@ public class MicroPhotoContext {
public static final String PACKAGE_NAME_MPAPP = "com.xypower.mpapp";
public static final String PACKAGE_NAME_MPMASTER = "com.xypower.mpmaster";
public static final String PACKAGE_NAME_MPRES = "com.xypower.mpres";
public static final String SERVICE_NAME_MPSERVICE = PACKAGE_NAME_MPAPP + ".MicroPhotoService";
public static final String SERVICE_NAME_MPMASTER = PACKAGE_NAME_MPMASTER + ".MpMasterService";
public static final String ACTION_HEARTBEAT_MP = "com.xypower.mpapp.ACT_HB";
public static final String ACTION_TAKEPHOTO_MP = "com.xypower.mpapp.ACT_TP";
public static final String ACTION_RESTART_MP = "com.xypower.mpapp.ACT_RESTART";
public static final String ACTION_UPDATE_CONFIGS_MP = "com.xypower.mpapp.ACT_UPD_CFG";
@ -44,6 +50,8 @@ public class MicroPhotoContext {
public final static int DEFAULT_HEARTBEAT_FOR_SHARED_NW = 10; // minutes
public final static int DEFAULT_QUICK_HEARTBEAT = 60; // second
public static final long BUILD_TIME_WO_SID_20250418 = 1744905600000L;
public static class AppConfig {
public String cmdid;
public String server;
@ -141,13 +149,13 @@ public class MicroPhotoContext {
return str;
}
public static boolean isAppAlive(Context context, String packageName) {
public static boolean isAppAlive(Context context, String packageName, String serviceClassName) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = am.getRunningServices(Integer.MAX_VALUE);
boolean isRunning = false;
for (ActivityManager.RunningServiceInfo rsi : services) {
if (packageName.equalsIgnoreCase(rsi.service.getPackageName())) {
if (packageName.equalsIgnoreCase(rsi.service.getPackageName()) && TextUtils.equals(serviceClassName, rsi.service.getClassName())) {
isRunning = true;
break;
}
@ -156,6 +164,21 @@ public class MicroPhotoContext {
return isRunning;
}
public static int getProcessIdOfService(Context context, String packageName, String serviceClassName) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = am.getRunningServices(Integer.MAX_VALUE);
int pid = 0;
for (ActivityManager.RunningServiceInfo rsi : services) {
if (packageName.equalsIgnoreCase(rsi.service.getPackageName()) && TextUtils.equals(serviceClassName, rsi.service.getClassName())) {
pid = rsi.pid;
break;
}
}
return pid;
}
public static String buildAppDir(Context contxt) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
@ -227,6 +250,22 @@ public class MicroPhotoContext {
return path;
}
public static String buildMpResAppDir(Context contxt) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
if (!path.endsWith(File.separator)) {
path += File.separator;
}
path += PACKAGE_NAME_MPRES + File.separator;
File pathFile = new File(path);
if (!pathFile.exists() && !pathFile.mkdirs()) {
return null;
}
return path;
}
public static boolean hasMpAppConfig(Context context) {
boolean existed = true;
String appPath = MicroPhotoContext.buildMpAppDir(context);
@ -261,7 +300,7 @@ public class MicroPhotoContext {
String content = FilesUtils.readTextFile(path);
JSONObject jsonObject = TextUtils.isEmpty(content) ? new JSONObject() : new JSONObject(content);
appConfig.cmdid = jsonObject.optString(jsonObject.has("cmdid") ? "cmdid" : "CMDID", "");
appConfig.cmdid = jsonObject.optString(jsonObject.has("CMDID") ? "CMDID" : "cmdid", "");
appConfig.server = jsonObject.optString(jsonObject.has("server") ? "server" : "Server", "");
appConfig.port = jsonObject.optInt(jsonObject.has("port") ? "port" : "Port", 0);
appConfig.protocol = jsonObject.optInt(jsonObject.has("protocol") ? "protocol" : "Protocol", DEFAULT_PROTOCOL);

@ -0,0 +1 @@
{"absHeartbeats":[33420,85808],"heartbeat":10,"mntnMode":0,"mpappMonitorTimeout":1800000,"port":40101,"quickHbMode":0,"quickHeartbeat":60,"separateNetwork":1,"server":"61.169.135.150","timeForKeepingLogs":15,"usingAbsHbTime":1}

@ -0,0 +1 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"cameraType":0,"compensation":0,"customHdr":0,"exposureTime":0,"hdrStep":0,"ldrEnabled":0,"orientation":0,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%%\r\n\u4fe1\u53f7:%%SL%% %%BV%%V"},"quality":80,"recognization":0,"requestTemplate":2,"resolutionCX":5376,"resolutionCY":3024,"sceneMode":0,"sensitivity":0,"usbCamera":0,"usingRawFormat":0,"usingSysCamera":0,"vendor":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0,"zoom":0,"zoomRatio":1}

@ -0,0 +1 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"burstCaptures":4,"cameraType":0,"compensation":0,"customHdr":0,"exposureTime":0,"hdrStep":0,"ldrEnabled":0,"orientation":3,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%%\r\n\u4fe1\u53f7:%%SL%% %%BV%%V"},"quality":80,"recognization":0,"requestTemplate":2,"resolutionCX":1920,"resolutionCY":1080,"sceneMode":0,"sensitivity":0,"usbCamera":0,"usingRawFormat":2,"usingSysCamera":0,"vendor":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0,"zoom":0,"zoomRatio":1}

@ -0,0 +1 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"cameraType":0,"compensation":0,"customHdr":0,"hdrStep":0,"ldrEnabled":0,"orientation":4,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%%\r\n\u4fe1\u53f7:%%SL%% %%BV%%V"},"recognization":0,"requestTemplate":1,"resolutionCX":3264,"resolutionCY":2448,"sceneMode":0,"usbCamera":0,"usingRawFormat":0,"usingSysCamera":0,"vendor":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0}

@ -1 +1 @@
{"blobName16":"354","blobName32":"366","blobName8":"output","borderColor":16776960,"enabled":1,"items":[{"enabled":1,"iid":0,"name":"\u6316\u6398\u673a","prob":0.5,"subType":5,"type":1},{"enabled":1,"iid":1,"name":"\u540a\u5854","prob":0.5,"subType":2,"type":1},{"enabled":1,"iid":2,"name":"\u540a\u8f66","prob":0.5,"subType":1,"type":1},{"enabled":1,"iid":3,"name":"\u6c34\u6ce5\u6cf5\u8f66","prob":0.5,"subType":4,"type":1},{"enabled":1,"iid":4,"name":"\u5c71\u706b","prob":0.5,"subType":40,"type":4},{"enabled":1,"iid":5,"name":"\u70df\u96fe","prob":0.5,"subType":41,"type":4},{"enabled":1,"iid":6,"name":"\u63a8\u571f\u673a","prob":0.5,"subType":3,"type":1},{"enabled":1,"iid":7,"name":"\u7ffb\u6597\u8f66","prob":0.5,"subType":10,"type":1},{"enabled":1,"iid":8,"name":"\u5bfc\u7ebf\u5f02\u7269","prob":0.5,"subType":1,"type":3},{"enabled":1,"iid":9,"name":"\u9632\u5c18\u7f51","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":10,"name":"\u538b\u8def\u673a","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":11,"name":"\u6405\u62cc\u8f66","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":12,"name":"\u6869\u673a","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":13,"name":"\u56f4\u6321","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":14,"name":"\u6c34\u9a6c","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":15,"name":"\u5b89\u5168\u5e3d","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":16,"name":"\u4e95\u76d6\u7f3a\u5931","prob":1.0099999904632568,"subType":2,"type":3}],"textColor":16776960,"thickness":4}
{"blobName16":"354","blobName32":"366","blobName8":"output","borderColor":16776960,"enabled":0,"items":[{"enabled":1,"iid":0,"name":"\u6316\u6398\u673a","prob":0.5,"subType":5,"type":1},{"enabled":1,"iid":1,"name":"\u540a\u5854","prob":0.5,"subType":2,"type":1},{"enabled":1,"iid":2,"name":"\u540a\u8f66","prob":0.5,"subType":1,"type":1},{"enabled":1,"iid":3,"name":"\u6c34\u6ce5\u6cf5\u8f66","prob":0.5,"subType":4,"type":1},{"enabled":1,"iid":4,"name":"\u5c71\u706b","prob":0.5,"subType":40,"type":4},{"enabled":1,"iid":5,"name":"\u70df\u96fe","prob":0.5,"subType":41,"type":4},{"enabled":1,"iid":6,"name":"\u63a8\u571f\u673a","prob":0.5,"subType":3,"type":1},{"enabled":1,"iid":7,"name":"\u7ffb\u6597\u8f66","prob":0.5,"subType":10,"type":1},{"enabled":1,"iid":8,"name":"\u5bfc\u7ebf\u5f02\u7269","prob":0.5,"subType":1,"type":3},{"enabled":1,"iid":9,"name":"\u9632\u5c18\u7f51","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":10,"name":"\u538b\u8def\u673a","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":11,"name":"\u6405\u62cc\u8f66","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":12,"name":"\u6869\u673a","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":13,"name":"\u56f4\u6321","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":14,"name":"\u6c34\u9a6c","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":15,"name":"\u5b89\u5168\u5e3d","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":16,"name":"\u4e95\u76d6\u7f3a\u5931","prob":1.0099999904632568,"subType":2,"type":3}],"textColor":16776960,"thickness":4,"version":"2024-12-30"}

@ -0,0 +1 @@
{"absHeartbeats":[33420,85808],"heartbeat":10,"mntnMode":0,"mpappMonitorTimeout":1800000,"port":40101,"quickHbMode":0,"quickHeartbeat":60,"separateNetwork":1,"server":"61.169.135.150","timeForKeepingLogs":15,"usingAbsHbTime":1}

@ -0,0 +1 @@
{"bsManufacturer":"\u4e0a\u6d77\u6b23\u5f71\u7535\u529b\u79d1\u6280\u80a1\u4efd\u6709\u9650\u516c\u53f8","channels":3,"encryption":0,"equipName":"\u56fe\u50cf\u5728\u7ebf\u76d1\u6d4b","heartbeat":10,"imgQuality":80,"model":"MSRDT-1-WP","network":0,"networkProtocol":0,"outputDbgInfo":0,"packetBase":1,"packetSize":32768,"port":6891,"postDataPaused":0,"productionDate":1717200000,"protocol":65298,"quality":80,"reportFault":0,"server":"61.169.135.146","timeForKeepingLogs":1296000,"timeForKeepingPhotos":1296000,"upgradePacketBase":1,"workStatusTimes":3}

@ -0,0 +1 @@
{"absHeartbeats":[33420,85808],"heartbeat":10,"mntnMode":0,"mpappMonitorTimeout":1800000,"port":40101,"quickHbMode":0,"quickHeartbeat":60,"separateNetwork":1,"server":"61.169.135.150","timeForKeepingLogs":15,"usingAbsHbTime":1}

@ -0,0 +1,100 @@
[{"v":6015, "c":1},
{"v":6283, "c":2},
{"v":6442, "c":3},
{"v":6553, "c":4},
{"v":6641, "c":5},
{"v":6708, "c":6},
{"v":6735, "c":7},
{"v":6742, "c":8},
{"v":6746, "c":9},
{"v":6751, "c":10},
{"v":6757, "c":11},
{"v":6765, "c":12},
{"v":6774, "c":13},
{"v":6785, "c":14},
{"v":6797, "c":15},
{"v":6811, "c":16},
{"v":6822, "c":17},
{"v":6833, "c":18},
{"v":6844, "c":19},
{"v":6853, "c":20},
{"v":6863, "c":21},
{"v":6871, "c":22},
{"v":6878, "c":23},
{"v":6883, "c":24},
{"v":6891, "c":25},
{"v":6896, "c":26},
{"v":6897, "c":27},
{"v":6901, "c":28},
{"v":6903, "c":29},
{"v":6904, "c":30},
{"v":6906, "c":31},
{"v":6907, "c":32},
{"v":6908, "c":33},
{"v":6910, "c":34},
{"v":6911, "c":35},
{"v":6911, "c":36},
{"v":6913, "c":37},
{"v":6914, "c":38},
{"v":6914, "c":39},
{"v":6915, "c":40},
{"v":6917, "c":41},
{"v":6918, "c":42},
{"v":6918, "c":43},
{"v":6921, "c":44},
{"v":6922, "c":45},
{"v":6924, "c":46},
{"v":6926, "c":47},
{"v":6927, "c":48},
{"v":6929, "c":49},
{"v":6931, "c":50},
{"v":6934, "c":51},
{"v":6938, "c":52},
{"v":6941, "c":53},
{"v":6946, "c":54},
{"v":6948, "c":55},
{"v":6952, "c":56},
{"v":6954, "c":57},
{"v":6957, "c":58},
{"v":6959, "c":59},
{"v":6961, "c":60},
{"v":6963, "c":61},
{"v":6965, "c":62},
{"v":6967, "c":63},
{"v":6971, "c":64},
{"v":6973, "c":65},
{"v":6976, "c":66},
{"v":6978, "c":67},
{"v":6980, "c":68},
{"v":6982, "c":69},
{"v":6984, "c":70},
{"v":6986, "c":71},
{"v":6988, "c":72},
{"v":6989, "c":73},
{"v":6991, "c":74},
{"v":6992, "c":75},
{"v":6993, "c":76},
{"v":6995, "c":77},
{"v":6997, "c":78},
{"v":6998, "c":79},
{"v":7000, "c":80},
{"v":7003, "c":81},
{"v":7004, "c":82},
{"v":7006, "c":83},
{"v":7008, "c":84},
{"v":7011, "c":85},
{"v":7014, "c":86},
{"v":7018, "c":87},
{"v":7021, "c":88},
{"v":7024, "c":89},
{"v":7029, "c":90},
{"v":7033, "c":91},
{"v":7039, "c":92},
{"v":7044, "c":93},
{"v":7052, "c":94},
{"v":7062, "c":95},
{"v":7073, "c":96},
{"v":7087, "c":97},
{"v":7104, "c":98},
{"v":7122, "c":99},
{"v":7142, "c":100}]

@ -0,0 +1 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"cameraType":0,"compensation":0,"customHdr":0,"exposureTime":0,"hdrStep":0,"ldrEnabled":0,"orientation":0,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%%\r\n\u4fe1\u53f7:%%SL%% %%BV%%V"},"quality":80,"recognization":0,"requestTemplate":2,"resolutionCX":5376,"resolutionCY":3024,"sceneMode":0,"sensitivity":0,"usbCamera":0,"usingRawFormat":0,"usingSysCamera":0,"vendor":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0,"zoom":0,"zoomRatio":1}

@ -0,0 +1 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"burstCaptures":4,"cameraType":0,"compensation":0,"customHdr":0,"exposureTime":0,"hdrStep":0,"ldrEnabled":0,"orientation":3,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%%\r\n\u4fe1\u53f7:%%SL%% %%BV%%V"},"quality":80,"recognization":0,"requestTemplate":2,"resolutionCX":1920,"resolutionCY":1080,"sceneMode":0,"sensitivity":0,"usbCamera":0,"usingRawFormat":2,"usingSysCamera":0,"vendor":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0,"zoom":0,"zoomRatio":1}

@ -0,0 +1 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"cameraType":0,"compensation":0,"customHdr":0,"hdrStep":0,"ldrEnabled":0,"orientation":4,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%%\r\n\u4fe1\u53f7:%%SL%% %%BV%%V"},"recognization":0,"requestTemplate":1,"resolutionCX":3264,"resolutionCY":2448,"sceneMode":0,"usbCamera":0,"usingRawFormat":0,"usingSysCamera":0,"vendor":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0}

@ -0,0 +1 @@
{"blobName16":"354","blobName32":"366","blobName8":"output","borderColor":16776960,"enabled":0,"items":[{"enabled":1,"iid":0,"name":"\u6316\u6398\u673a","prob":0.5,"subType":5,"type":1},{"enabled":1,"iid":1,"name":"\u540a\u5854","prob":0.5,"subType":2,"type":1},{"enabled":1,"iid":2,"name":"\u540a\u8f66","prob":0.5,"subType":1,"type":1},{"enabled":1,"iid":3,"name":"\u6c34\u6ce5\u6cf5\u8f66","prob":0.5,"subType":4,"type":1},{"enabled":1,"iid":4,"name":"\u5c71\u706b","prob":0.5,"subType":40,"type":4},{"enabled":1,"iid":5,"name":"\u70df\u96fe","prob":0.5,"subType":41,"type":4},{"enabled":1,"iid":6,"name":"\u63a8\u571f\u673a","prob":0.5,"subType":3,"type":1},{"enabled":1,"iid":7,"name":"\u7ffb\u6597\u8f66","prob":0.5,"subType":10,"type":1},{"enabled":1,"iid":8,"name":"\u5bfc\u7ebf\u5f02\u7269","prob":0.5,"subType":1,"type":3},{"enabled":1,"iid":9,"name":"\u9632\u5c18\u7f51","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":10,"name":"\u538b\u8def\u673a","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":11,"name":"\u6405\u62cc\u8f66","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":12,"name":"\u6869\u673a","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":13,"name":"\u56f4\u6321","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":14,"name":"\u6c34\u9a6c","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":15,"name":"\u5b89\u5168\u5e3d","prob":1.0099999904632568,"subType":2,"type":3},{"enabled":1,"iid":16,"name":"\u4e95\u76d6\u7f3a\u5931","prob":1.0099999904632568,"subType":2,"type":3}],"textColor":16776960,"thickness":4,"version":"2024-12-30"}

@ -0,0 +1 @@
{"absHeartbeats":[33420,85808],"heartbeat":10,"mntnMode":0,"mpappMonitorTimeout":1800000,"port":40101,"quickHbMode":0,"quickHeartbeat":60,"separateNetwork":1,"server":"61.169.135.150","timeForKeepingLogs":15,"usingAbsHbTime":1}

@ -6,6 +6,7 @@ import android.graphics.SurfaceTexture;
import android.hardware.camera2.*;
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;

@ -41,6 +41,7 @@ public class GPUCameraRecorder {
private final int degrees;
private final boolean recordNoFilter;
private final long duration;
private final boolean ismirror;
private long startTime;
@ -59,7 +60,8 @@ public class GPUCameraRecorder {
final boolean isLandscapeDevice,
final int degrees,
final boolean recordNoFilter,
final long duration
final long duration,
final boolean ismirror
) {
@ -81,6 +83,7 @@ public class GPUCameraRecorder {
this.degrees = degrees;
this.recordNoFilter = recordNoFilter;
this.duration = duration;
this.ismirror = ismirror;
// create preview Renderer
if (null == glPreviewRenderer) {
@ -119,7 +122,7 @@ public class GPUCameraRecorder {
public void run() {
if (glPreviewRenderer != null) {
glPreviewRenderer.setAngle(degrees);
glPreviewRenderer.onStartPreview(previewWidth, previewHeight, isLandscapeDevice);
glPreviewRenderer.onStartPreview(previewWidth, previewHeight, isLandscapeDevice,ismirror);
}
}
});

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.opengl.GLSurfaceView;
import android.util.Log;
@ -30,6 +31,10 @@ public class GPUCameraRecorderBuilder {
private int cameraHeight = 720;
private GlFilter glFilter;
private long duration;
private int rotation;
private Integer sensororientation;
private Integer facing;
private boolean ifmirror = false;
public GPUCameraRecorderBuilder(Activity activity, GLSurfaceView glSurfaceView) {
this.activity = activity;
@ -84,6 +89,11 @@ public class GPUCameraRecorderBuilder {
return this;
}
public GPUCameraRecorderBuilder rotation(int d) {
this.rotation = d;
return this;
}
public GPUCameraRecorderBuilder recordNoFilter(boolean recordNoFilter) {
this.recordNoFilter = recordNoFilter;
return this;
@ -97,12 +107,34 @@ public class GPUCameraRecorderBuilder {
CameraManager cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
boolean isLandscapeDevice = resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
CameraCharacteristics cameraCharacteristics = null;
try {
cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
} catch (Exception ex) {
ex.printStackTrace();
}
if (cameraCharacteristics != null) {
facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
sensororientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
}
int degrees = 0;
if (isLandscapeDevice) {
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
Log.d("GPUCameraRecorder", "Surface.ROTATION_90 = " + Surface.ROTATION_90 + " rotation = " + rotation);
degrees = 90 * (rotation - 2);
if (facing == 1) {
if (rotation == -1) {
degrees = sensororientation;
} else {
degrees = sensororientation + (rotation - 1) * 90;
}
ifmirror = false;
} else {
if (rotation == -1) {
degrees = sensororientation + 180;
} else {
degrees = sensororientation + (rotation - 1) * 90 + 180;
}
ifmirror = true;
}
Log.d("GPUCameraRecorder", "测试测试" + degrees);
GPUCameraRecorder GPUCameraRecorder = new GPUCameraRecorder(
cameraRecordListener,
@ -119,7 +151,8 @@ public class GPUCameraRecorderBuilder {
isLandscapeDevice,
degrees,
recordNoFilter,
duration
duration,
ifmirror
);
GPUCameraRecorder.setFilter(glFilter);

@ -66,11 +66,14 @@ public class GlPreviewRenderer extends GlFrameBufferObjectRenderer implements Su
Matrix.setIdentityM(STMatrix, 0);
}
public void onStartPreview(float cameraPreviewWidth, float cameraPreviewHeight, boolean isLandscapeDevice) {
public void onStartPreview(float cameraPreviewWidth, float cameraPreviewHeight, boolean isLandscapeDevice, boolean ismirror) {
Matrix.setIdentityM(MMatrix, 0);
Matrix.rotateM(MMatrix, 0, -angle, 0.0f, 0.0f, 1.0f);
Matrix.rotateM(MMatrix, 0, angle, 0.0f, 0.0f, 1.0f);
if (ismirror) {
Matrix.scaleM(MMatrix, 0, 1, -1, 1);
}
// Log.d("GPUCameraRecorder ", "angle" + angle);
// Log.d("GPUCameraRecorder ", "getMeasuredHeight " + glView.getMeasuredHeight());
// Log.d("GPUCameraRecorder ", "getMeasuredWidth " + glView.getMeasuredWidth());
@ -279,7 +282,7 @@ public class GlPreviewRenderer extends GlFrameBufferObjectRenderer implements Su
public void setAngle(int angle) {
this.angle = angle;
if (angle == 90 || angle == 270) {
if (angle == 180 || angle == 0) {
aspectRatio = (float) cameraResolution.getWidth() / cameraResolution.getHeight();
} else {
aspectRatio = (float) cameraResolution.getHeight() / cameraResolution.getWidth();

@ -4,7 +4,7 @@ plugins {
def AppMajorVersion = 1
def AppMinorVersion = 1
def AppBuildNumber = 18
def AppBuildNumber = 36
def AppVersionName = AppMajorVersion + "." + AppMinorVersion + "." + AppBuildNumber
def AppVersionCode = AppMajorVersion * 100000 + AppMinorVersion * 1000 + AppBuildNumber
@ -15,6 +15,7 @@ android {
defaultConfig {
applicationId "com.xypower.mpmaster"
minSdk 28
//noinspection ExpiredTargetSdkVersion
targetSdk 28
versionCode AppVersionCode
versionName AppVersionName
@ -96,15 +97,17 @@ android {
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.core:core:1.6.0'
implementation 'androidx.activity:activity:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.annotation:annotation:+'
implementation 'com.linkedin.dexmaker:dexmaker:2.28.3'
// implementation 'androidx.annotation:annotation:+'
implementation 'androidx.annotation:annotation:1.2.0'
// implementation 'com.linkedin.dexmaker:dexmaker:2.28.3'
implementation project(path: ':common')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.orhanobut:logger:2.2.0'
// implementation 'com.orhanobut:logger:2.2.0'
implementation files('libs/devapi.aar')
}

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xypower.mpmaster">
android:sharedUserId="com.xypower.mp"
package="com.xypower.mpmaster"
tools:ignore="Deprecated">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
@ -13,9 +15,13 @@
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.FORCE_STOP_PACKAGES"
tools:ignore="ProtectedPermissions" />
@ -111,7 +117,6 @@
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

@ -1 +0,0 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"compensation":0,"exposureTime":0,"ldrEnabled":0,"orientation":0,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%% \u7248\u672c:%%V%%\r\n\u4fe1\u53f7:%%SL%% \u7535\u6c60\u7535\u538b:%%BV%% \u7535\u6c60\u7535\u91cf:%%BP%% \u5145\u7535\u7535\u538b:%%CV%%"},"quality":80,"recognization":2,"requestTemplate":2,"resolutionCX":5376,"resolutionCY":3024,"sceneMode":0,"sensitivity":0,"usbCamera":0,"usingRawFormat":0,"usingSysCamera":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0,"zoom":0,"zoomRatio":1}

@ -1 +0,0 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"burstCaptures":4,"compensation":0,"exposureTime":0,"ldrEnabled":0,"orientation":3,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%% \u7248\u672c:%%V%%\r\n\u4fe1\u53f7:%%SL%% \u7535\u6c60\u7535\u538b:%%BV%% \u7535\u6c60\u7535\u91cf:%%BP%% \u5145\u7535\u7535\u538b:%%CV%%"},"quality":80,"recognization":2,"requestTemplate":2,"resolutionCX":1920,"resolutionCY":1080,"sceneMode":0,"sensitivity":0,"usbCamera":0,"usingRawFormat":2,"usingSysCamera":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0,"zoom":0,"zoomRatio":1}

@ -1 +0,0 @@
{"autoExposure":1,"autoFocus":1,"awbMode":1,"compensation":0,"ldrEnabled":0,"orientation":4,"osd":{"leftTop":"%%DATETIME%% CH:%%CH%% \u7248\u672c:%%V%%\r\n\u4fe1\u53f7:%%SL%% \u7535\u6c60\u7535\u538b:%%BV%% \u7535\u6c60\u7535\u91cf:%%BP%% \u5145\u7535\u7535\u538b:%%CV%%"},"recognization":2,"requestTemplate":1,"resolutionCX":3264,"resolutionCY":2448,"sceneMode":0,"usbCamera":0,"usingRawFormat":0,"usingSysCamera":0,"videoCX":1280,"videoCY":720,"videoDuration":5,"wait3ALocked":0}

@ -1,175 +0,0 @@
7767517
173 197
Input images 0 1 images
Convolution /model.0/conv/Conv 1 1 images /model.0/conv/Conv_output_0 0=32 1=6 11=6 2=1 12=1 3=2 13=2 4=2 14=2 15=2 16=2 5=1 6=3456
Swish /model.0/act/Mul 1 1 /model.0/conv/Conv_output_0 /model.0/act/Mul_output_0
Convolution /model.1/conv/Conv 1 1 /model.0/act/Mul_output_0 /model.1/conv/Conv_output_0 0=64 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=18432
Swish /model.1/act/Mul 1 1 /model.1/conv/Conv_output_0 /model.1/act/Mul_output_0
Split splitncnn_0 1 2 /model.1/act/Mul_output_0 /model.1/act/Mul_output_0_splitncnn_0 /model.1/act/Mul_output_0_splitncnn_1
Convolution /model.2/cv1/conv/Conv 1 1 /model.1/act/Mul_output_0_splitncnn_1 /model.2/cv1/conv/Conv_output_0 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=2048
Swish /model.2/cv1/act/Mul 1 1 /model.2/cv1/conv/Conv_output_0 /model.2/cv1/act/Mul_output_0
Split splitncnn_1 1 2 /model.2/cv1/act/Mul_output_0 /model.2/cv1/act/Mul_output_0_splitncnn_0 /model.2/cv1/act/Mul_output_0_splitncnn_1
Convolution /model.2/m/m.0/cv1/conv/Conv 1 1 /model.2/cv1/act/Mul_output_0_splitncnn_1 /model.2/m/m.0/cv1/conv/Conv_output_0 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=1024
Swish /model.2/m/m.0/cv1/act/Mul 1 1 /model.2/m/m.0/cv1/conv/Conv_output_0 /model.2/m/m.0/cv1/act/Mul_output_0
Convolution /model.2/m/m.0/cv2/conv/Conv 1 1 /model.2/m/m.0/cv1/act/Mul_output_0 /model.2/m/m.0/cv2/conv/Conv_output_0 0=32 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=9216
Swish /model.2/m/m.0/cv2/act/Mul 1 1 /model.2/m/m.0/cv2/conv/Conv_output_0 /model.2/m/m.0/cv2/act/Mul_output_0
BinaryOp /model.2/m/m.0/Add 2 1 /model.2/cv1/act/Mul_output_0_splitncnn_0 /model.2/m/m.0/cv2/act/Mul_output_0 /model.2/m/m.0/Add_output_0 0=0
Convolution /model.2/cv2/conv/Conv 1 1 /model.1/act/Mul_output_0_splitncnn_0 /model.2/cv2/conv/Conv_output_0 0=32 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=2048
Swish /model.2/cv2/act/Mul 1 1 /model.2/cv2/conv/Conv_output_0 /model.2/cv2/act/Mul_output_0
Concat /model.2/Concat 2 1 /model.2/m/m.0/Add_output_0 /model.2/cv2/act/Mul_output_0 /model.2/Concat_output_0 0=0
Convolution /model.2/cv3/conv/Conv 1 1 /model.2/Concat_output_0 /model.2/cv3/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096
Swish /model.2/cv3/act/Mul 1 1 /model.2/cv3/conv/Conv_output_0 /model.2/cv3/act/Mul_output_0
Convolution /model.3/conv/Conv 1 1 /model.2/cv3/act/Mul_output_0 /model.3/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=73728
Swish /model.3/act/Mul 1 1 /model.3/conv/Conv_output_0 /model.3/act/Mul_output_0
Split splitncnn_2 1 2 /model.3/act/Mul_output_0 /model.3/act/Mul_output_0_splitncnn_0 /model.3/act/Mul_output_0_splitncnn_1
Convolution /model.4/cv1/conv/Conv 1 1 /model.3/act/Mul_output_0_splitncnn_1 /model.4/cv1/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=8192
Swish /model.4/cv1/act/Mul 1 1 /model.4/cv1/conv/Conv_output_0 /model.4/cv1/act/Mul_output_0
Split splitncnn_3 1 2 /model.4/cv1/act/Mul_output_0 /model.4/cv1/act/Mul_output_0_splitncnn_0 /model.4/cv1/act/Mul_output_0_splitncnn_1
Convolution /model.4/m/m.0/cv1/conv/Conv 1 1 /model.4/cv1/act/Mul_output_0_splitncnn_1 /model.4/m/m.0/cv1/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096
Swish /model.4/m/m.0/cv1/act/Mul 1 1 /model.4/m/m.0/cv1/conv/Conv_output_0 /model.4/m/m.0/cv1/act/Mul_output_0
Convolution /model.4/m/m.0/cv2/conv/Conv 1 1 /model.4/m/m.0/cv1/act/Mul_output_0 /model.4/m/m.0/cv2/conv/Conv_output_0 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864
Swish /model.4/m/m.0/cv2/act/Mul 1 1 /model.4/m/m.0/cv2/conv/Conv_output_0 /model.4/m/m.0/cv2/act/Mul_output_0
BinaryOp /model.4/m/m.0/Add 2 1 /model.4/cv1/act/Mul_output_0_splitncnn_0 /model.4/m/m.0/cv2/act/Mul_output_0 /model.4/m/m.0/Add_output_0 0=0
Split splitncnn_4 1 2 /model.4/m/m.0/Add_output_0 /model.4/m/m.0/Add_output_0_splitncnn_0 /model.4/m/m.0/Add_output_0_splitncnn_1
Convolution /model.4/m/m.1/cv1/conv/Conv 1 1 /model.4/m/m.0/Add_output_0_splitncnn_1 /model.4/m/m.1/cv1/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096
Swish /model.4/m/m.1/cv1/act/Mul 1 1 /model.4/m/m.1/cv1/conv/Conv_output_0 /model.4/m/m.1/cv1/act/Mul_output_0
Convolution /model.4/m/m.1/cv2/conv/Conv 1 1 /model.4/m/m.1/cv1/act/Mul_output_0 /model.4/m/m.1/cv2/conv/Conv_output_0 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864
Swish /model.4/m/m.1/cv2/act/Mul 1 1 /model.4/m/m.1/cv2/conv/Conv_output_0 /model.4/m/m.1/cv2/act/Mul_output_0
BinaryOp /model.4/m/m.1/Add 2 1 /model.4/m/m.0/Add_output_0_splitncnn_0 /model.4/m/m.1/cv2/act/Mul_output_0 /model.4/m/m.1/Add_output_0 0=0
Convolution /model.4/cv2/conv/Conv 1 1 /model.3/act/Mul_output_0_splitncnn_0 /model.4/cv2/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=8192
Swish /model.4/cv2/act/Mul 1 1 /model.4/cv2/conv/Conv_output_0 /model.4/cv2/act/Mul_output_0
Concat /model.4/Concat 2 1 /model.4/m/m.1/Add_output_0 /model.4/cv2/act/Mul_output_0 /model.4/Concat_output_0 0=0
Convolution /model.4/cv3/conv/Conv 1 1 /model.4/Concat_output_0 /model.4/cv3/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.4/cv3/act/Mul 1 1 /model.4/cv3/conv/Conv_output_0 /model.4/cv3/act/Mul_output_0
Split splitncnn_5 1 2 /model.4/cv3/act/Mul_output_0 /model.4/cv3/act/Mul_output_0_splitncnn_0 /model.4/cv3/act/Mul_output_0_splitncnn_1
Convolution /model.5/conv/Conv 1 1 /model.4/cv3/act/Mul_output_0_splitncnn_1 /model.5/conv/Conv_output_0 0=256 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=294912
Swish /model.5/act/Mul 1 1 /model.5/conv/Conv_output_0 /model.5/act/Mul_output_0
Split splitncnn_6 1 2 /model.5/act/Mul_output_0 /model.5/act/Mul_output_0_splitncnn_0 /model.5/act/Mul_output_0_splitncnn_1
Convolution /model.6/cv1/conv/Conv 1 1 /model.5/act/Mul_output_0_splitncnn_1 /model.6/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=32768
Swish /model.6/cv1/act/Mul 1 1 /model.6/cv1/conv/Conv_output_0 /model.6/cv1/act/Mul_output_0
Split splitncnn_7 1 2 /model.6/cv1/act/Mul_output_0 /model.6/cv1/act/Mul_output_0_splitncnn_0 /model.6/cv1/act/Mul_output_0_splitncnn_1
Convolution /model.6/m/m.0/cv1/conv/Conv 1 1 /model.6/cv1/act/Mul_output_0_splitncnn_1 /model.6/m/m.0/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.6/m/m.0/cv1/act/Mul 1 1 /model.6/m/m.0/cv1/conv/Conv_output_0 /model.6/m/m.0/cv1/act/Mul_output_0
Convolution /model.6/m/m.0/cv2/conv/Conv 1 1 /model.6/m/m.0/cv1/act/Mul_output_0 /model.6/m/m.0/cv2/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456
Swish /model.6/m/m.0/cv2/act/Mul 1 1 /model.6/m/m.0/cv2/conv/Conv_output_0 /model.6/m/m.0/cv2/act/Mul_output_0
BinaryOp /model.6/m/m.0/Add 2 1 /model.6/cv1/act/Mul_output_0_splitncnn_0 /model.6/m/m.0/cv2/act/Mul_output_0 /model.6/m/m.0/Add_output_0 0=0
Split splitncnn_8 1 2 /model.6/m/m.0/Add_output_0 /model.6/m/m.0/Add_output_0_splitncnn_0 /model.6/m/m.0/Add_output_0_splitncnn_1
Convolution /model.6/m/m.1/cv1/conv/Conv 1 1 /model.6/m/m.0/Add_output_0_splitncnn_1 /model.6/m/m.1/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.6/m/m.1/cv1/act/Mul 1 1 /model.6/m/m.1/cv1/conv/Conv_output_0 /model.6/m/m.1/cv1/act/Mul_output_0
Convolution /model.6/m/m.1/cv2/conv/Conv 1 1 /model.6/m/m.1/cv1/act/Mul_output_0 /model.6/m/m.1/cv2/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456
Swish /model.6/m/m.1/cv2/act/Mul 1 1 /model.6/m/m.1/cv2/conv/Conv_output_0 /model.6/m/m.1/cv2/act/Mul_output_0
BinaryOp /model.6/m/m.1/Add 2 1 /model.6/m/m.0/Add_output_0_splitncnn_0 /model.6/m/m.1/cv2/act/Mul_output_0 /model.6/m/m.1/Add_output_0 0=0
Split splitncnn_9 1 2 /model.6/m/m.1/Add_output_0 /model.6/m/m.1/Add_output_0_splitncnn_0 /model.6/m/m.1/Add_output_0_splitncnn_1
Convolution /model.6/m/m.2/cv1/conv/Conv 1 1 /model.6/m/m.1/Add_output_0_splitncnn_1 /model.6/m/m.2/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.6/m/m.2/cv1/act/Mul 1 1 /model.6/m/m.2/cv1/conv/Conv_output_0 /model.6/m/m.2/cv1/act/Mul_output_0
Convolution /model.6/m/m.2/cv2/conv/Conv 1 1 /model.6/m/m.2/cv1/act/Mul_output_0 /model.6/m/m.2/cv2/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456
Swish /model.6/m/m.2/cv2/act/Mul 1 1 /model.6/m/m.2/cv2/conv/Conv_output_0 /model.6/m/m.2/cv2/act/Mul_output_0
BinaryOp /model.6/m/m.2/Add 2 1 /model.6/m/m.1/Add_output_0_splitncnn_0 /model.6/m/m.2/cv2/act/Mul_output_0 /model.6/m/m.2/Add_output_0 0=0
Convolution /model.6/cv2/conv/Conv 1 1 /model.5/act/Mul_output_0_splitncnn_0 /model.6/cv2/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=32768
Swish /model.6/cv2/act/Mul 1 1 /model.6/cv2/conv/Conv_output_0 /model.6/cv2/act/Mul_output_0
Concat /model.6/Concat 2 1 /model.6/m/m.2/Add_output_0 /model.6/cv2/act/Mul_output_0 /model.6/Concat_output_0 0=0
Convolution /model.6/cv3/conv/Conv 1 1 /model.6/Concat_output_0 /model.6/cv3/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.6/cv3/act/Mul 1 1 /model.6/cv3/conv/Conv_output_0 /model.6/cv3/act/Mul_output_0
Split splitncnn_10 1 2 /model.6/cv3/act/Mul_output_0 /model.6/cv3/act/Mul_output_0_splitncnn_0 /model.6/cv3/act/Mul_output_0_splitncnn_1
Convolution /model.7/conv/Conv 1 1 /model.6/cv3/act/Mul_output_0_splitncnn_1 /model.7/conv/Conv_output_0 0=512 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=1179648
Swish /model.7/act/Mul 1 1 /model.7/conv/Conv_output_0 /model.7/act/Mul_output_0
Split splitncnn_11 1 2 /model.7/act/Mul_output_0 /model.7/act/Mul_output_0_splitncnn_0 /model.7/act/Mul_output_0_splitncnn_1
Convolution /model.8/cv1/conv/Conv 1 1 /model.7/act/Mul_output_0_splitncnn_1 /model.8/cv1/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=131072
Swish /model.8/cv1/act/Mul 1 1 /model.8/cv1/conv/Conv_output_0 /model.8/cv1/act/Mul_output_0
Split splitncnn_12 1 2 /model.8/cv1/act/Mul_output_0 /model.8/cv1/act/Mul_output_0_splitncnn_0 /model.8/cv1/act/Mul_output_0_splitncnn_1
Convolution /model.8/m/m.0/cv1/conv/Conv 1 1 /model.8/cv1/act/Mul_output_0_splitncnn_1 /model.8/m/m.0/cv1/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.8/m/m.0/cv1/act/Mul 1 1 /model.8/m/m.0/cv1/conv/Conv_output_0 /model.8/m/m.0/cv1/act/Mul_output_0
Convolution /model.8/m/m.0/cv2/conv/Conv 1 1 /model.8/m/m.0/cv1/act/Mul_output_0 /model.8/m/m.0/cv2/conv/Conv_output_0 0=256 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=589824
Swish /model.8/m/m.0/cv2/act/Mul 1 1 /model.8/m/m.0/cv2/conv/Conv_output_0 /model.8/m/m.0/cv2/act/Mul_output_0
BinaryOp /model.8/m/m.0/Add 2 1 /model.8/cv1/act/Mul_output_0_splitncnn_0 /model.8/m/m.0/cv2/act/Mul_output_0 /model.8/m/m.0/Add_output_0 0=0
Convolution /model.8/cv2/conv/Conv 1 1 /model.7/act/Mul_output_0_splitncnn_0 /model.8/cv2/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=131072
Swish /model.8/cv2/act/Mul 1 1 /model.8/cv2/conv/Conv_output_0 /model.8/cv2/act/Mul_output_0
Concat /model.8/Concat 2 1 /model.8/m/m.0/Add_output_0 /model.8/cv2/act/Mul_output_0 /model.8/Concat_output_0 0=0
Convolution /model.8/cv3/conv/Conv 1 1 /model.8/Concat_output_0 /model.8/cv3/conv/Conv_output_0 0=512 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=262144
Swish /model.8/cv3/act/Mul 1 1 /model.8/cv3/conv/Conv_output_0 /model.8/cv3/act/Mul_output_0
Convolution /model.9/cv1/conv/Conv 1 1 /model.8/cv3/act/Mul_output_0 /model.9/cv1/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=131072
Swish /model.9/cv1/act/Mul 1 1 /model.9/cv1/conv/Conv_output_0 /model.9/cv1/act/Mul_output_0
Split splitncnn_13 1 2 /model.9/cv1/act/Mul_output_0 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/cv1/act/Mul_output_0_splitncnn_1
Pooling /model.9/m/MaxPool 1 1 /model.9/cv1/act/Mul_output_0_splitncnn_1 /model.9/m/MaxPool_output_0 0=0 1=5 11=5 2=1 12=1 3=2 13=2 14=2 15=2 5=1
Split splitncnn_14 1 2 /model.9/m/MaxPool_output_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_1
Pooling /model.9/m_1/MaxPool 1 1 /model.9/m/MaxPool_output_0_splitncnn_1 /model.9/m_1/MaxPool_output_0 0=0 1=5 11=5 2=1 12=1 3=2 13=2 14=2 15=2 5=1
Split splitncnn_15 1 2 /model.9/m_1/MaxPool_output_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_1
Pooling /model.9/m_2/MaxPool 1 1 /model.9/m_1/MaxPool_output_0_splitncnn_1 /model.9/m_2/MaxPool_output_0 0=0 1=5 11=5 2=1 12=1 3=2 13=2 14=2 15=2 5=1
Concat /model.9/Concat 4 1 /model.9/cv1/act/Mul_output_0_splitncnn_0 /model.9/m/MaxPool_output_0_splitncnn_0 /model.9/m_1/MaxPool_output_0_splitncnn_0 /model.9/m_2/MaxPool_output_0 /model.9/Concat_output_0 0=0
Convolution /model.9/cv2/conv/Conv 1 1 /model.9/Concat_output_0 /model.9/cv2/conv/Conv_output_0 0=512 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=524288
Swish /model.9/cv2/act/Mul 1 1 /model.9/cv2/conv/Conv_output_0 /model.9/cv2/act/Mul_output_0
Convolution /model.10/conv/Conv 1 1 /model.9/cv2/act/Mul_output_0 /model.10/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=131072
Swish /model.10/act/Mul 1 1 /model.10/conv/Conv_output_0 /model.10/act/Mul_output_0
Split splitncnn_16 1 2 /model.10/act/Mul_output_0 /model.10/act/Mul_output_0_splitncnn_0 /model.10/act/Mul_output_0_splitncnn_1
Interp /model.11/Resize 1 1 /model.10/act/Mul_output_0_splitncnn_1 /model.11/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 3=0 4=0 6=0
Concat /model.12/Concat 2 1 /model.11/Resize_output_0 /model.6/cv3/act/Mul_output_0_splitncnn_0 /model.12/Concat_output_0 0=0
Split splitncnn_17 1 2 /model.12/Concat_output_0 /model.12/Concat_output_0_splitncnn_0 /model.12/Concat_output_0_splitncnn_1
Convolution /model.13/cv1/conv/Conv 1 1 /model.12/Concat_output_0_splitncnn_1 /model.13/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.13/cv1/act/Mul 1 1 /model.13/cv1/conv/Conv_output_0 /model.13/cv1/act/Mul_output_0
Convolution /model.13/m/m.0/cv1/conv/Conv 1 1 /model.13/cv1/act/Mul_output_0 /model.13/m/m.0/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.13/m/m.0/cv1/act/Mul 1 1 /model.13/m/m.0/cv1/conv/Conv_output_0 /model.13/m/m.0/cv1/act/Mul_output_0
Convolution /model.13/m/m.0/cv2/conv/Conv 1 1 /model.13/m/m.0/cv1/act/Mul_output_0 /model.13/m/m.0/cv2/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456
Swish /model.13/m/m.0/cv2/act/Mul 1 1 /model.13/m/m.0/cv2/conv/Conv_output_0 /model.13/m/m.0/cv2/act/Mul_output_0
Convolution /model.13/cv2/conv/Conv 1 1 /model.12/Concat_output_0_splitncnn_0 /model.13/cv2/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.13/cv2/act/Mul 1 1 /model.13/cv2/conv/Conv_output_0 /model.13/cv2/act/Mul_output_0
Concat /model.13/Concat 2 1 /model.13/m/m.0/cv2/act/Mul_output_0 /model.13/cv2/act/Mul_output_0 /model.13/Concat_output_0 0=0
Convolution /model.13/cv3/conv/Conv 1 1 /model.13/Concat_output_0 /model.13/cv3/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.13/cv3/act/Mul 1 1 /model.13/cv3/conv/Conv_output_0 /model.13/cv3/act/Mul_output_0
Convolution /model.14/conv/Conv 1 1 /model.13/cv3/act/Mul_output_0 /model.14/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=32768
Swish /model.14/act/Mul 1 1 /model.14/conv/Conv_output_0 /model.14/act/Mul_output_0
Split splitncnn_18 1 2 /model.14/act/Mul_output_0 /model.14/act/Mul_output_0_splitncnn_0 /model.14/act/Mul_output_0_splitncnn_1
Interp /model.15/Resize 1 1 /model.14/act/Mul_output_0_splitncnn_1 /model.15/Resize_output_0 0=1 1=2.000000e+00 2=2.000000e+00 3=0 4=0 6=0
Concat /model.16/Concat 2 1 /model.15/Resize_output_0 /model.4/cv3/act/Mul_output_0_splitncnn_0 /model.16/Concat_output_0 0=0
Split splitncnn_19 1 2 /model.16/Concat_output_0 /model.16/Concat_output_0_splitncnn_0 /model.16/Concat_output_0_splitncnn_1
Convolution /model.17/cv1/conv/Conv 1 1 /model.16/Concat_output_0_splitncnn_1 /model.17/cv1/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.17/cv1/act/Mul 1 1 /model.17/cv1/conv/Conv_output_0 /model.17/cv1/act/Mul_output_0
Convolution /model.17/m/m.0/cv1/conv/Conv 1 1 /model.17/cv1/act/Mul_output_0 /model.17/m/m.0/cv1/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=4096
Swish /model.17/m/m.0/cv1/act/Mul 1 1 /model.17/m/m.0/cv1/conv/Conv_output_0 /model.17/m/m.0/cv1/act/Mul_output_0
Convolution /model.17/m/m.0/cv2/conv/Conv 1 1 /model.17/m/m.0/cv1/act/Mul_output_0 /model.17/m/m.0/cv2/conv/Conv_output_0 0=64 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=36864
Swish /model.17/m/m.0/cv2/act/Mul 1 1 /model.17/m/m.0/cv2/conv/Conv_output_0 /model.17/m/m.0/cv2/act/Mul_output_0
Convolution /model.17/cv2/conv/Conv 1 1 /model.16/Concat_output_0_splitncnn_0 /model.17/cv2/conv/Conv_output_0 0=64 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.17/cv2/act/Mul 1 1 /model.17/cv2/conv/Conv_output_0 /model.17/cv2/act/Mul_output_0
Concat /model.17/Concat 2 1 /model.17/m/m.0/cv2/act/Mul_output_0 /model.17/cv2/act/Mul_output_0 /model.17/Concat_output_0 0=0
Convolution /model.17/cv3/conv/Conv 1 1 /model.17/Concat_output_0 /model.17/cv3/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.17/cv3/act/Mul 1 1 /model.17/cv3/conv/Conv_output_0 /model.17/cv3/act/Mul_output_0
Split splitncnn_20 1 2 /model.17/cv3/act/Mul_output_0 /model.17/cv3/act/Mul_output_0_splitncnn_0 /model.17/cv3/act/Mul_output_0_splitncnn_1
Convolution /model.18/conv/Conv 1 1 /model.17/cv3/act/Mul_output_0_splitncnn_1 /model.18/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=147456
Swish /model.18/act/Mul 1 1 /model.18/conv/Conv_output_0 /model.18/act/Mul_output_0
Concat /model.19/Concat 2 1 /model.18/act/Mul_output_0 /model.14/act/Mul_output_0_splitncnn_0 /model.19/Concat_output_0 0=0
Split splitncnn_21 1 2 /model.19/Concat_output_0 /model.19/Concat_output_0_splitncnn_0 /model.19/Concat_output_0_splitncnn_1
Convolution /model.20/cv1/conv/Conv 1 1 /model.19/Concat_output_0_splitncnn_1 /model.20/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=32768
Swish /model.20/cv1/act/Mul 1 1 /model.20/cv1/conv/Conv_output_0 /model.20/cv1/act/Mul_output_0
Convolution /model.20/m/m.0/cv1/conv/Conv 1 1 /model.20/cv1/act/Mul_output_0 /model.20/m/m.0/cv1/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
Swish /model.20/m/m.0/cv1/act/Mul 1 1 /model.20/m/m.0/cv1/conv/Conv_output_0 /model.20/m/m.0/cv1/act/Mul_output_0
Convolution /model.20/m/m.0/cv2/conv/Conv 1 1 /model.20/m/m.0/cv1/act/Mul_output_0 /model.20/m/m.0/cv2/conv/Conv_output_0 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=147456
Swish /model.20/m/m.0/cv2/act/Mul 1 1 /model.20/m/m.0/cv2/conv/Conv_output_0 /model.20/m/m.0/cv2/act/Mul_output_0
Convolution /model.20/cv2/conv/Conv 1 1 /model.19/Concat_output_0_splitncnn_0 /model.20/cv2/conv/Conv_output_0 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=32768
Swish /model.20/cv2/act/Mul 1 1 /model.20/cv2/conv/Conv_output_0 /model.20/cv2/act/Mul_output_0
Concat /model.20/Concat 2 1 /model.20/m/m.0/cv2/act/Mul_output_0 /model.20/cv2/act/Mul_output_0 /model.20/Concat_output_0 0=0
Convolution /model.20/cv3/conv/Conv 1 1 /model.20/Concat_output_0 /model.20/cv3/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.20/cv3/act/Mul 1 1 /model.20/cv3/conv/Conv_output_0 /model.20/cv3/act/Mul_output_0
Split splitncnn_22 1 2 /model.20/cv3/act/Mul_output_0 /model.20/cv3/act/Mul_output_0_splitncnn_0 /model.20/cv3/act/Mul_output_0_splitncnn_1
Convolution /model.21/conv/Conv 1 1 /model.20/cv3/act/Mul_output_0_splitncnn_1 /model.21/conv/Conv_output_0 0=256 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=589824
Swish /model.21/act/Mul 1 1 /model.21/conv/Conv_output_0 /model.21/act/Mul_output_0
Concat /model.22/Concat 2 1 /model.21/act/Mul_output_0 /model.10/act/Mul_output_0_splitncnn_0 /model.22/Concat_output_0 0=0
Split splitncnn_23 1 2 /model.22/Concat_output_0 /model.22/Concat_output_0_splitncnn_0 /model.22/Concat_output_0_splitncnn_1
Convolution /model.23/cv1/conv/Conv 1 1 /model.22/Concat_output_0_splitncnn_1 /model.23/cv1/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=131072
Swish /model.23/cv1/act/Mul 1 1 /model.23/cv1/conv/Conv_output_0 /model.23/cv1/act/Mul_output_0
Convolution /model.23/m/m.0/cv1/conv/Conv 1 1 /model.23/cv1/act/Mul_output_0 /model.23/m/m.0/cv1/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=65536
Swish /model.23/m/m.0/cv1/act/Mul 1 1 /model.23/m/m.0/cv1/conv/Conv_output_0 /model.23/m/m.0/cv1/act/Mul_output_0
Convolution /model.23/m/m.0/cv2/conv/Conv 1 1 /model.23/m/m.0/cv1/act/Mul_output_0 /model.23/m/m.0/cv2/conv/Conv_output_0 0=256 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=589824
Swish /model.23/m/m.0/cv2/act/Mul 1 1 /model.23/m/m.0/cv2/conv/Conv_output_0 /model.23/m/m.0/cv2/act/Mul_output_0
Convolution /model.23/cv2/conv/Conv 1 1 /model.22/Concat_output_0_splitncnn_0 /model.23/cv2/conv/Conv_output_0 0=256 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=131072
Swish /model.23/cv2/act/Mul 1 1 /model.23/cv2/conv/Conv_output_0 /model.23/cv2/act/Mul_output_0
Concat /model.23/Concat 2 1 /model.23/m/m.0/cv2/act/Mul_output_0 /model.23/cv2/act/Mul_output_0 /model.23/Concat_output_0 0=0
Convolution /model.23/cv3/conv/Conv 1 1 /model.23/Concat_output_0 /model.23/cv3/conv/Conv_output_0 0=512 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=262144
Swish /model.23/cv3/act/Mul 1 1 /model.23/cv3/conv/Conv_output_0 /model.23/cv3/act/Mul_output_0
Convolution /model.24/m.0/Conv 1 1 /model.17/cv3/act/Mul_output_0_splitncnn_0 /model.24/m.0/Conv_output_0 0=66 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=8448
Reshape /model.24/Reshape 1 1 /model.24/m.0/Conv_output_0 /model.24/Reshape_output_0 0=-1 1=22 2=3
Permute /model.24/Transpose 1 1 /model.24/Reshape_output_0 output 0=1
Convolution /model.24/m.1/Conv 1 1 /model.20/cv3/act/Mul_output_0_splitncnn_0 /model.24/m.1/Conv_output_0 0=66 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16896
Reshape /model.24/Reshape_1 1 1 /model.24/m.1/Conv_output_0 /model.24/Reshape_1_output_0 0=-1 1=22 2=3
Permute /model.24/Transpose_1 1 1 /model.24/Reshape_1_output_0 354 0=1
Convolution /model.24/m.2/Conv 1 1 /model.23/cv3/act/Mul_output_0 /model.24/m.2/Conv_output_0 0=66 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=33792
Reshape /model.24/Reshape_2 1 1 /model.24/m.2/Conv_output_0 /model.24/Reshape_2_output_0 0=-1 1=22 2=3
Permute /model.24/Transpose_2 1 1 /model.24/Reshape_2_output_0 366 0=1

@ -1 +1 @@
{"absHeartbeats":[33420,85808],"heartbeat":10,"mntnMode":1,"mpappMonitorTimeout":1800000,"port":40101,"quickHbMode":0,"quickHeartbeat":60,"separateNetwork":1,"server":"61.169.135.150","timeForKeepingLogs":15,"usingAbsHbTime":1}
{"absHeartbeats":[33449,85836],"heartbeat":10,"mntnMode":0,"mpappMonitorTimeout":1800000,"port":40101,"quickHbMode":0,"quickHeartbeat":60,"separateNetwork":1,"server":"61.169.135.150","syncTime":0,"timeForKeepingLogs":15,"usingAbsHbTime":1}

@ -1,52 +1,39 @@
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.18.1)
# Declares and names the project.
add_definitions(-DTERMINAL_CLIENT)
add_definitions(-DTERMINAL_CLIENT_MNTN)
project("mpmaster")
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
include_directories(${TERM_CORE_ROOT})
add_library( # Sets the name of the library.
mpmaster
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
mpmaster.cpp )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
mpmaster
# Links the target library to the log library
# included in the NDK.
${log-lib} )
#
add_definitions(-DTERMINAL_CLIENT -DTERMINAL_CLIENT_MNTN)
#
include_directories(
${TERM_CORE_ROOT}
${CMAKE_CURRENT_SOURCE_DIR}/bzip2
${CMAKE_CURRENT_SOURCE_DIR}/bspatch
)
# bzip2
add_library(bz2 STATIC
bzip2/blocksort.c
bzip2/huffman.c
bzip2/crctable.c
bzip2/randtable.c
bzip2/compress.c
bzip2/decompress.c
bzip2/bzlib.c
)
# bspatchbzip2
add_definitions(-DBSPATCH_EXECUTABLE)
add_definitions(-DBSDIFF_EXECUTABLE)
add_library(bspatch STATIC bspatch/bspatch.c)
add_library(bsdiff STATIC bspatch/bsdiff.c)
target_link_libraries(bspatch bsdiff bz2 log) #
# JNIbspatchbzip2
add_library(mpmaster SHARED mpmaster.cpp)
target_link_libraries(mpmaster
bspatch # bspatch
bsdiff
bz2 # bzip2
${log-lib}
)

@ -0,0 +1,443 @@
/*-
* Copyright 2003-2005 Colin Percival
* Copyright 2012 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "bsdiff.h"
#include <limits.h>
#include <string.h>
#define MIN(x,y) (((x)<(y)) ? (x) : (y))
static void split(int64_t *I,int64_t *V,int64_t start,int64_t len,int64_t h)
{
int64_t i,j,k,x,tmp,jj,kk;
if(len<16) {
for(k=start;k<start+len;k+=j) {
j=1;x=V[I[k]+h];
for(i=1;k+i<start+len;i++) {
if(V[I[k+i]+h]<x) {
x=V[I[k+i]+h];
j=0;
};
if(V[I[k+i]+h]==x) {
tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
j++;
};
};
for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
if(j==1) I[k]=-1;
};
return;
};
x=V[I[start+len/2]+h];
jj=0;kk=0;
for(i=start;i<start+len;i++) {
if(V[I[i]+h]<x) jj++;
if(V[I[i]+h]==x) kk++;
};
jj+=start;kk+=jj;
i=start;j=0;k=0;
while(i<jj) {
if(V[I[i]+h]<x) {
i++;
} else if(V[I[i]+h]==x) {
tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
j++;
} else {
tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
k++;
};
};
while(jj+j<kk) {
if(V[I[jj+j]+h]==x) {
j++;
} else {
tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
k++;
};
};
if(jj>start) split(I,V,start,jj-start,h);
for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
if(jj==kk-1) I[jj]=-1;
if(start+len>kk) split(I,V,kk,start+len-kk,h);
}
static void qsufsort(int64_t *I,int64_t *V,const uint8_t *old,int64_t oldsize)
{
int64_t buckets[256];
int64_t i,h,len;
for(i=0;i<256;i++) buckets[i]=0;
for(i=0;i<oldsize;i++) buckets[old[i]]++;
for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
for(i=255;i>0;i--) buckets[i]=buckets[i-1];
buckets[0]=0;
for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
I[0]=oldsize;
for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
V[oldsize]=0;
for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
I[0]=-1;
for(h=1;I[0]!=-(oldsize+1);h+=h) {
len=0;
for(i=0;i<oldsize+1;) {
if(I[i]<0) {
len-=I[i];
i-=I[i];
} else {
if(len) I[i-len]=-len;
len=V[I[i]]+1-i;
split(I,V,i,len,h);
i+=len;
len=0;
};
};
if(len) I[i-len]=-len;
};
for(i=0;i<oldsize+1;i++) I[V[i]]=i;
}
static int64_t matchlen(const uint8_t *old,int64_t oldsize,const uint8_t *new,int64_t newsize)
{
int64_t i;
for(i=0;(i<oldsize)&&(i<newsize);i++)
if(old[i]!=new[i]) break;
return i;
}
static int64_t search(const int64_t *I,const uint8_t *old,int64_t oldsize,
const uint8_t *new,int64_t newsize,int64_t st,int64_t en,int64_t *pos)
{
int64_t x,y;
if(en-st<2) {
x=matchlen(old+I[st],oldsize-I[st],new,newsize);
y=matchlen(old+I[en],oldsize-I[en],new,newsize);
if(x>y) {
*pos=I[st];
return x;
} else {
*pos=I[en];
return y;
}
};
x=st+(en-st)/2;
if(memcmp(old+I[x],new,MIN(oldsize-I[x],newsize))<0) {
return search(I,old,oldsize,new,newsize,x,en,pos);
} else {
return search(I,old,oldsize,new,newsize,st,x,pos);
};
}
static void offtout(int64_t x,uint8_t *buf)
{
int64_t y;
if(x<0) y=-x; else y=x;
buf[0]=y%256;y-=buf[0];
y=y/256;buf[1]=y%256;y-=buf[1];
y=y/256;buf[2]=y%256;y-=buf[2];
y=y/256;buf[3]=y%256;y-=buf[3];
y=y/256;buf[4]=y%256;y-=buf[4];
y=y/256;buf[5]=y%256;y-=buf[5];
y=y/256;buf[6]=y%256;y-=buf[6];
y=y/256;buf[7]=y%256;
if(x<0) buf[7]|=0x80;
}
static int64_t writedata(struct bsdiff_stream* stream, const void* buffer, int64_t length)
{
int64_t result = 0;
while (length > 0)
{
const int smallsize = (int)MIN(length, INT_MAX);
const int writeresult = stream->write(stream, buffer, smallsize);
if (writeresult == -1)
{
return -1;
}
result += writeresult;
length -= smallsize;
buffer = (uint8_t*)buffer + smallsize;
}
return result;
}
struct bsdiff_request
{
const uint8_t* old;
int64_t oldsize;
const uint8_t* new;
int64_t newsize;
struct bsdiff_stream* stream;
int64_t *I;
uint8_t *buffer;
};
static int bsdiff_internal(const struct bsdiff_request req)
{
int64_t *I,*V;
int64_t scan,pos,len;
int64_t lastscan,lastpos,lastoffset;
int64_t oldscore,scsc;
int64_t s,Sf,lenf,Sb,lenb;
int64_t overlap,Ss,lens;
int64_t i;
uint8_t *buffer;
uint8_t buf[8 * 3];
if((V=req.stream->malloc((req.oldsize+1)*sizeof(int64_t)))==NULL) return -1;
I = req.I;
qsufsort(I,V,req.old,req.oldsize);
req.stream->free(V);
buffer = req.buffer;
/* Compute the differences, writing ctrl as we go */
scan=0;len=0;pos=0;
lastscan=0;lastpos=0;lastoffset=0;
while(scan<req.newsize) {
oldscore=0;
for(scsc=scan+=len;scan<req.newsize;scan++) {
len=search(I,req.old,req.oldsize,req.new+scan,req.newsize-scan,
0,req.oldsize,&pos);
for(;scsc<scan+len;scsc++)
if((scsc+lastoffset<req.oldsize) &&
(req.old[scsc+lastoffset] == req.new[scsc]))
oldscore++;
if(((len==oldscore) && (len!=0)) ||
(len>oldscore+8)) break;
if((scan+lastoffset<req.oldsize) &&
(req.old[scan+lastoffset] == req.new[scan]))
oldscore--;
};
if((len!=oldscore) || (scan==req.newsize)) {
s=0;Sf=0;lenf=0;
for(i=0;(lastscan+i<scan)&&(lastpos+i<req.oldsize);) {
if(req.old[lastpos+i]==req.new[lastscan+i]) s++;
i++;
if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
};
lenb=0;
if(scan<req.newsize) {
s=0;Sb=0;
for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
if(req.old[pos-i]==req.new[scan-i]) s++;
if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
};
};
if(lastscan+lenf>scan-lenb) {
overlap=(lastscan+lenf)-(scan-lenb);
s=0;Ss=0;lens=0;
for(i=0;i<overlap;i++) {
if(req.new[lastscan+lenf-overlap+i]==
req.old[lastpos+lenf-overlap+i]) s++;
if(req.new[scan-lenb+i]==
req.old[pos-lenb+i]) s--;
if(s>Ss) { Ss=s; lens=i+1; };
};
lenf+=lens-overlap;
lenb-=lens;
};
offtout(lenf,buf);
offtout((scan-lenb)-(lastscan+lenf),buf+8);
offtout((pos-lenb)-(lastpos+lenf),buf+16);
/* Write control data */
if (writedata(req.stream, buf, sizeof(buf)))
return -1;
/* Write diff data */
for(i=0;i<lenf;i++)
buffer[i]=req.new[lastscan+i]-req.old[lastpos+i];
if (writedata(req.stream, buffer, lenf))
return -1;
/* Write extra data */
for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
buffer[i]=req.new[lastscan+lenf+i];
if (writedata(req.stream, buffer, (scan-lenb)-(lastscan+lenf)))
return -1;
lastscan=scan-lenb;
lastpos=pos-lenb;
lastoffset=pos-scan;
};
};
return 0;
}
int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* new, int64_t newsize, struct bsdiff_stream* stream)
{
int result;
struct bsdiff_request req;
if((req.I=stream->malloc((oldsize+1)*sizeof(int64_t)))==NULL)
return -1;
if((req.buffer=stream->malloc(newsize+1))==NULL)
{
stream->free(req.I);
return -1;
}
req.old = old;
req.oldsize = oldsize;
req.new = new;
req.newsize = newsize;
req.stream = stream;
result = bsdiff_internal(req);
stream->free(req.buffer);
stream->free(req.I);
return result;
}
#include <sys/types.h>
#include <bzlib.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static int bz2_write(struct bsdiff_stream* stream, const void* buffer, int size)
{
int bz2err;
BZFILE* bz2;
bz2 = (BZFILE*)stream->opaque;
BZ2_bzWrite(&bz2err, bz2, (void*)buffer, size);
if (bz2err != BZ_STREAM_END && bz2err != BZ_OK)
return -1;
return 0;
}
int bsdiff_main(int argc, const char **argv)
{
int fd;
int bz2err;
uint8_t *old,*new;
off_t oldsize,newsize;
uint8_t buf[8];
FILE * pf;
struct bsdiff_stream stream;
BZFILE* bz2;
memset(&bz2, 0, sizeof(bz2));
stream.malloc = malloc;
stream.free = free;
stream.write = bz2_write;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
/* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
that we never try to malloc(0) and get a NULL pointer */
if(((fd=open(argv[1],O_RDONLY,0))<0) ||
((oldsize=lseek(fd,0,SEEK_END))==-1) ||
((old=malloc(oldsize+1))==NULL) ||
(lseek(fd,0,SEEK_SET)!=0) ||
(read(fd,old,oldsize)!=oldsize) ||
(close(fd)==-1)) err(1,"%s",argv[1]);
/* Allocate newsize+1 bytes instead of newsize bytes to ensure
that we never try to malloc(0) and get a NULL pointer */
if(((fd=open(argv[2],O_RDONLY,0))<0) ||
((newsize=lseek(fd,0,SEEK_END))==-1) ||
((new=malloc(newsize+1))==NULL) ||
(lseek(fd,0,SEEK_SET)!=0) ||
(read(fd,new,newsize)!=newsize) ||
(close(fd)==-1)) err(1,"%s",argv[2]);
/* Create the patch file */
if ((pf = fopen(argv[3], "w")) == NULL)
err(1, "%s", argv[3]);
/* Write header (signature+newsize)*/
offtout(newsize, buf);
if (fwrite("ENDSLEY/BSDIFF43", 16, 1, pf) != 1 ||
fwrite(buf, sizeof(buf), 1, pf) != 1)
err(1, "Failed to write header");
if (NULL == (bz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)))
errx(1, "BZ2_bzWriteOpen, bz2err=%d", bz2err);
stream.opaque = bz2;
if (bsdiff(old, oldsize, new, newsize, &stream))
err(1, "bsdiff");
BZ2_bzWriteClose(&bz2err, bz2, 0, NULL, NULL);
if (bz2err != BZ_OK)
err(1, "BZ2_bzWriteClose, bz2err=%d", bz2err);
if (fclose(pf))
err(1, "fclose");
/* Free the memory we used */
free(old);
free(new);
return 0;
}

@ -0,0 +1,44 @@
/*-
* Copyright 2003-2005 Colin Percival
* Copyright 2012 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BSDIFF_H
# define BSDIFF_H
# include <stddef.h>
# include <stdint.h>
struct bsdiff_stream
{
void* opaque;
void* (*malloc)(size_t size);
void (*free)(void* ptr);
int (*write)(struct bsdiff_stream* stream, const void* buffer, int size);
};
int bsdiff(const uint8_t* old, int64_t oldsize, const uint8_t* new, int64_t newsize, struct bsdiff_stream* stream);
#endif

@ -0,0 +1,201 @@
/*-
* Copyright 2003-2005 Colin Percival
* Copyright 2012 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <limits.h>
#include "bspatch.h"
#ifdef __cplusplus
extern "C" {
#endif
int bspatch_main(int argc, char** argv);
#ifdef __cplusplus
}
#endif
static int64_t offtin(uint8_t *buf)
{
int64_t y;
y=buf[7]&0x7F;
y=y*256;y+=buf[6];
y=y*256;y+=buf[5];
y=y*256;y+=buf[4];
y=y*256;y+=buf[3];
y=y*256;y+=buf[2];
y=y*256;y+=buf[1];
y=y*256;y+=buf[0];
if(buf[7]&0x80) y=-y;
return y;
}
int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream)
{
uint8_t buf[8];
int64_t oldpos,newpos;
int64_t ctrl[3];
int64_t i;
oldpos=0;newpos=0;
while(newpos<newsize) {
/* Read control data */
for(i=0;i<=2;i++) {
if (stream->read(stream, buf, 8))
return -1;
ctrl[i]=offtin(buf);
};
/* Sanity-check */
if (ctrl[0]<0 || ctrl[0]>INT_MAX ||
ctrl[1]<0 || ctrl[1]>INT_MAX ||
newpos+ctrl[0]>newsize)
return -1;
/* Read diff string */
if (stream->read(stream, new + newpos, ctrl[0]))
return -1;
/* Add old data to diff string */
for(i=0;i<ctrl[0];i++)
if((oldpos+i>=0) && (oldpos+i<oldsize))
new[newpos+i]+=old[oldpos+i];
/* Adjust pointers */
newpos+=ctrl[0];
oldpos+=ctrl[0];
/* Sanity-check */
if(newpos+ctrl[1]>newsize)
return -1;
/* Read extra string */
if (stream->read(stream, new + newpos, ctrl[1]))
return -1;
/* Adjust pointers */
newpos+=ctrl[1];
oldpos+=ctrl[2];
};
return 0;
}
#if defined(BSPATCH_EXECUTABLE)
#include <bzlib.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length)
{
int n;
int bz2err;
BZFILE* bz2;
bz2 = (BZFILE*)stream->opaque;
n = BZ2_bzRead(&bz2err, bz2, buffer, length);
if (n != length)
return -1;
return 0;
}
int bspatch_main(int argc,char * argv[])
{
FILE * f;
int fd;
int bz2err;
uint8_t header[24];
uint8_t *old, *new;
int64_t oldsize, newsize;
BZFILE* bz2;
struct bspatch_stream stream;
struct stat sb;
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
/* Open patch file */
if ((f = fopen(argv[3], "r")) == NULL)
err(1, "fopen(%s)", argv[3]);
/* Read header */
if (fread(header, 1, 24, f) != 24) {
if (feof(f))
errx(1, "Corrupt patch\n");
err(1, "fread(%s)", argv[3]);
}
/* Check for appropriate magic */
if (memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0)
errx(1, "Corrupt patch\n");
/* Read lengths from header */
newsize=offtin(header+16);
if(newsize<0)
errx(1,"Corrupt patch\n");
/* Close patch file and re-open it via libbzip2 at the right places */
if(((fd=open(argv[1],O_RDONLY,0))<0) ||
((oldsize=lseek(fd,0,SEEK_END))==-1) ||
((old=malloc(oldsize+1))==NULL) ||
(lseek(fd,0,SEEK_SET)!=0) ||
(read(fd,old,oldsize)!=oldsize) ||
(fstat(fd, &sb)) ||
(close(fd)==-1)) err(1,"%s",argv[1]);
if((new=malloc(newsize+1))==NULL) err(1,NULL);
if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 0, NULL, 0)))
errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err);
stream.read = bz2_read;
stream.opaque = bz2;
if (bspatch(old, oldsize, new, newsize, &stream))
errx(1, "bspatch");
/* Clean up the bzip2 reads */
BZ2_bzReadClose(&bz2err, bz2);
fclose(f);
/* Write the new file */
if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,sb.st_mode))<0) ||
(write(fd,new,newsize)!=newsize) || (close(fd)==-1))
err(1,"%s",argv[2]);
free(new);
free(old);
return 0;
}
#endif

@ -0,0 +1,41 @@
/*-
* Copyright 2003-2005 Colin Percival
* Copyright 2012 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted providing that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BSPATCH_H
# define BSPATCH_H
# include <stdint.h>
struct bspatch_stream
{
void* opaque;
int (*read)(const struct bspatch_stream* stream, void* buffer, int length);
};
int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream);
#endif

@ -0,0 +1,97 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `bz2' library (-lbz2). */
#define HAVE_LIBBZ2 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Name of package */
#define PACKAGE "bsdiff"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "bsdiff"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "bsdiff 0.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "bsdiff"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.1"
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
/* Define to the type of a signed integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef int64_t */
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */

@ -0,0 +1,42 @@
--------------------------------------------------------------------------
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2019 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@acm.org
bzip2/libbzip2 version 1.0.8 of 13 July 2019
--------------------------------------------------------------------------

@ -0,0 +1,217 @@
# ------------------------------------------------------------------
# This file is part of bzip2/libbzip2, a program and library for
# lossless, block-sorting data compression.
#
# bzip2/libbzip2 version 1.0.8 of 13 July 2019
# Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
#
# Please read the WARNING, DISCLAIMER and PATENTS sections in the
# README file.
#
# This program is released under the terms of the license contained
# in the file LICENSE.
# ------------------------------------------------------------------
SHELL=/bin/sh
# To assist in cross-compiling
CC=gcc
AR=ar
RANLIB=ranlib
LDFLAGS=
BIGFILES=-D_FILE_OFFSET_BITS=64
CFLAGS=-Wall -Winline -O2 -g $(BIGFILES)
# Where you want it installed when you do 'make install'
PREFIX=/usr/local
OBJS= blocksort.o \
huffman.o \
crctable.o \
randtable.o \
compress.o \
decompress.o \
bzlib.o
all: libbz2.a bzip2 bzip2recover test
bzip2: libbz2.a bzip2.o
$(CC) $(CFLAGS) $(LDFLAGS) -o bzip2 bzip2.o -L. -lbz2
bzip2recover: bzip2recover.o
$(CC) $(CFLAGS) $(LDFLAGS) -o bzip2recover bzip2recover.o
libbz2.a: $(OBJS)
rm -f libbz2.a
$(AR) cq libbz2.a $(OBJS)
@if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \
-f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \
echo $(RANLIB) libbz2.a ; \
$(RANLIB) libbz2.a ; \
fi
check: test
test: bzip2
@cat words1
./bzip2 -1 < sample1.ref > sample1.rb2
./bzip2 -2 < sample2.ref > sample2.rb2
./bzip2 -3 < sample3.ref > sample3.rb2
./bzip2 -d < sample1.bz2 > sample1.tst
./bzip2 -d < sample2.bz2 > sample2.tst
./bzip2 -ds < sample3.bz2 > sample3.tst
cmp sample1.bz2 sample1.rb2
cmp sample2.bz2 sample2.rb2
cmp sample3.bz2 sample3.rb2
cmp sample1.tst sample1.ref
cmp sample2.tst sample2.ref
cmp sample3.tst sample3.ref
@cat words3
install: bzip2 bzip2recover
if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi
if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi
if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi
if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi
cp -f bzip2 $(PREFIX)/bin/bzip2
cp -f bzip2 $(PREFIX)/bin/bunzip2
cp -f bzip2 $(PREFIX)/bin/bzcat
cp -f bzip2recover $(PREFIX)/bin/bzip2recover
chmod a+x $(PREFIX)/bin/bzip2
chmod a+x $(PREFIX)/bin/bunzip2
chmod a+x $(PREFIX)/bin/bzcat
chmod a+x $(PREFIX)/bin/bzip2recover
cp -f bzip2.1 $(PREFIX)/man/man1
chmod a+r $(PREFIX)/man/man1/bzip2.1
cp -f bzlib.h $(PREFIX)/include
chmod a+r $(PREFIX)/include/bzlib.h
cp -f libbz2.a $(PREFIX)/lib
chmod a+r $(PREFIX)/lib/libbz2.a
cp -f bzgrep $(PREFIX)/bin/bzgrep
ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzegrep
ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzfgrep
chmod a+x $(PREFIX)/bin/bzgrep
cp -f bzmore $(PREFIX)/bin/bzmore
ln -s -f $(PREFIX)/bin/bzmore $(PREFIX)/bin/bzless
chmod a+x $(PREFIX)/bin/bzmore
cp -f bzdiff $(PREFIX)/bin/bzdiff
ln -s -f $(PREFIX)/bin/bzdiff $(PREFIX)/bin/bzcmp
chmod a+x $(PREFIX)/bin/bzdiff
cp -f bzgrep.1 bzmore.1 bzdiff.1 $(PREFIX)/man/man1
chmod a+r $(PREFIX)/man/man1/bzgrep.1
chmod a+r $(PREFIX)/man/man1/bzmore.1
chmod a+r $(PREFIX)/man/man1/bzdiff.1
echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzegrep.1
echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzfgrep.1
echo ".so man1/bzmore.1" > $(PREFIX)/man/man1/bzless.1
echo ".so man1/bzdiff.1" > $(PREFIX)/man/man1/bzcmp.1
clean:
rm -f *.o libbz2.a bzip2 bzip2recover \
sample1.rb2 sample2.rb2 sample3.rb2 \
sample1.tst sample2.tst sample3.tst
blocksort.o: blocksort.c
@cat words0
$(CC) $(CFLAGS) -c blocksort.c
huffman.o: huffman.c
$(CC) $(CFLAGS) -c huffman.c
crctable.o: crctable.c
$(CC) $(CFLAGS) -c crctable.c
randtable.o: randtable.c
$(CC) $(CFLAGS) -c randtable.c
compress.o: compress.c
$(CC) $(CFLAGS) -c compress.c
decompress.o: decompress.c
$(CC) $(CFLAGS) -c decompress.c
bzlib.o: bzlib.c
$(CC) $(CFLAGS) -c bzlib.c
bzip2.o: bzip2.c
$(CC) $(CFLAGS) -c bzip2.c
bzip2recover.o: bzip2recover.c
$(CC) $(CFLAGS) -c bzip2recover.c
distclean: clean
rm -f manual.ps manual.html manual.pdf
DISTNAME=bzip2-1.0.8
dist: check manual
rm -f $(DISTNAME)
ln -s -f . $(DISTNAME)
tar cvf $(DISTNAME).tar \
$(DISTNAME)/blocksort.c \
$(DISTNAME)/huffman.c \
$(DISTNAME)/crctable.c \
$(DISTNAME)/randtable.c \
$(DISTNAME)/compress.c \
$(DISTNAME)/decompress.c \
$(DISTNAME)/bzlib.c \
$(DISTNAME)/bzip2.c \
$(DISTNAME)/bzip2recover.c \
$(DISTNAME)/bzlib.h \
$(DISTNAME)/bzlib_private.h \
$(DISTNAME)/Makefile \
$(DISTNAME)/LICENSE \
$(DISTNAME)/bzip2.1 \
$(DISTNAME)/bzip2.1.preformatted \
$(DISTNAME)/bzip2.txt \
$(DISTNAME)/words0 \
$(DISTNAME)/words1 \
$(DISTNAME)/words2 \
$(DISTNAME)/words3 \
$(DISTNAME)/sample1.ref \
$(DISTNAME)/sample2.ref \
$(DISTNAME)/sample3.ref \
$(DISTNAME)/sample1.bz2 \
$(DISTNAME)/sample2.bz2 \
$(DISTNAME)/sample3.bz2 \
$(DISTNAME)/dlltest.c \
$(DISTNAME)/manual.html \
$(DISTNAME)/manual.pdf \
$(DISTNAME)/manual.ps \
$(DISTNAME)/README \
$(DISTNAME)/README.COMPILATION.PROBLEMS \
$(DISTNAME)/README.XML.STUFF \
$(DISTNAME)/CHANGES \
$(DISTNAME)/libbz2.def \
$(DISTNAME)/libbz2.dsp \
$(DISTNAME)/dlltest.dsp \
$(DISTNAME)/makefile.msc \
$(DISTNAME)/unzcrash.c \
$(DISTNAME)/spewG.c \
$(DISTNAME)/mk251.c \
$(DISTNAME)/bzdiff \
$(DISTNAME)/bzdiff.1 \
$(DISTNAME)/bzmore \
$(DISTNAME)/bzmore.1 \
$(DISTNAME)/bzgrep \
$(DISTNAME)/bzgrep.1 \
$(DISTNAME)/Makefile-libbz2_so \
$(DISTNAME)/bz-common.xsl \
$(DISTNAME)/bz-fo.xsl \
$(DISTNAME)/bz-html.xsl \
$(DISTNAME)/bzip.css \
$(DISTNAME)/entities.xml \
$(DISTNAME)/manual.xml \
$(DISTNAME)/format.pl \
$(DISTNAME)/xmlproc.sh
gzip -v $(DISTNAME).tar
# For rebuilding the manual from sources on my SuSE 9.1 box
MANUAL_SRCS= bz-common.xsl bz-fo.xsl bz-html.xsl bzip.css \
entities.xml manual.xml
manual: manual.html manual.ps manual.pdf
manual.ps: $(MANUAL_SRCS)
./xmlproc.sh -ps manual.xml
manual.pdf: $(MANUAL_SRCS)
./xmlproc.sh -pdf manual.xml
manual.html: $(MANUAL_SRCS)
./xmlproc.sh -html manual.xml

@ -0,0 +1,59 @@
# This Makefile builds a shared version of the library,
# libbz2.so.1.0.8, with soname libbz2.so.1.0,
# at least on x86-Linux (RedHat 7.2),
# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).
# Please see the README file for some important info
# about building the library like this.
# ------------------------------------------------------------------
# This file is part of bzip2/libbzip2, a program and library for
# lossless, block-sorting data compression.
#
# bzip2/libbzip2 version 1.0.8 of 13 July 2019
# Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
#
# Please read the WARNING, DISCLAIMER and PATENTS sections in the
# README file.
#
# This program is released under the terms of the license contained
# in the file LICENSE.
# ------------------------------------------------------------------
SHELL=/bin/sh
CC=gcc
BIGFILES=-D_FILE_OFFSET_BITS=64
CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)
OBJS= blocksort.o \
huffman.o \
crctable.o \
randtable.o \
compress.o \
decompress.o \
bzlib.o
all: $(OBJS)
$(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.8 $(OBJS)
$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.8
rm -f libbz2.so.1.0
ln -s libbz2.so.1.0.8 libbz2.so.1.0
clean:
rm -f $(OBJS) bzip2.o libbz2.so.1.0.8 libbz2.so.1.0 bzip2-shared
blocksort.o: blocksort.c
$(CC) $(CFLAGS) -c blocksort.c
huffman.o: huffman.c
$(CC) $(CFLAGS) -c huffman.c
crctable.o: crctable.c
$(CC) $(CFLAGS) -c crctable.c
randtable.o: randtable.c
$(CC) $(CFLAGS) -c randtable.c
compress.o: compress.c
$(CC) $(CFLAGS) -c compress.c
decompress.o: decompress.c
$(CC) $(CFLAGS) -c decompress.c
bzlib.o: bzlib.c
$(CC) $(CFLAGS) -c bzlib.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,516 @@
/*-----------------------------------------------------------*/
/*--- Block recoverer program for bzip2 ---*/
/*--- bzip2recover.c ---*/
/*-----------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
/* This program is a complete hack and should be rewritten properly.
It isn't very complicated. */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
/* This program records bit locations in the file to be recovered.
That means that if 64-bit ints are not supported, we will not
be able to recover .bz2 files over 512MB (2^32 bits) long.
On GNU supported platforms, we take advantage of the 64-bit
int support to circumvent this problem. Ditto MSVC.
This change occurred in version 1.0.2; all prior versions have
the 512MB limitation.
*/
#ifdef __GNUC__
typedef unsigned long long int MaybeUInt64;
# define MaybeUInt64_FMT "%Lu"
#else
#ifdef _MSC_VER
typedef unsigned __int64 MaybeUInt64;
# define MaybeUInt64_FMT "%I64u"
#else
typedef unsigned int MaybeUInt64;
# define MaybeUInt64_FMT "%u"
#endif
#endif
typedef unsigned int UInt32;
typedef int Int32;
typedef unsigned char UChar;
typedef char Char;
typedef unsigned char Bool;
#define True ((Bool)1)
#define False ((Bool)0)
#define BZ_MAX_FILENAME 2000
Char inFileName[BZ_MAX_FILENAME];
Char outFileName[BZ_MAX_FILENAME];
Char progName[BZ_MAX_FILENAME];
MaybeUInt64 bytesOut = 0;
MaybeUInt64 bytesIn = 0;
/*---------------------------------------------------*/
/*--- Header bytes ---*/
/*---------------------------------------------------*/
#define BZ_HDR_B 0x42 /* 'B' */
#define BZ_HDR_Z 0x5a /* 'Z' */
#define BZ_HDR_h 0x68 /* 'h' */
#define BZ_HDR_0 0x30 /* '0' */
/*---------------------------------------------------*/
/*--- I/O errors ---*/
/*---------------------------------------------------*/
/*---------------------------------------------*/
static void readError ( void )
{
fprintf ( stderr,
"%s: I/O error reading `%s', possible reason follows.\n",
progName, inFileName );
perror ( progName );
fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
progName );
exit ( 1 );
}
/*---------------------------------------------*/
static void writeError ( void )
{
fprintf ( stderr,
"%s: I/O error reading `%s', possible reason follows.\n",
progName, inFileName );
perror ( progName );
fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
progName );
exit ( 1 );
}
/*---------------------------------------------*/
static void mallocFail ( Int32 n )
{
fprintf ( stderr,
"%s: malloc failed on request for %d bytes.\n",
progName, n );
fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
progName );
exit ( 1 );
}
/*---------------------------------------------*/
static void tooManyBlocks ( Int32 max_handled_blocks )
{
fprintf ( stderr,
"%s: `%s' appears to contain more than %d blocks\n",
progName, inFileName, max_handled_blocks );
fprintf ( stderr,
"%s: and cannot be handled. To fix, increase\n",
progName );
fprintf ( stderr,
"%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
progName );
exit ( 1 );
}
/*---------------------------------------------------*/
/*--- Bit stream I/O ---*/
/*---------------------------------------------------*/
typedef
struct {
FILE* handle;
Int32 buffer;
Int32 buffLive;
Char mode;
}
BitStream;
/*---------------------------------------------*/
static BitStream* bsOpenReadStream ( FILE* stream )
{
BitStream *bs = malloc ( sizeof(BitStream) );
if (bs == NULL) mallocFail ( sizeof(BitStream) );
bs->handle = stream;
bs->buffer = 0;
bs->buffLive = 0;
bs->mode = 'r';
return bs;
}
/*---------------------------------------------*/
static BitStream* bsOpenWriteStream ( FILE* stream )
{
BitStream *bs = malloc ( sizeof(BitStream) );
if (bs == NULL) mallocFail ( sizeof(BitStream) );
bs->handle = stream;
bs->buffer = 0;
bs->buffLive = 0;
bs->mode = 'w';
return bs;
}
/*---------------------------------------------*/
static void bsPutBit ( BitStream* bs, Int32 bit )
{
if (bs->buffLive == 8) {
Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
if (retVal == EOF) writeError();
bytesOut++;
bs->buffLive = 1;
bs->buffer = bit & 0x1;
} else {
bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
bs->buffLive++;
};
}
/*---------------------------------------------*/
/*--
Returns 0 or 1, or 2 to indicate EOF.
--*/
static Int32 bsGetBit ( BitStream* bs )
{
if (bs->buffLive > 0) {
bs->buffLive --;
return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
} else {
Int32 retVal = getc ( bs->handle );
if ( retVal == EOF ) {
if (errno != 0) readError();
return 2;
}
bs->buffLive = 7;
bs->buffer = retVal;
return ( ((bs->buffer) >> 7) & 0x1 );
}
}
/*---------------------------------------------*/
static void bsClose ( BitStream* bs )
{
Int32 retVal;
if ( bs->mode == 'w' ) {
while ( bs->buffLive < 8 ) {
bs->buffLive++;
bs->buffer <<= 1;
};
retVal = putc ( (UChar) (bs->buffer), bs->handle );
if (retVal == EOF) writeError();
bytesOut++;
retVal = fflush ( bs->handle );
if (retVal == EOF) writeError();
}
retVal = fclose ( bs->handle );
if (retVal == EOF) {
if (bs->mode == 'w') writeError(); else readError();
}
free ( bs );
}
/*---------------------------------------------*/
static void bsPutUChar ( BitStream* bs, UChar c )
{
Int32 i;
for (i = 7; i >= 0; i--)
bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
}
/*---------------------------------------------*/
static void bsPutUInt32 ( BitStream* bs, UInt32 c )
{
Int32 i;
for (i = 31; i >= 0; i--)
bsPutBit ( bs, (c >> i) & 0x1 );
}
/*---------------------------------------------*/
static Bool endsInBz2 ( Char* name )
{
Int32 n = strlen ( name );
if (n <= 4) return False;
return
(name[n-4] == '.' &&
name[n-3] == 'b' &&
name[n-2] == 'z' &&
name[n-1] == '2');
}
/*---------------------------------------------------*/
/*--- ---*/
/*---------------------------------------------------*/
/* This logic isn't really right when it comes to Cygwin. */
#ifdef _WIN32
# define BZ_SPLIT_SYM '\\' /* path splitter on Windows platform */
#else
# define BZ_SPLIT_SYM '/' /* path splitter on Unix platform */
#endif
#define BLOCK_HEADER_HI 0x00003141UL
#define BLOCK_HEADER_LO 0x59265359UL
#define BLOCK_ENDMARK_HI 0x00001772UL
#define BLOCK_ENDMARK_LO 0x45385090UL
/* Increase if necessary. However, a .bz2 file with > 50000 blocks
would have an uncompressed size of at least 40GB, so the chances
are low you'll need to up this.
*/
#define BZ_MAX_HANDLED_BLOCKS 50000
MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
MaybeUInt64 bEnd [BZ_MAX_HANDLED_BLOCKS];
MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
MaybeUInt64 rbEnd [BZ_MAX_HANDLED_BLOCKS];
Int32 main ( Int32 argc, Char** argv )
{
FILE* inFile;
FILE* outFile;
BitStream* bsIn, *bsWr;
Int32 b, wrBlock, currBlock, rbCtr;
MaybeUInt64 bitsRead;
UInt32 buffHi, buffLo, blockCRC;
Char* p;
strncpy ( progName, argv[0], BZ_MAX_FILENAME-1);
progName[BZ_MAX_FILENAME-1]='\0';
inFileName[0] = outFileName[0] = 0;
fprintf ( stderr,
"bzip2recover 1.0.8: extracts blocks from damaged .bz2 files.\n" );
if (argc != 2) {
fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
progName, progName );
switch (sizeof(MaybeUInt64)) {
case 8:
fprintf(stderr,
"\trestrictions on size of recovered file: None\n");
break;
case 4:
fprintf(stderr,
"\trestrictions on size of recovered file: 512 MB\n");
fprintf(stderr,
"\tto circumvent, recompile with MaybeUInt64 as an\n"
"\tunsigned 64-bit int.\n");
break;
default:
fprintf(stderr,
"\tsizeof(MaybeUInt64) is not 4 or 8 -- "
"configuration error.\n");
break;
}
exit(1);
}
if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
fprintf ( stderr,
"%s: supplied filename is suspiciously (>= %d chars) long. Bye!\n",
progName, (int)strlen(argv[1]) );
exit(1);
}
strcpy ( inFileName, argv[1] );
inFile = fopen ( inFileName, "rb" );
if (inFile == NULL) {
fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
exit(1);
}
bsIn = bsOpenReadStream ( inFile );
fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
bitsRead = 0;
buffHi = buffLo = 0;
currBlock = 0;
bStart[currBlock] = 0;
rbCtr = 0;
while (True) {
b = bsGetBit ( bsIn );
bitsRead++;
if (b == 2) {
if (bitsRead >= bStart[currBlock] &&
(bitsRead - bStart[currBlock]) >= 40) {
bEnd[currBlock] = bitsRead-1;
if (currBlock > 0)
fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
" to " MaybeUInt64_FMT " (incomplete)\n",
currBlock, bStart[currBlock], bEnd[currBlock] );
} else
currBlock--;
break;
}
buffHi = (buffHi << 1) | (buffLo >> 31);
buffLo = (buffLo << 1) | (b & 1);
if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
&& buffLo == BLOCK_HEADER_LO)
||
( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
&& buffLo == BLOCK_ENDMARK_LO)
) {
if (bitsRead > 49) {
bEnd[currBlock] = bitsRead-49;
} else {
bEnd[currBlock] = 0;
}
if (currBlock > 0 &&
(bEnd[currBlock] - bStart[currBlock]) >= 130) {
fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
" to " MaybeUInt64_FMT "\n",
rbCtr+1, bStart[currBlock], bEnd[currBlock] );
rbStart[rbCtr] = bStart[currBlock];
rbEnd[rbCtr] = bEnd[currBlock];
rbCtr++;
}
if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
currBlock++;
bStart[currBlock] = bitsRead;
}
}
bsClose ( bsIn );
/*-- identified blocks run from 1 to rbCtr inclusive. --*/
if (rbCtr < 1) {
fprintf ( stderr,
"%s: sorry, I couldn't find any block boundaries.\n",
progName );
exit(1);
};
fprintf ( stderr, "%s: splitting into blocks\n", progName );
inFile = fopen ( inFileName, "rb" );
if (inFile == NULL) {
fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
exit(1);
}
bsIn = bsOpenReadStream ( inFile );
/*-- placate gcc's dataflow analyser --*/
blockCRC = 0; bsWr = 0;
bitsRead = 0;
outFile = NULL;
wrBlock = 0;
while (True) {
b = bsGetBit(bsIn);
if (b == 2) break;
buffHi = (buffHi << 1) | (buffLo >> 31);
buffLo = (buffLo << 1) | (b & 1);
if (bitsRead == 47+rbStart[wrBlock])
blockCRC = (buffHi << 16) | (buffLo >> 16);
if (outFile != NULL && bitsRead >= rbStart[wrBlock]
&& bitsRead <= rbEnd[wrBlock]) {
bsPutBit ( bsWr, b );
}
bitsRead++;
if (bitsRead == rbEnd[wrBlock]+1) {
if (outFile != NULL) {
bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
bsPutUInt32 ( bsWr, blockCRC );
bsClose ( bsWr );
outFile = NULL;
}
if (wrBlock >= rbCtr) break;
wrBlock++;
} else
if (bitsRead == rbStart[wrBlock]) {
/* Create the output file name, correctly handling leading paths.
(31.10.2001 by Sergey E. Kusikov) */
Char* split;
Int32 ofs, k;
for (k = 0; k < BZ_MAX_FILENAME; k++)
outFileName[k] = 0;
strcpy (outFileName, inFileName);
split = strrchr (outFileName, BZ_SPLIT_SYM);
if (split == NULL) {
split = outFileName;
} else {
++split;
}
/* Now split points to the start of the basename. */
ofs = split - outFileName;
sprintf (split, "rec%5d", wrBlock+1);
for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
strcat (outFileName, inFileName + ofs);
if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
fprintf ( stderr, " writing block %d to `%s' ...\n",
wrBlock+1, outFileName );
outFile = fopen ( outFileName, "wb" );
if (outFile == NULL) {
fprintf ( stderr, "%s: can't write `%s'\n",
progName, outFileName );
exit(1);
}
bsWr = bsOpenWriteStream ( outFile );
bsPutUChar ( bsWr, BZ_HDR_B );
bsPutUChar ( bsWr, BZ_HDR_Z );
bsPutUChar ( bsWr, BZ_HDR_h );
bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
}
}
fprintf ( stderr, "%s: finished\n", progName );
return 0;
}
/*-----------------------------------------------------------*/
/*--- end bzip2recover.c ---*/
/*-----------------------------------------------------------*/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,282 @@
/*-------------------------------------------------------------*/
/*--- Public header file for the library. ---*/
/*--- bzlib.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#ifndef _BZLIB_H
#define _BZLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#define BZ_RUN 0
#define BZ_FLUSH 1
#define BZ_FINISH 2
#define BZ_OK 0
#define BZ_RUN_OK 1
#define BZ_FLUSH_OK 2
#define BZ_FINISH_OK 3
#define BZ_STREAM_END 4
#define BZ_SEQUENCE_ERROR (-1)
#define BZ_PARAM_ERROR (-2)
#define BZ_MEM_ERROR (-3)
#define BZ_DATA_ERROR (-4)
#define BZ_DATA_ERROR_MAGIC (-5)
#define BZ_IO_ERROR (-6)
#define BZ_UNEXPECTED_EOF (-7)
#define BZ_OUTBUFF_FULL (-8)
#define BZ_CONFIG_ERROR (-9)
typedef
struct {
char *next_in;
unsigned int avail_in;
unsigned int total_in_lo32;
unsigned int total_in_hi32;
char *next_out;
unsigned int avail_out;
unsigned int total_out_lo32;
unsigned int total_out_hi32;
void *state;
void *(*bzalloc)(void *,int,int);
void (*bzfree)(void *,void *);
void *opaque;
}
bz_stream;
#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif
#ifndef BZ_NO_STDIO
/* Need a definitition for FILE */
#include <stdio.h>
#endif
#ifdef _WIN32
# include <windows.h>
# ifdef small
/* windows.h define small to char */
# undef small
# endif
# ifdef BZ_EXPORT
# define BZ_API(func) WINAPI func
# define BZ_EXTERN extern
# else
/* import windows dll dynamically */
# define BZ_API(func) (WINAPI * func)
# define BZ_EXTERN
# endif
#else
# define BZ_API(func) func
# define BZ_EXTERN extern
#endif
/*-- Core (low-level) library functions --*/
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
bz_stream* strm,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
bz_stream* strm,
int action
);
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
bz_stream *strm,
int verbosity,
int small
);
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
bz_stream *strm
);
/*-- High(er) level library functions --*/
#ifndef BZ_NO_STDIO
#define BZ_MAX_UNUSED 5000
typedef void BZFILE;
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
int* bzerror,
FILE* f,
int verbosity,
int small,
void* unused,
int nUnused
);
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
int* bzerror,
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
int* bzerror,
BZFILE* b,
void** unused,
int* nUnused
);
BZ_EXTERN int BZ_API(BZ2_bzRead) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
int* bzerror,
FILE* f,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in,
unsigned int* nbytes_out
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in_lo32,
unsigned int* nbytes_in_hi32,
unsigned int* nbytes_out_lo32,
unsigned int* nbytes_out_hi32
);
#endif
/*-- Utility functions --*/
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int small,
int verbosity
);
/*--
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
threading-safeness of it.
If this code breaks, please contact both Yoshioka and me.
--*/
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
void
);
#ifndef BZ_NO_STDIO
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
const char *path,
const char *mode
);
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
int fd,
const char *mode
);
BZ_EXTERN int BZ_API(BZ2_bzread) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzflush) (
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzclose) (
BZFILE* b
);
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
BZFILE *b,
int *errnum
);
#endif
#ifdef __cplusplus
}
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib.h ---*/
/*-------------------------------------------------------------*/

@ -0,0 +1,509 @@
/*-------------------------------------------------------------*/
/*--- Private header file for the library. ---*/
/*--- bzlib_private.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#ifndef _BZLIB_PRIVATE_H
#define _BZLIB_PRIVATE_H
#include <stdlib.h>
#ifndef BZ_NO_STDIO
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#endif
#include "bzlib.h"
/*-- General stuff. --*/
#define BZ_VERSION "1.0.8, 13-Jul-2019"
typedef char Char;
typedef unsigned char Bool;
typedef unsigned char UChar;
typedef int Int32;
typedef unsigned int UInt32;
typedef short Int16;
typedef unsigned short UInt16;
#define True ((Bool)1)
#define False ((Bool)0)
#ifndef __GNUC__
#define __inline__ /* */
#endif
#ifndef BZ_NO_STDIO
extern void BZ2_bz__AssertH__fail ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
#if BZ_DEBUG
#define AssertD(cond,msg) \
{ if (!(cond)) { \
fprintf ( stderr, \
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
exit(1); \
}}
#else
#define AssertD(cond,msg) /* */
#endif
#define VPrintf0(zf) \
fprintf(stderr,zf)
#define VPrintf1(zf,za1) \
fprintf(stderr,zf,za1)
#define VPrintf2(zf,za1,za2) \
fprintf(stderr,zf,za1,za2)
#define VPrintf3(zf,za1,za2,za3) \
fprintf(stderr,zf,za1,za2,za3)
#define VPrintf4(zf,za1,za2,za3,za4) \
fprintf(stderr,zf,za1,za2,za3,za4)
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
fprintf(stderr,zf,za1,za2,za3,za4,za5)
#else
extern void bz_internal_error ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) bz_internal_error ( errcode ); }
#define AssertD(cond,msg) do { } while (0)
#define VPrintf0(zf) do { } while (0)
#define VPrintf1(zf,za1) do { } while (0)
#define VPrintf2(zf,za1,za2) do { } while (0)
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
#endif
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
/*-- Header bytes. --*/
#define BZ_HDR_B 0x42 /* 'B' */
#define BZ_HDR_Z 0x5a /* 'Z' */
#define BZ_HDR_h 0x68 /* 'h' */
#define BZ_HDR_0 0x30 /* '0' */
/*-- Constants for the back end. --*/
#define BZ_MAX_ALPHA_SIZE 258
#define BZ_MAX_CODE_LEN 23
#define BZ_RUNA 0
#define BZ_RUNB 1
#define BZ_N_GROUPS 6
#define BZ_G_SIZE 50
#define BZ_N_ITERS 4
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
/*-- Stuff for randomising repetitive blocks. --*/
extern Int32 BZ2_rNums[512];
#define BZ_RAND_DECLS \
Int32 rNToGo; \
Int32 rTPos \
#define BZ_RAND_INIT_MASK \
s->rNToGo = 0; \
s->rTPos = 0 \
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
#define BZ_RAND_UPD_MASK \
if (s->rNToGo == 0) { \
s->rNToGo = BZ2_rNums[s->rTPos]; \
s->rTPos++; \
if (s->rTPos == 512) s->rTPos = 0; \
} \
s->rNToGo--;
/*-- Stuff for doing CRCs. --*/
extern UInt32 BZ2_crc32Table[256];
#define BZ_INITIALISE_CRC(crcVar) \
{ \
crcVar = 0xffffffffL; \
}
#define BZ_FINALISE_CRC(crcVar) \
{ \
crcVar = ~(crcVar); \
}
#define BZ_UPDATE_CRC(crcVar,cha) \
{ \
crcVar = (crcVar << 8) ^ \
BZ2_crc32Table[(crcVar >> 24) ^ \
((UChar)cha)]; \
}
/*-- States and modes for compression. --*/
#define BZ_M_IDLE 1
#define BZ_M_RUNNING 2
#define BZ_M_FLUSHING 3
#define BZ_M_FINISHING 4
#define BZ_S_OUTPUT 1
#define BZ_S_INPUT 2
#define BZ_N_RADIX 2
#define BZ_N_QSORT 12
#define BZ_N_SHELL 18
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
/*-- Structure holding all the compression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* mode this stream is in, and whether inputting */
/* or outputting data */
Int32 mode;
Int32 state;
/* remembers avail_in when flush/finish requested */
UInt32 avail_in_expect;
/* for doing the block sorting */
UInt32* arr1;
UInt32* arr2;
UInt32* ftab;
Int32 origPtr;
/* aliases for arr1 and arr2 */
UInt32* ptr;
UChar* block;
UInt16* mtfv;
UChar* zbits;
/* for deciding when to use the fallback sorting algorithm */
Int32 workFactor;
/* run-length-encoding of the input */
UInt32 state_in_ch;
Int32 state_in_len;
BZ_RAND_DECLS;
/* input and output limits and current posns */
Int32 nblock;
Int32 nblockMAX;
Int32 numZ;
Int32 state_out_pos;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
UChar unseqToSeq[256];
/* the buffer for bit stream creation */
UInt32 bsBuff;
Int32 bsLive;
/* block and combined CRCs */
UInt32 blockCRC;
UInt32 combinedCRC;
/* misc administratium */
Int32 verbosity;
Int32 blockNo;
Int32 blockSize100k;
/* stuff for coding the MTF values */
Int32 nMTF;
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
/* second dimension: only 3 needed; 4 makes index calculations faster */
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
}
EState;
/*-- externs for compression. --*/
extern void
BZ2_blockSort ( EState* );
extern void
BZ2_compressBlock ( EState*, Bool );
extern void
BZ2_bsInitWrite ( EState* );
extern void
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
extern void
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
/*-- states for decompression. --*/
#define BZ_X_IDLE 1
#define BZ_X_OUTPUT 2
#define BZ_X_MAGIC_1 10
#define BZ_X_MAGIC_2 11
#define BZ_X_MAGIC_3 12
#define BZ_X_MAGIC_4 13
#define BZ_X_BLKHDR_1 14
#define BZ_X_BLKHDR_2 15
#define BZ_X_BLKHDR_3 16
#define BZ_X_BLKHDR_4 17
#define BZ_X_BLKHDR_5 18
#define BZ_X_BLKHDR_6 19
#define BZ_X_BCRC_1 20
#define BZ_X_BCRC_2 21
#define BZ_X_BCRC_3 22
#define BZ_X_BCRC_4 23
#define BZ_X_RANDBIT 24
#define BZ_X_ORIGPTR_1 25
#define BZ_X_ORIGPTR_2 26
#define BZ_X_ORIGPTR_3 27
#define BZ_X_MAPPING_1 28
#define BZ_X_MAPPING_2 29
#define BZ_X_SELECTOR_1 30
#define BZ_X_SELECTOR_2 31
#define BZ_X_SELECTOR_3 32
#define BZ_X_CODING_1 33
#define BZ_X_CODING_2 34
#define BZ_X_CODING_3 35
#define BZ_X_MTF_1 36
#define BZ_X_MTF_2 37
#define BZ_X_MTF_3 38
#define BZ_X_MTF_4 39
#define BZ_X_MTF_5 40
#define BZ_X_MTF_6 41
#define BZ_X_ENDHDR_2 42
#define BZ_X_ENDHDR_3 43
#define BZ_X_ENDHDR_4 44
#define BZ_X_ENDHDR_5 45
#define BZ_X_ENDHDR_6 46
#define BZ_X_CCRC_1 47
#define BZ_X_CCRC_2 48
#define BZ_X_CCRC_3 49
#define BZ_X_CCRC_4 50
/*-- Constants for the fast MTF decoder. --*/
#define MTFA_SIZE 4096
#define MTFL_SIZE 16
/*-- Structure holding all the decompression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* state indicator for this stream */
Int32 state;
/* for doing the final run-length decoding */
UChar state_out_ch;
Int32 state_out_len;
Bool blockRandomised;
BZ_RAND_DECLS;
/* the buffer for bit stream reading */
UInt32 bsBuff;
Int32 bsLive;
/* misc administratium */
Int32 blockSize100k;
Bool smallDecompress;
Int32 currBlockNo;
Int32 verbosity;
/* for undoing the Burrows-Wheeler transform */
Int32 origPtr;
UInt32 tPos;
Int32 k0;
Int32 unzftab[256];
Int32 nblock_used;
Int32 cftab[257];
Int32 cftabCopy[257];
/* for undoing the Burrows-Wheeler transform (FAST) */
UInt32 *tt;
/* for undoing the Burrows-Wheeler transform (SMALL) */
UInt16 *ll16;
UChar *ll4;
/* stored and calculated CRCs */
UInt32 storedBlockCRC;
UInt32 storedCombinedCRC;
UInt32 calculatedBlockCRC;
UInt32 calculatedCombinedCRC;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
Bool inUse16[16];
UChar seqToUnseq[256];
/* for decoding the MTF values */
UChar mtfa [MTFA_SIZE];
Int32 mtfbase[256 / MTFL_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 minLens[BZ_N_GROUPS];
/* save area for scalars in the main decompress code */
Int32 save_i;
Int32 save_j;
Int32 save_t;
Int32 save_alphaSize;
Int32 save_nGroups;
Int32 save_nSelectors;
Int32 save_EOB;
Int32 save_groupNo;
Int32 save_groupPos;
Int32 save_nextSym;
Int32 save_nblockMAX;
Int32 save_nblock;
Int32 save_es;
Int32 save_N;
Int32 save_curr;
Int32 save_zt;
Int32 save_zn;
Int32 save_zvec;
Int32 save_zj;
Int32 save_gSel;
Int32 save_gMinlen;
Int32* save_gLimit;
Int32* save_gBase;
Int32* save_gPerm;
}
DState;
/*-- Macros for decompression. --*/
#define BZ_GET_FAST(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
s->tPos = s->tt[s->tPos]; \
cccc = (UChar)(s->tPos & 0xff); \
s->tPos >>= 8;
#define BZ_GET_FAST_C(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
c_tPos = c_tt[c_tPos]; \
cccc = (UChar)(c_tPos & 0xff); \
c_tPos >>= 8;
#define SET_LL4(i,n) \
{ if (((i) & 0x1) == 0) \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
}
#define GET_LL4(i) \
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
#define SET_LL(i,n) \
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
SET_LL4(i, n >> 16); \
}
#define GET_LL(i) \
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
#define BZ_GET_SMALL(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
s->tPos = GET_LL(s->tPos);
/*-- externs for decompression. --*/
extern Int32
BZ2_indexIntoF ( Int32, Int32* );
extern Int32
BZ2_decompress ( DState* );
extern void
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
Int32, Int32, Int32 );
#endif
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
#ifdef BZ_NO_STDIO
#ifndef NULL
#define NULL 0
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib_private.h ---*/
/*-------------------------------------------------------------*/

@ -0,0 +1,672 @@
/*-------------------------------------------------------------*/
/*--- Compression machinery (not incl block sorting) ---*/
/*--- compress.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
/* CHANGES
0.9.0 -- original version.
0.9.0a/b -- no changes in this file.
0.9.0c -- changed setting of nGroups in sendMTFValues()
so as to do a bit better on small files
*/
#include "bzlib_private.h"
/*---------------------------------------------------*/
/*--- Bit stream I/O ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
void BZ2_bsInitWrite ( EState* s )
{
s->bsLive = 0;
s->bsBuff = 0;
}
/*---------------------------------------------------*/
static
void bsFinishWrite ( EState* s )
{
while (s->bsLive > 0) {
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
s->numZ++;
s->bsBuff <<= 8;
s->bsLive -= 8;
}
}
/*---------------------------------------------------*/
#define bsNEEDW(nz) \
{ \
while (s->bsLive >= 8) { \
s->zbits[s->numZ] \
= (UChar)(s->bsBuff >> 24); \
s->numZ++; \
s->bsBuff <<= 8; \
s->bsLive -= 8; \
} \
}
/*---------------------------------------------------*/
static
__inline__
void bsW ( EState* s, Int32 n, UInt32 v )
{
bsNEEDW ( n );
s->bsBuff |= (v << (32 - s->bsLive - n));
s->bsLive += n;
}
/*---------------------------------------------------*/
static
void bsPutUInt32 ( EState* s, UInt32 u )
{
bsW ( s, 8, (u >> 24) & 0xffL );
bsW ( s, 8, (u >> 16) & 0xffL );
bsW ( s, 8, (u >> 8) & 0xffL );
bsW ( s, 8, u & 0xffL );
}
/*---------------------------------------------------*/
static
void bsPutUChar ( EState* s, UChar c )
{
bsW( s, 8, (UInt32)c );
}
/*---------------------------------------------------*/
/*--- The back end proper ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
static
void makeMaps_e ( EState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->unseqToSeq[i] = s->nInUse;
s->nInUse++;
}
}
/*---------------------------------------------------*/
static
void generateMTFValues ( EState* s )
{
UChar yy[256];
Int32 i, j;
Int32 zPend;
Int32 wr;
Int32 EOB;
/*
After sorting (eg, here),
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
and
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
holds the original block data.
The first thing to do is generate the MTF values,
and put them in
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
Because there are strictly fewer or equal MTF values
than block values, ptr values in this area are overwritten
with MTF values only when they are no longer needed.
The final compressed bitstream is generated into the
area starting at
(UChar*) (&((UChar*)s->arr2)[s->nblock])
These storage aliases are set up in bzCompressInit(),
except for the last one, which is arranged in
compressBlock().
*/
UInt32* ptr = s->ptr;
UChar* block = s->block;
UInt16* mtfv = s->mtfv;
makeMaps_e ( s );
EOB = s->nInUse+1;
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
wr = 0;
zPend = 0;
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
for (i = 0; i < s->nblock; i++) {
UChar ll_i;
AssertD ( wr <= i, "generateMTFValues(1)" );
j = ptr[i]-1; if (j < 0) j += s->nblock;
ll_i = s->unseqToSeq[block[j]];
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
if (yy[0] == ll_i) {
zPend++;
} else {
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
{
register UChar rtmp;
register UChar* ryy_j;
register UChar rll_i;
rtmp = yy[1];
yy[1] = yy[0];
ryy_j = &(yy[1]);
rll_i = ll_i;
while ( rll_i != rtmp ) {
register UChar rtmp2;
ryy_j++;
rtmp2 = rtmp;
rtmp = *ryy_j;
*ryy_j = rtmp2;
};
yy[0] = rtmp;
j = ryy_j - &(yy[0]);
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
}
}
}
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
s->nMTF = wr;
}
/*---------------------------------------------------*/
#define BZ_LESSER_ICOST 0
#define BZ_GREATER_ICOST 15
static
void sendMTFValues ( EState* s )
{
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
Int32 nGroups, nBytes;
/*--
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
is a global since the decoder also needs it.
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
are also globals only used in this proc.
Made global to keep stack frame size small.
--*/
UInt16 cost[BZ_N_GROUPS];
Int32 fave[BZ_N_GROUPS];
UInt16* mtfv = s->mtfv;
if (s->verbosity >= 3)
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
"%d+2 syms in use\n",
s->nblock, s->nMTF, s->nInUse );
alphaSize = s->nInUse+2;
for (t = 0; t < BZ_N_GROUPS; t++)
for (v = 0; v < alphaSize; v++)
s->len[t][v] = BZ_GREATER_ICOST;
/*--- Decide how many coding tables to use ---*/
AssertH ( s->nMTF > 0, 3001 );
if (s->nMTF < 200) nGroups = 2; else
if (s->nMTF < 600) nGroups = 3; else
if (s->nMTF < 1200) nGroups = 4; else
if (s->nMTF < 2400) nGroups = 5; else
nGroups = 6;
/*--- Generate an initial set of coding tables ---*/
{
Int32 nPart, remF, tFreq, aFreq;
nPart = nGroups;
remF = s->nMTF;
gs = 0;
while (nPart > 0) {
tFreq = remF / nPart;
ge = gs-1;
aFreq = 0;
while (aFreq < tFreq && ge < alphaSize-1) {
ge++;
aFreq += s->mtfFreq[ge];
}
if (ge > gs
&& nPart != nGroups && nPart != 1
&& ((nGroups-nPart) % 2 == 1)) {
aFreq -= s->mtfFreq[ge];
ge--;
}
if (s->verbosity >= 3)
VPrintf5( " initial group %d, [%d .. %d], "
"has %d syms (%4.1f%%)\n",
nPart, gs, ge, aFreq,
(100.0 * (float)aFreq) / (float)(s->nMTF) );
for (v = 0; v < alphaSize; v++)
if (v >= gs && v <= ge)
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
s->len[nPart-1][v] = BZ_GREATER_ICOST;
nPart--;
gs = ge+1;
remF -= aFreq;
}
}
/*---
Iterate up to BZ_N_ITERS times to improve the tables.
---*/
for (iter = 0; iter < BZ_N_ITERS; iter++) {
for (t = 0; t < nGroups; t++) fave[t] = 0;
for (t = 0; t < nGroups; t++)
for (v = 0; v < alphaSize; v++)
s->rfreq[t][v] = 0;
/*---
Set up an auxiliary length table which is used to fast-track
the common case (nGroups == 6).
---*/
if (nGroups == 6) {
for (v = 0; v < alphaSize; v++) {
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
}
}
nSelectors = 0;
totc = 0;
gs = 0;
while (True) {
/*--- Set group start & end marks. --*/
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
/*--
Calculate the cost of this group as coded
by each of the coding tables.
--*/
for (t = 0; t < nGroups; t++) cost[t] = 0;
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
register UInt32 cost01, cost23, cost45;
register UInt16 icv;
cost01 = cost23 = cost45 = 0;
# define BZ_ITER(nn) \
icv = mtfv[gs+(nn)]; \
cost01 += s->len_pack[icv][0]; \
cost23 += s->len_pack[icv][1]; \
cost45 += s->len_pack[icv][2]; \
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
# undef BZ_ITER
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
UInt16 icv = mtfv[i];
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
}
}
/*--
Find the coding table which is best for this group,
and record its identity in the selector table.
--*/
bc = 999999999; bt = -1;
for (t = 0; t < nGroups; t++)
if (cost[t] < bc) { bc = cost[t]; bt = t; };
totc += bc;
fave[bt]++;
s->selector[nSelectors] = bt;
nSelectors++;
/*--
Increment the symbol frequencies for the selected table.
--*/
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
# undef BZ_ITUR
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++)
s->rfreq[bt][ mtfv[i] ]++;
}
gs = ge+1;
}
if (s->verbosity >= 3) {
VPrintf2 ( " pass %d: size is %d, grp uses are ",
iter+1, totc/8 );
for (t = 0; t < nGroups; t++)
VPrintf1 ( "%d ", fave[t] );
VPrintf0 ( "\n" );
}
/*--
Recompute the tables based on the accumulated frequencies.
--*/
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
comment in huffman.c for details. */
for (t = 0; t < nGroups; t++)
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
alphaSize, 17 /*20*/ );
}
AssertH( nGroups < 8, 3002 );
AssertH( nSelectors < 32768 &&
nSelectors <= BZ_MAX_SELECTORS,
3003 );
/*--- Compute MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
for (i = 0; i < nGroups; i++) pos[i] = i;
for (i = 0; i < nSelectors; i++) {
ll_i = s->selector[i];
j = 0;
tmp = pos[j];
while ( ll_i != tmp ) {
j++;
tmp2 = tmp;
tmp = pos[j];
pos[j] = tmp2;
};
pos[0] = tmp;
s->selectorMtf[i] = j;
}
};
/*--- Assign actual codes for the tables. --*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
AssertH ( !(minLen < 1), 3005 );
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
minLen, maxLen, alphaSize );
}
/*--- Transmit the mapping table. ---*/
{
Bool inUse16[16];
for (i = 0; i < 16; i++) {
inUse16[i] = False;
for (j = 0; j < 16; j++)
if (s->inUse[i * 16 + j]) inUse16[i] = True;
}
nBytes = s->numZ;
for (i = 0; i < 16; i++)
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
for (i = 0; i < 16; i++)
if (inUse16[i])
for (j = 0; j < 16; j++) {
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
}
/*--- Now the selectors. ---*/
nBytes = s->numZ;
bsW ( s, 3, nGroups );
bsW ( s, 15, nSelectors );
for (i = 0; i < nSelectors; i++) {
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( "selectors %d, ", s->numZ-nBytes );
/*--- Now the coding tables. ---*/
nBytes = s->numZ;
for (t = 0; t < nGroups; t++) {
Int32 curr = s->len[t][0];
bsW ( s, 5, curr );
for (i = 0; i < alphaSize; i++) {
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
bsW ( s, 1, 0 );
}
}
if (s->verbosity >= 3)
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
/*--- And finally, the block data proper ---*/
nBytes = s->numZ;
selCtr = 0;
gs = 0;
while (True) {
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
AssertH ( s->selector[selCtr] < nGroups, 3006 );
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
UInt16 mtfv_i;
UChar* s_len_sel_selCtr
= &(s->len[s->selector[selCtr]][0]);
Int32* s_code_sel_selCtr
= &(s->code[s->selector[selCtr]][0]);
# define BZ_ITAH(nn) \
mtfv_i = mtfv[gs+(nn)]; \
bsW ( s, \
s_len_sel_selCtr[mtfv_i], \
s_code_sel_selCtr[mtfv_i] )
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
# undef BZ_ITAH
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
bsW ( s,
s->len [s->selector[selCtr]] [mtfv[i]],
s->code [s->selector[selCtr]] [mtfv[i]] );
}
}
gs = ge+1;
selCtr++;
}
AssertH( selCtr == nSelectors, 3007 );
if (s->verbosity >= 3)
VPrintf1( "codes %d\n", s->numZ-nBytes );
}
/*---------------------------------------------------*/
void BZ2_compressBlock ( EState* s, Bool is_last_block )
{
if (s->nblock > 0) {
BZ_FINALISE_CRC ( s->blockCRC );
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
s->combinedCRC ^= s->blockCRC;
if (s->blockNo > 1) s->numZ = 0;
if (s->verbosity >= 2)
VPrintf4( " block %d: crc = 0x%08x, "
"combined CRC = 0x%08x, size = %d\n",
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
BZ2_blockSort ( s );
}
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
/*-- If this is the first block, create the stream header. --*/
if (s->blockNo == 1) {
BZ2_bsInitWrite ( s );
bsPutUChar ( s, BZ_HDR_B );
bsPutUChar ( s, BZ_HDR_Z );
bsPutUChar ( s, BZ_HDR_h );
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
}
if (s->nblock > 0) {
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
/*-- Now the block's CRC, so it is in a known place. --*/
bsPutUInt32 ( s, s->blockCRC );
/*--
Now a single bit indicating (non-)randomisation.
As of version 0.9.5, we use a better sorting algorithm
which makes randomisation unnecessary. So always set
the randomised bit to 'no'. Of course, the decoder
still needs to be able to handle randomised blocks
so as to maintain backwards compatibility with
older versions of bzip2.
--*/
bsW(s,1,0);
bsW ( s, 24, s->origPtr );
generateMTFValues ( s );
sendMTFValues ( s );
}
/*-- If this is the last block, add the stream trailer. --*/
if (is_last_block) {
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
bsPutUInt32 ( s, s->combinedCRC );
if (s->verbosity >= 2)
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
bsFinishWrite ( s );
}
}
/*-------------------------------------------------------------*/
/*--- end compress.c ---*/
/*-------------------------------------------------------------*/

@ -0,0 +1,104 @@
/*-------------------------------------------------------------*/
/*--- Table for doing CRCs ---*/
/*--- crctable.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*--
I think this is an implementation of the AUTODIN-II,
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
from code by Rob Warnock, in Section 51 of the
comp.compression FAQ.
--*/
UInt32 BZ2_crc32Table[256] = {
/*-- Ugly, innit? --*/
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
};
/*-------------------------------------------------------------*/
/*--- end crctable.c ---*/
/*-------------------------------------------------------------*/

@ -0,0 +1,652 @@
/*-------------------------------------------------------------*/
/*--- Decompression machinery ---*/
/*--- decompress.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
static
void makeMaps_d ( DState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->seqToUnseq[s->nInUse] = i;
s->nInUse++;
}
}
/*---------------------------------------------------*/
#define RETURN(rrr) \
{ retVal = rrr; goto save_state_and_return; };
#define GET_BITS(lll,vvv,nnn) \
case lll: s->state = lll; \
while (True) { \
if (s->bsLive >= nnn) { \
UInt32 v; \
v = (s->bsBuff >> \
(s->bsLive-nnn)) & ((1 << nnn)-1); \
s->bsLive -= nnn; \
vvv = v; \
break; \
} \
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
s->bsBuff \
= (s->bsBuff << 8) | \
((UInt32) \
(*((UChar*)(s->strm->next_in)))); \
s->bsLive += 8; \
s->strm->next_in++; \
s->strm->avail_in--; \
s->strm->total_in_lo32++; \
if (s->strm->total_in_lo32 == 0) \
s->strm->total_in_hi32++; \
}
#define GET_UCHAR(lll,uuu) \
GET_BITS(lll,uuu,8)
#define GET_BIT(lll,uuu) \
GET_BITS(lll,uuu,1)
/*---------------------------------------------------*/
#define GET_MTF_VAL(label1,label2,lval) \
{ \
if (groupPos == 0) { \
groupNo++; \
if (groupNo >= nSelectors) \
RETURN(BZ_DATA_ERROR); \
groupPos = BZ_G_SIZE; \
gSel = s->selector[groupNo]; \
gMinlen = s->minLens[gSel]; \
gLimit = &(s->limit[gSel][0]); \
gPerm = &(s->perm[gSel][0]); \
gBase = &(s->base[gSel][0]); \
} \
groupPos--; \
zn = gMinlen; \
GET_BITS(label1, zvec, zn); \
while (1) { \
if (zn > 20 /* the longest code */) \
RETURN(BZ_DATA_ERROR); \
if (zvec <= gLimit[zn]) break; \
zn++; \
GET_BIT(label2, zj); \
zvec = (zvec << 1) | zj; \
}; \
if (zvec - gBase[zn] < 0 \
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
RETURN(BZ_DATA_ERROR); \
lval = gPerm[zvec - gBase[zn]]; \
}
/*---------------------------------------------------*/
Int32 BZ2_decompress ( DState* s )
{
UChar uc;
Int32 retVal;
Int32 minLen, maxLen;
bz_stream* strm = s->strm;
/* stuff that needs to be saved/restored */
Int32 i;
Int32 j;
Int32 t;
Int32 alphaSize;
Int32 nGroups;
Int32 nSelectors;
Int32 EOB;
Int32 groupNo;
Int32 groupPos;
Int32 nextSym;
Int32 nblockMAX;
Int32 nblock;
Int32 es;
Int32 N;
Int32 curr;
Int32 zt;
Int32 zn;
Int32 zvec;
Int32 zj;
Int32 gSel;
Int32 gMinlen;
Int32* gLimit;
Int32* gBase;
Int32* gPerm;
if (s->state == BZ_X_MAGIC_1) {
/*initialise the save area*/
s->save_i = 0;
s->save_j = 0;
s->save_t = 0;
s->save_alphaSize = 0;
s->save_nGroups = 0;
s->save_nSelectors = 0;
s->save_EOB = 0;
s->save_groupNo = 0;
s->save_groupPos = 0;
s->save_nextSym = 0;
s->save_nblockMAX = 0;
s->save_nblock = 0;
s->save_es = 0;
s->save_N = 0;
s->save_curr = 0;
s->save_zt = 0;
s->save_zn = 0;
s->save_zvec = 0;
s->save_zj = 0;
s->save_gSel = 0;
s->save_gMinlen = 0;
s->save_gLimit = NULL;
s->save_gBase = NULL;
s->save_gPerm = NULL;
}
/*restore from the save area*/
i = s->save_i;
j = s->save_j;
t = s->save_t;
alphaSize = s->save_alphaSize;
nGroups = s->save_nGroups;
nSelectors = s->save_nSelectors;
EOB = s->save_EOB;
groupNo = s->save_groupNo;
groupPos = s->save_groupPos;
nextSym = s->save_nextSym;
nblockMAX = s->save_nblockMAX;
nblock = s->save_nblock;
es = s->save_es;
N = s->save_N;
curr = s->save_curr;
zt = s->save_zt;
zn = s->save_zn;
zvec = s->save_zvec;
zj = s->save_zj;
gSel = s->save_gSel;
gMinlen = s->save_gMinlen;
gLimit = s->save_gLimit;
gBase = s->save_gBase;
gPerm = s->save_gPerm;
retVal = BZ_OK;
switch (s->state) {
GET_UCHAR(BZ_X_MAGIC_1, uc);
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_2, uc);
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_3, uc)
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
s->blockSize100k -= BZ_HDR_0;
if (s->smallDecompress) {
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
s->ll4 = BZALLOC(
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
);
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
} else {
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
}
GET_UCHAR(BZ_X_BLKHDR_1, uc);
if (uc == 0x17) goto endhdr_2;
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_2, uc);
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_3, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_4, uc);
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_5, uc);
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_6, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
s->currBlockNo++;
if (s->verbosity >= 2)
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
s->storedBlockCRC = 0;
GET_UCHAR(BZ_X_BCRC_1, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_2, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_3, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_4, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
s->origPtr = 0;
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
if (s->origPtr < 0)
RETURN(BZ_DATA_ERROR);
if (s->origPtr > 10 + 100000*s->blockSize100k)
RETURN(BZ_DATA_ERROR);
/*--- Receive the mapping table ---*/
for (i = 0; i < 16; i++) {
GET_BIT(BZ_X_MAPPING_1, uc);
if (uc == 1)
s->inUse16[i] = True; else
s->inUse16[i] = False;
}
for (i = 0; i < 256; i++) s->inUse[i] = False;
for (i = 0; i < 16; i++)
if (s->inUse16[i])
for (j = 0; j < 16; j++) {
GET_BIT(BZ_X_MAPPING_2, uc);
if (uc == 1) s->inUse[i * 16 + j] = True;
}
makeMaps_d ( s );
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
alphaSize = s->nInUse+2;
/*--- Now the selectors ---*/
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
if (nGroups < 2 || nGroups > BZ_N_GROUPS) RETURN(BZ_DATA_ERROR);
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
for (i = 0; i < nSelectors; i++) {
j = 0;
while (True) {
GET_BIT(BZ_X_SELECTOR_3, uc);
if (uc == 0) break;
j++;
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
}
/* Having more than BZ_MAX_SELECTORS doesn't make much sense
since they will never be used, but some implementations might
"round up" the number of selectors, so just ignore those. */
if (i < BZ_MAX_SELECTORS)
s->selectorMtf[i] = j;
}
if (nSelectors > BZ_MAX_SELECTORS)
nSelectors = BZ_MAX_SELECTORS;
/*--- Undo the MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], tmp, v;
for (v = 0; v < nGroups; v++) pos[v] = v;
for (i = 0; i < nSelectors; i++) {
v = s->selectorMtf[i];
tmp = pos[v];
while (v > 0) { pos[v] = pos[v-1]; v--; }
pos[0] = tmp;
s->selector[i] = tmp;
}
}
/*--- Now the coding tables ---*/
for (t = 0; t < nGroups; t++) {
GET_BITS(BZ_X_CODING_1, curr, 5);
for (i = 0; i < alphaSize; i++) {
while (True) {
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
GET_BIT(BZ_X_CODING_2, uc);
if (uc == 0) break;
GET_BIT(BZ_X_CODING_3, uc);
if (uc == 0) curr++; else curr--;
}
s->len[t][i] = curr;
}
}
/*--- Create the Huffman decoding tables ---*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
BZ2_hbCreateDecodeTables (
&(s->limit[t][0]),
&(s->base[t][0]),
&(s->perm[t][0]),
&(s->len[t][0]),
minLen, maxLen, alphaSize
);
s->minLens[t] = minLen;
}
/*--- Now the MTF values ---*/
EOB = s->nInUse+1;
nblockMAX = 100000 * s->blockSize100k;
groupNo = -1;
groupPos = 0;
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
/*-- MTF init --*/
{
Int32 ii, jj, kk;
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
/*-- end MTF init --*/
nblock = 0;
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
while (True) {
if (nextSym == EOB) break;
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
es = -1;
N = 1;
do {
/* Check that N doesn't get too big, so that es doesn't
go negative. The maximum value that can be
RUNA/RUNB encoded is equal to the block size (post
the initial RLE), viz, 900k, so bounding N at 2
million should guard against overflow without
rejecting any legitimate inputs. */
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
N = N * 2;
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
}
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
es++;
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
s->unzftab[uc] += es;
if (s->smallDecompress)
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->ll16[nblock] = (UInt16)uc;
nblock++;
es--;
}
else
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->tt[nblock] = (UInt32)uc;
nblock++;
es--;
};
continue;
} else {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
/*-- uc = MTF ( nextSym-1 ) --*/
{
Int32 ii, jj, kk, pp, lno, off;
UInt32 nn;
nn = (UInt32)(nextSym - 1);
if (nn < MTFL_SIZE) {
/* avoid general-case expense */
pp = s->mtfbase[0];
uc = s->mtfa[pp+nn];
while (nn > 3) {
Int32 z = pp+nn;
s->mtfa[(z) ] = s->mtfa[(z)-1];
s->mtfa[(z)-1] = s->mtfa[(z)-2];
s->mtfa[(z)-2] = s->mtfa[(z)-3];
s->mtfa[(z)-3] = s->mtfa[(z)-4];
nn -= 4;
}
while (nn > 0) {
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
};
s->mtfa[pp] = uc;
} else {
/* general case */
lno = nn / MTFL_SIZE;
off = nn % MTFL_SIZE;
pp = s->mtfbase[lno] + off;
uc = s->mtfa[pp];
while (pp > s->mtfbase[lno]) {
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
};
s->mtfbase[lno]++;
while (lno > 0) {
s->mtfbase[lno]--;
s->mtfa[s->mtfbase[lno]]
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
lno--;
}
s->mtfbase[0]--;
s->mtfa[s->mtfbase[0]] = uc;
if (s->mtfbase[0] == 0) {
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
}
}
/*-- end uc = MTF ( nextSym-1 ) --*/
s->unzftab[s->seqToUnseq[uc]]++;
if (s->smallDecompress)
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
nblock++;
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
continue;
}
}
/* Now we know what nblock is, we can do a better sanity
check on s->origPtr.
*/
if (s->origPtr < 0 || s->origPtr >= nblock)
RETURN(BZ_DATA_ERROR);
/*-- Set up cftab to facilitate generation of T^(-1) --*/
/* Check: unzftab entries in range. */
for (i = 0; i <= 255; i++) {
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
RETURN(BZ_DATA_ERROR);
}
/* Actually generate cftab. */
s->cftab[0] = 0;
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
/* Check: cftab entries in range. */
for (i = 0; i <= 256; i++) {
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
/* s->cftab[i] can legitimately be == nblock */
RETURN(BZ_DATA_ERROR);
}
}
/* Check: cftab entries non-descending. */
for (i = 1; i <= 256; i++) {
if (s->cftab[i-1] > s->cftab[i]) {
RETURN(BZ_DATA_ERROR);
}
}
s->state_out_len = 0;
s->state_out_ch = 0;
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
s->state = BZ_X_OUTPUT;
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
if (s->smallDecompress) {
/*-- Make a copy of cftab, used in generation of T --*/
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
/*-- compute the T vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->ll16[i]);
SET_LL(i, s->cftabCopy[uc]);
s->cftabCopy[uc]++;
}
/*-- Compute T^(-1) by pointer reversal on T --*/
i = s->origPtr;
j = GET_LL(i);
do {
Int32 tmp = GET_LL(j);
SET_LL(j, i);
i = j;
j = tmp;
}
while (i != s->origPtr);
s->tPos = s->origPtr;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_SMALL(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_SMALL(s->k0); s->nblock_used++;
}
} else {
/*-- compute the T^(-1) vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->tt[i] & 0xff);
s->tt[s->cftab[uc]] |= (i << 8);
s->cftab[uc]++;
}
s->tPos = s->tt[s->origPtr] >> 8;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_FAST(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_FAST(s->k0); s->nblock_used++;
}
}
RETURN(BZ_OK);
endhdr_2:
GET_UCHAR(BZ_X_ENDHDR_2, uc);
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_3, uc);
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_4, uc);
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_5, uc);
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_6, uc);
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
s->storedCombinedCRC = 0;
GET_UCHAR(BZ_X_CCRC_1, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_2, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_3, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_4, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
s->state = BZ_X_IDLE;
RETURN(BZ_STREAM_END);
default: AssertH ( False, 4001 );
}
AssertH ( False, 4002 );
save_state_and_return:
s->save_i = i;
s->save_j = j;
s->save_t = t;
s->save_alphaSize = alphaSize;
s->save_nGroups = nGroups;
s->save_nSelectors = nSelectors;
s->save_EOB = EOB;
s->save_groupNo = groupNo;
s->save_groupPos = groupPos;
s->save_nextSym = nextSym;
s->save_nblockMAX = nblockMAX;
s->save_nblock = nblock;
s->save_es = es;
s->save_N = N;
s->save_curr = curr;
s->save_zt = zt;
s->save_zn = zn;
s->save_zvec = zvec;
s->save_zj = zj;
s->save_gSel = gSel;
s->save_gMinlen = gMinlen;
s->save_gLimit = gLimit;
s->save_gBase = gBase;
s->save_gPerm = gPerm;
return retVal;
}
/*-------------------------------------------------------------*/
/*--- end decompress.c ---*/
/*-------------------------------------------------------------*/

@ -0,0 +1,205 @@
/*-------------------------------------------------------------*/
/*--- Huffman coding low-level stuff ---*/
/*--- huffman.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.8 of 13 July 2019
Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
#define ADDWEIGHTS(zw1,zw2) \
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
#define UPHEAP(z) \
{ \
Int32 zz, tmp; \
zz = z; tmp = heap[zz]; \
while (weight[tmp] < weight[heap[zz >> 1]]) { \
heap[zz] = heap[zz >> 1]; \
zz >>= 1; \
} \
heap[zz] = tmp; \
}
#define DOWNHEAP(z) \
{ \
Int32 zz, yy, tmp; \
zz = z; tmp = heap[zz]; \
while (True) { \
yy = zz << 1; \
if (yy > nHeap) break; \
if (yy < nHeap && \
weight[heap[yy+1]] < weight[heap[yy]]) \
yy++; \
if (weight[tmp] < weight[heap[yy]]) break; \
heap[zz] = heap[yy]; \
zz = yy; \
} \
heap[zz] = tmp; \
}
/*---------------------------------------------------*/
void BZ2_hbMakeCodeLengths ( UChar *len,
Int32 *freq,
Int32 alphaSize,
Int32 maxLen )
{
/*--
Nodes and heap entries run from 1. Entry 0
for both the heap and nodes is a sentinel.
--*/
Int32 nNodes, nHeap, n1, n2, i, j, k;
Bool tooLong;
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
for (i = 0; i < alphaSize; i++)
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
while (True) {
nNodes = alphaSize;
nHeap = 0;
heap[0] = 0;
weight[0] = 0;
parent[0] = -2;
for (i = 1; i <= alphaSize; i++) {
parent[i] = -1;
nHeap++;
heap[nHeap] = i;
UPHEAP(nHeap);
}
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
while (nHeap > 1) {
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
nNodes++;
parent[n1] = parent[n2] = nNodes;
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
parent[nNodes] = -1;
nHeap++;
heap[nHeap] = nNodes;
UPHEAP(nHeap);
}
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
tooLong = False;
for (i = 1; i <= alphaSize; i++) {
j = 0;
k = i;
while (parent[k] >= 0) { k = parent[k]; j++; }
len[i-1] = j;
if (j > maxLen) tooLong = True;
}
if (! tooLong) break;
/* 17 Oct 04: keep-going condition for the following loop used
to be 'i < alphaSize', which missed the last element,
theoretically leading to the possibility of the compressor
looping. However, this count-scaling step is only needed if
one of the generated Huffman code words is longer than
maxLen, which up to and including version 1.0.2 was 20 bits,
which is extremely unlikely. In version 1.0.3 maxLen was
changed to 17 bits, which has minimal effect on compression
ratio, but does mean this scaling step is used from time to
time, enough to verify that it works.
This means that bzip2-1.0.3 and later will only produce
Huffman codes with a maximum length of 17 bits. However, in
order to preserve backwards compatibility with bitstreams
produced by versions pre-1.0.3, the decompressor must still
handle lengths of up to 20. */
for (i = 1; i <= alphaSize; i++) {
j = weight[i] >> 8;
j = 1 + (j / 2);
weight[i] = j << 8;
}
}
}
/*---------------------------------------------------*/
void BZ2_hbAssignCodes ( Int32 *code,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 n, vec, i;
vec = 0;
for (n = minLen; n <= maxLen; n++) {
for (i = 0; i < alphaSize; i++)
if (length[i] == n) { code[i] = vec; vec++; };
vec <<= 1;
}
}
/*---------------------------------------------------*/
void BZ2_hbCreateDecodeTables ( Int32 *limit,
Int32 *base,
Int32 *perm,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 pp, i, j, vec;
pp = 0;
for (i = minLen; i <= maxLen; i++)
for (j = 0; j < alphaSize; j++)
if (length[j] == i) { perm[pp] = j; pp++; };
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
vec = 0;
for (i = minLen; i <= maxLen; i++) {
vec += (base[i+1] - base[i]);
limit[i] = vec-1;
vec <<= 1;
}
for (i = minLen + 1; i <= maxLen; i++)
base[i] = ((limit[i-1] + 1) << 1) - base[i];
}
/*-------------------------------------------------------------*/
/*--- end huffman.c ---*/
/*-------------------------------------------------------------*/

@ -0,0 +1,27 @@
LIBRARY LIBBZ2
DESCRIPTION "libbzip2: library for data compression"
EXPORTS
BZ2_bzCompressInit
BZ2_bzCompress
BZ2_bzCompressEnd
BZ2_bzDecompressInit
BZ2_bzDecompress
BZ2_bzDecompressEnd
BZ2_bzReadOpen
BZ2_bzReadClose
BZ2_bzReadGetUnused
BZ2_bzRead
BZ2_bzWriteOpen
BZ2_bzWrite
BZ2_bzWriteClose
BZ2_bzWriteClose64
BZ2_bzBuffToBuffCompress
BZ2_bzBuffToBuffDecompress
BZ2_bzlibVersion
BZ2_bzopen
BZ2_bzdopen
BZ2_bzread
BZ2_bzwrite
BZ2_bzflush
BZ2_bzclose
BZ2_bzerror

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save