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