[Ffmpeg-devel] [PATCH] TIFF encoder (Google SoC qualification task)

Kamil Nowosad k.nowosad
Mon Apr 2 15:01:29 CEST 2007


Hi

On Sun, Apr 01, 2007 at 08:23:41PM +0200, Michael Niedermayer wrote:
> > -                *out++ = 0x80 | (count - 1);
> > +                if (style == FF_RLE_SETBIT)
> > +                    *out++ = 0x80 | (count - 1);
> > +                else
> > +                    *out++ = -count + 1;
> 
> this can be done without a branch, also it can be done more generically

Is this sufficent:

a = (uint8_t[]{   1,-1})[style];
b = (uint8_t[]{0x80, 0})[style];

and in loop:

*out++ = ((count - 1) | b) * a
?
Or maybe I don't see a more simple solution? (I see only two analogous
with +, and ^ instead of |)

> > +/* list of TIFF compression types */
> >  enum TiffCompr{
> 
> not doxygen compatible

It is done (I just wanted to ask some questions before submitting my
patch).

> > Index: libavcodec/tiffenc.c
> > ===================================================================
> > --- libavcodec/tiffenc.c	(wersja 0)
> > +++ libavcodec/tiffenc.c	(wersja 0)
> [...]
> 
> > +    uint16_t *color_map;
> 
> this could as well be a local array

Shouldn't I rather allocate the memory for that in tiff_init and free
in tiff_end ? I forgot about moving it there...

> > +    uLongf zlen;
> 
> what is uLongf?

It is a type used by zlib. Sorry, I haven't precisely checked, how is zlib 
used in other codecs. Now I've changed it to uint32_t.

> > +    case 0:                    // XXX: when a user chose vlc it also assigns the default
> > +        s->compression = TIFF_DEFAULT;
> > +        break;
> 
> hmm maybe its better to fail with an error if a unsupported compression is
> choosen

Yes, but the coder_type is 0 both in cases when user uses "-coder vlc" and 
when he doesn't use -coder at all. My idea is to redefine:

#define FF_CODER_TYPE_VLC       0
#define FF_CODER_TYPE_AC        1
#define FF_CODER_TYPE_RAW       2  // no coder
#define FF_CODER_TYPE_RLE       3  // run-length
#define FF_CODER_TYPE_DEFLATE   4 

in avcodec.h to something like that

#define FF_CODER_TYPE_DEFAULT   0
#define FF_CODER_TYPE_VLC       1
#define FF_CODER_TYPE_AC        2
#define FF_CODER_TYPE_RAW       3  // no coder
#define FF_CODER_TYPE_RLE       4  // run-length
#define FF_CODER_TYPE_DEFLATE   5

However, it needs changes in ffv1.c. I guess, that the separate patch is
needed ;-). Should I do it in such way? 

> > +#define COMPRESS(func) \
> > +        for (y = 0; y < avctx->height; y += s->lines_per_strip) {\
> > +            int i;\
> > +            s->strip_offset[s->strip++] = CURR_OFFSET(s);\
> > +            for (i = 0; (i < s->lines_per_strip) && (y + i < avctx->height); i++) {\
> > +                func;\
> > +                src += p->linesize[0];\
> > +            }\
> > +        }
> > +    switch (s->compression) {
> > +    case TIFF_RAW:
> > +        if (s->buf_end - s->buf < avctx->height * s->bytes_per_line) {
> > +            av_log(avctx, AV_LOG_ERROR, "the buffer given is too short\n");
> > +            return -1;
> > +        }
> > +        COMPRESS(bytestream_put_buffer(&s->buf, src, s->bytes_per_line));
> > +        break;
> > +
> > +    case TIFF_PACKBITS:
> > +        COMPRESS(ret =
> > +                 ff_encode_rle(s->buf, s->buf_end - s->buf, src,
> > +                               s->bytes_per_line, 1, FF_RLE_NEG);
> > +                 if (ret == -1) {
> > +                     av_log(avctx, AV_LOG_ERROR,
> > +                        "the buffer given is too short\n");
> > +                     return -1;
> > +                 }
> > +                 s->buf += ret;);
> > +        break;
> 
> hmm isnt this a little bit obfuscated? if theres no way to cleanly simplify
> it then it might be better to leave it ...

I'll try to something with that.

> > + * encoding scheme:
> > + * @li [if the client has not set it] TIFF signature
> > + * @li offset of the IFD
> > + * @li image data [divided into strips]
> > + * @li IFD data which doesn't fit inside the IFD
> > + * @li IFD, sorted by tag
> > + * @li [if the client will not set it] 32 zero bits
> 
> the comment in [] is wrong

Fixed.

> > +    const uint8_t header[4] = { 0x49, 0x49, 42, 0 };
> > +    const uint8_t trailer[4] = { 0, 0, 0, 0 };
> 
> these should be const static

Changed.

> > +    if (tiff_add_ifd_entry(avctx, TIFF_WIDTH,         TIFF_LONG,     1,           &avctx->width)||
> > +        tiff_add_ifd_entry(avctx, TIFF_HEIGHT,        TIFF_LONG,     1,           &avctx->height)||
> > +        tiff_add_ifd_entry(avctx, TIFF_BPP,           TIFF_SHORT,    s->nsamples, s->bpp_info)||
> > +        tiff_add_ifd_entry(avctx, TIFF_COMPR,         TIFF_SHORT,    1,           &s->compression)||
> > +        tiff_add_ifd_entry(avctx, TIFF_INVERT,        TIFF_SHORT,    1,           &s->photometric_interpretation)||
> > +        tiff_add_ifd_entry(avctx, TIFF_STRIP_OFFS,    TIFF_LONG,     s->strip,    s->strip_offset)||
> > +        tiff_add_ifd_entry(avctx, TIFF_SAMPLESPERPIX, TIFF_SHORT,    1,           &s->nsamples)||
> > +        tiff_add_ifd_entry(avctx, TIFF_ROWSPERSTRIP,  TIFF_LONG,     1,           &s->lines_per_strip)||
> > +        tiff_add_ifd_entry(avctx, TIFF_STRIP_SIZE,    TIFF_LONG,     s->strip,    s->strip_size)||
> > +        tiff_add_ifd_entry(avctx, TIFF_XRES,          TIFF_RATIONAL, 1,           xres)||
> > +        tiff_add_ifd_entry(avctx, TIFF_YRES,          TIFF_RATIONAL, 1,           yres)||
> > +        tiff_add_ifd_entry(avctx, TIFF_RES_UNIT,      TIFF_SHORT,    1,           (uint16_t[]){2})||
> > +        ((s->has_color_map) &&
> > +        tiff_add_ifd_entry(avctx, TIFF_PAL,           TIFF_SHORT,    3 << s->bpp, s->color_map))
> > +        )
> > +        goto cleanup;
> 
> this is the longest if() ive seen in a patch i think, cant that be avoided?

I've changed that.

> > +static int tiff_init(AVCodecContext * avctx)
> > +{
> > +    return 0;
> > +}
> > +
> > +static int tiff_end(AVCodecContext * avctx)
> > +{
> > +    return 0;
> > +}
> 
> hmm, these can be removed if theres nothing to allocate and cleanup but
> then why are strip_offset/strip_size/color_map in the context at all
> they could as well be local variables

Ok, I'll remove them if they won't be needed.

Sorry to bother you with such kind of stupid shortcomings... I'm now getting 
out of habits gained during the contest programming ;-) 

-- 
Best regards,
Kamil Nowosad




More information about the ffmpeg-devel mailing list