7z Format description (2.30 Beta 25)
-----------------------------------

This file contains description of 7z archive format. 
7z archive can contain files compressed with any method.
See "Methods.txt" for description for defined compressing methods.


Format structure Overview
-------------------------

Some fields can be optional.

Archive structure
~~~~~~~~~~~~~~~~~  
SignatureHeader
[PackedStreams]
[PackedStreamsForHeaders]
[
  Header 
  or 
  {
    Packed Header
    HeaderInfo
  }
]



Header structure
~~~~~~~~~~~~~~~~  
{
  ArchiveProperties
  AdditionalStreams
  {
    PackInfo
    {
      PackPos
      NumPackStreams
      Sizes[NumPackStreams]
      CRCs[NumPackStreams]
    }
    CodersInfo
    {
      NumFolders
      Folders[NumFolders]
      {
        NumCoders
        CodersInfo[NumCoders]
        {
          ID
          NumInStreams;
          NumOutStreams;
          PropertiesSize
          Properties[PropertiesSize]
        }
        NumBindPairs
        BindPairsInfo[NumBindPairs]
        {
          InIndex;
          OutIndex;
        }
        PackedIndices
      }
      UnPackSize[Folders][Folders.NumOutstreams]
      CRCs[NumFolders]
    }
    SubStreamsInfo
    {
      NumUnPackStreamsInFolders[NumFolders];
      UnPackSizes[]
      CRCs[]
    }
  }
  MainStreamsInfo
  {
    (Same as in AdditionalStreams)
  }
  FilesInfo
  {
    NumFiles
    Properties[]
    {
      ID
      Size
      Data
    }
  }
}

HeaderInfo structure
~~~~~~~~~~~~~~~~~~~~
{
  (Same as in AdditionalStreams)
}



Notes about Notation and encoding
---------------------------------

7z uses little endian encoding.

7z archive format has optional headers that are marked as
[]
Header
[]

REAL_UINT64 means real UINT64.

UINT64 means real UINT64 encoded with the following scheme:

  Size of encoding sequence depends from first byte:
  First_Byte  Extra_Bytes        Value
  (binary)   
  0xxxxxxx               : ( xxxxxxx           )
  10xxxxxx    BYTE y[1]  : (  xxxxxx << (8 * 1)) + y
  110xxxxx    BYTE y[2]  : (   xxxxx << (8 * 2)) + y
  ...
  1111110x    BYTE y[6]  : (       x << (8 * 6)) + y
  11111110    BYTE y[7]  :                         y
  11111111    BYTE y[8]  :                         y



Property IDs
------------

0x00 = kEnd,

0x01 = kHeader,

0x02 = kArchiveProperties,
    
0x03 = kAdditionalStreamsInfo,
0x04 = kMainStreamsInfo,
0x05 = kFilesInfo,
    
0x06 = kPackInfo,
0x07 = kUnPackInfo,
0x08 = kSubStreamsInfo,

0x09 = kSize,
0x0A = kCRC,

0x0B = kFolder,

0x0C = kCodersUnPackSize,
0x0D = kNumUnPackStream,

0x0E = kEmptyStream,
0x0F = kEmptyFile,
0x10 = kAnti,

0x11 = kName,
0x12 = kCreationTime,
0x13 = kLastAccessTime,
0x14 = kLastWriteTime,
0x15 = kWinAttributes,
0x16 = kComment,

0x17 = kEncodedHeader,


7z format headers
-----------------

SignatureHeader
~~~~~~~~~~~~~~~
  BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};

  ArchiveVersion
  {
    BYTE Major;   // now = 0
    BYTE Minor;   // now = 2
  };

  UINT32 StartHeaderCRC;

  StartHeader
  {
    REAL_UINT64 NextHeaderOffset
    REAL_UINT64 NextHeaderSize
    UINT32 NextHeaderCRC
  }


...........................


ArchiveProperties
~~~~~~~~~~~~~~~~~
BYTE NID::kArchiveProperties (0x02)
for (;;)
{
  BYTE PropertyType;
  if (aType == 0)
    break;
  UINT64 PropertySize;
  BYTE PropertyData[PropertySize];
}


Digests (NumStreams)
~~~~~~~~~~~~~~~~~~~~~
  BYTE AllAreDefined
  if (AllAreDefined == 0)
  {
    for(NumStreams)
      BIT Defined
  }
  UINT32 CRCs[NumDefined]


PackInfo
~~~~~~~~~~~~
  BYTE NID::kPackInfo  (0x06)
  UINT64 PackPos
  UINT64 NumPackStreams

  []
  BYTE NID::kSize    (0x09)
  UINT64 PackSizes[NumPackStreams]
  []

  []
  BYTE NID::kCRC      (0x0A)
  PackStreamDigests[NumPackStreams]
  []

  BYTE NID::kEnd


Folder
~~~~~~
  UINT64 NumCoders;
  for (NumCoders)
  {
    BYTE 
    {
      0:3 DecompressionMethod.IDSize
      4:
        0 - IsSimple
        1 - Is not simple
      5:
        0 - No Attributes
        1 - There Are Attributes
      7:
        0 - Last Method in Alternative_Method_List
        1 - There are more alternative methods
    } 
    BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
    if (!IsSimple)
    {
      UINT64 NumInStreams;
      UINT64 NumOutStreams;
    }
    if (DecompressionMethod[0] != 0)
    {
      UINT64 PropertiesSize
      BYTE Properties[PropertiesSize]
    }
  }
    
  NumBindPairs = NumOutStreamsTotal - 1;

  for (NumBindPairs)
  {
    UINT64 InIndex;
    UINT64 OutIndex;
  }

  NumPackedStreams = NumInStreamsTotal - NumBindPairs;
  if (NumPackedStreams > 1)
    for(NumPackedStreams)
    {
      UINT64 Index;
    };




Coders Info
~~~~~~~~~~~

  BYTE NID::kUnPackInfo  (0x07)


  BYTE NID::kFolder  (0x0B)
  UINT64 NumFolders
  BYTE External
  switch(External)
  {
    case 0:
      Folders[NumFolders]
    case 1:
      UINT64 DataStreamIndex
  }


  BYTE ID::kCodersUnPackSize  (0x0C)
  for(Folders)
    for(Folder.NumOutStreams)
     UINT64 UnPackSize;


  []
  BYTE NID::kCRC   (0x0A)
  UnPackDigests[NumFolders]
  []

  

  BYTE NID::kEnd



SubStreams Info
~~~~~~~~~~~~~~
  BYTE NID::kSubStreamsInfo; (0x08)

  []
  BYTE NID::kNumUnPackStream; (0x0D)
  UINT64 NumUnPackStreamsInFolders[NumFolders];
  []


  []
  BYTE NID::kSize  (0x09)
  UINT64 UnPackSizes[]
  []


  []
  BYTE NID::kCRC  (0x0A)
  Digests[Number of streams with unknown CRC]
  []

  
  BYTE NID::kEnd


Streams Info
~~~~~~~~~~~~

  []
  PackInfo
  []


  []
  CodersInfo
  []


  []
  SubStreamsInfo
  []

  BYTE NID::kEnd


FilesInfo
~~~~~~~~~
  BYTE NID::kFilesInfo;  (0x05)
  UINT64 NumFiles

  for (;;)
  {
    BYTE PropertyType;
    if (aType == 0)
      break;

    UINT64 Size;

    switch(PropertyType)
    {
      kEmptyStream:   (0x0E)
        for(NumFiles)
          BIT IsEmptyStream

      kEmptyFile:     (0x0F)
        for(EmptyStreams)
          BIT IsEmptyFile

      kAnti:          (0x10)
        for(EmptyStreams)
          BIT IsAntiFile
      
      case kCreationTime:   (0x12)
      case kLastAccessTime: (0x13)
      case kLastWriteTime:  (0x14)
        BYTE AllAreDefined
        if (AllAreDefined == 0)
        {
          for(NumFiles)
            BIT TimeDefined
        }
        BYTE External;
        if(External != 0)
          UINT64 DataIndex
        []
        for(Definded Items)
          UINT32 Time
        []
      
      kNames:     (0x11)
        BYTE External;
        if(External != 0)
          UINT64 DataIndex
        []
        for(Files)
        {
          wchar_t Names[NameSize];
          wchar_t 0;
        }
        []

      kAttributes:  (0x15)
        BYTE AllAreDefined
        if (AllAreDefined == 0)
        {
          for(NumFiles)
            BIT AttributesAreDefined
        }
        BYTE External;
        if(External != 0)
          UINT64 DataIndex
        []
        for(Definded Attributes)
          UINT32 Attributes
        []
    }
  }


Header
~~~~~~
  BYTE NID::kHeader (0x01)

  []
  ArchiveProperties
  []

  []
  BYTE NID::kAdditionalStreamsInfo; (0x03)
  StreamsInfo
  []

  []
  BYTE NID::kMainStreamsInfo;    (0x04)
  StreamsInfo
  []

  []
  FilesInfo
  []

  BYTE NID::kEnd


HeaderInfo
~~~~~~~~~~
  []
  BYTE NID::kEncodedHeader; (0x17)
  StreamsInfo for Encoded Header
  []


---
End of document
