/** * Read a run length encoded SGI image. * @param out_buf output buffer * @param in_buf input buffer * @param in_end end of input buffer * @param s the current image state * @return 0 if no error, else return error number. */ static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf, const uint8_t *in_end, SgiState* s) { uint8_t *dest_row; unsigned int len = s->height * s->depth * 4; const uint8_t *start_table = in_buf; unsigned int y, z; unsigned int start_offset; /* size of RLE offset and length tables */ if(len * 2 > in_end - in_buf) { return AVERROR_INVALIDDATA; } in_buf -= SGI_HEADER_SIZE; for (z = 0; z < s->depth; z++) { dest_row = out_buf; for (y = 0; y < s->height; y++) { dest_row -= s->linesize; start_offset = bytestream_get_be32(&start_table); if(start_offset > in_end - in_buf) { return AVERROR_INVALIDDATA; } if (expand_rle_row(in_buf + start_offset, in_end, dest_row + z, dest_row + FFABS(s->linesize), s->depth) != s->width) return AVERROR_INVALIDDATA; } } return 0; }
/** * Read a run length encoded SGI image. * @param out_buf output buffer * @param s the current image state * @return 0 if no error, else return error number. */ static int read_rle_sgi(uint8_t *out_buf, SgiState *s) { uint8_t *dest_row; unsigned int len = s->height * s->depth * 4; GetByteContext g_table = s->g; unsigned int y, z; unsigned int start_offset; /* size of RLE offset and length tables */ if (len * 2 > bytestream2_get_bytes_left(&s->g)) { return AVERROR_INVALIDDATA; } for (z = 0; z < s->depth; z++) { dest_row = out_buf; for (y = 0; y < s->height; y++) { dest_row -= s->linesize; start_offset = bytestream2_get_be32(&g_table); bytestream2_seek(&s->g, start_offset, SEEK_SET); if (expand_rle_row(s, dest_row + z, dest_row + FFABS(s->linesize), s->depth) != s->width) { return AVERROR_INVALIDDATA; } } } return 0; }
/* read a run length encoded sgi image */ static int read_rle_sgi(const SGIInfo *sgi_info, AVPicture *pict, ByteIOContext *f) { uint8_t *dest_row; unsigned long *start_table; int y, z, xsize, ysize, zsize, tablen; long start_offset; int ret = 0; xsize = sgi_info->xsize; ysize = sgi_info->ysize; zsize = sgi_info->zsize; /* skip header */ url_fseek(f, SGI_HEADER_SIZE, SEEK_SET); /* size of rle offset and length tables */ tablen = ysize * zsize * sizeof(long); start_table = (unsigned long *)av_malloc(tablen); if (!get_buffer(f, (uint8_t *)start_table, tablen)) { ret = AVERROR_IO; goto fail; } /* skip run length table */ url_fseek(f, tablen, SEEK_CUR); for (z = 0; z < zsize; z++) { for (y = 0; y < ysize; y++) { dest_row = pict->data[0] + (ysize - 1 - y) * (xsize * zsize); start_offset = BE_32(&start_table[y + z * ysize]); /* don't seek if already at the next rle start offset */ if (url_ftell(f) != start_offset) { url_fseek(f, start_offset, SEEK_SET); } if (expand_rle_row(f, dest_row, z, zsize) != xsize) { ret = AVERROR_INVALIDDATA; goto fail; } } } fail: av_free(start_table); return ret; }