GbrImagePlugin.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. version = i32(self.fp.read(4))
  38. if header_size < 20:
  39. raise SyntaxError("not a GIMP brush")
  40. if version not in (1, 2):
  41. raise SyntaxError(f"Unsupported GIMP brush version: {version}")
  42. width = i32(self.fp.read(4))
  43. height = i32(self.fp.read(4))
  44. color_depth = i32(self.fp.read(4))
  45. if width <= 0 or height <= 0:
  46. raise SyntaxError("not a GIMP brush")
  47. if color_depth not in (1, 4):
  48. raise SyntaxError(f"Unsupported GIMP brush color depth: {color_depth}")
  49. if version == 1:
  50. comment_length = header_size - 20
  51. else:
  52. comment_length = header_size - 28
  53. magic_number = self.fp.read(4)
  54. if magic_number != b"GIMP":
  55. raise SyntaxError("not a GIMP brush, bad magic number")
  56. self.info["spacing"] = i32(self.fp.read(4))
  57. comment = self.fp.read(comment_length)[:-1]
  58. if color_depth == 1:
  59. self.mode = "L"
  60. else:
  61. self.mode = "RGBA"
  62. self._size = width, height
  63. self.info["comment"] = comment
  64. # Image might not be small
  65. Image._decompression_bomb_check(self.size)
  66. # Data is an uncompressed block of w * h * bytes/pixel
  67. self._data_size = width * height * color_depth
  68. def load(self):
  69. if self.im:
  70. # Already loaded
  71. return
  72. self.im = Image.core.new(self.mode, self.size)
  73. self.frombytes(self.fp.read(self._data_size))
  74. #
  75. # registry
  76. Image.register_open(GbrImageFile.format, GbrImageFile, _accept)
  77. Image.register_extension(GbrImageFile.format, ".gbr")