| Home | Trees | Indices | Help |
|
|---|
|
|
1 """
2 :mod:`pyffi.formats.tga` --- Targa (.tga)
3 =========================================
4
5 Implementation
6 --------------
7
8 .. autoclass:: TgaFormat
9 :show-inheritance:
10 :members:
11
12 Regression tests
13 ----------------
14
15 Read a TGA file
16 ^^^^^^^^^^^^^^^
17
18 >>> # check and read tga file
19 >>> stream = open('tests/tga/test.tga', 'rb')
20 >>> data = TgaFormat.Data()
21 >>> data.inspect(stream)
22 >>> data.read(stream)
23 >>> stream.close()
24 >>> data.header.width
25 60
26 >>> data.header.height
27 20
28
29 Parse all TGA files in a directory tree
30 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31
32 >>> for stream, data in TgaFormat.walkData('tests/tga'):
33 ... data.read(stream)
34 ... print(stream.name)
35 tests/tga/test.tga
36 tests/tga/test_footer.tga
37
38 Create a TGA file from scratch and write to file
39 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40
41 >>> data = TgaFormat.Data()
42 >>> from tempfile import TemporaryFile
43 >>> stream = TemporaryFile()
44 >>> data.write(stream)
45 >>> stream.close()
46 """
47
48 # ***** BEGIN LICENSE BLOCK *****
49 #
50 # Copyright (c) 2007-2011, Python File Format Interface
51 # All rights reserved.
52 #
53 # Redistribution and use in source and binary forms, with or without
54 # modification, are permitted provided that the following conditions
55 # are met:
56 #
57 # * Redistributions of source code must retain the above copyright
58 # notice, this list of conditions and the following disclaimer.
59 #
60 # * Redistributions in binary form must reproduce the above
61 # copyright notice, this list of conditions and the following
62 # disclaimer in the documentation and/or other materials provided
63 # with the distribution.
64 #
65 # * Neither the name of the Python File Format Interface
66 # project nor the names of its contributors may be used to endorse
67 # or promote products derived from this software without specific
68 # prior written permission.
69 #
70 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
71 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
72 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
73 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
74 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
75 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
76 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
78 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
79 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
80 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
81 # POSSIBILITY OF SUCH DAMAGE.
82 #
83 # ***** END LICENSE BLOCK *****
84
85 import struct, os, re
86
87 import pyffi.object_models.xml
88 import pyffi.object_models.common
89 import pyffi.object_models.xml.basic
90 import pyffi.object_models.xml.struct_
91 import pyffi.object_models
92 import pyffi.utils.graph
93 from pyffi.utils.graph import EdgeFilter
94
96 """This class implements the TGA format."""
97 xml_file_name = 'tga.xml'
98 # where to look for tga.xml and in what order:
99 # TGAXMLPATH env var, or TgaFormat module directory
100 xml_file_path = [os.getenv('TGAXMLPATH'), os.path.dirname(__file__)]
101 # filter for recognizing tga files by extension
102 RE_FILENAME = re.compile(r'^.*\.tga$', re.IGNORECASE)
103
104 # basic types
105 int = pyffi.object_models.common.Int
106 uint = pyffi.object_models.common.UInt
107 byte = pyffi.object_models.common.Byte
108 ubyte = pyffi.object_models.common.UByte
109 char = pyffi.object_models.common.Char
110 short = pyffi.object_models.common.Short
111 ushort = pyffi.object_models.common.UShort
112 float = pyffi.object_models.common.Float
113 PixelData = pyffi.object_models.common.UndecodedData
114
171
176
178 data = data
179 if data.header.image_type in (TgaFormat.ImageType.INDEXED,
180 TgaFormat.ImageType.RGB,
181 TgaFormat.ImageType.GREY):
182 self.children = [
183 TgaFormat.Pixel(argument=data.header.pixel_size)
184 for i in xrange(data.header.width
185 * data.header.height)]
186 for pixel in self.children:
187 pixel.read(stream, data)
188 else:
189 self.children = []
190 count = 0
191 while count < data.header.width * data.header.height:
192 pixel = TgaFormat.RLEPixels(
193 argument=data.header.pixel_size)
194 pixel.read(stream, data)
195 self.children.append(pixel)
196 count += pixel.header.count + 1
197
199 data = data
200 for child in self.children:
201 child.arg = data.header.pixel_size
202 child.write(stream, data)
203
207
211
213
215 self.header = TgaFormat.Header()
216 self.image = TgaFormat.Image()
217 self.footer = None # TgaFormat.Footer() is optional
218
220 """Quick heuristic check if stream contains Targa data,
221 by looking at the first 18 bytes.
222
223 :param stream: The stream to inspect.
224 :type stream: file
225 """
226 # XXX todo: set some of the actual fields of the header
227
228 pos = stream.tell()
229 # read header
230 try:
231 id_length, colormap_type, image_type, \
232 colormap_index, colormap_length, colormap_size, \
233 x_origin, y_origin, width, height, \
234 pixel_size, flags = struct.unpack("<BBBHHBHHHHBB",
235 stream.read(18))
236 except struct.error:
237 # could not read 18 bytes
238 # not a TGA file
239 raise ValueError("Not a Targa file.")
240 finally:
241 stream.seek(pos)
242 # check if tga type is valid
243 # check pixel size
244 # check width and height
245 if not(image_type in (1, 2, 3, 9, 10, 11)
246 and pixel_size in (8, 24, 32)
247 and width <= 100000
248 and height <= 100000):
249 raise ValueError("Not a Targa file.")
250 # this looks like a tga file!
251
253 """Read a tga file.
254
255 :param stream: The stream from which to read.
256 :type stream: ``file``
257 """
258 # read the file
259 self.inspect(stream) # quick check
260
261 # header
262 self.header.read(stream, self)
263
264 # image
265 self.image.read(stream, self)
266
267 # check if we are at the end of the file
268 if not stream.read(1):
269 self.footer = None
270 return
271
272 # footer
273 stream.seek(-26, os.SEEK_END)
274 self.footer = TgaFormat.Footer()
275 self.footer.read(stream, self)
276
278 """Write a tga file.
279
280 :param stream: The stream to write to.
281 :type stream: ``file``
282 """
283 self.header.write(stream, self)
284 self.image.write(stream, self)
285 if self.footer:
286 self.footer.write(stream, self)
287
293
299
300 if __name__ == '__main__':
301 import doctest
302 doctest.testmod()
303
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Oct 10 19:04:07 2011 | http://epydoc.sourceforge.net |