static int epic_decode_tile(ePICContext *dc, uint8_t *out, int tile_height,

                            int tile_width, int stride)

{

    int x, y;

    uint32_t pix;

    uint32_t *curr_row = NULL, *above_row = NULL, *above2_row;



    for (y = 0; y < tile_height; y++, out += stride) {

        above2_row = above_row;

        above_row  = curr_row;

        curr_row   = (uint32_t *) out;



        for (x = 0, dc->next_run_pos = 0; x < tile_width;) {

            if (dc->els_ctx.err)

                return AVERROR_INVALIDDATA; 



            pix = curr_row[x - 1]; 



            if (y >= 1 && x >= 2 &&

                pix != curr_row[x - 2]  && pix != above_row[x - 1] &&

                pix != above_row[x - 2] && pix != above_row[x] &&

                !epic_cache_entries_for_pixel(&dc->hash, pix)) {

                curr_row[x] = epic_decode_pixel_pred(dc, x, y, curr_row, above_row);

                x++;

            } else {

                int got_pixel, run;

                dc->stack_pos = 0; 



                if (y < 2 || x < 2 || x == tile_width - 1) {

                    run       = 1;

                    got_pixel = epic_handle_edges(dc, x, y, curr_row, above_row, &pix);

                } else

                    got_pixel = epic_decode_run_length(dc, x, y, tile_width,

                                                       curr_row, above_row,

                                                       above2_row, &pix, &run);



                if (!got_pixel && !epic_predict_from_NW_NE(dc, x, y, run,

                                                           tile_width, curr_row,

                                                           above_row, &pix)) {

                    uint32_t ref_pix = curr_row[x - 1];

                    if (!x || !epic_decode_from_cache(dc, ref_pix, &pix)) {

                        pix = epic_decode_pixel_pred(dc, x, y, curr_row, above_row);

                        if (x) {

                            int ret = epic_add_pixel_to_cache(&dc->hash,

                                                              ref_pix,

                                                              pix);

                            if (ret)

                                return ret;

                        }

                    }

                }

                for (; run > 0; x++, run--)

                    curr_row[x] = pix;

            }

        }

    }



    return 0;

}
