The basics
What is a DDS file?
A DDS file holds a texture: an image meant to be wrapped onto 3D objects by a graphics card. Microsoft introduced it with DirectX 7.0 in 1999, and it has become a common texture format for PC games, including the textures in many game mods. Where a PNG stores one picture as compactly as possible on disk, a DDS stores it the way the GPU wants it in memory.
- Block-compressed. Most DDS files use BC compression, which the graphics card decodes in hardware as it draws. A compressed texture takes a quarter or less of the memory, and the game doesn't have to decompress it.
- Mipmaps included. A DDS can carry ready-made smaller copies of the image, each half the size of the previous, which the GPU uses for distant surfaces.
- More than flat images. One file can hold a cube map (six faces of a sky or reflection), a volume texture (a 3D grid of pixels) or an array of textures.
The compression is lossy and tuned for speed of decoding, not for photos on a screen, so a DDS is a poor format for sharing pictures. Browsers don't display it.
Anatomy
What's inside a DDS file
A DDS file is a 4-byte magic number, a 124-byte header, an optional 20-byte DX10 header, then the texture data: the main image followed by any mipmaps, cube faces or array slices. All numbers are little-endian. Below is every byte of a 136-byte file we built for this page from Microsoft's documentation and checked in four different decoders: a single 4 × 4 block of BC1 (DXT1), left half red, right half blue. It isn't offered for download.
tiny.dds: one 4 × 4 BC1 (DXT1) texture, 136 bytes
offset bytes part
000000 44 44 53 20 magic: "DDS "
000004 7C 00 00 00 header size: 124
000008 07 10 08 00 flags: caps, height, width,
pixel format, linear size
00000C 04 00 00 00 04 00 00 00 height 4, width 4
000014 08 00 00 00 linear size: 8 bytes of top-level data
000018 00 00 00 00 00 00 00 00 depth 0, mipmap count 0
000020 00 × 44 reserved
00004C 20 00 00 00 pixel format: size 32
000050 04 00 00 00 pixel format flags: FOURCC
000054 44 58 54 31 FourCC: "DXT1"
000058 00 × 20 bit count and masks: unused
00006C 00 10 00 00 caps: TEXTURE
000070 00 × 16 caps2, caps3, caps4, reserved
000080 00 F8 colour 0: F800 = red (5:6:5)
000082 1F 00 colour 1: 001F = blue
000084 50 50 50 50 16 two-bit indices, one byte per row
50 → 0, 0, 1, 1 → red red blue blue- 1
44 44 53 20The magic number
DDSin ASCII, with a trailing space. A valid file is at least 128 bytes: these 4 plus the 124-byte header. - 2
7C 00 00 00Header size
Always 124 (
0x7C). The header is the old DirectDrawDDSURFACEDESC2structure without its DirectDraw dependencies. - 3
07 10 08 00Flags
0x81007: caps (0x1), height (0x2), width (0x4), pixel format (0x1000) and linear size (0x80000). Microsoft advises readers not to rely on these flags, because some writers leave them out. - 4
08 00 00 00Pitch or linear size
For a compressed texture, the size in bytes of the top-level image: one block of 8 bytes. For uncompressed data it's the bytes per row. Writers often fill it in wrongly, so Microsoft recommends computing it yourself.
- 5
00 00 00 00 00 00 00 00Depth and mipmap count
Depth is only used by volume textures. The mipmap count is 0 here, so there's just the one image; a 1024 × 1024 texture with a full mip chain would say 11.
- 6
44 58 54 31The pixel format
A 32-byte structure inside the header. Its flags say whether the format is given as bit masks (for uncompressed RGB) or as a four-character code. Here it's the code
DXT1, meaning BC1. The codeDX10would mean a 20-byte DX10 header follows. - 7
00 10 00 00Caps
DDSCAPS_TEXTURE(0x1000), required in every file. Files with mipmaps also setCOMPLEXandMIPMAP, and cube maps set the cube map flags incaps2. - 8
00 F8 1F 00A BC1 block: two colours
Two colours in 16-bit 5:6:5 format (5 bits red, 6 green, 5 blue).
F800is pure red and001Fpure blue. Because the first is the larger number, the block uses four colours: these two and two blends between them. - 9
50 50 50 50A BC1 block: the indices
Sixteen 2-bit numbers, one per pixel, each choosing one of the four colours. Each byte is one row, read from the lowest bits up:
0x50is 00, 00, 01, 01, so each row is red, red, blue, blue. A whole 4 × 4 block fits in 8 bytes instead of 48.
Under the hood
Block compression: BC1 to BC7
Block compression splits the image into 4 × 4 pixel blocks and stores each one in a fixed number of bytes, so the GPU can find and decode any block instantly. BC1 to BC3 come from S3 Texture Compression (S3TC), developed by S3 Graphics, and were known as DXT1 to DXT5 in DirectX 9. Direct3D 10 and 11 added the rest.
| Format | Older name | Stores | Bytes per block | Good for |
|---|---|---|---|---|
| BC1 | DXT1 | RGB, optional 1-bit alpha | 8 | Opaque colour textures |
| BC2 | DXT2, DXT3 | RGB + 4-bit alpha | 16 | Rarely used today |
| BC3 | DXT4, DXT5 | RGB + smooth alpha | 16 | Textures with soft transparency |
| BC4 | ATI1 | One channel | 8 | Greyscale masks, height, roughness |
| BC5 | ATI2 | Two channels | 16 | Normal maps |
| BC6H | None | RGB half float (HDR) | 16 | HDR skies and lighting |
| BC7 | None | RGB or RGBA, high quality | 16 | Colour textures where quality matters |
In a BC1 block, two colours are stored and two more are blended from them: one-third and two-thirds of the way between. Each pixel picks one of the four with a 2-bit index. If the first colour isn't the larger number, the block switches to three colours plus fully transparent, which is BC1's 1-bit alpha. BC7 uses the same idea with 8 different modes per block and better precision, which is why it looks much better than BC1 at twice the size.
| Format | Top level only | With full mip chain |
|---|---|---|
| Uncompressed RGBA, 8 bits per channel | 16 MiB | About 21.3 MiB |
| BC7 or BC3 | 4 MiB | About 5.3 MiB |
| BC1 | 2 MiB | About 2.7 MiB |
A full mip chain adds about one-third. Because the formats work on 4 × 4 blocks, Direct3D requires the dimensions of a block-compressed texture to be multiples of 4; most game textures are powers of two, such as 512, 1024 or 2048.
Structure
Mipmaps, cube maps, volumes and arrays
After the headers, the data is just surfaces one after another, with no markers between them. A reader works out where each one starts from the size, format and counts in the header:
- Mipmaps: the full-size image first, then each smaller level down to 1 × 1. The header's mipmap count says how many levels there are.
- Cube maps: six faces in the order +X, −X, +Y, −Y, +Z, −Z, each with its own mip chain. Direct3D 10 and later require all six; Direct3D 9 accepted partial cube maps.
- Volume textures: slices of a 3D texture, with the header's depth field set.
- Texture arrays: several textures of the same size and format, possible only with the DX10 header; each array element comes with all its mipmaps.
Since nothing marks where one surface ends, a header with a wrong mipmap count or format makes every later surface garbage. That's the most common cause of textures that look like noise or crash a game.
Versions
Legacy DDS and the DX10 header
The original header describes pixel formats with bit masks or a four-character code such as DXT1, DXT5, ATI2. That can't express everything Direct3D 10 and later support: BC6H, BC7, sRGB variants, floating-point formats or texture arrays. So when the code is DX10, a 20-byte extra header follows:
| Field | What it holds |
|---|---|
dxgiFormat | The exact DXGI format, such as BC7_UNORM_SRGB or R16G16B16A16_FLOAT |
resourceDimension | 1D, 2D or 3D texture |
miscFlag | 0x4 for a cube map |
arraySize | Number of textures in an array, or of cubes in a cube map array |
miscFlags2 | Alpha mode: unknown, straight, premultiplied, opaque or custom |
Not every tool reads the DX10 header, and Microsoft recommends the legacy header for uncompressed RGB and BC1 to BC3 when compatibility matters. Use the DX10 header for BC6H, BC7, sRGB or arrays, and check that the game or engine supports it.
Comparison
DDS vs PNG, TGA and KTX2
| DDS | PNG | TGA | KTX2 | |
|---|---|---|---|---|
| Purpose | GPU-ready textures (DirectX) | General images | Source art, textures | GPU-ready textures (Vulkan, OpenGL, web) |
| Compression | None or BC1–BC7 (lossy) | Lossless | None or RLE (lossless) | Block compression, optionally supercompressed |
| Mipmaps, cube maps, arrays | Yes | No | No | Yes |
| Decoded by the GPU directly | Yes | No | No | Yes |
| Owner | Microsoft | W3C, ISO | Truevision | Khronos Group |
A common workflow keeps the artwork as PSD, TGA or PNG and converts it to DDS as a build step. Editing the DDS itself and saving again compresses an already-compressed image a second time and loses a little more quality each time.
Troubleshooting
Common DDS problems
- The app can't open it. Older tools only understand legacy DXT1 to DXT5 files. BC7, BC6H and anything with the DX10 header need a current version of GIMP, Paint.NET, texconv or NVIDIA's tools. Windows' built-in imaging component only decodes BC1 to BC3.
- It's upside down. DirectX treats the top row as the first row; some OpenGL-based tools and engines expect the bottom row first. GIMP's DDS export has a "Flip image vertically" option.
- A normal map looks red and green, not blue-purple. BC5 stores only two channels (X and Y); the third is calculated by the shader. That's normal for the file.
- Transparent areas are black, or edges have dark fringes. The alpha mode doesn't match: premultiplied versus straight alpha, or a BC1 file where alpha was expected.
- Colours are too dark or too light in the game. An sRGB texture was saved as linear, or the other way round. Match the format to what the engine expects (
_SRGBformats for colour textures in most engines). - Blocky or banded areas. BC1 artefacts, especially on gradients. Use BC7 for colour textures when the target hardware supports it.
- A mod texture crashes the game or shows noise. Mismatched format, size or mipmap count. Save it in the same format and size as the original texture, with mipmaps if the original had them.
How to
How to open, edit and convert a DDS file
- GIMP (Windows, macOS, Linux) has opened and saved DDS since version 2.10.10. Export offers BC1 to BC5 and BC7, mipmaps, cube maps, volume maps and texture arrays.
- Paint.NET (Windows) opens and saves DDS files.
- Visual Studio's Image Editor opens DDS files, shows their mipmap levels and can generate mipmaps.
- NVIDIA Texture Tools Exporter (Windows, NVIDIA GPU) is a standalone app and a Photoshop plug-in that reads and writes DDS with BC1 to BC7. Photoshop has no DDS support of its own.
- texconv, part of Microsoft's open-source DirectXTex, converts on the command line on Windows.
# PNG to BC7 DDS with a full mip chain (writes texture.dds)
texconv -f BC7_UNORM -m 0 texture.png
# all PNGs in a folder: sRGB in and out, DX10 header, overwrite
texconv -f BC7_UNORM -m 0 -dx10 -srgb -y -o C:\out textures\*.png
# DDS back to PNG
texconv -ft png texture.ddsTo check what's in a file, OpenImageIO's oiiotool --info -v texture.dds prints the size, channels and compression. A DDS file is plain image data with no scripts; with game mods, the real risk is in executable files that come with them, not in the textures.
Sample files
There are no sample DDS files on this page yet. To make one for testing, export an image from GIMP and choose a compression such as BC1 or BC7, or on Windows run texconv -f BC1_UNORM input.png with Microsoft's DirectXTex tools.
Put it online
Have a DDS file? Give it a link.
Drop a DDS texture on 99helpers and it gets its own web address. Browsers can't display DDS, so anyone who opens the link downloads the file, ready for a game, an engine or a texture tool.
Questions
DDS files, frequently asked
What is a DDS file?
A DirectDraw Surface: Microsoft's texture format for DirectX. It stores images the way a graphics card uses them, usually block-compressed and with mipmaps, and is used by many PC games.
How do I open a DDS file?
Use GIMP or Paint.NET, both free, or Visual Studio's Image Editor. Photoshop needs NVIDIA's Texture Tools Exporter plug-in. Browsers and most photo viewers can't display DDS.
How do I convert DDS to PNG?
Open it in GIMP or Paint.NET and export as PNG, or run texconv -ft png texture.dds on Windows. The result looks the same, but block-compression artefacts in the DDS stay in the PNG.
Which compression should I use: BC1, BC3 or BC7?
BC1 for opaque colour textures where size matters most, BC3 for soft transparency on older targets, BC7 for the best quality colour or alpha on DirectX 11-class hardware, BC5 for normal maps and BC4 for single-channel masks.
Why is my DDS texture upside down?
DirectX and OpenGL disagree about which row comes first. Flip it vertically on export (GIMP has an option for it) or in the engine's import settings.
What are mipmaps?
Smaller copies of a texture, each half the size of the previous one, down to 1 × 1. The GPU uses them for distant surfaces, which avoids shimmering. They add about a third to the file size.
Is DDS lossless?
Uncompressed DDS is. The BC formats are lossy: they approximate each 4 × 4 block. Keep a lossless master (PNG, TGA or PSD) and convert to DDS last.
Related formats
Other file types explained
Keep going
Related
Sources
- Microsoft Learn: Programming Guide for DDS
- Microsoft Learn: DDS_HEADER structure
- Microsoft Learn: DDS_HEADER_DXT10 structure
- Microsoft Learn: Texture block compression in Direct3D 11
- Microsoft Learn: Block compression (Direct3D 10)
- Wikipedia: DirectDraw Surface
- DirectXTex wiki: Texconv
Last reviewed 27 October 2026.