sillstone 0.2.0b1__py3-none-any.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.
sillstone/__init__.py ADDED
@@ -0,0 +1,551 @@
1
+ """Sillstone Python SDK: Zero-dependency multimedia, hashing, and array computing suite."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ from dataclasses import dataclass
7
+ from pathlib import Path
8
+ import struct
9
+
10
+ from ._generated import (
11
+ LIB,
12
+ sillstone_version_major_raw,
13
+ sillstone_version_minor_raw,
14
+ sillstone_version_patch_raw,
15
+ sillstone_buffer_checksum_raw,
16
+ sillstone_digest_sha256_raw,
17
+ sillstone_digest_sha3_256_raw,
18
+ sillstone_digest_sha3_512_raw,
19
+ sillstone_digest_blake2b_512_raw,
20
+ sillstone_digest_blake3_raw,
21
+ sillstone_math_dst1_raw,
22
+ sillstone_math_dst2_raw,
23
+ sillstone_math_dst3_raw,
24
+ sillstone_unicode_grapheme_count_raw,
25
+ sillstone_unicode_char_category_raw,
26
+ sillstone_image_phash_raw,
27
+ sillstone_image_ahash_raw,
28
+ sillstone_image_dhash_raw,
29
+ sillstone_image_whash_raw,
30
+ sillstone_image_colorhash_raw,
31
+ sillstone_text_tlsh_raw,
32
+ sillstone_text_tlsh_distance_raw,
33
+ sillstone_curator_detect_raw,
34
+ sillstone_curator_content_hash_raw,
35
+ sillstone_curator_signature_raw,
36
+ sillstone_curator_describe_raw,
37
+ sillstone_curator_match_raw,
38
+ sillstone_curator_free_raw,
39
+ )
40
+
41
+ __version__ = "0.2.0b1"
42
+
43
+ __all__ = [
44
+ "version",
45
+ "buffer_checksum",
46
+ "sha256",
47
+ "sha3_256",
48
+ "sha3_512",
49
+ "blake2b_512",
50
+ "blake3",
51
+ "dst1",
52
+ "dst2",
53
+ "dst3",
54
+ "grapheme_count",
55
+ "char_category",
56
+ "phash",
57
+ "ahash",
58
+ "dhash",
59
+ "whash",
60
+ "colorhash",
61
+ "tlsh",
62
+ "tlsh_distance",
63
+ "detect",
64
+ "content_hash",
65
+ "signature",
66
+ "describe",
67
+ "match_signatures",
68
+ "parse_signature",
69
+ "parse_describe",
70
+ "fnv1a64",
71
+ "Detection",
72
+ "Signature",
73
+ "Description",
74
+ "MatchResult",
75
+ "FfiError",
76
+ "FORMATS",
77
+ "MODALITIES",
78
+ "MATCH_TAGS",
79
+ "STATUS_OK",
80
+ "STATUS_INVALID",
81
+ "STATUS_REJECTED",
82
+ ]
83
+
84
+ #: Status codes
85
+ STATUS_OK = 0
86
+ STATUS_INVALID = -1
87
+ STATUS_REJECTED = -2
88
+
89
+ #: Format names by wire code (declaration order)
90
+ FORMATS = ("png", "jpeg", "bmp", "zip", "mp4", "mp3", "wav", "flac", "pdf", "gif", "unknown")
91
+
92
+ #: Modality names by wire code (declaration order)
93
+ MODALITIES = ("image", "audio", "text", "binary", "video")
94
+
95
+ #: Match-outcome tags by wire code (declaration order)
96
+ MATCH_TAGS = ("image", "audio", "text", "binary", "video")
97
+
98
+ #: Signature-stream tag bytes (declaration order)
99
+ SIGNATURE_TAGS = ("image", "audio", "text", "binary", "video")
100
+
101
+
102
+ class FfiError(Exception):
103
+ """A non-zero status code came back from the cdylib."""
104
+
105
+ def __init__(self, op: str, status: int) -> None:
106
+ kind = {
107
+ STATUS_INVALID: "invalid argument",
108
+ STATUS_REJECTED: "input rejected",
109
+ }.get(status, "unknown failure")
110
+ super().__init__(f"{op} failed: {kind} (status {status})")
111
+ self.status = status
112
+
113
+
114
+ @dataclass(frozen=True)
115
+ class Detection:
116
+ """Container sniffing result."""
117
+ format: str
118
+ modality: str
119
+ pending: bool
120
+
121
+
122
+ @dataclass(frozen=True)
123
+ class Signature:
124
+ """A tier-2 signature, re-expressed from the signature stream."""
125
+ modality: str
126
+ phash: int | None = None
127
+ peak_count: int | None = None
128
+ frames: int | None = None
129
+ peaks: tuple[tuple[int, int], ...] | None = None
130
+ peaks_bytes: bytes | None = None
131
+ word_count: int | None = None
132
+ words: tuple[int, ...] | None = None
133
+ chunk_count: int | None = None
134
+ digest_bytes: bytes | None = None
135
+ frame_count: int | None = None
136
+ width: int | None = None
137
+ height: int | None = None
138
+ duration_bits: int | None = None
139
+ frame_hashes: tuple[int, ...] | None = None
140
+ minhash: tuple[int, ...] | None = None
141
+
142
+
143
+ @dataclass(frozen=True)
144
+ class Description:
145
+ """Both tiers plus facts, re-expressed from the describe stream."""
146
+ format: str
147
+ modality: str
148
+ tier1: str
149
+ signature: Signature
150
+ facts: dict
151
+
152
+
153
+ @dataclass(frozen=True)
154
+ class MatchResult:
155
+ """A match outcome, re-expressed from the slots."""
156
+ tag: str
157
+ slots: tuple[int, ...]
158
+ matched: bool
159
+
160
+ def slot_float(self, index: int) -> float:
161
+ """Reinterprets slot `index` as an IEEE-754 double."""
162
+ return struct.unpack("<d", struct.pack("<Q", self.slots[index]))[0]
163
+
164
+
165
+ def version() -> str:
166
+ """Returns library version string."""
167
+ return f"{sillstone_version_major_raw()}.{sillstone_version_minor_raw()}.{sillstone_version_patch_raw()}"
168
+
169
+
170
+ def buffer_checksum(data: bytes) -> int:
171
+ """Computes standard 64-bit FNV-1a checksum over input bytes."""
172
+ return int(sillstone_buffer_checksum_raw(data, len(data)))
173
+
174
+
175
+ def sha256(data: bytes) -> bytes:
176
+ """Computes 32-byte SHA-256 digest."""
177
+ out = ctypes.create_string_buffer(32)
178
+ rc = sillstone_digest_sha256_raw(data, len(data), out)
179
+ if rc != 0:
180
+ raise FfiError("sha256", rc)
181
+ return out.raw
182
+
183
+
184
+ def sha3_256(data: bytes) -> bytes:
185
+ """Computes 32-byte SHA-3-256 digest."""
186
+ out = ctypes.create_string_buffer(32)
187
+ rc = sillstone_digest_sha3_256_raw(data, len(data), out)
188
+ if rc != 0:
189
+ raise FfiError("sha3_256", rc)
190
+ return out.raw
191
+
192
+
193
+ def sha3_512(data: bytes) -> bytes:
194
+ """Computes 64-byte SHA-3-512 digest."""
195
+ out = ctypes.create_string_buffer(64)
196
+ rc = sillstone_digest_sha3_512_raw(data, len(data), out)
197
+ if rc != 0:
198
+ raise FfiError("sha3_512", rc)
199
+ return out.raw
200
+
201
+
202
+ def blake2b_512(data: bytes) -> bytes:
203
+ """Computes 64-byte unkeyed BLAKE2b digest."""
204
+ out = ctypes.create_string_buffer(64)
205
+ rc = sillstone_digest_blake2b_512_raw(data, len(data), out)
206
+ if rc != 0:
207
+ raise FfiError("blake2b_512", rc)
208
+ return out.raw
209
+
210
+
211
+ def blake3(data: bytes) -> bytes:
212
+ """Computes 32-byte BLAKE3 digest."""
213
+ out = ctypes.create_string_buffer(32)
214
+ rc = sillstone_digest_blake3_raw(data, len(data), out)
215
+ if rc != 0:
216
+ raise FfiError("blake3", rc)
217
+ return out.raw
218
+
219
+
220
+ def dst1(data: list[float]) -> list[float]:
221
+ """Computes orthonormal DST-I over input float array."""
222
+ c_in = (ctypes.c_double * len(data))(*data)
223
+ c_out = (ctypes.c_double * len(data))()
224
+ rc = sillstone_math_dst1_raw(c_in, len(data), c_out)
225
+ if rc != 0:
226
+ raise FfiError("dst1", rc)
227
+ return list(c_out)
228
+
229
+
230
+ def dst2(data: list[float]) -> list[float]:
231
+ """Computes orthonormal DST-II over input float array."""
232
+ c_in = (ctypes.c_double * len(data))(*data)
233
+ c_out = (ctypes.c_double * len(data))()
234
+ rc = sillstone_math_dst2_raw(c_in, len(data), c_out)
235
+ if rc != 0:
236
+ raise FfiError("dst2", rc)
237
+ return list(c_out)
238
+
239
+
240
+ def dst3(data: list[float]) -> list[float]:
241
+ """Computes orthonormal DST-III over input float array."""
242
+ c_in = (ctypes.c_double * len(data))(*data)
243
+ c_out = (ctypes.c_double * len(data))()
244
+ rc = sillstone_math_dst3_raw(c_in, len(data), c_out)
245
+ if rc != 0:
246
+ raise FfiError("dst3", rc)
247
+ return list(c_out)
248
+
249
+
250
+ def grapheme_count(text: str) -> int:
251
+ """Counts UAX #29 grapheme clusters in a string."""
252
+ raw = text.encode("utf-8")
253
+ count = ctypes.c_size_t()
254
+ rc = sillstone_unicode_grapheme_count_raw(raw, len(raw), ctypes.byref(count))
255
+ if rc != 0:
256
+ raise FfiError("grapheme_count", rc)
257
+ return count.value
258
+
259
+
260
+ def char_category(char: str) -> int:
261
+ """Returns general category tag for a single character."""
262
+ cp = ord(char[0])
263
+ cat = ctypes.c_uint8()
264
+ rc = sillstone_unicode_char_category_raw(cp, ctypes.byref(cat))
265
+ if rc != 0:
266
+ raise FfiError("char_category", rc)
267
+ return cat.value
268
+
269
+
270
+ def phash(data: bytes, width: int, height: int, layout: int = 0) -> int:
271
+ """Computes 64-bit perceptual hash (pHash) of an image."""
272
+ out = ctypes.c_uint64()
273
+ rc = sillstone_image_phash_raw(data, len(data), width, height, layout, ctypes.byref(out))
274
+ if rc != 0:
275
+ raise FfiError("phash", rc)
276
+ return out.value
277
+
278
+
279
+ def ahash(data: bytes, width: int, height: int, layout: int = 0) -> int:
280
+ """Computes 64-bit average hash (aHash) of an image."""
281
+ out = ctypes.c_uint64()
282
+ rc = sillstone_image_ahash_raw(data, len(data), width, height, layout, ctypes.byref(out))
283
+ if rc != 0:
284
+ raise FfiError("ahash", rc)
285
+ return out.value
286
+
287
+
288
+ def dhash(data: bytes, width: int, height: int, layout: int = 0) -> int:
289
+ """Computes 64-bit difference hash (dHash) of an image."""
290
+ out = ctypes.c_uint64()
291
+ rc = sillstone_image_dhash_raw(data, len(data), width, height, layout, ctypes.byref(out))
292
+ if rc != 0:
293
+ raise FfiError("dhash", rc)
294
+ return out.value
295
+
296
+
297
+ def whash(data: bytes, width: int, height: int, layout: int = 0) -> int:
298
+ """Computes 64-bit wavelet hash (wHash) of an image."""
299
+ out = ctypes.c_uint64()
300
+ rc = sillstone_image_whash_raw(data, len(data), width, height, layout, ctypes.byref(out))
301
+ if rc != 0:
302
+ raise FfiError("whash", rc)
303
+ return out.value
304
+
305
+
306
+ def colorhash(data: bytes, width: int, height: int, layout: int = 0) -> int:
307
+ """Computes 64-bit color distribution hash of an image."""
308
+ out = ctypes.c_uint64()
309
+ rc = sillstone_image_colorhash_raw(data, len(data), width, height, layout, ctypes.byref(out))
310
+ if rc != 0:
311
+ raise FfiError("colorhash", rc)
312
+ return out.value
313
+
314
+
315
+ def tlsh(data: bytes) -> str:
316
+ """Computes 70-hex-char TrendMicro Locality Sensitive Hash string."""
317
+ out = ctypes.create_string_buffer(72)
318
+ rc = sillstone_text_tlsh_raw(data, len(data), out)
319
+ if rc != 0:
320
+ raise FfiError("tlsh", rc)
321
+ return out.raw.decode("ascii", errors="replace")
322
+
323
+
324
+ def tlsh_distance(hash_a: str | bytes, hash_b: str | bytes) -> int:
325
+ """Computes TLSH distance between two 70-hex-char hashes."""
326
+ a_bytes = hash_a.encode("ascii") if isinstance(hash_a, str) else hash_a
327
+ b_bytes = hash_b.encode("ascii") if isinstance(hash_b, str) else hash_b
328
+ out = ctypes.c_uint32()
329
+ rc = sillstone_text_tlsh_distance_raw(a_bytes, b_bytes, ctypes.byref(out))
330
+ if rc != 0:
331
+ raise FfiError("tlsh_distance", rc)
332
+ return out.value
333
+
334
+
335
+ def fnv1a64(data: bytes) -> int:
336
+ """The 64-bit FNV-1a fold the reference sub-digests use."""
337
+ h = 0xCBF29CE484222325
338
+ for b in data:
339
+ h ^= b
340
+ h = (h * 0x100000001B3) & 0xFFFFFFFFFFFFFFFF
341
+ return h
342
+
343
+
344
+ def detect(data: bytes) -> Detection:
345
+ """Sniffs container and modality without full decode."""
346
+ fmt = ctypes.c_uint32()
347
+ mod = ctypes.c_uint32()
348
+ pending = ctypes.c_uint32()
349
+ rc = sillstone_curator_detect_raw(
350
+ data, len(data), ctypes.byref(fmt), ctypes.byref(mod), ctypes.byref(pending)
351
+ )
352
+ if rc != 0:
353
+ raise FfiError("curator_detect", rc)
354
+ return Detection(
355
+ format=FORMATS[fmt.value],
356
+ modality=MODALITIES[mod.value],
357
+ pending=pending.value == 1,
358
+ )
359
+
360
+
361
+ def content_hash(data: bytes) -> bytes:
362
+ """Computes 32-byte tier-1 content digest."""
363
+ buf = (ctypes.c_ubyte * 32)()
364
+ out_len = ctypes.c_size_t()
365
+ rc = sillstone_curator_content_hash_raw(data, len(data), buf, len(buf), ctypes.byref(out_len))
366
+ if rc != 0:
367
+ raise FfiError("curator_content_hash", rc)
368
+ return bytes(buf)
369
+
370
+
371
+ def _stream_op(raw_fn, data: bytes) -> bytes:
372
+ out = ctypes.c_void_p()
373
+ out_len = ctypes.c_size_t()
374
+ rc = raw_fn(data, len(data), ctypes.byref(out), ctypes.byref(out_len))
375
+ if rc != 0:
376
+ raise FfiError(raw_fn.__name__, rc)
377
+ try:
378
+ return ctypes.string_at(out, out_len.value)
379
+ finally:
380
+ sillstone_curator_free_raw(out, out_len.value)
381
+
382
+
383
+ def signature(data: bytes) -> Signature:
384
+ """Computes tier-2 signature stream and parses it into a Signature object."""
385
+ return parse_signature(_stream_op(sillstone_curator_signature_raw, data))
386
+
387
+
388
+ def describe(data: bytes) -> Description:
389
+ """Computes both tiers and parses the describe stream."""
390
+ return parse_describe(_stream_op(sillstone_curator_describe_raw, data))
391
+
392
+
393
+ def match_signatures(a: bytes, b: bytes) -> MatchResult:
394
+ """Scores two raw inputs across modalities."""
395
+ tag = ctypes.c_uint32()
396
+ slots = (ctypes.c_uint64 * 4)()
397
+ matched = ctypes.c_uint32()
398
+ rc = sillstone_curator_match_raw(
399
+ a, len(a), b, len(b), ctypes.byref(tag), slots, len(slots), ctypes.byref(matched)
400
+ )
401
+ if rc != 0:
402
+ raise FfiError("curator_match", rc)
403
+ return MatchResult(
404
+ tag=MATCH_TAGS[tag.value],
405
+ slots=tuple(int(s) for s in slots),
406
+ matched=matched.value == 1,
407
+ )
408
+
409
+ def parse_signature(raw: bytes) -> Signature:
410
+ """Re-expresses the canonical signature stream as a Signature."""
411
+ if len(raw) < 1:
412
+ raise ValueError("signature stream is empty")
413
+ tag = raw[0]
414
+ if tag >= len(SIGNATURE_TAGS):
415
+ raise ValueError(f"unknown signature tag {tag}")
416
+ modality = SIGNATURE_TAGS[tag]
417
+ if modality == "image":
418
+ if len(raw) != 9:
419
+ raise ValueError("image stream is not tag + u64")
420
+ return Signature(modality=modality, phash=int.from_bytes(raw[1:9], "big"))
421
+ if modality == "audio":
422
+ if len(raw) < 13:
423
+ raise ValueError("audio stream is shorter than its 13-byte header")
424
+ peak_count = int.from_bytes(raw[1:9], "big")
425
+ frames = int.from_bytes(raw[9:13], "big")
426
+ payload = raw[13:]
427
+ if peak_count != len(payload) or len(payload) % 6 != 0:
428
+ raise ValueError("audio peak count disagrees with the payload")
429
+ peaks = tuple(
430
+ (
431
+ int.from_bytes(payload[i : i + 4], "little"),
432
+ int.from_bytes(payload[i + 4 : i + 6], "little"),
433
+ )
434
+ for i in range(0, len(payload), 6)
435
+ )
436
+ return Signature(
437
+ modality=modality,
438
+ peak_count=peak_count,
439
+ frames=frames,
440
+ peaks=peaks,
441
+ peaks_bytes=payload,
442
+ )
443
+ if modality == "text":
444
+ if len(raw) < 9:
445
+ raise ValueError("text stream is shorter than its 9-byte header")
446
+ word_count = int.from_bytes(raw[1:9], "big")
447
+ payload = raw[9:]
448
+ if word_count != len(payload) or len(payload) % 8 != 0:
449
+ raise ValueError("text word count disagrees with the payload")
450
+ words = tuple(int.from_bytes(payload[i : i + 8], "big") for i in range(0, len(payload), 8))
451
+ return Signature(modality=modality, word_count=word_count, words=words)
452
+ if modality == "binary":
453
+ if len(raw) < 9:
454
+ raise ValueError("binary stream is shorter than its 9-byte header")
455
+ chunk_count = int.from_bytes(raw[1:9], "big")
456
+ payload = raw[9:]
457
+ if chunk_count != len(payload) or len(payload) % 32 != 0:
458
+ raise ValueError("binary chunk count disagrees with the payload")
459
+ return Signature(modality=modality, chunk_count=chunk_count, digest_bytes=payload)
460
+ # video
461
+ if len(raw) < 18:
462
+ raise ValueError("video stream is shorter than its 18-byte header")
463
+ frame_count = int.from_bytes(raw[1:5], "big")
464
+ width = int.from_bytes(raw[5:9], "big")
465
+ height = int.from_bytes(raw[9:13], "big")
466
+ duration_bits = int.from_bytes(raw[13:21], "big")
467
+ rest = raw[21:]
468
+ if frame_count > len(rest) or frame_count % 8 != 0:
469
+ raise ValueError("video frame count disagrees with the payload")
470
+ frames_payload = rest[:frame_count]
471
+ minhash_payload = rest[frame_count:]
472
+ if len(minhash_payload) % 8 != 0:
473
+ raise ValueError("video minhash payload is not whole words")
474
+ return Signature(
475
+ modality=modality,
476
+ frame_count=frame_count,
477
+ width=width,
478
+ height=height,
479
+ duration_bits=duration_bits,
480
+ frame_hashes=tuple(
481
+ int.from_bytes(frames_payload[i : i + 8], "little")
482
+ for i in range(0, len(frames_payload), 8)
483
+ ),
484
+ minhash=tuple(
485
+ int.from_bytes(minhash_payload[i : i + 8], "little")
486
+ for i in range(0, len(minhash_payload), 8)
487
+ ),
488
+ )
489
+
490
+
491
+ def parse_describe(raw: bytes) -> Description:
492
+ """Re-expresses the canonical describe stream as a Description."""
493
+ if len(raw) < 35:
494
+ raise ValueError("describe stream is shorter than its 35-byte header")
495
+ fmt = raw[0]
496
+ mod = raw[1]
497
+ if fmt >= len(FORMATS) or mod >= len(MODALITIES):
498
+ raise ValueError(f"unknown describe codes {fmt}/{mod}")
499
+ tier1 = raw[2:34].hex()
500
+ modality = MODALITIES[mod]
501
+ sig_end = len(raw) - _facts_len(modality)
502
+ sig = parse_signature(raw[34:sig_end])
503
+ facts_raw = raw[sig_end:]
504
+ facts: dict = {}
505
+ if modality == "image":
506
+ _need(facts_raw, 16)
507
+ facts = {"width": _be32(facts_raw, 0), "height": _be32(facts_raw, 4), "keypoints": _be64(facts_raw, 8)}
508
+ elif modality == "audio":
509
+ _need(facts_raw, 18)
510
+ facts = {
511
+ "sample_rate": _be32(facts_raw, 0),
512
+ "channels": int.from_bytes(facts_raw[4:6], "big"),
513
+ "frames": _be32(facts_raw, 6),
514
+ "peaks": _be64(facts_raw, 10),
515
+ }
516
+ elif modality == "text":
517
+ _need(facts_raw, 16)
518
+ facts = {"words": _be64(facts_raw, 0), "canonical_len": _be64(facts_raw, 8)}
519
+ elif modality == "binary":
520
+ _need(facts_raw, 16)
521
+ facts = {"len": _be64(facts_raw, 0), "chunks": _be64(facts_raw, 8)}
522
+ else:
523
+ _need(facts_raw, 24)
524
+ facts = {
525
+ "width": _be32(facts_raw, 0),
526
+ "height": _be32(facts_raw, 4),
527
+ "duration_bits": _be64(facts_raw, 8),
528
+ "frames_sampled": _be64(facts_raw, 16),
529
+ }
530
+ return Description(format=FORMATS[fmt], modality=modality, tier1=tier1, signature=sig, facts=facts)
531
+
532
+
533
+ def _be32(raw: bytes, off: int) -> int:
534
+ return int.from_bytes(raw[off : off + 4], "big")
535
+
536
+
537
+ def _be64(raw: bytes, off: int) -> int:
538
+ return int.from_bytes(raw[off : off + 8], "big")
539
+
540
+
541
+ def _need(raw: bytes, n: int) -> None:
542
+ if len(raw) != n:
543
+ raise ValueError(f"facts block is {len(raw)} bytes, want {n}")
544
+
545
+
546
+ def _facts_len(modality: str) -> int:
547
+ if modality == "audio":
548
+ return 18
549
+ if modality == "video":
550
+ return 24
551
+ return 16
@@ -0,0 +1,238 @@
1
+ # Generated by sillstone-idl-gen. DO NOT EDIT.
2
+ import ctypes
3
+ import os
4
+ import sys
5
+
6
+ def _load_lib():
7
+ ext = '.dll' if sys.platform == 'win32' else ('.dylib' if sys.platform == 'darwin' else '.so')
8
+ prefix = '' if sys.platform == 'win32' else 'lib'
9
+ lib_name = f'{prefix}sillstone_ffi{ext}'
10
+ dir_path = os.path.dirname(os.path.abspath(__file__))
11
+ candidates = [
12
+ os.path.join(dir_path, lib_name),
13
+ os.path.join(dir_path, '..', '..', '..', 'target', 'release', lib_name),
14
+ os.path.join(dir_path, '..', '..', '..', 'target', 'debug', lib_name),
15
+ ]
16
+ for c in candidates:
17
+ if os.path.exists(c):
18
+ return ctypes.CDLL(c)
19
+ return None
20
+
21
+ LIB = _load_lib()
22
+
23
+ def sillstone_version_major_raw(*args):
24
+ if LIB is None:
25
+ raise RuntimeError('sillstone_ffi library not loaded')
26
+ fn = getattr(LIB, 'sillstone_version_major')
27
+ fn.restype = ctypes.c_uint32
28
+ fn.argtypes = []
29
+ return fn(*args)
30
+
31
+ def sillstone_version_minor_raw(*args):
32
+ if LIB is None:
33
+ raise RuntimeError('sillstone_ffi library not loaded')
34
+ fn = getattr(LIB, 'sillstone_version_minor')
35
+ fn.restype = ctypes.c_uint32
36
+ fn.argtypes = []
37
+ return fn(*args)
38
+
39
+ def sillstone_version_patch_raw(*args):
40
+ if LIB is None:
41
+ raise RuntimeError('sillstone_ffi library not loaded')
42
+ fn = getattr(LIB, 'sillstone_version_patch')
43
+ fn.restype = ctypes.c_uint32
44
+ fn.argtypes = []
45
+ return fn(*args)
46
+
47
+ def sillstone_buffer_checksum_raw(*args):
48
+ if LIB is None:
49
+ raise RuntimeError('sillstone_ffi library not loaded')
50
+ fn = getattr(LIB, 'sillstone_buffer_checksum')
51
+ fn.restype = ctypes.c_uint64
52
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t]
53
+ return fn(*args)
54
+
55
+ def sillstone_digest_sha256_raw(*args):
56
+ if LIB is None:
57
+ raise RuntimeError('sillstone_ffi library not loaded')
58
+ fn = getattr(LIB, 'sillstone_digest_sha256')
59
+ fn.restype = ctypes.c_int32
60
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
61
+ return fn(*args)
62
+
63
+ def sillstone_digest_sha3_256_raw(*args):
64
+ if LIB is None:
65
+ raise RuntimeError('sillstone_ffi library not loaded')
66
+ fn = getattr(LIB, 'sillstone_digest_sha3_256')
67
+ fn.restype = ctypes.c_int32
68
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
69
+ return fn(*args)
70
+
71
+ def sillstone_digest_sha3_512_raw(*args):
72
+ if LIB is None:
73
+ raise RuntimeError('sillstone_ffi library not loaded')
74
+ fn = getattr(LIB, 'sillstone_digest_sha3_512')
75
+ fn.restype = ctypes.c_int32
76
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
77
+ return fn(*args)
78
+
79
+ def sillstone_digest_blake2b_512_raw(*args):
80
+ if LIB is None:
81
+ raise RuntimeError('sillstone_ffi library not loaded')
82
+ fn = getattr(LIB, 'sillstone_digest_blake2b_512')
83
+ fn.restype = ctypes.c_int32
84
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
85
+ return fn(*args)
86
+
87
+ def sillstone_digest_blake3_raw(*args):
88
+ if LIB is None:
89
+ raise RuntimeError('sillstone_ffi library not loaded')
90
+ fn = getattr(LIB, 'sillstone_digest_blake3')
91
+ fn.restype = ctypes.c_int32
92
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
93
+ return fn(*args)
94
+
95
+ def sillstone_math_dst1_raw(*args):
96
+ if LIB is None:
97
+ raise RuntimeError('sillstone_ffi library not loaded')
98
+ fn = getattr(LIB, 'sillstone_math_dst1')
99
+ fn.restype = ctypes.c_int32
100
+ fn.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_size_t, ctypes.POINTER(ctypes.c_double)]
101
+ return fn(*args)
102
+
103
+ def sillstone_math_dst2_raw(*args):
104
+ if LIB is None:
105
+ raise RuntimeError('sillstone_ffi library not loaded')
106
+ fn = getattr(LIB, 'sillstone_math_dst2')
107
+ fn.restype = ctypes.c_int32
108
+ fn.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_size_t, ctypes.POINTER(ctypes.c_double)]
109
+ return fn(*args)
110
+
111
+ def sillstone_math_dst3_raw(*args):
112
+ if LIB is None:
113
+ raise RuntimeError('sillstone_ffi library not loaded')
114
+ fn = getattr(LIB, 'sillstone_math_dst3')
115
+ fn.restype = ctypes.c_int32
116
+ fn.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_size_t, ctypes.POINTER(ctypes.c_double)]
117
+ return fn(*args)
118
+
119
+ def sillstone_unicode_grapheme_count_raw(*args):
120
+ if LIB is None:
121
+ raise RuntimeError('sillstone_ffi library not loaded')
122
+ fn = getattr(LIB, 'sillstone_unicode_grapheme_count')
123
+ fn.restype = ctypes.c_int32
124
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)]
125
+ return fn(*args)
126
+
127
+ def sillstone_unicode_char_category_raw(*args):
128
+ if LIB is None:
129
+ raise RuntimeError('sillstone_ffi library not loaded')
130
+ fn = getattr(LIB, 'sillstone_unicode_char_category')
131
+ fn.restype = ctypes.c_int32
132
+ fn.argtypes = [ctypes.c_uint32, ctypes.c_void_p]
133
+ return fn(*args)
134
+
135
+ def sillstone_curator_detect_raw(*args):
136
+ if LIB is None:
137
+ raise RuntimeError('sillstone_ffi library not loaded')
138
+ fn = getattr(LIB, 'sillstone_curator_detect')
139
+ fn.restype = ctypes.c_int32
140
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)]
141
+ return fn(*args)
142
+
143
+ def sillstone_curator_content_hash_raw(*args):
144
+ if LIB is None:
145
+ raise RuntimeError('sillstone_ffi library not loaded')
146
+ fn = getattr(LIB, 'sillstone_curator_content_hash')
147
+ fn.restype = ctypes.c_int32
148
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)]
149
+ return fn(*args)
150
+
151
+ def sillstone_curator_signature_raw(*args):
152
+ if LIB is None:
153
+ raise RuntimeError('sillstone_ffi library not loaded')
154
+ fn = getattr(LIB, 'sillstone_curator_signature')
155
+ fn.restype = ctypes.c_int32
156
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_size_t)]
157
+ return fn(*args)
158
+
159
+ def sillstone_curator_describe_raw(*args):
160
+ if LIB is None:
161
+ raise RuntimeError('sillstone_ffi library not loaded')
162
+ fn = getattr(LIB, 'sillstone_curator_describe')
163
+ fn.restype = ctypes.c_int32
164
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_size_t)]
165
+ return fn(*args)
166
+
167
+ def sillstone_curator_match_raw(*args):
168
+ if LIB is None:
169
+ raise RuntimeError('sillstone_ffi library not loaded')
170
+ fn = getattr(LIB, 'sillstone_curator_match')
171
+ fn.restype = ctypes.c_int32
172
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_size_t, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint64), ctypes.c_size_t, ctypes.POINTER(ctypes.c_uint32)]
173
+ return fn(*args)
174
+
175
+ def sillstone_curator_free_raw(*args):
176
+ if LIB is None:
177
+ raise RuntimeError('sillstone_ffi library not loaded')
178
+ fn = getattr(LIB, 'sillstone_curator_free')
179
+ fn.restype = None
180
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t]
181
+ return fn(*args)
182
+
183
+ def sillstone_image_phash_raw(*args):
184
+ if LIB is None:
185
+ raise RuntimeError('sillstone_ffi library not loaded')
186
+ fn = getattr(LIB, 'sillstone_image_phash')
187
+ fn.restype = ctypes.c_int32
188
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint64)]
189
+ return fn(*args)
190
+
191
+ def sillstone_image_ahash_raw(*args):
192
+ if LIB is None:
193
+ raise RuntimeError('sillstone_ffi library not loaded')
194
+ fn = getattr(LIB, 'sillstone_image_ahash')
195
+ fn.restype = ctypes.c_int32
196
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint64)]
197
+ return fn(*args)
198
+
199
+ def sillstone_image_dhash_raw(*args):
200
+ if LIB is None:
201
+ raise RuntimeError('sillstone_ffi library not loaded')
202
+ fn = getattr(LIB, 'sillstone_image_dhash')
203
+ fn.restype = ctypes.c_int32
204
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint64)]
205
+ return fn(*args)
206
+
207
+ def sillstone_image_whash_raw(*args):
208
+ if LIB is None:
209
+ raise RuntimeError('sillstone_ffi library not loaded')
210
+ fn = getattr(LIB, 'sillstone_image_whash')
211
+ fn.restype = ctypes.c_int32
212
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint64)]
213
+ return fn(*args)
214
+
215
+ def sillstone_image_colorhash_raw(*args):
216
+ if LIB is None:
217
+ raise RuntimeError('sillstone_ffi library not loaded')
218
+ fn = getattr(LIB, 'sillstone_image_colorhash')
219
+ fn.restype = ctypes.c_int32
220
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.POINTER(ctypes.c_uint64)]
221
+ return fn(*args)
222
+
223
+ def sillstone_text_tlsh_raw(*args):
224
+ if LIB is None:
225
+ raise RuntimeError('sillstone_ffi library not loaded')
226
+ fn = getattr(LIB, 'sillstone_text_tlsh')
227
+ fn.restype = ctypes.c_int32
228
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
229
+ return fn(*args)
230
+
231
+ def sillstone_text_tlsh_distance_raw(*args):
232
+ if LIB is None:
233
+ raise RuntimeError('sillstone_ffi library not loaded')
234
+ fn = getattr(LIB, 'sillstone_text_tlsh_distance')
235
+ fn.restype = ctypes.c_int32
236
+ fn.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint32)]
237
+ return fn(*args)
238
+
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: sillstone
3
+ Version: 0.2.0b1
4
+ Summary: Pure-Rust zero-dependency multimedia, hashing, and array computing suite
5
+ Author: Sillstone Contributors
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/sillstone/sillstone
8
+ Project-URL: Repository, https://github.com/sillstone/sillstone
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.9
13
+ Description-Content-Type: text/markdown
@@ -0,0 +1,6 @@
1
+ sillstone/__init__.py,sha256=7R5WusbC1YvlT5w5balSircs6sYC3dAp8Se3l0nby4s,17881
2
+ sillstone/_generated.py,sha256=Yye6k-Z1f7fxOx4I2fWwn-PcQoNcPnFKUGdlev1eqZI,9406
3
+ sillstone-0.2.0b1.dist-info/METADATA,sha256=5fuGC3dGUAFnk0CFMBGALJq5Dy2TMyXuCmh2TJOrERw,535
4
+ sillstone-0.2.0b1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
5
+ sillstone-0.2.0b1.dist-info/top_level.txt,sha256=gU-OK-Ivn1TF9HzJTn8UAmC2-gZ3anvkUA2dOTMTDMg,10
6
+ sillstone-0.2.0b1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ sillstone