How does bitcoind store blocks? I want to parse blockchain manually and extract the UTXO set (for various reasons). Is there any way to understand how the blocks are stored without going through the C++ code? 

Some specs will be great.
There is a lot of information available, just not consolidated. After searching for sometime, I found the best answer from this link.

The format of each file is:

4 bytes: Magic bytes
4 bytes: Encodes size N of next upcoming block.
N bytes: Block encoded in standard format (with header)
--
above repeats


Quotes from the original link:

4 | 4 | 80 | TxData | 4 | 4 | 80 | TxData | 4 | 4 | 80 | TxData | ...



First 4 bytes: magic bytes (identifying which network you are on)
Second 4 bytes: the number of bytes of the remaining block
Next 80 bytes: block header itself
Next NumBlockBytes - 80 bytes: Transaction data in this block [ numTx | Tx1 | Tx2 | Tx3 | ... ]


What I don't understand is why are the magic bytes repeated? We could very well have used:

4 | 4 | 80 | TxData | 4 | 80 | TxData | 4 | 80 | TxData | ...