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

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

59 statements  

1# 

2# The Python Imaging Library. 

3# $Id$ 

4# 

5# Sun image file handling 

6# 

7# History: 

8# 1995-09-10 fl Created 

9# 1996-05-28 fl Fixed 32-bit alignment 

10# 1998-12-29 fl Import ImagePalette module 

11# 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault) 

12# 

13# Copyright (c) 1997-2001 by Secret Labs AB 

14# Copyright (c) 1995-1996 by Fredrik Lundh 

15# 

16# See the README file for information on usage and redistribution. 

17# 

18from __future__ import annotations 

19 

20__lazy_modules__ = {"PIL._binary"} 

21 

22from . import Image, ImageFile, ImagePalette 

23from ._binary import i32be as i32 

24 

25 

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

27 return len(prefix) >= 4 and i32(prefix) == 0x59A66A95 

28 

29 

30## 

31# Image plugin for Sun raster files. 

32 

33 

34class SunImageFile(ImageFile.ImageFile): 

35 format = "SUN" 

36 format_description = "Sun Raster File" 

37 

38 def _open(self) -> None: 

39 # The Sun Raster file header is 32 bytes in length 

40 # and has the following format: 

41 

42 # typedef struct _SunRaster 

43 # { 

44 # DWORD MagicNumber; /* Magic (identification) number */ 

45 # DWORD Width; /* Width of image in pixels */ 

46 # DWORD Height; /* Height of image in pixels */ 

47 # DWORD Depth; /* Number of bits per pixel */ 

48 # DWORD Length; /* Size of image data in bytes */ 

49 # DWORD Type; /* Type of raster file */ 

50 # DWORD ColorMapType; /* Type of color map */ 

51 # DWORD ColorMapLength; /* Size of the color map in bytes */ 

52 # } SUNRASTER; 

53 

54 assert self.fp is not None 

55 

56 # HEAD 

57 s = self.fp.read(32) 

58 if not _accept(s): 

59 msg = "not an SUN raster file" 

60 raise SyntaxError(msg) 

61 

62 offset = 32 

63 

64 self._size = i32(s, 4), i32(s, 8) 

65 

66 depth = i32(s, 12) 

67 # data_length = i32(s, 16) # unreliable, ignore. 

68 file_type = i32(s, 20) 

69 palette_type = i32(s, 24) # 0: None, 1: RGB, 2: Raw/arbitrary 

70 palette_length = i32(s, 28) 

71 

72 if depth == 1: 

73 self._mode, rawmode = "1", "1;I" 

74 elif depth == 4: 

75 self._mode, rawmode = "L", "L;4" 

76 elif depth == 8: 

77 self._mode = rawmode = "L" 

78 elif depth == 24: 

79 if file_type == 3: 

80 self._mode, rawmode = "RGB", "RGB" 

81 else: 

82 self._mode, rawmode = "RGB", "BGR" 

83 elif depth == 32: 

84 if file_type == 3: 

85 self._mode, rawmode = "RGB", "RGBX" 

86 else: 

87 self._mode, rawmode = "RGB", "BGRX" 

88 else: 

89 msg = "Unsupported Mode/Bit Depth" 

90 raise SyntaxError(msg) 

91 

92 if palette_length: 

93 if palette_length > 1024: 

94 msg = "Unsupported Color Palette Length" 

95 raise SyntaxError(msg) 

96 

97 if palette_type != 1: 

98 msg = "Unsupported Palette Type" 

99 raise SyntaxError(msg) 

100 

101 offset = offset + palette_length 

102 self.palette = ImagePalette.raw("RGB;L", self.fp.read(palette_length)) 

103 if self.mode == "L": 

104 self._mode = "P" 

105 rawmode = rawmode.replace("L", "P") 

106 

107 # 16 bit boundaries on stride 

108 stride = ((self.size[0] * depth + 15) // 16) * 2 

109 

110 # file type: Type is the version (or flavor) of the bitmap 

111 # file. The following values are typically found in the Type 

112 # field: 

113 # 0000h Old 

114 # 0001h Standard 

115 # 0002h Byte-encoded 

116 # 0003h RGB format 

117 # 0004h TIFF format 

118 # 0005h IFF format 

119 # FFFFh Experimental 

120 

121 # Old and standard are the same, except for the length tag. 

122 # byte-encoded is run-length-encoded 

123 # RGB looks similar to standard, but RGB byte order 

124 # TIFF and IFF mean that they were converted from T/IFF 

125 # Experimental means that it's something else. 

126 # (https://www.fileformat.info/format/sunraster/egff.htm) 

127 

128 if file_type in (0, 1, 3, 4, 5): 

129 self.tile = [ImageFile._Tile("raw", None, offset, (rawmode, stride))] 

130 elif file_type == 2: 

131 self.tile = [ImageFile._Tile("sun_rle", None, offset, rawmode)] 

132 else: 

133 msg = "Unsupported Sun Raster file type" 

134 raise SyntaxError(msg) 

135 

136 

137# 

138# registry 

139 

140 

141Image.register_open(SunImageFile.format, SunImageFile, _accept) 

142 

143Image.register_extension(SunImageFile.format, ".ras")