static int decode_wdlt(uint8_t *frame, int width, int height,

                       const uint8_t *src, const uint8_t *src_end)

{

    const uint8_t *frame_end   = frame + width * height;

    uint8_t *line_ptr;

    int count, i, v, lines, segments;



    lines = bytestream_get_le16(&src);

    if (lines > height || src >= src_end)

        return -1;



    while (lines--) {

        segments = bytestream_get_le16(&src);

        while ((segments & 0xC000) == 0xC000) {

            unsigned delta = -((int16_t)segments * width);

            if (frame_end - frame <= delta)

                return -1;

            frame    += delta;

            segments = bytestream_get_le16(&src);

        }

        if (segments & 0x8000) {

            frame[width - 1] = segments & 0xFF;

            segments = bytestream_get_le16(&src);

        }

        line_ptr = frame;

        frame += width;

        while (segments--) {

            if (src_end - src < 2)

                return -1;

            if (frame - line_ptr <= *src)

                return -1;

            line_ptr += *src++;

            count = (int8_t)*src++;

            if (count >= 0) {

                if (frame - line_ptr < count*2 || src_end - src < count*2)

                    return -1;

                bytestream_get_buffer(&src, line_ptr, count*2);

                line_ptr += count * 2;

            } else {

                count = -count;

                if (frame - line_ptr < count*2 || src_end - src < 2)

                    return -1;

                v = bytestream_get_le16(&src);

                for (i = 0; i < count; i++)

                    bytestream_put_le16(&line_ptr, v);

            }

        }

    }



    return 0;

}

static int decode_wdlt(uint8_t *frame, int width, int height,

                       const uint8_t *src, const uint8_t *src_end)

{

    const uint8_t *frame_end   = frame + width * height;

    uint8_t *line_ptr;

    int count, i, v, lines, segments;



    lines = bytestream_get_le16(&src);

    if (lines > height || src >= src_end)

        return -1;



    while (lines--) {

        segments = bytestream_get_le16(&src);

        while ((segments & 0xC000) == 0xC000) {

            unsigned delta = -((int16_t)segments * width);

            if (frame_end - frame <= delta)

                return -1;

            frame    += delta;

            segments = bytestream_get_le16(&src);

        }

        if (segments & 0x8000) {

            frame[width - 1] = segments & 0xFF;

            segments = bytestream_get_le16(&src);

        }

        line_ptr = frame;

        frame += width;

        while (segments--) {

            if (src_end - src < 2)

                return -1;

            if (frame - line_ptr <= *src)

                return -1;

            line_ptr += *src++;

            count = (int8_t)*src++;

            if (count >= 0) {

                if (frame - line_ptr < count*2 || src_end - src < count*2)

                    return -1;

                bytestream_get_buffer(&src, line_ptr, count*2);

                line_ptr += count * 2;

            } else {

                count = -count;

                if (frame - line_ptr < count*2 || src_end - src < 2)

                    return -1;

                v = bytestream_get_le16(&src);

                for (i = 0; i < count; i++)

                    bytestream_put_le16(&line_ptr, v);

            }

        }

    }



    return 0;

}

                       const uint8_t *src, const uint8_t *src_end)                        const uint8_t *src, const uint8_t *src_end)                 return -1;                        const uint8_t *src, const uint8_t *src_end)                 return -1;                        const uint8_t *src, const uint8_t *src_end)                 return -1;                        const uint8_t *src, const uint8_t *src_end)     lines = bytestream_get_le16(&src);             if (frame - line_ptr <= *src)                 return -1;             line_ptr += *src++;             count = (int8_t)*src++; static int decode_wdlt(uint8_t *frame, int width, int height,                        const uint8_t *src, const uint8_t *src_end)     lines = bytestream_get_le16(&src);     if (lines > height || src >= src_end)         segments = bytestream_get_le16(&src);             segments = bytestream_get_le16(&src);             segments = bytestream_get_le16(&src);             if (src_end - src < 2)                 return -1;             if (frame - line_ptr <= *src)             line_ptr += *src++;             count = (int8_t)*src++;                 if (frame - line_ptr < count*2 || src_end - src < count*2)                 bytestream_get_buffer(&src, line_ptr, count*2);                 if (frame - line_ptr < count*2 || src_end - src < 2)                 v = bytestream_get_le16(&src);                        const uint8_t *src, const uint8_t *src_end)                        const uint8_t *src, const uint8_t *src_end)
static int FUNC_0(uint8_t *VAR_0, int VAR_1, int VAR_2,

                       const uint8_t *VAR_3, const uint8_t *VAR_4)

{

    const uint8_t *VAR_5   = VAR_0 + VAR_1 * VAR_2;

    uint8_t *line_ptr;

    int VAR_6, VAR_7, VAR_8, VAR_9, VAR_10;



    VAR_9 = bytestream_get_le16(&VAR_3);

    if (VAR_9 > VAR_2 || VAR_3 >= VAR_4)

        return -1;



    while (VAR_9--) {

        VAR_10 = bytestream_get_le16(&VAR_3);

        while ((VAR_10 & 0xC000) == 0xC000) {

            unsigned VAR_11 = -((int16_t)VAR_10 * VAR_1);

            if (VAR_5 - VAR_0 <= VAR_11)

                return -1;

            VAR_0    += VAR_11;

            VAR_10 = bytestream_get_le16(&VAR_3);

        }

        if (VAR_10 & 0x8000) {

            VAR_0[VAR_1 - 1] = VAR_10 & 0xFF;

            VAR_10 = bytestream_get_le16(&VAR_3);

        }

        line_ptr = VAR_0;

        VAR_0 += VAR_1;

        while (VAR_10--) {

            if (VAR_4 - VAR_3 < 2)

                return -1;

            if (VAR_0 - line_ptr <= *VAR_3)

                return -1;

            line_ptr += *VAR_3++;

            VAR_6 = (int8_t)*VAR_3++;

            if (VAR_6 >= 0) {

                if (VAR_0 - line_ptr < VAR_6*2 || VAR_4 - VAR_3 < VAR_6*2)

                    return -1;

                bytestream_get_buffer(&VAR_3, line_ptr, VAR_6*2);

                line_ptr += VAR_6 * 2;

            } else {

                VAR_6 = -VAR_6;

                if (VAR_0 - line_ptr < VAR_6*2 || VAR_4 - VAR_3 < 2)

                    return -1;

                VAR_8 = bytestream_get_le16(&VAR_3);

                for (VAR_7 = 0; VAR_7 < VAR_6; VAR_7++)

                    bytestream_put_le16(&line_ptr, VAR_8);

            }

        }

    }



    return 0;

}

static int FUNC_0(uint8_t *VAR_0, int VAR_1, int VAR_2,
const uint8_t *VAR_3, const uint8_t *VAR_4)
{ const uint8_t *VAR_5   = VAR_0 + VAR_1 * VAR_2; uint8_t *line_ptr; int VAR_6, VAR_7, VAR_8, VAR_9, VAR_10; VAR_9 = bytestream_get_le16(&VAR_3); if (VAR_9 > VAR_2 || VAR_3 >= VAR_4)
return -1; while (VAR_9--) { VAR_10 = bytestream_get_le16(&VAR_3); while ((VAR_10 & 0xC000) == 0xC000) { unsigned VAR_11 = -((int16_t)VAR_10 * VAR_1); if (VAR_5 - VAR_0 <= VAR_11)
return -1; VAR_0    += VAR_11; VAR_10 = bytestream_get_le16(&VAR_3); } if (VAR_10 & 0x8000) { VAR_0[VAR_1 - 1] = VAR_10 & 0xFF; VAR_10 = bytestream_get_le16(&VAR_3); } line_ptr = VAR_0; VAR_0 += VAR_1; while (VAR_10--) { if (VAR_4 - VAR_3 < 2)
return -1; if (VAR_0 - line_ptr <= *VAR_3)
return -1; line_ptr += *VAR_3++; VAR_6 = (int8_t)*VAR_3++; if (VAR_6 >= 0) { if (VAR_0 - line_ptr < VAR_6*2 || VAR_4 - VAR_3 < VAR_6*2)
return -1; bytestream_get_buffer(&VAR_3, line_ptr, VAR_6*2); line_ptr += VAR_6 * 2; } else { VAR_6 = -VAR_6; if (VAR_0 - line_ptr < VAR_6*2 || VAR_4 - VAR_3 < 2)
return -1; VAR_8 = bytestream_get_le16(&VAR_3); for (VAR_7 = 0; VAR_7 < VAR_6; VAR_7++) bytestream_put_le16(&line_ptr, VAR_8); } } } return 0; }