Home | Trees | Indices | Help |
|
---|
|
1 """ 2 :mod:`pyffi.formats.dds` --- DirectDraw Surface (.dds) 3 ====================================================== 4 5 Implementation 6 -------------- 7 8 .. autoclass:: DdsFormat 9 :show-inheritance: 10 :members: 11 12 Regression tests 13 ---------------- 14 15 Read a DDS file 16 ^^^^^^^^^^^^^^^ 17 18 >>> # check and read dds file 19 >>> stream = open('tests/dds/test.dds', 'rb') 20 >>> data = DdsFormat.Data() 21 >>> data.inspect(stream) 22 >>> data.header.pixel_format.size 23 32 24 >>> data.header.height 25 20 26 >>> data.read(stream) 27 >>> len(data.pixeldata.get_value()) 28 888 29 30 Parse all DDS files in a directory tree 31 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 32 33 >>> for stream, data in DdsFormat.walkData('tests/dds'): 34 ... print(stream.name) 35 tests/dds/test.dds 36 37 Create a DDS file from scratch and write to file 38 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 39 40 >>> data = DdsFormat.Data() 41 >>> from tempfile import TemporaryFile 42 >>> stream = TemporaryFile() 43 >>> data.write(stream) 44 45 Get list of versions 46 ^^^^^^^^^^^^^^^^^^^^ 47 48 >>> for vnum in sorted(DdsFormat.versions.values()): 49 ... print('0x%08X' % vnum) 50 0x09000000 51 0x0A000000 52 """ 53 54 # ***** BEGIN LICENSE BLOCK ***** 55 # 56 # Copyright (c) 2007-2011, Python File Format Interface 57 # All rights reserved. 58 # 59 # Redistribution and use in source and binary forms, with or without 60 # modification, are permitted provided that the following conditions 61 # are met: 62 # 63 # * Redistributions of source code must retain the above copyright 64 # notice, this list of conditions and the following disclaimer. 65 # 66 # * Redistributions in binary form must reproduce the above 67 # copyright notice, this list of conditions and the following 68 # disclaimer in the documentation and/or other materials provided 69 # with the distribution. 70 # 71 # * Neither the name of the Python File Format Interface 72 # project nor the names of its contributors may be used to endorse 73 # or promote products derived from this software without specific 74 # prior written permission. 75 # 76 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 77 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 78 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 79 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 80 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 81 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 82 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 83 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 84 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 85 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 86 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 87 # POSSIBILITY OF SUCH DAMAGE. 88 # 89 # ***** END LICENSE BLOCK ***** 90 91 import struct 92 import os 93 import re 94 95 import pyffi.object_models.xml 96 import pyffi.object_models.common 97 from pyffi.object_models.xml.basic import BasicBase 98 import pyffi.object_models 99 from pyffi.utils.graph import EdgeFilter102 """This class implements the DDS format.""" 103 xml_file_name = 'dds.xml' 104 # where to look for dds.xml and in what order: 105 # DDSXMLPATH env var, or DdsFormat module directory 106 xml_file_path = [os.getenv('DDSXMLPATH'), os.path.dirname(__file__)] 107 # file name regular expression match 108 RE_FILENAME = re.compile(r'^.*\.dds$', re.IGNORECASE) 109 # used for comparing floats 110 _EPSILON = 0.0001 111 112 # basic types 113 int = pyffi.object_models.common.Int 114 uint = pyffi.object_models.common.UInt 115 byte = pyffi.object_models.common.Byte 116 ubyte = pyffi.object_models.common.UByte 117 char = pyffi.object_models.common.Char 118 short = pyffi.object_models.common.Short 119 ushort = pyffi.object_models.common.UShort 120 float = pyffi.object_models.common.Float 121 PixelData = pyffi.object_models.common.UndecodedData 122 123 # implementation of dds-specific basic types 124272126 """Basic type which implements the header of a DDS file.""" 129 132169 170 @staticmethod134 return self.__str__()135137 """Return a hash value for this value. 138 139 :return: An immutable object that can be used as a hash. 140 """ 141 return None142144 """Read header string from stream and check it. 145 146 :param stream: The stream to read from. 147 :type stream: file 148 """ 149 hdrstr = stream.read(4) 150 # check if the string is correct 151 if hdrstr != "DDS ".encode("ascii"): 152 raise ValueError( 153 "invalid DDS header: expected 'DDS ' but got '%s'" % hdrstr)154156 """Write the header string to stream. 157 158 :param stream: The stream to write to. 159 :type stream: file 160 """ 161 stream.write("DDS ".encode("ascii"))162172 """Converts version string into an integer. 173 174 :param version_str: The version string. 175 :type version_str: str 176 :return: A version integer. 177 178 >>> hex(DdsFormat.version_number('DX10')) 179 '0xa000000' 180 """ 181 return {'DX9': 0x09000000, 'DX10': 0x0A000000}[version_str]182184 """A class to contain the actual dds data."""186 self.version = version 187 self.header = DdsFormat.Header() 188 self.pixeldata = DdsFormat.PixelData() 189 190 # TODO refactor xml model so we can get rid of these 191 self.user_version = 0 192 self.user_version2 = 0193195 """Quickly checks if stream contains DDS data, and gets the 196 version, by looking at the first 8 bytes. 197 198 :param stream: The stream to inspect. 199 :type stream: file 200 """ 201 pos = stream.tell() 202 try: 203 hdrstr = stream.read(4) 204 if hdrstr != "DDS ".encode("ascii"): 205 raise ValueError("Not a DDS file.") 206 size = struct.unpack("<I", stream.read(4)) 207 if size == 124: 208 self.version = 0x09000000 # DX9 209 elif size == 144: 210 self.version = 0x0A000000 # DX10 211 finally: 212 stream.seek(pos)213 214 # overriding pyffi.object_models.FileFormat.Data methods 215217 """Quickly checks if stream contains DDS data, and reads the 218 header. 219 220 :param stream: The stream to inspect. 221 :type stream: file 222 """ 223 pos = stream.tell() 224 try: 225 self.inspect_quick(stream) 226 self.header.read(stream, data=self) 227 finally: 228 stream.seek(pos)229 230232 """Read a dds file. 233 234 :param stream: The stream from which to read. 235 :type stream: ``file`` 236 :param verbose: The level of verbosity. 237 :type verbose: ``int`` 238 """ 239 # read the file 240 self.inspect_quick(stream) 241 self.header.read(stream, data=self) 242 self.pixeldata.read(stream, data=self) 243 244 # check if we are at the end of the file 245 if stream.read(1): 246 raise ValueError( 247 'end of file not reached: corrupt dds file?')248250 """Write a dds file. 251 252 :param stream: The stream to which to write. 253 :type stream: ``file`` 254 :param verbose: The level of verbosity. 255 :type verbose: ``int`` 256 """ 257 # TODO: make sure pixel data has correct length 258 259 # write the file 260 # first header 261 self.header.write(stream, data=self) 262 # next the pixel data 263 self.pixeldata.write(stream, data=self)264 265 # DetailNode 266 269
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 10 19:04:07 2011 | http://epydoc.sourceforge.net |