Handmade Hero»Episode Guide
Parsing ZLIB Headers
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:00Welcome to the stream
🗩
0:00Welcome to the stream
🗩
0:00Welcome to the stream
🗩
0:21Recap and set the stage for parsing PNG IDAT data
🗩
0:21Recap and set the stage for parsing PNG IDAT data
🗩
0:21Recap and set the stage for parsing PNG IDAT data
🗩
1:18Run the program to look at our IDAT chunks
🏃
1:18Run the program to look at our IDAT chunks
🏃
1:18Run the program to look at our IDAT chunks
🏃
3:58Set up to parse IDAT chunks1
📖
3:58Set up to parse IDAT chunks1
📖
3:58Set up to parse IDAT chunks1
📖
6:44Prepare ReadEntireFile() and ConsumeSize() to read the .png file into a linked list of streaming_chunks
6:44Prepare ReadEntireFile() and ConsumeSize() to read the .png file into a linked list of streaming_chunks
6:44Prepare ReadEntireFile() and ConsumeSize() to read the .png file into a linked list of streaming_chunks
13:38Run it to see that it works
🏃
13:38Run it to see that it works
🏃
13:38Run it to see that it works
🏃
13:39Enable ParsePNG() to build up a linked list of IDAT chunks, introducing AllocateChunk()
13:39Enable ParsePNG() to build up a linked list of IDAT chunks, introducing AllocateChunk()
13:39Enable ParsePNG() to build up a linked list of IDAT chunks, introducing AllocateChunk()
19:09Describe this obtuse, single-expression singly linked list append
📖
19:09Describe this obtuse, single-expression singly linked list append
📖
19:09Describe this obtuse, single-expression singly linked list append
📖
20:11Enable ParsePNG() to parse the IDATHeader
20:11Enable ParsePNG() to parse the IDATHeader
20:11Enable ParsePNG() to parse the IDATHeader
21:19Run it to see our decompressed IDAT chunks
🏃
21:19Run it to see our decompressed IDAT chunks
🏃
21:19Run it to see our decompressed IDAT chunks
🏃
21:30Make ParsePNG() print the IDAT chunk sizes
21:30Make ParsePNG() print the IDAT chunk sizes
21:30Make ParsePNG() print the IDAT chunk sizes
21:45Run it see the sizes of the IDAT chunks and determine that GIMP is outputting in 8192-byte chunks
🏃
21:45Run it see the sizes of the IDAT chunks and determine that GIMP is outputting in 8192-byte chunks
🏃
21:45Run it see the sizes of the IDAT chunks and determine that GIMP is outputting in 8192-byte chunks
🏃
23:30Consult the PNG2 and ZLIB specs3 to understand what we need to support
📖
23:30Consult the PNG2 and ZLIB specs3 to understand what we need to support
📖
23:30Consult the PNG2 and ZLIB specs3 to understand what we need to support
📖
25:19Further condense ParsePNG() to support compression method 8 (DEFLATE) and no preset dictionary
25:19Further condense ParsePNG() to support compression method 8 (DEFLATE) and no preset dictionary
25:19Further condense ParsePNG() to support compression method 8 (DEFLATE) and no preset dictionary
26:21Run it to see our "Supported" message
🏃
26:21Run it to see our "Supported" message
🏃
26:21Run it to see our "Supported" message
🏃
26:27Begin to make ParsePNG() decompress the IDAT data using DEFLATE4
26:27Begin to make ParsePNG() decompress the IDAT data using DEFLATE4
26:27Begin to make ParsePNG() decompress the IDAT data using DEFLATE4
35:19LZ-Style Compressors
🖌
35:19LZ-Style Compressors
🖌
35:19LZ-Style Compressors
🖌
40:55Run-Length Encoding as LZ Mode 2
🖌
40:55Run-Length Encoding as LZ Mode 2
🖌
40:55Run-Length Encoding as LZ Mode 2
🖌
44:45Enable ParsePNG() to LZ-decompress the IDAT data5
44:45Enable ParsePNG() to LZ-decompress the IDAT data5
44:45Enable ParsePNG() to LZ-decompress the IDAT data5
49:37Read about non-compressed and compressed blocks, including Huffman codes, in the DEFLATE spec6
📖
49:37Read about non-compressed and compressed blocks, including Huffman codes, in the DEFLATE spec6
📖
49:37Read about non-compressed and compressed blocks, including Huffman codes, in the DEFLATE spec6
📖
57:56Implement ConsumeBits() and FlushByte() and enable ParsePNG() to parse BTYPE 00 chunks7
57:56Implement ConsumeBits() and FlushByte() and enable ParsePNG() to parse BTYPE 00 chunks7
57:56Implement ConsumeBits() and FlushByte() and enable ParsePNG() to parse BTYPE 00 chunks7
1:09:13Step through ParsePNG() to see our consumed bits
🏃
1:09:13Step through ParsePNG() to see our consumed bits
🏃
1:09:13Step through ParsePNG() to see our consumed bits
🏃
1:10:36Read about dynamic Huffman codes (BTYPE 10)8
📖
1:10:36Read about dynamic Huffman codes (BTYPE 10)8
📖
1:10:36Read about dynamic Huffman codes (BTYPE 10)8
📖
1:13:13Enable ParsePNG() to handle dynamic Huffman coded (BTYPE 10) chunks9
1:13:13Enable ParsePNG() to handle dynamic Huffman coded (BTYPE 10) chunks9
1:13:13Enable ParsePNG() to handle dynamic Huffman coded (BTYPE 10) chunks9
1:32:44Step through ParsePNG() to inspect our HLIT, HDIST and HCLEN, and realise that the code lengths are swizzled from most to least likely
🏃
1:32:44Step through ParsePNG() to inspect our HLIT, HDIST and HCLEN, and realise that the code lengths are swizzled from most to least likely
🏃
1:32:44Step through ParsePNG() to inspect our HLIT, HDIST and HCLEN, and realise that the code lengths are swizzled from most to least likely
🏃
1:36:25Set up ParsePNG() to build up our Huffman table, introducing stubs for ComputeHuffman() and HuffmanDecode()10
1:36:25Set up ParsePNG() to build up our Huffman table, introducing stubs for ComputeHuffman() and HuffmanDecode()10
1:36:25Set up ParsePNG() to build up our Huffman table, introducing stubs for ComputeHuffman() and HuffmanDecode()10
1:52:40Q&A
🗩
1:52:40Q&A
🗩
1:52:40Q&A
🗩
1:53:41lorymaster Q: I'm happy you're doing this. I've had problems making my inflate decoder (for fun) working, and you being a spec decoder works out perfectly
🗪
1:53:41lorymaster Q: I'm happy you're doing this. I've had problems making my inflate decoder (for fun) working, and you being a spec decoder works out perfectly
🗪
1:53:41lorymaster Q: I'm happy you're doing this. I've had problems making my inflate decoder (for fun) working, and you being a spec decoder works out perfectly
🗪
1:53:57ratchetfreak Q: I believe the length for the LZ should be interpreted like u32 copy_length = length_table_base[LitLen-257] + ConsumeBits(length_table_extra_bits[LitLen - 257]); And the distance is similar with the other table(s)
🗪
1:53:57ratchetfreak Q: I believe the length for the LZ should be interpreted like u32 copy_length = length_table_base[LitLen-257] + ConsumeBits(length_table_extra_bits[LitLen - 257]); And the distance is similar with the other table(s)
🗪
1:53:57ratchetfreak Q: I believe the length for the LZ should be interpreted like u32 copy_length = length_table_base[LitLen-257] + ConsumeBits(length_table_extra_bits[LitLen - 257]); And the distance is similar with the other table(s)
🗪
1:54:47Brian Q: How have you found the png and zlib specification, compared to other specifications you have read and implemented?
🗪
1:54:47Brian Q: How have you found the png and zlib specification, compared to other specifications you have read and implemented?
🗪
1:54:47Brian Q: How have you found the png and zlib specification, compared to other specifications you have read and implemented?
🗪
1:55:51gg_nate Q: Any way to fix the pink flashing? It was fairly persistent today
🗪
1:55:51gg_nate Q: Any way to fix the pink flashing? It was fairly persistent today
🗪
1:55:51gg_nate Q: Any way to fix the pink flashing? It was fairly persistent today
🗪
1:56:09bigmofo1 Q: Will Yangtian iterate over the art live?
🗪
1:56:09bigmofo1 Q: Will Yangtian iterate over the art live?
🗪
1:56:09bigmofo1 Q: Will Yangtian iterate over the art live?
🗪
1:56:46Brian Q: What do you do when you have an incomplete specification? Is it then more just trial and error, or are there techniques on how to continue?
🗪
1:56:46Brian Q: What do you do when you have an incomplete specification? Is it then more just trial and error, or are there techniques on how to continue?
🗪
1:56:46Brian Q: What do you do when you have an incomplete specification? Is it then more just trial and error, or are there techniques on how to continue?
🗪
1:59:12jim0_o Q: What 4coder version are you using on stream?
🗪
1:59:12jim0_o Q: What 4coder version are you using on stream?
🗪
1:59:12jim0_o Q: What 4coder version are you using on stream?
🗪
1:59:56rationalcoder Q: Just caught up with the stream, but I have had a question for a while: When you come up with a reusable data structure and want to share it between projects / other people, how do you deal with custom allocation? I have been writing some hybrid data structures, and I want to add custom allocation, but adding a template parameter seems like a bad solution to the problem
🗪
1:59:56rationalcoder Q: Just caught up with the stream, but I have had a question for a while: When you come up with a reusable data structure and want to share it between projects / other people, how do you deal with custom allocation? I have been writing some hybrid data structures, and I want to add custom allocation, but adding a template parameter seems like a bad solution to the problem
🗪
1:59:56rationalcoder Q: Just caught up with the stream, but I have had a question for a while: When you come up with a reusable data structure and want to share it between projects / other people, how do you deal with custom allocation? I have been writing some hybrid data structures, and I want to add custom allocation, but adding a template parameter seems like a bad solution to the problem
🗪
2:00:19jim0_o Q: I see it in the *Message* window that you don't get at start up apparently
🗪
2:00:19jim0_o Q: I see it in the *Message* window that you don't get at start up apparently
🗪
2:00:19jim0_o Q: I see it in the *Message* window that you don't get at start up apparently
🗪
2:00:30Custom memory allocation in Granny
🗩
2:00:30Custom memory allocation in Granny
🗩
2:00:30Custom memory allocation in Granny
🗩
2:04:03snovind92 Q: Why does no one spec the simplest solution possible, so people can easily implement the parsers and exporters they need (in cases when space / speed does not matter)?
🗪
2:04:03snovind92 Q: Why does no one spec the simplest solution possible, so people can easily implement the parsers and exporters they need (in cases when space / speed does not matter)?
🗪
2:04:03snovind92 Q: Why does no one spec the simplest solution possible, so people can easily implement the parsers and exporters they need (in cases when space / speed does not matter)?
🗪
2:07:01flyinginthedark Q: Are you going to do audio formats next?
🗪
2:07:01flyinginthedark Q: Are you going to do audio formats next?
🗪
2:07:01flyinginthedark Q: Are you going to do audio formats next?
🗪
2:07:47We're all done
🗩
2:07:47We're all done
🗩
2:07:47We're all done
🗩