I think you have a bug in codepoint_read(). The last argument is a pointer to variable unicode_t named decoded. If the first if statement in that function is true, then the a value is never assigned to that variable, the function returns, and immediately outside the function the value of that variable is read. But that variable was never initialized.
https://bitbucket.org/knight666/utf8rewind/src/c22e458912952...
https://bitbucket.org/knight666/utf8rewind/src/c22e458912952...
https://bitbucket.org/knight666/utf8rewind/src/c22e458912952...
The prior while statement makes sure the second parameter src_size is never 0, but the pointer src might be.
Undefined behavior can be caused by passing a NULL pointer as the first parameter and a non-negative second parameter to utf8toutf16().