Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PIL/GbrImagePlugin.py: 72%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

50 statements  

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. 

26from __future__ import annotations 

27 

28from . import Image, ImageFile 

29from ._binary import i32be as i32 

30 

31 

32def _accept(prefix: bytes) -> bool: 

33 return len(prefix) >= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2) 

34 

35 

36## 

37# Image plugin for the GIMP brush format. 

38 

39 

40class GbrImageFile(ImageFile.ImageFile): 

41 format = "GBR" 

42 format_description = "GIMP brush file" 

43 

44 def _open(self) -> None: 

45 header_size = i32(self.fp.read(4)) 

46 if header_size < 20: 

47 msg = "not a GIMP brush" 

48 raise SyntaxError(msg) 

49 version = i32(self.fp.read(4)) 

50 if version not in (1, 2): 

51 msg = f"Unsupported GIMP brush version: {version}" 

52 raise SyntaxError(msg) 

53 

54 width = i32(self.fp.read(4)) 

55 height = i32(self.fp.read(4)) 

56 color_depth = i32(self.fp.read(4)) 

57 if width <= 0 or height <= 0: 

58 msg = "not a GIMP brush" 

59 raise SyntaxError(msg) 

60 if color_depth not in (1, 4): 

61 msg = f"Unsupported GIMP brush color depth: {color_depth}" 

62 raise SyntaxError(msg) 

63 

64 if version == 1: 

65 comment_length = header_size - 20 

66 else: 

67 comment_length = header_size - 28 

68 magic_number = self.fp.read(4) 

69 if magic_number != b"GIMP": 

70 msg = "not a GIMP brush, bad magic number" 

71 raise SyntaxError(msg) 

72 self.info["spacing"] = i32(self.fp.read(4)) 

73 

74 comment = self.fp.read(comment_length)[:-1] 

75 

76 if color_depth == 1: 

77 self._mode = "L" 

78 else: 

79 self._mode = "RGBA" 

80 

81 self._size = width, height 

82 

83 self.info["comment"] = comment 

84 

85 # Image might not be small 

86 Image._decompression_bomb_check(self.size) 

87 

88 # Data is an uncompressed block of w * h * bytes/pixel 

89 self._data_size = width * height * color_depth 

90 

91 def load(self) -> Image.core.PixelAccess | None: 

92 if self._im is None: 

93 self.im = Image.core.new(self.mode, self.size) 

94 self.frombytes(self.fp.read(self._data_size)) 

95 return Image.Image.load(self) 

96 

97 

98# 

99# registry 

100 

101 

102Image.register_open(GbrImageFile.format, GbrImageFile, _accept) 

103Image.register_extension(GbrImageFile.format, ".gbr")