mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-16 10:50:19 +02:00
fix(identify): attribute C2PA by claim_generator, not incidental issuer tokens (v0.6.1)
Verified on real signed files that the issuer byte-scan mis-attributes multi-entity manifests: Leica read as "Truepic" (timestamp authority in the chain), Nikon as "Adobe Firefly" (XMP-toolkit "Adobe" + the sample's "Adobe_MAX" name), Truepic as "Google". Platform attribution now prefers the claim generator (what produced the asset) and falls back to the issuer scan. - New _CLAIM_GENERATOR_PLATFORM map + _platform_from_generator; claim generator read for non-PNG via the now-public c2pa.cbor_text_after. - Device tokens listed only where verified against a real C2PA file (Leica lc_c2pa, Nikon, Truepic Lens); Pixel/Samsung/Sony/Canon/Bria deferred until a real sample confirms the in-manifest string. Camera C2PA marks capture authenticity, so these never set is_ai. - cbor_text_after made public (was _cbor_text_after); call sites + tests updated. - Regression test: claim_generator beats incidental Adobe/Google/Truepic tokens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
2676325184
commit
dda2ee7fbb
@@ -337,6 +337,25 @@ class TestIdentifyIptcAi:
|
||||
assert "Gemini" in r.platform
|
||||
|
||||
|
||||
class TestIdentifyC2paClaimGenerator:
|
||||
"""C2PA attribution prefers claim_generator over incidental issuer tokens."""
|
||||
|
||||
def test_claim_generator_beats_incidental_tokens(self, tmp_path: Path):
|
||||
# Real manifests mention timestamp authorities / XMP toolkits, so
|
||||
# "Adobe"/"Google"/"Truepic" appear incidentally; the claim generator
|
||||
# (a Leica camera) must win the platform attribution. Regression guard
|
||||
# for the real-sample mis-attribution (Leica->Truepic, Nikon->Adobe).
|
||||
gen = b"M11-P/2.0.1 lc_c2pa"
|
||||
blob = (
|
||||
b"\xff\xd8\xff\xe1 c2pa.claim jumbf Adobe Google Truepic "
|
||||
b"claim_generator" + bytes([0x60 + len(gen)]) + gen + b" \xff\xd9"
|
||||
)
|
||||
p = tmp_path / "leica_like.jpg"
|
||||
p.write_bytes(blob)
|
||||
r = identify(p, check_visible=False, check_invisible=False)
|
||||
assert r.platform == "Leica (camera, C2PA capture)"
|
||||
|
||||
|
||||
# ── Open invisible watermark (SD/SDXL/FLUX) integration ─────────────
|
||||
|
||||
from remove_ai_watermarks.invisible_watermark import is_available as _wm_available # noqa: E402
|
||||
|
||||
Reference in New Issue
Block a user