├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── CMakePresets.json ├── README.md ├── etc ├── CMVS_Symbol.json └── note.md ├── lib ├── CMVS │ ├── CMakeLists.txt │ └── src │ │ ├── #collation │ │ ├── CMV │ │ │ ├── CMV6_Coder.h │ │ │ ├── CMV6_Hook.cpp │ │ │ ├── CMV6_Hook.h │ │ │ ├── CMV6_Hook_Def.h │ │ │ ├── CMV6_PixelArray.h │ │ │ ├── CMV_Editor.cpp │ │ │ ├── CMV_Editor.h │ │ │ └── CMV_Struct.h │ │ ├── FileDump │ │ │ ├── CMVSFileDump.cpp │ │ │ └── CMVSFileDump.h │ │ └── PB3 │ │ │ ├── PB3_Dump.cpp │ │ │ └── PB3_Dump.h │ │ └── CMVS │ │ ├── CMVS_Types.h │ │ ├── MGV_Editor.cpp │ │ ├── MGV_Editor.h │ │ ├── PS3_Cryptor.cpp │ │ ├── PS3_Cryptor.h │ │ ├── PS3_TextEditor.cpp │ │ ├── PS3_TextEditor.h │ │ ├── VFS_Extract.cpp │ │ ├── VFS_Extract.h │ │ ├── VFS_Hook.cpp │ │ └── VFS_Hook.h └── CMakeLists.txt ├── src ├── #collation │ ├── CMV6Editor │ │ └── main.cpp │ ├── CMV6Hook │ │ └── dllmain.cpp │ ├── CMVSFileDump │ │ └── dllmain.cpp │ └── CMVSFileExtract │ │ └── dllmain.cpp ├── CMakeLists.txt ├── MGV_Editor │ ├── CMakeLists.txt │ └── main.cpp ├── PS3_Cryptor │ ├── CMakeLists.txt │ └── main.cpp ├── PS3_TextEditor │ ├── CMakeLists.txt │ └── main.cpp ├── VFS_Extract │ ├── CMakeLists.txt │ └── dllmain.cpp └── VFS_Hook │ ├── CMakeLists.txt │ ├── VFSHook.ini │ └── dllmain.cpp └── third └── libwebp ├── include ├── decode.h ├── demux.h ├── encode.h ├── format_constants.h ├── mux.h ├── mux_types.h └── types.h └── lib.X86 └── libwebp.lib /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /.vs 6 | /.build 7 | /.bin 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/Rut"] 2 | path = lib/Rut 3 | url = https://github.com/Dir-A/Rut.git 4 | [submodule "lib/RxHook"] 5 | path = lib/RxHook 6 | url = https://github.com/Dir-A/RxHook.git 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Main CMakeLists 2 | cmake_minimum_required(VERSION 3.20) 3 | 4 | # Project Name 5 | project(CMVS_Tools) 6 | 7 | # Option 8 | set(UVAR_BUILD_TEST TRUE) 9 | set(UVAR_IPO_OPTIMIZATION TRUE) 10 | set(UVAR_STATIC_MSVC_RUNTIME TRUE) 11 | 12 | # Value Define 13 | set(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") 14 | 15 | # Out Path 16 | if (CMAKE_SIZEOF_VOID_P EQUAL 4) 17 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 18 | set(EXECUTABLE_OUTPUT_PATH "${ROOT_DIR}/.bin/x32/debug") 19 | set(LIBRARY_OUTPUT_PATH "${ROOT_DIR}/.bin/x32/debug") 20 | else() 21 | set(EXECUTABLE_OUTPUT_PATH "${ROOT_DIR}/.bin/x32/release") 22 | set(LIBRARY_OUTPUT_PATH "${ROOT_DIR}/.bin/x32/release") 23 | endif() 24 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) 25 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 26 | set(EXECUTABLE_OUTPUT_PATH "${ROOT_DIR}/.bin/x64/debug") 27 | set(LIBRARY_OUTPUT_PATH "${ROOT_DIR}/.bin/x64/debug") 28 | else() 29 | set(EXECUTABLE_OUTPUT_PATH "${ROOT_DIR}/.bin/x64/release") 30 | set(LIBRARY_OUTPUT_PATH "${ROOT_DIR}/.bin/x64/release") 31 | endif() 32 | endif() 33 | 34 | # IPO 35 | if(UVAR_IPO_OPTIMIZATION) 36 | include(CheckIPOSupported) 37 | check_ipo_supported(RESULT IPO_CHECK_RESULT OUTPUT output) 38 | if(IPO_CHECK_RESULT) 39 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE) 40 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE) 41 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL TRUE) 42 | else() 43 | message(WARNING "IPO is not supported: ${output}") 44 | endif() 45 | endif() 46 | 47 | # MSVC Setting 48 | if(MSVC) 49 | # Runtime 50 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 51 | if (UVAR_STATIC_MSVC_RUNTIME) 52 | set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug) 53 | else() 54 | set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL) 55 | endif() 56 | else() 57 | if (UVAR_STATIC_MSVC_RUNTIME) 58 | set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) 59 | else() 60 | set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) 61 | endif() 62 | endif() 63 | 64 | # Macro 65 | add_definitions(-DUNICODE -D_UNICODE) 66 | 67 | # Compile Flags 68 | if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") 69 | add_compile_options(/Gy) 70 | add_compile_options(/Zc:inline) 71 | endif() 72 | endif() 73 | 74 | # Subdirectory 75 | add_subdirectory("lib") 76 | add_subdirectory("src") 77 | 78 | # Test 79 | if(UVAR_BUILD_TEST) 80 | # add_subdirectory("test") 81 | endif() 82 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "configurePresets": [ 4 | { 5 | "name": "windows-base", 6 | "hidden": true, 7 | "generator": "Ninja", 8 | "binaryDir": "${sourceDir}/.build/${presetName}", 9 | "installDir": "${sourceDir}/.install/${presetName}", 10 | "cacheVariables": { 11 | "CMAKE_C_COMPILER": "cl.exe", 12 | "CMAKE_CXX_COMPILER": "cl.exe" 13 | }, 14 | "condition": { 15 | "type": "equals", 16 | "lhs": "${hostSystemName}", 17 | "rhs": "Windows" 18 | } 19 | }, 20 | { 21 | "name": "x64-debug", 22 | "displayName": "x64 Debug", 23 | "inherits": "windows-base", 24 | "architecture": { 25 | "value": "x64", 26 | "strategy": "external" 27 | }, 28 | "cacheVariables": { 29 | "CMAKE_BUILD_TYPE": "Debug" 30 | } 31 | }, 32 | { 33 | "name": "x64-release", 34 | "displayName": "x64 Release", 35 | "inherits": "x64-debug", 36 | "cacheVariables": { 37 | "CMAKE_BUILD_TYPE": "Release" 38 | } 39 | }, 40 | { 41 | "name": "x86-debug", 42 | "displayName": "x86 Debug", 43 | "inherits": "windows-base", 44 | "architecture": { 45 | "value": "x86", 46 | "strategy": "external" 47 | }, 48 | "cacheVariables": { 49 | "CMAKE_BUILD_TYPE": "Debug" 50 | } 51 | }, 52 | { 53 | "name": "x86-release", 54 | "displayName": "x86 Release", 55 | "inherits": "x86-debug", 56 | "cacheVariables": { 57 | "CMAKE_BUILD_TYPE": "Release" 58 | } 59 | }, 60 | { 61 | "name": "x86-MinSizeRel", 62 | "displayName": "x86 MinSizeRel", 63 | "inherits": "x86-debug", 64 | "cacheVariables": { 65 | "CMAKE_BUILD_TYPE": "MinSizeRel" 66 | } 67 | }, 68 | { 69 | "name": "x86-RelWithDebInfo", 70 | "displayName": "x86 RelWithDebInfo", 71 | "inherits": "x86-debug", 72 | "cacheVariables": { 73 | "CMAKE_BUILD_TYPE": "RelWithDebInfo" 74 | } 75 | } 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CMVS_Tools 2 | Tools For Purple software's CMVS Engine. 3 | 4 | ## File Extension 5 | `.ps2` `.ps3` `.pb3` `.cpz` 6 | 7 | ## Tools 8 | ### PS3_TextEditor 9 | - export msg text from `.ps3` `.ps2` file 10 | - import msg text to `.ps3` `.ps2` file 11 | 12 | ### PS3_Cryptor 13 | - Decrypt `.ps3` `.ps2` file 14 | - Encrypt `.ps3` `.ps2` file (fake encryption) 15 | 16 | ### MGV_Editor 17 | - unpack `.ogv` video file and `.ogg` audio file from `.mgv` file 18 | - replace `.ogv` video file 19 | 20 | ### VFS_Extract 21 | extract file by file name via hook the function that create pack stream to get the pack stream obj. 22 | 23 | ### VFS_Hook 24 | patch files without repack via hook the interface for reading files. 25 | 26 | ### CMV6_Hook 27 | - [x] unpack .CMV 28 | - [x] decode .JBPD (dynamic for now) 29 | - [x] decode .JBPD to BitMap 30 | - [x] decode .JBPD to WebP 31 | - [x] repack .CMV 32 | - [x] play .CMV with WebPDecoder 33 | 34 | ## Essays 35 | [[CMVS] 文件读取分析](https://github.com/Dir-A/Dir-A_Essays_MD/blob/main/Reverse/%5BCMVS%5D%20%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E5%88%86%E6%9E%90/CMVS%20%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E5%88%86%E6%9E%90.md) 36 | [[CMVS] 紫社引擎 折腾日记 Purple software](https://github.com/Dir-A/Dir-A_Essays_MD/blob/main/Reverse/%5BCMVS%5D%20%E7%B4%AB%E7%A4%BE%E5%BC%95%E6%93%8E%20%E6%8A%98%E8%85%BE%E6%97%A5%E8%AE%B0%20Purple%20software/%5BCMVS%5D%20%E7%B4%AB%E7%A4%BE%E5%BC%95%E6%93%8E%20%E6%8A%98%E8%85%BE%E6%97%A5%E8%AE%B0%20Purple%20software.md) 37 | 38 | ## More 39 | Check the details of reverse analysis [note](/etc) 40 | 41 | ## Tested 42 | クナド国記 PKG 43 | 青春フラジャイル PKG 44 | リアライブ PKG 45 | アオイトリ PKG 46 | アマツツミ PKG 47 | ハピメアFD ハピメアWパック PKG 48 | クロノクロック PKG 49 | ハピメア PKG 50 | しあわせ家族部 PKG 51 | 未来ノスタルジア PKG 52 | -------------------------------------------------------------------------------- /etc/CMVS_Symbol.json: -------------------------------------------------------------------------------- 1 | { 2 | "game_title": "クナド国記", 3 | "game_version": "1.0", 4 | "game_engine": "CMVS", 5 | "export_time": "2023-11-21 16:41:27.016977", 6 | "func_list": [ 7 | { 8 | "name": "CMVS::401000::Ctor", 9 | "addr": "0x401000" 10 | }, 11 | { 12 | "name": "CMVS::PackCoder::CPZ1::Ctor", 13 | "addr": "0x40d430" 14 | }, 15 | { 16 | "name": "CMVS::PackCoder::CPZ1::Dector", 17 | "addr": "0x40d4a0" 18 | }, 19 | { 20 | "name": "CMVS::PackCoder::CPZ1::ReadRes", 21 | "addr": "0x40d520" 22 | }, 23 | { 24 | "name": "CMVS::PackCoder::CPZ1::GetIndex", 25 | "addr": "0x40d630" 26 | }, 27 | { 28 | "name": "CMVS::PackCoder::CPZ1::Decode", 29 | "addr": "0x40d780" 30 | }, 31 | { 32 | "name": "CMVS::PackCoder::CPZ2::Ctor", 33 | "addr": "0x40d7d0" 34 | }, 35 | { 36 | "name": "CMVS::PackCoder::CPZ2::Dector", 37 | "addr": "0x40d850" 38 | }, 39 | { 40 | "name": "CMVS::PackCoder::CPZ2::ReadRes", 41 | "addr": "0x40d8b0" 42 | }, 43 | { 44 | "name": "CMVS::PackCoder::CPZ2::GetIndex", 45 | "addr": "0x40da60" 46 | }, 47 | { 48 | "name": "CMVS::PackCoder::CPZ2::Decode_R0", 49 | "addr": "0x40dc50" 50 | }, 51 | { 52 | "name": "CMVS::PackCoder::CPZ2::Decode_R1", 53 | "addr": "0x40dd60" 54 | }, 55 | { 56 | "name": "CMVS::PackCoder::CPZ6::Ctor", 57 | "addr": "0x40de30" 58 | }, 59 | { 60 | "name": "CMVS::PackCoder::CPZ6::Dector", 61 | "addr": "0x40de90" 62 | }, 63 | { 64 | "name": "CMVS::PackCoder::CPZ6::40DEF0", 65 | "addr": "0x40def0" 66 | }, 67 | { 68 | "name": "CMVS::PackCoder::CPZ6::ReadRes", 69 | "addr": "0x40df30" 70 | }, 71 | { 72 | "name": "CMVS::PackCoder::CPZ6::GetIndex", 73 | "addr": "0x40e1f0" 74 | }, 75 | { 76 | "name": "CMVS::PackCoder::CPZ6::ReadIndex", 77 | "addr": "0x40e230" 78 | }, 79 | { 80 | "name": "CMVS::PackCoder::CPZ6::40E710", 81 | "addr": "0x40e710" 82 | }, 83 | { 84 | "name": "CMVS::PackCoder::CPZ6::40E810", 85 | "addr": "0x40e810" 86 | }, 87 | { 88 | "name": "CMVS::PackCoder::CPZ6_B::Ctor", 89 | "addr": "0x40e830" 90 | }, 91 | { 92 | "name": "CMVS::PackCoder::CPZ6_B::Dector", 93 | "addr": "0x40e890" 94 | }, 95 | { 96 | "name": "CMVS::PackCoder::CPZ6_B::40E8F0", 97 | "addr": "0x40e8f0" 98 | }, 99 | { 100 | "name": "CMVS::PackCoder::CPZ6_B::ReadFile", 101 | "addr": "0x40e970" 102 | }, 103 | { 104 | "name": "CMVS::PackCoder::CPZ6_B::ReadRes", 105 | "addr": "0x40e990" 106 | }, 107 | { 108 | "name": "CMVS::PackCoder::CPZ6_B::GetIndex", 109 | "addr": "0x40ec50" 110 | }, 111 | { 112 | "name": "CMVS::PackCoder::CPZ6_B::ReadIndex", 113 | "addr": "0x40ec90" 114 | }, 115 | { 116 | "name": "CMVS::PackCoder::CPZ6_B::DecodeRes", 117 | "addr": "0x40f170" 118 | }, 119 | { 120 | "name": "CMVS::PackCoder::CPZ7::Ctor", 121 | "addr": "0x40f320" 122 | }, 123 | { 124 | "name": "CMVS::PackCoder::CPZ7::Dector", 125 | "addr": "0x40f380" 126 | }, 127 | { 128 | "name": "CMVS::PackCoder::CPZ7::40F3E0", 129 | "addr": "0x40f3e0" 130 | }, 131 | { 132 | "name": "CMVS::PackCoder::CPZ7::ReadRes", 133 | "addr": "0x40f460" 134 | }, 135 | { 136 | "name": "CMVS::PackCoder::CPZ7::ReadRes_1", 137 | "addr": "0x40f720" 138 | }, 139 | { 140 | "name": "CMVS::PackCoder::CPZ7::GetIndex", 141 | "addr": "0x40f980" 142 | }, 143 | { 144 | "name": "CMVS::PackCoder::CPZ7::ReadIndex", 145 | "addr": "0x40f9c0" 146 | }, 147 | { 148 | "name": "CMVS::PackCoder::CPZ7::DecodeRes", 149 | "addr": "0x40ff40" 150 | }, 151 | { 152 | "name": "CMVS::PackCoder::CPZ7::4100F0", 153 | "addr": "0x4100f0" 154 | }, 155 | { 156 | "name": "CMVS::PackCoder::CPZ7_B::Ctor", 157 | "addr": "0x410110" 158 | }, 159 | { 160 | "name": "CMVS::PackCoder::CPZ7_B::Dector", 161 | "addr": "0x410170" 162 | }, 163 | { 164 | "name": "CMVS::PackCoder::CPZ7_B::4101D0", 165 | "addr": "0x4101d0" 166 | }, 167 | { 168 | "name": "CMVS::PackCoder::CPZ7_B::410310", 169 | "addr": "0x410310" 170 | }, 171 | { 172 | "name": "CMVS::PackCoder::CPZ7_B::ReadFile", 173 | "addr": "0x410350" 174 | }, 175 | { 176 | "name": "CMVS::PackCoder::CPZ7_B::GetIndex", 177 | "addr": "0x410610" 178 | }, 179 | { 180 | "name": "CMVS::PackCoder::CPZ7_B::ReadIndex", 181 | "addr": "0x410650" 182 | }, 183 | { 184 | "name": "CMVS::PackCoder::CPZ7_B::410C00", 185 | "addr": "0x410c00" 186 | }, 187 | { 188 | "name": "CMVS::PackCoder::CPZ7_B::410C30", 189 | "addr": "0x410c30" 190 | }, 191 | { 192 | "name": "CMVS::GetHeigh_S", 193 | "addr": "0x411b80" 194 | }, 195 | { 196 | "name": "CMVS::EnumSMonitor::Proc", 197 | "addr": "0x411c20" 198 | }, 199 | { 200 | "name": "CMVS::EnumSMonitor", 201 | "addr": "0x411fe0" 202 | }, 203 | { 204 | "name": "CMVS::Video::MGV::Dctor", 205 | "addr": "0x4123e0" 206 | }, 207 | { 208 | "name": "CMVS::Video::MGV::Loader", 209 | "addr": "0x412570" 210 | }, 211 | { 212 | "name": "CMVS::Video::MGV::Decoder", 213 | "addr": "0x416900" 214 | }, 215 | { 216 | "name": "CMVS::Video::MGV::Dctor_0", 217 | "addr": "0x416b70" 218 | }, 219 | { 220 | "name": "CMVS::Video::MGV::DecFrame_1", 221 | "addr": "0x416ec0" 222 | }, 223 | { 224 | "name": "CMVS::Video::MGV::DecFrame_0", 225 | "addr": "0x416f70" 226 | }, 227 | { 228 | "name": "CMVS::Video::MGV::New_Play_Thread", 229 | "addr": "0x417020" 230 | }, 231 | { 232 | "name": "CMVS::Video::MGV::Player_Thread", 233 | "addr": "0x417090" 234 | }, 235 | { 236 | "name": "CMVS::Set::Instance", 237 | "addr": "0x418140" 238 | }, 239 | { 240 | "name": "CMVS::Set::EngineDir", 241 | "addr": "0x418150" 242 | }, 243 | { 244 | "name": "CMVS::FindFile", 245 | "addr": "0x419680" 246 | }, 247 | { 248 | "name": "CMVS::GetFileSize", 249 | "addr": "0x4196e0" 250 | }, 251 | { 252 | "name": "CMVS::ReadData", 253 | "addr": "0x419740" 254 | }, 255 | { 256 | "name": "CMVS::ReadAllData", 257 | "addr": "0x4198f0" 258 | }, 259 | { 260 | "name": "CMVS::GetPackVersion", 261 | "addr": "0x4199d0" 262 | }, 263 | { 264 | "name": "CMVS::HPET::GetFlag", 265 | "addr": "0x4199e0" 266 | }, 267 | { 268 | "name": "CMVS::GetHWND", 269 | "addr": "0x419ac0" 270 | }, 271 | { 272 | "name": "CMVS::GetFontSJISFlag", 273 | "addr": "0x419ad0" 274 | }, 275 | { 276 | "name": "CMVS::Str::ToInt", 277 | "addr": "0x419ae0" 278 | }, 279 | { 280 | "name": "CMVS::Str::ToFloat", 281 | "addr": "0x419bc0" 282 | }, 283 | { 284 | "name": "CMVS::GetFontName", 285 | "addr": "0x419c70" 286 | }, 287 | { 288 | "name": "CMVS::EnumFont", 289 | "addr": "0x419c90" 290 | }, 291 | { 292 | "name": "CMVS::Timer::Update", 293 | "addr": "0x419d20" 294 | }, 295 | { 296 | "name": "CMVS::GetHeigh", 297 | "addr": "0x419d60" 298 | }, 299 | { 300 | "name": "CMVS::GetWidth", 301 | "addr": "0x419d70" 302 | }, 303 | { 304 | "name": "CMVS::GetSysTime", 305 | "addr": "0x419e00" 306 | }, 307 | { 308 | "name": "CMVS::SaveSomething", 309 | "addr": "0x419e40" 310 | }, 311 | { 312 | "name": "CMVS::InitTimer", 313 | "addr": "0x419ee0" 314 | }, 315 | { 316 | "name": "CMVS::Timer::419F20", 317 | "addr": "0x419f20" 318 | }, 319 | { 320 | "name": "CMVS::Timer::419F70", 321 | "addr": "0x419f70" 322 | }, 323 | { 324 | "name": "CMVS::Timer::419FC0", 325 | "addr": "0x419fc0" 326 | }, 327 | { 328 | "name": "CMVS::SetPackVersion", 329 | "addr": "0x41a030" 330 | }, 331 | { 332 | "name": "CMVS::HPET::Init", 333 | "addr": "0x41a040" 334 | }, 335 | { 336 | "name": "CMVS::SaveHWND", 337 | "addr": "0x41a060" 338 | }, 339 | { 340 | "name": "CMVS::SetDefFontName", 341 | "addr": "0x41a070" 342 | }, 343 | { 344 | "name": "CMVS::Win32::SetRect", 345 | "addr": "0x41a090" 346 | }, 347 | { 348 | "name": "CMVS::FontSJIS", 349 | "addr": "0x41a0b0" 350 | }, 351 | { 352 | "name": "CMVS::Str::IsSjis", 353 | "addr": "0x41a0c0" 354 | }, 355 | { 356 | "name": "CMVS::Str::HasChar", 357 | "addr": "0x41a0f0" 358 | }, 359 | { 360 | "name": "CMVS::Str::Cmp", 361 | "addr": "0x41a140" 362 | }, 363 | { 364 | "name": "CMVS::Str::Cmp2", 365 | "addr": "0x41a1b0" 366 | }, 367 | { 368 | "name": "CMVS::Str::CtrlChar", 369 | "addr": "0x41a220" 370 | }, 371 | { 372 | "name": "CMVS::Str::FindChar", 373 | "addr": "0x41a330" 374 | }, 375 | { 376 | "name": "CMVS::Str::SplitToNumber", 377 | "addr": "0x41a3d0" 378 | }, 379 | { 380 | "name": "CMVS::EnumFontProc", 381 | "addr": "0x41a510" 382 | }, 383 | { 384 | "name": "CMVS::Timer::Now", 385 | "addr": "0x41a540" 386 | }, 387 | { 388 | "name": "CMVS::OBJDesBuffer2", 389 | "addr": "0x41a640" 390 | }, 391 | { 392 | "name": "CMVS::OBJDesBuffer", 393 | "addr": "0x41a6a0" 394 | }, 395 | { 396 | "name": "CMVS::Des", 397 | "addr": "0x41a6f0" 398 | }, 399 | { 400 | "name": "CMVS::Base_0::Ctor", 401 | "addr": "0x41aa60" 402 | }, 403 | { 404 | "name": "CMVS::Set::KeyConfigFilePath", 405 | "addr": "0x41ab80" 406 | }, 407 | { 408 | "name": "CMVS::Win32::WndProc", 409 | "addr": "0x41aba0" 410 | }, 411 | { 412 | "name": "CMVS::Win32::RegClass", 413 | "addr": "0x41ad40" 414 | }, 415 | { 416 | "name": "CMVS::Win32::CreateWindow", 417 | "addr": "0x41adf0" 418 | }, 419 | { 420 | "name": "CMVS::Win32::SetTitle", 421 | "addr": "0x41aee0" 422 | }, 423 | { 424 | "name": "CMVS::CreateMutexOBJ", 425 | "addr": "0x41af50" 426 | }, 427 | { 428 | "name": "CMVS::CreateMutex", 429 | "addr": "0x41afa0" 430 | }, 431 | { 432 | "name": "CMVS::MainFrame::Ctor", 433 | "addr": "0x41b160" 434 | }, 435 | { 436 | "name": "CMVS::MainFrame::Dector", 437 | "addr": "0x41b1d0" 438 | }, 439 | { 440 | "name": "CMVS::RunVM", 441 | "addr": "0x41b1e0" 442 | }, 443 | { 444 | "name": "CMVS::InitConfig", 445 | "addr": "0x41b520" 446 | }, 447 | { 448 | "name": "CMVS::InitEngine", 449 | "addr": "0x41d510" 450 | }, 451 | { 452 | "name": "CMVS::Base::Ctor", 453 | "addr": "0x424850" 454 | }, 455 | { 456 | "name": "CMVS::OBJDes2", 457 | "addr": "0x4250a0" 458 | }, 459 | { 460 | "name": "CMVS::MainFrameWnd::Ctor", 461 | "addr": "0x426430" 462 | }, 463 | { 464 | "name": "CMVS::InitRect", 465 | "addr": "0x426a10" 466 | }, 467 | { 468 | "name": "CMVS::GetAppPath", 469 | "addr": "0x426fa0" 470 | }, 471 | { 472 | "name": "CMVS::Win32::TranslateAccelerator", 473 | "addr": "0x426fc0" 474 | }, 475 | { 476 | "name": "CMVS::Win32::Command", 477 | "addr": "0x426fe0" 478 | }, 479 | { 480 | "name": "CMVS::OBJDes3", 481 | "addr": "0x427590" 482 | }, 483 | { 484 | "name": "CMVS::Win32::Init", 485 | "addr": "0x428750" 486 | }, 487 | { 488 | "name": "CMVS::Win32::Command_", 489 | "addr": "0x428850" 490 | }, 491 | { 492 | "name": "CMVS::GetWidth_S", 493 | "addr": "0x428ff0" 494 | }, 495 | { 496 | "name": "CMVS::SetScreenRect", 497 | "addr": "0x42ad70" 498 | }, 499 | { 500 | "name": "CMVS::GetSize", 501 | "addr": "0x432c30" 502 | }, 503 | { 504 | "name": "CMVS::Video::GetScreenHeigh", 505 | "addr": "0x432c50" 506 | }, 507 | { 508 | "name": "CMVS::GeSIZE", 509 | "addr": "0x432c60" 510 | }, 511 | { 512 | "name": "CMVS::Video::GetScreenWidth", 513 | "addr": "0x432c90" 514 | }, 515 | { 516 | "name": "CMVS::RegUnPath", 517 | "addr": "0x432ed0" 518 | }, 519 | { 520 | "name": "CMVS::VM::DrawBackLog_Sub", 521 | "addr": "0x439080" 522 | }, 523 | { 524 | "name": "CMVS::Texture::Ctor", 525 | "addr": "0x43b080" 526 | }, 527 | { 528 | "name": "CMVS::Image::Decoder", 529 | "addr": "0x43f380" 530 | }, 531 | { 532 | "name": "CMVS::Image::Decode::BMP", 533 | "addr": "0x43f4b0" 534 | }, 535 | { 536 | "name": "CMVS::Image::Decode::MSK", 537 | "addr": "0x43f5b0" 538 | }, 539 | { 540 | "name": "CMVS::Image::Decode::PB2", 541 | "addr": "0x43f630" 542 | }, 543 | { 544 | "name": "CMVS::Image::Decode::PB3", 545 | "addr": "0x43f7c0" 546 | }, 547 | { 548 | "name": "CMVS::Image::Decode::PNG", 549 | "addr": "0x43fae0" 550 | }, 551 | { 552 | "name": "CMVS::Image::Reader", 553 | "addr": "0x43fdf0" 554 | }, 555 | { 556 | "name": "CMVS::RegImagePath", 557 | "addr": "0x4401c0" 558 | }, 559 | { 560 | "name": "CMVS::Image::ClearCache", 561 | "addr": "0x440720" 562 | }, 563 | { 564 | "name": "CMVS::Image::GetCacheData", 565 | "addr": "0x440920" 566 | }, 567 | { 568 | "name": "CMVS::Video::CMV::Dector", 569 | "addr": "0x440a50" 570 | }, 571 | { 572 | "name": "CMVS::Video::CMV::Loader", 573 | "addr": "0x440ca0" 574 | }, 575 | { 576 | "name": "CMVS::Video::Reader::V3", 577 | "addr": "0x441320" 578 | }, 579 | { 580 | "name": "CMVS::Video::Reader::V1", 581 | "addr": "0x4414b0" 582 | }, 583 | { 584 | "name": "CMVS::RegVideoPath", 585 | "addr": "0x4415f0" 586 | }, 587 | { 588 | "name": "CMVS::ImageVideo::Ctor", 589 | "addr": "0x441910" 590 | }, 591 | { 592 | "name": "CMVS::ImageVideo::Dector", 593 | "addr": "0x441990" 594 | }, 595 | { 596 | "name": "CMVS::Video::CMV::DecFrame", 597 | "addr": "0x441b20" 598 | }, 599 | { 600 | "name": "CMVS::ImageVideo::Loader", 601 | "addr": "0x442c60" 602 | }, 603 | { 604 | "name": "CMVS::Video::CMV::Reader_Flow", 605 | "addr": "0x442ef0" 606 | }, 607 | { 608 | "name": "CMVS::Video::CMV::New_Play_Thread", 609 | "addr": "0x4437c0" 610 | }, 611 | { 612 | "name": "CMVS::Video::CMV::Player_Thread", 613 | "addr": "0x443820" 614 | }, 615 | { 616 | "name": "CMVS::443910::Ctor", 617 | "addr": "0x443910" 618 | }, 619 | { 620 | "name": "CMVS::4439F0::Dector", 621 | "addr": "0x4439f0" 622 | }, 623 | { 624 | "name": "CMVS::Image::Loader", 625 | "addr": "0x4467a0" 626 | }, 627 | { 628 | "name": "CMVS::VM::CreateFont", 629 | "addr": "0x461940" 630 | }, 631 | { 632 | "name": "CMVS::Draw::Char", 633 | "addr": "0x461b80" 634 | }, 635 | { 636 | "name": "CMVS::VM::DrawTextBox_Sub", 637 | "addr": "0x463890" 638 | }, 639 | { 640 | "name": "CMVS::VM::DrawTextBox_Fixed_Sub", 641 | "addr": "0x464a60" 642 | }, 643 | { 644 | "name": "CMVS::PackCoder::CPZ3::Ctor", 645 | "addr": "0x469530" 646 | }, 647 | { 648 | "name": "CMVS::PackCoder::CPZ3::Dector", 649 | "addr": "0x4695b0" 650 | }, 651 | { 652 | "name": "CMVS::PackCoder::CPZ3::ReadRes", 653 | "addr": "0x469610" 654 | }, 655 | { 656 | "name": "CMVS::PackCoder::CPZ3::GetIndex", 657 | "addr": "0x4697b0" 658 | }, 659 | { 660 | "name": "CMVS::PackCoder::CPZ3::Decode_R0", 661 | "addr": "0x469970" 662 | }, 663 | { 664 | "name": "CMVS::PackCoder::CPZ3::Decode_R1", 665 | "addr": "0x4699b0" 666 | }, 667 | { 668 | "name": "CMVS::PackCoder::CPZ3::469A80", 669 | "addr": "0x469a80" 670 | }, 671 | { 672 | "name": "CMVS::Str::ToLowerCase", 673 | "addr": "0x469aa0" 674 | }, 675 | { 676 | "name": "CMVS::PackCoder::CPZ5::Ctor", 677 | "addr": "0x469af0" 678 | }, 679 | { 680 | "name": "CMVS::PackCoder::CPZ5::Dector", 681 | "addr": "0x469b50" 682 | }, 683 | { 684 | "name": "CMVS::PackCoder::CPZ5::Decode_R0", 685 | "addr": "0x469bb0" 686 | }, 687 | { 688 | "name": "CMVS::PackCoder::CPZ5::ReadRes", 689 | "addr": "0x469bf0" 690 | }, 691 | { 692 | "name": "CMVS::PackCoder::CPZ5::ReadRes_1", 693 | "addr": "0x469e40" 694 | }, 695 | { 696 | "name": "CMVS::PackCoder::CPZ5::GetIndex", 697 | "addr": "0x46a020" 698 | }, 699 | { 700 | "name": "CMVS::PackCoder::CPZ5::ReadIndex", 701 | "addr": "0x46a060" 702 | }, 703 | { 704 | "name": "CMVS::PackCoder::CPZ5::Decode_R1", 705 | "addr": "0x46a520" 706 | }, 707 | { 708 | "name": "CMVS::PackCoder::CPZ5::Decode_R2", 709 | "addr": "0x46a6a0" 710 | }, 711 | { 712 | "name": "CMVS::PackCoder::CPZ5_B::Ctor", 713 | "addr": "0x46a780" 714 | }, 715 | { 716 | "name": "CMVS::PackCoder::CPZ5_B::Dector", 717 | "addr": "0x46a7e0" 718 | }, 719 | { 720 | "name": "CMVS::PackCoder::CPZ5_B::GetIndex", 721 | "addr": "0x46a840" 722 | }, 723 | { 724 | "name": "CMVS::PackCoder::CPZ5_B::ReadIndex", 725 | "addr": "0x46a880" 726 | }, 727 | { 728 | "name": "CMVS::PackCoder::CPZ5_B::Decode_R0", 729 | "addr": "0x46ad50" 730 | }, 731 | { 732 | "name": "CMVS::PackCoder::CPZ5_B::Decode_R1", 733 | "addr": "0x46ad90" 734 | }, 735 | { 736 | "name": "CMVS::PackCoder::CPZ5_C::Ctor", 737 | "addr": "0x46ae90" 738 | }, 739 | { 740 | "name": "CMVS::PackCoder::CPZ5_C::Dector", 741 | "addr": "0x46aef0" 742 | }, 743 | { 744 | "name": "CMVS::PackCoder::CPZ5_C::ReadRes", 745 | "addr": "0x46af50" 746 | }, 747 | { 748 | "name": "CMVS::PackCoder::CPZ5_C::GetIndex", 749 | "addr": "0x46b200" 750 | }, 751 | { 752 | "name": "CMVS::PackCoder::CPZ5_C::ReadIndex", 753 | "addr": "0x46b240" 754 | }, 755 | { 756 | "name": "CMVS::PackCoder::CPZ5_C::Decode_R0", 757 | "addr": "0x46b710" 758 | }, 759 | { 760 | "name": "CMVS::PackCoder::CPZ5_D::Ctor", 761 | "addr": "0x46b8c0" 762 | }, 763 | { 764 | "name": "CMVS::PackCoder::CPZ5_D::Dector", 765 | "addr": "0x46b920" 766 | }, 767 | { 768 | "name": "CMVS::PackCoder::CPZ5_D::Decode_R0", 769 | "addr": "0x46b980" 770 | }, 771 | { 772 | "name": "CMVS::PackCoder::CPZ5_D::ReadRes", 773 | "addr": "0x46ba00" 774 | }, 775 | { 776 | "name": "CMVS::PackCoder::CPZ5_D::GetIndex", 777 | "addr": "0x46bc60" 778 | }, 779 | { 780 | "name": "CMVS::PackCoder::CPZ5_D::ReadIndex", 781 | "addr": "0x46bca0" 782 | }, 783 | { 784 | "name": "CMVS::PackCoder::CPZ5_X::Ctor", 785 | "addr": "0x46c170" 786 | }, 787 | { 788 | "name": "CMVS::PackCoder::CPZ5_X::Dector", 789 | "addr": "0x46c1d0" 790 | }, 791 | { 792 | "name": "CMVS::PackCoder::CPZ5_X::Decode_R0", 793 | "addr": "0x46c230" 794 | }, 795 | { 796 | "name": "CMVS::PackCoder::CPZ5_X::ReadRes", 797 | "addr": "0x46c2b0" 798 | }, 799 | { 800 | "name": "CMVS::PackCoder::CPZ5_X::GetIndex", 801 | "addr": "0x46c560" 802 | }, 803 | { 804 | "name": "CMVS::PackCoder::CPZ5_X::ReadIndex", 805 | "addr": "0x46c5a0" 806 | }, 807 | { 808 | "name": "CMVS::PackCoder::CPZ5_X::Decode_R1", 809 | "addr": "0x46ca70" 810 | }, 811 | { 812 | "name": "CMVS::PackCoder::CPZ5_X::Decode_R2", 813 | "addr": "0x46cc20" 814 | }, 815 | { 816 | "name": "CMVS::PackCoder::CPZ5_X::46CD20", 817 | "addr": "0x46cd20" 818 | }, 819 | { 820 | "name": "CMVS::PackCoder::Base::SetVtable_Ctor", 821 | "addr": "0x46cd40" 822 | }, 823 | { 824 | "name": "CMVS::PackCoder::Base::SetVtable_Dector", 825 | "addr": "0x46cd50" 826 | }, 827 | { 828 | "name": "CMVS::PackCoder::Base_Dector", 829 | "addr": "0x46cd60" 830 | }, 831 | { 832 | "name": "CMVS::Script::Reader", 833 | "addr": "0x46ce10" 834 | }, 835 | { 836 | "name": "CMVS::RegCommPath", 837 | "addr": "0x46cf90" 838 | }, 839 | { 840 | "name": "CMVS::MainScriptCtrl::Ctor", 841 | "addr": "0x46d2b0" 842 | }, 843 | { 844 | "name": "CMVS::ParseOpcode", 845 | "addr": "0x46db80" 846 | }, 847 | { 848 | "name": "CMVS::Decompress", 849 | "addr": "0x470450" 850 | }, 851 | { 852 | "name": "CMVS::Compress", 853 | "addr": "0x470560" 854 | }, 855 | { 856 | "name": "CMVS::ScriptCommand::Ctor", 857 | "addr": "0x470b70" 858 | }, 859 | { 860 | "name": "CMVS::VM::GetStr", 861 | "addr": "0x470de0" 862 | }, 863 | { 864 | "name": "CMVS::VM::Adjust", 865 | "addr": "0x471380" 866 | }, 867 | { 868 | "name": "CMVS::ParseOpcode_Sub", 869 | "addr": "0x472fa0" 870 | }, 871 | { 872 | "name": "CMVS::SaveData", 873 | "addr": "0x477560" 874 | }, 875 | { 876 | "name": "CMVS::Script::Loader", 877 | "addr": "0x478240" 878 | }, 879 | { 880 | "name": "CMVS::VM::RegImgPath_Un0", 881 | "addr": "0x47b680" 882 | }, 883 | { 884 | "name": "CMVS::VM::RegImgPath", 885 | "addr": "0x47b700" 886 | }, 887 | { 888 | "name": "CMVS::VM::RegImgPath_Un1", 889 | "addr": "0x47b7b0" 890 | }, 891 | { 892 | "name": "CMVS::VM::RegVideoPath", 893 | "addr": "0x47b830" 894 | }, 895 | { 896 | "name": "CMVS::VM::RegVideoPath_Un0", 897 | "addr": "0x47b8e0" 898 | }, 899 | { 900 | "name": "CMVS::VM::RegCommPath_Un0", 901 | "addr": "0x47b960" 902 | }, 903 | { 904 | "name": "CMVS::VM::RegBgmPath", 905 | "addr": "0x47ba10" 906 | }, 907 | { 908 | "name": "CMVS::VM::RegxxPath_Un1", 909 | "addr": "0x47ba90" 910 | }, 911 | { 912 | "name": "CMVS::VM::RegXXPath_Un0", 913 | "addr": "0x47bb40" 914 | }, 915 | { 916 | "name": "CMVS::VM::RegScriptPath", 917 | "addr": "0x47bc10" 918 | }, 919 | { 920 | "name": "CMVS::VM::RegCommPath_Un1", 921 | "addr": "0x47bcc0" 922 | }, 923 | { 924 | "name": "CMVS::VM::GetAppPath", 925 | "addr": "0x47bd40" 926 | }, 927 | { 928 | "name": "CMVS::VM::RegVoicePath", 929 | "addr": "0x47bd80" 930 | }, 931 | { 932 | "name": "CMVS::VM::RegCommPath_Un2", 933 | "addr": "0x47be30" 934 | }, 935 | { 936 | "name": "CMVS::VM::RegSePath", 937 | "addr": "0x47beb0" 938 | }, 939 | { 940 | "name": "CMVS::VM::RegCommPath_Un3", 941 | "addr": "0x47bf60" 942 | }, 943 | { 944 | "name": "CMVS::VM::CImage_Play", 945 | "addr": "0x47c630" 946 | }, 947 | { 948 | "name": "CMVS::VM::StrToInt", 949 | "addr": "0x47d560" 950 | }, 951 | { 952 | "name": "CMVS::VM::LoadScript", 953 | "addr": "0x485fb0" 954 | }, 955 | { 956 | "name": "CMVS::VM::DrawBackLog", 957 | "addr": "0x488530" 958 | }, 959 | { 960 | "name": "CMVS::VM::DrawTextBox", 961 | "addr": "0x488e70" 962 | }, 963 | { 964 | "name": "CMVS::VM::MGV_Play", 965 | "addr": "0x489240" 966 | }, 967 | { 968 | "name": "CMVS::VM::CMV_Play", 969 | "addr": "0x489430" 970 | }, 971 | { 972 | "name": "CMVS::Audio::Reader", 973 | "addr": "0x48adb0" 974 | }, 975 | { 976 | "name": "CMVS::Audio::Loader_", 977 | "addr": "0x48afc0" 978 | }, 979 | { 980 | "name": "CMVS::Audio::Loader", 981 | "addr": "0x48bc00" 982 | }, 983 | { 984 | "name": "CMVS::CFontEnumFontProc", 985 | "addr": "0x492120" 986 | }, 987 | { 988 | "name": "CMVS::CFontEnumFont", 989 | "addr": "0x492210" 990 | } 991 | ] 992 | } -------------------------------------------------------------------------------- /lib/CMVS/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project 2 | project(CMVS) 3 | 4 | # Source File Path 5 | list(APPEND "${PROJECT_NAME}_SRC_FILE" 6 | "src/CMVS/MGV_Editor.cpp" 7 | "src/CMVS/PS3_Cryptor.cpp" 8 | "src/CMVS/PS3_TextEditor.cpp" ) 9 | 10 | # Source File Only x32 11 | if (CMAKE_SIZEOF_VOID_P EQUAL 4) 12 | list(APPEND "${PROJECT_NAME}_SRC_FILE" 13 | "src/CMVS/VFS_Hook.cpp" 14 | "src/CMVS/VFS_Extract.cpp" ) 15 | endif() 16 | 17 | # Set Library 18 | add_library("${PROJECT_NAME}" "${${PROJECT_NAME}_SRC_FILE}") 19 | target_include_directories("${PROJECT_NAME}" INTERFACE "src") 20 | target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_23) 21 | target_compile_definitions("${PROJECT_NAME}" PRIVATE UNICODE _UNICODE) 22 | target_compile_options("${PROJECT_NAME}" PRIVATE "$<$:/source-charset:utf-8>") 23 | 24 | # Add Library 25 | target_link_libraries("${PROJECT_NAME}" PRIVATE Rut RxHook) 26 | target_link_libraries("${PROJECT_NAME}" PRIVATE "${ROOT_DIR}/third/libwebp/lib.X86/libwebp.lib") -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV6_Coder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "CMV6_Hook_Def.h" 8 | 9 | 10 | namespace CMVS::CMV 11 | { 12 | static BITMAPFILEHEADER sg_BitMapFile = { 0 }; 13 | static BITMAPINFOHEADER sg_BitMapInfo = { 0 }; 14 | 15 | static ImageSecData sg_SecData = { 0 }; 16 | static ImageSecWidthBites sg_SecBites = { 0 }; 17 | 18 | static bool sg_isLossless = true; 19 | static float sg_dwWebPQuality = 75.0F; 20 | 21 | 22 | //Fast Use To Dynamic Dump Frame 23 | bool SaveAsBmp(wchar_t* wpFilePath, uint8_t* pBitMapBuffer, uint32_t szFile) 24 | { 25 | lstrcatW(wpFilePath, L".bmp"); 26 | const HANDLE hfile = CreateFileW(wpFilePath, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); 27 | if (hfile == INVALID_HANDLE_VALUE) { return false; } 28 | 29 | WriteFile(hfile, &sg_BitMapFile, sizeof(BITMAPFILEHEADER), nullptr, nullptr); 30 | WriteFile(hfile, &sg_BitMapInfo, sizeof(BITMAPINFOHEADER), nullptr, nullptr); 31 | WriteFile(hfile, pBitMapBuffer, szFile, nullptr, nullptr); 32 | FlushFileBuffers(hfile); 33 | CloseHandle(hfile); 34 | 35 | return true; 36 | } 37 | 38 | //Lossless WebP Format But Slow Encoding Speed. Use To Decode JBPX By Calling DecJBPX 39 | bool SaveAsWebP(wchar_t* wpFilePath, uint8_t* pBitMapBuffer, uint32_t szFile) 40 | { 41 | lstrcatW(wpFilePath, L".webp"); 42 | const HANDLE hfile = CreateFileW(wpFilePath, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); 43 | if (hfile == INVALID_HANDLE_VALUE) { return false; } 44 | 45 | //Destroy Alpha Channel 46 | for (size_t ite_byte = 3; ite_byte < szFile; ite_byte++) 47 | { 48 | pBitMapBuffer[ite_byte] = 0xFF; 49 | ite_byte += 3; 50 | } 51 | 52 | //Encode To WebP 53 | uint8_t* webp_ptr = nullptr; 54 | size_t webp_size = 0; 55 | if (sg_isLossless) 56 | { 57 | webp_size = WebPEncodeLosslessBGRA(pBitMapBuffer, 1280, 720, 1280 * 4, &webp_ptr); 58 | } 59 | else 60 | { 61 | webp_size = WebPEncodeBGRA(pBitMapBuffer, 1280, 720, 1280 * 4, sg_dwWebPQuality, &webp_ptr); 62 | } 63 | 64 | //Write File To Disk 65 | WriteFile(hfile, webp_ptr, webp_size, nullptr, nullptr); 66 | FlushFileBuffers(hfile); 67 | CloseHandle(hfile); 68 | WebPFree(webp_ptr); 69 | 70 | std::wcout << L"Dump:" << wpFilePath << std::endl; 71 | 72 | return true; 73 | } 74 | 75 | static int sg_iWidth = 1280; 76 | static int sg_iHight = 720; 77 | uint32_t __stdcall DecWebP(ImageSecData* lpImageSecData, ImageSecWidthBites* lpImageSecWidthBites, uint8_t* pWebPBuffer, uint32_t* szWebPBuffer, uint32_t dwUnknow) 78 | { 79 | //If WebP Encode CMV 80 | if (*(uint32_t*)pWebPBuffer == 0x46464952) 81 | { 82 | uint8_t* pBitMap = WebPDecodeBGRA((uint8_t*)pWebPBuffer, *szWebPBuffer, &sg_iWidth, &sg_iHight); 83 | if (pBitMap) 84 | { 85 | SplitImage720(lpImageSecData, pBitMap); 86 | WebPFree(pBitMap); 87 | } 88 | 89 | return 0; 90 | } 91 | else 92 | { 93 | return sg_fnDecJBPDBuffer(lpImageSecData, lpImageSecWidthBites, pWebPBuffer, szWebPBuffer, dwUnknow); 94 | } 95 | } 96 | 97 | void InitDecodeInfo() 98 | { 99 | InitJBPXInfo(&sg_SecData, &sg_SecBites); 100 | InitBMPInfo(&sg_BitMapFile, &sg_BitMapInfo); 101 | } 102 | 103 | //Set BMP Format File Info 104 | void InitBMPInfo(BITMAPFILEHEADER* lpBitMapFile, BITMAPINFOHEADER* lpBitMapInfo) 105 | { 106 | lpBitMapFile->bfType = 0x4D42; 107 | lpBitMapFile->bfSize = 0x384036; 108 | lpBitMapFile->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 109 | 110 | lpBitMapInfo->biSize = 40; 111 | lpBitMapInfo->biWidth = 1280; 112 | lpBitMapInfo->biHeight = 720; 113 | lpBitMapInfo->biPlanes = 1; 114 | lpBitMapInfo->biBitCount = 32; 115 | lpBitMapInfo->biCompression = 0; 116 | lpBitMapInfo->biSizeImage = 0x384000; 117 | } 118 | 119 | //Set JBPX Fromat Processing Conditions 120 | void InitJBPXInfo(ImageSecData* lpImageSecData, ImageSecWidthBites* lpImageSecWidthBites) 121 | { 122 | for (size_t iteSec = 0; iteSec < 0xF; iteSec++) 123 | { 124 | ((uint8_t**)lpImageSecData)[iteSec] = (uint8_t*)malloc(0x40000); 125 | ((uint32_t*)lpImageSecWidthBites)[iteSec] = 0x400; 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV6_Hook.cpp: -------------------------------------------------------------------------------- 1 | #include "CMV6_Hook.h" 2 | #include "CMV6_Hook_Def.h" 3 | #include "CMV6_PixelArray.h" 4 | #include "CMV6_Coder.h" 5 | #include "CMV_Editor.h" 6 | #include "../../../RxHook/RxHook.h" 7 | #include "../../../Rut/RxStream.h" 8 | 9 | 10 | 11 | #include 12 | #include 13 | 14 | using namespace Rut; 15 | 16 | 17 | namespace CMVS::CMV 18 | { 19 | static wchar_t sg_aFilePathBuffer[0xFF] = { 0 }; 20 | static uint8_t* sg_pJBPDBuffer = (uint8_t*)malloc(0x384000); 21 | static uint8_t* sg_pBitMapBuffer = (uint8_t*)malloc(0x384000); 22 | 23 | static fnTransFrame sg_fnTransFrame = (fnTransFrame)0x004311E0; 24 | static fnGetJBPXBuffer sg_fnGetJBPXBuffer = (fnGetJBPXBuffer)0x004333D0; 25 | static fnDecJBPDBuffer sg_fnDecJBPDBuffer = (fnDecJBPDBuffer)0x00518490; 26 | static fnDecJBP1Buffer sg_fnDecJBP1Buffer = (fnDecJBP1Buffer)0x00431401; 27 | 28 | 29 | //Make Full Path Of Dump File 30 | wchar_t* MakeFileName(uint32_t nSequence) 31 | { 32 | swprintf_s(sg_aFilePathBuffer, L"Dump\\%08d", nSequence); 33 | return sg_aFilePathBuffer; 34 | } 35 | 36 | 37 | bool LoadJBPX(const wchar_t* wpJBPXFilePath, uint8_t* pJBPXBuffer, uint32_t* szJBPXFile) 38 | { 39 | *szJBPXFile = 0; 40 | FILE* fpJBPX = nullptr; 41 | 42 | errno_t err = _wfopen_s(&fpJBPX, wpJBPXFilePath, L"rb"); 43 | if ((fpJBPX == nullptr) || (err != 0)) { return false; } 44 | 45 | // Get Size 46 | fseek(fpJBPX, 0, SEEK_END); 47 | *szJBPXFile = ftell(fpJBPX); 48 | if (!(*szJBPXFile)) { return false; } 49 | fseek(fpJBPX, 0, SEEK_SET); 50 | 51 | // Write To Buffer 52 | fread(pJBPXBuffer, 1, *szJBPXFile, fpJBPX); 53 | 54 | fflush(fpJBPX); 55 | fclose(fpJBPX); 56 | 57 | return true; 58 | } 59 | 60 | bool JBPXDecodeToWebP(const wchar_t* lpJBPXFilePath, uint8_t* pJBPXBuffer, uint32_t szJBPXBuffer) 61 | { 62 | sg_fnDecJBPDBuffer(&sg_SecData, &sg_SecBites, (PBYTE)pJBPXBuffer, &szJBPXBuffer, 0); 63 | MergeImage720(&sg_SecData, sg_pBitMapBuffer); 64 | return SaveAsWebP((wchar_t*)lpJBPXFilePath, (PUCHAR)sg_pBitMapBuffer, sg_BitMapInfo.biSizeImage); 65 | } 66 | 67 | bool JBPXDecodeFromeFile(std::wstring wsJBPXPath) 68 | { 69 | static uint32_t jbpx_size = 0; 70 | 71 | bool is_load = LoadJBPX(wsJBPXPath.c_str(), sg_pJBPDBuffer, &jbpx_size); 72 | if (is_load == false) { std::wcout << L"Load File Failed!!\n" << std::endl; return false; } 73 | 74 | bool is_decode = JBPXDecodeToWebP(wsJBPXPath.c_str(), sg_pJBPDBuffer, jbpx_size); 75 | if (is_decode) { std::wcout << L"Decode File Failed!!\n" << std::endl; return false; } 76 | 77 | return true; 78 | } 79 | 80 | void ReDoDecodeJBPXFromeFile() 81 | { 82 | std::wstring jbpx_path; 83 | while (true) 84 | { 85 | std::wcout << L"Input JBPX File Name:" << std::endl; 86 | std::wcin >> jbpx_path; 87 | JBPXDecodeFromeFile(jbpx_path); 88 | } 89 | } 90 | 91 | void UnPackCMV() 92 | { 93 | BOOL isSingle = FALSE; 94 | BOOL isDecode = FALSE; 95 | PCHAR pJBPXBuffer = NULL; 96 | PWCHAR resFilePath = NULL; 97 | std::wstring cmvFileName; 98 | 99 | CreateDirectoryW(L"Unpack", NULL); 100 | CreateDirectoryW(L"Dump", NULL); 101 | 102 | while (true) 103 | { 104 | std::wcout << L"** UnPackCMV / Decode JBPX Thread **\n" << std::endl; 105 | 106 | //Single JBPX Or CMV File 107 | std::wcout 108 | << L"Code 1 : Decode Single JBPX \n" 109 | << L"Code 0 : Process CMV File \n" 110 | << L"Input Code:"; 111 | std::wcin >> isSingle; 112 | if (isSingle) 113 | { 114 | CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ReDoDecodeJBPXFromeFile, NULL, NULL, NULL); 115 | return; 116 | } 117 | std::wcout << std::endl; 118 | 119 | //Create CMV File OBJ 120 | std::wcout << "Input File Name:"; 121 | std::wcin >> cmvFileName; 122 | CMV6File::CMV6Unpack cmvFile(cmvFileName, L"Unpack\\"); 123 | std::wcout << std::endl; 124 | 125 | //Is Decode JBPX 126 | std::wcout 127 | << "Code 1 : Decode JBPX \n" 128 | << "Code 0 : Not Decode Will Unpack All Resources(.JBPX / .Ogg) \n" 129 | << L"Input Code:"; 130 | std::wcin >> isDecode; 131 | if (isDecode) 132 | { 133 | //Save Image Lossless or Lossy 134 | std::wcout 135 | << L"Code 1 : Lossless\n" 136 | << L"Code 0 : Lossy\n" 137 | << L"Input Code:"; 138 | std::wcin >> g_isLossless; 139 | if (!g_isLossless) 140 | { 141 | std::wcout 142 | << L"Set Quality Of WebP Lossy\n" 143 | << L"Input Quality:"; 144 | std::wcin >> g_dwWebPQuality; 145 | } 146 | 147 | std::wcout 148 | << L'\n' 149 | << L"*********************************************\n" 150 | << L"* Dump Start Will Save File In Dump Folder. *\n" 151 | << L"*********************************************\n"; 152 | 153 | //ReDo Decode JBPX Frome CMV File 154 | for (CMV6File::CMV_Index& descriptor : cmvFile.m_vecDescriptor) 155 | { 156 | //If Audio File 157 | if (descriptor.uiResType == 0) 158 | { 159 | cmvFile.UnPackSingleRes(descriptor.uiSequence); 160 | continue; 161 | } 162 | 163 | resFilePath = MakeFileName(descriptor.uiSequence); 164 | pJBPXBuffer = cmvFile.GetResToBuffer(descriptor.uiOffset + cmvFile.m_Header.uiResSecOffset, descriptor.uiCmpSize); 165 | JBPXDecodeToWebP(resFilePath, pJBPXBuffer, descriptor.uiCmpSize); 166 | } 167 | } 168 | else 169 | { 170 | std::wcout 171 | << L'\n' 172 | << L"*************************************************\n" 173 | << L"* Unpack Start Will Save File In Unpack Folder. *\n" 174 | << L"*************************************************\n\n"; 175 | 176 | cmvFile.UnPackAllRes(); 177 | } 178 | 179 | std::wcout << std::endl; 180 | } 181 | } 182 | 183 | uint8_t* __fastcall GetJBPDBuffer_Hook(uint32_t* pTHIS, uint32_t dwEDX, uint32_t dwSequence, uint32_t* szJBPDBuffer) 184 | { 185 | MakeFileName(dwSequence); 186 | return sg_fnGetJBPXBuffer(pTHIS, dwEDX, dwSequence, szJBPDBuffer); 187 | } 188 | 189 | uint32_t __stdcall DecJBPD_Hook(ImageSecData* lpImageSecData, ImageSecWidthBites* lpImageSecWidthBites, uint8_t* pJBPDBuffer, uint32_t* szJBPDBuffer, uint32_t dwUnknow) 190 | { 191 | MergeImage720(lpImageSecData, sg_pBitMapBuffer); 192 | SaveAsBmp(sg_aFilePathBuffer, sg_pBitMapBuffer, sg_BitMapInfo.biSizeImage); 193 | return sg_fnDecJBPDBuffer(lpImageSecData, lpImageSecWidthBites, pJBPDBuffer, szJBPDBuffer, dwUnknow); 194 | } 195 | 196 | 197 | //************************* 198 | //* EXPORT FUNC * 199 | //************************* 200 | void CMV6FrameDump() 201 | { 202 | RxStream::SetConsole(L"CMV6FrameDump"); 203 | 204 | InitBMPInfo(&sg_BitMapFile, &sg_BitMapInfo); 205 | 206 | RxHook::DetourAttachFunc(&sg_fnDecJBPDBuffer, DecJBPD_Hook); 207 | RxHook::DetourAttachFunc(&sg_fnGetJBPXBuffer, GetJBPDBuffer_Hook); 208 | } 209 | 210 | void CMV6DecodeWebP() 211 | { 212 | //TDA::ConsoleX::SetConsole(L"CMV6DecodeWebP"); 213 | 214 | RxHook::DetourAttachFunc(&sg_fnDecJBPDBuffer, DecWebP); 215 | } 216 | 217 | //Set Console Input .CMV File Path Unpack All Resources And Decode JBPX 218 | void UnPackCMVThread() 219 | { 220 | RxStream::SetConsole(L"UnPackCMV / Decode JBPX Thread"); 221 | 222 | InitDecodeInfo(); 223 | //CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)UnPackCMV, NULL, NULL, NULL); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV6_Hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace CMVS::CMV 5 | { 6 | void CMV6FrameDump(); 7 | void CMV6DecodeWebP(); 8 | void UnPackCMVThread(); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV6_Hook_Def.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | namespace CMVS::CMV 6 | { 7 | struct ImageSecData 8 | { 9 | uint8_t* pSec0; 10 | uint8_t* pSec1; 11 | uint8_t* pSec2; 12 | uint8_t* pSec3; 13 | uint8_t* pSec4; 14 | uint8_t* pSec5; 15 | uint8_t* pSec6; 16 | uint8_t* pSec7; 17 | uint8_t* pSec8; 18 | uint8_t* pSec9; 19 | uint8_t* pSecA; 20 | uint8_t* pSecB; 21 | uint8_t* pSecC; 22 | uint8_t* pSecD; 23 | uint8_t* pSecE; 24 | }; 25 | 26 | struct ImageSecWidthBites 27 | { 28 | uint32_t szSec0; 29 | uint32_t szSec1; 30 | uint32_t szSec2; 31 | uint32_t szSec3; 32 | uint32_t szSec4; 33 | uint32_t szSec5; 34 | uint32_t szSec6; 35 | uint32_t szSec7; 36 | uint32_t szSec8; 37 | uint32_t szSec9; 38 | uint32_t szSecA; 39 | uint32_t szSecB; 40 | uint32_t szSecC; 41 | uint32_t szSecD; 42 | uint32_t szSecE; 43 | }; 44 | 45 | 46 | typedef uint32_t(__stdcall* fnDecJBP1Buffer)(ImageSecData* lpImageSecData, ImageSecWidthBites* lpImageSecWidthBites, uint8_t* pJBP1Buffer, uint32_t* szJBP1Buffer, uint32_t dwUnknow); 47 | typedef uint32_t(__stdcall* fnDecJBPDBuffer)(ImageSecData* lpImageSecData, ImageSecWidthBites* lpImageSecWidthBites, uint8_t* pJBPDBuffer, uint32_t* szJBPDBuffer, uint32_t dwUnknow); 48 | typedef uint32_t(__thiscall* fnTransFrame)(uint32_t* pThis, uint32_t a2, uint8_t* pJBPXBuffer, uint32_t* szJBPXBuffer, uint32_t a5); 49 | typedef uint8_t* (__fastcall* fnGetJBPXBuffer)(uint32_t* pTHIS, uint32_t dwEDX, uint32_t dwSequence, uint32_t* szJBPDBuffer); 50 | } -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV6_PixelArray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CMV6_Hook_Def.h" 3 | 4 | 5 | namespace CMVS::CMV 6 | { 7 | //For 1280 x 720 8 | //MergeImage Frome 15 Sectors 9 | //PerLineBytes = 0x400 10 | //ImageHight 1,2,3,4,5,6,7,8,9 = 0x100; A,B,C,D,E = 0xD0 11 | void MergeImage720(ImageSecData* lpImageSecData, uint8_t* pMergeBuffer) 12 | { 13 | for (size_t iteHight = 0; iteHight < 0x100; iteHight++) 14 | { 15 | memcpy(&pMergeBuffer[0x400 * 0], &lpImageSecData->pSec0[0x400 * iteHight], 0x400); 16 | memcpy(&pMergeBuffer[0x400 * 1], &lpImageSecData->pSec1[0x400 * iteHight], 0x400); 17 | memcpy(&pMergeBuffer[0x400 * 2], &lpImageSecData->pSec2[0x400 * iteHight], 0x400); 18 | memcpy(&pMergeBuffer[0x400 * 3], &lpImageSecData->pSec3[0x400 * iteHight], 0x400); 19 | memcpy(&pMergeBuffer[0x400 * 4], &lpImageSecData->pSec4[0x400 * iteHight], 0x400); 20 | pMergeBuffer += 0x400 * 5; 21 | } 22 | 23 | for (size_t iteHight = 0; iteHight < 0x100; iteHight++) 24 | { 25 | memcpy(&pMergeBuffer[0x400 * 0], &lpImageSecData->pSec5[0x400 * iteHight], 0x400); 26 | memcpy(&pMergeBuffer[0x400 * 1], &lpImageSecData->pSec6[0x400 * iteHight], 0x400); 27 | memcpy(&pMergeBuffer[0x400 * 2], &lpImageSecData->pSec7[0x400 * iteHight], 0x400); 28 | memcpy(&pMergeBuffer[0x400 * 3], &lpImageSecData->pSec8[0x400 * iteHight], 0x400); 29 | memcpy(&pMergeBuffer[0x400 * 4], &lpImageSecData->pSec9[0x400 * iteHight], 0x400); 30 | pMergeBuffer += 0x400 * 5; 31 | } 32 | 33 | for (size_t iteHight = 0; iteHight < 0xD0; iteHight++) 34 | { 35 | memcpy(&pMergeBuffer[0x400 * 0], &lpImageSecData->pSecA[0x400 * iteHight], 0x400); 36 | memcpy(&pMergeBuffer[0x400 * 1], &lpImageSecData->pSecB[0x400 * iteHight], 0x400); 37 | memcpy(&pMergeBuffer[0x400 * 2], &lpImageSecData->pSecC[0x400 * iteHight], 0x400); 38 | memcpy(&pMergeBuffer[0x400 * 3], &lpImageSecData->pSecD[0x400 * iteHight], 0x400); 39 | memcpy(&pMergeBuffer[0x400 * 4], &lpImageSecData->pSecE[0x400 * iteHight], 0x400); 40 | pMergeBuffer += 0x400 * 5; 41 | } 42 | } 43 | 44 | //For 1280 x 720 45 | //SplitImage Frome 15 Sectors 46 | //PerLineBytes = 0x400 47 | //ImageHight 1,2,3,4,5,6,7,8,9 = 0x100; A,B,C,D,E = 0xD0 48 | void SplitImage720(ImageSecData* lpImageSecData, uint8_t* pSplitBuffer) 49 | { 50 | for (size_t iteHight = 0; iteHight < 0x100; iteHight++) 51 | { 52 | memcpy(&lpImageSecData->pSec0[0x400 * iteHight], &pSplitBuffer[0x400 * 0], 0x400); 53 | memcpy(&lpImageSecData->pSec0[0x400 * iteHight], &pSplitBuffer[0x400 * 0], 0x400); 54 | memcpy(&lpImageSecData->pSec1[0x400 * iteHight], &pSplitBuffer[0x400 * 1], 0x400); 55 | memcpy(&lpImageSecData->pSec2[0x400 * iteHight], &pSplitBuffer[0x400 * 2], 0x400); 56 | memcpy(&lpImageSecData->pSec3[0x400 * iteHight], &pSplitBuffer[0x400 * 3], 0x400); 57 | memcpy(&lpImageSecData->pSec4[0x400 * iteHight], &pSplitBuffer[0x400 * 4], 0x400); 58 | pSplitBuffer += 0x400 * 5; 59 | } 60 | 61 | for (size_t iteHight = 0; iteHight < 0x100; iteHight++) 62 | { 63 | memcpy(&lpImageSecData->pSec5[0x400 * iteHight], &pSplitBuffer[0x400 * 0], 0x400); 64 | memcpy(&lpImageSecData->pSec6[0x400 * iteHight], &pSplitBuffer[0x400 * 1], 0x400); 65 | memcpy(&lpImageSecData->pSec7[0x400 * iteHight], &pSplitBuffer[0x400 * 2], 0x400); 66 | memcpy(&lpImageSecData->pSec8[0x400 * iteHight], &pSplitBuffer[0x400 * 3], 0x400); 67 | memcpy(&lpImageSecData->pSec9[0x400 * iteHight], &pSplitBuffer[0x400 * 4], 0x400); 68 | pSplitBuffer += 0x400 * 5; 69 | } 70 | 71 | for (size_t iteHight = 0; iteHight < 0xD0; iteHight++) 72 | { 73 | memcpy(&lpImageSecData->pSecA[0x400 * iteHight], &pSplitBuffer[0x400 * 0], 0x400); 74 | memcpy(&lpImageSecData->pSecB[0x400 * iteHight], &pSplitBuffer[0x400 * 1], 0x400); 75 | memcpy(&lpImageSecData->pSecC[0x400 * iteHight], &pSplitBuffer[0x400 * 2], 0x400); 76 | memcpy(&lpImageSecData->pSecD[0x400 * iteHight], &pSplitBuffer[0x400 * 3], 0x400); 77 | memcpy(&lpImageSecData->pSecE[0x400 * iteHight], &pSplitBuffer[0x400 * 4], 0x400); 78 | pSplitBuffer += 0x400 * 5; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV_Editor.cpp: -------------------------------------------------------------------------------- 1 | #include "CMV_Editor.h" 2 | #include "../../lib/Rut/RxPath.h" 3 | #include "../../lib/Rut/RxStream.h" 4 | 5 | #include 6 | #include 7 | 8 | using namespace Rut; 9 | 10 | 11 | namespace CMVS::CMV 12 | { 13 | CMVEditor::CMVEditor(const std::wstring& wsCMV) : m_Header({}), m_wsCMV(wsCMV) 14 | { 15 | m_ifsCMV.Create(wsCMV, RIO::RIO_IN, RCO::RCO_OPEN); 16 | m_ifsCMV.Read(&m_Header, sizeof(m_Header)); 17 | m_wsFolder = RxPath::NotSuffix(m_wsCMV) + L"\\"; 18 | ReadIndex(); 19 | } 20 | 21 | wchar_t* CMVEditor::MakeFileName(uint32_t uiSequence, uint32_t uiType) 22 | { 23 | static wchar_t name_tmp[20] = { 0 }; 24 | 25 | switch (uiType) 26 | { 27 | case CMV_ResType::OGG: { swprintf_s(name_tmp, L"%08d.ogg", uiSequence); } break; 28 | case CMV_ResType::JBPX: { swprintf_s(name_tmp, L"%08d.jbpx", uiSequence); } break; 29 | case CMV_ResType::WEBP: { swprintf_s(name_tmp, L"%08d.webp", uiSequence); } break; 30 | } 31 | 32 | return name_tmp; 33 | } 34 | 35 | void CMVEditor::ReadIndex() 36 | { 37 | //Read Index 38 | size_t index_size = (m_Header.uiResMaxSequence + 1) * sizeof(CMV_Entry); 39 | CMV_Entry* index_ptr = m_AutoMem[index_size]; 40 | m_ifsCMV.Read(index_ptr, index_size); 41 | 42 | //Read Entry 43 | for (size_t ite_entry = 0; ite_entry <= m_Header.uiResMaxSequence; ite_entry++) 44 | { 45 | m_vcIndex.push_back(index_ptr[ite_entry]); 46 | } 47 | } 48 | 49 | void CMVEditor::SaveFrame(CMV_Entry& ceEntry) 50 | { 51 | size_t size = ceEntry.uiCmpSize; 52 | size_t offset = m_Header.uiResSecOffset + ceEntry.uiOffset; 53 | wchar_t* name = MakeFileName(ceEntry.uiSequence, ceEntry.uiResType); 54 | 55 | m_ifsCMV.SetPos(offset); 56 | m_ifsCMV.Read(m_AutoMem[size], size); 57 | RxStream::SaveFileViaPath((m_wsFolder + name).c_str(), m_AutoMem, size); 58 | } 59 | 60 | void CMVEditor::ExtractAll() 61 | { 62 | std::for_each(m_vcIndex.begin(), m_vcIndex.end(), [this](auto& entry) { SaveFrame(entry); }); 63 | } 64 | 65 | void CMVEditor::ExtractViaSeq(uint32_t uiSequence) 66 | { 67 | SaveFrame(m_vcIndex[uiSequence]); 68 | } 69 | 70 | //void CMVEditor::MakeNewPack() 71 | //{ 72 | // if (m_fsCMV.is_open()) 73 | // { 74 | // //Set Header 75 | // m_hdHeader.uiResMaxSequence = m_vecAddResInfo.size() - 1; 76 | // m_hdHeader.uiResSecOffset = (m_hdHeader.uiResMaxSequence + 1) * 0x14 + sizeof(CMV_Header); 77 | // m_hdHeader.uiCMVFileSize = m_hdHeader.uiResSecOffset + m_szData; 78 | 79 | // //Write Header 80 | // m_fsCMV.write((char*)&m_hdHeader, sizeof(CMV_Header)); 81 | 82 | // //Write Index 83 | // size_t posResSecOffset = 0; 84 | // for (AddResInfo& iteInfo : m_vecAddResInfo) 85 | // { 86 | // iteInfo.Descriptor.uiOffset = posResSecOffset; 87 | // posResSecOffset += iteInfo.Descriptor.uiCmpSize; 88 | 89 | // m_fsCMV.write((char*)&iteInfo.Descriptor, sizeof(CMV_Index)); 90 | // } 91 | 92 | // //Write Resources 93 | // size_t szRes = 0; 94 | // for (AddResInfo& iteInfo : m_vecAddResInfo) 95 | // { 96 | // szRes = iteInfo.Descriptor.uiCmpSize; 97 | // m_fsRES.open(iteInfo.wsResPath, std::ios::in | std::ios::binary); 98 | // if (m_fsRES.is_open()) 99 | // { 100 | // HeapReSize(szRes); 101 | 102 | // if (m_pRes) 103 | // { 104 | // m_fsRES.read(m_pRes, iteInfo.Descriptor.uiCmpSize); 105 | // m_fsCMV.write(m_pRes, iteInfo.Descriptor.uiCmpSize); 106 | // } 107 | 108 | // m_fsRES.close(); 109 | // } 110 | // } 111 | 112 | // m_fsCMV.flush(); 113 | // } 114 | //} 115 | } 116 | 117 | -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV_Editor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "CMV_Struct.h" 5 | #include "../../lib/Rut/RxStream.h" 6 | 7 | 8 | namespace CMVS::CMV 9 | { 10 | class CMVEditor 11 | { 12 | private: 13 | CMV_Header m_Header; 14 | Rut::RxStream::AutoMem m_AutoMem; 15 | 16 | std::wstring m_wsCMV; 17 | std::wstring m_wsFolder; 18 | Rut::RxStream::Binary m_ifsCMV; 19 | std::vector m_vcIndex; 20 | 21 | void SaveFrame(CMV_Entry& ceEntry); 22 | void ReadIndex(); 23 | 24 | public: 25 | CMVEditor(const std::wstring& wsCMV); 26 | 27 | void ExtractAll(); 28 | void ExtractViaSeq(uint32_t uiSequence); 29 | 30 | static wchar_t* MakeFileName(uint32_t uiSequence, uint32_t uiType); 31 | }; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/CMV/CMV_Struct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace CMVS::CMV 5 | { 6 | //CMVFile (Some As CMV4 CMV3) 7 | /* 8 | * CMVFileHeader 9 | * CMVIndexDescriptor[uiResCount + 1]; 10 | * ResourcesData 11 | */ 12 | struct CMV_Header 13 | { 14 | uint8_t aSignature[4]; // CMV6 CMV4 CMV3 15 | uint32_t uiResSecOffset; 16 | uint32_t uiCMVFileSize; 17 | uint32_t uiUnknow0; // Not Used 18 | uint32_t uiResMaxSequence; // Start With Zero 19 | uint32_t uiFrameRate; 20 | uint32_t uiFrameRateTime; // Per Second 21 | uint32_t uiImageWidth; 22 | uint32_t uiImageHight; 23 | uint32_t uiBitCount; 24 | uint32_t uiAudioFlag; // About Audio File Load If 0x0 Game Will Crash In MOG_INputMemory 25 | }; 26 | 27 | struct CMV_Entry 28 | { 29 | uint32_t uiSequence; // Max = uiResCount 30 | uint32_t uiCmpSize; 31 | uint32_t uiOrgSize; // Pixel Array Size ((uiBitCount / 8) * uiImageWidth * uiImageHight) 32 | uint32_t uiResType; // 0 = ogg, 02 = jbpx 33 | uint32_t uiOffset; // ResFileOffset = uiOffset + uiResOffset 34 | }; 35 | 36 | enum CMV_ResType 37 | { 38 | OGG, 39 | WEBP, //Custom 40 | JBPX 41 | }; 42 | } -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/FileDump/CMVSFileDump.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZQF-ReVN/RxCMVS/584f9f58e994f3648f94d0e58ca35da1a916e968/lib/CMVS/src/#collation/FileDump/CMVSFileDump.cpp -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/FileDump/CMVSFileDump.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZQF-ReVN/RxCMVS/584f9f58e994f3648f94d0e58ca35da1a916e968/lib/CMVS/src/#collation/FileDump/CMVSFileDump.h -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/PB3/PB3_Dump.cpp: -------------------------------------------------------------------------------- 1 | #include "PB3_Dump.h" 2 | 3 | 4 | namespace CMVS::PB3 5 | { 6 | struct BITMAPDEC 7 | { 8 | PBYTE lpBMPBuffer; 9 | PBYTE lpBits; 10 | LONG szBytesPerLine; 11 | DWORD szDiB; 12 | DWORD szPixel; 13 | }; 14 | 15 | LPCSTR g_lpFileNmae = 0; 16 | BITMAPDEC g_bDec = { 0 }; 17 | BITMAPFILEHEADER g_bFile = { 0 }; 18 | BITMAPINFOHEADER g_bInfo = { 0 }; 19 | 20 | VOID WriteBMPFile(BITMAPFILEHEADER* lpFile, BITMAPINFOHEADER* lpInfo, BITMAPDEC* lpDec) 21 | { 22 | HANDLE hFile = 0; 23 | 24 | hFile = CreateFileA(g_lpFileNmae, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 25 | if (hFile != INVALID_HANDLE_VALUE) 26 | { 27 | WriteFile(hFile, lpFile, sizeof(BITMAPFILEHEADER), NULL, NULL); 28 | WriteFile(hFile, lpInfo, sizeof(BITMAPINFOHEADER), NULL, NULL); 29 | WriteFile(hFile, lpDec->lpBits, lpDec->szDiB, NULL, NULL); 30 | FlushFileBuffers(hFile); 31 | CloseHandle(hFile); 32 | } 33 | } 34 | 35 | VOID InitBMPStruct() 36 | { 37 | //Init FileHeader 38 | memcpy(&g_bFile, g_bDec.lpBMPBuffer, sizeof(g_bFile)); 39 | 40 | //Init InfoHeader 41 | memcpy(&g_bInfo, &g_bDec.lpBMPBuffer[sizeof(g_bFile)], sizeof(g_bInfo)); 42 | 43 | //Set Poniter To Bits Data 44 | g_bDec.lpBits = &g_bDec.lpBMPBuffer[sizeof(g_bFile) + sizeof(g_bInfo)]; 45 | 46 | //Calculate Perline Size 47 | g_bDec.szBytesPerLine = ((g_bInfo.biWidth * g_bInfo.biBitCount + 31) / 32) * 4; 48 | 49 | //Calculate The Size Of DiB 50 | g_bDec.szDiB = g_bDec.szBytesPerLine * g_bInfo.biHeight; 51 | 52 | //Calculate One Pixel Size 53 | g_bDec.szPixel = g_bDec.szBytesPerLine / g_bInfo.biWidth; 54 | 55 | } 56 | 57 | BOOL ReadPixel(BITMAPINFOHEADER* lpInfo, BITMAPDEC* lpMapDec, RGBQUAD* lpPixel, LONG x, LONG y) 58 | { 59 | if (x < lpInfo->biWidth && y < lpInfo->biHeight) 60 | { 61 | UINT px = x * lpMapDec->szPixel; 62 | UINT py = y * lpMapDec->szBytesPerLine; 63 | memcpy(lpPixel, &lpMapDec->lpBits[py + px], lpMapDec->szPixel); 64 | 65 | return TRUE; 66 | } 67 | else 68 | { 69 | return FALSE; 70 | } 71 | } 72 | 73 | BOOL WritePixel(BITMAPINFOHEADER* lpInfo, BITMAPDEC* lpMapDec, RGBQUAD* lpPixel, LONG x, LONG y) 74 | { 75 | if (x < lpInfo->biWidth && y < lpInfo->biHeight) 76 | { 77 | UINT px = x * lpMapDec->szPixel; 78 | UINT py = y * lpMapDec->szBytesPerLine; 79 | memcpy(&lpMapDec->lpBits[py + px], lpPixel, lpMapDec->szPixel); 80 | 81 | return TRUE; 82 | } 83 | else 84 | { 85 | return FALSE; 86 | } 87 | } 88 | 89 | BOOL VerFlipBitMap() 90 | { 91 | RGBQUAD pixel = { 0 }; 92 | BITMAPDEC bDec = g_bDec; 93 | 94 | bDec.lpBits = (PBYTE)VirtualAlloc(NULL, g_bDec.szDiB, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 95 | 96 | if (bDec.lpBits != NULL) 97 | { 98 | for (LONG y = 0; y < g_bInfo.biHeight; y++) 99 | { 100 | for (LONG x = 0; x < g_bInfo.biWidth; x++) 101 | { 102 | BOOL isRead = ReadPixel(&g_bInfo, &g_bDec, &pixel, x, y); 103 | BOOL isWritten = WritePixel(&g_bInfo, &bDec, &pixel, x, g_bInfo.biHeight - y - 1); 104 | if (!(isRead && isWritten)) 105 | { 106 | VirtualFree(bDec.lpBits, NULL, MEM_RELEASE); 107 | return FALSE; 108 | } 109 | } 110 | } 111 | 112 | WriteBMPFile(&g_bFile, &g_bInfo, &bDec); 113 | VirtualFree(bDec.lpBits, NULL, MEM_RELEASE); 114 | return TRUE;; 115 | } 116 | 117 | return FALSE; 118 | } 119 | 120 | bool DumpBMPFile(PBYTE lpBuffer, LPCSTR lpFileName, DWORD dwSizeDiB) 121 | { 122 | g_bFile = { 0 }; 123 | g_bInfo = { 0 }; 124 | g_bDec = { 0 }; 125 | g_lpFileNmae = lpFileName; 126 | 127 | g_bDec.lpBMPBuffer = lpBuffer; 128 | if (g_bDec.lpBMPBuffer != NULL) 129 | { 130 | InitBMPStruct(); 131 | 132 | if (dwSizeDiB < g_bDec.szDiB) 133 | { 134 | return false; 135 | } 136 | 137 | if (g_bInfo.biBitCount == 32) 138 | { 139 | VerFlipBitMap(); 140 | return true; 141 | } 142 | 143 | return false; 144 | } 145 | 146 | return false; 147 | } 148 | } 149 | 150 | -------------------------------------------------------------------------------- /lib/CMVS/src/#collation/PB3/PB3_Dump.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | namespace CMVS::PB3 7 | { 8 | bool DumpBMPFile(PBYTE lpBuffer, LPCSTR lpOutFileName, DWORD dwSizeDiB); 9 | } 10 | -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/CMVS_Types.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | namespace CMVS 6 | { 7 | struct Pack_Coder; 8 | 9 | struct VFS_Entry 10 | { 11 | char aReadPath[2048]; 12 | Pack_Coder* pCoder; 13 | }; 14 | 15 | struct VFS_Comm_Index 16 | { 17 | VFS_Entry Entry[4]; 18 | }; 19 | 20 | struct VFS_Image_Index 21 | { 22 | uint8_t aUn0[4200]; 23 | VFS_Entry aEntries[10]; 24 | uint8_t aUn1[2052]; 25 | }; 26 | 27 | struct Rect_Size 28 | { 29 | uint32_t aUn[6]; 30 | uint32_t iWidth; 31 | uint32_t iHeigh; 32 | }; 33 | 34 | struct Engine 35 | { 36 | uint32_t* pVtable; 37 | HWND hWnd; 38 | uint32_t hInstance; 39 | uint32_t cpKeyConfigFilePath; 40 | uint32_t lpParam; 41 | uint32_t usIconID; 42 | uint32_t uiUn0_0; 43 | uint32_t uiBase_Val_0; 44 | uint32_t aUn1[50]; 45 | WNDCLASSA WndClass; 46 | uint32_t uiBase_Val_1; 47 | uint32_t aUn2_1; 48 | uint32_t aUn2_2; 49 | uint32_t aUn2_3; 50 | char aTitle[128]; 51 | char aWorkDir[1000]; 52 | uint32_t aUn3[126]; 53 | Rect_Size WndSize; 54 | uint32_t aBase_Val[343]; 55 | VFS_Comm_Index* aVFSIndexPtr[8]; 56 | uint32_t aUn4[1742]; 57 | char aPath_0[176]; 58 | uint32_t aMainFrame_Val_0[20]; 59 | char aPath_1[128]; 60 | uint32_t aMainFrame_Val_1[14]; 61 | char aMainFrameWnd_WorkDir[1920]; 62 | uint32_t aUn5[32]; 63 | uint32_t uiTimer; 64 | uint32_t aCommand_Buffer[64]; 65 | char aScriptName[128]; 66 | uint32_t uiScriptSize; 67 | uint32_t aUn6_0; 68 | uint32_t aUn6_1; 69 | uint32_t aUn6_2; 70 | uint32_t uiReg0; 71 | uint32_t iCodeExecutLen; 72 | uint32_t uiReg1; 73 | uint32_t aCommand_Val_3[15]; 74 | uint32_t aUn7[444]; 75 | uint32_t aCommand_Val_5; 76 | uint32_t pScript; 77 | uint32_t aCommand_Val_0[3]; 78 | uint32_t pCodeSeg; 79 | uint32_t uiUn8_0; 80 | uint32_t uiUn8_1; 81 | uint32_t uiUn8_2; 82 | uint32_t pStrSeg; 83 | uint32_t uiUn8_3; 84 | uint32_t uiUn8_4; 85 | uint32_t uiUn8_5; 86 | uint32_t pUnSeg; 87 | uint32_t uiUn8_6; 88 | uint32_t uiUn8_7; 89 | uint32_t uiUn8_8; 90 | uint32_t aCommand_Val_1[5]; 91 | uint32_t aStackBuffer[16384]; 92 | uint32_t aUn9[64]; 93 | uint32_t* pStackPtr; 94 | uint32_t nStackTop; 95 | uint32_t aCommand_Val_e0; 96 | uint32_t aCommand_Buffer_1[63]; 97 | uint32_t aCommand_Val_e1; 98 | uint32_t aCommand_Val_2[14]; 99 | uint32_t aUnA[255]; 100 | uint32_t uiMainFrame_Val_0; 101 | uint32_t uiMainFrame_Val_1; 102 | }; 103 | 104 | struct Image 105 | { 106 | uint8_t* pPixelArray; 107 | uint32_t nSize; 108 | uint32_t nWidth; 109 | uint32_t nHight; 110 | uint32_t nBits; 111 | uint32_t nType; 112 | }; 113 | 114 | //-MGVFile 115 | // -MGVHeader 116 | // -IndexCount * 4 117 | // -Audio 118 | // -Video 119 | struct MGV_HDR 120 | { 121 | uint8_t aSignature[4]; 122 | uint32_t uiBitCount; 123 | uint32_t uiVideoSize; 124 | uint32_t uiAudioSize; 125 | uint32_t uiFrameIndexCount; 126 | uint16_t usWidth; 127 | uint16_t usHight; 128 | uint32_t uiFrameRateTime; //1s = 1000ms 129 | uint32_t uiFrameRate; // FrameRate * 1000 130 | }; 131 | 132 | struct PS3_HDR 133 | { 134 | uint32_t uiSignature; 135 | uint32_t uiHeaderSize; 136 | uint32_t uiUn0; 137 | uint32_t uiDataDecodeKey; 138 | uint32_t uiTextCount; 139 | uint32_t uiCodeBlockSize; 140 | uint32_t uiUnBlockSize; 141 | uint32_t uiTextBlockSize; 142 | uint32_t uiUn2; 143 | uint32_t uiDataCompressSize; 144 | uint32_t uiDataDecompressSize; 145 | uint32_t uiUn3; 146 | }; 147 | 148 | 149 | typedef BOOL(__thiscall* Fn_RunVM)(Engine* This); 150 | 151 | typedef HLOCAL(__stdcall* Fn_ReadFullData)(char* cpFileName, uint32_t* pSize_Ret); 152 | 153 | typedef HLOCAL(__thiscall* Fn_ScriptReader)(VFS_Entry* pEntry, char* cpScriptName, uint32_t* pSize_Ret); 154 | 155 | typedef BOOL(__thiscall* Fn_ImageReader)(uint32_t* This, Image* pCImage, char* cpPrefixPath, char* cpImageName, uint32_t pUn0); 156 | 157 | typedef BOOL(__thiscall* Fn_ImageDecoder)(uint32_t* This, Image* pCImage, HLOCAL pData, uint32_t nDataSize, char* cpImageName, uint32_t pUn0); 158 | 159 | typedef HLOCAL(__thiscall* Fn_PackReadFile)(Pack_Coder* pCoder, VFS_Entry* pEntry, const char* cpFileName, uint32_t* pFileSize_Ret, uint32_t uiUn0, uint32_t uiUn1); 160 | 161 | typedef BOOL(__thiscall* Fn_RegCommPath)(VFS_Comm_Index* This, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9); 162 | 163 | typedef BOOL(__thiscall* Fn_RegVideoPath)(VFS_Comm_Index* This, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9); 164 | 165 | typedef BOOL(__thiscall* Fn_RegImagePath)(VFS_Image_Index* This, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9); 166 | 167 | typedef BOOL(__thiscall* Fn_RegUnPath)(VFS_Comm_Index* This, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9); 168 | 169 | 170 | struct Pack_Coder_VTable 171 | { 172 | uint32_t* fnUn0; 173 | uint32_t* fnUn1; 174 | uint32_t* fnUn2; 175 | uint32_t* fnUn3; 176 | Fn_PackReadFile fnReadFile; 177 | uint32_t* fnUn4; 178 | uint32_t* fnUn5; 179 | }; 180 | 181 | struct Pack_Coder 182 | { 183 | Pack_Coder_VTable* pVtable; 184 | }; 185 | } -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/MGV_Editor.cpp: -------------------------------------------------------------------------------- 1 | #include "MGV_Editor.h" 2 | #include "CMVS_Types.h" 3 | #include 4 | #include 5 | 6 | using namespace Rut; 7 | 8 | 9 | namespace CMVS::MGV 10 | { 11 | void Editor::Extract(const std::filesystem::path& phMGV) 12 | { 13 | RxFile::Binary ifs_mgv{ phMGV, RIO_READ }; 14 | 15 | MGV_HDR hdr = ifs_mgv.Get(); 16 | 17 | uint32_t index_size = hdr.uiFrameIndexCount * 4; 18 | ifs_mgv.SetPos(sizeof(hdr) + index_size); 19 | 20 | RxMem::Auto buffer; 21 | 22 | buffer.ReadData(ifs_mgv, hdr.uiAudioSize); 23 | buffer.SaveData(phMGV.stem().replace_extension(L".ogg")); 24 | 25 | buffer.ReadData(ifs_mgv, hdr.uiVideoSize); 26 | buffer.SaveData(phMGV.stem().replace_extension(L".ogv")); 27 | } 28 | 29 | void Editor::Replace(const std::filesystem::path& phMGV, const std::filesystem::path& phVideo) 30 | { 31 | RxFile::Binary ifs_mgv{ phMGV, RIO_READ }; 32 | RxFile::Binary ofs_mgv{ phMGV.wstring() + L".new", RIO_WRITE }; 33 | 34 | MGV_HDR hdr = ifs_mgv.Get(); 35 | 36 | // Write Header 37 | hdr.uiVideoSize = (uint32_t)std::filesystem::file_size(phVideo); 38 | ofs_mgv.Write(&hdr, sizeof(hdr)); 39 | 40 | RxMem::Auto buffer; 41 | 42 | //Write Index 43 | uint32_t index_size = hdr.uiFrameIndexCount * 4; 44 | buffer.ReadData(ifs_mgv, index_size); 45 | ofs_mgv.Write(buffer.GetPtr(), buffer.GetSize()); 46 | 47 | //Write Audio 48 | buffer.ReadData(ifs_mgv, hdr.uiAudioSize); 49 | ofs_mgv.Write(buffer.GetPtr(), buffer.GetSize()); 50 | 51 | //Write Video 52 | buffer.LoadFile(phVideo); 53 | ofs_mgv.Write(buffer.GetPtr(), buffer.GetSize()); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/MGV_Editor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | namespace CMVS::MGV 7 | { 8 | class Editor 9 | { 10 | public: 11 | static void Extract(const std::filesystem::path& phMGV); 12 | static void Replace(const std::filesystem::path& phMGV, const std::filesystem::path& phVideo); 13 | }; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/PS3_Cryptor.cpp: -------------------------------------------------------------------------------- 1 | #include "PS3_Cryptor.h" 2 | #include "CMVS_Types.h" 3 | 4 | 5 | namespace CMVS::PS3 6 | { 7 | void Cryptor::Decode(std::wstring_view wsPath, Rut::RxMem::Auto& rfBuffer) 8 | { 9 | Rut::RxMem::Auto tmp_ps3(wsPath); 10 | uint8_t* enc_file_ptr = tmp_ps3.GetPtr(); 11 | size_t enc_file_size = tmp_ps3.GetSize(); 12 | PS3_HDR* enc_hdr_ptr = (PS3_HDR*)enc_file_ptr; 13 | 14 | uint8_t* enc_data_comp_ptr = enc_file_ptr + enc_hdr_ptr->uiHeaderSize; 15 | size_t enc_data_comp_size = enc_file_size - enc_hdr_ptr->uiHeaderSize; 16 | KeyDecData(enc_data_comp_ptr, enc_data_comp_size, enc_hdr_ptr->uiDataDecodeKey); 17 | 18 | rfBuffer.SetSize(enc_hdr_ptr->uiDataDecompressSize + enc_hdr_ptr->uiHeaderSize); 19 | 20 | uint8_t* dec_file_ptr = rfBuffer.GetPtr(); 21 | uint8_t* dec_data_ptr = dec_file_ptr + enc_hdr_ptr->uiHeaderSize; 22 | LZSS_Decode(enc_data_comp_ptr, enc_hdr_ptr->uiDataCompressSize, dec_data_ptr); 23 | 24 | memcpy(dec_file_ptr, enc_file_ptr, enc_hdr_ptr->uiHeaderSize); 25 | } 26 | 27 | void Cryptor::Encode(std::wstring_view wsPath, Rut::RxMem::Auto& rfBuffer) 28 | { 29 | Rut::RxMem::Auto tmp_ps3(wsPath); 30 | uint8_t* dec_file_ptr = tmp_ps3.GetPtr(); 31 | size_t dec_file_size = tmp_ps3.GetSize(); 32 | 33 | PS3_HDR* dec_hdr_ptr = (PS3_HDR*)dec_file_ptr; 34 | uint8_t* dec_data_ptr = dec_file_ptr + dec_hdr_ptr->uiHeaderSize; 35 | 36 | 37 | rfBuffer.SetSize(dec_file_size * 2); 38 | uint8_t* enc_file_ptr = rfBuffer.GetPtr(); 39 | memcpy(enc_file_ptr, dec_file_ptr, dec_hdr_ptr->uiHeaderSize); 40 | 41 | PS3_HDR* enc_hdr_ptr = (PS3_HDR*)enc_file_ptr; 42 | uint8_t* enc_data_comp_ptr = enc_file_ptr + enc_hdr_ptr->uiHeaderSize; 43 | enc_hdr_ptr->uiDataCompressSize = (uint32_t)LZSS_Encode_Fake(dec_data_ptr, dec_hdr_ptr->uiDataDecompressSize, enc_data_comp_ptr); 44 | KeyEncData(enc_data_comp_ptr, enc_hdr_ptr->uiDataCompressSize, enc_hdr_ptr->uiDataDecodeKey); 45 | 46 | rfBuffer.SetSize(enc_hdr_ptr->uiDataCompressSize + enc_hdr_ptr->uiHeaderSize); 47 | } 48 | 49 | 50 | static uint8_t Ror8(uint8_t ucValue, uint8_t ucShift) 51 | { 52 | return (ucValue >> ucShift) | (ucValue << (8 - ucShift)); 53 | } 54 | 55 | static uint8_t Rol8(uint8_t ucValue, uint8_t ucShift) 56 | { 57 | return (ucValue << ucShift) | (ucValue >> (8 - ucShift)); 58 | } 59 | 60 | void Cryptor::KeyDecData(uint8_t* pData, size_t uiDataSize, uint32_t uiKey) 61 | { 62 | if (uiDataSize == 0) { return; } 63 | 64 | uint8_t dec_key = ((uint8_t)(uiKey >> 3)) + ((uint8_t)(uiKey >> 24)); 65 | uint8_t dec_shift = (uint8_t)((((uint32_t)(uiKey >> 20)) % 5) + 1); 66 | 67 | for (uint32_t ite = 0; ite < uiDataSize; ite++) 68 | { 69 | uint8_t tmp_byte = pData[ite]; 70 | tmp_byte -= 0x7C; 71 | tmp_byte = dec_key ^ tmp_byte; 72 | tmp_byte = Ror8(tmp_byte, dec_shift); 73 | pData[ite] = tmp_byte; 74 | } 75 | } 76 | 77 | void Cryptor::KeyEncData(uint8_t* pData, size_t uiDataSize, uint32_t uiKey) 78 | { 79 | if (uiDataSize == 0) { return; } 80 | 81 | uint8_t dec_key = ((uint8_t)(uiKey >> 3)) + ((uint8_t)(uiKey >> 24)); 82 | uint8_t dec_shift = (uint8_t)((((uint32_t)(uiKey >> 20)) % 5) + 1); 83 | 84 | for (uint32_t ite = 0; ite < uiDataSize; ite++) 85 | { 86 | uint8_t tmp_byte = pData[ite]; 87 | tmp_byte = Rol8(tmp_byte, dec_shift); 88 | tmp_byte = dec_key ^ tmp_byte; 89 | tmp_byte += 0x7C; 90 | pData[ite] = tmp_byte; 91 | } 92 | } 93 | 94 | void Cryptor::LZSS_Decode(uint8_t* pEnc, size_t nEncSize, uint8_t* pDec) 95 | { 96 | constexpr size_t slider_size = 0x800; 97 | constexpr size_t slider_max_index = 0x7FF; 98 | constexpr size_t slider_beg_index = 0x7DF; 99 | 100 | uint8_t* dec_ptr = pDec; 101 | uint8_t* enc_ptr = pEnc; 102 | uint8_t* enc_end = pEnc + nEncSize; 103 | 104 | uint32_t token = 0; 105 | uint8_t slider_buf[slider_size] = { 0 }; 106 | size_t ite_slider = slider_beg_index; 107 | 108 | while (true) 109 | { 110 | token >>= 1; 111 | 112 | if ((token & 0x100) == 0) // read token 113 | { 114 | if (enc_ptr >= enc_end) return; 115 | token = enc_ptr++[0] | 0xFF00; 116 | } 117 | 118 | if (enc_ptr >= enc_end) return; 119 | 120 | if (token & 1) // not compress 121 | { 122 | uint8_t tmp = enc_ptr[0]; 123 | 124 | dec_ptr++[0] = tmp; 125 | slider_buf[ite_slider] = tmp; 126 | ite_slider = (ite_slider + 1) & slider_max_index; 127 | 128 | enc_ptr += 1; 129 | } 130 | else // compress 131 | { 132 | if ((enc_ptr + 1) >= enc_end) return; 133 | 134 | size_t copy_len = (enc_ptr[1] & 0x1F) + 1; 135 | size_t copy_off = ((enc_ptr[1] & 0xE0) << 3) | enc_ptr[0]; 136 | 137 | for (size_t ite = 0; ite <= copy_len; ite++) 138 | { 139 | size_t off = (ite + copy_off) & slider_max_index; 140 | uint8_t tmp = slider_buf[off]; 141 | 142 | dec_ptr++[0] = tmp; 143 | slider_buf[ite_slider] = tmp; 144 | ite_slider = (ite_slider + 1) & slider_max_index; 145 | } 146 | 147 | enc_ptr += 2; 148 | } 149 | } 150 | } 151 | 152 | size_t Cryptor::LZSS_Encode_Fake(uint8_t* pRaw, size_t nRawSize, uint8_t* pEnc) 153 | { 154 | uint8_t* pEnc_Back = pEnc; 155 | size_t align = nRawSize % 8; 156 | for (size_t iteRaw = 0; iteRaw < ((nRawSize - align) / 8); iteRaw++) 157 | { 158 | pEnc[0] = 0xFF; 159 | memcpy(pEnc + 1, pRaw, 8); 160 | 161 | pEnc += 9; 162 | pRaw += 8; 163 | } 164 | 165 | if (align) 166 | { 167 | pEnc[0] = 0xFF; 168 | memcpy(pEnc + 1, pRaw, align); 169 | pEnc += align + 1; 170 | } 171 | 172 | return (size_t)(pEnc - pEnc_Back); 173 | } 174 | } -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/PS3_Cryptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | namespace CMVS::PS3 6 | { 7 | class Cryptor 8 | { 9 | public: 10 | static void Decode(std::wstring_view wsPath, Rut::RxMem::Auto& rfDecode); 11 | static void Encode(std::wstring_view wsPath, Rut::RxMem::Auto& rfEncode); 12 | 13 | private: 14 | static void KeyDecData(uint8_t* pData, size_t uiDataSize, uint32_t uiKey); 15 | static void KeyEncData(uint8_t* pData, size_t uiDataSize, uint32_t uiKey); 16 | 17 | static void LZSS_Decode(uint8_t* pEnc, size_t nEncSize, uint8_t* pDec); 18 | static size_t LZSS_Encode_Fake(uint8_t* pRaw, size_t nRawSize, uint8_t* pEnc); 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/PS3_TextEditor.cpp: -------------------------------------------------------------------------------- 1 | #include "PS3_TextEditor.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace Rut; 8 | 9 | 10 | namespace CMVS::PS3 11 | { 12 | static std::wstring NumToStr(const wchar_t* wpFormat, size_t nValue) 13 | { 14 | wchar_t buf[0x10]; 15 | size_t len = (size_t)swprintf_s(buf, 0x10, wpFormat, nValue); 16 | return { buf, len }; 17 | } 18 | 19 | void TextEditor::Init(std::wstring_view wsPath) 20 | { 21 | m_wsPath = wsPath; 22 | m_amPS3.LoadFile(wsPath); 23 | this->ReadEntry(); 24 | } 25 | 26 | bool TextEditor::Import(std::wstring_view wsJsonPath, std::wstring_view wsSavePath, size_t nCodePage) 27 | { 28 | // Check 29 | if (this->m_vecTextIndex.empty()) { return false; } 30 | 31 | // Read Json 32 | RxJson::JValue json = RxJson::Parser{}.Load(wsJsonPath); 33 | RxJson::JArray& jarr_scn = json[L"Scenario"]; 34 | 35 | // Check 36 | if (jarr_scn.size() != m_vecTextIndex.size()) { return false; } 37 | 38 | 39 | // Read To TextIndex 40 | size_t append_text_size = 0; 41 | size_t text_seg_len = this->GeTextSegSize(); 42 | uint8_t* code_seg_ptr = this->GetCodeSegPtr(); 43 | for (size_t ite = 0; ite < this->m_vecTextIndex.size(); ite++) 44 | { 45 | // Read Text 46 | Text_Entry& entry = m_vecTextIndex[ite]; 47 | entry.msText = RxStr::ToMBCS(jarr_scn[ite][L"tra"].ToStrView(), nCodePage); 48 | 49 | if (entry.msText.empty()) { throw std::runtime_error("CMVS::PS3::Editor::Insert Error! Text Empty"); } 50 | 51 | // Cal New Text Rva 52 | entry.uiRvaValRva = (uint32_t)(text_seg_len + append_text_size); 53 | append_text_size += entry.msText.size() + 1; 54 | 55 | // Write New Text Rva 56 | uint32_t* rva_ptr = (uint32_t*)(code_seg_ptr + entry.uiRvaPtrRva); 57 | *rva_ptr = entry.uiRvaValRva; 58 | } 59 | 60 | 61 | // Write Append Data 62 | RxMem::Auto append_text_data; 63 | append_text_data.SetSize(append_text_size); 64 | uint8_t* append_text_ptr = append_text_data.GetPtr(); 65 | for (auto& entry : m_vecTextIndex) 66 | { 67 | size_t str_full_len = entry.msText.size() + 1; 68 | memcpy(append_text_ptr, entry.msText.data(), str_full_len); 69 | append_text_ptr += str_full_len; 70 | } 71 | this->m_amPS3.Append(append_text_data); 72 | 73 | // Set Header Data 74 | PS3_HDR* hdr_ptr = this->GetHdrPtr(); 75 | hdr_ptr->uiDataDecompressSize += (uint32_t)append_text_size; 76 | hdr_ptr->uiTextBlockSize += (uint32_t)append_text_size; 77 | 78 | // Save Data 79 | this->m_amPS3.SaveData(wsSavePath); 80 | 81 | return true; 82 | } 83 | 84 | void TextEditor::Export(std::wstring_view wsPath, size_t nCodePage) 85 | { 86 | size_t hdr_len = this->GetHdrSize(); 87 | size_t code_len = this->GetCodeSegSize(); 88 | 89 | RxJson::JValue json_root; 90 | RxJson::JArray& jarr_scn = json_root[L"Scenario"].ToAry(); 91 | for (auto& entry : m_vecTextIndex) 92 | { 93 | std::wstring text; 94 | RxStr::ToWCS(entry.msText, text, nCodePage); 95 | 96 | RxJson::JObject jobj_info; 97 | jobj_info[L"raw"] = text; 98 | jobj_info[L"tra"] = text; 99 | 100 | if(false) 101 | { 102 | jobj_info[L"FOA_Ptr"] = NumToStr(L"0x%08x", hdr_len + entry.uiRvaPtrRva); 103 | jobj_info[L"FOA_Rva"] = NumToStr(L"0x%08x", hdr_len + code_len + entry.uiRvaValRva); 104 | } 105 | 106 | jarr_scn.push_back(jobj_info); 107 | } 108 | 109 | RxJson::Parser::Save(json_root, wsPath, true); 110 | } 111 | 112 | 113 | void TextEditor::ReadEntry() 114 | { 115 | constexpr uint8_t push_str_opcode_beg[4] = { 0x01, 0x02, 0x20, 0x01 }; 116 | constexpr uint8_t push_str_opcode_end[4] = { 0x0F, 0x02, 0x30, 0x04 }; 117 | 118 | Text_Entry entry; 119 | uint8_t* code_seg_ptr = this->GetCodeSegPtr(); 120 | uint32_t code_seg_size = this->GetCodeSegSize(); 121 | for (size_t ite = 0; ite < code_seg_size; ite++) 122 | { 123 | if (memcmp(push_str_opcode_beg, (code_seg_ptr + ite), sizeof(push_str_opcode_beg))) { continue; } 124 | if (memcmp(push_str_opcode_end, (code_seg_ptr + ite + sizeof(push_str_opcode_beg) + 4), sizeof(push_str_opcode_end))) { continue; } 125 | 126 | entry.uiRvaPtrRva = (uint32_t)(ite + sizeof(push_str_opcode_beg)); 127 | entry.uiRvaValRva = *(uint32_t*)(code_seg_ptr + entry.uiRvaPtrRva); 128 | 129 | // Filter String 130 | std::string_view ms_text = (char*)this->GetTextSegPtr() + entry.uiRvaValRva; 131 | if (this->Filter(ms_text)) { continue; } 132 | 133 | entry.msText = ms_text; 134 | m_vecTextIndex.emplace_back(entry); 135 | } 136 | } 137 | 138 | bool TextEditor::Filter(std::string_view msText) 139 | { 140 | if (msText.empty() || 141 | msText.find(".ogg") != std::string::npos || msText.find(".wav") != std::string::npos || 142 | msText.find(".mv2") != std::string::npos || msText.find(".pb3") != std::string::npos || 143 | msText.find(".pb2") != std::string::npos || msText.find(".ps3") != std::string::npos || 144 | msText.find(".ps2") != std::string::npos || msText.find(".cur") != std::string::npos || 145 | msText.find(".cmv") != std::string::npos || msText.find(".mgv") != std::string::npos) 146 | { 147 | return true; 148 | } 149 | else 150 | { 151 | return false; 152 | } 153 | } 154 | 155 | uint8_t* TextEditor::GetPS3Ptr() const 156 | { 157 | return m_amPS3.GetPtr(); 158 | } 159 | 160 | PS3_HDR* TextEditor::GetHdrPtr() 161 | { 162 | return (PS3_HDR*)this->GetPS3Ptr(); 163 | } 164 | 165 | uint32_t TextEditor::GetHdrSize() 166 | { 167 | return this->GetHdrPtr()->uiHeaderSize; 168 | } 169 | 170 | uint32_t TextEditor::GetCodeSegSize() 171 | { 172 | return this->GetHdrPtr()->uiCodeBlockSize + (4 * this->GeTextCount()) + this->GetHdrPtr()->uiUnBlockSize; 173 | } 174 | 175 | uint32_t TextEditor::GeTextSegSize() 176 | { 177 | return this->GetHdrPtr()->uiTextBlockSize; 178 | } 179 | 180 | uint8_t* TextEditor::GetCodeSegPtr() 181 | { 182 | return this->GetPS3Ptr() + this->GetHdrSize(); 183 | } 184 | 185 | uint8_t* TextEditor::GetTextSegPtr() 186 | { 187 | return this->GetPS3Ptr() + this->GetHdrSize() + this->GetCodeSegSize(); 188 | } 189 | 190 | uint32_t TextEditor::GeTextCount() 191 | { 192 | return this->GetHdrPtr()->uiTextCount; 193 | } 194 | } -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/PS3_TextEditor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "CMVS_Types.h" 5 | #include 6 | 7 | 8 | namespace CMVS::PS3 9 | { 10 | class TextEditor 11 | { 12 | private: 13 | struct Text_Entry 14 | { 15 | std::string msText; 16 | uint32_t uiRvaValRva{}; // A Value [Text Data Rva] In Block 17 | uint32_t uiRvaPtrRva{}; // A Pointer [Text Data Rva’s Rva] In Code Block 18 | }; 19 | 20 | public: 21 | Rut::RxMem::Auto m_amPS3; 22 | std::wstring m_wsPath; 23 | std::vector m_vecTextIndex; 24 | 25 | TextEditor() {}; 26 | 27 | void Init(std::wstring_view wsPath); 28 | bool Import(std::wstring_view wsJsonPath, std::wstring_view wsSavePath, size_t nCodePage); 29 | void Export(std::wstring_view wsPath, size_t nCodePage); 30 | 31 | void ReadEntry(); 32 | bool Filter(std::string_view msText); 33 | 34 | private: 35 | uint8_t* GetPS3Ptr() const; 36 | PS3_HDR* GetHdrPtr(); 37 | uint32_t GetHdrSize(); 38 | uint32_t GetCodeSegSize(); 39 | uint32_t GeTextSegSize(); 40 | uint8_t* GetCodeSegPtr(); 41 | uint8_t* GetTextSegPtr(); 42 | uint32_t GeTextCount(); 43 | }; 44 | } -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/VFS_Extract.cpp: -------------------------------------------------------------------------------- 1 | #include "VFS_Extract.h" 2 | #include "CMVS_Types.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | 12 | namespace CMVS::VFS 13 | { 14 | static Engine* sg_pEngine = nullptr; 15 | static Fn_RegCommPath sg_fnRegCommPath = nullptr; 16 | static Fn_RegVideoPath sg_fnRegVideoPath = nullptr; 17 | static Fn_RegImagePath sg_fnRegImagePath = nullptr; 18 | 19 | static std::set sg_stEntryPtr; 20 | 21 | 22 | static BOOL __fastcall RegCommPath_Hook(VFS_Comm_Index* This,uint32_t uiEDX, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9) 23 | { 24 | for (size_t ite = 0; ite < 4; ite++) 25 | { 26 | sg_stEntryPtr.insert(&This->Entry[ite]); 27 | } 28 | return sg_fnRegCommPath(This, nIndex, cpPath, a4, a5, a6, a7, a8, a9); 29 | } 30 | 31 | static BOOL __fastcall RegImagePath_Hook(VFS_Image_Index* This, uint32_t uiEDX, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9) 32 | { 33 | for (size_t ite = 0; ite < 10; ite++) 34 | { 35 | sg_stEntryPtr.insert(&This->aEntries[ite]); 36 | } 37 | return sg_fnRegImagePath(This, nIndex, cpPath, a4, a5, a6, a7, a8, a9); 38 | } 39 | 40 | static BOOL __fastcall RegVideoPath_Hook(VFS_Comm_Index* This, uint32_t uiEDX, uint32_t nIndex, const char* cpPath, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8, uint32_t a9) 41 | { 42 | for (size_t ite = 0; ite < 4; ite++) 43 | { 44 | sg_stEntryPtr.insert(&This->Entry[ite]); 45 | } 46 | return sg_fnRegVideoPath(This, nIndex, cpPath, a4, a5, a6, a7, a8, a9); 47 | } 48 | 49 | 50 | 51 | static VFS_Entry* FindEntry(std::string_view msPackName) 52 | { 53 | for (VFS_Entry* entry_ptr : sg_stEntryPtr) 54 | { 55 | if (entry_ptr->pCoder) 56 | { 57 | if (strstr(entry_ptr->aReadPath, msPackName.data())) 58 | { 59 | return entry_ptr; 60 | } 61 | } 62 | } 63 | return nullptr; 64 | } 65 | 66 | static void PrintEntries() 67 | { 68 | for (VFS_Entry* entry_ptr : sg_stEntryPtr) 69 | { 70 | if (entry_ptr->pCoder) 71 | { 72 | Rut::RxCmd::PutFormat("%s\n", entry_ptr->aReadPath); 73 | } 74 | } 75 | } 76 | 77 | static void ExtractFile(std::string_view msPackName, std::string_view msFileName) 78 | { 79 | VFS_Entry* entry_ptr = FindEntry(msPackName); 80 | 81 | if (entry_ptr) 82 | { 83 | uint32_t file_size = 0; 84 | HLOCAL h_heap = entry_ptr->pCoder->pVtable->fnReadFile(entry_ptr->pCoder, entry_ptr, msFileName.data(), &file_size, 0, 0); 85 | if (h_heap && file_size) 86 | { 87 | Rut::RxFile::SaveFileViaPath(msFileName, h_heap, file_size); 88 | ::LocalFree(h_heap); 89 | std::cout << "File extract successfully!\n"; 90 | } 91 | } 92 | else 93 | { 94 | std::cout << "Not Find Pack!\n"; 95 | } 96 | } 97 | 98 | static void __stdcall ExtractThread() 99 | { 100 | Rut::RxCmd::Alloc(L"CMVS_VFS_Extract", true); 101 | 102 | std::string command; 103 | while (true) 104 | { 105 | std::cout << "$>"; 106 | std::cin >> command; 107 | 108 | if (command == "ls") 109 | { 110 | PrintEntries(); 111 | } 112 | else if (command == "ext") 113 | { 114 | std::string pack_name; 115 | std::string file_name; 116 | 117 | std::cout << "PackName:"; 118 | std::cin >> pack_name; 119 | std::cout << "FileName:"; 120 | std::cin >> file_name; 121 | 122 | ExtractFile(pack_name, file_name); 123 | } 124 | 125 | std::cout << std::endl; 126 | } 127 | } 128 | 129 | 130 | // ******************* 131 | // * EXPORT FUNC * 132 | // ******************* 133 | void Extract(uint32_t fnRegCommPath, uint32_t fnRegImagePath, uint32_t fnRegVideoPath) 134 | { 135 | sg_fnRegCommPath = (Fn_RegCommPath)fnRegCommPath; 136 | sg_fnRegImagePath = (Fn_RegImagePath)fnRegImagePath; 137 | sg_fnRegVideoPath = (Fn_RegVideoPath)fnRegVideoPath; 138 | 139 | Rut::RxHook::Detours::Begin(); 140 | Rut::RxHook::Detours::Attach(&sg_fnRegCommPath, RegCommPath_Hook); 141 | Rut::RxHook::Detours::Attach(&sg_fnRegImagePath, RegImagePath_Hook); 142 | Rut::RxHook::Detours::Attach(&sg_fnRegVideoPath, RegVideoPath_Hook); 143 | Rut::RxHook::Detours::Commit(); 144 | 145 | ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ExtractThread, NULL, NULL, NULL); 146 | } 147 | } -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/VFS_Extract.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | namespace CMVS::VFS 5 | { 6 | void Extract(uint32_t fnRegCommPath, uint32_t fnRegImagePath, uint32_t fnRegVideoPath); 7 | } -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/VFS_Hook.cpp: -------------------------------------------------------------------------------- 1 | #include "VFS_Hook.h" 2 | #include "CMVS_Types.h" 3 | #include 4 | 5 | #include 6 | 7 | 8 | namespace CMVS::VFS 9 | { 10 | static char sg_aHookFolder[MAX_PATH] = { 0 }; 11 | static Fn_ScriptReader sg_fnScriptReader = nullptr; 12 | static Fn_ReadFullData sg_fnReadFullData = nullptr; 13 | static Fn_ImageReader sg_fnImageReader = nullptr; 14 | static Fn_ImageDecoder sg_fnImageDecoder = nullptr; 15 | 16 | 17 | static HLOCAL LoadFile(char* cpScriptName, uint32_t* pSize_Ret) 18 | { 19 | char full_path[MAX_PATH]; 20 | lstrcpyA(full_path, sg_aHookFolder); lstrcatA(full_path, cpScriptName); 21 | return sg_fnReadFullData(full_path, pSize_Ret); 22 | } 23 | 24 | static HLOCAL __fastcall ScriptReader_Hook(VFS_Entry* pEntry, uint32_t uiEDX, char* cpScriptName, uint32_t* pSize_Ret) 25 | { 26 | HLOCAL buffer = LoadFile(cpScriptName, pSize_Ret); 27 | return buffer != nullptr ? (buffer) : (sg_fnScriptReader(pEntry, cpScriptName, pSize_Ret)); 28 | } 29 | 30 | static BOOL __fastcall ImageReader_Hook(uint32_t* This, uint32_t uiEDX, Image* pCImage, char* cpPrefixPath, char* cpImageName, uint32_t pUn0) 31 | { 32 | uint32_t* flag_ptr = (uint32_t*)(This + 0x1824); 33 | if (*flag_ptr == 0) 34 | { 35 | uint32_t data_size = 0; 36 | HLOCAL data_ptr = LoadFile(cpImageName, &data_size); 37 | if (data_ptr) 38 | { 39 | return sg_fnImageDecoder(This, pCImage, data_ptr, data_size, cpPrefixPath, pUn0); 40 | } 41 | } 42 | return sg_fnImageReader(This, pCImage, cpPrefixPath, cpImageName, pUn0); 43 | } 44 | 45 | 46 | // ******************* 47 | // * EXPORT FUNC * 48 | // ******************* 49 | void SetHookFolder(const char* cpFolder) 50 | { 51 | lstrcpyA(sg_aHookFolder, cpFolder); 52 | } 53 | 54 | void HookPS3_V380(uint32_t fnReadFullData, uint32_t fnScriptReader) 55 | { 56 | sg_fnReadFullData = (Fn_ReadFullData)fnReadFullData; 57 | sg_fnScriptReader = (Fn_ScriptReader)fnScriptReader; 58 | 59 | Rut::RxHook::Detours::AttrachDirectly(&sg_fnScriptReader, ScriptReader_Hook); 60 | } 61 | 62 | void HookPB3_V380(uint32_t fnReadFullData, uint32_t fnImageReader, uint32_t fnImageDecoder) 63 | { 64 | sg_fnImageReader = (Fn_ImageReader)fnImageReader; 65 | sg_fnImageDecoder = (Fn_ImageDecoder)fnImageDecoder; 66 | sg_fnReadFullData = (Fn_ReadFullData)fnReadFullData; 67 | 68 | Rut::RxHook::Detours::AttrachDirectly(&sg_fnImageReader, ImageReader_Hook); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/CMVS/src/CMVS/VFS_Hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | namespace CMVS::VFS 6 | { 7 | void SetHookFolder(const char* cpFolder); 8 | void HookPS3_V380(uint32_t fnReadFullData, uint32_t fnScriptReader); 9 | void HookPB3_V380(uint32_t fnReadFullData, uint32_t fnImageReader, uint32_t fnImageDecoder); 10 | } 11 | 12 | 13 | /* 14 | CMVS_380_ 3.80-3.76 15 | CMVS_342_ 3.42-3.20 16 | CMVS_210_ 2.10-1.10 17 | */ 18 | 19 | /* 20 | //クナド国記 PKG 21 | #define CMVS_380_ 22 | #define SCRIPTADDR 0x0046CE10 23 | #define SCRIPTXOR 0x0046CEF1 24 | #define SCRIPTCOM 0x0046CF1D 25 | #define IMAGEADDR 0x0043FE8D 26 | 27 | //青春フラジャイル PKG 28 | #define CMVS_380_ 29 | #define SCRIPTADDR 0x0046CB80 30 | #define SCRIPTXOR 0x0046CC61 31 | #define SCRIPTCOM 0x0046CC8D 32 | #define IMAGEADDR 0x0043FF3D 33 | 34 | //リアライブ PKG 35 | #define CMVS_380_ 36 | #define SCRIPTADDR 0x0046CB80 37 | #define SCRIPTXOR 0x0046CC61 38 | #define SCRIPTCOM 0x0046CC8D 39 | #define IMAGEADDR 0x0043FF7D 40 | 41 | //アオイトリ PKG 42 | #define CMVS_342_ 43 | #define SCRIPTADDR 0x0045FEE0 44 | #define SCRIPTXOR 0x0045FFC6 45 | #define SCRIPTCOM 0x0045FFF1 46 | #define IMAGEADDR 0x00434485 47 | 48 | //アマツツミ PKG 49 | #define CMVS_342_ 50 | #define SCRIPTADDR 0x0045A7B0 51 | #define SCRIPTXOR 0x0045A896 52 | #define SCRIPTCOM 0x0045A8C1 53 | #define IMAGEADDR 0x00430685 54 | 55 | //ハピメアFD ハピメアWパック PKG 56 | #define CMVS_342_ 57 | #define SCRIPTADDR 0x00457BC0 58 | #define SCRIPTXOR 0x00457CA6 59 | #define SCRIPTCOM 0x00457CD1 60 | #define IMAGEADDR 0x0042EA55 61 | 62 | //クロノクロック PKG 63 | #define CMVS_342_ 64 | #define SCRIPTADDR 0x00457AB0 65 | #define SCRIPTXOR 0x00457B96 66 | #define SCRIPTCOM 0x00457BC1 67 | #define IMAGEADDR 0x0042F455 68 | 69 | //ハピメア PKG 70 | #define CMVS_342_ 71 | #define SCRIPTADDR 0x00452200 72 | #define SCRIPTXOR 0x004522E6 73 | #define SCRIPTCOM 0x00452311 74 | #define IMAGEADDR 0x00429FC5 75 | 76 | //しあわせ家族部 PKG 77 | #define CMVS_210_ 78 | #define SCRIPTADDR 0x0044C100 79 | #define SCRIPTXOR 0x0044C1C5 80 | #define SCRIPTCOM 0x0044C1EA 81 | #define IMAGEADDR 0x004268FF 82 | 83 | //未来ノスタルジア PKG 84 | #define CMVS_210_ 85 | #define SCRIPTADDR 0x0044A820 86 | #define SCRIPTXOR 0x0044A8E5 87 | #define SCRIPTCOM 0x0044A90A 88 | #define IMAGEADDR 0x00425EDF 89 | 90 | //初恋サクラメント PKG 91 | #define CMVS_210_ 92 | #define SCRIPTADDR 0x0044A1D0 93 | #define SCRIPTXOR 0x0044A295 94 | #define SCRIPTCOM 0x0044A2BA 95 | #define IMAGEADDR 0x00425F7F 96 | 97 | //夏に奏でる僕らの詩 PKG 98 | #define CMVS_210_ 99 | #define SCRIPTADDR 0x00443FB0 100 | #define SCRIPTXOR 0x00444075 101 | #define SCRIPTCOM 0x0044409A 102 | #define IMAGEADDR 0x0042116F 103 | 104 | //明日の君と逢うために PKG 105 | #define CMVS_210_ 106 | #define SCRIPTADDR 0x00441460 107 | #define SCRIPTXOR 0x00441525 108 | #define SCRIPTCOM 0x0044154A 109 | #define IMAGEADDR 0x0041FA5F 110 | 111 | //メモリア PKG 112 | #define CMVS_210_ 113 | #define SCRIPTADDR 0x00441460 114 | #define SCRIPTXOR 0x00441525 115 | #define SCRIPTCOM 0x0044154A 116 | #define IMAGEADDR 0x0041FA5F 117 | 118 | //明日の七海と逢うためにFD PKG 119 | #define CMVS_210_ 120 | #define SCRIPTADDR 0x0043DAC0 121 | #define SCRIPTXOR 0x0043DB85 122 | #define SCRIPTCOM 0x0043DBAA 123 | #define IMAGEADDR 0x0041E96F 124 | 125 | //明日の七海と逢うために PKG 126 | #define CMVS_210_ 127 | #define SCRIPTADDR 0x00439C10 128 | #define SCRIPTXOR 0x00439CD8 129 | #define SCRIPTCOM 0x00439CFE 130 | #define IMAGEADDR 0x0041E12B 131 | 132 | //プリミティブ リンク PKG 133 | #define CMVS_210_ 134 | #define SCRIPTADDR 0x0042C7E0 135 | #define SCRIPTXOR 0x0042C8A8 136 | #define SCRIPTCOM 0x0042C8CE 137 | #define IMAGEADDR 0x0041477B 138 | 139 | */ -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory("Rut") 2 | add_subdirectory("RxHook") 3 | add_subdirectory("CMVS") -------------------------------------------------------------------------------- /src/#collation/CMV6Editor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../lib/CmvsTools/CMV.h" 4 | #include "../../third/libwebp/include/encode.h" 5 | #include "../../third/libwebp/include/decode.h" 6 | #pragma comment(lib,"../../third/libwebp/lib/libwebp.lib") 7 | 8 | using namespace CMVSTools::CMV; 9 | 10 | 11 | //void EncodeWebP(std::wstring strFileName) 12 | //{ 13 | // std::ifstream ifsBitMap(strFileName, std::ios::binary); 14 | // if (ifsBitMap.is_open()) 15 | // { 16 | // size_t szBitMap = 0; 17 | // ifsBitMap.seekg(0x22); 18 | // ifsBitMap.read((char*)&szBitMap, 0x4); 19 | // 20 | // ifsBitMap.seekg(0x36); 21 | // uint8_t* pRawData = new uint8_t[szBitMap]; 22 | // if (pRawData) 23 | // { 24 | // ifsBitMap.read((char*)pRawData, szBitMap); 25 | // } 26 | // else 27 | // { 28 | // return; 29 | // } 30 | // 31 | // //Destroy Alpha Channel 32 | // for (size_t iteBitMap = 3; iteBitMap < szBitMap; iteBitMap++) 33 | // { 34 | // pRawData[iteBitMap] = 0xFF; 35 | // iteBitMap += 3; 36 | // } 37 | // 38 | // uint8_t* pWebP = nullptr; 39 | // size_t sz = WebPEncodeBGRA(pRawData, 1280, 720, 1280 * 3, 70, &pWebP); 40 | // 41 | // std::ofstream oWebp(L"1.webp", std::ios::binary); 42 | // if (oWebp.is_open()) 43 | // { 44 | // oWebp.write((char*)pWebP, sz); 45 | // 46 | // oWebp.flush(); 47 | // oWebp.close(); 48 | // } 49 | // 50 | // WebPFree(pWebP); 51 | // delete[] pRawData; 52 | // ifsBitMap.close(); 53 | // } 54 | //} 55 | // 56 | //void DecodeWebP() 57 | //{ 58 | // size_t szFile = 0x1401C; 59 | // std::ifstream ifsWebP(L"1.webp", std::ios::binary); 60 | // if (ifsWebP.is_open()) 61 | // { 62 | // char* pWebP = new char[szFile]; 63 | // ifsWebP.read(pWebP, szFile); 64 | // 65 | // int width = 1280; 66 | // int hight = 720; 67 | // uint8_t* pBitMap = WebPDecodeBGRA((uint8_t*)pWebP, szFile, &width, &hight); 68 | // WebPFree(pBitMap); 69 | // 70 | // std::ofstream ofsBitMap(L"1.raw",std::ios::binary); 71 | // ofsBitMap.write((char*)pBitMap, 1280 * 4 * 720); 72 | // ofsBitMap.flush(); 73 | // ofsBitMap.close(); 74 | // 75 | // 76 | // delete[] pWebP; 77 | // ifsWebP.close(); 78 | // } 79 | //} 80 | 81 | //void PackCMV() 82 | //{ 83 | // size_t resRawSize = 0x2A3000; 84 | // size_t resCount = 3576; 85 | // std::wstring resPath = L"webp\\"; 86 | // 87 | // //Create Pack OBJ 88 | // CMV6Pack newPack(L"new.cmv"); 89 | // 90 | // //Init File Header 91 | // newPack.m_Header.aSignature[0] = 'C'; 92 | // newPack.m_Header.aSignature[1] = 'M'; 93 | // newPack.m_Header.aSignature[2] = 'V'; 94 | // newPack.m_Header.aSignature[3] = '6'; 95 | // newPack.m_Header.uiFrameRate = 30; 96 | // newPack.m_Header.uiFrameRateTime = 1; 97 | // newPack.m_Header.uiImageWidth = 1280; 98 | // newPack.m_Header.uiImageHight = 720; 99 | // newPack.m_Header.uiBitCount = 24; 100 | // newPack.m_Header.uiAudioFlag = 2; 101 | // 102 | // 103 | // //AddRes 104 | // CMV_Index descriptor = { 0 }; 105 | // std::wstring resName; 106 | // std::ifstream ifsRes; 107 | // descriptor.uiResType = 2; 108 | // //Processing JBPX 109 | // for (size_t iteFile = 1; iteFile < resCount; iteFile++) 110 | // { 111 | // resName = resPath + newPack.MakeFileName(iteFile, 1); 112 | // ifsRes.open(resName); 113 | // 114 | // if (ifsRes.is_open()) 115 | // { 116 | // descriptor.uiSequence = iteFile; 117 | // descriptor.uiCmpSize = newPack.GetFileSize(ifsRes); 118 | // descriptor.uiOrgSize = resRawSize; 119 | // newPack.AddRes(descriptor, resName); 120 | // ifsRes.close(); 121 | // } 122 | // } 123 | // 124 | // //Processing Ogg 125 | // resName = resPath + newPack.MakeFileName(resCount, 0); 126 | // ifsRes.open(resName); 127 | // if (ifsRes.is_open()) 128 | // { 129 | // descriptor.uiResType = 0; 130 | // descriptor.uiSequence = resCount; 131 | // descriptor.uiCmpSize = newPack.GetFileSize(ifsRes); 132 | // descriptor.uiOrgSize = descriptor.uiCmpSize; 133 | // 134 | // newPack.AddRes(descriptor, resName); 135 | // ifsRes.close(); 136 | // } 137 | // 138 | // 139 | // //MakePack 140 | // newPack.MakeNewPack(); 141 | //} 142 | 143 | int main() 144 | { 145 | CMVEditor editor(L"sf01.cmv"); 146 | editor.ExtractAll(); 147 | editor.ExtractViaSeq(2); 148 | //DecodeWebP(); 149 | //EncodeWebP(L"00001397.bmp"); 150 | //PackCMV(); 151 | } -------------------------------------------------------------------------------- /src/#collation/CMV6Hook/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../lib/CmvsTools/CMV6Hook.h" 4 | 5 | using namespace CMVSTools::CMV6Hook; 6 | 7 | 8 | VOID StartHook() 9 | { 10 | //UnPackCMVThread(); 11 | CMV6DecodeWebP(); 12 | } 13 | 14 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 15 | { 16 | switch (ul_reason_for_call) 17 | { 18 | case DLL_PROCESS_ATTACH: 19 | StartHook(); 20 | break; 21 | case DLL_THREAD_ATTACH: 22 | case DLL_THREAD_DETACH: 23 | case DLL_PROCESS_DETACH: 24 | break; 25 | } 26 | return TRUE; 27 | } 28 | 29 | EXTERN_C VOID _declspec(dllexport) DirA(){} 30 | 31 | -------------------------------------------------------------------------------- /src/#collation/CMVSFileDump/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../lib/CmvsTools/CmvsFileDump.h" 4 | 5 | using namespace CMVSTools::CMVSFileDump; 6 | 7 | 8 | VOID StartHook() 9 | { 10 | DumpFile(); 11 | } 12 | 13 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 14 | { 15 | switch (ul_reason_for_call) 16 | { 17 | case DLL_PROCESS_ATTACH: 18 | StartHook(); 19 | break; 20 | case DLL_THREAD_ATTACH: 21 | break; 22 | case DLL_THREAD_DETACH: 23 | break; 24 | case DLL_PROCESS_DETACH: 25 | break; 26 | } 27 | return TRUE; 28 | } 29 | 30 | extern "C" VOID __declspec(dllexport) Dir_A() {} 31 | -------------------------------------------------------------------------------- /src/#collation/CMVSFileExtract/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../lib/CmvsTools/CmvsExtract.h" 4 | 5 | using namespace CMVSTools::CMVSExtract; 6 | 7 | VOID StartHook() 8 | { 9 | SetCmvsExtract(); 10 | } 11 | 12 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 13 | { 14 | switch (ul_reason_for_call) 15 | { 16 | case DLL_PROCESS_ATTACH: 17 | StartHook(); 18 | break; 19 | case DLL_THREAD_ATTACH: 20 | break; 21 | case DLL_THREAD_DETACH: 22 | break; 23 | case DLL_PROCESS_DETACH: 24 | break; 25 | } 26 | return TRUE; 27 | } 28 | 29 | VOID __declspec(dllexport) DirA() {} -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory("MGV_Editor") 2 | add_subdirectory("PS3_TextEditor") 3 | add_subdirectory("PS3_Cryptor") 4 | add_subdirectory("VFS_Hook") 5 | add_subdirectory("VFS_Extract") -------------------------------------------------------------------------------- /src/MGV_Editor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project Name 2 | project(MGV_Editor) 3 | 4 | # Current Project 5 | add_executable("${PROJECT_NAME}" "main.cpp") 6 | target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_23) 7 | target_compile_options("${PROJECT_NAME}" PRIVATE "$<$:/source-charset:utf-8>") 8 | 9 | # Add Library 10 | target_link_libraries("${PROJECT_NAME}" PRIVATE Rut CMVS) -------------------------------------------------------------------------------- /src/MGV_Editor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | 8 | static void UserMain(int argc, wchar_t* argv[]) 9 | { 10 | try 11 | { 12 | Rut::RxCmd::Arg arg; 13 | arg.AddCmd(L"-mgv", L"mgv file"); 14 | arg.AddCmd(L"-ogv", L"ogv path"); 15 | arg.AddCmd(L"-mode", L"mode [extract]:extract ogv ogg file, [replace]:repalce ogv file"); 16 | arg.AddExample(L"-mode extract -mgv op.mgv"); 17 | arg.AddExample(L"-mode replace -mgv op.mgv -ogv op.ogv"); 18 | if (arg.Load(argc, argv) == false) { return; } 19 | 20 | if (arg[L"-mode"] == L"extract") 21 | { 22 | CMVS::MGV::Editor::Extract(arg[L"-mgv"]); 23 | } 24 | else if (arg[L"-mode"] == L"replace") 25 | { 26 | CMVS::MGV::Editor::Replace(arg[L"-mgv"], arg[L"-ogv"]); 27 | } 28 | else 29 | { 30 | throw std::runtime_error("Error Command!"); 31 | } 32 | } 33 | catch (const std::runtime_error& err) 34 | { 35 | std::cerr << err.what() << std::endl; 36 | } 37 | } 38 | 39 | static void DebugMain() 40 | { 41 | //MGVPack mgv(L"1.mgv"); 42 | //MGVHeader header = { 0 }; 43 | //header.aSignature[0] = 'M'; 44 | //header.aSignature[1] = 'G'; 45 | //header.aSignature[2] = 'V'; 46 | //header.aSignature[3] = '1'; 47 | 48 | //header.uiVideoSize = 0x59F4762; 49 | //header.uiAudioSize = 0x192566; 50 | //header.uiBitCount = 32; 51 | //header.usWidth = 1280; 52 | //header.usHight = 720; 53 | //header.uiFrameIndexCount = 0x0DF0; // FrameRate * Time. If Value Too Large Game Will Get Stuck After Playback 54 | //header.uiFrameRateTime = 1000; //1s 55 | //header.uiFrameRate = 30 * 1000; //30 * 1000 56 | 57 | //mgv.InitMGVInfo(&header); 58 | //mgv.MakePack(L"op.mgv.ogg", L"op.mgv.ogv"); 59 | } 60 | 61 | 62 | int wmain(int argc, wchar_t* argv[]) 63 | { 64 | ::UserMain(argc, argv); 65 | } 66 | -------------------------------------------------------------------------------- /src/PS3_Cryptor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project Name 2 | project(PS3_Cryptor) 3 | 4 | # Current Project 5 | add_executable("${PROJECT_NAME}" "main.cpp") 6 | target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_23) 7 | target_compile_options("${PROJECT_NAME}" PRIVATE "$<$:/source-charset:utf-8>") 8 | 9 | # Add Library 10 | target_link_libraries("${PROJECT_NAME}" PRIVATE Rut CMVS) -------------------------------------------------------------------------------- /src/PS3_Cryptor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | static void UserMain(int argc, wchar_t* argv[]) 10 | { 11 | try 12 | { 13 | Rut::RxCmd::Arg arg; 14 | arg.AddCmd(L"-ps3", L"ps3 path"); 15 | arg.AddCmd(L"-save", L"save path"); 16 | arg.AddCmd(L"-mode", L"mode [decode]:decode ps3 file, [encode]:encode ps3 file"); 17 | arg.AddExample(L"-mode decode -ps3 sn1001.ps3 -save sn1001.ps3.dec"); 18 | arg.AddExample(L"-mode encode -ps3 sn1001.ps3 -save sn1001.ps3.enc"); 19 | if (arg.Load(argc, argv) == false) { return; } 20 | 21 | if (arg[L"-mode"] == L"decode") 22 | { 23 | Rut::RxMem::Auto out_mem; 24 | CMVS::PS3::Cryptor::Decode(arg[L"-ps3"], out_mem); 25 | out_mem.SaveData(arg[L"-save"]); 26 | } 27 | else if (arg[L"-mode"] == L"encode") 28 | { 29 | Rut::RxMem::Auto out_mem; 30 | CMVS::PS3::Cryptor::Encode(arg[L"-ps3"], out_mem); 31 | out_mem.SaveData(arg[L"-save"]); 32 | } 33 | else 34 | { 35 | throw std::runtime_error("Error Command!"); 36 | } 37 | } 38 | catch (const std::runtime_error& err) 39 | { 40 | std::cerr << err.what() << std::endl; 41 | } 42 | } 43 | 44 | static void DebugMain() 45 | { 46 | 47 | } 48 | 49 | 50 | int wmain(int argc, wchar_t* argv[]) 51 | { 52 | ::UserMain(argc, argv); 53 | //::DebugMain(); 54 | } 55 | -------------------------------------------------------------------------------- /src/PS3_TextEditor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project Name 2 | project(PS3_TextEditor) 3 | 4 | # Current Project 5 | add_executable("${PROJECT_NAME}" "main.cpp") 6 | target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_23) 7 | target_compile_options("${PROJECT_NAME}" PRIVATE "$<$:/source-charset:utf-8>") 8 | 9 | # Add Library 10 | target_link_libraries("${PROJECT_NAME}" PRIVATE Rut CMVS) -------------------------------------------------------------------------------- /src/PS3_TextEditor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | static void UserMain(int argc, wchar_t* argv[]) 10 | { 11 | try 12 | { 13 | Rut::RxCmd::Arg arg; 14 | arg.AddCmd(L"-ps3", L"ps3 path"); 15 | arg.AddCmd(L"-save", L"ps3 save path"); 16 | arg.AddCmd(L"-json", L"json path"); 17 | arg.AddCmd(L"-code", L"codepage"); 18 | arg.AddCmd(L"-mode", L"[export]:export texts, [import]:import texts"); 19 | arg.AddExample(L"-mode export -ps3 sn1001.ps3 -json sn1001.ps3.json -code 932"); 20 | arg.AddExample(L"-mode import -ps3 sn1001.ps3 -json sn1001.ps3.json -save sn1001.ps3.new -code 932"); 21 | if (arg.Load(argc, argv) == false) { return; } 22 | 23 | if (arg[L"-mode"] == L"export") 24 | { 25 | CMVS::PS3::TextEditor editor; 26 | editor.Init(arg[L"-ps3"]); 27 | editor.Export(arg[L"-json"], arg[L"-code"]); 28 | Rut::RxCmd::PutFormat(L"Success: %s", arg[L"-ps3"]); 29 | } 30 | else if (arg[L"-mode"] == L"import") 31 | { 32 | CMVS::PS3::TextEditor editor; 33 | editor.Init(arg[L"-ps3"]); 34 | if (editor.Import(arg[L"-json"], arg[L"-save"], arg[L"-code"])) 35 | { 36 | Rut::RxCmd::PutFormat(L"Success: %s", arg[L"-ps3"]); 37 | } 38 | else 39 | { 40 | Rut::RxCmd::PutFormat(L"\n\tFailure: %s\n", arg[L"-ps3"]); 41 | } 42 | } 43 | else 44 | { 45 | throw std::runtime_error("Error Command!"); 46 | } 47 | } 48 | catch (const std::runtime_error& err) 49 | { 50 | std::cerr << err.what() << std::endl; 51 | } 52 | } 53 | 54 | static void DebugMain() 55 | { 56 | { 57 | CMVS::PS3::TextEditor editor; 58 | editor.Init(L"sn1001.ps3.new"); 59 | editor.Export(L"sn1001.ps3.new.json", 932); 60 | } 61 | { 62 | //CMVS::PS3::TextEditor editor; 63 | //editor.Init(L"sn1001.ps3.dec"); 64 | //editor.Insert(L"sn1001.ps3.json", L"sn1001.ps3.new", 932); 65 | } 66 | } 67 | 68 | 69 | int wmain(int argc, wchar_t* argv[]) 70 | { 71 | ::UserMain(argc, argv); 72 | //::DebugMain(); 73 | } 74 | -------------------------------------------------------------------------------- /src/VFS_Extract/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # x32 Only 2 | if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4) 3 | return() 4 | endif() 5 | 6 | # Project Name 7 | project(VFS_Extract) 8 | 9 | # Current Project 10 | add_library("${PROJECT_NAME}" MODULE "dllmain.cpp") 11 | target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_23) 12 | target_compile_definitions("${PROJECT_NAME}" PRIVATE UNICODE _UNICODE) 13 | target_compile_options("${PROJECT_NAME}" PRIVATE "$<$:/source-charset:utf-8>") 14 | 15 | # Add Library 16 | target_link_libraries("${PROJECT_NAME}" PRIVATE Rut CMVS) -------------------------------------------------------------------------------- /src/VFS_Extract/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | 6 | static void StartHook(HMODULE hDllBase) 7 | { 8 | CMVS::VFS::Extract(0x0046CF90, 0x004401C0, 0x004415F0); 9 | } 10 | 11 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 12 | { 13 | switch (ul_reason_for_call) 14 | { 15 | case DLL_PROCESS_ATTACH: 16 | StartHook(hModule); 17 | break; 18 | case DLL_THREAD_ATTACH: 19 | break; 20 | case DLL_THREAD_DETACH: 21 | break; 22 | case DLL_PROCESS_DETACH: 23 | break; 24 | } 25 | return TRUE; 26 | } 27 | 28 | extern "C" VOID __declspec(dllexport) Dir_A() {} -------------------------------------------------------------------------------- /src/VFS_Hook/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # x32 Only 2 | if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4) 3 | return() 4 | endif() 5 | 6 | # Project Name 7 | project(VFS_Hook) 8 | 9 | # Current Project 10 | add_library("${PROJECT_NAME}" MODULE "dllmain.cpp") 11 | target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_23) 12 | target_compile_definitions("${PROJECT_NAME}" PRIVATE UNICODE _UNICODE) 13 | target_compile_options("${PROJECT_NAME}" PRIVATE "$<$:/source-charset:utf-8>") 14 | 15 | # Add Library 16 | target_link_libraries("${PROJECT_NAME}" PRIVATE Rut RxHook CMVS) -------------------------------------------------------------------------------- /src/VFS_Hook/VFSHook.ini: -------------------------------------------------------------------------------- 1 | [CMVS_File_Hook] 2 | HookFolder = FileHook\\ 3 | GameSelected = ハピメアFD_RE_PKG 4 | 5 | 6 | [ハピメアFD_RE_PKG] 7 | Engine_Ver = CMVS_380_ 8 | Script_Loa = 0x0046D0A0 9 | Script_Xor = 0x0046D181 10 | Script_Com = 0x0046D1AD 11 | Image_Load = 0x004402BD 12 | 13 | [ハピメア_RE_PKG] 14 | Engine_Ver = CMVS_380_ 15 | Script_Loa = 0x0046D0A0 16 | Script_Xor = 0x0046D181 17 | Script_Com = 0x0046D1AD 18 | Image_Load = 0x004402BD 19 | 20 | [クナド国記_PKG] 21 | Engine_Ver = CMVS_380_ 22 | Script_Loa = 0x0046CE10 23 | Script_Xor = 0x0046CEF1 24 | Script_Com = 0x0046CF1D 25 | Image_Load = 0x0043FE8D 26 | 27 | [青春フラジャイル_PKG] 28 | Engine_Ver = CMVS_380_ 29 | Script_Loa = 0x0046CB80 30 | Script_Xor = 0x0046CC61 31 | Script_Com = 0x0046CC8D 32 | Image_Load = 0x0043FF3D 33 | 34 | [リアライブ_PKG] 35 | Engine_Ver = CMVS_380_ 36 | Script_Loa = 0x0046CB80 37 | Script_Xor = 0x0046CC61 38 | Script_Com = 0x0046CC8D 39 | Image_Load = 0x0043FF7D 40 | 41 | [アオイトリ_PKG] 42 | Engine_Ver = CMVS_342_ 43 | Script_Loa = 0x0045FEE0 44 | Script_Xor = 0x0045FFC6 45 | Script_Com = 0x0045FFF1 46 | Image_Load = 0x00434485 47 | 48 | [アマツツミ_PKG] 49 | Engine_Ver = CMVS_342_ 50 | Script_Loa = 0x0045A7B0 51 | Script_Xor = 0x0045A896 52 | Script_Com = 0x0045A8C1 53 | Image_Load = 0x00430685 54 | 55 | [ハピメアFD_ハピメアWパック_PKG] 56 | Engine_Ver = CMVS_342_ 57 | Script_Loa = 0x00457BC0 58 | Script_Xor = 0x00457CA6 59 | Script_Com = 0x00457CD1 60 | Image_Load = 0x0042EA55 61 | 62 | [クロノクロック_PKG] 63 | Engine_Ver = CMVS_342_ 64 | Script_Loa = 0x00457AB0 65 | Script_Xor = 0x00457B96 66 | Script_Com = 0x00457BC1 67 | Image_Load = 0x0042F455 68 | 69 | [ハピメア_PKG] 70 | Engine_Ver = CMVS_342_ 71 | Script_Loa = 0x00452200 72 | Script_Xor = 0x004522E6 73 | Script_Com = 0x00452311 74 | Image_Load = 0x00429FC5 75 | 76 | [しあわせ家族部_PKG] 77 | Engine_Ver = CMVS_210_ 78 | Script_Loa = 0x0044C100 79 | Script_Xor = 0x0044C1C5 80 | Script_Com = 0x0044C1EA 81 | Image_Load = 0x004268FF 82 | 83 | [未来ノスタルジア_PKG] 84 | Engine_Ver = CMVS_210_ 85 | Script_Loa = 0x0044A820 86 | Script_Xor = 0x0044A8E5 87 | Script_Com = 0x0044A90A 88 | Image_Load = 0x00425EDF 89 | 90 | [初恋サクラメント_PKG] 91 | Engine_Ver = CMVS_210_ 92 | Script_Loa = 0x0044A1D0 93 | Script_Xor = 0x0044A295 94 | Script_Com = 0x0044A2BA 95 | Image_Load = 0x00425F7F 96 | 97 | [夏に奏でる僕らの詩_PKG] 98 | Engine_Ver = CMVS_210_ 99 | Script_Loa = 0x00443FB0 100 | Script_Xor = 0x00444075 101 | Script_Com = 0x0044409A 102 | Image_Load = 0x0042116F 103 | 104 | [明日の君と逢うために_PKG] 105 | Engine_Ver = CMVS_210_ 106 | Script_Loa = 0x00441460 107 | Script_Xor = 0x00441525 108 | Script_Com = 0x0044154A 109 | Image_Load = 0x0041FA5F 110 | 111 | [メモリア_PKG] 112 | Engine_Ver = CMVS_210_ 113 | Script_Loa = 0x00441460 114 | Script_Xor = 0x00441525 115 | Script_Com = 0x0044154A 116 | Image_Load = 0x0041FA5F 117 | 118 | [明日の七海と逢うためにFD_PKG] 119 | Engine_Ver = CMVS_210_ 120 | Script_Loa = 0x0043DAC0 121 | Script_Xor = 0x0043DB85 122 | Script_Com = 0x0043DBAA 123 | Image_Load = 0x0041E96F 124 | 125 | [明日の七海と逢うために_PKG] 126 | Engine_Ver = CMVS_210_ 127 | Script_Loa = 0x00439C10 128 | Script_Xor = 0x00439CD8 129 | Script_Com = 0x00439CFE 130 | Image_Load = 0x0041E12B 131 | 132 | [プリミティブ_リンク_PKG] 133 | Engine_Ver = CMVS_210_ 134 | Script_Loa = 0x0042C7E0 135 | Script_Xor = 0x0042C8A8 136 | Script_Com = 0x0042C8CE 137 | Image_Load = 0x0041477B -------------------------------------------------------------------------------- /src/VFS_Hook/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace Rut; 10 | 11 | 12 | static void HookFont(RxINI::Parser& rfINN) 13 | { 14 | auto save_str_on_heap = [](const std::string& msStr) -> char* 15 | { 16 | char* pStr = new char[msStr.size() + 1]; 17 | memcpy(pStr, msStr.c_str(), msStr.size() + 1); 18 | return pStr; 19 | }; 20 | 21 | bool is_hook_font_a = rfINN[L"HookFont"][L"HookCreateFontA"]; 22 | bool is_hook_font_indirect_a = rfINN[L"HookFont"][L"HookCreateFontIndirectA"]; 23 | 24 | if (is_hook_font_a) 25 | { 26 | RxHook::HookCreateFontA(rfINN[L"HookFont"][L"Charset"], save_str_on_heap(rfINN[L"HookFont"][L"FontName"])); 27 | } 28 | 29 | if (is_hook_font_indirect_a) 30 | { 31 | RxHook::HookCreateFontIndirectA(rfINN[L"HookFont"][L"Charset"], save_str_on_heap(rfINN[L"HookFont"][L"FontName"])); 32 | } 33 | } 34 | 35 | static void HookFile(RxINI::Parser& rfINN) 36 | { 37 | std::wstring seleted_game_name = rfINN.Get(L"CMVS_File_Hook", L"GameSelected"); 38 | 39 | auto& seleted_game = rfINN.Get(seleted_game_name); 40 | std::wstring version = seleted_game[L"Engine_Ver"]; 41 | uint32_t script_loa = seleted_game[L"Script_Lod"]; 42 | uint32_t script_xor = seleted_game[L"Script_Xor"]; 43 | uint32_t script_com = seleted_game[L"Script_Com"]; 44 | uint32_t image_load = seleted_game[L"Image_Load"]; 45 | 46 | std::string hook_folder = rfINN.Get(L"CMVS_File_Hook", L"HookFolder"); 47 | CMVS::VFS::SetHookFolder(hook_folder.c_str()); 48 | 49 | if (version == L"CMVS_380_") 50 | { 51 | //CMVS::FileHook::SetPS3Hook_380_(script_loa); 52 | //CMVS::FileHook::SetPB3Hook_380_(image_load); 53 | } 54 | else if (version == L"CMVS_342_") 55 | { 56 | //CMVS::FileHook::SetPS3Hook_342_(script_loa, script_xor, script_com); 57 | //CMVS::FileHook::SetPB3Hook_342_(image_load); 58 | } 59 | else if (version == L"CMVS_210_") 60 | { 61 | //CMVS::FileHook::SetPS3Hook_210_(script_loa, script_xor, script_com); 62 | //CMVS::FileHook::SetPB3Hook_210_(image_load); 63 | } 64 | } 65 | 66 | static void StartHook(HMODULE hDllBase) 67 | { 68 | try 69 | { 70 | RxINI::Parser ini(RxPath::RemoveSuffix(RxPath::ModulePathW(hDllBase)) + L".ini"); 71 | HookFont(ini); 72 | HookFile(ini); 73 | } 74 | catch (const std::runtime_error& err) 75 | { 76 | MessageBoxA(NULL, err.what(), NULL, NULL); 77 | } 78 | } 79 | 80 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 81 | { 82 | switch (ul_reason_for_call) 83 | { 84 | case DLL_PROCESS_ATTACH: 85 | StartHook(hModule); 86 | break; 87 | case DLL_THREAD_ATTACH: 88 | break; 89 | case DLL_THREAD_DETACH: 90 | break; 91 | case DLL_PROCESS_DETACH: 92 | break; 93 | } 94 | return TRUE; 95 | } 96 | 97 | extern "C" VOID __declspec(dllexport) Dir_A() {} -------------------------------------------------------------------------------- /third/libwebp/include/decode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Main decoding functions for WebP images. 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_DECODE_H_ 15 | #define WEBP_WEBP_DECODE_H_ 16 | 17 | #include "./types.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #define WEBP_DECODER_ABI_VERSION 0x0209 // MAJOR(8b) + MINOR(8b) 24 | 25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 26 | // the types are left here for reference. 27 | // typedef enum VP8StatusCode VP8StatusCode; 28 | // typedef enum WEBP_CSP_MODE WEBP_CSP_MODE; 29 | typedef struct WebPRGBABuffer WebPRGBABuffer; 30 | typedef struct WebPYUVABuffer WebPYUVABuffer; 31 | typedef struct WebPDecBuffer WebPDecBuffer; 32 | typedef struct WebPIDecoder WebPIDecoder; 33 | typedef struct WebPBitstreamFeatures WebPBitstreamFeatures; 34 | typedef struct WebPDecoderOptions WebPDecoderOptions; 35 | typedef struct WebPDecoderConfig WebPDecoderConfig; 36 | 37 | // Return the decoder's version number, packed in hexadecimal using 8bits for 38 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507. 39 | WEBP_EXTERN int WebPGetDecoderVersion(void); 40 | 41 | // Retrieve basic header information: width, height. 42 | // This function will also validate the header, returning true on success, 43 | // false otherwise. '*width' and '*height' are only valid on successful return. 44 | // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant. 45 | // Note: The following chunk sequences (before the raw VP8/VP8L data) are 46 | // considered valid by this function: 47 | // RIFF + VP8(L) 48 | // RIFF + VP8X + (optional chunks) + VP8(L) 49 | // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. 50 | // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. 51 | WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size, 52 | int* width, int* height); 53 | 54 | // Decodes WebP images pointed to by 'data' and returns RGBA samples, along 55 | // with the dimensions in *width and *height. The ordering of samples in 56 | // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). 57 | // The returned pointer should be deleted calling WebPFree(). 58 | // Returns NULL in case of error. 59 | WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, 60 | int* width, int* height); 61 | 62 | // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. 63 | WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, 64 | int* width, int* height); 65 | 66 | // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. 67 | WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, 68 | int* width, int* height); 69 | 70 | // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. 71 | // If the bitstream contains transparency, it is ignored. 72 | WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, 73 | int* width, int* height); 74 | 75 | // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. 76 | WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, 77 | int* width, int* height); 78 | 79 | 80 | // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer 81 | // returned is the Y samples buffer. Upon return, *u and *v will point to 82 | // the U and V chroma data. These U and V buffers need NOT be passed to 83 | // WebPFree(), unlike the returned Y luma one. The dimension of the U and V 84 | // planes are both (*width + 1) / 2 and (*height + 1)/ 2. 85 | // Upon return, the Y buffer has a stride returned as '*stride', while U and V 86 | // have a common stride returned as '*uv_stride'. 87 | // Return NULL in case of error. 88 | // (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr 89 | WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size, 90 | int* width, int* height, 91 | uint8_t** u, uint8_t** v, 92 | int* stride, int* uv_stride); 93 | 94 | // These five functions are variants of the above ones, that decode the image 95 | // directly into a pre-allocated buffer 'output_buffer'. The maximum storage 96 | // available in this buffer is indicated by 'output_buffer_size'. If this 97 | // storage is not sufficient (or an error occurred), NULL is returned. 98 | // Otherwise, output_buffer is returned, for convenience. 99 | // The parameter 'output_stride' specifies the distance (in bytes) 100 | // between scanlines. Hence, output_buffer_size is expected to be at least 101 | // output_stride x picture-height. 102 | WEBP_EXTERN uint8_t* WebPDecodeRGBAInto( 103 | const uint8_t* data, size_t data_size, 104 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 105 | WEBP_EXTERN uint8_t* WebPDecodeARGBInto( 106 | const uint8_t* data, size_t data_size, 107 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 108 | WEBP_EXTERN uint8_t* WebPDecodeBGRAInto( 109 | const uint8_t* data, size_t data_size, 110 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 111 | 112 | // RGB and BGR variants. Here too the transparency information, if present, 113 | // will be dropped and ignored. 114 | WEBP_EXTERN uint8_t* WebPDecodeRGBInto( 115 | const uint8_t* data, size_t data_size, 116 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 117 | WEBP_EXTERN uint8_t* WebPDecodeBGRInto( 118 | const uint8_t* data, size_t data_size, 119 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 120 | 121 | // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly 122 | // into pre-allocated luma/chroma plane buffers. This function requires the 123 | // strides to be passed: one for the luma plane and one for each of the 124 | // chroma ones. The size of each plane buffer is passed as 'luma_size', 125 | // 'u_size' and 'v_size' respectively. 126 | // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred 127 | // during decoding (or because some buffers were found to be too small). 128 | WEBP_EXTERN uint8_t* WebPDecodeYUVInto( 129 | const uint8_t* data, size_t data_size, 130 | uint8_t* luma, size_t luma_size, int luma_stride, 131 | uint8_t* u, size_t u_size, int u_stride, 132 | uint8_t* v, size_t v_size, int v_stride); 133 | 134 | //------------------------------------------------------------------------------ 135 | // Output colorspaces and buffer 136 | 137 | // Colorspaces 138 | // Note: the naming describes the byte-ordering of packed samples in memory. 139 | // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... 140 | // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. 141 | // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: 142 | // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... 143 | // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... 144 | // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for 145 | // these two modes: 146 | // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... 147 | // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... 148 | 149 | typedef enum WEBP_CSP_MODE { 150 | MODE_RGB = 0, MODE_RGBA = 1, 151 | MODE_BGR = 2, MODE_BGRA = 3, 152 | MODE_ARGB = 4, MODE_RGBA_4444 = 5, 153 | MODE_RGB_565 = 6, 154 | // RGB-premultiplied transparent modes (alpha value is preserved) 155 | MODE_rgbA = 7, 156 | MODE_bgrA = 8, 157 | MODE_Argb = 9, 158 | MODE_rgbA_4444 = 10, 159 | // YUV modes must come after RGB ones. 160 | MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 161 | MODE_LAST = 13 162 | } WEBP_CSP_MODE; 163 | 164 | // Some useful macros: 165 | static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { 166 | return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || 167 | mode == MODE_rgbA_4444); 168 | } 169 | 170 | static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { 171 | return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || 172 | mode == MODE_RGBA_4444 || mode == MODE_YUVA || 173 | WebPIsPremultipliedMode(mode)); 174 | } 175 | 176 | static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { 177 | return (mode < MODE_YUV); 178 | } 179 | 180 | //------------------------------------------------------------------------------ 181 | // WebPDecBuffer: Generic structure for describing the output sample buffer. 182 | 183 | struct WebPRGBABuffer { // view as RGBA 184 | uint8_t* rgba; // pointer to RGBA samples 185 | int stride; // stride in bytes from one scanline to the next. 186 | size_t size; // total size of the *rgba buffer. 187 | }; 188 | 189 | struct WebPYUVABuffer { // view as YUVA 190 | uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples 191 | int y_stride; // luma stride 192 | int u_stride, v_stride; // chroma strides 193 | int a_stride; // alpha stride 194 | size_t y_size; // luma plane size 195 | size_t u_size, v_size; // chroma planes size 196 | size_t a_size; // alpha-plane size 197 | }; 198 | 199 | // Output buffer 200 | struct WebPDecBuffer { 201 | WEBP_CSP_MODE colorspace; // Colorspace. 202 | int width, height; // Dimensions. 203 | int is_external_memory; // If non-zero, 'internal_memory' pointer is not 204 | // used. If value is '2' or more, the external 205 | // memory is considered 'slow' and multiple 206 | // read/write will be avoided. 207 | union { 208 | WebPRGBABuffer RGBA; 209 | WebPYUVABuffer YUVA; 210 | } u; // Nameless union of buffer parameters. 211 | uint32_t pad[4]; // padding for later use 212 | 213 | uint8_t* private_memory; // Internally allocated memory (only when 214 | // is_external_memory is 0). Should not be used 215 | // externally, but accessed via the buffer union. 216 | }; 217 | 218 | // Internal, version-checked, entry point 219 | WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int); 220 | 221 | // Initialize the structure as empty. Must be called before any other use. 222 | // Returns false in case of version mismatch 223 | static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { 224 | return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); 225 | } 226 | 227 | // Free any memory associated with the buffer. Must always be called last. 228 | // Note: doesn't free the 'buffer' structure itself. 229 | WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer); 230 | 231 | //------------------------------------------------------------------------------ 232 | // Enumeration of the status codes 233 | 234 | typedef enum VP8StatusCode { 235 | VP8_STATUS_OK = 0, 236 | VP8_STATUS_OUT_OF_MEMORY, 237 | VP8_STATUS_INVALID_PARAM, 238 | VP8_STATUS_BITSTREAM_ERROR, 239 | VP8_STATUS_UNSUPPORTED_FEATURE, 240 | VP8_STATUS_SUSPENDED, 241 | VP8_STATUS_USER_ABORT, 242 | VP8_STATUS_NOT_ENOUGH_DATA 243 | } VP8StatusCode; 244 | 245 | //------------------------------------------------------------------------------ 246 | // Incremental decoding 247 | // 248 | // This API allows streamlined decoding of partial data. 249 | // Picture can be incrementally decoded as data become available thanks to the 250 | // WebPIDecoder object. This object can be left in a SUSPENDED state if the 251 | // picture is only partially decoded, pending additional input. 252 | // Code example: 253 | // 254 | // WebPInitDecBuffer(&output_buffer); 255 | // output_buffer.colorspace = mode; 256 | // ... 257 | // WebPIDecoder* idec = WebPINewDecoder(&output_buffer); 258 | // while (additional_data_is_available) { 259 | // // ... (get additional data in some new_data[] buffer) 260 | // status = WebPIAppend(idec, new_data, new_data_size); 261 | // if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { 262 | // break; // an error occurred. 263 | // } 264 | // 265 | // // The above call decodes the current available buffer. 266 | // // Part of the image can now be refreshed by calling 267 | // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. 268 | // } 269 | // WebPIDelete(idec); 270 | 271 | // Creates a new incremental decoder with the supplied buffer parameter. 272 | // This output_buffer can be passed NULL, in which case a default output buffer 273 | // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' 274 | // is kept, which means that the lifespan of 'output_buffer' must be larger than 275 | // that of the returned WebPIDecoder object. 276 | // The supplied 'output_buffer' content MUST NOT be changed between calls to 277 | // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is 278 | // not set to 0. In such a case, it is allowed to modify the pointers, size and 279 | // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain 280 | // within valid bounds. 281 | // All other fields of WebPDecBuffer MUST remain constant between calls. 282 | // Returns NULL if the allocation failed. 283 | WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer); 284 | 285 | // This function allocates and initializes an incremental-decoder object, which 286 | // will output the RGB/A samples specified by 'csp' into a preallocated 287 | // buffer 'output_buffer'. The size of this buffer is at least 288 | // 'output_buffer_size' and the stride (distance in bytes between two scanlines) 289 | // is specified by 'output_stride'. 290 | // Additionally, output_buffer can be passed NULL in which case the output 291 | // buffer will be allocated automatically when the decoding starts. The 292 | // colorspace 'csp' is taken into account for allocating this buffer. All other 293 | // parameters are ignored. 294 | // Returns NULL if the allocation failed, or if some parameters are invalid. 295 | WEBP_EXTERN WebPIDecoder* WebPINewRGB( 296 | WEBP_CSP_MODE csp, 297 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 298 | 299 | // This function allocates and initializes an incremental-decoder object, which 300 | // will output the raw luma/chroma samples into a preallocated planes if 301 | // supplied. The luma plane is specified by its pointer 'luma', its size 302 | // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane 303 | // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v 304 | // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer 305 | // can be pass NULL in case one is not interested in the transparency plane. 306 | // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied. 307 | // In this case, the output buffer will be automatically allocated (using 308 | // MODE_YUVA) when decoding starts. All parameters are then ignored. 309 | // Returns NULL if the allocation failed or if a parameter is invalid. 310 | WEBP_EXTERN WebPIDecoder* WebPINewYUVA( 311 | uint8_t* luma, size_t luma_size, int luma_stride, 312 | uint8_t* u, size_t u_size, int u_stride, 313 | uint8_t* v, size_t v_size, int v_stride, 314 | uint8_t* a, size_t a_size, int a_stride); 315 | 316 | // Deprecated version of the above, without the alpha plane. 317 | // Kept for backward compatibility. 318 | WEBP_EXTERN WebPIDecoder* WebPINewYUV( 319 | uint8_t* luma, size_t luma_size, int luma_stride, 320 | uint8_t* u, size_t u_size, int u_stride, 321 | uint8_t* v, size_t v_size, int v_stride); 322 | 323 | // Deletes the WebPIDecoder object and associated memory. Must always be called 324 | // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. 325 | WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec); 326 | 327 | // Copies and decodes the next available data. Returns VP8_STATUS_OK when 328 | // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more 329 | // data is expected. Returns error in other cases. 330 | WEBP_EXTERN VP8StatusCode WebPIAppend( 331 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 332 | 333 | // A variant of the above function to be used when data buffer contains 334 | // partial data from the beginning. In this case data buffer is not copied 335 | // to the internal memory. 336 | // Note that the value of the 'data' pointer can change between calls to 337 | // WebPIUpdate, for instance when the data buffer is resized to fit larger data. 338 | WEBP_EXTERN VP8StatusCode WebPIUpdate( 339 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 340 | 341 | // Returns the RGB/A image decoded so far. Returns NULL if output params 342 | // are not initialized yet. The RGB/A output type corresponds to the colorspace 343 | // specified during call to WebPINewDecoder() or WebPINewRGB(). 344 | // *last_y is the index of last decoded row in raster scan order. Some pointers 345 | // (*last_y, *width etc.) can be NULL if corresponding information is not 346 | // needed. The values in these pointers are only valid on successful (non-NULL) 347 | // return. 348 | WEBP_EXTERN uint8_t* WebPIDecGetRGB( 349 | const WebPIDecoder* idec, int* last_y, 350 | int* width, int* height, int* stride); 351 | 352 | // Same as above function to get a YUVA image. Returns pointer to the luma 353 | // plane or NULL in case of error. If there is no alpha information 354 | // the alpha pointer '*a' will be returned NULL. 355 | WEBP_EXTERN uint8_t* WebPIDecGetYUVA( 356 | const WebPIDecoder* idec, int* last_y, 357 | uint8_t** u, uint8_t** v, uint8_t** a, 358 | int* width, int* height, int* stride, int* uv_stride, int* a_stride); 359 | 360 | // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the 361 | // alpha information (if present). Kept for backward compatibility. 362 | static WEBP_INLINE uint8_t* WebPIDecGetYUV( 363 | const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, 364 | int* width, int* height, int* stride, int* uv_stride) { 365 | return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, 366 | stride, uv_stride, NULL); 367 | } 368 | 369 | // Generic call to retrieve information about the displayable area. 370 | // If non NULL, the left/right/width/height pointers are filled with the visible 371 | // rectangular area so far. 372 | // Returns NULL in case the incremental decoder object is in an invalid state. 373 | // Otherwise returns the pointer to the internal representation. This structure 374 | // is read-only, tied to WebPIDecoder's lifespan and should not be modified. 375 | WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea( 376 | const WebPIDecoder* idec, int* left, int* top, int* width, int* height); 377 | 378 | //------------------------------------------------------------------------------ 379 | // Advanced decoding parametrization 380 | // 381 | // Code sample for using the advanced decoding API 382 | /* 383 | // A) Init a configuration object 384 | WebPDecoderConfig config; 385 | CHECK(WebPInitDecoderConfig(&config)); 386 | 387 | // B) optional: retrieve the bitstream's features. 388 | CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); 389 | 390 | // C) Adjust 'config', if needed 391 | config.no_fancy_upsampling = 1; 392 | config.output.colorspace = MODE_BGRA; 393 | // etc. 394 | 395 | // Note that you can also make config.output point to an externally 396 | // supplied memory buffer, provided it's big enough to store the decoded 397 | // picture. Otherwise, config.output will just be used to allocate memory 398 | // and store the decoded picture. 399 | 400 | // D) Decode! 401 | CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); 402 | 403 | // E) Decoded image is now in config.output (and config.output.u.RGBA) 404 | 405 | // F) Reclaim memory allocated in config's object. It's safe to call 406 | // this function even if the memory is external and wasn't allocated 407 | // by WebPDecode(). 408 | WebPFreeDecBuffer(&config.output); 409 | */ 410 | 411 | // Features gathered from the bitstream 412 | struct WebPBitstreamFeatures { 413 | int width; // Width in pixels, as read from the bitstream. 414 | int height; // Height in pixels, as read from the bitstream. 415 | int has_alpha; // True if the bitstream contains an alpha channel. 416 | int has_animation; // True if the bitstream is an animation. 417 | int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless 418 | 419 | uint32_t pad[5]; // padding for later use 420 | }; 421 | 422 | // Internal, version-checked, entry point 423 | WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal( 424 | const uint8_t*, size_t, WebPBitstreamFeatures*, int); 425 | 426 | // Retrieve features from the bitstream. The *features structure is filled 427 | // with information gathered from the bitstream. 428 | // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns 429 | // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the 430 | // features from headers. Returns error in other cases. 431 | // Note: The following chunk sequences (before the raw VP8/VP8L data) are 432 | // considered valid by this function: 433 | // RIFF + VP8(L) 434 | // RIFF + VP8X + (optional chunks) + VP8(L) 435 | // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. 436 | // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. 437 | static WEBP_INLINE VP8StatusCode WebPGetFeatures( 438 | const uint8_t* data, size_t data_size, 439 | WebPBitstreamFeatures* features) { 440 | return WebPGetFeaturesInternal(data, data_size, features, 441 | WEBP_DECODER_ABI_VERSION); 442 | } 443 | 444 | // Decoding options 445 | struct WebPDecoderOptions { 446 | int bypass_filtering; // if true, skip the in-loop filtering 447 | int no_fancy_upsampling; // if true, use faster pointwise upsampler 448 | int use_cropping; // if true, cropping is applied _first_ 449 | int crop_left, crop_top; // top-left position for cropping. 450 | // Will be snapped to even values. 451 | int crop_width, crop_height; // dimension of the cropping area 452 | int use_scaling; // if true, scaling is applied _afterward_ 453 | int scaled_width, scaled_height; // final resolution 454 | int use_threads; // if true, use multi-threaded decoding 455 | int dithering_strength; // dithering strength (0=Off, 100=full) 456 | int flip; // if true, flip output vertically 457 | int alpha_dithering_strength; // alpha dithering strength in [0..100] 458 | 459 | uint32_t pad[5]; // padding for later use 460 | }; 461 | 462 | // Main object storing the configuration for advanced decoding. 463 | struct WebPDecoderConfig { 464 | WebPBitstreamFeatures input; // Immutable bitstream features (optional) 465 | WebPDecBuffer output; // Output buffer (can point to external mem) 466 | WebPDecoderOptions options; // Decoding options 467 | }; 468 | 469 | // Internal, version-checked, entry point 470 | WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int); 471 | 472 | // Initialize the configuration as empty. This function must always be 473 | // called first, unless WebPGetFeatures() is to be called. 474 | // Returns false in case of mismatched version. 475 | static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) { 476 | return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); 477 | } 478 | 479 | // Instantiate a new incremental decoder object with the requested 480 | // configuration. The bitstream can be passed using 'data' and 'data_size' 481 | // parameter, in which case the features will be parsed and stored into 482 | // config->input. Otherwise, 'data' can be NULL and no parsing will occur. 483 | // Note that 'config' can be NULL too, in which case a default configuration 484 | // is used. If 'config' is not NULL, it must outlive the WebPIDecoder object 485 | // as some references to its fields will be used. No internal copy of 'config' 486 | // is made. 487 | // The return WebPIDecoder object must always be deleted calling WebPIDelete(). 488 | // Returns NULL in case of error (and config->status will then reflect 489 | // the error condition, if available). 490 | WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size, 491 | WebPDecoderConfig* config); 492 | 493 | // Non-incremental version. This version decodes the full data at once, taking 494 | // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK 495 | // if the decoding was successful). Note that 'config' cannot be NULL. 496 | WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, 497 | WebPDecoderConfig* config); 498 | 499 | #ifdef __cplusplus 500 | } // extern "C" 501 | #endif 502 | 503 | #endif // WEBP_WEBP_DECODE_H_ 504 | -------------------------------------------------------------------------------- /third/libwebp/include/demux.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Demux API. 11 | // Enables extraction of image and extended format data from WebP files. 12 | 13 | // Code Example: Demuxing WebP data to extract all the frames, ICC profile 14 | // and EXIF/XMP metadata. 15 | /* 16 | WebPDemuxer* demux = WebPDemux(&webp_data); 17 | 18 | uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 19 | uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 20 | // ... (Get information about the features present in the WebP file). 21 | uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); 22 | 23 | // ... (Iterate over all frames). 24 | WebPIterator iter; 25 | if (WebPDemuxGetFrame(demux, 1, &iter)) { 26 | do { 27 | // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), 28 | // ... and get other frame properties like width, height, offsets etc. 29 | // ... see 'struct WebPIterator' below for more info). 30 | } while (WebPDemuxNextFrame(&iter)); 31 | WebPDemuxReleaseIterator(&iter); 32 | } 33 | 34 | // ... (Extract metadata). 35 | WebPChunkIterator chunk_iter; 36 | if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); 37 | // ... (Consume the ICC profile in 'chunk_iter.chunk'). 38 | WebPDemuxReleaseChunkIterator(&chunk_iter); 39 | if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); 40 | // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). 41 | WebPDemuxReleaseChunkIterator(&chunk_iter); 42 | if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); 43 | // ... (Consume the XMP metadata in 'chunk_iter.chunk'). 44 | WebPDemuxReleaseChunkIterator(&chunk_iter); 45 | WebPDemuxDelete(demux); 46 | */ 47 | 48 | #ifndef WEBP_WEBP_DEMUX_H_ 49 | #define WEBP_WEBP_DEMUX_H_ 50 | 51 | #include "./decode.h" // for WEBP_CSP_MODE 52 | #include "./mux_types.h" 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | #define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b) 59 | 60 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 61 | // the types are left here for reference. 62 | // typedef enum WebPDemuxState WebPDemuxState; 63 | // typedef enum WebPFormatFeature WebPFormatFeature; 64 | typedef struct WebPDemuxer WebPDemuxer; 65 | typedef struct WebPIterator WebPIterator; 66 | typedef struct WebPChunkIterator WebPChunkIterator; 67 | typedef struct WebPAnimInfo WebPAnimInfo; 68 | typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions; 69 | 70 | //------------------------------------------------------------------------------ 71 | 72 | // Returns the version number of the demux library, packed in hexadecimal using 73 | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. 74 | WEBP_EXTERN int WebPGetDemuxVersion(void); 75 | 76 | //------------------------------------------------------------------------------ 77 | // Life of a Demux object 78 | 79 | typedef enum WebPDemuxState { 80 | WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing. 81 | WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header. 82 | WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete, 83 | // data may be available. 84 | WEBP_DEMUX_DONE = 2 // Entire file has been parsed. 85 | } WebPDemuxState; 86 | 87 | // Internal, version-checked, entry point 88 | WEBP_EXTERN WebPDemuxer* WebPDemuxInternal( 89 | const WebPData*, int, WebPDemuxState*, int); 90 | 91 | // Parses the full WebP file given by 'data'. For single images the WebP file 92 | // header alone or the file header and the chunk header may be absent. 93 | // Returns a WebPDemuxer object on successful parse, NULL otherwise. 94 | static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { 95 | return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); 96 | } 97 | 98 | // Parses the possibly incomplete WebP file given by 'data'. 99 | // If 'state' is non-NULL it will be set to indicate the status of the demuxer. 100 | // Returns NULL in case of error or if there isn't enough data to start parsing; 101 | // and a WebPDemuxer object on successful parse. 102 | // Note that WebPDemuxer keeps internal pointers to 'data' memory segment. 103 | // If this data is volatile, the demuxer object should be deleted (by calling 104 | // WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data. 105 | // This is usually an inexpensive operation. 106 | static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( 107 | const WebPData* data, WebPDemuxState* state) { 108 | return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); 109 | } 110 | 111 | // Frees memory associated with 'dmux'. 112 | WEBP_EXTERN void WebPDemuxDelete(WebPDemuxer* dmux); 113 | 114 | //------------------------------------------------------------------------------ 115 | // Data/information extraction. 116 | 117 | typedef enum WebPFormatFeature { 118 | WEBP_FF_FORMAT_FLAGS, // bit-wise combination of WebPFeatureFlags 119 | // corresponding to the 'VP8X' chunk (if present). 120 | WEBP_FF_CANVAS_WIDTH, 121 | WEBP_FF_CANVAS_HEIGHT, 122 | WEBP_FF_LOOP_COUNT, // only relevant for animated file 123 | WEBP_FF_BACKGROUND_COLOR, // idem. 124 | WEBP_FF_FRAME_COUNT // Number of frames present in the demux object. 125 | // In case of a partial demux, this is the number 126 | // of frames seen so far, with the last frame 127 | // possibly being partial. 128 | } WebPFormatFeature; 129 | 130 | // Get the 'feature' value from the 'dmux'. 131 | // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() 132 | // returned a state > WEBP_DEMUX_PARSING_HEADER. 133 | // If 'feature' is WEBP_FF_FORMAT_FLAGS, the returned value is a bit-wise 134 | // combination of WebPFeatureFlags values. 135 | // If 'feature' is WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, the returned 136 | // value is only meaningful if the bitstream is animated. 137 | WEBP_EXTERN uint32_t WebPDemuxGetI( 138 | const WebPDemuxer* dmux, WebPFormatFeature feature); 139 | 140 | //------------------------------------------------------------------------------ 141 | // Frame iteration. 142 | 143 | struct WebPIterator { 144 | int frame_num; 145 | int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. 146 | int x_offset, y_offset; // offset relative to the canvas. 147 | int width, height; // dimensions of this frame. 148 | int duration; // display duration in milliseconds. 149 | WebPMuxAnimDispose dispose_method; // dispose method for the frame. 150 | int complete; // true if 'fragment' contains a full frame. partial images 151 | // may still be decoded with the WebP incremental decoder. 152 | WebPData fragment; // The frame given by 'frame_num'. Note for historical 153 | // reasons this is called a fragment. 154 | int has_alpha; // True if the frame contains transparency. 155 | WebPMuxAnimBlend blend_method; // Blend operation for the frame. 156 | 157 | uint32_t pad[2]; // padding for later use. 158 | void* private_; // for internal use only. 159 | }; 160 | 161 | // Retrieves frame 'frame_number' from 'dmux'. 162 | // 'iter->fragment' points to the frame on return from this function. 163 | // Setting 'frame_number' equal to 0 will return the last frame of the image. 164 | // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. 165 | // Call WebPDemuxReleaseIterator() when use of the iterator is complete. 166 | // NOTE: 'dmux' must persist for the lifetime of 'iter'. 167 | WEBP_EXTERN int WebPDemuxGetFrame( 168 | const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); 169 | 170 | // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or 171 | // previous ('iter->frame_num' - 1) frame. These functions do not loop. 172 | // Returns true on success, false otherwise. 173 | WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter); 174 | WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter); 175 | 176 | // Releases any memory associated with 'iter'. 177 | // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same 178 | // iter. Also, must be called before destroying the associated WebPDemuxer with 179 | // WebPDemuxDelete(). 180 | WEBP_EXTERN void WebPDemuxReleaseIterator(WebPIterator* iter); 181 | 182 | //------------------------------------------------------------------------------ 183 | // Chunk iteration. 184 | 185 | struct WebPChunkIterator { 186 | // The current and total number of chunks with the fourcc given to 187 | // WebPDemuxGetChunk(). 188 | int chunk_num; 189 | int num_chunks; 190 | WebPData chunk; // The payload of the chunk. 191 | 192 | uint32_t pad[6]; // padding for later use 193 | void* private_; 194 | }; 195 | 196 | // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from 197 | // 'dmux'. 198 | // 'fourcc' is a character array containing the fourcc of the chunk to return, 199 | // e.g., "ICCP", "XMP ", "EXIF", etc. 200 | // Setting 'chunk_number' equal to 0 will return the last chunk in a set. 201 | // Returns true if the chunk is found, false otherwise. Image related chunk 202 | // payloads are accessed through WebPDemuxGetFrame() and related functions. 203 | // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. 204 | // NOTE: 'dmux' must persist for the lifetime of the iterator. 205 | WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux, 206 | const char fourcc[4], int chunk_number, 207 | WebPChunkIterator* iter); 208 | 209 | // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous 210 | // ('iter->chunk_num' - 1) chunk. These functions do not loop. 211 | // Returns true on success, false otherwise. 212 | WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter); 213 | WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter); 214 | 215 | // Releases any memory associated with 'iter'. 216 | // Must be called before destroying the associated WebPDemuxer with 217 | // WebPDemuxDelete(). 218 | WEBP_EXTERN void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); 219 | 220 | //------------------------------------------------------------------------------ 221 | // WebPAnimDecoder API 222 | // 223 | // This API allows decoding (possibly) animated WebP images. 224 | // 225 | // Code Example: 226 | /* 227 | WebPAnimDecoderOptions dec_options; 228 | WebPAnimDecoderOptionsInit(&dec_options); 229 | // Tune 'dec_options' as needed. 230 | WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options); 231 | WebPAnimInfo anim_info; 232 | WebPAnimDecoderGetInfo(dec, &anim_info); 233 | for (uint32_t i = 0; i < anim_info.loop_count; ++i) { 234 | while (WebPAnimDecoderHasMoreFrames(dec)) { 235 | uint8_t* buf; 236 | int timestamp; 237 | WebPAnimDecoderGetNext(dec, &buf, ×tamp); 238 | // ... (Render 'buf' based on 'timestamp'). 239 | // ... (Do NOT free 'buf', as it is owned by 'dec'). 240 | } 241 | WebPAnimDecoderReset(dec); 242 | } 243 | const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec); 244 | // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data). 245 | WebPAnimDecoderDelete(dec); 246 | */ 247 | 248 | typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object. 249 | 250 | // Global options. 251 | struct WebPAnimDecoderOptions { 252 | // Output colorspace. Only the following modes are supported: 253 | // MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA. 254 | WEBP_CSP_MODE color_mode; 255 | int use_threads; // If true, use multi-threaded decoding. 256 | uint32_t padding[7]; // Padding for later use. 257 | }; 258 | 259 | // Internal, version-checked, entry point. 260 | WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal( 261 | WebPAnimDecoderOptions*, int); 262 | 263 | // Should always be called, to initialize a fresh WebPAnimDecoderOptions 264 | // structure before modification. Returns false in case of version mismatch. 265 | // WebPAnimDecoderOptionsInit() must have succeeded before using the 266 | // 'dec_options' object. 267 | static WEBP_INLINE int WebPAnimDecoderOptionsInit( 268 | WebPAnimDecoderOptions* dec_options) { 269 | return WebPAnimDecoderOptionsInitInternal(dec_options, 270 | WEBP_DEMUX_ABI_VERSION); 271 | } 272 | 273 | // Internal, version-checked, entry point. 274 | WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal( 275 | const WebPData*, const WebPAnimDecoderOptions*, int); 276 | 277 | // Creates and initializes a WebPAnimDecoder object. 278 | // Parameters: 279 | // webp_data - (in) WebP bitstream. This should remain unchanged during the 280 | // lifetime of the output WebPAnimDecoder object. 281 | // dec_options - (in) decoding options. Can be passed NULL to choose 282 | // reasonable defaults (in particular, color mode MODE_RGBA 283 | // will be picked). 284 | // Returns: 285 | // A pointer to the newly created WebPAnimDecoder object, or NULL in case of 286 | // parsing error, invalid option or memory error. 287 | static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew( 288 | const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) { 289 | return WebPAnimDecoderNewInternal(webp_data, dec_options, 290 | WEBP_DEMUX_ABI_VERSION); 291 | } 292 | 293 | // Global information about the animation.. 294 | struct WebPAnimInfo { 295 | uint32_t canvas_width; 296 | uint32_t canvas_height; 297 | uint32_t loop_count; 298 | uint32_t bgcolor; 299 | uint32_t frame_count; 300 | uint32_t pad[4]; // padding for later use 301 | }; 302 | 303 | // Get global information about the animation. 304 | // Parameters: 305 | // dec - (in) decoder instance to get information from. 306 | // info - (out) global information fetched from the animation. 307 | // Returns: 308 | // True on success. 309 | WEBP_EXTERN int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec, 310 | WebPAnimInfo* info); 311 | 312 | // Fetch the next frame from 'dec' based on options supplied to 313 | // WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size 314 | // 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The 315 | // returned buffer 'buf' is valid only until the next call to 316 | // WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete(). 317 | // Parameters: 318 | // dec - (in/out) decoder instance from which the next frame is to be fetched. 319 | // buf - (out) decoded frame. 320 | // timestamp - (out) timestamp of the frame in milliseconds. 321 | // Returns: 322 | // False if any of the arguments are NULL, or if there is a parsing or 323 | // decoding error, or if there are no more frames. Otherwise, returns true. 324 | WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, 325 | uint8_t** buf, int* timestamp); 326 | 327 | // Check if there are more frames left to decode. 328 | // Parameters: 329 | // dec - (in) decoder instance to be checked. 330 | // Returns: 331 | // True if 'dec' is not NULL and some frames are yet to be decoded. 332 | // Otherwise, returns false. 333 | WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec); 334 | 335 | // Resets the WebPAnimDecoder object, so that next call to 336 | // WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be 337 | // helpful when all frames need to be decoded multiple times (e.g. 338 | // info.loop_count times) without destroying and recreating the 'dec' object. 339 | // Parameters: 340 | // dec - (in/out) decoder instance to be reset 341 | WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec); 342 | 343 | // Grab the internal demuxer object. 344 | // Getting the demuxer object can be useful if one wants to use operations only 345 | // available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned 346 | // demuxer object is owned by 'dec' and is valid only until the next call to 347 | // WebPAnimDecoderDelete(). 348 | // 349 | // Parameters: 350 | // dec - (in) decoder instance from which the demuxer object is to be fetched. 351 | WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer( 352 | const WebPAnimDecoder* dec); 353 | 354 | // Deletes the WebPAnimDecoder object. 355 | // Parameters: 356 | // dec - (in/out) decoder instance to be deleted 357 | WEBP_EXTERN void WebPAnimDecoderDelete(WebPAnimDecoder* dec); 358 | 359 | #ifdef __cplusplus 360 | } // extern "C" 361 | #endif 362 | 363 | #endif // WEBP_WEBP_DEMUX_H_ 364 | -------------------------------------------------------------------------------- /third/libwebp/include/encode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // WebP encoder: main interface 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_ENCODE_H_ 15 | #define WEBP_WEBP_ENCODE_H_ 16 | 17 | #include "./types.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #define WEBP_ENCODER_ABI_VERSION 0x020f // MAJOR(8b) + MINOR(8b) 24 | 25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 26 | // the types are left here for reference. 27 | // typedef enum WebPImageHint WebPImageHint; 28 | // typedef enum WebPEncCSP WebPEncCSP; 29 | // typedef enum WebPPreset WebPPreset; 30 | // typedef enum WebPEncodingError WebPEncodingError; 31 | typedef struct WebPConfig WebPConfig; 32 | typedef struct WebPPicture WebPPicture; // main structure for I/O 33 | typedef struct WebPAuxStats WebPAuxStats; 34 | typedef struct WebPMemoryWriter WebPMemoryWriter; 35 | 36 | // Return the encoder's version number, packed in hexadecimal using 8bits for 37 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507. 38 | WEBP_EXTERN int WebPGetEncoderVersion(void); 39 | 40 | //------------------------------------------------------------------------------ 41 | // One-stop-shop call! No questions asked: 42 | 43 | // Returns the size of the compressed data (pointed to by *output), or 0 if 44 | // an error occurred. The compressed data must be released by the caller 45 | // using the call 'WebPFree(*output)'. 46 | // These functions compress using the lossy format, and the quality_factor 47 | // can go from 0 (smaller output, lower quality) to 100 (best quality, 48 | // larger output). 49 | WEBP_EXTERN size_t WebPEncodeRGB(const uint8_t* rgb, 50 | int width, int height, int stride, 51 | float quality_factor, uint8_t** output); 52 | WEBP_EXTERN size_t WebPEncodeBGR(const uint8_t* bgr, 53 | int width, int height, int stride, 54 | float quality_factor, uint8_t** output); 55 | WEBP_EXTERN size_t WebPEncodeRGBA(const uint8_t* rgba, 56 | int width, int height, int stride, 57 | float quality_factor, uint8_t** output); 58 | WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra, 59 | int width, int height, int stride, 60 | float quality_factor, uint8_t** output); 61 | 62 | // These functions are the equivalent of the above, but compressing in a 63 | // lossless manner. Files are usually larger than lossy format, but will 64 | // not suffer any compression loss. 65 | // Note these functions, like the lossy versions, use the library's default 66 | // settings. For lossless this means 'exact' is disabled. RGB values in 67 | // transparent areas will be modified to improve compression. To avoid this, 68 | // use WebPEncode() and set WebPConfig::exact to 1. 69 | WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb, 70 | int width, int height, int stride, 71 | uint8_t** output); 72 | WEBP_EXTERN size_t WebPEncodeLosslessBGR(const uint8_t* bgr, 73 | int width, int height, int stride, 74 | uint8_t** output); 75 | WEBP_EXTERN size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, 76 | int width, int height, int stride, 77 | uint8_t** output); 78 | WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, 79 | int width, int height, int stride, 80 | uint8_t** output); 81 | 82 | //------------------------------------------------------------------------------ 83 | // Coding parameters 84 | 85 | // Image characteristics hint for the underlying encoder. 86 | typedef enum WebPImageHint { 87 | WEBP_HINT_DEFAULT = 0, // default preset. 88 | WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot 89 | WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting 90 | WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). 91 | WEBP_HINT_LAST 92 | } WebPImageHint; 93 | 94 | // Compression parameters. 95 | struct WebPConfig { 96 | int lossless; // Lossless encoding (0=lossy(default), 1=lossless). 97 | float quality; // between 0 and 100. For lossy, 0 gives the smallest 98 | // size and 100 the largest. For lossless, this 99 | // parameter is the amount of effort put into the 100 | // compression: 0 is the fastest but gives larger 101 | // files compared to the slowest, but best, 100. 102 | int method; // quality/speed trade-off (0=fast, 6=slower-better) 103 | 104 | WebPImageHint image_hint; // Hint for image type (lossless only for now). 105 | 106 | int target_size; // if non-zero, set the desired target size in bytes. 107 | // Takes precedence over the 'compression' parameter. 108 | float target_PSNR; // if non-zero, specifies the minimal distortion to 109 | // try to achieve. Takes precedence over target_size. 110 | int segments; // maximum number of segments to use, in [1..4] 111 | int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum. 112 | int filter_strength; // range: [0 = off .. 100 = strongest] 113 | int filter_sharpness; // range: [0 = off .. 7 = least sharp] 114 | int filter_type; // filtering type: 0 = simple, 1 = strong (only used 115 | // if filter_strength > 0 or autofilter > 0) 116 | int autofilter; // Auto adjust filter's strength [0 = off, 1 = on] 117 | int alpha_compression; // Algorithm for encoding the alpha plane (0 = none, 118 | // 1 = compressed with WebP lossless). Default is 1. 119 | int alpha_filtering; // Predictive filtering method for alpha plane. 120 | // 0: none, 1: fast, 2: best. Default if 1. 121 | int alpha_quality; // Between 0 (smallest size) and 100 (lossless). 122 | // Default is 100. 123 | int pass; // number of entropy-analysis passes (in [1..10]). 124 | 125 | int show_compressed; // if true, export the compressed picture back. 126 | // In-loop filtering is not applied. 127 | int preprocessing; // preprocessing filter: 128 | // 0=none, 1=segment-smooth, 2=pseudo-random dithering 129 | int partitions; // log2(number of token partitions) in [0..3]. Default 130 | // is set to 0 for easier progressive decoding. 131 | int partition_limit; // quality degradation allowed to fit the 512k limit 132 | // on prediction modes coding (0: no degradation, 133 | // 100: maximum possible degradation). 134 | int emulate_jpeg_size; // If true, compression parameters will be remapped 135 | // to better match the expected output size from 136 | // JPEG compression. Generally, the output size will 137 | // be similar but the degradation will be lower. 138 | int thread_level; // If non-zero, try and use multi-threaded encoding. 139 | int low_memory; // If set, reduce memory usage (but increase CPU use). 140 | 141 | int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off 142 | // (default)]. 143 | int exact; // if non-zero, preserve the exact RGB values under 144 | // transparent area. Otherwise, discard this invisible 145 | // RGB information for better compression. The default 146 | // value is 0. 147 | 148 | int use_delta_palette; // reserved for future lossless feature 149 | int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion 150 | 151 | int qmin; // minimum permissible quality factor 152 | int qmax; // maximum permissible quality factor 153 | }; 154 | 155 | // Enumerate some predefined settings for WebPConfig, depending on the type 156 | // of source picture. These presets are used when calling WebPConfigPreset(). 157 | typedef enum WebPPreset { 158 | WEBP_PRESET_DEFAULT = 0, // default preset. 159 | WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot 160 | WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting 161 | WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details 162 | WEBP_PRESET_ICON, // small-sized colorful images 163 | WEBP_PRESET_TEXT // text-like 164 | } WebPPreset; 165 | 166 | // Internal, version-checked, entry point 167 | WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int); 168 | 169 | // Should always be called, to initialize a fresh WebPConfig structure before 170 | // modification. Returns false in case of version mismatch. WebPConfigInit() 171 | // must have succeeded before using the 'config' object. 172 | // Note that the default values are lossless=0 and quality=75. 173 | static WEBP_INLINE int WebPConfigInit(WebPConfig* config) { 174 | return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f, 175 | WEBP_ENCODER_ABI_VERSION); 176 | } 177 | 178 | // This function will initialize the configuration according to a predefined 179 | // set of parameters (referred to by 'preset') and a given quality factor. 180 | // This function can be called as a replacement to WebPConfigInit(). Will 181 | // return false in case of error. 182 | static WEBP_INLINE int WebPConfigPreset(WebPConfig* config, 183 | WebPPreset preset, float quality) { 184 | return WebPConfigInitInternal(config, preset, quality, 185 | WEBP_ENCODER_ABI_VERSION); 186 | } 187 | 188 | // Activate the lossless compression mode with the desired efficiency level 189 | // between 0 (fastest, lowest compression) and 9 (slower, best compression). 190 | // A good default level is '6', providing a fair tradeoff between compression 191 | // speed and final compressed size. 192 | // This function will overwrite several fields from config: 'method', 'quality' 193 | // and 'lossless'. Returns false in case of parameter error. 194 | WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level); 195 | 196 | // Returns true if 'config' is non-NULL and all configuration parameters are 197 | // within their valid ranges. 198 | WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config); 199 | 200 | //------------------------------------------------------------------------------ 201 | // Input / Output 202 | // Structure for storing auxiliary statistics. 203 | 204 | struct WebPAuxStats { 205 | int coded_size; // final size 206 | 207 | float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha 208 | int block_count[3]; // number of intra4/intra16/skipped macroblocks 209 | int header_bytes[2]; // approximate number of bytes spent for header 210 | // and mode-partition #0 211 | int residual_bytes[3][4]; // approximate number of bytes spent for 212 | // DC/AC/uv coefficients for each (0..3) segments. 213 | int segment_size[4]; // number of macroblocks in each segments 214 | int segment_quant[4]; // quantizer values for each segments 215 | int segment_level[4]; // filtering strength for each segments [0..63] 216 | 217 | int alpha_data_size; // size of the transparency data 218 | int layer_data_size; // size of the enhancement layer data 219 | 220 | // lossless encoder statistics 221 | uint32_t lossless_features; // bit0:predictor bit1:cross-color transform 222 | // bit2:subtract-green bit3:color indexing 223 | int histogram_bits; // number of precision bits of histogram 224 | int transform_bits; // precision bits for transform 225 | int cache_bits; // number of bits for color cache lookup 226 | int palette_size; // number of color in palette, if used 227 | int lossless_size; // final lossless size 228 | int lossless_hdr_size; // lossless header (transform, huffman etc) size 229 | int lossless_data_size; // lossless image data size 230 | 231 | uint32_t pad[2]; // padding for later use 232 | }; 233 | 234 | // Signature for output function. Should return true if writing was successful. 235 | // data/data_size is the segment of data to write, and 'picture' is for 236 | // reference (and so one can make use of picture->custom_ptr). 237 | typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size, 238 | const WebPPicture* picture); 239 | 240 | // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using 241 | // the following WebPMemoryWriter object (to be set as a custom_ptr). 242 | struct WebPMemoryWriter { 243 | uint8_t* mem; // final buffer (of size 'max_size', larger than 'size'). 244 | size_t size; // final size 245 | size_t max_size; // total capacity 246 | uint32_t pad[1]; // padding for later use 247 | }; 248 | 249 | // The following must be called first before any use. 250 | WEBP_EXTERN void WebPMemoryWriterInit(WebPMemoryWriter* writer); 251 | 252 | // The following must be called to deallocate writer->mem memory. The 'writer' 253 | // object itself is not deallocated. 254 | WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer); 255 | // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon 256 | // completion, writer.mem and writer.size will hold the coded data. 257 | // writer.mem must be freed by calling WebPMemoryWriterClear. 258 | WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size, 259 | const WebPPicture* picture); 260 | 261 | // Progress hook, called from time to time to report progress. It can return 262 | // false to request an abort of the encoding process, or true otherwise if 263 | // everything is OK. 264 | typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture); 265 | 266 | // Color spaces. 267 | typedef enum WebPEncCSP { 268 | // chroma sampling 269 | WEBP_YUV420 = 0, // 4:2:0 270 | WEBP_YUV420A = 4, // alpha channel variant 271 | WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors 272 | WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present 273 | } WebPEncCSP; 274 | 275 | // Encoding error conditions. 276 | typedef enum WebPEncodingError { 277 | VP8_ENC_OK = 0, 278 | VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects 279 | VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits 280 | VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL 281 | VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid 282 | VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height 283 | VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k 284 | VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M 285 | VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes 286 | VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G 287 | VP8_ENC_ERROR_USER_ABORT, // abort request by user 288 | VP8_ENC_ERROR_LAST // list terminator. always last. 289 | } WebPEncodingError; 290 | 291 | // maximum width/height allowed (inclusive), in pixels 292 | #define WEBP_MAX_DIMENSION 16383 293 | 294 | // Main exchange structure (input samples, output bytes, statistics) 295 | // 296 | // Once WebPPictureInit() has been called, it's ok to make all the INPUT fields 297 | // (use_argb, y/u/v, argb, ...) point to user-owned data, even if 298 | // WebPPictureAlloc() has been called. Depending on the value use_argb, 299 | // it's guaranteed that either *argb or *y/*u/*v content will be kept untouched. 300 | struct WebPPicture { 301 | // INPUT 302 | ////////////// 303 | // Main flag for encoder selecting between ARGB or YUV input. 304 | // It is recommended to use ARGB input (*argb, argb_stride) for lossless 305 | // compression, and YUV input (*y, *u, *v, etc.) for lossy compression 306 | // since these are the respective native colorspace for these formats. 307 | int use_argb; 308 | 309 | // YUV input (mostly used for input to lossy compression) 310 | WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr). 311 | int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION) 312 | uint8_t* y, *u, *v; // pointers to luma/chroma planes. 313 | int y_stride, uv_stride; // luma/chroma strides. 314 | uint8_t* a; // pointer to the alpha plane 315 | int a_stride; // stride of the alpha plane 316 | uint32_t pad1[2]; // padding for later use 317 | 318 | // ARGB input (mostly used for input to lossless compression) 319 | uint32_t* argb; // Pointer to argb (32 bit) plane. 320 | int argb_stride; // This is stride in pixels units, not bytes. 321 | uint32_t pad2[3]; // padding for later use 322 | 323 | // OUTPUT 324 | /////////////// 325 | // Byte-emission hook, to store compressed bytes as they are ready. 326 | WebPWriterFunction writer; // can be NULL 327 | void* custom_ptr; // can be used by the writer. 328 | 329 | // map for extra information (only for lossy compression mode) 330 | int extra_info_type; // 1: intra type, 2: segment, 3: quant 331 | // 4: intra-16 prediction mode, 332 | // 5: chroma prediction mode, 333 | // 6: bit cost, 7: distortion 334 | uint8_t* extra_info; // if not NULL, points to an array of size 335 | // ((width + 15) / 16) * ((height + 15) / 16) that 336 | // will be filled with a macroblock map, depending 337 | // on extra_info_type. 338 | 339 | // STATS AND REPORTS 340 | /////////////////////////// 341 | // Pointer to side statistics (updated only if not NULL) 342 | WebPAuxStats* stats; 343 | 344 | // Error code for the latest error encountered during encoding 345 | WebPEncodingError error_code; 346 | 347 | // If not NULL, report progress during encoding. 348 | WebPProgressHook progress_hook; 349 | 350 | void* user_data; // this field is free to be set to any value and 351 | // used during callbacks (like progress-report e.g.). 352 | 353 | uint32_t pad3[3]; // padding for later use 354 | 355 | // Unused for now 356 | uint8_t* pad4, *pad5; 357 | uint32_t pad6[8]; // padding for later use 358 | 359 | // PRIVATE FIELDS 360 | //////////////////// 361 | void* memory_; // row chunk of memory for yuva planes 362 | void* memory_argb_; // and for argb too. 363 | void* pad7[2]; // padding for later use 364 | }; 365 | 366 | // Internal, version-checked, entry point 367 | WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int); 368 | 369 | // Should always be called, to initialize the structure. Returns false in case 370 | // of version mismatch. WebPPictureInit() must have succeeded before using the 371 | // 'picture' object. 372 | // Note that, by default, use_argb is false and colorspace is WEBP_YUV420. 373 | static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) { 374 | return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION); 375 | } 376 | 377 | //------------------------------------------------------------------------------ 378 | // WebPPicture utils 379 | 380 | // Convenience allocation / deallocation based on picture->width/height: 381 | // Allocate y/u/v buffers as per colorspace/width/height specification. 382 | // Note! This function will free the previous buffer if needed. 383 | // Returns false in case of memory error. 384 | WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture); 385 | 386 | // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*(). 387 | // Note that this function does _not_ free the memory used by the 'picture' 388 | // object itself. 389 | // Besides memory (which is reclaimed) all other fields of 'picture' are 390 | // preserved. 391 | WEBP_EXTERN void WebPPictureFree(WebPPicture* picture); 392 | 393 | // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst 394 | // will fully own the copied pixels (this is not a view). The 'dst' picture need 395 | // not be initialized as its content is overwritten. 396 | // Returns false in case of memory allocation error. 397 | WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst); 398 | 399 | // Compute the single distortion for packed planes of samples. 400 | // 'src' will be compared to 'ref', and the raw distortion stored into 401 | // '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be 402 | // stored in '*result'. 403 | // 'x_step' is the horizontal stride (in bytes) between samples. 404 | // 'src/ref_stride' is the byte distance between rows. 405 | // Returns false in case of error (bad parameter, memory allocation error, ...). 406 | WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride, 407 | const uint8_t* ref, size_t ref_stride, 408 | int width, int height, 409 | size_t x_step, 410 | int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM 411 | float* distortion, float* result); 412 | 413 | // Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results 414 | // are in dB, stored in result[] in the B/G/R/A/All order. The distortion is 415 | // always performed using ARGB samples. Hence if the input is YUV(A), the 416 | // picture will be internally converted to ARGB (just for the measurement). 417 | // Warning: this function is rather CPU-intensive. 418 | WEBP_EXTERN int WebPPictureDistortion( 419 | const WebPPicture* src, const WebPPicture* ref, 420 | int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM 421 | float result[5]); 422 | 423 | // self-crops a picture to the rectangle defined by top/left/width/height. 424 | // Returns false in case of memory allocation error, or if the rectangle is 425 | // outside of the source picture. 426 | // The rectangle for the view is defined by the top-left corner pixel 427 | // coordinates (left, top) as well as its width and height. This rectangle 428 | // must be fully be comprised inside the 'src' source picture. If the source 429 | // picture uses the YUV420 colorspace, the top and left coordinates will be 430 | // snapped to even values. 431 | WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture, 432 | int left, int top, int width, int height); 433 | 434 | // Extracts a view from 'src' picture into 'dst'. The rectangle for the view 435 | // is defined by the top-left corner pixel coordinates (left, top) as well 436 | // as its width and height. This rectangle must be fully be comprised inside 437 | // the 'src' source picture. If the source picture uses the YUV420 colorspace, 438 | // the top and left coordinates will be snapped to even values. 439 | // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed 440 | // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so, 441 | // the original dimension will be lost). Picture 'dst' need not be initialized 442 | // with WebPPictureInit() if it is different from 'src', since its content will 443 | // be overwritten. 444 | // Returns false in case of invalid parameters. 445 | WEBP_EXTERN int WebPPictureView(const WebPPicture* src, 446 | int left, int top, int width, int height, 447 | WebPPicture* dst); 448 | 449 | // Returns true if the 'picture' is actually a view and therefore does 450 | // not own the memory for pixels. 451 | WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture); 452 | 453 | // Rescale a picture to new dimension width x height. 454 | // If either 'width' or 'height' (but not both) is 0 the corresponding 455 | // dimension will be calculated preserving the aspect ratio. 456 | // No gamma correction is applied. 457 | // Returns false in case of error (invalid parameter or insufficient memory). 458 | WEBP_EXTERN int WebPPictureRescale(WebPPicture* picture, int width, int height); 459 | 460 | // Colorspace conversion function to import RGB samples. 461 | // Previous buffer will be free'd, if any. 462 | // *rgb buffer should have a size of at least height * rgb_stride. 463 | // Returns false in case of memory error. 464 | WEBP_EXTERN int WebPPictureImportRGB( 465 | WebPPicture* picture, const uint8_t* rgb, int rgb_stride); 466 | // Same, but for RGBA buffer. 467 | WEBP_EXTERN int WebPPictureImportRGBA( 468 | WebPPicture* picture, const uint8_t* rgba, int rgba_stride); 469 | // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format 470 | // input buffer ignoring the alpha channel. Avoids needing to copy the data 471 | // to a temporary 24-bit RGB buffer to import the RGB only. 472 | WEBP_EXTERN int WebPPictureImportRGBX( 473 | WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride); 474 | 475 | // Variants of the above, but taking BGR(A|X) input. 476 | WEBP_EXTERN int WebPPictureImportBGR( 477 | WebPPicture* picture, const uint8_t* bgr, int bgr_stride); 478 | WEBP_EXTERN int WebPPictureImportBGRA( 479 | WebPPicture* picture, const uint8_t* bgra, int bgra_stride); 480 | WEBP_EXTERN int WebPPictureImportBGRX( 481 | WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride); 482 | 483 | // Converts picture->argb data to the YUV420A format. The 'colorspace' 484 | // parameter is deprecated and should be equal to WEBP_YUV420. 485 | // Upon return, picture->use_argb is set to false. The presence of real 486 | // non-opaque transparent values is detected, and 'colorspace' will be 487 | // adjusted accordingly. Note that this method is lossy. 488 | // Returns false in case of error. 489 | WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture, 490 | WebPEncCSP /*colorspace = WEBP_YUV420*/); 491 | 492 | // Same as WebPPictureARGBToYUVA(), but the conversion is done using 493 | // pseudo-random dithering with a strength 'dithering' between 494 | // 0.0 (no dithering) and 1.0 (maximum dithering). This is useful 495 | // for photographic picture. 496 | WEBP_EXTERN int WebPPictureARGBToYUVADithered( 497 | WebPPicture* picture, WebPEncCSP colorspace, float dithering); 498 | 499 | // Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion. 500 | // Downsampling is handled with extra care in case of color clipping. This 501 | // method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better 502 | // and sharper YUV representation. 503 | // Returns false in case of error. 504 | WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture); 505 | // kept for backward compatibility: 506 | WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture); 507 | 508 | // Converts picture->yuv to picture->argb and sets picture->use_argb to true. 509 | // The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to 510 | // ARGB incurs a small loss too. 511 | // Note that the use of this colorspace is discouraged if one has access to the 512 | // raw ARGB samples, since using YUV420 is comparatively lossy. 513 | // Returns false in case of error. 514 | WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture); 515 | 516 | // Helper function: given a width x height plane of RGBA or YUV(A) samples 517 | // clean-up or smoothen the YUV or RGB samples under fully transparent area, 518 | // to help compressibility (no guarantee, though). 519 | WEBP_EXTERN void WebPCleanupTransparentArea(WebPPicture* picture); 520 | 521 | // Scan the picture 'picture' for the presence of non fully opaque alpha values. 522 | // Returns true in such case. Otherwise returns false (indicating that the 523 | // alpha plane can be ignored altogether e.g.). 524 | WEBP_EXTERN int WebPPictureHasTransparency(const WebPPicture* picture); 525 | 526 | // Remove the transparency information (if present) by blending the color with 527 | // the background color 'background_rgb' (specified as 24bit RGB triplet). 528 | // After this call, all alpha values are reset to 0xff. 529 | WEBP_EXTERN void WebPBlendAlpha(WebPPicture* picture, uint32_t background_rgb); 530 | 531 | //------------------------------------------------------------------------------ 532 | // Main call 533 | 534 | // Main encoding call, after config and picture have been initialized. 535 | // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION), 536 | // and the 'config' object must be a valid one. 537 | // Returns false in case of error, true otherwise. 538 | // In case of error, picture->error_code is updated accordingly. 539 | // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending 540 | // on the value of 'picture->use_argb'. It is highly recommended to use 541 | // the former for lossy encoding, and the latter for lossless encoding 542 | // (when config.lossless is true). Automatic conversion from one format to 543 | // another is provided but they both incur some loss. 544 | WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture); 545 | 546 | //------------------------------------------------------------------------------ 547 | 548 | #ifdef __cplusplus 549 | } // extern "C" 550 | #endif 551 | 552 | #endif // WEBP_WEBP_ENCODE_H_ 553 | -------------------------------------------------------------------------------- /third/libwebp/include/format_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Internal header for constants related to WebP file format. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_ 15 | #define WEBP_WEBP_FORMAT_CONSTANTS_H_ 16 | 17 | // Create fourcc of the chunk from the chunk tag characters. 18 | #define MKFOURCC(a, b, c, d) ((a) | (b) << 8 | (c) << 16 | (uint32_t)(d) << 24) 19 | 20 | // VP8 related constants. 21 | #define VP8_SIGNATURE 0x9d012a // Signature in VP8 data. 22 | #define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition 23 | #define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition 24 | #define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. 25 | 26 | // VP8L related constants. 27 | #define VP8L_SIGNATURE_SIZE 1 // VP8L signature size. 28 | #define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte. 29 | #define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store 30 | // width and height. 31 | #define VP8L_VERSION_BITS 3 // 3 bits reserved for version. 32 | #define VP8L_VERSION 0 // version 0 33 | #define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header. 34 | 35 | #define MAX_PALETTE_SIZE 256 36 | #define MAX_CACHE_BITS 11 37 | #define HUFFMAN_CODES_PER_META_CODE 5 38 | #define ARGB_BLACK 0xff000000 39 | 40 | #define DEFAULT_CODE_LENGTH 8 41 | #define MAX_ALLOWED_CODE_LENGTH 15 42 | 43 | #define NUM_LITERAL_CODES 256 44 | #define NUM_LENGTH_CODES 24 45 | #define NUM_DISTANCE_CODES 40 46 | #define CODE_LENGTH_CODES 19 47 | 48 | #define MIN_HUFFMAN_BITS 2 // min number of Huffman bits 49 | #define MAX_HUFFMAN_BITS 9 // max number of Huffman bits 50 | 51 | #define TRANSFORM_PRESENT 1 // The bit to be written when next data 52 | // to be read is a transform. 53 | #define NUM_TRANSFORMS 4 // Maximum number of allowed transform 54 | // in a bitstream. 55 | typedef enum { 56 | PREDICTOR_TRANSFORM = 0, 57 | CROSS_COLOR_TRANSFORM = 1, 58 | SUBTRACT_GREEN = 2, 59 | COLOR_INDEXING_TRANSFORM = 3 60 | } VP8LImageTransformType; 61 | 62 | // Alpha related constants. 63 | #define ALPHA_HEADER_LEN 1 64 | #define ALPHA_NO_COMPRESSION 0 65 | #define ALPHA_LOSSLESS_COMPRESSION 1 66 | #define ALPHA_PREPROCESSED_LEVELS 1 67 | 68 | // Mux related constants. 69 | #define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L"). 70 | #define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size. 71 | #define CHUNK_HEADER_SIZE 8 // Size of a chunk header. 72 | #define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP"). 73 | #define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk. 74 | #define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk. 75 | #define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk. 76 | 77 | #define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height. 78 | #define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height. 79 | #define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count 80 | #define MAX_DURATION (1 << 24) // maximum duration 81 | #define MAX_POSITION_OFFSET (1 << 24) // maximum frame x/y offset 82 | 83 | // Maximum chunk payload is such that adding the header and padding won't 84 | // overflow a uint32_t. 85 | #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) 86 | 87 | #endif // WEBP_WEBP_FORMAT_CONSTANTS_H_ 88 | -------------------------------------------------------------------------------- /third/libwebp/include/mux.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // RIFF container manipulation and encoding for WebP images. 11 | // 12 | // Authors: Urvang (urvang@google.com) 13 | // Vikas (vikasa@google.com) 14 | 15 | #ifndef WEBP_WEBP_MUX_H_ 16 | #define WEBP_WEBP_MUX_H_ 17 | 18 | #include "./mux_types.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define WEBP_MUX_ABI_VERSION 0x0108 // MAJOR(8b) + MINOR(8b) 25 | 26 | //------------------------------------------------------------------------------ 27 | // Mux API 28 | // 29 | // This API allows manipulation of WebP container images containing features 30 | // like color profile, metadata, animation. 31 | // 32 | // Code Example#1: Create a WebPMux object with image data, color profile and 33 | // XMP metadata. 34 | /* 35 | int copy_data = 0; 36 | WebPMux* mux = WebPMuxNew(); 37 | // ... (Prepare image data). 38 | WebPMuxSetImage(mux, &image, copy_data); 39 | // ... (Prepare ICCP color profile data). 40 | WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); 41 | // ... (Prepare XMP metadata). 42 | WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data); 43 | // Get data from mux in WebP RIFF format. 44 | WebPMuxAssemble(mux, &output_data); 45 | WebPMuxDelete(mux); 46 | // ... (Consume output_data; e.g. write output_data.bytes to file). 47 | WebPDataClear(&output_data); 48 | */ 49 | 50 | // Code Example#2: Get image and color profile data from a WebP file. 51 | /* 52 | int copy_data = 0; 53 | // ... (Read data from file). 54 | WebPMux* mux = WebPMuxCreate(&data, copy_data); 55 | WebPMuxGetFrame(mux, 1, &image); 56 | // ... (Consume image; e.g. call WebPDecode() to decode the data). 57 | WebPMuxGetChunk(mux, "ICCP", &icc_profile); 58 | // ... (Consume icc_data). 59 | WebPMuxDelete(mux); 60 | WebPFree(data); 61 | */ 62 | 63 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 64 | // the types are left here for reference. 65 | // typedef enum WebPMuxError WebPMuxError; 66 | // typedef enum WebPChunkId WebPChunkId; 67 | typedef struct WebPMux WebPMux; // main opaque object. 68 | typedef struct WebPMuxFrameInfo WebPMuxFrameInfo; 69 | typedef struct WebPMuxAnimParams WebPMuxAnimParams; 70 | typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions; 71 | 72 | // Error codes 73 | typedef enum WebPMuxError { 74 | WEBP_MUX_OK = 1, 75 | WEBP_MUX_NOT_FOUND = 0, 76 | WEBP_MUX_INVALID_ARGUMENT = -1, 77 | WEBP_MUX_BAD_DATA = -2, 78 | WEBP_MUX_MEMORY_ERROR = -3, 79 | WEBP_MUX_NOT_ENOUGH_DATA = -4 80 | } WebPMuxError; 81 | 82 | // IDs for different types of chunks. 83 | typedef enum WebPChunkId { 84 | WEBP_CHUNK_VP8X, // VP8X 85 | WEBP_CHUNK_ICCP, // ICCP 86 | WEBP_CHUNK_ANIM, // ANIM 87 | WEBP_CHUNK_ANMF, // ANMF 88 | WEBP_CHUNK_DEPRECATED, // (deprecated from FRGM) 89 | WEBP_CHUNK_ALPHA, // ALPH 90 | WEBP_CHUNK_IMAGE, // VP8/VP8L 91 | WEBP_CHUNK_EXIF, // EXIF 92 | WEBP_CHUNK_XMP, // XMP 93 | WEBP_CHUNK_UNKNOWN, // Other chunks. 94 | WEBP_CHUNK_NIL 95 | } WebPChunkId; 96 | 97 | //------------------------------------------------------------------------------ 98 | 99 | // Returns the version number of the mux library, packed in hexadecimal using 100 | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. 101 | WEBP_EXTERN int WebPGetMuxVersion(void); 102 | 103 | //------------------------------------------------------------------------------ 104 | // Life of a Mux object 105 | 106 | // Internal, version-checked, entry point 107 | WEBP_EXTERN WebPMux* WebPNewInternal(int); 108 | 109 | // Creates an empty mux object. 110 | // Returns: 111 | // A pointer to the newly created empty mux object. 112 | // Or NULL in case of memory error. 113 | static WEBP_INLINE WebPMux* WebPMuxNew(void) { 114 | return WebPNewInternal(WEBP_MUX_ABI_VERSION); 115 | } 116 | 117 | // Deletes the mux object. 118 | // Parameters: 119 | // mux - (in/out) object to be deleted 120 | WEBP_EXTERN void WebPMuxDelete(WebPMux* mux); 121 | 122 | //------------------------------------------------------------------------------ 123 | // Mux creation. 124 | 125 | // Internal, version-checked, entry point 126 | WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int, int); 127 | 128 | // Creates a mux object from raw data given in WebP RIFF format. 129 | // Parameters: 130 | // bitstream - (in) the bitstream data in WebP RIFF format 131 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 132 | // object and value 0 indicates data will NOT be copied. 133 | // Returns: 134 | // A pointer to the mux object created from given data - on success. 135 | // NULL - In case of invalid data or memory error. 136 | static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream, 137 | int copy_data) { 138 | return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION); 139 | } 140 | 141 | //------------------------------------------------------------------------------ 142 | // Non-image chunks. 143 | 144 | // Note: Only non-image related chunks should be managed through chunk APIs. 145 | // (Image related chunks are: "ANMF", "VP8 ", "VP8L" and "ALPH"). 146 | // To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(), 147 | // WebPMuxGetFrame() and WebPMuxDeleteFrame(). 148 | 149 | // Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object. 150 | // Any existing chunk(s) with the same id will be removed. 151 | // Parameters: 152 | // mux - (in/out) object to which the chunk is to be added 153 | // fourcc - (in) a character array containing the fourcc of the given chunk; 154 | // e.g., "ICCP", "XMP ", "EXIF" etc. 155 | // chunk_data - (in) the chunk data to be added 156 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 157 | // object and value 0 indicates data will NOT be copied. 158 | // Returns: 159 | // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL 160 | // or if fourcc corresponds to an image chunk. 161 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 162 | // WEBP_MUX_OK - on success. 163 | WEBP_EXTERN WebPMuxError WebPMuxSetChunk( 164 | WebPMux* mux, const char fourcc[4], const WebPData* chunk_data, 165 | int copy_data); 166 | 167 | // Gets a reference to the data of the chunk with id 'fourcc' in the mux object. 168 | // The caller should NOT free the returned data. 169 | // Parameters: 170 | // mux - (in) object from which the chunk data is to be fetched 171 | // fourcc - (in) a character array containing the fourcc of the chunk; 172 | // e.g., "ICCP", "XMP ", "EXIF" etc. 173 | // chunk_data - (out) returned chunk data 174 | // Returns: 175 | // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL 176 | // or if fourcc corresponds to an image chunk. 177 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id. 178 | // WEBP_MUX_OK - on success. 179 | WEBP_EXTERN WebPMuxError WebPMuxGetChunk( 180 | const WebPMux* mux, const char fourcc[4], WebPData* chunk_data); 181 | 182 | // Deletes the chunk with the given 'fourcc' from the mux object. 183 | // Parameters: 184 | // mux - (in/out) object from which the chunk is to be deleted 185 | // fourcc - (in) a character array containing the fourcc of the chunk; 186 | // e.g., "ICCP", "XMP ", "EXIF" etc. 187 | // Returns: 188 | // WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL 189 | // or if fourcc corresponds to an image chunk. 190 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc. 191 | // WEBP_MUX_OK - on success. 192 | WEBP_EXTERN WebPMuxError WebPMuxDeleteChunk( 193 | WebPMux* mux, const char fourcc[4]); 194 | 195 | //------------------------------------------------------------------------------ 196 | // Images. 197 | 198 | // Encapsulates data about a single frame. 199 | struct WebPMuxFrameInfo { 200 | WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream 201 | // or a single-image WebP file. 202 | int x_offset; // x-offset of the frame. 203 | int y_offset; // y-offset of the frame. 204 | int duration; // duration of the frame (in milliseconds). 205 | 206 | WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF 207 | // or WEBP_CHUNK_IMAGE 208 | WebPMuxAnimDispose dispose_method; // Disposal method for the frame. 209 | WebPMuxAnimBlend blend_method; // Blend operation for the frame. 210 | uint32_t pad[1]; // padding for later use 211 | }; 212 | 213 | // Sets the (non-animated) image in the mux object. 214 | // Note: Any existing images (including frames) will be removed. 215 | // Parameters: 216 | // mux - (in/out) object in which the image is to be set 217 | // bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image 218 | // WebP file (non-animated) 219 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 220 | // object and value 0 indicates data will NOT be copied. 221 | // Returns: 222 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL. 223 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 224 | // WEBP_MUX_OK - on success. 225 | WEBP_EXTERN WebPMuxError WebPMuxSetImage( 226 | WebPMux* mux, const WebPData* bitstream, int copy_data); 227 | 228 | // Adds a frame at the end of the mux object. 229 | // Notes: (1) frame.id should be WEBP_CHUNK_ANMF 230 | // (2) For setting a non-animated image, use WebPMuxSetImage() instead. 231 | // (3) Type of frame being pushed must be same as the frames in mux. 232 | // (4) As WebP only supports even offsets, any odd offset will be snapped 233 | // to an even location using: offset &= ~1 234 | // Parameters: 235 | // mux - (in/out) object to which the frame is to be added 236 | // frame - (in) frame data. 237 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 238 | // object and value 0 indicates data will NOT be copied. 239 | // Returns: 240 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL 241 | // or if content of 'frame' is invalid. 242 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 243 | // WEBP_MUX_OK - on success. 244 | WEBP_EXTERN WebPMuxError WebPMuxPushFrame( 245 | WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data); 246 | 247 | // Gets the nth frame from the mux object. 248 | // The content of 'frame->bitstream' is allocated using WebPMalloc(), and NOT 249 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 250 | // WebPDataClear(). 251 | // nth=0 has a special meaning - last position. 252 | // Parameters: 253 | // mux - (in) object from which the info is to be fetched 254 | // nth - (in) index of the frame in the mux object 255 | // frame - (out) data of the returned frame 256 | // Returns: 257 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL. 258 | // WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. 259 | // WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. 260 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 261 | // WEBP_MUX_OK - on success. 262 | WEBP_EXTERN WebPMuxError WebPMuxGetFrame( 263 | const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame); 264 | 265 | // Deletes a frame from the mux object. 266 | // nth=0 has a special meaning - last position. 267 | // Parameters: 268 | // mux - (in/out) object from which a frame is to be deleted 269 | // nth - (in) The position from which the frame is to be deleted 270 | // Returns: 271 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL. 272 | // WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object 273 | // before deletion. 274 | // WEBP_MUX_OK - on success. 275 | WEBP_EXTERN WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth); 276 | 277 | //------------------------------------------------------------------------------ 278 | // Animation. 279 | 280 | // Animation parameters. 281 | struct WebPMuxAnimParams { 282 | uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as: 283 | // Bits 00 to 07: Alpha. 284 | // Bits 08 to 15: Red. 285 | // Bits 16 to 23: Green. 286 | // Bits 24 to 31: Blue. 287 | int loop_count; // Number of times to repeat the animation [0 = infinite]. 288 | }; 289 | 290 | // Sets the animation parameters in the mux object. Any existing ANIM chunks 291 | // will be removed. 292 | // Parameters: 293 | // mux - (in/out) object in which ANIM chunk is to be set/added 294 | // params - (in) animation parameters. 295 | // Returns: 296 | // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. 297 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 298 | // WEBP_MUX_OK - on success. 299 | WEBP_EXTERN WebPMuxError WebPMuxSetAnimationParams( 300 | WebPMux* mux, const WebPMuxAnimParams* params); 301 | 302 | // Gets the animation parameters from the mux object. 303 | // Parameters: 304 | // mux - (in) object from which the animation parameters to be fetched 305 | // params - (out) animation parameters extracted from the ANIM chunk 306 | // Returns: 307 | // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. 308 | // WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object. 309 | // WEBP_MUX_OK - on success. 310 | WEBP_EXTERN WebPMuxError WebPMuxGetAnimationParams( 311 | const WebPMux* mux, WebPMuxAnimParams* params); 312 | 313 | //------------------------------------------------------------------------------ 314 | // Misc Utilities. 315 | 316 | // Sets the canvas size for the mux object. The width and height can be 317 | // specified explicitly or left as zero (0, 0). 318 | // * When width and height are specified explicitly, then this frame bound is 319 | // enforced during subsequent calls to WebPMuxAssemble() and an error is 320 | // reported if any animated frame does not completely fit within the canvas. 321 | // * When unspecified (0, 0), the constructed canvas will get the frame bounds 322 | // from the bounding-box over all frames after calling WebPMuxAssemble(). 323 | // Parameters: 324 | // mux - (in) object to which the canvas size is to be set 325 | // width - (in) canvas width 326 | // height - (in) canvas height 327 | // Returns: 328 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or 329 | // width or height are invalid or out of bounds 330 | // WEBP_MUX_OK - on success. 331 | WEBP_EXTERN WebPMuxError WebPMuxSetCanvasSize(WebPMux* mux, 332 | int width, int height); 333 | 334 | // Gets the canvas size from the mux object. 335 | // Note: This method assumes that the VP8X chunk, if present, is up-to-date. 336 | // That is, the mux object hasn't been modified since the last call to 337 | // WebPMuxAssemble() or WebPMuxCreate(). 338 | // Parameters: 339 | // mux - (in) object from which the canvas size is to be fetched 340 | // width - (out) canvas width 341 | // height - (out) canvas height 342 | // Returns: 343 | // WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL. 344 | // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. 345 | // WEBP_MUX_OK - on success. 346 | WEBP_EXTERN WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux, 347 | int* width, int* height); 348 | 349 | // Gets the feature flags from the mux object. 350 | // Note: This method assumes that the VP8X chunk, if present, is up-to-date. 351 | // That is, the mux object hasn't been modified since the last call to 352 | // WebPMuxAssemble() or WebPMuxCreate(). 353 | // Parameters: 354 | // mux - (in) object from which the features are to be fetched 355 | // flags - (out) the flags specifying which features are present in the 356 | // mux object. This will be an OR of various flag values. 357 | // Enum 'WebPFeatureFlags' can be used to test individual flag values. 358 | // Returns: 359 | // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL. 360 | // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. 361 | // WEBP_MUX_OK - on success. 362 | WEBP_EXTERN WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, 363 | uint32_t* flags); 364 | 365 | // Gets number of chunks with the given 'id' in the mux object. 366 | // Parameters: 367 | // mux - (in) object from which the info is to be fetched 368 | // id - (in) chunk id specifying the type of chunk 369 | // num_elements - (out) number of chunks with the given chunk id 370 | // Returns: 371 | // WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL. 372 | // WEBP_MUX_OK - on success. 373 | WEBP_EXTERN WebPMuxError WebPMuxNumChunks(const WebPMux* mux, 374 | WebPChunkId id, int* num_elements); 375 | 376 | // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. 377 | // This function also validates the mux object. 378 | // Note: The content of 'assembled_data' will be ignored and overwritten. 379 | // Also, the content of 'assembled_data' is allocated using WebPMalloc(), and 380 | // NOT owned by the 'mux' object. It MUST be deallocated by the caller by 381 | // calling WebPDataClear(). It's always safe to call WebPDataClear() upon 382 | // return, even in case of error. 383 | // Parameters: 384 | // mux - (in/out) object whose chunks are to be assembled 385 | // assembled_data - (out) assembled WebP data 386 | // Returns: 387 | // WEBP_MUX_BAD_DATA - if mux object is invalid. 388 | // WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL. 389 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 390 | // WEBP_MUX_OK - on success. 391 | WEBP_EXTERN WebPMuxError WebPMuxAssemble(WebPMux* mux, 392 | WebPData* assembled_data); 393 | 394 | //------------------------------------------------------------------------------ 395 | // WebPAnimEncoder API 396 | // 397 | // This API allows encoding (possibly) animated WebP images. 398 | // 399 | // Code Example: 400 | /* 401 | WebPAnimEncoderOptions enc_options; 402 | WebPAnimEncoderOptionsInit(&enc_options); 403 | // Tune 'enc_options' as needed. 404 | WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options); 405 | while() { 406 | WebPConfig config; 407 | WebPConfigInit(&config); 408 | // Tune 'config' as needed. 409 | WebPAnimEncoderAdd(enc, frame, timestamp_ms, &config); 410 | } 411 | WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL); 412 | WebPAnimEncoderAssemble(enc, webp_data); 413 | WebPAnimEncoderDelete(enc); 414 | // Write the 'webp_data' to a file, or re-mux it further. 415 | */ 416 | 417 | typedef struct WebPAnimEncoder WebPAnimEncoder; // Main opaque object. 418 | 419 | // Forward declarations. Defined in encode.h. 420 | struct WebPPicture; 421 | struct WebPConfig; 422 | 423 | // Global options. 424 | struct WebPAnimEncoderOptions { 425 | WebPMuxAnimParams anim_params; // Animation parameters. 426 | int minimize_size; // If true, minimize the output size (slow). Implicitly 427 | // disables key-frame insertion. 428 | int kmin; 429 | int kmax; // Minimum and maximum distance between consecutive key 430 | // frames in the output. The library may insert some key 431 | // frames as needed to satisfy this criteria. 432 | // Note that these conditions should hold: kmax > kmin 433 | // and kmin >= kmax / 2 + 1. Also, if kmax <= 0, then 434 | // key-frame insertion is disabled; and if kmax == 1, 435 | // then all frames will be key-frames (kmin value does 436 | // not matter for these special cases). 437 | int allow_mixed; // If true, use mixed compression mode; may choose 438 | // either lossy and lossless for each frame. 439 | int verbose; // If true, print info and warning messages to stderr. 440 | 441 | uint32_t padding[4]; // Padding for later use. 442 | }; 443 | 444 | // Internal, version-checked, entry point. 445 | WEBP_EXTERN int WebPAnimEncoderOptionsInitInternal( 446 | WebPAnimEncoderOptions*, int); 447 | 448 | // Should always be called, to initialize a fresh WebPAnimEncoderOptions 449 | // structure before modification. Returns false in case of version mismatch. 450 | // WebPAnimEncoderOptionsInit() must have succeeded before using the 451 | // 'enc_options' object. 452 | static WEBP_INLINE int WebPAnimEncoderOptionsInit( 453 | WebPAnimEncoderOptions* enc_options) { 454 | return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION); 455 | } 456 | 457 | // Internal, version-checked, entry point. 458 | WEBP_EXTERN WebPAnimEncoder* WebPAnimEncoderNewInternal( 459 | int, int, const WebPAnimEncoderOptions*, int); 460 | 461 | // Creates and initializes a WebPAnimEncoder object. 462 | // Parameters: 463 | // width/height - (in) canvas width and height of the animation. 464 | // enc_options - (in) encoding options; can be passed NULL to pick 465 | // reasonable defaults. 466 | // Returns: 467 | // A pointer to the newly created WebPAnimEncoder object. 468 | // Or NULL in case of memory error. 469 | static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew( 470 | int width, int height, const WebPAnimEncoderOptions* enc_options) { 471 | return WebPAnimEncoderNewInternal(width, height, enc_options, 472 | WEBP_MUX_ABI_VERSION); 473 | } 474 | 475 | // Optimize the given frame for WebP, encode it and add it to the 476 | // WebPAnimEncoder object. 477 | // The last call to 'WebPAnimEncoderAdd' should be with frame = NULL, which 478 | // indicates that no more frames are to be added. This call is also used to 479 | // determine the duration of the last frame. 480 | // Parameters: 481 | // enc - (in/out) object to which the frame is to be added. 482 | // frame - (in/out) frame data in ARGB or YUV(A) format. If it is in YUV(A) 483 | // format, it will be converted to ARGB, which incurs a small loss. 484 | // timestamp_ms - (in) timestamp of this frame in milliseconds. 485 | // Duration of a frame would be calculated as 486 | // "timestamp of next frame - timestamp of this frame". 487 | // Hence, timestamps should be in non-decreasing order. 488 | // config - (in) encoding options; can be passed NULL to pick 489 | // reasonable defaults. 490 | // Returns: 491 | // On error, returns false and frame->error_code is set appropriately. 492 | // Otherwise, returns true. 493 | WEBP_EXTERN int WebPAnimEncoderAdd( 494 | WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms, 495 | const struct WebPConfig* config); 496 | 497 | // Assemble all frames added so far into a WebP bitstream. 498 | // This call should be preceded by a call to 'WebPAnimEncoderAdd' with 499 | // frame = NULL; if not, the duration of the last frame will be internally 500 | // estimated. 501 | // Parameters: 502 | // enc - (in/out) object from which the frames are to be assembled. 503 | // webp_data - (out) generated WebP bitstream. 504 | // Returns: 505 | // True on success. 506 | WEBP_EXTERN int WebPAnimEncoderAssemble(WebPAnimEncoder* enc, 507 | WebPData* webp_data); 508 | 509 | // Get error string corresponding to the most recent call using 'enc'. The 510 | // returned string is owned by 'enc' and is valid only until the next call to 511 | // WebPAnimEncoderAdd() or WebPAnimEncoderAssemble() or WebPAnimEncoderDelete(). 512 | // Parameters: 513 | // enc - (in/out) object from which the error string is to be fetched. 514 | // Returns: 515 | // NULL if 'enc' is NULL. Otherwise, returns the error string if the last call 516 | // to 'enc' had an error, or an empty string if the last call was a success. 517 | WEBP_EXTERN const char* WebPAnimEncoderGetError(WebPAnimEncoder* enc); 518 | 519 | // Deletes the WebPAnimEncoder object. 520 | // Parameters: 521 | // enc - (in/out) object to be deleted 522 | WEBP_EXTERN void WebPAnimEncoderDelete(WebPAnimEncoder* enc); 523 | 524 | //------------------------------------------------------------------------------ 525 | 526 | #ifdef __cplusplus 527 | } // extern "C" 528 | #endif 529 | 530 | #endif // WEBP_WEBP_MUX_H_ 531 | -------------------------------------------------------------------------------- /third/libwebp/include/mux_types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Data-types common to the mux and demux libraries. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_WEBP_MUX_TYPES_H_ 15 | #define WEBP_WEBP_MUX_TYPES_H_ 16 | 17 | #include // memset() 18 | #include "./types.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 25 | // the types are left here for reference. 26 | // typedef enum WebPFeatureFlags WebPFeatureFlags; 27 | // typedef enum WebPMuxAnimDispose WebPMuxAnimDispose; 28 | // typedef enum WebPMuxAnimBlend WebPMuxAnimBlend; 29 | typedef struct WebPData WebPData; 30 | 31 | // VP8X Feature Flags. 32 | typedef enum WebPFeatureFlags { 33 | ANIMATION_FLAG = 0x00000002, 34 | XMP_FLAG = 0x00000004, 35 | EXIF_FLAG = 0x00000008, 36 | ALPHA_FLAG = 0x00000010, 37 | ICCP_FLAG = 0x00000020, 38 | 39 | ALL_VALID_FLAGS = 0x0000003e 40 | } WebPFeatureFlags; 41 | 42 | // Dispose method (animation only). Indicates how the area used by the current 43 | // frame is to be treated before rendering the next frame on the canvas. 44 | typedef enum WebPMuxAnimDispose { 45 | WEBP_MUX_DISPOSE_NONE, // Do not dispose. 46 | WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color. 47 | } WebPMuxAnimDispose; 48 | 49 | // Blend operation (animation only). Indicates how transparent pixels of the 50 | // current frame are blended with those of the previous canvas. 51 | typedef enum WebPMuxAnimBlend { 52 | WEBP_MUX_BLEND, // Blend. 53 | WEBP_MUX_NO_BLEND // Do not blend. 54 | } WebPMuxAnimBlend; 55 | 56 | // Data type used to describe 'raw' data, e.g., chunk data 57 | // (ICC profile, metadata) and WebP compressed image data. 58 | // 'bytes' memory must be allocated using WebPMalloc() and such. 59 | struct WebPData { 60 | const uint8_t* bytes; 61 | size_t size; 62 | }; 63 | 64 | // Initializes the contents of the 'webp_data' object with default values. 65 | static WEBP_INLINE void WebPDataInit(WebPData* webp_data) { 66 | if (webp_data != NULL) { 67 | memset(webp_data, 0, sizeof(*webp_data)); 68 | } 69 | } 70 | 71 | // Clears the contents of the 'webp_data' object by calling WebPFree(). 72 | // Does not deallocate the object itself. 73 | static WEBP_INLINE void WebPDataClear(WebPData* webp_data) { 74 | if (webp_data != NULL) { 75 | WebPFree((void*)webp_data->bytes); 76 | WebPDataInit(webp_data); 77 | } 78 | } 79 | 80 | // Allocates necessary storage for 'dst' and copies the contents of 'src'. 81 | // Returns true on success. 82 | static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) { 83 | if (src == NULL || dst == NULL) return 0; 84 | WebPDataInit(dst); 85 | if (src->bytes != NULL && src->size != 0) { 86 | dst->bytes = (uint8_t*)WebPMalloc(src->size); 87 | if (dst->bytes == NULL) return 0; 88 | memcpy((void*)dst->bytes, src->bytes, src->size); 89 | dst->size = src->size; 90 | } 91 | return 1; 92 | } 93 | 94 | #ifdef __cplusplus 95 | } // extern "C" 96 | #endif 97 | 98 | #endif // WEBP_WEBP_MUX_TYPES_H_ 99 | -------------------------------------------------------------------------------- /third/libwebp/include/types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Common types + memory wrappers 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_TYPES_H_ 15 | #define WEBP_WEBP_TYPES_H_ 16 | 17 | #include // for size_t 18 | 19 | #ifndef _MSC_VER 20 | #include 21 | #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ 22 | (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) 23 | #define WEBP_INLINE inline 24 | #else 25 | #define WEBP_INLINE 26 | #endif 27 | #else 28 | typedef signed char int8_t; 29 | typedef unsigned char uint8_t; 30 | typedef signed short int16_t; 31 | typedef unsigned short uint16_t; 32 | typedef signed int int32_t; 33 | typedef unsigned int uint32_t; 34 | typedef unsigned long long int uint64_t; 35 | typedef long long int int64_t; 36 | #define WEBP_INLINE __forceinline 37 | #endif /* _MSC_VER */ 38 | 39 | #ifndef WEBP_EXTERN 40 | // This explicitly marks library functions and allows for changing the 41 | // signature for e.g., Windows DLL builds. 42 | # if defined(__GNUC__) && __GNUC__ >= 4 43 | # define WEBP_EXTERN extern __attribute__ ((visibility ("default"))) 44 | # else 45 | # define WEBP_EXTERN extern 46 | # endif /* __GNUC__ >= 4 */ 47 | #endif /* WEBP_EXTERN */ 48 | 49 | // Macro to check ABI compatibility (same major revision number) 50 | #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | // Allocates 'size' bytes of memory. Returns NULL upon error. Memory 57 | // must be deallocated by calling WebPFree(). This function is made available 58 | // by the core 'libwebp' library. 59 | WEBP_EXTERN void* WebPMalloc(size_t size); 60 | 61 | // Releases memory returned by the WebPDecode*() functions (from decode.h). 62 | WEBP_EXTERN void WebPFree(void* ptr); 63 | 64 | #ifdef __cplusplus 65 | } // extern "C" 66 | #endif 67 | 68 | #endif // WEBP_WEBP_TYPES_H_ 69 | -------------------------------------------------------------------------------- /third/libwebp/lib.X86/libwebp.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZQF-ReVN/RxCMVS/584f9f58e994f3648f94d0e58ca35da1a916e968/third/libwebp/lib.X86/libwebp.lib --------------------------------------------------------------------------------