As we said, step through the code with a debugger.
Make notes about the values you are writing out for each channel while you are encoding: both the value you are encoding, and the actual channel value. Use a single character test first so that at most you will be noting down 20 (e.g. 4 channels * (1 character + 4 zeroes) * 2 for before and after) numbers if I understand your encoding correctly. If you feel that pen and paper is too tedious or error prone, add logging to your code to let it write it out for you. Better yet, move your encoding/decoding code into a library and call that library from a console program and write your trace logs to the console.
Next debug the decoding phase: as each channel value is read from input. Verify that the channel values matches what you wrote down for that pixel. If there is a mismatch, that means you might not actually be using PNG (which is supposed to be lossless), or that some other image processing is happening on the bitmap before you get a chance to load it back again. Another possibility is that you are hitting integer overflow during encoding. As I recall from your code, you are just using addition to insert your value to be encoded instead of replacing the lower 2 bits. If the original channel value is already 252 , adding 4 will give you 256 which does does not fit in 8 bits.
Next, step through the code that extracts through encoded values with a debugger. Compare with your encoded value. If there is a mismatch, then that means there is a bug in your extraction code.
Again, if you find all that inspection too tedious or error prone, use some logging.
If the extracted values are correct, but your decoding loop keeps going past the 4 zeroes you use as a terminator, then it's logic bug in your terminating condition detection.