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