[Ffmpeg-devel] [PATCH] ported SGI decoder to the new API
Xiaohui Sun
sunxiaohui
Tue Apr 3 18:11:08 CEST 2007
Hi,
I updated the patch.
>
>
> [...]
> > Index: libavcodec/rle.c
> > ===================================================================
> > --- libavcodec/rle.c (revision 0)
> > +++ libavcodec/rle.c (revision 0)
>
> i think this should be diffed against the old rle code (currently in
> targaenc.c)
>
I used the current rle code.
> [...]
> > +#include "common.h"
> > +#include "bytestream.h"
> > +#include "rle.h"
> > +
> > +/**
> > + * Count up to 127 consecutive pixels which are either all the same or
> > + * all differ from the previous and next pixels with one bpp
> > + * @param start pointer to the first pixel
> > + * @param len maximum number of pixels
> > + * @param same 1 if searching for identical pixel values, 0 for
> differing
> > + * @return number of matching consecutive pixels found
> > + */
> > +static av_always_inline int count_pixels_1bpp(uint8_t *start, int
> len, int same)
> > +{
> > + uint8_t *pos;
> > + int count = 1;
> > +
> > + for (pos = start + 1; count < FFMIN(127, len); pos ++, count ++) {
> > + if (same != !(*(pos - 1) != * pos)) {
> > + if (!same) {
> > + /* if bpp == 1, then 0 1 1 0 is more efficiently
> encoded as a single
> > + * raw block of pixels. for larger bpp, RLE is as
> good or better */
> > + if (count + 1 < FFMIN(127, len) && *pos != *(pos + 1))
> > + continue;
> > +
> > + /* if RLE can encode the next block better than as
> a raw block,
> > + * back up and leave _all_ the identical pixels for
> RLE */
> > + count --;
> > + }
> > + break;
> > + }
> > + }
> > + return count;
> > +}
> > +
> > +/**
> > + * Count up to 127 consecutive pixels which are either all the same or
> > + * all differ from the previous and next pixels with more than one bpp
> > + * @param start pointer to the first pixel
> > + * @param len maximum number of pixels
> > + * @param bpp bytes per pixel
> > + * @param same 1 if searching for identical pixel values, 0 for
> differing
> > + * @return number of matching consecutive pixels found
> > + */
> > +static av_always_inline int count_pixels_nbpp(uint8_t *start, int
> len, int bpp, int same)
> > +{
> > + uint8_t *pos;
> > + int count = 1;
> > +
> > + for (pos = start + bpp; count < FFMIN(127, len); pos += bpp,
> count ++) {
> > + if (same != !memcmp(pos - bpp, pos, bpp)) {
> > + if (!same) {
> > + /* if RLE can encode the next block better than as
> a raw block,
> > + * back up and leave _all_ the identical pixels for
> RLE */
> > + count --;
> > + }
> > + break;
> > + }
> > + }
> > + return count;
> > +}
>
> code duplication
see above
>
> [...]
> > +/**
> > + * expand an RLE row into a channel
> > + * @param in_buf input buffer
> > + * @param out_ptr output buffer
> > + * @param end_ptr end of line in output buffer
> > + * @param chan_offset offsets into input buffer
> > + * @param pixelstride pixel stride of input buffer
> > + * @return Size of output in bytes, -1 if buffer overflows
> > + */
> > +static int expand_rle_row(uint8_t *in_buf, uint8_t* end_buf,
> > + unsigned char *out_ptr, uint8_t* end_ptr,
> > + int chan_offset, int pixelstride)
> > +{
> > + unsigned char pixel, count;
> > + unsigned char *orig = out_ptr;
> > +
> > + out_ptr += chan_offset;
>
> it would be cleaner if the out_ptr argument would point to the output
> array instead of passing the chan_offset into the functin and then
> changing
> the out_ptr
>
changed
>
> > +
> > + while (1) {
>
> > + if(in_buf + 1 > end_buf) return -1;
>
> this check isnt really needed as the input array is guranteed to be 8
> bytes
> larger then end_buf
>
removed
>
> [...]
> > + start_offset = bytestream_get_be32(&start_table);
> > + if(start_offset > end_buf - in_buf) {
> > + return AVERROR_INVALIDDATA;
> > + }
>
> excelent, finally the check looks good
>
>
> > + if (expand_rle_row(in_buf + start_offset, end_buf,
> dest_row,
> > + dest_row + s->linesize, z, s->depth) != s->width)
> > + return AVERROR_INVALIDDATA;
>
> linesize can be negative
>
I modified, but not sure.
>
>
> [...]
> > +static int decode_frame(AVCodecContext *avctx,
> > + void *data, int *data_size,
> > + uint8_t *buf, int buf_size)
> > +{
> > + SgiState *s = avctx->priv_data;
> > + AVFrame *picture = data;
> > + AVFrame *p = &s->picture;
> > + uint8_t* orig_buf = buf, *end_buf = buf + buf_size;
>
> the orig_buf variable seems to be unneeded
done
>
>
> [...]
> > + s->linesize = p->linesize[0];
> > + p->pict_type = FF_I_TYPE;
> > + p->key_frame = 1;
> > + ptr = p->data[0];
> > +
> > + end_ptr = ptr + s->linesize * s->height;
>
> linesize can be negative
changed, but not sure
>
> also i think ptr / buf are confusing names, out_ptr / in_buf would be
> clearer
>
done
>
> [...]
> > +static av_always_inline int encode_rle_1bpp(int w, uint8_t* in_buf,
> > + unsigned char* out_buf, uint8_t* end_buf)
> > +{
> > + int x, count;
> > + uint8_t* orig_buf = out_buf;
> > +
> > + for (x = 0; x < w; x += count) {
> > + /* see if we can encode the next set of pixels with RLE */
> > + if ((count = ff_count_pixels(in_buf, w - x, 1, 1)) > 1) {
> > + if (out_buf + 2 > end_buf) return -1;
> > + bytestream_put_byte(&out_buf, count);
> > + bytestream_put_byte(&out_buf, *in_buf);
> > + } else {
> > + /* fall back on uncompressed */
> > + count = ff_count_pixels(in_buf, w-x, 1, 0);
> > +
> > + if (out_buf + count + 1 > end_buf) return -1;
> > + bytestream_put_byte(&out_buf, 0x80 | count);
> > + bytestream_put_buffer(&out_buf, in_buf, count);
> > + }
> > + in_buf += count;
> > + }
>
> > + *(out_buf++) = 0;
>
> it seems this byte can end outside the array
modified
>
>
> [...]
> > + /* make an intermediate consecutive buffer */
> > + if ((encode_buf = (char *)av_malloc(width)) == NULL)
>
> unneeded cast
>
removed
>
> > + return -1;
> > +
> > + for (z = 0; z < depth; z++) {
> > + in_buf = p->data[0] + p->linesize[0] * (height - 1) + z;
> > +
> > + for (y = 0; y < height; y++) {
> > + bytestream_put_be32(&offsettab, buf - orig_buf);
> > +
>
> > + for (x = 0; x < width; x++)
> > + *(encode_buf + x) = *(in_buf + depth * x);
>
> i think encode_buf[x] = in_buf[depth*z] is more readable and definitly
> more
> commonly used
done
>
>
> > +
> > + if((length = encode_rle_1bpp(width, encode_buf, buf,
> end_buf)) == -1)
> > + return -1;
>
> memleak
done
>
>
> [...]
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: sgi_port.patch
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070404/98c5166a/attachment.asc>
More information about the ffmpeg-devel
mailing list