xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/email/mime/image.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker# Copyright (C) 2001-2006 Python Software Foundation
2*cda5da8dSAndroid Build Coastguard Worker# Author: Barry Warsaw
3*cda5da8dSAndroid Build Coastguard Worker# Contact: [email protected]
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard Worker"""Class representing image/* type MIME documents."""
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Worker__all__ = ['MIMEImage']
8*cda5da8dSAndroid Build Coastguard Worker
9*cda5da8dSAndroid Build Coastguard Workerfrom email import encoders
10*cda5da8dSAndroid Build Coastguard Workerfrom email.mime.nonmultipart import MIMENonMultipart
11*cda5da8dSAndroid Build Coastguard Worker
12*cda5da8dSAndroid Build Coastguard Worker
13*cda5da8dSAndroid Build Coastguard Workerclass MIMEImage(MIMENonMultipart):
14*cda5da8dSAndroid Build Coastguard Worker    """Class for generating image/* type MIME documents."""
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, _imagedata, _subtype=None,
17*cda5da8dSAndroid Build Coastguard Worker                 _encoder=encoders.encode_base64, *, policy=None, **_params):
18*cda5da8dSAndroid Build Coastguard Worker        """Create an image/* type MIME document.
19*cda5da8dSAndroid Build Coastguard Worker
20*cda5da8dSAndroid Build Coastguard Worker        _imagedata contains the bytes for the raw image data.  If the data
21*cda5da8dSAndroid Build Coastguard Worker        type can be detected (jpeg, png, gif, tiff, rgb, pbm, pgm, ppm,
22*cda5da8dSAndroid Build Coastguard Worker        rast, xbm, bmp, webp, and exr attempted), then the subtype will be
23*cda5da8dSAndroid Build Coastguard Worker        automatically included in the Content-Type header. Otherwise, you can
24*cda5da8dSAndroid Build Coastguard Worker        specify the specific image subtype via the _subtype parameter.
25*cda5da8dSAndroid Build Coastguard Worker
26*cda5da8dSAndroid Build Coastguard Worker        _encoder is a function which will perform the actual encoding for
27*cda5da8dSAndroid Build Coastguard Worker        transport of the image data.  It takes one argument, which is this
28*cda5da8dSAndroid Build Coastguard Worker        Image instance.  It should use get_payload() and set_payload() to
29*cda5da8dSAndroid Build Coastguard Worker        change the payload to the encoded form.  It should also add any
30*cda5da8dSAndroid Build Coastguard Worker        Content-Transfer-Encoding or other headers to the message as
31*cda5da8dSAndroid Build Coastguard Worker        necessary.  The default encoding is Base64.
32*cda5da8dSAndroid Build Coastguard Worker
33*cda5da8dSAndroid Build Coastguard Worker        Any additional keyword arguments are passed to the base class
34*cda5da8dSAndroid Build Coastguard Worker        constructor, which turns them into parameters on the Content-Type
35*cda5da8dSAndroid Build Coastguard Worker        header.
36*cda5da8dSAndroid Build Coastguard Worker        """
37*cda5da8dSAndroid Build Coastguard Worker        _subtype = _what(_imagedata) if _subtype is None else _subtype
38*cda5da8dSAndroid Build Coastguard Worker        if _subtype is None:
39*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('Could not guess image MIME subtype')
40*cda5da8dSAndroid Build Coastguard Worker        MIMENonMultipart.__init__(self, 'image', _subtype, policy=policy,
41*cda5da8dSAndroid Build Coastguard Worker                                  **_params)
42*cda5da8dSAndroid Build Coastguard Worker        self.set_payload(_imagedata)
43*cda5da8dSAndroid Build Coastguard Worker        _encoder(self)
44*cda5da8dSAndroid Build Coastguard Worker
45*cda5da8dSAndroid Build Coastguard Worker
46*cda5da8dSAndroid Build Coastguard Worker_rules = []
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard Worker
49*cda5da8dSAndroid Build Coastguard Worker# Originally from the imghdr module.
50*cda5da8dSAndroid Build Coastguard Workerdef _what(data):
51*cda5da8dSAndroid Build Coastguard Worker    for rule in _rules:
52*cda5da8dSAndroid Build Coastguard Worker        if res := rule(data):
53*cda5da8dSAndroid Build Coastguard Worker            return res
54*cda5da8dSAndroid Build Coastguard Worker    else:
55*cda5da8dSAndroid Build Coastguard Worker        return None
56*cda5da8dSAndroid Build Coastguard Worker
57*cda5da8dSAndroid Build Coastguard Worker
58*cda5da8dSAndroid Build Coastguard Workerdef rule(rulefunc):
59*cda5da8dSAndroid Build Coastguard Worker    _rules.append(rulefunc)
60*cda5da8dSAndroid Build Coastguard Worker    return rulefunc
61*cda5da8dSAndroid Build Coastguard Worker
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard Worker@rule
64*cda5da8dSAndroid Build Coastguard Workerdef _jpeg(h):
65*cda5da8dSAndroid Build Coastguard Worker    """JPEG data with JFIF or Exif markers; and raw JPEG"""
66*cda5da8dSAndroid Build Coastguard Worker    if h[6:10] in (b'JFIF', b'Exif'):
67*cda5da8dSAndroid Build Coastguard Worker        return 'jpeg'
68*cda5da8dSAndroid Build Coastguard Worker    elif h[:4] == b'\xff\xd8\xff\xdb':
69*cda5da8dSAndroid Build Coastguard Worker        return 'jpeg'
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Worker
72*cda5da8dSAndroid Build Coastguard Worker@rule
73*cda5da8dSAndroid Build Coastguard Workerdef _png(h):
74*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'\211PNG\r\n\032\n'):
75*cda5da8dSAndroid Build Coastguard Worker        return 'png'
76*cda5da8dSAndroid Build Coastguard Worker
77*cda5da8dSAndroid Build Coastguard Worker
78*cda5da8dSAndroid Build Coastguard Worker@rule
79*cda5da8dSAndroid Build Coastguard Workerdef _gif(h):
80*cda5da8dSAndroid Build Coastguard Worker    """GIF ('87 and '89 variants)"""
81*cda5da8dSAndroid Build Coastguard Worker    if h[:6] in (b'GIF87a', b'GIF89a'):
82*cda5da8dSAndroid Build Coastguard Worker        return 'gif'
83*cda5da8dSAndroid Build Coastguard Worker
84*cda5da8dSAndroid Build Coastguard Worker
85*cda5da8dSAndroid Build Coastguard Worker@rule
86*cda5da8dSAndroid Build Coastguard Workerdef _tiff(h):
87*cda5da8dSAndroid Build Coastguard Worker    """TIFF (can be in Motorola or Intel byte order)"""
88*cda5da8dSAndroid Build Coastguard Worker    if h[:2] in (b'MM', b'II'):
89*cda5da8dSAndroid Build Coastguard Worker        return 'tiff'
90*cda5da8dSAndroid Build Coastguard Worker
91*cda5da8dSAndroid Build Coastguard Worker
92*cda5da8dSAndroid Build Coastguard Worker@rule
93*cda5da8dSAndroid Build Coastguard Workerdef _rgb(h):
94*cda5da8dSAndroid Build Coastguard Worker    """SGI image library"""
95*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'\001\332'):
96*cda5da8dSAndroid Build Coastguard Worker        return 'rgb'
97*cda5da8dSAndroid Build Coastguard Worker
98*cda5da8dSAndroid Build Coastguard Worker
99*cda5da8dSAndroid Build Coastguard Worker@rule
100*cda5da8dSAndroid Build Coastguard Workerdef _pbm(h):
101*cda5da8dSAndroid Build Coastguard Worker    """PBM (portable bitmap)"""
102*cda5da8dSAndroid Build Coastguard Worker    if len(h) >= 3 and \
103*cda5da8dSAndroid Build Coastguard Worker            h[0] == ord(b'P') and h[1] in b'14' and h[2] in b' \t\n\r':
104*cda5da8dSAndroid Build Coastguard Worker        return 'pbm'
105*cda5da8dSAndroid Build Coastguard Worker
106*cda5da8dSAndroid Build Coastguard Worker
107*cda5da8dSAndroid Build Coastguard Worker@rule
108*cda5da8dSAndroid Build Coastguard Workerdef _pgm(h):
109*cda5da8dSAndroid Build Coastguard Worker    """PGM (portable graymap)"""
110*cda5da8dSAndroid Build Coastguard Worker    if len(h) >= 3 and \
111*cda5da8dSAndroid Build Coastguard Worker            h[0] == ord(b'P') and h[1] in b'25' and h[2] in b' \t\n\r':
112*cda5da8dSAndroid Build Coastguard Worker        return 'pgm'
113*cda5da8dSAndroid Build Coastguard Worker
114*cda5da8dSAndroid Build Coastguard Worker
115*cda5da8dSAndroid Build Coastguard Worker@rule
116*cda5da8dSAndroid Build Coastguard Workerdef _ppm(h):
117*cda5da8dSAndroid Build Coastguard Worker    """PPM (portable pixmap)"""
118*cda5da8dSAndroid Build Coastguard Worker    if len(h) >= 3 and \
119*cda5da8dSAndroid Build Coastguard Worker            h[0] == ord(b'P') and h[1] in b'36' and h[2] in b' \t\n\r':
120*cda5da8dSAndroid Build Coastguard Worker        return 'ppm'
121*cda5da8dSAndroid Build Coastguard Worker
122*cda5da8dSAndroid Build Coastguard Worker
123*cda5da8dSAndroid Build Coastguard Worker@rule
124*cda5da8dSAndroid Build Coastguard Workerdef _rast(h):
125*cda5da8dSAndroid Build Coastguard Worker    """Sun raster file"""
126*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'\x59\xA6\x6A\x95'):
127*cda5da8dSAndroid Build Coastguard Worker        return 'rast'
128*cda5da8dSAndroid Build Coastguard Worker
129*cda5da8dSAndroid Build Coastguard Worker
130*cda5da8dSAndroid Build Coastguard Worker@rule
131*cda5da8dSAndroid Build Coastguard Workerdef _xbm(h):
132*cda5da8dSAndroid Build Coastguard Worker    """X bitmap (X10 or X11)"""
133*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'#define '):
134*cda5da8dSAndroid Build Coastguard Worker        return 'xbm'
135*cda5da8dSAndroid Build Coastguard Worker
136*cda5da8dSAndroid Build Coastguard Worker
137*cda5da8dSAndroid Build Coastguard Worker@rule
138*cda5da8dSAndroid Build Coastguard Workerdef _bmp(h):
139*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'BM'):
140*cda5da8dSAndroid Build Coastguard Worker        return 'bmp'
141*cda5da8dSAndroid Build Coastguard Worker
142*cda5da8dSAndroid Build Coastguard Worker
143*cda5da8dSAndroid Build Coastguard Worker@rule
144*cda5da8dSAndroid Build Coastguard Workerdef _webp(h):
145*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'RIFF') and h[8:12] == b'WEBP':
146*cda5da8dSAndroid Build Coastguard Worker        return 'webp'
147*cda5da8dSAndroid Build Coastguard Worker
148*cda5da8dSAndroid Build Coastguard Worker
149*cda5da8dSAndroid Build Coastguard Worker@rule
150*cda5da8dSAndroid Build Coastguard Workerdef _exr(h):
151*cda5da8dSAndroid Build Coastguard Worker    if h.startswith(b'\x76\x2f\x31\x01'):
152*cda5da8dSAndroid Build Coastguard Worker        return 'exr'
153