PyCriCodecsEx 0.0.1__cp311-cp311-win32.whl → 0.0.3__cp311-cp311-win32.whl
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.
Potentially problematic release.
This version of PyCriCodecsEx might be problematic. Click here for more details.
- CriCodecsEx.cp311-win32.pyd +0 -0
- PyCriCodecsEx/__init__.py +1 -1
- PyCriCodecsEx/acb.py +198 -19
- PyCriCodecsEx/adx.py +143 -4
- PyCriCodecsEx/awb.py +29 -14
- PyCriCodecsEx/chunk.py +24 -7
- PyCriCodecsEx/cpk.py +25 -16
- PyCriCodecsEx/hca.py +187 -38
- PyCriCodecsEx/usm.py +68 -339
- PyCriCodecsEx/utf.py +25 -37
- pycricodecsex-0.0.3.dist-info/METADATA +35 -0
- pycricodecsex-0.0.3.dist-info/RECORD +15 -0
- pycricodecsex-0.0.1.dist-info/METADATA +0 -81
- pycricodecsex-0.0.1.dist-info/RECORD +0 -15
- {pycricodecsex-0.0.1.dist-info → pycricodecsex-0.0.3.dist-info}/WHEEL +0 -0
- {pycricodecsex-0.0.1.dist-info → pycricodecsex-0.0.3.dist-info}/licenses/LICENSE +0 -0
- {pycricodecsex-0.0.1.dist-info → pycricodecsex-0.0.3.dist-info}/top_level.txt +0 -0
PyCriCodecsEx/utf.py
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
from typing import BinaryIO, TypeVar, Type, List
|
|
2
|
+
from copy import deepcopy
|
|
2
3
|
|
|
3
4
|
T = TypeVar("T")
|
|
5
|
+
Ty = TypeVar("Ty", bound="UTFViewer")
|
|
4
6
|
from io import BytesIO, FileIO
|
|
5
7
|
from struct import unpack, calcsize, pack
|
|
6
8
|
from PyCriCodecsEx.chunk import *
|
|
7
9
|
|
|
8
10
|
class UTF:
|
|
11
|
+
"""Use this class to unpack @UTF table binary payload."""
|
|
9
12
|
|
|
10
13
|
_dictarray: list
|
|
11
14
|
|
|
@@ -21,11 +24,11 @@ class UTF:
|
|
|
21
24
|
recursive: bool
|
|
22
25
|
encoding : str = 'utf-8'
|
|
23
26
|
|
|
24
|
-
def __init__(self, stream, recursive=False):
|
|
27
|
+
def __init__(self, stream : str | BinaryIO, recursive=False):
|
|
25
28
|
"""Unpacks UTF table binary payload
|
|
26
29
|
|
|
27
30
|
Args:
|
|
28
|
-
stream (Union[str
|
|
31
|
+
stream (Union[str | BinaryIO]): The input stream or file path to read the UTF table from.
|
|
29
32
|
recursive (bool): Whether to recursively unpack nested UTF tables.
|
|
30
33
|
"""
|
|
31
34
|
if type(stream) == str:
|
|
@@ -288,6 +291,7 @@ class UTF:
|
|
|
288
291
|
return self._dictarray
|
|
289
292
|
|
|
290
293
|
class UTFBuilder:
|
|
294
|
+
"""Use this class to build UTF table binary payloads from a `dictarray`."""
|
|
291
295
|
|
|
292
296
|
encoding: str
|
|
293
297
|
dictarray: list
|
|
@@ -302,7 +306,7 @@ class UTFBuilder:
|
|
|
302
306
|
|
|
303
307
|
def __init__(
|
|
304
308
|
self,
|
|
305
|
-
|
|
309
|
+
dictarray_src: list[dict],
|
|
306
310
|
encrypt: bool = False,
|
|
307
311
|
encoding: str = "utf-8",
|
|
308
312
|
table_name: str = "PyCriCodecs_table",
|
|
@@ -311,14 +315,14 @@ class UTFBuilder:
|
|
|
311
315
|
"""Packs UTF payload back into their binary form
|
|
312
316
|
|
|
313
317
|
Args:
|
|
314
|
-
|
|
318
|
+
dictarray_src: list[dict]: A list of dictionaries representing the UTF table.
|
|
315
319
|
encrypt: Whether to encrypt the table (default: False).
|
|
316
320
|
encoding: The character encoding to use (default: "utf-8").
|
|
317
321
|
table_name: The name of the table (default: "PyCriCodecs_table").
|
|
318
322
|
ignore_recursion: Whether to ignore recursion when packing (default: False).
|
|
319
323
|
"""
|
|
320
|
-
assert type(
|
|
321
|
-
|
|
324
|
+
assert type(dictarray_src) == list, "dictarray must be a list of dictionaries (see UTF.dictarray)."
|
|
325
|
+
dictarray = deepcopy(dictarray_src)
|
|
322
326
|
# Preprocess for nested dictarray types
|
|
323
327
|
def dfs(payload: list[dict], name: str) -> None:
|
|
324
328
|
for dict in range(len(payload)):
|
|
@@ -589,36 +593,18 @@ class UTFBuilder:
|
|
|
589
593
|
return dataarray
|
|
590
594
|
|
|
591
595
|
class UTFViewer:
|
|
596
|
+
"""Use this class to create dataclass-like access to `dictarray`s."""
|
|
597
|
+
|
|
592
598
|
_payload: dict
|
|
593
599
|
|
|
594
600
|
def __init__(self, payload):
|
|
595
601
|
"""Construct a non-owning read-write, deletable view of a UTF table dictarray.
|
|
602
|
+
|
|
596
603
|
Nested classes are supported.
|
|
597
|
-
Sorting (using .sort()) is done in-place and affects the original payload.
|
|
598
604
|
|
|
599
|
-
|
|
600
|
-
```python
|
|
601
|
-
class CueNameTable(UTFViewer):
|
|
602
|
-
CueName : str
|
|
603
|
-
CueIndex : int
|
|
604
|
-
class ACBTable(UTFViewer):
|
|
605
|
-
CueNameTable : List[CueNameTable]
|
|
606
|
-
Awb : AWB
|
|
607
|
-
src = ACB(ACB_sample)
|
|
608
|
-
payload = ACBTable(src.payload)
|
|
609
|
-
>>> Referencing items through Python is allowed
|
|
610
|
-
name = payload.CueNameTable
|
|
611
|
-
>>> Lists can be indexed
|
|
612
|
-
name_str = name[0].CueName
|
|
613
|
-
>>> Deleting items from lists is also allowed
|
|
614
|
-
src.view.CueNameTable.pop(1)
|
|
615
|
-
src.view.CueTable.pop(1)
|
|
616
|
-
>>> The changes will be reflected in the original UTF payload
|
|
617
|
-
|
|
618
|
-
See __new__ for the actual constructor.
|
|
619
|
-
```
|
|
605
|
+
Sorting (using .sort()) is done in-place and affects the original payload.
|
|
620
606
|
"""
|
|
621
|
-
assert isinstance(payload, dict), "
|
|
607
|
+
assert isinstance(payload, dict), "payload must be a dictionary."
|
|
622
608
|
super().__setattr__("_payload", payload)
|
|
623
609
|
|
|
624
610
|
def __getattr__(self, item):
|
|
@@ -643,7 +629,9 @@ class UTFViewer:
|
|
|
643
629
|
def __setattr__(self, item, value):
|
|
644
630
|
payload = super().__getattribute__("_payload")
|
|
645
631
|
if item not in payload:
|
|
646
|
-
raise AttributeError(f"{item} not in payload")
|
|
632
|
+
raise AttributeError(f"{item} not in payload. UTFViewer should not store extra states")
|
|
633
|
+
if isinstance(value, dict) or isinstance(value, list):
|
|
634
|
+
raise AttributeError(f"Dict or list assignment is not allowed as this may potentially change the table layout. Access by elements and use list APIs instead")
|
|
647
635
|
typeof, _ = payload[item]
|
|
648
636
|
payload[item] = (typeof, value)
|
|
649
637
|
|
|
@@ -659,9 +647,9 @@ class UTFViewer:
|
|
|
659
647
|
|
|
660
648
|
class ListView(list):
|
|
661
649
|
_payload : List[dict]
|
|
662
|
-
def __init__(self, payload: list[
|
|
650
|
+
def __init__(self, clazz : Type[Ty], payload: list[Ty]):
|
|
663
651
|
self._payload = payload
|
|
664
|
-
super().__init__([
|
|
652
|
+
super().__init__([clazz(item) for item in payload])
|
|
665
653
|
|
|
666
654
|
def pop(self, index = -1):
|
|
667
655
|
self._payload.pop(index)
|
|
@@ -669,7 +657,7 @@ class UTFViewer:
|
|
|
669
657
|
|
|
670
658
|
def append(self, o : "UTFViewer"):
|
|
671
659
|
if len(self):
|
|
672
|
-
assert type(self[0]) == type(o), "all items in the list must be of the same type."
|
|
660
|
+
assert isinstance(o, UTFViewer) and type(self[0]) == type(o), "all items in the list must be of the same type, and must be an instance of UTFViewer."
|
|
673
661
|
self._payload.append(o._payload)
|
|
674
662
|
return super().append(o)
|
|
675
663
|
|
|
@@ -677,9 +665,9 @@ class UTFViewer:
|
|
|
677
665
|
for item in iterable:
|
|
678
666
|
self.append(item)
|
|
679
667
|
|
|
680
|
-
def insert(self, index, o : "UTFViewer"):
|
|
668
|
+
def insert(self, index, o : "UTFViewer"):
|
|
681
669
|
if len(self):
|
|
682
|
-
assert type(self[0]) == type(o), "all items in the list must be of the same type."
|
|
670
|
+
assert isinstance(o, UTFViewer) and type(self[0]) == type(o), "all items in the list must be of the same type, and must be an instance of UTFViewer."
|
|
683
671
|
self._payload.insert(index, o._payload)
|
|
684
672
|
return super().insert(index, o)
|
|
685
673
|
|
|
@@ -698,7 +686,7 @@ class UTFViewer:
|
|
|
698
686
|
self._payload[:] = [self._payload[i] for x,i in p]
|
|
699
687
|
self[:] = [x for x,i in p]
|
|
700
688
|
|
|
701
|
-
def __new__(cls: Type[
|
|
689
|
+
def __new__(cls: Type[Ty], payload: list | dict, **args) -> Ty | List[Ty]:
|
|
702
690
|
if isinstance(payload, list):
|
|
703
|
-
return UTFViewer.ListView(payload)
|
|
691
|
+
return UTFViewer.ListView(cls, payload)
|
|
704
692
|
return super().__new__(cls)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyCriCodecsEx
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Criware formats library for Python
|
|
5
|
+
Home-page: https://mos9527.github.io/PyCriCodecsEx/
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Provides-Extra: usm
|
|
13
|
+
Requires-Dist: ffmpeg-python; extra == "usm"
|
|
14
|
+
Dynamic: classifier
|
|
15
|
+
Dynamic: description
|
|
16
|
+
Dynamic: description-content-type
|
|
17
|
+
Dynamic: home-page
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
Dynamic: provides-extra
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
Dynamic: summary
|
|
22
|
+
|
|
23
|
+
PyCriCodecsEx
|
|
24
|
+
---
|
|
25
|
+
A continuation of @Youjose's work on Criware formats. Feautres are still in flux and subject to change. When in doubt, Refer to the [original repo](https://github.com/Youjose/PyCriCodecs) for more information.
|
|
26
|
+
|
|
27
|
+
Detailed documentation, installation instructions are available at https://mos9527.com/PyCriCodecsEx
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Credits
|
|
31
|
+
- https://github.com/Youjose/PyCriCodecs
|
|
32
|
+
- https://github.com/Mikewando/PyCriCodecs ([PR#1 on USM](https://github.com/mos9527/PyCriCodecsEx/pull/1))
|
|
33
|
+
- https://github.com/donmai-me/WannaCRI
|
|
34
|
+
- https://github.com/vgmstream/vgmstream
|
|
35
|
+
- https://github.com/K0lb3/UnityPy (For CI script)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
CriCodecsEx.cp311-win32.pyd,sha256=HRG3LEkKVD--EV5Oc16VgJnhi3TC_JndeFWgrmnyYb8,68096
|
|
2
|
+
PyCriCodecsEx/__init__.py,sha256=4dCrvStS1OgE3Vlcv-qx5-TAo377yOMEToEqCi-PwY4,23
|
|
3
|
+
PyCriCodecsEx/acb.py,sha256=nOWggyQTPOBArzRp_7VRO9TY1diLxr2mRPKQd-sd2s0,10723
|
|
4
|
+
PyCriCodecsEx/adx.py,sha256=s3gJBgKrwWjUahrxSJEy1GNHJrdz3iaylgr0TyTIi7M,5967
|
|
5
|
+
PyCriCodecsEx/awb.py,sha256=t6owuEOH3Be31iBuEMwriOh0cPdVtpzsNbTPfLwg_cc,6363
|
|
6
|
+
PyCriCodecsEx/chunk.py,sha256=xmc92tONmXpdbOW2g-KckTeppTXFo8Km0J95UYbbvQg,2810
|
|
7
|
+
PyCriCodecsEx/cpk.py,sha256=bMJgvzPInM95R9dEdhHGW65jR9tFBKUacyOwZS2gOyA,38206
|
|
8
|
+
PyCriCodecsEx/hca.py,sha256=BamujR3tRxMmgnPAYpUOamzOUOBs5hXWhkcBnj7Eeh4,19445
|
|
9
|
+
PyCriCodecsEx/usm.py,sha256=LWSXXkfV1FZpymV0X6UH-lyS5gV6ecBHlLLXXXN9wMc,36972
|
|
10
|
+
PyCriCodecsEx/utf.py,sha256=0LBzpIbJiyL_4KOf_QpEJytr3PbHj8_M4Bd-Lay4wuk,28247
|
|
11
|
+
pycricodecsex-0.0.3.dist-info/licenses/LICENSE,sha256=B47Qr_82CmMyuL-wNFAH_P6PNJWaonv5dxo9MfgjEXw,1083
|
|
12
|
+
pycricodecsex-0.0.3.dist-info/METADATA,sha256=buywcqSll1E63mnWNtEgwHiyAY8NbvMyP8CDLXAJLH0,1291
|
|
13
|
+
pycricodecsex-0.0.3.dist-info/WHEEL,sha256=Ri8zddKrjGdgjlj1OpSsvpDnvHfnQhMQWi3E_v2pqng,97
|
|
14
|
+
pycricodecsex-0.0.3.dist-info/top_level.txt,sha256=mSrrEse9hT0s6nl-sWAQWAhNRuZ6jo98pbFoN3L2MXk,26
|
|
15
|
+
pycricodecsex-0.0.3.dist-info/RECORD,,
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: PyCriCodecsEx
|
|
3
|
-
Version: 0.0.1
|
|
4
|
-
Summary: Criware formats library for Python
|
|
5
|
-
Home-page: https://github.com/mos9527/PyCriCodecsEx
|
|
6
|
-
Classifier: Programming Language :: Python :: 3
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
Classifier: Operating System :: OS Independent
|
|
9
|
-
Requires-Python: >=3.10
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Provides-Extra: usm
|
|
13
|
-
Requires-Dist: ffmpeg-python; extra == "usm"
|
|
14
|
-
Dynamic: classifier
|
|
15
|
-
Dynamic: description
|
|
16
|
-
Dynamic: description-content-type
|
|
17
|
-
Dynamic: home-page
|
|
18
|
-
Dynamic: license-file
|
|
19
|
-
Dynamic: provides-extra
|
|
20
|
-
Dynamic: requires-python
|
|
21
|
-
Dynamic: summary
|
|
22
|
-
|
|
23
|
-
# PyCriCodecsEx
|
|
24
|
-
A continuation of @Youjose's work on Criware formats. Feautres are still in flux and subject to change. When in doubt, Refer to the [original repo](https://github.com/Youjose/PyCriCodecs) for more information.
|
|
25
|
-
|
|
26
|
-
# Installation
|
|
27
|
-
```bash
|
|
28
|
-
pip install PyCriCodecsEx
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
For USM features, you need `ffmpeg` installed and available in your PATH. See also https://github.com/kkroening/ffmpeg-python?tab=readme-ov-file#installing-ffmpeg
|
|
32
|
-
|
|
33
|
-
## Features
|
|
34
|
-
If not otherwise mentioned, all features marked with [x] are considered working, and has been verified with official tools.
|
|
35
|
-
|
|
36
|
-
### ACB Cue sheets (also AWB)
|
|
37
|
-
- [x] Editing & Saving (Scripting APIs. Helper functions TODO. see examples in [Tests](https://github.com/mos9527/PyCriCodecsEx/tree/main/Tests))
|
|
38
|
-
### USM Sofdec2 (Encode & Decode)
|
|
39
|
-
#### Audio Stream
|
|
40
|
-
For audio to be muxed in, you need a PCM WAV sample with NO metadata, which can be produced with e.g.:
|
|
41
|
-
```bash
|
|
42
|
-
ffmpeg -i input.mp3 -vn -c:a pcm_s16le -map_metadata -1 output.wav
|
|
43
|
-
```
|
|
44
|
-
Decoding and Encoded format can be the following:
|
|
45
|
-
- [x] HCA
|
|
46
|
-
- [x] ADX
|
|
47
|
-
#### Video Stream
|
|
48
|
-
**NOTE**: You definitely want to tweak these encode settings a bit.
|
|
49
|
-
- [x] Sofdec Prime (MPEG1, from `.m1v` container)
|
|
50
|
-
- Prepare source file with: `ffmpeg -i <input_file> -c:v mpeg1video -an <output_file>.m1v`
|
|
51
|
-
- [x] H264 (from `.h264` raw container)
|
|
52
|
-
- Prepare source file with: `ffmpeg -i <input_file> -c:v libx264 -an <output_file>.h264`
|
|
53
|
-
- [x] VP9 (from `.ivf` container)
|
|
54
|
-
- Prepare source file with: `ffmpeg -i <input_file> -c:v libvpx -an <output_file>.ivf`
|
|
55
|
-
### HCA Audio Codec
|
|
56
|
-
- [x] Decoding (up to version 3.0)
|
|
57
|
-
- [x] Encoding (up to version 3.0)
|
|
58
|
-
### ADX Audio Codec
|
|
59
|
-
- [x] Decoding
|
|
60
|
-
- [x] Encoding
|
|
61
|
-
### CPK
|
|
62
|
-
- [x] Unpacking
|
|
63
|
-
- [x] Packing
|
|
64
|
-
|
|
65
|
-
## Roadmap
|
|
66
|
-
- [ ] ACB Extraction (Massive TODO. see also https://github.com/mos9527/PyCriCodecsEx/blob/main/Research/ACBSchema.py)
|
|
67
|
-
- [ ] Interface for encode tasks (CLI then maybe GUI?)
|
|
68
|
-
- [ ] Documentation
|
|
69
|
-
- [ ] C/C++ port + FFI
|
|
70
|
-
## Currently Known Bugs
|
|
71
|
-
- USM seeking does not work. Though most games don't use it anyways.
|
|
72
|
-
- Not important, and might not fix: ADX encoding and decoding at higher bitdepths (11-15) adds popping noise.
|
|
73
|
-
- Some CPK's that has the same filename for every file in the entry will overwrite each other.
|
|
74
|
-
- Probably many more I am unaware of, report if you find any.
|
|
75
|
-
|
|
76
|
-
# Credits
|
|
77
|
-
- https://github.com/Youjose/PyCriCodecs
|
|
78
|
-
- https://github.com/Mikewando/PyCriCodecs ([PR#1 on USM](https://github.com/mos9527/PyCriCodecsEx/pull/1))
|
|
79
|
-
- https://github.com/donmai-me/WannaCRI
|
|
80
|
-
- https://github.com/vgmstream/vgmstream
|
|
81
|
-
- https://github.com/K0lb3/UnityPy (For CI script)
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
CriCodecsEx.cp311-win32.pyd,sha256=vNU5Znkk844dYwph88LlPvWAC8RuC4s_1E7_NDXPe4s,68096
|
|
2
|
-
PyCriCodecsEx/__init__.py,sha256=ry5O5SW74ugwOUMKSV2_LbWjYa8B0IEvUm7S-lHPA2c,23
|
|
3
|
-
PyCriCodecsEx/acb.py,sha256=v0CxjveQewxUWuila1O0qDGcAfvOxqnzYqAL4AHneqU,2706
|
|
4
|
-
PyCriCodecsEx/adx.py,sha256=KnL4wy1ccoc6uHYZVino7cJQB2pMn4BbRhpH3r527TY,777
|
|
5
|
-
PyCriCodecsEx/awb.py,sha256=p68tVqZOorOE1Js-w1Sqy4GMvu9gxzlBgUL2LAUNEqU,5657
|
|
6
|
-
PyCriCodecsEx/chunk.py,sha256=nrRUANDFZ1LDszHEGDDnQDuNnAB_kGCzbpC7bsgtjqc,2504
|
|
7
|
-
PyCriCodecsEx/cpk.py,sha256=AKShN6P7p70i3GQfKKS-VH3mkbexOLfHEJrjuxS0SQQ,37692
|
|
8
|
-
PyCriCodecsEx/hca.py,sha256=lSslLyv1D1zM_kHFyOlKpbM7qzghmJDYRd-isP8qcyg,14192
|
|
9
|
-
PyCriCodecsEx/usm.py,sha256=X4mv-3ksiX10C6EDACpu-dwRn9eSy3wmY7of2aO7eiA,46216
|
|
10
|
-
PyCriCodecsEx/utf.py,sha256=Yp1Le3AS7UC4So_sGO39N5X5D23X7MsWugHo52npwR0,28256
|
|
11
|
-
pycricodecsex-0.0.1.dist-info/licenses/LICENSE,sha256=B47Qr_82CmMyuL-wNFAH_P6PNJWaonv5dxo9MfgjEXw,1083
|
|
12
|
-
pycricodecsex-0.0.1.dist-info/METADATA,sha256=Z4KAoITGoFoNhiiJ_YXSnrBE--W51_Q-pXt3lerFMX8,3324
|
|
13
|
-
pycricodecsex-0.0.1.dist-info/WHEEL,sha256=Ri8zddKrjGdgjlj1OpSsvpDnvHfnQhMQWi3E_v2pqng,97
|
|
14
|
-
pycricodecsex-0.0.1.dist-info/top_level.txt,sha256=mSrrEse9hT0s6nl-sWAQWAhNRuZ6jo98pbFoN3L2MXk,26
|
|
15
|
-
pycricodecsex-0.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|