GbrImagePlugin.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #
  2. # The Python Imaging Library
  3. #
  4. # load a GIMP brush file
  5. #
  6. # History:
  7. # 96-03-14 fl Created
  8. # 16-01-08 es Version 2
  9. #
  10. # Copyright (c) Secret Labs AB 1997.
  11. # Copyright (c) Fredrik Lundh 1996.
  12. # Copyright (c) Eric Soroos 2016.
  13. #
  14. # See the README file for information on usage and redistribution.
  15. #
  16. #
  17. # See https://github.com/GNOME/gimp/blob/mainline/devel-docs/gbr.txt for
  18. # format documentation.
  19. #
  20. # This code Interprets version 1 and 2 .gbr files.
  21. # Version 1 files are obsolete, and should not be used for new
  22. # brushes.
  23. # Version 2 files are saved by GIMP v2.8 (at least)
  24. # Version 3 files have a format specifier of 18 for 16bit floats in
  25. # the color depth field. This is currently unsupported by Pillow.
  26. from . import Image, ImageFile
  27. from ._binary import i32be as i32
  28. def _accept(prefix):
  29. return len(prefix) >= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2)
  30. ##
  31. # Image plugin for the GIMP brush format.
  32. class GbrImageFile(ImageFile.ImageFile):
  33. format = "GBR"
  34. format_description = "GIMP brush file"
  35. def _open(self):
  36. header_size = i32(self.fp.read(4))
  37. if header_size < 20:
  38. msg = "not a GIMP brush"
  39. raise SyntaxError(msg)
  40. version = i32(self.fp.read(4))
  41. if version not in (1, 2):
  42. msg = f"Unsupported GIMP brush version: {version}"
  43. raise SyntaxError(msg)
  44. width = i32(self.fp.read(4))
  45. height = i32(self.fp.read(4))
  46. color_depth = i32(self.fp.read(4))
  47. if width <= 0 or height <= 0:
  48. msg = "not a GIMP brush"
  49. raise SyntaxError(msg)
  50. if color_depth not in (1, 4):
  51. msg = f"Unsupported GIMP brush color depth: {color_depth}"
  52. raise SyntaxError(msg)
  53. if version == 1:
  54. comment_length = header_size - 20
  55. else:
  56. comment_length = header_size - 28
  57. magic_number = self.fp.read(4)
  58. if magic_number != b"GIMP":
  59. msg = "not a GIMP brush, bad magic number"
  60. raise SyntaxError(msg)
  61. self.info["spacing"] = i32(self.fp.read(4))
  62. comment = self.fp.read(comment_length)[:-1]
  63. if color_depth == 1:
  64. self._mode = "L"
  65. else:
  66. self._mode = "RGBA"
  67. self._size = width, height
  68. self.info["comment"] = comment
  69. # Image might not be small
  70. Image._decompression_bomb_check(self.size)
  71. # Data is an uncompressed block of w * h * bytes/pixel
  72. self._data_size = width * height * color_depth
  73. def load(self):
  74. if not self.im:
  75. self.im = Image.core.new(self.mode, self.size)
  76. self.frombytes(self.fp.read(self._data_size))
  77. return Image.Image.load(self)
  78. #
  79. # registry
  80. Image.register_open(GbrImageFile.format, GbrImageFile, _accept)
  81. Image.register_extension(GbrImageFile.format, ".gbr")