Partitioning the PNG Reader for Integration
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next timestamp
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 and Index Controls

a
w
s
d
h j k l


Esc Close menu / unfocus timestamp

Quotes and References Menus and Index

Enter Jump to timestamp

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:00Recap and set the stage for the day working towards putting art into Handmade Hero
🗩
0:00Recap and set the stage for the day working towards putting art into Handmade Hero
🗩
0:00Recap and set the stage for the day working towards putting art into Handmade Hero
🗩
3:08puremouron Is anyone else mesmerised by the bobbing orphan on the web page1
🗪
3:08puremouron Is anyone else mesmerised by the bobbing orphan on the web page1
🗪
3:08puremouron Is anyone else mesmerised by the bobbing orphan on the web page1
🗪
4:53Unpack the new art into a dedicated directory where the artist may dump art
🗹
4:53Unpack the new art into a dedicated directory where the artist may dump art
🗹
4:53Unpack the new art into a dedicated directory where the artist may dump art
🗹
7:13Show off item_template.png and character_template.png
🎨
7:13Show off item_template.png and character_template.png
🎨
7:13Show off item_template.png and character_template.png
🎨
9:20Discover how to switch the default image viewer back to the one that used to be the default
📖
9:20Discover how to switch the default image viewer back to the one that used to be the default
📖
9:20Discover how to switch the default image viewer back to the one that used to be the default
📖
13:08Switch the default image viewer back to Windows Photo viewer2
🗹
13:08Switch the default image viewer back to Windows Photo viewer2
🗹
13:08Switch the default image viewer back to Windows Photo viewer2
🗹
14:28Show off our new art
🎨
14:28Show off our new art
🎨
14:28Show off our new art
🎨
17:26Set up to read our new PNGs
🗹
17:26Set up to read our new PNGs
🗹
17:26Set up to read our new PNGs
🗹
19:02Run our PNG reader on character_hero.png and crash in ConsumeSize()
🏃
19:02Run our PNG reader on character_hero.png and crash in ConsumeSize()
🏃
19:02Run our PNG reader on character_hero.png and crash in ConsumeSize()
🏃
20:58Note in ParsePNG() the need to handle BTYPE0 blocks that straddle IDAT chunk boundaries
20:58Note in ParsePNG() the need to handle BTYPE0 blocks that straddle IDAT chunk boundaries
20:58Note in ParsePNG() the need to handle BTYPE0 blocks that straddle IDAT chunk boundaries
22:52Step through ParsePNG() to see that BFINAL does not get set
🏃
22:52Step through ParsePNG() to see that BFINAL does not get set
🏃
22:52Step through ParsePNG() to see that BFINAL does not get set
🏃
28:28Let it run to completion, writing out our image
🏃
28:28Let it run to completion, writing out our image
🏃
28:28Let it run to completion, writing out our image
🏃
28:55View character_hero.bmp to see that it looks correct but for the alpha channel
🎨
28:55View character_hero.bmp to see that it looks correct but for the alpha channel
🎨
28:55View character_hero.bmp to see that it looks correct but for the alpha channel
🎨
31:10Inspect the Width and Height values, to see that they are as expected
🏃
31:10Inspect the Width and Height values, to see that they are as expected
🏃
31:10Inspect the Width and Height values, to see that they are as expected
🏃
32:25Consult the DEFLATE,3 ZLIB4 and PNG5 specifications for information on BFINAL and chunk processing
📖
32:25Consult the DEFLATE,3 ZLIB4 and PNG5 specifications for information on BFINAL and chunk processing
📖
32:25Consult the DEFLATE,3 ZLIB4 and PNG5 specifications for information on BFINAL and chunk processing
📖
41:52Enable ParsePNG() to break out of its consumption loop once all the expected pixels have been consumed
41:52Enable ParsePNG() to break out of its consumption loop once all the expected pixels have been consumed
41:52Enable ParsePNG() to break out of its consumption loop once all the expected pixels have been consumed
43:19Run it successfully to see that the output looks correct
🏃
43:19Run it successfully to see that the output looks correct
🏃
43:19Run it successfully to see that the output looks correct
🏃
43:52Run it successfully on hand_skeleton.png
🏃
43:52Run it successfully on hand_skeleton.png
🏃
43:52Run it successfully on hand_skeleton.png
🏃
44:17Inspect the output image to see that it looks correct, and wonder if Photoshop's PNG encoder is busted
🎨
44:17Inspect the output image to see that it looks correct, and wonder if Photoshop's PNG encoder is busted
🎨
44:17Inspect the output image to see that it looks correct, and wonder if Photoshop's PNG encoder is busted
🎨
46:55Remove stale code from WriteImageTopDownRGBA() and note in ParsePNG() to figure out why we can't rely on BFINAL being set to 1 on the last chunk of Photoshop-exported PNG files
46:55Remove stale code from WriteImageTopDownRGBA() and note in ParsePNG() to figure out why we can't rely on BFINAL being set to 1 on the last chunk of Photoshop-exported PNG files
46:55Remove stale code from WriteImageTopDownRGBA() and note in ParsePNG() to figure out why we can't rely on BFINAL being set to 1 on the last chunk of Photoshop-exported PNG files
49:47Consult stb_image.h for insight into its consumption loop
📖
49:47Consult stb_image.h for insight into its consumption loop
📖
49:47Consult stb_image.h for insight into its consumption loop
📖
53:51Set up to test our PNG image with stb_image.h
53:51Set up to test our PNG image with stb_image.h
53:51Set up to test our PNG image with stb_image.h
56:57Run stb_png_test successfully on character_hero.png
🏃
56:57Run stb_png_test successfully on character_hero.png
🏃
56:57Run stb_png_test successfully on character_hero.png
🏃
1:00:37Step through stbi__parse_zlib() and into stbi__parse_uncompressed_block() to see that it processes 0-length blocks
🏃
1:00:37Step through stbi__parse_zlib() and into stbi__parse_uncompressed_block() to see that it processes 0-length blocks
🏃
1:00:37Step through stbi__parse_zlib() and into stbi__parse_uncompressed_block() to see that it processes 0-length blocks
🏃
1:05:29Investigate the handling of 0-length blocks by FlushByte() in ParsePNG(), reverting the latter to break out of its consumption loop only if BFINAL is 1
1:05:29Investigate the handling of 0-length blocks by FlushByte() in ParsePNG(), reverting the latter to break out of its consumption loop only if BFINAL is 1
1:05:29Investigate the handling of 0-length blocks by FlushByte() in ParsePNG(), reverting the latter to break out of its consumption loop only if BFINAL is 1
1:07:24Set up to test our PNG reader on character_hero.png
🗹
1:07:24Set up to test our PNG reader on character_hero.png
🗹
1:07:24Set up to test our PNG reader on character_hero.png
🗹
1:08:59Break on the FlushByte() call in ParsePNG() and realise that it may be flushing more than a byte
🏃
1:08:59Break on the FlushByte() call in ParsePNG() and realise that it may be flushing more than a byte
🏃
1:08:59Break on the FlushByte() call in ParsePNG() and realise that it may be flushing more than a byte
🏃
1:10:02Change ParsePNG() to consume 16-bits for the LEN and NLEN, and FlushByte() to only flush the remainder of the byte
1:10:02Change ParsePNG() to consume 16-bits for the LEN and NLEN, and FlushByte() to only flush the remainder of the byte
1:10:02Change ParsePNG() to consume 16-bits for the LEN and NLEN, and FlushByte() to only flush the remainder of the byte
1:11:41Run it to see that we correctly parse character_hero.png
🏃
1:11:41Run it to see that we correctly parse character_hero.png
🏃
1:11:41Run it to see that we correctly parse character_hero.png
🏃
1:12:19Enable ParsePNG() to parse blocks that straddle IDAT chunk boundaries, introducing RefillIfNecessary()
1:12:19Enable ParsePNG() to parse blocks that straddle IDAT chunk boundaries, introducing RefillIfNecessary()
1:12:19Enable ParsePNG() to parse blocks that straddle IDAT chunk boundaries, introducing RefillIfNecessary()
1:16:07Run it to see that it still works
🏃
1:16:07Run it to see that it still works
🏃
1:16:07Run it to see that it still works
🏃
1:16:35Remove the ReversedBits table
1:16:35Remove the ReversedBits table
1:16:35Remove the ReversedBits table
1:17:19Determine to split up the PNG reader for integration into the game, while retaining the small test app
🗩
1:17:19Determine to split up the PNG reader for integration into the game, while retaining the small test app
🗩
1:17:19Determine to split up the PNG reader for integration into the game, while retaining the small test app
🗩
1:18:23Create test_png.cpp to contain everything except the decoding code
1:18:23Create test_png.cpp to contain everything except the decoding code
1:18:23Create test_png.cpp to contain everything except the decoding code
1:22:07Consider supporting buffered error handling in the PNG decoder
1:22:07Consider supporting buffered error handling in the PNG decoder
1:22:07Consider supporting buffered error handling in the PNG decoder
1:24:01Create handmade_stream.cpp to contain all the stream consumption code for our PNG reader
1:24:01Create handmade_stream.cpp to contain all the stream consumption code for our PNG reader
1:24:01Create handmade_stream.cpp to contain all the stream consumption code for our PNG reader
1:32:03Introduce Outf() to write errors into our stream, augmenting the stream struct with Errors and stream_chunk with File and LineNumber
1:32:03Introduce Outf() to write errors into our stream, augmenting the stream struct with Errors and stream_chunk with File and LineNumber
1:32:03Introduce Outf() to write errors into our stream, augmenting the stream struct with Errors and stream_chunk with File and LineNumber
1:38:49Make test_png.cpp initialise an Info and Error stream, pass them to ReadEntireFile() and WriteImageTopDownRGBA(), and write those stream to file using a new DumpStreamToCRT()
1:38:49Make test_png.cpp initialise an Info and Error stream, pass them to ReadEntireFile() and WriteImageTopDownRGBA(), and write those stream to file using a new DumpStreamToCRT()
1:38:49Make test_png.cpp initialise an Info and Error stream, pass them to ReadEntireFile() and WriteImageTopDownRGBA(), and write those stream to file using a new DumpStreamToCRT()
1:44:16Introduce OnDemandMemoryStream()
1:44:16Introduce OnDemandMemoryStream()
1:44:16Introduce OnDemandMemoryStream()
1:45:02Compile and run and get no output, with a view to addressing that later
🏃
1:45:02Compile and run and get no output, with a view to addressing that later
🏃
1:45:02Compile and run and get no output, with a view to addressing that later
🏃
1:45:16Q&A
🗩
1:45:16Q&A
🗩
1:45:16Q&A
🗩
1:46:29ivereadthesequel Q: So what is the focus now? This logging / error system?
🗪
1:46:29ivereadthesequel Q: So what is the focus now? This logging / error system?
🗪
1:46:29ivereadthesequel Q: So what is the focus now? This logging / error system?
🗪
1:48:18tonelessr Q: I haven't been following the PNG streams closely, but how satisfied are you with the code for the reader?
🗪
1:48:18tonelessr Q: I haven't been following the PNG streams closely, but how satisfied are you with the code for the reader?
🗪
1:48:18tonelessr Q: I haven't been following the PNG streams closely, but how satisfied are you with the code for the reader?
🗪
1:49:13lvias Q: Could you explain the bug that was solved again?
🗪
1:49:13lvias Q: Could you explain the bug that was solved again?
🗪
1:49:13lvias Q: Could you explain the bug that was solved again?
🗪
1:51:22flyinginthedark Q: Is TODO comment still in the code?
🗪
1:51:22flyinginthedark Q: Is TODO comment still in the code?
🗪
1:51:22flyinginthedark Q: Is TODO comment still in the code?
🗪
1:51:57tonelessr Q: Any plans to switch to LLVM anytime in the series?
🗪
1:51:57tonelessr Q: Any plans to switch to LLVM anytime in the series?
🗪
1:51:57tonelessr Q: Any plans to switch to LLVM anytime in the series?
🗪
1:52:41AsafGartner Q: If Visual Studio can load PNG files, maybe it can display BMP files with alpha?
🗪
1:52:41AsafGartner Q: If Visual Studio can load PNG files, maybe it can display BMP files with alpha?
🗪
1:52:41AsafGartner Q: If Visual Studio can load PNG files, maybe it can display BMP files with alpha?
🗪
1:53:42Enable WriteImageTopDownRGBA() to conditionally replace the alpha pixels with all black, and the program to output this as an extra BMP file
1:53:42Enable WriteImageTopDownRGBA() to conditionally replace the alpha pixels with all black, and the program to output this as an extra BMP file
1:53:42Enable WriteImageTopDownRGBA() to conditionally replace the alpha pixels with all black, and the program to output this as an extra BMP file
1:58:38Run it and inspect our two output BMP files
🏃
1:58:38Run it and inspect our two output BMP files
🏃
1:58:38Run it and inspect our two output BMP files
🏃
1:59:00Introduce MulAlpha() to composite the alpha and non-alpha pixels
1:59:00Introduce MulAlpha() to composite the alpha and non-alpha pixels
1:59:00Introduce MulAlpha() to composite the alpha and non-alpha pixels
2:03:06Run it to see our premultiplied output
🏃
2:03:06Run it to see our premultiplied output
🏃
2:03:06Run it to see our premultiplied output
🏃
2:03:49tonelessr Q: This is off-topic, but will there be any blog posts on Molly Rocket for any of the projects anytime? Kind of miss those
🗪
2:03:49tonelessr Q: This is off-topic, but will there be any blog posts on Molly Rocket for any of the projects anytime? Kind of miss those
🗪
2:03:49tonelessr Q: This is off-topic, but will there be any blog posts on Molly Rocket for any of the projects anytime? Kind of miss those
🗪
2:04:05cynokron Q: I am confused why you shift the multiply down by 8 bits. Wouldn't you want to mask with 0xFF?
🗪
2:04:05cynokron Q: I am confused why you shift the multiply down by 8 bits. Wouldn't you want to mask with 0xFF?
🗪
2:04:05cynokron Q: I am confused why you shift the multiply down by 8 bits. Wouldn't you want to mask with 0xFF?
🗪
2:04:44Basis in Fixed Point Multiply
🖌
2:04:44Basis in Fixed Point Multiply
🖌
2:04:44Basis in Fixed Point Multiply
🖌
2:11:05sneakybob_wot Q: Can you briefly explain how the binary reverse works you implemented last week?
🗪
2:11:05sneakybob_wot Q: Can you briefly explain how the binary reverse works you implemented last week?
🗪
2:11:05sneakybob_wot Q: Can you briefly explain how the binary reverse works you implemented last week?
🗪
2:11:10Bit Reversal
🖌
2:11:10Bit Reversal
🖌
2:11:10Bit Reversal
🖌
2:13:25We're all done
🗩
2:13:25We're all done
🗩
2:13:25We're all done
🗩