Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/PIL/TgaImagePlugin.py: 12%

102 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# 

2# The Python Imaging Library. 

3# $Id$ 

4# 

5# TGA file handling 

6# 

7# History: 

8# 95-09-01 fl created (reads 24-bit files only) 

9# 97-01-04 fl support more TGA versions, including compressed images 

10# 98-07-04 fl fixed orientation and alpha layer bugs 

11# 98-09-11 fl fixed orientation for runlength decoder 

12# 

13# Copyright (c) Secret Labs AB 1997-98. 

14# Copyright (c) Fredrik Lundh 1995-97. 

15# 

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

17# 

18 

19 

20import warnings 

21 

22from . import Image, ImageFile, ImagePalette 

23from ._binary import i16le as i16 

24from ._binary import o8 

25from ._binary import o16le as o16 

26 

27# 

28# -------------------------------------------------------------------- 

29# Read RGA file 

30 

31 

32MODES = { 

33 # map imagetype/depth to rawmode 

34 (1, 8): "P", 

35 (3, 1): "1", 

36 (3, 8): "L", 

37 (3, 16): "LA", 

38 (2, 16): "BGR;5", 

39 (2, 24): "BGR", 

40 (2, 32): "BGRA", 

41} 

42 

43 

44## 

45# Image plugin for Targa files. 

46 

47 

48class TgaImageFile(ImageFile.ImageFile): 

49 

50 format = "TGA" 

51 format_description = "Targa" 

52 

53 def _open(self): 

54 

55 # process header 

56 s = self.fp.read(18) 

57 

58 id_len = s[0] 

59 

60 colormaptype = s[1] 

61 imagetype = s[2] 

62 

63 depth = s[16] 

64 

65 flags = s[17] 

66 

67 self._size = i16(s, 12), i16(s, 14) 

68 

69 # validate header fields 

70 if ( 

71 colormaptype not in (0, 1) 

72 or self.size[0] <= 0 

73 or self.size[1] <= 0 

74 or depth not in (1, 8, 16, 24, 32) 

75 ): 

76 raise SyntaxError("not a TGA file") 

77 

78 # image mode 

79 if imagetype in (3, 11): 

80 self.mode = "L" 

81 if depth == 1: 

82 self.mode = "1" # ??? 

83 elif depth == 16: 

84 self.mode = "LA" 

85 elif imagetype in (1, 9): 

86 self.mode = "P" 

87 elif imagetype in (2, 10): 

88 self.mode = "RGB" 

89 if depth == 32: 

90 self.mode = "RGBA" 

91 else: 

92 raise SyntaxError("unknown TGA mode") 

93 

94 # orientation 

95 orientation = flags & 0x30 

96 self._flip_horizontally = orientation in [0x10, 0x30] 

97 if orientation in [0x20, 0x30]: 

98 orientation = 1 

99 elif orientation in [0, 0x10]: 

100 orientation = -1 

101 else: 

102 raise SyntaxError("unknown TGA orientation") 

103 

104 self.info["orientation"] = orientation 

105 

106 if imagetype & 8: 

107 self.info["compression"] = "tga_rle" 

108 

109 if id_len: 

110 self.info["id_section"] = self.fp.read(id_len) 

111 

112 if colormaptype: 

113 # read palette 

114 start, size, mapdepth = i16(s, 3), i16(s, 5), s[7] 

115 if mapdepth == 16: 

116 self.palette = ImagePalette.raw( 

117 "BGR;15", b"\0" * 2 * start + self.fp.read(2 * size) 

118 ) 

119 elif mapdepth == 24: 

120 self.palette = ImagePalette.raw( 

121 "BGR", b"\0" * 3 * start + self.fp.read(3 * size) 

122 ) 

123 elif mapdepth == 32: 

124 self.palette = ImagePalette.raw( 

125 "BGRA", b"\0" * 4 * start + self.fp.read(4 * size) 

126 ) 

127 

128 # setup tile descriptor 

129 try: 

130 rawmode = MODES[(imagetype & 7, depth)] 

131 if imagetype & 8: 

132 # compressed 

133 self.tile = [ 

134 ( 

135 "tga_rle", 

136 (0, 0) + self.size, 

137 self.fp.tell(), 

138 (rawmode, orientation, depth), 

139 ) 

140 ] 

141 else: 

142 self.tile = [ 

143 ( 

144 "raw", 

145 (0, 0) + self.size, 

146 self.fp.tell(), 

147 (rawmode, 0, orientation), 

148 ) 

149 ] 

150 except KeyError: 

151 pass # cannot decode 

152 

153 def load_end(self): 

154 if self._flip_horizontally: 

155 self.im = self.im.transpose(Image.Transpose.FLIP_LEFT_RIGHT) 

156 

157 

158# 

159# -------------------------------------------------------------------- 

160# Write TGA file 

161 

162 

163SAVE = { 

164 "1": ("1", 1, 0, 3), 

165 "L": ("L", 8, 0, 3), 

166 "LA": ("LA", 16, 0, 3), 

167 "P": ("P", 8, 1, 1), 

168 "RGB": ("BGR", 24, 0, 2), 

169 "RGBA": ("BGRA", 32, 0, 2), 

170} 

171 

172 

173def _save(im, fp, filename): 

174 

175 try: 

176 rawmode, bits, colormaptype, imagetype = SAVE[im.mode] 

177 except KeyError as e: 

178 raise OSError(f"cannot write mode {im.mode} as TGA") from e 

179 

180 if "rle" in im.encoderinfo: 

181 rle = im.encoderinfo["rle"] 

182 else: 

183 compression = im.encoderinfo.get("compression", im.info.get("compression")) 

184 rle = compression == "tga_rle" 

185 if rle: 

186 imagetype += 8 

187 

188 id_section = im.encoderinfo.get("id_section", im.info.get("id_section", "")) 

189 id_len = len(id_section) 

190 if id_len > 255: 

191 id_len = 255 

192 id_section = id_section[:255] 

193 warnings.warn("id_section has been trimmed to 255 characters") 

194 

195 if colormaptype: 

196 colormapfirst, colormaplength, colormapentry = 0, 256, 24 

197 else: 

198 colormapfirst, colormaplength, colormapentry = 0, 0, 0 

199 

200 if im.mode in ("LA", "RGBA"): 

201 flags = 8 

202 else: 

203 flags = 0 

204 

205 orientation = im.encoderinfo.get("orientation", im.info.get("orientation", -1)) 

206 if orientation > 0: 

207 flags = flags | 0x20 

208 

209 fp.write( 

210 o8(id_len) 

211 + o8(colormaptype) 

212 + o8(imagetype) 

213 + o16(colormapfirst) 

214 + o16(colormaplength) 

215 + o8(colormapentry) 

216 + o16(0) 

217 + o16(0) 

218 + o16(im.size[0]) 

219 + o16(im.size[1]) 

220 + o8(bits) 

221 + o8(flags) 

222 ) 

223 

224 if id_section: 

225 fp.write(id_section) 

226 

227 if colormaptype: 

228 fp.write(im.im.getpalette("RGB", "BGR")) 

229 

230 if rle: 

231 ImageFile._save( 

232 im, fp, [("tga_rle", (0, 0) + im.size, 0, (rawmode, orientation))] 

233 ) 

234 else: 

235 ImageFile._save( 

236 im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))] 

237 ) 

238 

239 # write targa version 2 footer 

240 fp.write(b"\000" * 8 + b"TRUEVISION-XFILE." + b"\000") 

241 

242 

243# 

244# -------------------------------------------------------------------- 

245# Registry 

246 

247 

248Image.register_open(TgaImageFile.format, TgaImageFile) 

249Image.register_save(TgaImageFile.format, _save) 

250 

251Image.register_extensions(TgaImageFile.format, [".tga", ".icb", ".vda", ".vst"]) 

252 

253Image.register_mime(TgaImageFile.format, "image/x-tga")