omnizip 0.4.7-arm-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,326 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 Ribose Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a
6
+ # copy of this software and associated documentation files (the "Software"),
7
+ # to deal in the Software without restriction, including without limitation
8
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
+ # and/or sell copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ module Omnizip
24
+ module Algorithms
25
+ class LZMA < Algorithm
26
+ # SDK-compatible distance encoder/decoder
27
+ #
28
+ # This class implements the LZMA SDK's distance encoding scheme:
29
+ # - Slot 0-3: Direct encoding (no extra bits)
30
+ # - Slot 4-13: Slot + 1-5 direct bits
31
+ # - Slot 14+: Slot + fixed bits + aligned bits
32
+ #
33
+ # The slot categorizes distances into ranges, and extra bits
34
+ # specify the exact position within that range.
35
+ class DistanceCoder
36
+ include Constants
37
+
38
+ # Initialize the distance coder
39
+ #
40
+ # @param num_len_to_pos_states [Integer] Number of length states for slot selection
41
+ def initialize(num_len_to_pos_states)
42
+ @num_len_to_pos_states = num_len_to_pos_states
43
+
44
+ # Slot encoders: one per length state, 128 models each
45
+ # Tree needs 2^(num_bits+1) models for a 6-bit tree: indices 1-127
46
+ # This matches the tree decode algorithm which accesses up to index 127
47
+ @slot_encoders = Array.new(num_len_to_pos_states) do
48
+ Array.new(1 << (NUM_DIST_SLOT_BITS + 1)) { BitModel.new }
49
+ end
50
+
51
+ # Position encoders for slots 4-13
52
+ # SDK convention: size = NUM_FULL_DISTANCES - END_POS_MODEL_INDEX = 128 - 14 = 114
53
+ # Indexed by: base - slot - 1 (matches LZMA SDK and XZ Utils)
54
+ @pos_encoders = Array.new(NUM_FULL_DISTANCES - END_POS_MODEL_INDEX) do
55
+ BitModel.new
56
+ end
57
+
58
+ # Aligned encoder for slots 14+ (4-bit aligned)
59
+ # Tree needs 2^5 = 32 models for 4-bit tree
60
+ @align_encoder = Array.new(1 << (DIST_ALIGN_BITS + 1)) do
61
+ BitModel.new
62
+ end
63
+
64
+ # Precompute distance slot lookup table for fast encoding
65
+ @slot_fast = Array.new(DIST_SLOT_FAST_LIMIT)
66
+ init_slot_fast_table
67
+ end
68
+
69
+ # Reset all probability models in place
70
+ #
71
+ # This method resets the bit models to their initial state.
72
+ # Called during state reset to reinitialize probability models.
73
+ #
74
+ # @return [void]
75
+ def reset_models
76
+ @slot_encoders.each do |len_state_models|
77
+ len_state_models.each(&:reset)
78
+ end
79
+ @pos_encoders.each(&:reset)
80
+ @align_encoder.each(&:reset)
81
+ end
82
+
83
+ # Encode a match distance using SDK-compatible encoding
84
+ #
85
+ # @param range_encoder [RangeEncoder] The range encoder
86
+ # @param distance [Integer] Distance value (already subtracted 1)
87
+ # @param len_state [Integer] Length state for slot selection
88
+ # @return [void]
89
+ def encode(range_encoder, distance, len_state)
90
+ slot = get_dist_slot(distance)
91
+
92
+ # Encode the slot using the appropriate slot encoder
93
+ encode_tree(range_encoder, @slot_encoders[len_state], slot,
94
+ NUM_DIST_SLOT_BITS)
95
+
96
+ # Encode extra bits based on slot
97
+ if slot >= START_POS_MODEL_INDEX
98
+ footer_bits = (slot >> 1) - 1
99
+ base = (2 | (slot & 1)) << footer_bits
100
+
101
+ if slot < END_POS_MODEL_INDEX
102
+ # Slots 4-13: Use position encoders (reverse tree encoding)
103
+ # SDK/XZ Utils convention: base_idx = base - slot - 1
104
+ encode_reverse_tree(range_encoder,
105
+ @pos_encoders,
106
+ base - slot - 1,
107
+ distance - base,
108
+ footer_bits)
109
+ else
110
+ # Slots 14+: Fixed direct bits + aligned bits
111
+ # Encode high bits as direct bits
112
+ range_encoder.encode_direct_bits((distance - base) >> DIST_ALIGN_BITS,
113
+ footer_bits - DIST_ALIGN_BITS)
114
+
115
+ # Encode low 4 bits using aligned encoder (reverse tree)
116
+ encode_reverse_tree(range_encoder,
117
+ @align_encoder,
118
+ 0,
119
+ distance - base,
120
+ DIST_ALIGN_BITS)
121
+ end
122
+ end
123
+ end
124
+
125
+ # Decode a match distance using SDK-compatible decoding
126
+ #
127
+ # @param range_decoder [RangeDecoder] The range decoder
128
+ # @param len_state [Integer] Length state for slot selection
129
+ # @return [Integer] Decoded distance value (before adding 1)
130
+ def decode(range_decoder, len_state)
131
+ slot = decode_tree(range_decoder, @slot_encoders[len_state],
132
+ NUM_DIST_SLOT_BITS)
133
+
134
+ # Decode extra bits based on slot
135
+ if slot < START_POS_MODEL_INDEX
136
+ # Slots 0-3: No extra bits
137
+ slot
138
+ else
139
+ footer_bits = (slot >> 1) - 1
140
+
141
+ if slot < END_POS_MODEL_INDEX
142
+ # Slots 4-13: Use position encoders (reverse tree decoding)
143
+ # SDK/XZ Utils convention: base_idx = base - slot - 1
144
+ base = (2 | (slot & 1)) << footer_bits
145
+ result = base + decode_reverse_tree(range_decoder,
146
+ @pos_encoders,
147
+ base - slot - 1,
148
+ footer_bits)
149
+ else
150
+ # Slots 14+: Fixed direct bits + aligned bits
151
+ # XZ Utils pattern (lzma_decoder.c:500-514):
152
+ # - Start with rep0 = 2 + (slot & 1)
153
+ # - Decode high_bits using rc_direct (builds up from starting value)
154
+ # - Shift left by ALIGN_BITS
155
+ # - Decode low_bits using aligned encoder
156
+ # - Add symbol (slot) to final result
157
+
158
+ footer_bits = (slot >> 1) - 1
159
+ num_direct_bits = footer_bits - DIST_ALIGN_BITS
160
+
161
+ # XZ Utils pattern for slot >= 14:
162
+ # rep0 = 2 + (slot & 1)
163
+ # rc_direct(rep0, num_direct_bits)
164
+ # rep0 <<= ALIGN_BITS
165
+ # rc_bittree_rev4(coder->pos_align)
166
+ # IMPORTANT: slot value is NOT added to result
167
+ # Reference: /Users/mulgogi/src/external/xz/src/liblzma/lzma/lzma_decoder.c:507-512
168
+ result = 2 + (slot & 1)
169
+
170
+ # Use decode_direct_bits_with_base to match XZ Utils rc_direct
171
+ # rc_direct builds on the base value iteratively
172
+ result = range_decoder.decode_direct_bits_with_base(
173
+ num_direct_bits, result
174
+ )
175
+
176
+ # Decode low 4 bits using aligned encoder (reverse tree)
177
+ low_bits = decode_reverse_tree(range_decoder,
178
+ @align_encoder,
179
+ 0,
180
+ DIST_ALIGN_BITS)
181
+
182
+ # Final result: (result << 4) + low_bits
183
+ # NOTE: slot value is NOT added (XZ Utils pattern - line 513 adds symbol for EOPM check only)
184
+ result = (result << DIST_ALIGN_BITS) + low_bits
185
+ end
186
+ result
187
+ end
188
+ end
189
+
190
+ private
191
+
192
+ # Initialize fast distance slot lookup table
193
+ #
194
+ # @return [void]
195
+ def init_slot_fast_table
196
+ # Fill table based on slot ranges
197
+ # Slot 0: distance 0
198
+ # Slot 1: distance 1
199
+ # Slot 2: distance 2
200
+ # Slot 3: distance 3
201
+ # Slot 4: distances 4-5
202
+ # Slot 5: distances 6-7
203
+ # Slot 6: distances 8-11
204
+ # etc.
205
+
206
+ slot = 0
207
+ c = 0
208
+
209
+ while slot < NUM_DIST_SLOTS && c < DIST_SLOT_FAST_LIMIT
210
+ # Calculate the start and end of this slot's range
211
+ if slot < 4
212
+ # Slots 0-3 map to single distances
213
+ @slot_fast[c] = slot
214
+ c += 1
215
+ slot += 1
216
+ else
217
+ # Slots 4+ have power-of-2 ranges
218
+ footer_bits = (slot >> 1) - 1
219
+ range_size = 1 << footer_bits
220
+
221
+ # Fill this slot's range
222
+ range_size.times do
223
+ break if c >= DIST_SLOT_FAST_LIMIT
224
+
225
+ @slot_fast[c] = slot
226
+ c += 1
227
+ end
228
+ slot += 1
229
+ end
230
+ end
231
+ end
232
+
233
+ # Get the distance slot for a given distance
234
+ #
235
+ # @param distance [Integer] Distance value
236
+ # @return [Integer] Distance slot (0-63)
237
+ def get_dist_slot(distance)
238
+ if distance < DIST_SLOT_FAST_LIMIT
239
+ @slot_fast[distance]
240
+ else
241
+ # For large distances, calculate slot directly
242
+ # Find the highest bit position
243
+ n = 31
244
+ while n >= 0
245
+ break if (distance >> n) != 0
246
+
247
+ n -= 1
248
+ end
249
+
250
+ # slot = 2 * n + high_bit
251
+ ((n << 1) + ((distance >> (n - 1)) & 1))
252
+ end
253
+ end
254
+
255
+ # Encode a value using a tree of bit models
256
+ #
257
+ # @param range_encoder [RangeEncoder] The range encoder
258
+ # @param models [Array<BitModel>] Array of bit models for the tree
259
+ # @param symbol [Integer] Symbol to encode
260
+ # @param num_bits [Integer] Number of bits in the tree
261
+ # @return [void]
262
+ def encode_tree(range_encoder, models, symbol, num_bits)
263
+ m = 1
264
+ (num_bits - 1).downto(0) do |i|
265
+ bit = (symbol >> i) & 1
266
+ range_encoder.encode_bit(models[m], bit)
267
+ m = (m << 1) | bit
268
+ end
269
+ end
270
+
271
+ # Decode a value using a tree of bit models
272
+ #
273
+ # @param range_decoder [RangeDecoder] The range decoder
274
+ # @param models [Array<BitModel>] Array of bit models for the tree
275
+ # @param num_bits [Integer] Number of bits in the tree
276
+ # @return [Integer] Decoded symbol
277
+ def decode_tree(range_decoder, models, num_bits)
278
+ m = 1
279
+ symbol = 0
280
+ (num_bits - 1).downto(0) do |i|
281
+ bit = range_decoder.decode_bit(models[m])
282
+ m = (m << 1) | bit
283
+ symbol |= (bit << i)
284
+ end
285
+ symbol
286
+ end
287
+
288
+ # Encode a value using reverse bit-tree encoding
289
+ #
290
+ # @param range_encoder [RangeEncoder] The range encoder
291
+ # @param models [Array<BitModel>] Array of bit models
292
+ # @param base_idx [Integer] Base index into models array
293
+ # @param symbol [Integer] Symbol to encode
294
+ # @param num_bits [Integer] Number of bits
295
+ # @return [void]
296
+ def encode_reverse_tree(range_encoder, models, base_idx, symbol,
297
+ num_bits)
298
+ m = 1
299
+ num_bits.times do |i|
300
+ bit = (symbol >> i) & 1
301
+ range_encoder.encode_bit(models[base_idx + m], bit)
302
+ m = (m << 1) | bit
303
+ end
304
+ end
305
+
306
+ # Decode a value using reverse bit-tree decoding
307
+ #
308
+ # @param range_decoder [RangeDecoder] The range decoder
309
+ # @param models [Array<BitModel>] Array of bit models
310
+ # @param base_idx [Integer] Base index into models array
311
+ # @param num_bits [Integer] Number of bits
312
+ # @return [Integer] Decoded symbol
313
+ def decode_reverse_tree(range_decoder, models, base_idx, num_bits)
314
+ m = 1
315
+ symbol = 0
316
+ num_bits.times do |i|
317
+ bit = range_decoder.decode_bit(models[base_idx + m])
318
+ m = (m << 1) | bit
319
+ symbol |= (bit << i)
320
+ end
321
+ symbol
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 Ribose Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a
6
+ # copy of this software and associated documentation files (the "Software"),
7
+ # to deal in the Software without restriction, including without limitation
8
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
+ # and/or sell copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ module Omnizip
24
+ module Algorithms
25
+ class LZMA < Algorithm
26
+ # LZMA Encoder - Factory for LZMA compression implementations
27
+ #
28
+ # This class provides a unified interface for LZMA encoding, delegating
29
+ # to the appropriate implementation based on the target format:
30
+ #
31
+ # 1. SDK-compatible (default): For 7-Zip containers, uses 7-Zip SDK implementation
32
+ # 2. XZ-compatible: For XZ/LZMA files, uses XZ Utils implementation
33
+ #
34
+ # The encoder produces a stream that consists of:
35
+ # - Property byte (lc, lp, pb parameters)
36
+ # - Dictionary size (4 bytes)
37
+ # - Uncompressed size (8 bytes)
38
+ # - Compressed data
39
+ class Encoder
40
+ include Constants
41
+
42
+ attr_reader :dict_size, :lc, :lp, :pb
43
+
44
+ # Initialize the encoder
45
+ #
46
+ # @param output [IO] Output stream for compressed data
47
+ # @param options [Hash] Encoding options
48
+ # @option options [Integer] :dict_size Dictionary size
49
+ # @option options [Integer] :lc Literal context bits (0-8)
50
+ # @option options [Integer] :lp Literal position bits (0-4)
51
+ # @option options [Integer] :pb Position bits (0-4)
52
+ # @option options [Boolean] :write_size Write actual size (false for standalone .lzma)
53
+ # @option options [Boolean] :sdk_compatible Use SDK-compatible encoding (default: true)
54
+ # @option options [Boolean] :xz_compatible Use XZ-compatible encoding (default: false)
55
+ # @option options [Boolean] :raw_mode Skip header for raw LZMA encoding (for 7-Zip/LZMA2)
56
+ def initialize(output, options = {})
57
+ @output = output
58
+ @dict_size = options[:dict_size] || (1 << 16) # 64KB default
59
+ @lc = options[:lc] || 3
60
+ @lp = options[:lp] || 0
61
+ @pb = options[:pb] || 2
62
+ @write_size = options.fetch(:write_size, true)
63
+ @xz_compatible = options.fetch(:xz_compatible, false)
64
+ @sdk_compatible = options.fetch(:sdk_compatible, !@xz_compatible)
65
+ @raw_mode = options.fetch(:raw_mode, false)
66
+
67
+ validate_parameters
68
+
69
+ # Factory pattern: create implementation based on mode
70
+ @impl = if @xz_compatible
71
+ # Use XzEncoder (XZ Utils LZMA)
72
+ XzEncoderAdapter.new(output, options)
73
+ else
74
+ # Use SdkEncoder (7-Zip LZMA SDK compatible) - DEFAULT
75
+ Implementations::SevenZip::LZMA::Encoder.new(output,
76
+ options)
77
+ end
78
+ end
79
+
80
+ # Encode a stream of data
81
+ #
82
+ # @param input [String, IO] Input data to compress
83
+ # @return [Array<String, Integer>, void] Tuple of [data, decode_bytes] in raw mode, void otherwise
84
+ def encode_stream(input)
85
+ @impl.encode_stream(input)
86
+ end
87
+
88
+ private
89
+
90
+ # Validate encoding parameters
91
+ #
92
+ # @return [void]
93
+ # @raise [ArgumentError] If parameters are invalid
94
+ def validate_parameters
95
+ raise ArgumentError, "lc must be 0-8" unless @lc.between?(0, 8)
96
+ raise ArgumentError, "lp must be 0-4" unless @lp.between?(0, 4)
97
+ raise ArgumentError, "pb must be 0-4" unless @pb.between?(0, 4)
98
+ return if @dict_size.between?(DICT_SIZE_MIN, DICT_SIZE_MAX)
99
+
100
+ raise ArgumentError, "Invalid dictionary size"
101
+ end
102
+ end
103
+
104
+ # Adapter for XzEncoder to match SdkEncoder interface
105
+ #
106
+ # XzEncoder has a different interface (encode(input, output) vs encode_stream(input)).
107
+ # This adapter wraps XzEncoder to provide the same interface as SdkEncoder.
108
+ class XzEncoderAdapter
109
+ # Initialize adapter
110
+ #
111
+ # @param output [IO] Output stream
112
+ # @param options [Hash] Encoding options
113
+ def initialize(output, options = {})
114
+ @output = output
115
+ @options = options
116
+ @xz_encoder = XzEncoder.new(options)
117
+ @bytes_for_decode = nil
118
+ end
119
+
120
+ # Encode stream (matches SdkEncoder interface)
121
+ #
122
+ # @param input [String, IO] Input data to compress
123
+ # @return [Array<String, Integer>] Tuple of [compressed_data, decode_bytes]
124
+ def encode_stream(input)
125
+ input_data = input.is_a?(String) ? input : input.read
126
+ @bytes_for_decode = @xz_encoder.encode(input_data, @output)
127
+ [@output.string, @bytes_for_decode]
128
+ end
129
+
130
+ # Get bytes for decode (for LZMA2 compatibility)
131
+ #
132
+ # @return [Integer] Number of bytes decoder will consume
133
+ def bytes_for_decode
134
+ @bytes_for_decode || @output.string.bytesize
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 Ribose Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a
6
+ # copy of this software and associated documentation files (the "Software"),
7
+ # to deal in the Software without restriction, including without limitation
8
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
+ # and/or sell copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ module Omnizip
24
+ module Algorithms
25
+ class LZMA < Algorithm
26
+ # SDK-compatible length encoder/decoder
27
+ #
28
+ # This class implements the LZMA SDK's length encoding scheme:
29
+ # - Lengths 0-7: choice=0, 3 bits from low tree
30
+ # - Lengths 8-15: choice=1, choice2=0, 3 bits from mid tree
31
+ # - Lengths 16+: choice=1, choice2=1, 8 bits from high tree
32
+ #
33
+ # Position state is used to select which low/mid tree to use,
34
+ # providing context-dependent compression.
35
+ class LengthCoder
36
+ include Constants
37
+
38
+ # Initialize the length coder
39
+ #
40
+ # @param num_pos_states [Integer] Number of position states (1 << pb)
41
+ def initialize(num_pos_states)
42
+ @num_pos_states = num_pos_states
43
+ @choice = BitModel.new
44
+ @choice2 = BitModel.new
45
+
46
+ # Low trees: one per position state, 8 symbols each
47
+ # Tree needs 2^(num_bits+1) models: 2^4 = 16 for 3-bit tree
48
+ @low = Array.new(num_pos_states) do
49
+ Array.new(1 << (NUM_LEN_LOW_BITS + 1)) { BitModel.new }
50
+ end
51
+
52
+ # Mid trees: one per position state, 8 symbols each
53
+ # Tree needs 2^(num_bits+1) models: 2^4 = 16 for 3-bit tree
54
+ @mid = Array.new(num_pos_states) do
55
+ Array.new(1 << (NUM_LEN_MID_BITS + 1)) { BitModel.new }
56
+ end
57
+
58
+ # High tree: shared across all position states, 256 symbols
59
+ # Tree needs 2^(num_bits+1) models: 2^9 = 512 for 8-bit tree
60
+ @high = Array.new(1 << (NUM_LEN_HIGH_BITS + 1)) { BitModel.new }
61
+ end
62
+
63
+ # Encode a match length using SDK-compatible encoding
64
+ #
65
+ # @param range_encoder [RangeEncoder] The range encoder
66
+ # @param length [Integer] Length value (already subtracted MATCH_LEN_MIN)
67
+ # @param pos_state [Integer] Position state for tree selection
68
+ # @return [void]
69
+ def encode(range_encoder, length, pos_state)
70
+ if length < LEN_LOW_SYMBOLS
71
+ # 0-7: Use low tree
72
+ range_encoder.encode_bit(@choice, 0)
73
+ encode_tree(range_encoder, @low[pos_state], length,
74
+ NUM_LEN_LOW_BITS)
75
+ elsif length < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS
76
+ # 8-15: Use mid tree
77
+ range_encoder.encode_bit(@choice, 1)
78
+ range_encoder.encode_bit(@choice2, 0)
79
+ encode_tree(range_encoder, @mid[pos_state],
80
+ length - LEN_LOW_SYMBOLS, NUM_LEN_MID_BITS)
81
+ else
82
+ # 16+: Use high tree
83
+ range_encoder.encode_bit(@choice, 1)
84
+ range_encoder.encode_bit(@choice2, 1)
85
+ encode_tree(range_encoder, @high,
86
+ length - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS,
87
+ NUM_LEN_HIGH_BITS)
88
+ end
89
+ end
90
+
91
+ # Decode a match length using SDK-compatible decoding
92
+ #
93
+ # @param range_decoder [RangeDecoder] The range decoder
94
+ # @param pos_state [Integer] Position state for tree selection
95
+ # @return [Integer] Decoded length value (before adding MATCH_LEN_MIN)
96
+ def decode(range_decoder, pos_state)
97
+ choice_bit = range_decoder.decode_bit(@choice)
98
+
99
+ if choice_bit.zero?
100
+ # Low tree
101
+ decode_tree(range_decoder, @low[pos_state],
102
+ NUM_LEN_LOW_BITS)
103
+ elsif range_decoder.decode_bit(@choice2).zero?
104
+ # Mid tree
105
+ LEN_LOW_SYMBOLS +
106
+ decode_tree(range_decoder, @mid[pos_state], NUM_LEN_MID_BITS)
107
+ else
108
+ # High tree
109
+ LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS +
110
+ decode_tree(range_decoder, @high, NUM_LEN_HIGH_BITS)
111
+ end
112
+ end
113
+
114
+ # Reset probability models to initial values
115
+ #
116
+ # Called during state reset (control >= 0xA0) to reset the length
117
+ # coder's probability models. This matches XZ Utils behavior.
118
+ #
119
+ # @return [void]
120
+ def reset_models
121
+ @choice.reset
122
+ @choice2.reset
123
+
124
+ @low.each do |state_models|
125
+ state_models.each(&:reset)
126
+ end
127
+
128
+ @mid.each do |state_models|
129
+ state_models.each(&:reset)
130
+ end
131
+
132
+ @high.each(&:reset)
133
+ end
134
+
135
+ private
136
+
137
+ # Encode a value using a tree of bit models
138
+ #
139
+ # @param range_encoder [RangeEncoder] The range encoder
140
+ # @param models [Array<BitModel>] Array of bit models for the tree
141
+ # @param symbol [Integer] Symbol to encode
142
+ # @param num_bits [Integer] Number of bits in the tree
143
+ # @return [void]
144
+ def encode_tree(range_encoder, models, symbol, num_bits)
145
+ m = 1
146
+ (num_bits - 1).downto(0) do |i|
147
+ bit = (symbol >> i) & 1
148
+ range_encoder.encode_bit(models[m], bit)
149
+ m = (m << 1) | bit
150
+ end
151
+ end
152
+
153
+ # Decode a value using a tree of bit models
154
+ #
155
+ # @param range_decoder [RangeDecoder] The range decoder
156
+ # @param models [Array<BitModel>] Array of bit models for the tree
157
+ # @param num_bits [Integer] Number of bits in the tree
158
+ # @return [Integer] Decoded symbol
159
+ def decode_tree(range_decoder, models, num_bits)
160
+ m = 1
161
+ symbol = 0
162
+ (num_bits - 1).downto(0) do |i|
163
+ bit = range_decoder.decode_bit(models[m])
164
+ m = (m << 1) | bit
165
+ symbol |= (bit << i)
166
+ end
167
+ symbol
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end