from PIL import Image, UnidentifiedImageError import io # Common AI metadata identifiers in image files. AI_INDICATORS = [ b'c2pa', b'claim_generator', b'claim_generator_info', b'created_software_agent', b'actions.v2', b'assertions', b'urn:c2pa', b'jumd', b'jumb', b'jumdcbor', b'jumdc2ma', b'jumdc2as', b'jumdc2cl', b'cbor', b'convertedsfwareagent',b'c2pa.version', b'c2pa.assertions', b'c2pa.actions', b'c2pa.thumbnail', b'c2pa.signature', b'c2pa.manifest', b'c2pa.manifest_store', b'c2pa.ingredient', b'c2pa.parent', b'c2pa.provenance', b'c2pa.claim', b'c2pa.hash', b'c2pa.authority', b'jumdc2pn', b'jumdrefs', b'jumdver', b'jumdmeta', 'midjourney'.encode('utf-8'), 'stable-diffusion'.encode('utf-8'), 'stable diffusion'.encode('utf-8'), 'stable_diffusion'.encode('utf-8'), 'artbreeder'.encode('utf-8'), 'runwayml'.encode('utf-8'), 'remix.ai'.encode('utf-8'), 'firefly'.encode('utf-8'), 'adobe_firefly'.encode('utf-8'), # OpenAI / DALL·E indicators (all encoded to bytes) 'openai'.encode('utf-8'), 'dalle'.encode('utf-8'), 'dalle2'.encode('utf-8'), 'DALL-E'.encode('utf-8'), 'DALL·E'.encode('utf-8'), 'created_by: openai'.encode('utf-8'), 'tool: dalle'.encode('utf-8'), 'tool: dalle2'.encode('utf-8'), 'creator: openai'.encode('utf-8'), 'creator: dalle'.encode('utf-8'), 'openai.com'.encode('utf-8'), 'api.openai.com'.encode('utf-8'), 'openai_model'.encode('utf-8'), 'openai_gpt'.encode('utf-8'), #Further possible AI-Generation Indicators 'generated_by'.encode('utf-8'), 'model_id'.encode('utf-8'), 'model_version'.encode('utf-8'), 'model_info'.encode('utf-8'), 'tool_name'.encode('utf-8'), 'tool_creator'.encode('utf-8'), 'tool_version'.encode('utf-8'), 'model_signature'.encode('utf-8'), 'ai_model'.encode('utf-8'), 'ai_tool'.encode('utf-8'), 'generator'.encode('utf-8'), 'generated_by_ai'.encode('utf-8'), 'ai_generated'.encode('utf-8'), 'ai_art'.encode('utf-8') ] def run_metadata(image_bytes: bytes) -> str: try: img = Image.open(io.BytesIO(image_bytes)) img.load() exif = img.getexif() software = str(exif.get(305, "")).strip() suspicious_editors = ["Photoshop", "GIMP", "Snapseed", "Pixlr", "VSCO", "Editor", "Adobe", "Luminar"] if any(editor.lower() in software.lower() for editor in suspicious_editors): return "edited" if any(indicator in image_bytes for indicator in AI_INDICATORS): return "ai_generated" return "undetermined" except UnidentifiedImageError: return "error: invalid image format" except Exception as e: return f"error: {str(e)}"