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;

}
