cridecoder 0.3.4__tar.gz → 0.3.5__tar.gz

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 (49) hide show
  1. {cridecoder-0.3.4 → cridecoder-0.3.5}/Cargo.lock +1 -1
  2. {cridecoder-0.3.4 → cridecoder-0.3.5}/Cargo.toml +4 -4
  3. {cridecoder-0.3.4 → cridecoder-0.3.5}/PKG-INFO +2 -2
  4. {cridecoder-0.3.4 → cridecoder-0.3.5}/pyproject.toml +1 -1
  5. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/decoder.rs +6 -4
  6. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/hca_file.rs +5 -1
  7. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/python.rs +66 -38
  8. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/usm/extractor.rs +6 -8
  9. {cridecoder-0.3.4 → cridecoder-0.3.5}/.github/copilot-instructions.md +0 -0
  10. {cridecoder-0.3.4 → cridecoder-0.3.5}/.github/dependabot.yml +0 -0
  11. {cridecoder-0.3.4 → cridecoder-0.3.5}/.github/workflows/ci.yml +0 -0
  12. {cridecoder-0.3.4 → cridecoder-0.3.5}/.github/workflows/release-crate.yml +0 -0
  13. {cridecoder-0.3.4 → cridecoder-0.3.5}/.github/workflows/release-python.yml +0 -0
  14. {cridecoder-0.3.4 → cridecoder-0.3.5}/.gitignore +0 -0
  15. {cridecoder-0.3.4 → cridecoder-0.3.5}/AGENTS.md +0 -0
  16. {cridecoder-0.3.4 → cridecoder-0.3.5}/CLAUDE.md +0 -0
  17. {cridecoder-0.3.4 → cridecoder-0.3.5}/KNOWN_GAPS.md +0 -0
  18. {cridecoder-0.3.4 → cridecoder-0.3.5}/LICENSE +0 -0
  19. {cridecoder-0.3.4 → cridecoder-0.3.5}/README.md +0 -0
  20. {cridecoder-0.3.4 → cridecoder-0.3.5}/cridecoder.pyi +0 -0
  21. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/debug_acb.rs +0 -0
  22. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/hca_attrib.rs +0 -0
  23. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/hca_parallel.rs +0 -0
  24. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/profile_acb.rs +0 -0
  25. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/profile_hca.rs +0 -0
  26. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/test_acb.rs +0 -0
  27. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/test_hca.rs +0 -0
  28. {cridecoder-0.3.4 → cridecoder-0.3.5}/examples/test_usm.rs +0 -0
  29. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/afs.rs +0 -0
  30. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/builder.rs +0 -0
  31. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/consts.rs +0 -0
  32. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/decode.rs +0 -0
  33. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/extractor.rs +0 -0
  34. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/track.rs +0 -0
  35. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb/utf.rs +0 -0
  36. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/acb.rs +0 -0
  37. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/ath.rs +0 -0
  38. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/bitreader.rs +0 -0
  39. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/cipher.rs +0 -0
  40. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/encoder.rs +0 -0
  41. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/imdct.rs +0 -0
  42. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca/tables.rs +0 -0
  43. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/hca.rs +0 -0
  44. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/lib.rs +0 -0
  45. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/reader.rs +0 -0
  46. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/usm/builder.rs +0 -0
  47. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/usm/metadata.rs +0 -0
  48. {cridecoder-0.3.4 → cridecoder-0.3.5}/src/usm.rs +0 -0
  49. {cridecoder-0.3.4 → cridecoder-0.3.5}/tests/integration_tests.rs +0 -0
@@ -28,7 +28,7 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
28
28
 
29
29
  [[package]]
30
30
  name = "cridecoder"
31
- version = "0.3.4"
31
+ version = "0.3.5"
32
32
  dependencies = [
33
33
  "byteorder",
34
34
  "encoding_rs",
@@ -1,12 +1,12 @@
1
1
  [package]
2
2
  name = "cridecoder"
3
- version = "0.3.4"
3
+ version = "0.3.5"
4
4
  edition = "2021"
5
5
  description = "CRI codec library for ACB/AWB, HCA audio, and USM video extraction"
6
6
  license = "MIT"
7
- authors = ["Team-Haruki"]
8
- repository = "https://github.com/Team-Haruki/cridecoder"
9
- homepage = "https://github.com/Team-Haruki/cridecoder"
7
+ authors = ["Seiunx Dev"]
8
+ repository = "https://github.com/seiunx-dev/cridecoder"
9
+ homepage = "https://github.com/seiunx-dev/cridecoder"
10
10
  readme = "README.md"
11
11
  keywords = ["cri", "hca", "acb", "usm", "audio"]
12
12
  categories = ["multimedia::audio", "multimedia::video", "parser-implementations"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cridecoder
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -11,7 +11,7 @@ Classifier: Topic :: Multimedia :: Sound/Audio
11
11
  Classifier: Topic :: Multimedia :: Video
12
12
  License-File: LICENSE
13
13
  Summary: CRI codec library for ACB/AWB, HCA audio, and USM video extraction
14
- Home-Page: https://github.com/Team-Haruki/cridecoder
14
+ Home-Page: https://github.com/seiunx-dev/cridecoder
15
15
  License: MIT
16
16
  Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "cridecoder"
7
- version = "0.3.4"
7
+ version = "0.3.5"
8
8
  description = "CRI codec library for ACB/AWB, HCA audio, and USM video extraction"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -179,8 +179,8 @@ const fn build_crc16_slice() -> [[u16; 256]; 8] {
179
179
  /// naive loop (verified in tests) but ~5x faster over a full frame.
180
180
  pub fn crc16_checksum(data: &[u8]) -> u16 {
181
181
  let mut sum: u16 = 0;
182
- let mut chunks = data.chunks_exact(8);
183
- for c in &mut chunks {
182
+ let (chunks, remainder) = data.as_chunks::<8>();
183
+ for c in chunks {
184
184
  let i0 = ((sum >> 8) as u8 ^ c[0]) as usize;
185
185
  let i1 = (sum as u8 ^ c[1]) as usize;
186
186
  sum = CRC16_SLICE[7][i0]
@@ -192,7 +192,7 @@ pub fn crc16_checksum(data: &[u8]) -> u16 {
192
192
  ^ CRC16_SLICE[1][c[6] as usize]
193
193
  ^ CRC16_SLICE[0][c[7] as usize];
194
194
  }
195
- for &byte in chunks.remainder() {
195
+ for &byte in remainder {
196
196
  sum = (sum << 8) ^ CRC16_TABLE[((sum >> 8) ^ byte as u16) as usize];
197
197
  }
198
198
  sum
@@ -1024,7 +1024,9 @@ impl ClHca {
1024
1024
  }
1025
1025
  }
1026
1026
  for (ch, chunk) in out
1027
- .chunks_exact_mut(HCA_SAMPLES_PER_FRAME)
1027
+ .as_chunks_mut::<HCA_SAMPLES_PER_FRAME>()
1028
+ .0
1029
+ .iter_mut()
1028
1030
  .enumerate()
1029
1031
  .take(channels)
1030
1032
  {
@@ -702,7 +702,11 @@ fn decode_chunk_pcm(a: DecodeChunkArgs<'_>) -> Result<Vec<u8>, HcaError> {
702
702
  imdct_overlap(dct0, &mut a.prev[0], a.wave);
703
703
  imdct_overlap(dct1, &mut a.prev[1], &mut wave2);
704
704
  let out = &mut a.pcm[sf * 256..(sf + 1) * 256];
705
- for (pair, (&l, &r)) in out.chunks_exact_mut(2).zip(a.wave.iter().zip(wave2.iter()))
705
+ for (pair, (&l, &r)) in out
706
+ .as_chunks_mut::<2>()
707
+ .0
708
+ .iter_mut()
709
+ .zip(a.wave.iter().zip(wave2.iter()))
706
710
  {
707
711
  pair[0] = pcm_f32_to_i16(l);
708
712
  pair[1] = pcm_f32_to_i16(r);
@@ -27,13 +27,13 @@ use crate::usm::UsmBuilder;
27
27
  /// Returns:
28
28
  /// List of extracted file paths, or None if the file is invalid
29
29
  #[pyfunction]
30
- fn extract_acb(acb_path: &str, output_dir: &str) -> PyResult<Option<Vec<String>>> {
30
+ fn extract_acb(py: Python<'_>, acb_path: &str, output_dir: &str) -> PyResult<Option<Vec<String>>> {
31
31
  let acb_path = Path::new(acb_path);
32
32
  let output_dir = Path::new(output_dir);
33
33
  fs::create_dir_all(output_dir)
34
34
  .map_err(|e| PyRuntimeError::new_err(format!("Failed to create output dir: {}", e)))?;
35
35
 
36
- acb::extract_acb_from_file(acb_path, output_dir)
36
+ py.detach(|| acb::extract_acb_from_file(acb_path, output_dir))
37
37
  .map_err(|e| PyRuntimeError::new_err(format!("ACB extraction failed: {}", e)))
38
38
  }
39
39
 
@@ -61,7 +61,8 @@ fn extract_acb_tracks<'py>(
61
61
  fs::create_dir_all(output_dir)
62
62
  .map_err(|e| PyRuntimeError::new_err(format!("Failed to create output dir: {}", e)))?;
63
63
 
64
- let tracks = acb::extract_acb_tracks_from_file(acb_path, output_dir)
64
+ let tracks = py
65
+ .detach(|| acb::extract_acb_tracks_from_file(acb_path, output_dir))
65
66
  .map_err(|e| PyRuntimeError::new_err(format!("ACB extraction failed: {}", e)))?;
66
67
 
67
68
  let tracks = match tracks {
@@ -131,7 +132,8 @@ fn extract_acb_bytes<'py>(
131
132
  py: Python<'py>,
132
133
  acb_data: &[u8],
133
134
  ) -> PyResult<Vec<Bound<'py, pyo3::types::PyDict>>> {
134
- let tracks = acb::extract_acb_to_memory(Cursor::new(acb_data), None)
135
+ let tracks = py
136
+ .detach(|| acb::extract_acb_to_memory(Cursor::new(acb_data), None))
135
137
  .map_err(|e| PyRuntimeError::new_err(format!("ACB extraction failed: {}", e)))?;
136
138
 
137
139
  let mut out = Vec::with_capacity(tracks.len());
@@ -164,7 +166,8 @@ fn extract_acb_unique_bytes<'py>(
164
166
  py: Python<'py>,
165
167
  acb_data: &[u8],
166
168
  ) -> PyResult<Vec<Bound<'py, pyo3::types::PyDict>>> {
167
- let waveforms = acb::extract_acb_unique_to_memory(Cursor::new(acb_data), None)
169
+ let waveforms = py
170
+ .detach(|| acb::extract_acb_unique_to_memory(Cursor::new(acb_data), None))
168
171
  .map_err(|e| PyRuntimeError::new_err(format!("ACB extraction failed: {}", e)))?;
169
172
 
170
173
  let mut out = Vec::with_capacity(waveforms.len());
@@ -235,7 +238,11 @@ fn decode_acb_to_wav_bytes<'py>(
235
238
  /// Returns:
236
239
  /// None on success
237
240
  #[pyfunction]
238
- fn build_acb(tracks: Vec<(String, u32, Vec<u8>)>, output_path: &str) -> PyResult<()> {
241
+ fn build_acb(
242
+ py: Python<'_>,
243
+ tracks: Vec<(String, u32, Vec<u8>)>,
244
+ output_path: &str,
245
+ ) -> PyResult<()> {
239
246
  let mut builder = AcbBuilder::new();
240
247
 
241
248
  for (name, cue_id, data) in tracks {
@@ -246,8 +253,7 @@ fn build_acb(tracks: Vec<(String, u32, Vec<u8>)>, output_path: &str) -> PyResult
246
253
  let mut output = fs::File::create(output_path)
247
254
  .map_err(|e| PyRuntimeError::new_err(format!("Failed to create output file: {}", e)))?;
248
255
 
249
- builder
250
- .build(&mut output, None)
256
+ py.detach(|| builder.build(&mut output, None))
251
257
  .map_err(|e| PyRuntimeError::new_err(format!("ACB build failed: {}", e)))?;
252
258
 
253
259
  Ok(())
@@ -261,7 +267,7 @@ fn build_acb(tracks: Vec<(String, u32, Vec<u8>)>, output_path: &str) -> PyResult
261
267
  /// Returns:
262
268
  /// ACB file data as bytes
263
269
  #[pyfunction]
264
- fn build_acb_bytes(tracks: Vec<(String, u32, Vec<u8>)>) -> PyResult<Vec<u8>> {
270
+ fn build_acb_bytes(py: Python<'_>, tracks: Vec<(String, u32, Vec<u8>)>) -> PyResult<Vec<u8>> {
265
271
  let mut builder = AcbBuilder::new();
266
272
 
267
273
  for (name, cue_id, data) in tracks {
@@ -269,12 +275,13 @@ fn build_acb_bytes(tracks: Vec<(String, u32, Vec<u8>)>) -> PyResult<Vec<u8>> {
269
275
  builder.add_track(track);
270
276
  }
271
277
 
272
- let mut output = Cursor::new(Vec::new());
273
- builder
274
- .build(&mut output, None)
275
- .map_err(|e| PyRuntimeError::new_err(format!("ACB build failed: {}", e)))?;
276
-
277
- Ok(output.into_inner())
278
+ py.detach(|| {
279
+ let mut output = Cursor::new(Vec::new());
280
+ builder
281
+ .build(&mut output, None)
282
+ .map(|_| output.into_inner())
283
+ })
284
+ .map_err(|e| PyRuntimeError::new_err(format!("ACB build failed: {}", e)))
278
285
  }
279
286
 
280
287
  /// Build a single-track music ACB from one HCA track (returns bytes).
@@ -303,6 +310,7 @@ fn build_acb_bytes(tracks: Vec<(String, u32, Vec<u8>)>) -> PyResult<Vec<u8>> {
303
310
  #[pyfunction]
304
311
  #[allow(clippy::too_many_arguments)]
305
312
  fn build_music_acb_bytes(
313
+ py: Python<'_>,
306
314
  name: String,
307
315
  hca_data: Vec<u8>,
308
316
  cue_id: u32,
@@ -340,12 +348,13 @@ fn build_music_acb_bytes(
340
348
  );
341
349
  builder.add_track(TrackInput::new(name, cue_id, hca_data));
342
350
 
343
- let mut output = Cursor::new(Vec::new());
344
- builder
345
- .build(&mut output, None)
346
- .map_err(|e| PyRuntimeError::new_err(format!("Music ACB build failed: {}", e)))?;
347
-
348
- Ok(output.into_inner())
351
+ py.detach(|| {
352
+ let mut output = Cursor::new(Vec::new());
353
+ builder
354
+ .build(&mut output, None)
355
+ .map(|_| output.into_inner())
356
+ })
357
+ .map_err(|e| PyRuntimeError::new_err(format!("Music ACB build failed: {}", e)))
349
358
  }
350
359
 
351
360
  /// Resolve the optional `threads` argument shared by the HCA decode bindings:
@@ -453,6 +462,18 @@ fn decode_hca_bytes(
453
462
  #[pyfunction]
454
463
  #[pyo3(signature = (wav_data, sample_rate=None, channels=None, bitrate=256000, encryption_key=None))]
455
464
  fn encode_hca_bytes(
465
+ py: Python<'_>,
466
+ wav_data: &[u8],
467
+ sample_rate: Option<u32>,
468
+ channels: Option<u32>,
469
+ bitrate: u32,
470
+ encryption_key: Option<u64>,
471
+ ) -> PyResult<Vec<u8>> {
472
+ py.detach(|| encode_wav_to_hca(wav_data, sample_rate, channels, bitrate, encryption_key))
473
+ }
474
+
475
+ /// GIL-free core of the HCA encode bindings (WAV parse + PCM convert + encode).
476
+ fn encode_wav_to_hca(
456
477
  wav_data: &[u8],
457
478
  sample_rate: Option<u32>,
458
479
  channels: Option<u32>,
@@ -595,13 +616,16 @@ fn encode_hca<'py>(
595
616
  bitrate: u32,
596
617
  encryption_key: Option<u64>,
597
618
  ) -> PyResult<Bound<'py, pyo3::types::PyDict>> {
598
- let wav_data = fs::read(wav_path)
599
- .map_err(|e| PyRuntimeError::new_err(format!("Failed to read WAV: {}", e)))?;
619
+ let hca_data = py.detach(|| {
620
+ let wav_data = fs::read(wav_path)
621
+ .map_err(|e| PyRuntimeError::new_err(format!("Failed to read WAV: {}", e)))?;
600
622
 
601
- let hca_data = encode_hca_bytes(&wav_data, None, None, bitrate, encryption_key)?;
623
+ let hca_data = encode_wav_to_hca(&wav_data, None, None, bitrate, encryption_key)?;
602
624
 
603
- fs::write(hca_path, &hca_data)
604
- .map_err(|e| PyRuntimeError::new_err(format!("Failed to write HCA: {}", e)))?;
625
+ fs::write(hca_path, &hca_data)
626
+ .map_err(|e| PyRuntimeError::new_err(format!("Failed to write HCA: {}", e)))?;
627
+ Ok::<_, PyErr>(hca_data)
628
+ })?;
605
629
 
606
630
  let dict = pyo3::types::PyDict::new(py);
607
631
  dict.set_item("size", hca_data.len())?;
@@ -623,6 +647,7 @@ fn encode_hca<'py>(
623
647
  #[pyfunction]
624
648
  #[pyo3(signature = (usm_path, output_dir, key=None, export_audio=false))]
625
649
  fn extract_usm(
650
+ py: Python<'_>,
626
651
  usm_path: &str,
627
652
  output_dir: &str,
628
653
  key: Option<u64>,
@@ -633,7 +658,8 @@ fn extract_usm(
633
658
  fs::create_dir_all(output_dir)
634
659
  .map_err(|e| PyRuntimeError::new_err(format!("Failed to create output dir: {}", e)))?;
635
660
 
636
- let files = usm::extract_usm_file(usm_path, output_dir, key, export_audio)
661
+ let files = py
662
+ .detach(|| usm::extract_usm_file(usm_path, output_dir, key, export_audio))
637
663
  .map_err(|e| PyRuntimeError::new_err(format!("USM extraction failed: {}", e)))?;
638
664
 
639
665
  Ok(files
@@ -663,7 +689,8 @@ fn extract_usm_bytes<'py>(
663
689
  key: Option<u64>,
664
690
  export_audio: bool,
665
691
  ) -> PyResult<Vec<Bound<'py, pyo3::types::PyDict>>> {
666
- let streams = usm::extract_usm_to_memory(Cursor::new(usm_data), b"", key, export_audio)
692
+ let streams = py
693
+ .detach(|| usm::extract_usm_to_memory(Cursor::new(usm_data), b"", key, export_audio))
667
694
  .map_err(|e| PyRuntimeError::new_err(format!("USM extraction failed: {}", e)))?;
668
695
 
669
696
  let mut out = Vec::with_capacity(streams.len());
@@ -690,6 +717,7 @@ fn extract_usm_bytes<'py>(
690
717
  #[pyfunction]
691
718
  #[pyo3(signature = (name, video_data, output_path, encryption_key=None))]
692
719
  fn build_usm(
720
+ py: Python<'_>,
693
721
  name: &str,
694
722
  video_data: Vec<u8>,
695
723
  output_path: &str,
@@ -704,8 +732,7 @@ fn build_usm(
704
732
  let mut output = fs::File::create(output_path)
705
733
  .map_err(|e| PyRuntimeError::new_err(format!("Failed to create output file: {}", e)))?;
706
734
 
707
- builder
708
- .build(&mut output)
735
+ py.detach(|| builder.build(&mut output))
709
736
  .map_err(|e| PyRuntimeError::new_err(format!("USM build failed: {}", e)))?;
710
737
 
711
738
  Ok(())
@@ -723,6 +750,7 @@ fn build_usm(
723
750
  #[pyfunction]
724
751
  #[pyo3(signature = (name, video_data, encryption_key=None))]
725
752
  fn build_usm_bytes(
753
+ py: Python<'_>,
726
754
  name: &str,
727
755
  video_data: Vec<u8>,
728
756
  encryption_key: Option<u64>,
@@ -733,12 +761,11 @@ fn build_usm_bytes(
733
761
  builder = builder.encryption_key(key);
734
762
  }
735
763
 
736
- let mut output = Cursor::new(Vec::new());
737
- builder
738
- .build(&mut output)
739
- .map_err(|e| PyRuntimeError::new_err(format!("USM build failed: {}", e)))?;
740
-
741
- Ok(output.into_inner())
764
+ py.detach(|| {
765
+ let mut output = Cursor::new(Vec::new());
766
+ builder.build(&mut output).map(|_| output.into_inner())
767
+ })
768
+ .map_err(|e| PyRuntimeError::new_err(format!("USM build failed: {}", e)))
742
769
  }
743
770
 
744
771
  /// Read metadata from a USM file.
@@ -749,9 +776,10 @@ fn build_usm_bytes(
749
776
  /// Returns:
750
777
  /// Metadata as a JSON string
751
778
  #[pyfunction]
752
- fn read_usm_metadata(usm_path: &str) -> PyResult<String> {
779
+ fn read_usm_metadata(py: Python<'_>, usm_path: &str) -> PyResult<String> {
753
780
  let usm_path = Path::new(usm_path);
754
- let metadata = usm::read_metadata_file(usm_path)
781
+ let metadata = py
782
+ .detach(|| usm::read_metadata_file(usm_path))
755
783
  .map_err(|e| PyRuntimeError::new_err(format!("Metadata read failed: {}", e)))?;
756
784
 
757
785
  serde_json::to_string_pretty(&metadata)
@@ -341,15 +341,14 @@ fn mask_video(buf: &mut [u8], vmask: &VideoMask) {
341
341
  // Second pass: original i in 0x100..size -> buf[0x140..len]. 0x100 is
342
342
  // 32-aligned, so row position j maps to mask lane j.
343
343
  {
344
- let mut chunks = buf[0x140..len].chunks_exact_mut(MASK_LEN);
345
- for row in &mut chunks {
346
- let row: &mut [u8; MASK_LEN] = row.try_into().unwrap();
344
+ let (chunks, remainder) = buf[0x140..len].as_chunks_mut::<MASK_LEN>();
345
+ for row in chunks {
347
346
  for j in 0..MASK_LEN {
348
347
  row[j] ^= mask[j];
349
348
  mask[j] = row[j] ^ vm1[j];
350
349
  }
351
350
  }
352
- for (j, b) in chunks.into_remainder().iter_mut().enumerate() {
351
+ for (j, b) in remainder.iter_mut().enumerate() {
353
352
  *b ^= mask[j];
354
353
  mask[j] = *b ^ vm1[j];
355
354
  }
@@ -371,14 +370,13 @@ fn mask_audio(buf: &mut [u8], amask: &AudioMask) {
371
370
  let Some(region) = buf.get_mut(0x140..) else {
372
371
  return;
373
372
  };
374
- let mut chunks = region.chunks_exact_mut(MASK_LEN);
375
- for row in &mut chunks {
376
- let row: &mut [u8; MASK_LEN] = row.try_into().unwrap();
373
+ let (chunks, remainder) = region.as_chunks_mut::<MASK_LEN>();
374
+ for row in chunks {
377
375
  for j in 0..MASK_LEN {
378
376
  row[j] ^= amask[j];
379
377
  }
380
378
  }
381
- for (j, b) in chunks.into_remainder().iter_mut().enumerate() {
379
+ for (j, b) in remainder.iter_mut().enumerate() {
382
380
  *b ^= amask[j];
383
381
  }
384
382
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes