static int rle_unpack(const unsigned char *src, int src_len, int src_count, unsigned char *dest, int dest_len) { const unsigned char *ps; const unsigned char *ps_end; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; ps = src; ps_end = src + src_len; pd = dest; if (src_count & 1) { if (ps_end - ps < 1) return 0; *pd++ = *ps++; } src_count >>= 1; i = 0; do { if (ps_end - ps < 1) break; l = *ps++; if (l & 0x80) { l = (l & 0x7F) * 2; if (pd + l > dest_end || ps_end - ps < l) return ps - src; memcpy(pd, ps, l); ps += l; pd += l; } else { if (pd + i > dest_end || ps_end - ps < 2) return ps - src; for (i = 0; i < l; i++) { *pd++ = ps[0]; *pd++ = ps[1]; } ps += 2; } i += l; } while (i < src_count); return ps - src; }