HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

BLP Format

11-01-2008, 11:28 AM#1
cohadar
This is an attempt to finally and properly document BLP image format used in warcraft 3.

For that purpose I extracted headers of all blp images I found in war3.mpq and war3x.mpq
Current patch version is v1.22

Zipped text file with this info is attached,
here is a sample of what it looks like:
Collapse JASS:
============================================================
Abilities/Spells/Demon/DarkPortal/DemonRune1backup.blp
magicMarker = BLP1
compression = 0
flags = 0
width = 128
height = 128
pictureType = 5.1
============================================================
Abilities/Spells/Human/AerialShackles/ensnare.blp
magicMarker = BLP1
compression = 0
flags = 8
width = 64
height = 128
pictureType = 3.1
============================================================
Abilities/Spells/Human/Banish/GenericGlow2bA.blp
magicMarker = BLP1
compression = 0
flags = 8
width = 128
height = 128
pictureType = 4.1

This is what we currently know about BLP:
Hidden information:

Collapse JASS:
//+-----------------------------------------------------------------------------
//| Info
//+-----------------------------------------------------------------------------
The BLP file format!
Compiled by Magnus Ostberg (aka Magos)
[email]MagosXGMail.com[/email]


//+-----------------------------------------------------------------------------
//| Data types
//+-----------------------------------------------------------------------------
CHAR   - 8bit character
BYTE   - 8bit unsigned integer
WORD   - 16bit unsigned integer
DWORD  - 32bit unsigned integer
FLOAT  - 32bit floating point number
COLOR  - 32bit color value of type RGBA, one byte per channel
X[n]   - An n-dimensional vector of type X


//+-----------------------------------------------------------------------------
//| Descriptions
//+-----------------------------------------------------------------------------
[X | Y];      - Exactly one of the structures X and Y are present.

X;            - A structure that must be present.

X            - A flag value, more than one can be combined.


//+-----------------------------------------------------------------------------
//| Notes
//+-----------------------------------------------------------------------------
- A full mipmap chain must be present. The last mipmap must be 1x1 (no larger).
  If an image is 32x8 the mipmap chain must be 32x8, 16x4, 8x2, 4x1, 2x1, 1x1.
  Sizes not of powers of 2 seems to work fine too, the same rules for mipmaps
  still applies. Ex: 24x17, 12x8 (rounded down), 6x4, 3x2, 1x1 (rounded down).


//+-----------------------------------------------------------------------------
//| BLP structure
//+-----------------------------------------------------------------------------
struct Blp

  DWORD 'BLP1';
  DWORD Compression;                   //0 - Uses JPEG compression
                                       //1 - Uses palettes (uncompressed)
  DWORD Flags;                         //#8 - Uses alpha channel (?)
  DWORD Width;
  DWORD Height;
  DWORD PictureType;                   //3 - Uncompressed index list + alpha list
                                       //4 - Uncompressed index list + alpha list
                                       //5 - Uncompressed index list
  DWORD PictureSubType;                //1 - ???
  DWORD MipMapOffset[16];
  DWORD MipMapSize[16];

  [BlpJpeg | BlpUncompressed1 | BlpUncompressed2]
;


//+-----------------------------------------------------------------------------
//| BLP JPEG structure (Compression == 0)
//+-----------------------------------------------------------------------------
struct BlpJpeg

  DWORD JpegHeaderSize;

  BYTE[JpegHeaderSize] JpegHeader;

  struct MipMap[16]
  {
    BYTE[???] JpegData;
  };

  // Up to 16 mipmaps can be stored in a blp image. 2^16 = 65536, so there's
  // little risk it won't be enough. Each JPEG (JFIF to be more exact) image
  // is constructed by merging the header with the mipmap (all mipmaps uses
  // the same header. It seems like Warcraft 3 can handle JPEG header sizes
  // of 0 (in case you have trouble generating JPEG images using the same
  // header) however there are other fan tools that does not. Specifying a
  // low number like 4 will work too as the only shared data are the initial
  // JPEG markers.
  //
  // Each mipmap has a certain size and is located at  a certain offset as
  // specified in the main blp header. There can be (and sometimes are in
  // Blizzard's images) unused space between the JPEG header and the JPEG
  // data. Why this is I don't know!
  //
  // The JPEG header of Blizzard's images is usually 624 bytes long. This
  // may or may not be true for your own generated images depending on how
  // you generated them.
  //
  // The JPEG format is advanced so I won't go into detail here.
;


//+-----------------------------------------------------------------------------
//| BLP Uncompressed 1 structure (Compression == 1, PictureType == 3 or 4)
//+-----------------------------------------------------------------------------
struct BlpUncompressed1

  COLOR[256] Palette;

  struct MipMap[16]
  {
    BYTE IndexList[CurrentWidth * CurrentHeight];
    BYTE AlphaList[CurrentWidth * CurrentHeight];
  };

  // CurrentWidth/CurrentHeight is the width/height for the current mipmap.
  // Mipmap size/offset works the same as explained for JPEGs above.
  //
  // Each cell in the index list refers to a location in the palette where
  // the corresponding RGB value is (the palette is still RGBA, but A is not
  // used). The alpha list contains the alpha value for the pixel.
;


//+-----------------------------------------------------------------------------
//| BLP Uncompressed 2 structure (Compression == 1, PictureType == 5)
//+-----------------------------------------------------------------------------
struct BlpUncompressed2

  COLOR[256] Palette;

  struct MipMap[16]
  {
    BYTE IndexList[CurrentWidth * CurrentHeight];
  };

  // CurrentWidth/CurrentHeight is the width/height for the current mipmap.
  // Mipmap size/offset works the same as explained for JPEGs above.
  //
  // Each cell in the index list refers to a location in the palette where
  // the corresponding RGBA value is. The alpha value is inversed so the real
  // alpha is "255 - alpha".
;


Here is some statistics I extracted from BLP headers:
Collapse JASS:
All BLPs in warcraft 3 FT are BLP1  (RoC used BLP0, WoW uses BLP2)

There is a total of 6266 BLP images in current version of warcraft 3

There are 2 main compression types:
compression = 0  - jpeg- used by 4917 images
compression = 1  - paletted- used by 1349 images

There are 2 flag values:
flags = 0  -noalpha- 3874
flags = 8  -alpha- 2392

There are 7 picture types:
pictureType = 2.1  - 392
pictureType = 3.0  - 123
pictureType = 3.1  - 245
pictureType = 4.0  - 92
pictureType = 4.1  - 1905
pictureType = 5.0  - 46
pictureType = 5.1  - 3463

Things we do not know:
* What do format types 2, 3, 4, 5 mean if you are using jpeg compression?
* What do format subtypes .0 and .1 mean?
* How is player color coded in images?
Attached Files
File type: 7zBLPZ.7z (39.6 KB)
11-03-2008, 06:48 PM#2
cohadar
After directly extracting jpeg images from BLP files I found out that:
1. Red and Blue colors are swapped.
2. Jpeg compression type is so old (2001) it is not supported in java ImageIO
3. Using new jpeg compression inside BLP works but fucksup colors. (even when using BGR instead of RGB)
11-03-2008, 07:08 PM#3
Vexorian
hmnn

I am not sure if this should got to resources or tutorials.

Or merged with the specs thing we have.
11-03-2008, 07:50 PM#4
cohadar
I was actually hoping someone would take a more detailed look at this and fill in the missing details.

For example I am fairly sure some artists around here know how Player colors are working in skins.
11-04-2008, 12:37 AM#5
Vexorian
That's just the alpha channel, in some geosets, alpha means transparency (or lack of), in other geosets it means [put team color here] Just t saying that is not part of the BLP format.
11-04-2008, 12:57 AM#6
AnemicRoyalty
Team Colour is a separate texture on a different material layer, so the alpha on the skin layer is just about the blending mode.
None - solid,
Transparent - hard edge transparency for alpha'd areas - think the DH's blades
Blend - smooth transparency for alpha used for TC mostly but looks bizarre if there's no texture underneath
Additive - makes the entire texture semitransparent and drops out the black
Additive Alpha - makes the entire texture semitransparent and drops out the alphaed areas and the black.
Modulate - inverse of Additive, drops out the white areas, keeping the black.
11-04-2008, 06:11 AM#7
Rising_Dusk
By definition, a compendium of knowledge is a dish best served as a tutorial (Similar to the WC3 ability guide and such). Keep working on this, I'd love to see it finished to your and Vex's liking -- It'd be very useful.

Moved, in any case.
11-04-2008, 10:24 AM#8
Tide-Arc Ephemera
I'm just curious, but is this legal? 'Cause I thought that BLP was kinda property of Blizzard.
11-04-2008, 10:27 AM#9
cohadar
Quote:
Originally Posted by AnemicRoyalty
Team Colour is a separate texture on a different material layer, so the alpha on the skin layer is just about the blending mode.
None - solid,
Transparent - hard edge transparency for alpha'd areas - think the DH's blades
Blend - smooth transparency for alpha used for TC mostly but looks bizarre if there's no texture underneath
Additive - makes the entire texture semitransparent and drops out the black
Additive Alpha - makes the entire texture semitransparent and drops out the alphaed areas and the black.
Modulate - inverse of Additive, drops out the white areas, keeping the black.

This is great.
Can you maybe give me specific examples of standard BLPs that use each format?
Than I could search them in the list above and see what compression types they are using and fill in the missing details.

Is Team-Color monochrome texture?
11-04-2008, 01:24 PM#10
Spec
Interesting, I'd try to help with this.
- Jpeg is compressed in RGBA colorspace or JCS_UNKNOWN (that's why colors shown swapped). Such jpegs can be handled with jpeg lib by Independent Jpeg Group.
- I've heard somewhere, that picture subtype affects only model textures (if 0 - team colors won't show up).
Never heard about /2/ picture type, going to test it.
11-04-2008, 02:37 PM#11
Vexorian
Quote:
Originally Posted by Tide-Arc Ephemera
I'm just curious, but is this legal? 'Cause I thought that BLP was kinda property of Blizzard.
It's not legal, the EULA forbids reverse engineering, but we chose long ago to blatantly ignore that part of the EULA.
11-06-2008, 10:16 PM#12
AnemicRoyalty
Quote:
Originally Posted by cohadar
This is great.
Can you maybe give me specific examples of standard BLPs that use each format?
Than I could search them in the list above and see what compression types they are using and fill in the missing details.

Is Team-Color monochrome texture?

Sorry, but it's a bit less elegant than that.

The blending mode is information stored in the material of the model, not the
texture. Team colour uses a placeholder (Replaceable ID 1, Replaceable ID 2
for glows) which the game then interprets based on information for the in-
game unit (which player it appears to be owned by) and substitutes one of
the glow or solid team colour textures.

There are 16 different team colours and glows (although the last 4 are just
black). These are separate textures that can be found in the .mpq under
ReplaceableTextures\TeamColor and ReplaceableTextures\TeamGlow.
12-05-2008, 12:48 PM#13
PitzerMike
I strongly feel this would be better suited in the Programming forum, so that people looking for this information will actually find it.
I'll sticky it there and also link to it from the "Inside the w3m/w3x" thread.
12-05-2008, 08:49 PM#14
akolyt0r
Quote:
Originally Posted by Vexorian
It's not legal, the EULA forbids reverse engineering, but we chose long ago to blatantly ignore that part of the EULA.

At least in Germany Reverse Engineering is allowed - even if EULAs tell different
Of course you may not directly use code you got trough this ...but you may reverse engineer programs to look at the code and learn stuff....what is directly what this thread is about ...huh?!
08-20-2009, 06:04 AM#15
Earth-Fury
Quote:
Originally Posted by cohadar
2. Jpeg compression type is so old (2001) it is not supported in java ImageIO

At least some of the JPEGs (CorruptedAncientOfWar, BTNArnk) are compatible with the JPEG reader that comes with the JRE. Colours are still fucked, however.

The BLPs exported by War3Viewer are not compatible with the default reader, however they are compatible with the Java Advanced Imaging JPEG reader. (https://jai-imageio.dev.java.net/) Again, colours still seem to be fucked.

My work continues on an ImageIO reader for BLP1s... (I'll release what I have under zlib if/when i finish it. If I don't finish it, I'll still release it under zlib if anyone cares enough to bother me to.)