Gildor's Forums

Author Topic: Blade and Soul Texture2D Compression  (Read 4280 times)
stricq
Newbie
*
Posts: 5



View Profile
Blade and Soul Texture2D Compression
« on: January 27, 2016, 10:49 »

I'm working on a program to export textures from Bns.  I have found that the textures are compressed.  After looking through the data I can see the data structures are ALMOST identical to the full package compression data structures.

1. What are the three ints after the last property?
2. Why is the UncompressedOffset always 0x00000100?
3. It looks like the CompressedSize and CompressedOffset are swapped in the CompressedChunk data (as opposed to the full package compression), correct?
4. What are the two ints after each block of compressed data?
5. What are the 16 bytes at the end of the object's data, looks like a GUID?

Here is what I have so far:

After last property:

uint x3 of unknown, usually 0x00000000

uint CompressedChunk array offset

uint 0x00000005 CompressedChunk array length

--------------------------------- First Compressed Chunk ---------------------------------

uint 0x00000100 CompressedChunk.UncompressedOffset (what is this really?)

uint 0x00000080 CompressedChunk.UncompressedSize

uint 0x00000024 CompressedChunk.CompressedSize (swapped with offset)

uint CompressedChunk.CompressedOffset to ChunkHeader (swapped with size)

--------------------------- Compressed Chunk Header -------------------------------

uint 0x9e2a83c1 ChunkHeader.Signature

uint 0x00020000 ChunkHeader.BlockSize

uint 0x0000000c ChunkHeader.CompressedSize

uint 0x00000080 ChunkHeader.UncompressedSize

-------------------------- Block 1 of 1 (looks like always 1 Block) ---------------------------------------

uint 0x0000000c Block.CompressedSize

uint 0x00000080 Block.UncompressedSize

Block.CompressedSize bytes of data

---------------------------- End of First Compressed Chunk --------------------------

uint x2 of Unknown after every Compressed Chunk

16 bytes of data, possible GUID

Thanks for the help, your forums were instrumental in understanding the package compression.
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7973



View Profile WWW
Re: Blade and Soul Texture2D Compression
« Reply #1 on: January 27, 2016, 12:36 »

1. I'd recommend you to check all threads in "Unreal coding". In particular - http://www.gildor.org/smf/index.php/topic,297.0.html
2. UModel's source code is available on GitHub, you may find some answers by yourself.

What's the goal of your texture extraction program over UModel? Learning?
Logged
stricq
Newbie
*
Posts: 5



View Profile
Re: Blade and Soul Texture2D Compression
« Reply #2 on: January 27, 2016, 19:06 »

I've read that thread and it was very useful, and I've looked through the source on GitHub.  I think I figured that the textures falls under the bulk data compression and that the Uncompressed Offset value is actually the bulk data flags.  But I still haven't figured out what the 3 ints are after the properties and the 2 ints after each compressed chunk.

Even just a pointer into the correct source file would be helpful.

Thanks.
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7973



View Profile WWW
Re: Blade and Soul Texture2D Compression
« Reply #3 on: January 27, 2016, 22:23 »

You should use structure names if you want to get help. What are "properties" in your previous message?

All source code relative to bulk serialization exists in UnCoreSerialize.cpp. Entry point for bulk serialization is FByteBulkData::Serialize(). It serializes header, and in a case of inline data - data itself. Data could exists in a different place - in the same file or in a different file. Bulk header knows nothing about name of "different file", so FByteBulkData::SerializeData could be called with different FArchive. Example of use - UTexture2D::LoadBulkTexture, it loads texture data from package or from tfc.
Logged
stricq
Newbie
*
Posts: 5



View Profile
Re: Blade and Soul Texture2D Compression
« Reply #4 on: January 29, 2016, 07:42 »

The properties as named in the name table: IntProperty, StrProperty, ByteProperty, etc.

I still don't know what the 3 ints after the properties are but I think I know what the two ints after each block of compressed data are.  ... Ah, I got it, it's the width and height of each subsequent Mipmap level.

I any case I have the decompressed data I would like to be able write that out as a DDS file.  But here I have no clue how to do this, ever after reading your code.
« Last Edit: January 29, 2016, 09:44 by stricq » Logged
Gildor
Administrator
Hero Member
*****
Posts: 7973



View Profile WWW
Re: Blade and Soul Texture2D Compression
« Reply #5 on: January 30, 2016, 00:02 »

I'm unsure what you mean, so I'll point you at UModel's code. Properties are serialized from UObject::Serialize. This function is called (indirectly) from UTexture2D::Serialize.

This is a layout of UTexture2D for UE3:
1. Properties (UObject::Serialize)
2. SourceArt bulk (UTexture3::Serialize)
3. Mipmaps (UTexture2D::Serialize)
4. Probably other fields.
Logged
stricq
Newbie
*
Posts: 5



View Profile
Re: Blade and Soul Texture2D Compression
« Reply #6 on: February 05, 2016, 09:25 »

For this flag on a mipmap of a Texture2D:

BULKDATA_StoreInSeparateFile   0x01

Is there any way to tell what the other file is?  Or is it just a matter of looking through all the files for an object of the same name?
Logged
Gildor
Administrator
Hero Member
*****
Posts: 7973



View Profile WWW
Re: Blade and Soul Texture2D Compression
« Reply #7 on: February 05, 2016, 13:41 »

Without this flag, bulk data usually follows the bulk header. With it, data stored in a different file. The file information is located in UTextre2D object. Look at UTexture2D::GetTextureData() code for more info.
Logged
Jump to:  

Powered by SMF | SMF © 2006-2009, Simple Machines LLC
Leviathan design by Bloc | XHTML | CSS