static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst, int width, int height) {

    unsigned char *dst_end = dst + width*height;

    int size,size1,size2,offset,run;

    unsigned char *dst_start = dst;



    if (src[0] & 0x01)

        src += 5;

    else

        src += 2;



    if (src+3>src_end)

        return -1;

    size = AV_RB24(src);

    src += 3;



    while(size>0 && src<src_end) {



        /* determine size1 and size2 */

        size1 = (src[0] & 3);

        if ( src[0] & 0x80 ) {  // 1

            if (src[0] & 0x40 ) {  // 11

                if ( src[0] & 0x20 ) {  // 111

                    if ( src[0] < 0xFC )  // !(111111)

                        size1 = (((src[0] & 31) + 1) << 2);

                    src++;

                    size2 = 0;

                } else {  // 110

                    offset = ((src[0] & 0x10) << 12) + AV_RB16(&src[1]) + 1;

                    size2 = ((src[0] & 0xC) << 6) + src[3] + 5;

                    src += 4;

                }

            } else {  // 10

                size1 = ( ( src[1] & 0xC0) >> 6 );

                offset = (AV_RB16(&src[1]) & 0x3FFF) + 1;

                size2 = (src[0] & 0x3F) + 4;

                src += 3;

            }

        } else {  // 0

            offset = ((src[0] & 0x60) << 3) + src[1] + 1;

            size2 = ((src[0] & 0x1C) >> 2) + 3;

            src += 2;

        }





        /* fetch strip from src */

        if (size1>src_end-src)

            break;



        if (size1>0) {

            size -= size1;

            run = FFMIN(size1, dst_end-dst);

            memcpy(dst, src, run);

            dst += run;

            src += run;

        }



        if (size2>0) {

            if (dst-dst_start<offset)

                return 0;

            size -= size2;

            run = FFMIN(size2, dst_end-dst);

            av_memcpy_backptr(dst, offset, run);

            dst += run;

        }

    }



    return 0;

}
