Merge commit 'd12b5b2f135aade4099f4b26b0fe678656158c13'
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>
Wed, 11 May 2016 18:10:10 +0000 (19:10 +0100)
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>
Wed, 11 May 2016 18:13:03 +0000 (19:13 +0100)
* commit 'd12b5b2f135aade4099f4b26b0fe678656158c13':
  build: Split test programs off into separate files

Some conversions done by: James Almer <jamrial@gmail.com>
Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
114 files changed:
1  2 
libavcodec/Makefile
libavcodec/avfft-test.c
libavcodec/avfft.c
libavcodec/cabac-test.c
libavcodec/cabac.c
libavcodec/iirfilter-test.c
libavcodec/iirfilter.c
libavcodec/imgconvert-test.c
libavcodec/imgconvert.c
libavcodec/jpeg2000dwt-test.c
libavcodec/jpeg2000dwt.c
libavcodec/mathops-test.c
libavcodec/options-test.c
libavcodec/rangecoder-test.c
libavcodec/rangecoder.c
libavcodec/snowenc-test.c
libavcodec/snowenc.c
libavcodec/utils-test.c
libavcodec/utils.c
libavdevice/timefilter-test.c
libavdevice/timefilter.c
libavfilter/filtfmts-test.c
libavfilter/formats-test.c
libavfilter/formats.c
libavformat/rtmpdh-test.c
libavformat/rtmpdh.c
libavformat/srtp-test.c
libavformat/srtp.c
libavutil/adler32-test.c
libavutil/adler32.c
libavutil/aes-test.c
libavutil/aes.c
libavutil/atomic-test.c
libavutil/atomic.c
libavutil/avstring-test.c
libavutil/avstring.c
libavutil/base64-test.c
libavutil/base64.c
libavutil/blowfish-test.c
libavutil/blowfish.c
libavutil/bprint-test.c
libavutil/bprint.c
libavutil/camellia-test.c
libavutil/camellia.c
libavutil/cast5-test.c
libavutil/cast5.c
libavutil/color_utils-test.c
libavutil/color_utils.c
libavutil/cpu-test.c
libavutil/cpu.c
libavutil/crc-test.c
libavutil/crc.c
libavutil/des-test.c
libavutil/des.c
libavutil/dict-test.c
libavutil/dict.c
libavutil/display-test.c
libavutil/display.c
libavutil/error-test.c
libavutil/error.c
libavutil/eval-test.c
libavutil/eval.c
libavutil/fifo-test.c
libavutil/fifo.c
libavutil/file-test.c
libavutil/file.c
libavutil/float_dsp-test.c
libavutil/float_dsp.c
libavutil/hash-test.c
libavutil/hash.c
libavutil/hmac-test.c
libavutil/hmac.c
libavutil/lfg-test.c
libavutil/lfg.c
libavutil/lls-test.c
libavutil/lls.c
libavutil/log-test.c
libavutil/log.c
libavutil/md5-test.c
libavutil/md5.c
libavutil/murmur3-test.c
libavutil/murmur3.c
libavutil/opt-test.c
libavutil/opt.c
libavutil/parseutils-test.c
libavutil/parseutils.c
libavutil/pca-test.c
libavutil/pca.c
libavutil/pixdesc-test.c
libavutil/pixdesc.c
libavutil/pixelutils-test.c
libavutil/pixelutils.c
libavutil/random_seed-test.c
libavutil/random_seed.c
libavutil/rational-test.c
libavutil/rational.c
libavutil/ripemd-test.c
libavutil/ripemd.c
libavutil/sha-test.c
libavutil/sha.c
libavutil/sha512-test.c
libavutil/sha512.c
libavutil/softfloat-test.c
libavutil/tea-test.c
libavutil/tea.c
libavutil/tree-test.c
libavutil/tree.c
libavutil/twofish-test.c
libavutil/twofish.c
libavutil/utf8-test.c
libavutil/xtea-test.c
libavutil/xtea.c
library.mak
tests/ref/fate/source

@@@ -985,21 -783,11 +985,21 @@@ SKIPHEADERS-$(CONFIG_MEDIACODEC)       
  SKIPHEADERS-$(CONFIG_QSV)              += qsv.h qsv_internal.h
  SKIPHEADERS-$(CONFIG_QSVDEC)           += qsvdec.h
  SKIPHEADERS-$(CONFIG_QSVENC)           += qsvenc.h
 +SKIPHEADERS-$(CONFIG_XVMC)             += xvmc.h
  SKIPHEADERS-$(CONFIG_VAAPI)            += vaapi_encode.h vaapi_internal.h
 -SKIPHEADERS-$(CONFIG_VDA)              += vda.h vda_internal.h
 +SKIPHEADERS-$(CONFIG_VDA)              += vda.h vda_vt_internal.h
  SKIPHEADERS-$(CONFIG_VDPAU)            += vdpau.h vdpau_internal.h
-             avfft                                                       \
 +SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX)     += videotoolbox.h vda_vt_internal.h
 +
 +TESTPROGS = imgconvert                                                  \
 +            jpeg2000dwt                                                 \
 +            mathops                                                    \
 +            options                                                     \
 +            utils                                                       \
  
 -TESTPROGS-$(CONFIG_FFT)                   += fft fft-fixed
 +TESTPROGS-$(CONFIG_CABAC)                 += cabac
++TESTPROGS-$(CONFIG_DCT)                   += avfft
 +TESTPROGS-$(CONFIG_FFT)                   += fft fft-fixed fft-fixed32
  TESTPROGS-$(CONFIG_GOLOMB)                += golomb
  TESTPROGS-$(CONFIG_IDCTDSP)               += dct
  TESTPROGS-$(CONFIG_IIRFILTER)             += iirfilter
index 0000000,0000000..83949f4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,52 @@@
++/*
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "config.h"
++#include "avfft.h"
++
++int main(int argc, char **argv)
++{
++    int i;
++#define LEN 1024
++    FFTSample *ref  = av_malloc_array(LEN, sizeof(*ref));
++    FFTSample *data = av_malloc_array(LEN, sizeof(*data));
++    RDFTContext *rdft_context  = av_rdft_init(10, DFT_R2C);
++    RDFTContext *irdft_context = av_rdft_init(10, IDFT_C2R);
++
++    if (!ref || !data || !rdft_context || !irdft_context)
++        return 2;
++    for (i=0; i<LEN; i++) {
++        ref[i] = data[i] = i*456 + 123 + i*i;
++    }
++    av_rdft_calc(rdft_context, data);
++    av_rdft_calc(irdft_context, data);
++
++    for (i=0; i<LEN; i++) {
++        if (fabs(ref[i] - data[i]/LEN*2) > 1) {
++            fprintf(stderr, "Failed at %d (%f %f)\n", i, ref[i], data[i]/LEN*2);
++            return 1;
++        }
++    }
++
++    av_rdft_end(rdft_context);
++    av_rdft_end(irdft_context);
++    av_free(data);
++    av_free(ref);
++
++    return 0;
++}
Simple merge
index 0000000,0000000..47f31e9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,165 @@@
++/*
++ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "cabac.c"
++
++#define SIZE 10240
++
++#include "libavutil/lfg.h"
++#include "avcodec.h"
++
++static inline void put_cabac_bit(CABACContext *c, int b){
++    put_bits(&c->pb, 1, b);
++    for(;c->outstanding_count; c->outstanding_count--){
++        put_bits(&c->pb, 1, 1-b);
++    }
++}
++
++static inline void renorm_cabac_encoder(CABACContext *c){
++    while(c->range < 0x100){
++        //FIXME optimize
++        if(c->low<0x100){
++            put_cabac_bit(c, 0);
++        }else if(c->low<0x200){
++            c->outstanding_count++;
++            c->low -= 0x100;
++        }else{
++            put_cabac_bit(c, 1);
++            c->low -= 0x200;
++        }
++
++        c->range+= c->range;
++        c->low += c->low;
++    }
++}
++
++static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
++    int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
++
++    if(bit == ((*state)&1)){
++        c->range -= RangeLPS;
++        *state    = ff_h264_mlps_state[128 + *state];
++    }else{
++        c->low += c->range - RangeLPS;
++        c->range = RangeLPS;
++        *state= ff_h264_mlps_state[127 - *state];
++    }
++
++    renorm_cabac_encoder(c);
++}
++
++/**
++ * @param bit 0 -> write zero bit, !=0 write one bit
++ */
++static void put_cabac_bypass(CABACContext *c, int bit){
++    c->low += c->low;
++
++    if(bit){
++        c->low += c->range;
++    }
++//FIXME optimize
++    if(c->low<0x200){
++        put_cabac_bit(c, 0);
++    }else if(c->low<0x400){
++        c->outstanding_count++;
++        c->low -= 0x200;
++    }else{
++        put_cabac_bit(c, 1);
++        c->low -= 0x400;
++    }
++}
++
++/**
++ *
++ * @return the number of bytes written
++ */
++static int put_cabac_terminate(CABACContext *c, int bit){
++    c->range -= 2;
++
++    if(!bit){
++        renorm_cabac_encoder(c);
++    }else{
++        c->low += c->range;
++        c->range= 2;
++
++        renorm_cabac_encoder(c);
++
++        av_assert0(c->low <= 0x1FF);
++        put_cabac_bit(c, c->low>>9);
++        put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
++
++        flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
++    }
++
++    return (put_bits_count(&c->pb)+7)>>3;
++}
++
++int main(void){
++    CABACContext c;
++    uint8_t b[9*SIZE];
++    uint8_t r[9*SIZE];
++    int i, ret = 0;
++    uint8_t state[10]= {0};
++    AVLFG prng;
++
++    av_lfg_init(&prng, 1);
++    ff_init_cabac_encoder(&c, b, SIZE);
++
++    for(i=0; i<SIZE; i++){
++        if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
++        else         r[i] = (i>>8)&1;
++    }
++
++    for(i=0; i<SIZE; i++){
++        put_cabac_bypass(&c, r[i]&1);
++    }
++
++    for(i=0; i<SIZE; i++){
++        put_cabac(&c, state, r[i]&1);
++    }
++
++    i= put_cabac_terminate(&c, 1);
++    b[i++] = av_lfg_get(&prng);
++    b[i  ] = av_lfg_get(&prng);
++
++    ff_init_cabac_decoder(&c, b, SIZE);
++
++    memset(state, 0, sizeof(state));
++
++    for(i=0; i<SIZE; i++){
++        if( (r[i]&1) != get_cabac_bypass(&c) ) {
++            av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
++            ret = 1;
++        }
++    }
++
++    for(i=0; i<SIZE; i++){
++        if( (r[i]&1) != get_cabac_noinline(&c, state) ) {
++            av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
++            ret = 1;
++        }
++    }
++    if(!get_cabac_terminate(&c)) {
++        av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
++        ret = 1;
++    }
++
++    return ret;
++}
@@@ -182,168 -168,9 +182,21 @@@ int ff_init_cabac_decoder(CABACContext 
  #if CABAC_BITS == 16
      c->low =  (*c->bytestream++)<<18;
      c->low+=  (*c->bytestream++)<<10;
 +    // Keep our fetches on a 2-byte boundry as this should avoid ever having to
 +    // do unaligned loads if the compiler (or asm) optimises the double byte
 +    // load into a single instruction
 +    if(((uintptr_t)c->bytestream & 1) == 0) {
 +        c->low += (1 << 9);
 +    }
 +    else {
 +        c->low += ((*c->bytestream++) << 2) + 2;
 +    }
  #else
      c->low =  (*c->bytestream++)<<10;
 -#endif
      c->low+= ((*c->bytestream++)<<2) + 2;
 +#endif
      c->range= 0x1FE;
 +    if ((c->range<<(CABAC_BITS+1)) < c->low)
 +        return AVERROR_INVALIDDATA;
 +    return 0;
  }
- #ifdef TEST
- #define SIZE 10240
- #include "libavutil/lfg.h"
- #include "avcodec.h"
- static inline void put_cabac_bit(CABACContext *c, int b){
-     put_bits(&c->pb, 1, b);
-     for(;c->outstanding_count; c->outstanding_count--){
-         put_bits(&c->pb, 1, 1-b);
-     }
- }
- static inline void renorm_cabac_encoder(CABACContext *c){
-     while(c->range < 0x100){
-         //FIXME optimize
-         if(c->low<0x100){
-             put_cabac_bit(c, 0);
-         }else if(c->low<0x200){
-             c->outstanding_count++;
-             c->low -= 0x100;
-         }else{
-             put_cabac_bit(c, 1);
-             c->low -= 0x200;
-         }
-         c->range+= c->range;
-         c->low += c->low;
-     }
- }
- static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
-     int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
-     if(bit == ((*state)&1)){
-         c->range -= RangeLPS;
-         *state    = ff_h264_mlps_state[128 + *state];
-     }else{
-         c->low += c->range - RangeLPS;
-         c->range = RangeLPS;
-         *state= ff_h264_mlps_state[127 - *state];
-     }
-     renorm_cabac_encoder(c);
- }
- /**
-  * @param bit 0 -> write zero bit, !=0 write one bit
-  */
- static void put_cabac_bypass(CABACContext *c, int bit){
-     c->low += c->low;
-     if(bit){
-         c->low += c->range;
-     }
- //FIXME optimize
-     if(c->low<0x200){
-         put_cabac_bit(c, 0);
-     }else if(c->low<0x400){
-         c->outstanding_count++;
-         c->low -= 0x200;
-     }else{
-         put_cabac_bit(c, 1);
-         c->low -= 0x400;
-     }
- }
- /**
-  *
-  * @return the number of bytes written
-  */
- static int put_cabac_terminate(CABACContext *c, int bit){
-     c->range -= 2;
-     if(!bit){
-         renorm_cabac_encoder(c);
-     }else{
-         c->low += c->range;
-         c->range= 2;
-         renorm_cabac_encoder(c);
-         av_assert0(c->low <= 0x1FF);
-         put_cabac_bit(c, c->low>>9);
-         put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
-         flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
-     }
-     return (put_bits_count(&c->pb)+7)>>3;
- }
- int main(void){
-     CABACContext c;
-     uint8_t b[9*SIZE];
-     uint8_t r[9*SIZE];
-     int i, ret = 0;
-     uint8_t state[10]= {0};
-     AVLFG prng;
-     av_lfg_init(&prng, 1);
-     ff_init_cabac_encoder(&c, b, SIZE);
-     for(i=0; i<SIZE; i++){
-         if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
-         else         r[i] = (i>>8)&1;
-     }
-     for(i=0; i<SIZE; i++){
-         put_cabac_bypass(&c, r[i]&1);
-     }
-     for(i=0; i<SIZE; i++){
-         put_cabac(&c, state, r[i]&1);
-     }
-     i= put_cabac_terminate(&c, 1);
-     b[i++] = av_lfg_get(&prng);
-     b[i  ] = av_lfg_get(&prng);
-     ff_init_cabac_decoder(&c, b, SIZE);
-     memset(state, 0, sizeof(state));
-     for(i=0; i<SIZE; i++){
-         if( (r[i]&1) != get_cabac_bypass(&c) ) {
-             av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
-             ret = 1;
-         }
-     }
-     for(i=0; i<SIZE; i++){
-         if( (r[i]&1) != get_cabac_noinline(&c, state) ) {
-             av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
-             ret = 1;
-         }
-     }
-     if(!get_cabac_terminate(&c)) {
-         av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
-         ret = 1;
-     }
-     return ret;
- }
- #endif /* TEST */
index 0000000,139a35d..0138097
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,52 +1,52 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    ff_iir_filter_free_coeffs(fcoeffs);
 -    ff_iir_filter_free_state(fstate);
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <math.h>
+ #include <stdint.h>
+ #include <stdio.h>
+ #include "iirfilter.h"
+ #define FILT_ORDER 4
+ #define SIZE 1024
+ int main(void)
+ {
+     struct FFIIRFilterCoeffs *fcoeffs = NULL;
+     struct FFIIRFilterState  *fstate  = NULL;
+     float cutoff_coeff = 0.4;
+     int16_t x[SIZE], y[SIZE];
+     int i;
+     fcoeffs = ff_iir_filter_init_coeffs(NULL, FF_FILTER_TYPE_BUTTERWORTH,
+                                         FF_FILTER_MODE_LOWPASS, FILT_ORDER,
+                                         cutoff_coeff, 0.0, 0.0);
+     fstate  = ff_iir_filter_init_state(FILT_ORDER);
+     for (i = 0; i < SIZE; i++)
+         x[i] = lrint(0.75 * INT16_MAX * sin(0.5 * M_PI * i * i / SIZE));
+     ff_iir_filter(fcoeffs, fstate, SIZE, x, 1, y, 1);
+     for (i = 0; i < SIZE; i++)
+         printf("%6d %6d\n", x[i], y[i]);
++    ff_iir_filter_free_coeffsp(&fcoeffs);
++    ff_iir_filter_free_statep(&fstate);
+     return 0;
+ }
@@@ -302,56 -302,16 +302,24 @@@ void ff_iir_filter_flt(const struct FFI
      }
  }
  
 -av_cold void ff_iir_filter_free_state(struct FFIIRFilterState *state)
 +av_cold void ff_iir_filter_free_statep(struct FFIIRFilterState **state)
  {
 -    av_free(state);
 +    av_freep(state);
  }
  
 -av_cold void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs)
 +av_cold void ff_iir_filter_free_coeffsp(struct FFIIRFilterCoeffs **coeffsp)
  {
 +    struct FFIIRFilterCoeffs *coeffs = *coeffsp;
      if (coeffs) {
 -        av_free(coeffs->cx);
 -        av_free(coeffs->cy);
 +        av_freep(&coeffs->cx);
 +        av_freep(&coeffs->cy);
      }
 -    av_free(coeffs);
 +    av_freep(coeffsp);
 +}
 +
 +void ff_iir_filter_init(FFIIRFilterContext *f) {
 +    f->filter_flt = ff_iir_filter_flt;
 +
 +    if (HAVE_MIPSFPU)
 +        ff_iir_filter_init_mips(f);
  }
- #ifdef TEST
- #include <stdio.h>
- #define FILT_ORDER 4
- #define SIZE 1024
- int main(void)
- {
-     struct FFIIRFilterCoeffs *fcoeffs = NULL;
-     struct FFIIRFilterState  *fstate  = NULL;
-     float cutoff_coeff = 0.4;
-     int16_t x[SIZE], y[SIZE];
-     int i;
-     fcoeffs = ff_iir_filter_init_coeffs(NULL, FF_FILTER_TYPE_BUTTERWORTH,
-                                         FF_FILTER_MODE_LOWPASS, FILT_ORDER,
-                                         cutoff_coeff, 0.0, 0.0);
-     fstate  = ff_iir_filter_init_state(FILT_ORDER);
-     for (i = 0; i < SIZE; i++)
-         x[i] = lrint(0.75 * INT16_MAX * sin(0.5 * M_PI * i * i / SIZE));
-     ff_iir_filter(fcoeffs, fstate, SIZE, x, 1, y, 1);
-     for (i = 0; i < SIZE; i++)
-         printf("%6d %6d\n", x[i], y[i]);
-     ff_iir_filter_free_coeffsp(&fcoeffs);
-     ff_iir_filter_free_statep(&fstate);
-     return 0;
- }
- #endif /* TEST */
index 0000000,0000000..96004d7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,50 @@@
++/*
++ * Misc image conversion routines
++ * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "imgconvert.c"
++
++#if FF_API_AVPICTURE
++FF_DISABLE_DEPRECATION_WARNINGS
++int main(void){
++    int i;
++    int err=0;
++    int skip = 0;
++
++    for (i=0; i<AV_PIX_FMT_NB*2; i++) {
++        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
++        if(!desc || !desc->name) {
++            skip ++;
++            continue;
++        }
++        if (skip) {
++            av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
++            skip = 0;
++        }
++        av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc));
++        if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
++            av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
++            err = 1;
++        }
++    }
++    return err;
++}
++FF_ENABLE_DEPRECATION_WARNINGS
++#endif /* FF_API_AVPICTURE */
@@@ -228,36 -245,8 +228,8 @@@ int av_picture_pad(AVPicture *dst, cons
                  (padbottom >> y_shift) + (padright >> x_shift));
          }
      }
 +
      return 0;
  }
- #ifdef TEST
- int main(void){
-     int i;
-     int err=0;
-     int skip = 0;
-     for (i=0; i<AV_PIX_FMT_NB*2; i++) {
-         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
-         if(!desc || !desc->name) {
-             skip ++;
-             continue;
-         }
-         if (skip) {
-             av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
-             skip = 0;
-         }
-         av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc));
-         if ((!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
-             av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
-             err = 1;
-         }
-     }
-     return err;
- }
--
- #endif
  FF_ENABLE_DEPRECATION_WARNINGS
  #endif /* FF_API_AVPICTURE */
index 0000000,0000000..30f1ce1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,141 @@@
++/*
++ * Discrete wavelet transform
++ * Copyright (c) 2007 Kamil Nowosad
++ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "jpeg2000dwt.c"
++
++#include "libavutil/lfg.h"
++
++#define MAX_W 256
++
++static int test_dwt(int *array, int *ref, int border[2][2], int decomp_levels, int type, int max_diff) {
++    int ret, j;
++    DWTContext s1={{{0}}}, *s= &s1;
++    int64_t err2 = 0;
++
++    ret = ff_jpeg2000_dwt_init(s,  border, decomp_levels, type);
++    if (ret < 0) {
++        fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
++        return 1;
++    }
++    ret = ff_dwt_encode(s, array);
++    if (ret < 0) {
++        fprintf(stderr, "ff_dwt_encode failed\n");
++        return 1;
++    }
++    ret = ff_dwt_decode(s, array);
++    if (ret < 0) {
++        fprintf(stderr, "ff_dwt_encode failed\n");
++        return 1;
++    }
++    for (j = 0; j<MAX_W * MAX_W; j++) {
++        if (FFABS(array[j] - ref[j]) > max_diff) {
++            fprintf(stderr, "missmatch at %d (%d != %d) decomp:%d border %d %d %d %d\n",
++                    j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
++            return 2;
++        }
++        err2 += (array[j] - ref[j]) * (array[j] - ref[j]);
++        array[j] = ref[j];
++    }
++    ff_dwt_destroy(s);
++
++    printf("%s, decomp:%2d border %3d %3d %3d %3d milli-err2:%9"PRId64"\n",
++           type == FF_DWT53 ? "5/3i" : "9/7i",
++           decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1],
++           1000*err2 / ((border[0][1] - border[0][0])*(border[1][1] - border[1][0])));
++
++    return 0;
++}
++
++static int test_dwtf(float *array, float *ref, int border[2][2], int decomp_levels, float max_diff) {
++    int ret, j;
++    DWTContext s1={{{0}}}, *s= &s1;
++    double err2 = 0;
++
++    ret = ff_jpeg2000_dwt_init(s,  border, decomp_levels, FF_DWT97);
++    if (ret < 0) {
++        fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
++        return 1;
++    }
++    ret = ff_dwt_encode(s, array);
++    if (ret < 0) {
++        fprintf(stderr, "ff_dwt_encode failed\n");
++        return 1;
++    }
++    ret = ff_dwt_decode(s, array);
++    if (ret < 0) {
++        fprintf(stderr, "ff_dwt_encode failed\n");
++        return 1;
++    }
++    for (j = 0; j<MAX_W * MAX_W; j++) {
++        if (FFABS(array[j] - ref[j]) > max_diff) {
++            fprintf(stderr, "missmatch at %d (%f != %f) decomp:%d border %d %d %d %d\n",
++                    j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
++            return 2;
++        }
++        err2 += (array[j] - ref[j]) * (array[j] - ref[j]);
++        array[j] = ref[j];
++    }
++    ff_dwt_destroy(s);
++
++    printf("9/7f, decomp:%2d border %3d %3d %3d %3d err2:%20.3f\n",
++           decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1],
++           err2 / ((border[0][1] - border[0][0])*(border[1][1] - border[1][0])));
++
++    return 0;
++}
++
++static int array[MAX_W * MAX_W];
++static int ref  [MAX_W * MAX_W];
++static float arrayf[MAX_W * MAX_W];
++static float reff  [MAX_W * MAX_W];
++
++int main(void) {
++    AVLFG prng;
++    int i,j;
++    int border[2][2];
++    int ret, decomp_levels;
++
++    av_lfg_init(&prng, 1);
++
++    for (i = 0; i<MAX_W * MAX_W; i++)
++        arrayf[i] = reff[i] = array[i] = ref[i] =  av_lfg_get(&prng) % 2048;
++
++    for (i = 0; i < 100; i++) {
++        for (j=0; j<4; j++)
++            border[j>>1][j&1] = av_lfg_get(&prng) % MAX_W;
++        if (border[0][0] >= border[0][1] || border[1][0] >= border[1][1])
++            continue;
++        decomp_levels = av_lfg_get(&prng) % FF_DWT_MAX_DECLVLS;
++
++        ret = test_dwt(array, ref, border, decomp_levels, FF_DWT53, 0);
++        if (ret)
++            return ret;
++        ret = test_dwt(array, ref, border, decomp_levels, FF_DWT97_INT, FFMIN(7+5*decomp_levels, 15+3*decomp_levels));
++        if (ret)
++            return ret;
++        ret = test_dwtf(arrayf, reff, border, decomp_levels, 0.05);
++        if (ret)
++            return ret;
++    }
++
++    return 0;
++}
Simple merge
index 0000000,0000000..d47f144
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,41 @@@
++/*
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "mathops.h"
++
++#include <stdlib.h>
++
++int main(void)
++{
++    unsigned u;
++
++    for(u=0; u<65536; u++) {
++        unsigned s = u*u;
++        unsigned root = ff_sqrt(s);
++        unsigned root_m1 = ff_sqrt(s-1);
++        if (s && root != u) {
++            fprintf(stderr, "ff_sqrt failed at %u with %u\n", s, root);
++            return 1;
++        }
++        if (u && root_m1 != u - 1) {
++            fprintf(stderr, "ff_sqrt failed at %u with %u\n", s, root);
++            return 1;
++        }
++    }
++    return 0;
++}
index 0000000,0000000..2a08579
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,189 @@@
++/*
++ * Copyright (c) 2001 Fabrice Bellard
++ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "options.c"
++
++static int dummy_init(AVCodecContext *ctx)
++{
++    //TODO: this code should set every possible pointer that could be set by codec and is not an option;
++    ctx->extradata_size = 8;
++    ctx->extradata = av_malloc(ctx->extradata_size);
++    return 0;
++}
++
++static int dummy_close(AVCodecContext *ctx)
++{
++    av_freep(&ctx->extradata);
++    ctx->extradata_size = 0;
++    return 0;
++}
++
++static int dummy_encode(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
++{
++    return AVERROR(ENOSYS);
++}
++
++typedef struct Dummy12Context {
++    AVClass  *av_class;
++    int      num;
++    char*    str;
++} Dummy12Context;
++
++typedef struct Dummy3Context {
++    void     *fake_av_class;
++    int      num;
++    char*    str;
++} Dummy3Context;
++
++#define OFFSET(x) offsetof(Dummy12Context, x)
++#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
++static const AVOption dummy_options[] = {
++    { "str", "set str", OFFSET(str), AV_OPT_TYPE_STRING, { .str = "i'm src default value" }, 0, 0, VE},
++    { "num", "set num", OFFSET(num), AV_OPT_TYPE_INT,    { .i64 = 1500100900 },    0, INT_MAX, VE},
++    { NULL },
++};
++
++static const AVClass dummy_v1_class = {
++    .class_name = "dummy_v1_class",
++    .item_name  = av_default_item_name,
++    .option     = dummy_options,
++    .version    = LIBAVUTIL_VERSION_INT,
++};
++
++static const AVClass dummy_v2_class = {
++    .class_name = "dummy_v2_class",
++    .item_name  = av_default_item_name,
++    .option     = dummy_options,
++    .version    = LIBAVUTIL_VERSION_INT,
++};
++
++/* codec with options */
++static AVCodec dummy_v1_encoder = {
++    .name             = "dummy_v1_codec",
++    .type             = AVMEDIA_TYPE_VIDEO,
++    .id               = AV_CODEC_ID_NONE - 1,
++    .encode2          = dummy_encode,
++    .init             = dummy_init,
++    .close            = dummy_close,
++    .priv_class       = &dummy_v1_class,
++    .priv_data_size   = sizeof(Dummy12Context),
++};
++
++/* codec with options, different class */
++static AVCodec dummy_v2_encoder = {
++    .name             = "dummy_v2_codec",
++    .type             = AVMEDIA_TYPE_VIDEO,
++    .id               = AV_CODEC_ID_NONE - 2,
++    .encode2          = dummy_encode,
++    .init             = dummy_init,
++    .close            = dummy_close,
++    .priv_class       = &dummy_v2_class,
++    .priv_data_size   = sizeof(Dummy12Context),
++};
++
++/* codec with priv data, but no class */
++static AVCodec dummy_v3_encoder = {
++    .name             = "dummy_v3_codec",
++    .type             = AVMEDIA_TYPE_VIDEO,
++    .id               = AV_CODEC_ID_NONE - 3,
++    .encode2          = dummy_encode,
++    .init             = dummy_init,
++    .close            = dummy_close,
++    .priv_data_size   = sizeof(Dummy3Context),
++};
++
++/* codec without priv data */
++static AVCodec dummy_v4_encoder = {
++    .name             = "dummy_v4_codec",
++    .type             = AVMEDIA_TYPE_VIDEO,
++    .id               = AV_CODEC_ID_NONE - 4,
++    .encode2          = dummy_encode,
++    .init             = dummy_init,
++    .close            = dummy_close,
++};
++
++static void test_copy_print_codec(const AVCodecContext *ctx)
++{
++    printf("%-14s: %dx%d prv: %s",
++           ctx->codec ? ctx->codec->name : "NULL",
++           ctx->width, ctx->height,
++           ctx->priv_data ? "set" : "null");
++    if (ctx->codec && ctx->codec->priv_class && ctx->codec->priv_data_size) {
++        int64_t i64;
++        char *str = NULL;
++        av_opt_get_int(ctx->priv_data, "num", 0, &i64);
++        av_opt_get(ctx->priv_data, "str", 0, (uint8_t**)&str);
++        printf(" opts: %"PRId64" %s", i64, str);
++        av_free(str);
++    }
++    printf("\n");
++}
++
++static void test_copy(const AVCodec *c1, const AVCodec *c2)
++{
++    AVCodecContext *ctx1, *ctx2;
++    printf("%s -> %s\nclosed:\n", c1 ? c1->name : "NULL", c2 ? c2->name : "NULL");
++    ctx1 = avcodec_alloc_context3(c1);
++    ctx2 = avcodec_alloc_context3(c2);
++    ctx1->width = ctx1->height = 128;
++    if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
++        av_opt_set(ctx2->priv_data, "num", "667", 0);
++        av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
++    }
++    avcodec_copy_context(ctx2, ctx1);
++    test_copy_print_codec(ctx1);
++    test_copy_print_codec(ctx2);
++    if (ctx1->codec) {
++        printf("opened:\n");
++        avcodec_open2(ctx1, ctx1->codec, NULL);
++        if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
++            av_opt_set(ctx2->priv_data, "num", "667", 0);
++            av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
++        }
++        avcodec_copy_context(ctx2, ctx1);
++        test_copy_print_codec(ctx1);
++        test_copy_print_codec(ctx2);
++        avcodec_close(ctx1);
++    }
++    avcodec_free_context(&ctx1);
++    avcodec_free_context(&ctx2);
++}
++
++int main(void)
++{
++    AVCodec *dummy_codec[] = {
++        &dummy_v1_encoder,
++        &dummy_v2_encoder,
++        &dummy_v3_encoder,
++        &dummy_v4_encoder,
++        NULL,
++    };
++    int i, j;
++
++    for (i = 0; dummy_codec[i]; i++)
++        avcodec_register(dummy_codec[i]);
++
++    printf("testing avcodec_copy_context()\n");
++    for (i = 0; i < FF_ARRAY_ELEMS(dummy_codec); i++)
++        for (j = 0; j < FF_ARRAY_ELEMS(dummy_codec); j++)
++            test_copy(dummy_codec[i], dummy_codec[j]);
++    return 0;
++}
index 0000000,f4c76c0..2892949
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,64 +1,64 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    ff_build_rac_states(&c, 0.05 * (1LL << 32), 128 + 64 + 32 + 16);
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdint.h>
+ #include <string.h>
+ #include "libavutil/lfg.h"
+ #include "libavutil/log.h"
+ #include "rangecoder.h"
+ #define SIZE 10240
+ int main(void)
+ {
+     RangeCoder c;
+     uint8_t b[9 * SIZE];
+     uint8_t r[9 * SIZE];
+     int i;
+     uint8_t state[10];
+     AVLFG prng;
+     av_lfg_init(&prng, 1);
+     ff_init_range_encoder(&c, b, SIZE);
++    ff_build_rac_states(&c, (1LL << 32) / 20, 128 + 64 + 32 + 16);
+     memset(state, 128, sizeof(state));
+     for (i = 0; i < SIZE; i++)
+         r[i] = av_lfg_get(&prng) % 7;
+     for (i = 0; i < SIZE; i++)
+         put_rac(&c, state, r[i] & 1);
+     ff_rac_terminate(&c);
+     ff_init_range_decoder(&c, b, SIZE);
+     memset(state, 128, sizeof(state));
+     for (i = 0; i < SIZE; i++)
+         if ((r[i] & 1) != get_rac(&c, state)) {
+             av_log(NULL, AV_LOG_ERROR, "rac failure at %d\n", i);
+             return 1;
+         }
+     return 0;
+ }
Simple merge
index 0000000,0000000..e1ed86f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,147 @@@
++/*
++ * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "snowenc.c"
++
++#undef malloc
++#undef free
++#undef printf
++
++#include "libavutil/lfg.h"
++#include "libavutil/mathematics.h"
++
++int main(void){
++#define width  256
++#define height 256
++    int buffer[2][width*height];
++    SnowContext s;
++    int i;
++    AVLFG prng;
++    s.spatial_decomposition_count=6;
++    s.spatial_decomposition_type=1;
++
++    s.temp_dwt_buffer  = av_mallocz_array(width, sizeof(DWTELEM));
++    s.temp_idwt_buffer = av_mallocz_array(width, sizeof(IDWTELEM));
++
++    if (!s.temp_dwt_buffer || !s.temp_idwt_buffer) {
++        fprintf(stderr, "Failed to allocate memory\n");
++        return 1;
++    }
++
++    av_lfg_init(&prng, 1);
++
++    printf("testing 5/3 DWT\n");
++    for(i=0; i<width*height; i++)
++        buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
++
++    ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
++    ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
++
++    for(i=0; i<width*height; i++)
++        if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
++
++    printf("testing 9/7 DWT\n");
++    s.spatial_decomposition_type=0;
++    for(i=0; i<width*height; i++)
++        buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
++
++    ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
++    ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
++
++    for(i=0; i<width*height; i++)
++        if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
++
++    {
++    int level, orientation, x, y;
++    int64_t errors[8][4];
++    int64_t g=0;
++
++        memset(errors, 0, sizeof(errors));
++        s.spatial_decomposition_count=3;
++        s.spatial_decomposition_type=0;
++        for(level=0; level<s.spatial_decomposition_count; level++){
++            for(orientation=level ? 1 : 0; orientation<4; orientation++){
++                int w= width  >> (s.spatial_decomposition_count-level);
++                int h= height >> (s.spatial_decomposition_count-level);
++                int stride= width  << (s.spatial_decomposition_count-level);
++                DWTELEM *buf= buffer[0];
++                int64_t error=0;
++
++                if(orientation&1) buf+=w;
++                if(orientation>1) buf+=stride>>1;
++
++                memset(buffer[0], 0, sizeof(int)*width*height);
++                buf[w/2 + h/2*stride]= 256*256;
++                ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
++                for(y=0; y<height; y++){
++                    for(x=0; x<width; x++){
++                        int64_t d= buffer[0][x + y*width];
++                        error += d*d;
++                        if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d);
++                    }
++                    if(FFABS(height/2-y)<9 && level==2) printf("\n");
++                }
++                error= (int)(sqrt(error)+0.5);
++                errors[level][orientation]= error;
++                if(g) g=av_gcd(g, error);
++                else g= error;
++            }
++        }
++        printf("static int const visual_weight[][4]={\n");
++        for(level=0; level<s.spatial_decomposition_count; level++){
++            printf("  {");
++            for(orientation=0; orientation<4; orientation++){
++                printf("%8"PRId64",", errors[level][orientation]/g);
++            }
++            printf("},\n");
++        }
++        printf("};\n");
++        {
++            int level=2;
++            int w= width  >> (s.spatial_decomposition_count-level);
++            //int h= height >> (s.spatial_decomposition_count-level);
++            int stride= width  << (s.spatial_decomposition_count-level);
++            DWTELEM *buf= buffer[0];
++            int64_t error=0;
++
++            buf+=w;
++            buf+=stride>>1;
++
++            memset(buffer[0], 0, sizeof(int)*width*height);
++            for(y=0; y<height; y++){
++                for(x=0; x<width; x++){
++                    int tab[4]={0,2,3,1};
++                    buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)];
++                }
++            }
++            ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
++            for(y=0; y<height; y++){
++                for(x=0; x<width; x++){
++                    int64_t d= buffer[0][x + y*width];
++                    error += d*d;
++                    if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9) printf("%8"PRId64" ", d);
++                }
++                if(FFABS(height/2-y)<9) printf("\n");
++            }
++        }
++
++    }
++    return 0;
++}
index b1d177d,0000000..00aef57
mode 100644,000000..100644
--- /dev/null
@@@ -1,2086 -1,0 +1,1957 @@@
- #ifdef TEST
- #undef malloc
- #undef free
- #undef printf
- #include "libavutil/lfg.h"
- #include "libavutil/mathematics.h"
- int main(void){
- #define width  256
- #define height 256
-     int buffer[2][width*height];
-     SnowContext s;
-     int i;
-     AVLFG prng;
-     s.spatial_decomposition_count=6;
-     s.spatial_decomposition_type=1;
-     s.temp_dwt_buffer  = av_mallocz_array(width, sizeof(DWTELEM));
-     s.temp_idwt_buffer = av_mallocz_array(width, sizeof(IDWTELEM));
-     if (!s.temp_dwt_buffer || !s.temp_idwt_buffer) {
-         fprintf(stderr, "Failed to allocate memory\n");
-         return 1;
-     }
-     av_lfg_init(&prng, 1);
-     printf("testing 5/3 DWT\n");
-     for(i=0; i<width*height; i++)
-         buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
-     ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-     ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-     for(i=0; i<width*height; i++)
-         if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
-     printf("testing 9/7 DWT\n");
-     s.spatial_decomposition_type=0;
-     for(i=0; i<width*height; i++)
-         buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
-     ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-     ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-     for(i=0; i<width*height; i++)
-         if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
-     {
-     int level, orientation, x, y;
-     int64_t errors[8][4];
-     int64_t g=0;
-         memset(errors, 0, sizeof(errors));
-         s.spatial_decomposition_count=3;
-         s.spatial_decomposition_type=0;
-         for(level=0; level<s.spatial_decomposition_count; level++){
-             for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                 int w= width  >> (s.spatial_decomposition_count-level);
-                 int h= height >> (s.spatial_decomposition_count-level);
-                 int stride= width  << (s.spatial_decomposition_count-level);
-                 DWTELEM *buf= buffer[0];
-                 int64_t error=0;
-                 if(orientation&1) buf+=w;
-                 if(orientation>1) buf+=stride>>1;
-                 memset(buffer[0], 0, sizeof(int)*width*height);
-                 buf[w/2 + h/2*stride]= 256*256;
-                 ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-                 for(y=0; y<height; y++){
-                     for(x=0; x<width; x++){
-                         int64_t d= buffer[0][x + y*width];
-                         error += d*d;
-                         if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d);
-                     }
-                     if(FFABS(height/2-y)<9 && level==2) printf("\n");
-                 }
-                 error= (int)(sqrt(error)+0.5);
-                 errors[level][orientation]= error;
-                 if(g) g=av_gcd(g, error);
-                 else g= error;
-             }
-         }
-         printf("static int const visual_weight[][4]={\n");
-         for(level=0; level<s.spatial_decomposition_count; level++){
-             printf("  {");
-             for(orientation=0; orientation<4; orientation++){
-                 printf("%8"PRId64",", errors[level][orientation]/g);
-             }
-             printf("},\n");
-         }
-         printf("};\n");
-         {
-             int level=2;
-             int w= width  >> (s.spatial_decomposition_count-level);
-             //int h= height >> (s.spatial_decomposition_count-level);
-             int stride= width  << (s.spatial_decomposition_count-level);
-             DWTELEM *buf= buffer[0];
-             int64_t error=0;
-             buf+=w;
-             buf+=stride>>1;
-             memset(buffer[0], 0, sizeof(int)*width*height);
-             for(y=0; y<height; y++){
-                 for(x=0; x<width; x++){
-                     int tab[4]={0,2,3,1};
-                     buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)];
-                 }
-             }
-             ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
-             for(y=0; y<height; y++){
-                 for(x=0; x<width; x++){
-                     int64_t d= buffer[0][x + y*width];
-                     error += d*d;
-                     if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9) printf("%8"PRId64" ", d);
-                 }
-                 if(FFABS(height/2-y)<9) printf("\n");
-             }
-         }
-     }
-     return 0;
- }
- #endif /* TEST */
 +/*
 + * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include "libavutil/intmath.h"
 +#include "libavutil/libm.h"
 +#include "libavutil/log.h"
 +#include "libavutil/opt.h"
 +#include "avcodec.h"
 +#include "internal.h"
 +#include "snow_dwt.h"
 +#include "snow.h"
 +
 +#include "rangecoder.h"
 +#include "mathops.h"
 +
 +#include "mpegvideo.h"
 +#include "h263.h"
 +
 +#define FF_ME_ITER 50
 +
 +static av_cold int encode_init(AVCodecContext *avctx)
 +{
 +    SnowContext *s = avctx->priv_data;
 +    int plane_index, ret;
 +    int i;
 +
 +#if FF_API_PRIVATE_OPT
 +FF_DISABLE_DEPRECATION_WARNINGS
 +    if (avctx->prediction_method)
 +        s->pred = avctx->prediction_method;
 +FF_ENABLE_DEPRECATION_WARNINGS
 +#endif
 +
 +    if(s->pred == DWT_97
 +       && (avctx->flags & AV_CODEC_FLAG_QSCALE)
 +       && avctx->global_quality == 0){
 +        av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n");
 +        return -1;
 +    }
 +#if FF_API_MOTION_EST
 +FF_DISABLE_DEPRECATION_WARNINGS
 +    if (avctx->me_method == ME_ITER)
 +        s->motion_est = FF_ME_ITER;
 +FF_ENABLE_DEPRECATION_WARNINGS
 +#endif
 +
 +    s->spatial_decomposition_type= s->pred; //FIXME add decorrelator type r transform_type
 +
 +    s->mv_scale       = (avctx->flags & AV_CODEC_FLAG_QPEL) ? 2 : 4;
 +    s->block_max_depth= (avctx->flags & AV_CODEC_FLAG_4MV ) ? 1 : 0;
 +
 +    for(plane_index=0; plane_index<3; plane_index++){
 +        s->plane[plane_index].diag_mc= 1;
 +        s->plane[plane_index].htaps= 6;
 +        s->plane[plane_index].hcoeff[0]=  40;
 +        s->plane[plane_index].hcoeff[1]= -10;
 +        s->plane[plane_index].hcoeff[2]=   2;
 +        s->plane[plane_index].fast_mc= 1;
 +    }
 +
 +    if ((ret = ff_snow_common_init(avctx)) < 0) {
 +        return ret;
 +    }
 +    ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
 +
 +    ff_snow_alloc_blocks(s);
 +
 +    s->version=0;
 +
 +    s->m.avctx   = avctx;
 +    s->m.bit_rate= avctx->bit_rate;
 +
 +    s->m.me.temp      =
 +    s->m.me.scratchpad= av_mallocz_array((avctx->width+64), 2*16*2*sizeof(uint8_t));
 +    s->m.me.map       = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
 +    s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
 +    s->m.sc.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
 +    if (!s->m.me.scratchpad || !s->m.me.map || !s->m.me.score_map || !s->m.sc.obmc_scratchpad)
 +        return AVERROR(ENOMEM);
 +
 +    ff_h263_encode_init(&s->m); //mv_penalty
 +
 +    s->max_ref_frames = av_clip(avctx->refs, 1, MAX_REF_FRAMES);
 +
 +    if(avctx->flags&AV_CODEC_FLAG_PASS1){
 +        if(!avctx->stats_out)
 +            avctx->stats_out = av_mallocz(256);
 +
 +        if (!avctx->stats_out)
 +            return AVERROR(ENOMEM);
 +    }
 +    if((avctx->flags&AV_CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){
 +        if(ff_rate_control_init(&s->m) < 0)
 +            return -1;
 +    }
 +    s->pass1_rc= !(avctx->flags & (AV_CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2));
 +
 +    switch(avctx->pix_fmt){
 +    case AV_PIX_FMT_YUV444P:
 +//    case AV_PIX_FMT_YUV422P:
 +    case AV_PIX_FMT_YUV420P:
 +//    case AV_PIX_FMT_YUV411P:
 +    case AV_PIX_FMT_YUV410P:
 +        s->nb_planes = 3;
 +        s->colorspace_type= 0;
 +        break;
 +    case AV_PIX_FMT_GRAY8:
 +        s->nb_planes = 1;
 +        s->colorspace_type = 1;
 +        break;
 +/*    case AV_PIX_FMT_RGB32:
 +        s->colorspace= 1;
 +        break;*/
 +    default:
 +        av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n");
 +        return -1;
 +    }
 +    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
 +
 +    ff_set_cmp(&s->mecc, s->mecc.me_cmp, s->avctx->me_cmp);
 +    ff_set_cmp(&s->mecc, s->mecc.me_sub_cmp, s->avctx->me_sub_cmp);
 +
 +    s->input_picture = av_frame_alloc();
 +    if (!s->input_picture)
 +        return AVERROR(ENOMEM);
 +
 +    if ((ret = ff_snow_get_buffer(s, s->input_picture)) < 0)
 +        return ret;
 +
 +    if(s->motion_est == FF_ME_ITER){
 +        int size= s->b_width * s->b_height << 2*s->block_max_depth;
 +        for(i=0; i<s->max_ref_frames; i++){
 +            s->ref_mvs[i]= av_mallocz_array(size, sizeof(int16_t[2]));
 +            s->ref_scores[i]= av_mallocz_array(size, sizeof(uint32_t));
 +            if (!s->ref_mvs[i] || !s->ref_scores[i])
 +                return AVERROR(ENOMEM);
 +        }
 +    }
 +
 +    return 0;
 +}
 +
 +//near copy & paste from dsputil, FIXME
 +static int pix_sum(uint8_t * pix, int line_size, int w, int h)
 +{
 +    int s, i, j;
 +
 +    s = 0;
 +    for (i = 0; i < h; i++) {
 +        for (j = 0; j < w; j++) {
 +            s += pix[0];
 +            pix ++;
 +        }
 +        pix += line_size - w;
 +    }
 +    return s;
 +}
 +
 +//near copy & paste from dsputil, FIXME
 +static int pix_norm1(uint8_t * pix, int line_size, int w)
 +{
 +    int s, i, j;
 +    uint32_t *sq = ff_square_tab + 256;
 +
 +    s = 0;
 +    for (i = 0; i < w; i++) {
 +        for (j = 0; j < w; j ++) {
 +            s += sq[pix[0]];
 +            pix ++;
 +        }
 +        pix += line_size - w;
 +    }
 +    return s;
 +}
 +
 +static inline int get_penalty_factor(int lambda, int lambda2, int type){
 +    switch(type&0xFF){
 +    default:
 +    case FF_CMP_SAD:
 +        return lambda>>FF_LAMBDA_SHIFT;
 +    case FF_CMP_DCT:
 +        return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
 +    case FF_CMP_W53:
 +        return (4*lambda)>>(FF_LAMBDA_SHIFT);
 +    case FF_CMP_W97:
 +        return (2*lambda)>>(FF_LAMBDA_SHIFT);
 +    case FF_CMP_SATD:
 +    case FF_CMP_DCT264:
 +        return (2*lambda)>>FF_LAMBDA_SHIFT;
 +    case FF_CMP_RD:
 +    case FF_CMP_PSNR:
 +    case FF_CMP_SSE:
 +    case FF_CMP_NSSE:
 +        return lambda2>>FF_LAMBDA_SHIFT;
 +    case FF_CMP_BIT:
 +        return 1;
 +    }
 +}
 +
 +//FIXME copy&paste
 +#define P_LEFT P[1]
 +#define P_TOP P[2]
 +#define P_TOPRIGHT P[3]
 +#define P_MEDIAN P[4]
 +#define P_MV1 P[9]
 +#define FLAG_QPEL   1 //must be 1
 +
 +static int encode_q_branch(SnowContext *s, int level, int x, int y){
 +    uint8_t p_buffer[1024];
 +    uint8_t i_buffer[1024];
 +    uint8_t p_state[sizeof(s->block_state)];
 +    uint8_t i_state[sizeof(s->block_state)];
 +    RangeCoder pc, ic;
 +    uint8_t *pbbak= s->c.bytestream;
 +    uint8_t *pbbak_start= s->c.bytestream_start;
 +    int score, score2, iscore, i_len, p_len, block_s, sum, base_bits;
 +    const int w= s->b_width  << s->block_max_depth;
 +    const int h= s->b_height << s->block_max_depth;
 +    const int rem_depth= s->block_max_depth - level;
 +    const int index= (x + y*w) << rem_depth;
 +    const int block_w= 1<<(LOG2_MB_SIZE - level);
 +    int trx= (x+1)<<rem_depth;
 +    int try= (y+1)<<rem_depth;
 +    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
 +    const BlockNode *top   = y ? &s->block[index-w] : &null_block;
 +    const BlockNode *right = trx<w ? &s->block[index+1] : &null_block;
 +    const BlockNode *bottom= try<h ? &s->block[index+w] : &null_block;
 +    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
 +    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
 +    int pl = left->color[0];
 +    int pcb= left->color[1];
 +    int pcr= left->color[2];
 +    int pmx, pmy;
 +    int mx=0, my=0;
 +    int l,cr,cb;
 +    const int stride= s->current_picture->linesize[0];
 +    const int uvstride= s->current_picture->linesize[1];
 +    uint8_t *current_data[3]= { s->input_picture->data[0] + (x + y*  stride)*block_w,
 +                                s->input_picture->data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift),
 +                                s->input_picture->data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)};
 +    int P[10][2];
 +    int16_t last_mv[3][2];
 +    int qpel= !!(s->avctx->flags & AV_CODEC_FLAG_QPEL); //unused
 +    const int shift= 1+qpel;
 +    MotionEstContext *c= &s->m.me;
 +    int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
 +    int mx_context= av_log2(2*FFABS(left->mx - top->mx));
 +    int my_context= av_log2(2*FFABS(left->my - top->my));
 +    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
 +    int ref, best_ref, ref_score, ref_mx, ref_my;
 +
 +    av_assert0(sizeof(s->block_state) >= 256);
 +    if(s->keyframe){
 +        set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
 +        return 0;
 +    }
 +
 +//    clip predictors / edge ?
 +
 +    P_LEFT[0]= left->mx;
 +    P_LEFT[1]= left->my;
 +    P_TOP [0]= top->mx;
 +    P_TOP [1]= top->my;
 +    P_TOPRIGHT[0]= tr->mx;
 +    P_TOPRIGHT[1]= tr->my;
 +
 +    last_mv[0][0]= s->block[index].mx;
 +    last_mv[0][1]= s->block[index].my;
 +    last_mv[1][0]= right->mx;
 +    last_mv[1][1]= right->my;
 +    last_mv[2][0]= bottom->mx;
 +    last_mv[2][1]= bottom->my;
 +
 +    s->m.mb_stride=2;
 +    s->m.mb_x=
 +    s->m.mb_y= 0;
 +    c->skip= 0;
 +
 +    av_assert1(c->  stride ==   stride);
 +    av_assert1(c->uvstride == uvstride);
 +
 +    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
 +    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
 +    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
 +    c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_DMV;
 +
 +    c->xmin = - x*block_w - 16+3;
 +    c->ymin = - y*block_w - 16+3;
 +    c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
 +    c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
 +
 +    if(P_LEFT[0]     > (c->xmax<<shift)) P_LEFT[0]    = (c->xmax<<shift);
 +    if(P_LEFT[1]     > (c->ymax<<shift)) P_LEFT[1]    = (c->ymax<<shift);
 +    if(P_TOP[0]      > (c->xmax<<shift)) P_TOP[0]     = (c->xmax<<shift);
 +    if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
 +    if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
 +    if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip
 +    if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
 +
 +    P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
 +    P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
 +
 +    if (!y) {
 +        c->pred_x= P_LEFT[0];
 +        c->pred_y= P_LEFT[1];
 +    } else {
 +        c->pred_x = P_MEDIAN[0];
 +        c->pred_y = P_MEDIAN[1];
 +    }
 +
 +    score= INT_MAX;
 +    best_ref= 0;
 +    for(ref=0; ref<s->ref_frames; ref++){
 +        init_ref(c, current_data, s->last_picture[ref]->data, NULL, block_w*x, block_w*y, 0);
 +
 +        ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
 +                                         (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w);
 +
 +        av_assert2(ref_mx >= c->xmin);
 +        av_assert2(ref_mx <= c->xmax);
 +        av_assert2(ref_my >= c->ymin);
 +        av_assert2(ref_my <= c->ymax);
 +
 +        ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w);
 +        ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0);
 +        ref_score+= 2*av_log2(2*ref)*c->penalty_factor;
 +        if(s->ref_mvs[ref]){
 +            s->ref_mvs[ref][index][0]= ref_mx;
 +            s->ref_mvs[ref][index][1]= ref_my;
 +            s->ref_scores[ref][index]= ref_score;
 +        }
 +        if(score > ref_score){
 +            score= ref_score;
 +            best_ref= ref;
 +            mx= ref_mx;
 +            my= ref_my;
 +        }
 +    }
 +    //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2
 +
 +  //  subpel search
 +    base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start);
 +    pc= s->c;
 +    pc.bytestream_start=
 +    pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo
 +    memcpy(p_state, s->block_state, sizeof(s->block_state));
 +
 +    if(level!=s->block_max_depth)
 +        put_rac(&pc, &p_state[4 + s_context], 1);
 +    put_rac(&pc, &p_state[1 + left->type + top->type], 0);
 +    if(s->ref_frames > 1)
 +        put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0);
 +    pred_mv(s, &pmx, &pmy, best_ref, left, top, tr);
 +    put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1);
 +    put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1);
 +    p_len= pc.bytestream - pc.bytestream_start;
 +    score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT;
 +
 +    block_s= block_w*block_w;
 +    sum = pix_sum(current_data[0], stride, block_w, block_w);
 +    l= (sum + block_s/2)/block_s;
 +    iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s;
 +
 +    if (s->nb_planes > 2) {
 +        block_s= block_w*block_w>>(s->chroma_h_shift + s->chroma_v_shift);
 +        sum = pix_sum(current_data[1], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift);
 +        cb= (sum + block_s/2)/block_s;
 +    //    iscore += pix_norm1(&current_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s;
 +        sum = pix_sum(current_data[2], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift);
 +        cr= (sum + block_s/2)/block_s;
 +    //    iscore += pix_norm1(&current_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;
 +    }else
 +        cb = cr = 0;
 +
 +    ic= s->c;
 +    ic.bytestream_start=
 +    ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo
 +    memcpy(i_state, s->block_state, sizeof(s->block_state));
 +    if(level!=s->block_max_depth)
 +        put_rac(&ic, &i_state[4 + s_context], 1);
 +    put_rac(&ic, &i_state[1 + left->type + top->type], 1);
 +    put_symbol(&ic, &i_state[32],  l-pl , 1);
 +    if (s->nb_planes > 2) {
 +        put_symbol(&ic, &i_state[64], cb-pcb, 1);
 +        put_symbol(&ic, &i_state[96], cr-pcr, 1);
 +    }
 +    i_len= ic.bytestream - ic.bytestream_start;
 +    iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT;
 +
 +    av_assert1(iscore < 255*255*256 + s->lambda2*10);
 +    av_assert1(iscore >= 0);
 +    av_assert1(l>=0 && l<=255);
 +    av_assert1(pl>=0 && pl<=255);
 +
 +    if(level==0){
 +        int varc= iscore >> 8;
 +        int vard= score >> 8;
 +        if (vard <= 64 || vard < varc)
 +            c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
 +        else
 +            c->scene_change_score+= s->m.qscale;
 +    }
 +
 +    if(level!=s->block_max_depth){
 +        put_rac(&s->c, &s->block_state[4 + s_context], 0);
 +        score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);
 +        score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);
 +        score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);
 +        score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1);
 +        score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead
 +
 +        if(score2 < score && score2 < iscore)
 +            return score2;
 +    }
 +
 +    if(iscore < score){
 +        pred_mv(s, &pmx, &pmy, 0, left, top, tr);
 +        memcpy(pbbak, i_buffer, i_len);
 +        s->c= ic;
 +        s->c.bytestream_start= pbbak_start;
 +        s->c.bytestream= pbbak + i_len;
 +        set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA);
 +        memcpy(s->block_state, i_state, sizeof(s->block_state));
 +        return iscore;
 +    }else{
 +        memcpy(pbbak, p_buffer, p_len);
 +        s->c= pc;
 +        s->c.bytestream_start= pbbak_start;
 +        s->c.bytestream= pbbak + p_len;
 +        set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0);
 +        memcpy(s->block_state, p_state, sizeof(s->block_state));
 +        return score;
 +    }
 +}
 +
 +static void encode_q_branch2(SnowContext *s, int level, int x, int y){
 +    const int w= s->b_width  << s->block_max_depth;
 +    const int rem_depth= s->block_max_depth - level;
 +    const int index= (x + y*w) << rem_depth;
 +    int trx= (x+1)<<rem_depth;
 +    BlockNode *b= &s->block[index];
 +    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
 +    const BlockNode *top   = y ? &s->block[index-w] : &null_block;
 +    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
 +    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
 +    int pl = left->color[0];
 +    int pcb= left->color[1];
 +    int pcr= left->color[2];
 +    int pmx, pmy;
 +    int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
 +    int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref;
 +    int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref;
 +    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
 +
 +    if(s->keyframe){
 +        set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
 +        return;
 +    }
 +
 +    if(level!=s->block_max_depth){
 +        if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){
 +            put_rac(&s->c, &s->block_state[4 + s_context], 1);
 +        }else{
 +            put_rac(&s->c, &s->block_state[4 + s_context], 0);
 +            encode_q_branch2(s, level+1, 2*x+0, 2*y+0);
 +            encode_q_branch2(s, level+1, 2*x+1, 2*y+0);
 +            encode_q_branch2(s, level+1, 2*x+0, 2*y+1);
 +            encode_q_branch2(s, level+1, 2*x+1, 2*y+1);
 +            return;
 +        }
 +    }
 +    if(b->type & BLOCK_INTRA){
 +        pred_mv(s, &pmx, &pmy, 0, left, top, tr);
 +        put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1);
 +        put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1);
 +        if (s->nb_planes > 2) {
 +            put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1);
 +            put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1);
 +        }
 +        set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA);
 +    }else{
 +        pred_mv(s, &pmx, &pmy, b->ref, left, top, tr);
 +        put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0);
 +        if(s->ref_frames > 1)
 +            put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0);
 +        put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1);
 +        put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1);
 +        set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0);
 +    }
 +}
 +
 +static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){
 +    int i, x2, y2;
 +    Plane *p= &s->plane[plane_index];
 +    const int block_size = MB_SIZE >> s->block_max_depth;
 +    const int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
 +    const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
 +    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
 +    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
 +    const int ref_stride= s->current_picture->linesize[plane_index];
 +    uint8_t *src= s-> input_picture->data[plane_index];
 +    IDWTELEM *dst= (IDWTELEM*)s->m.sc.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
 +    const int b_stride = s->b_width << s->block_max_depth;
 +    const int w= p->width;
 +    const int h= p->height;
 +    int index= mb_x + mb_y*b_stride;
 +    BlockNode *b= &s->block[index];
 +    BlockNode backup= *b;
 +    int ab=0;
 +    int aa=0;
 +
 +    av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc stuff above
 +
 +    b->type|= BLOCK_INTRA;
 +    b->color[plane_index]= 0;
 +    memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM));
 +
 +    for(i=0; i<4; i++){
 +        int mb_x2= mb_x + (i &1) - 1;
 +        int mb_y2= mb_y + (i>>1) - 1;
 +        int x= block_w*mb_x2 + block_w/2;
 +        int y= block_h*mb_y2 + block_h/2;
 +
 +        add_yblock(s, 0, NULL, dst + (i&1)*block_w + (i>>1)*obmc_stride*block_h, NULL, obmc,
 +                    x, y, block_w, block_h, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index);
 +
 +        for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_h); y2++){
 +            for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){
 +                int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_h*mb_y - block_h/2))*obmc_stride;
 +                int obmc_v= obmc[index];
 +                int d;
 +                if(y<0) obmc_v += obmc[index + block_h*obmc_stride];
 +                if(x<0) obmc_v += obmc[index + block_w];
 +                if(y+block_h>h) obmc_v += obmc[index - block_h*obmc_stride];
 +                if(x+block_w>w) obmc_v += obmc[index - block_w];
 +                //FIXME precalculate this or simplify it somehow else
 +
 +                d = -dst[index] + (1<<(FRAC_BITS-1));
 +                dst[index] = d;
 +                ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v;
 +                aa += obmc_v * obmc_v; //FIXME precalculate this
 +            }
 +        }
 +    }
 +    *b= backup;
 +
 +    return av_clip_uint8( ROUNDED_DIV(ab<<LOG2_OBMC_MAX, aa) ); //FIXME we should not need clipping
 +}
 +
 +static inline int get_block_bits(SnowContext *s, int x, int y, int w){
 +    const int b_stride = s->b_width << s->block_max_depth;
 +    const int b_height = s->b_height<< s->block_max_depth;
 +    int index= x + y*b_stride;
 +    const BlockNode *b     = &s->block[index];
 +    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
 +    const BlockNode *top   = y ? &s->block[index-b_stride] : &null_block;
 +    const BlockNode *tl    = y && x ? &s->block[index-b_stride-1] : left;
 +    const BlockNode *tr    = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl;
 +    int dmx, dmy;
 +//  int mx_context= av_log2(2*FFABS(left->mx - top->mx));
 +//  int my_context= av_log2(2*FFABS(left->my - top->my));
 +
 +    if(x<0 || x>=b_stride || y>=b_height)
 +        return 0;
 +/*
 +1            0      0
 +01X          1-2    1
 +001XX        3-6    2-3
 +0001XXX      7-14   4-7
 +00001XXXX   15-30   8-15
 +*/
 +//FIXME try accurate rate
 +//FIXME intra and inter predictors if surrounding blocks are not the same type
 +    if(b->type & BLOCK_INTRA){
 +        return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0]))
 +                   + av_log2(2*FFABS(left->color[1] - b->color[1]))
 +                   + av_log2(2*FFABS(left->color[2] - b->color[2])));
 +    }else{
 +        pred_mv(s, &dmx, &dmy, b->ref, left, top, tr);
 +        dmx-= b->mx;
 +        dmy-= b->my;
 +        return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda
 +                    + av_log2(2*FFABS(dmy))
 +                    + av_log2(2*b->ref));
 +    }
 +}
 +
 +static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uint8_t (*obmc_edged)[MB_SIZE * 2]){
 +    Plane *p= &s->plane[plane_index];
 +    const int block_size = MB_SIZE >> s->block_max_depth;
 +    const int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
 +    const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
 +    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
 +    const int ref_stride= s->current_picture->linesize[plane_index];
 +    uint8_t *dst= s->current_picture->data[plane_index];
 +    uint8_t *src= s->  input_picture->data[plane_index];
 +    IDWTELEM *pred= (IDWTELEM*)s->m.sc.obmc_scratchpad + plane_index*block_size*block_size*4;
 +    uint8_t *cur = s->scratchbuf;
 +    uint8_t *tmp = s->emu_edge_buffer;
 +    const int b_stride = s->b_width << s->block_max_depth;
 +    const int b_height = s->b_height<< s->block_max_depth;
 +    const int w= p->width;
 +    const int h= p->height;
 +    int distortion;
 +    int rate= 0;
 +    const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
 +    int sx= block_w*mb_x - block_w/2;
 +    int sy= block_h*mb_y - block_h/2;
 +    int x0= FFMAX(0,-sx);
 +    int y0= FFMAX(0,-sy);
 +    int x1= FFMIN(block_w*2, w-sx);
 +    int y1= FFMIN(block_h*2, h-sy);
 +    int i,x,y;
 +
 +    av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below chckinhg only block_w
 +
 +    ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_h*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h);
 +
 +    for(y=y0; y<y1; y++){
 +        const uint8_t *obmc1= obmc_edged[y];
 +        const IDWTELEM *pred1 = pred + y*obmc_stride;
 +        uint8_t *cur1 = cur + y*ref_stride;
 +        uint8_t *dst1 = dst + sx + (sy+y)*ref_stride;
 +        for(x=x0; x<x1; x++){
 +#if FRAC_BITS >= LOG2_OBMC_MAX
 +            int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX);
 +#else
 +            int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS);
 +#endif
 +            v = (v + pred1[x]) >> FRAC_BITS;
 +            if(v&(~255)) v= ~(v>>31);
 +            dst1[x] = v;
 +        }
 +    }
 +
 +    /* copy the regions where obmc[] = (uint8_t)256 */
 +    if(LOG2_OBMC_MAX == 8
 +        && (mb_x == 0 || mb_x == b_stride-1)
 +        && (mb_y == 0 || mb_y == b_height-1)){
 +        if(mb_x == 0)
 +            x1 = block_w;
 +        else
 +            x0 = block_w;
 +        if(mb_y == 0)
 +            y1 = block_h;
 +        else
 +            y0 = block_h;
 +        for(y=y0; y<y1; y++)
 +            memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0);
 +    }
 +
 +    if(block_w==16){
 +        /* FIXME rearrange dsputil to fit 32x32 cmp functions */
 +        /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */
 +        /* FIXME cmps overlap but do not cover the wavelet's whole support.
 +         * So improving the score of one block is not strictly guaranteed
 +         * to improve the score of the whole frame, thus iterative motion
 +         * estimation does not always converge. */
 +        if(s->avctx->me_cmp == FF_CMP_W97)
 +            distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
 +        else if(s->avctx->me_cmp == FF_CMP_W53)
 +            distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
 +        else{
 +            distortion = 0;
 +            for(i=0; i<4; i++){
 +                int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
 +                distortion += s->mecc.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16);
 +            }
 +        }
 +    }else{
 +        av_assert2(block_w==8);
 +        distortion = s->mecc.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
 +    }
 +
 +    if(plane_index==0){
 +        for(i=0; i<4; i++){
 +/* ..RRr
 + * .RXx.
 + * rxx..
 + */
 +            rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1);
 +        }
 +        if(mb_x == b_stride-2)
 +            rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1);
 +    }
 +    return distortion + rate*penalty_factor;
 +}
 +
 +static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){
 +    int i, y2;
 +    Plane *p= &s->plane[plane_index];
 +    const int block_size = MB_SIZE >> s->block_max_depth;
 +    const int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
 +    const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
 +    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
 +    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
 +    const int ref_stride= s->current_picture->linesize[plane_index];
 +    uint8_t *dst= s->current_picture->data[plane_index];
 +    uint8_t *src= s-> input_picture->data[plane_index];
 +    //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst
 +    // const has only been removed from zero_dst to suppress a warning
 +    static IDWTELEM zero_dst[4096]; //FIXME
 +    const int b_stride = s->b_width << s->block_max_depth;
 +    const int w= p->width;
 +    const int h= p->height;
 +    int distortion= 0;
 +    int rate= 0;
 +    const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
 +
 +    av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below
 +
 +    for(i=0; i<9; i++){
 +        int mb_x2= mb_x + (i%3) - 1;
 +        int mb_y2= mb_y + (i/3) - 1;
 +        int x= block_w*mb_x2 + block_w/2;
 +        int y= block_h*mb_y2 + block_h/2;
 +
 +        add_yblock(s, 0, NULL, zero_dst, dst, obmc,
 +                   x, y, block_w, block_h, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
 +
 +        //FIXME find a cleaner/simpler way to skip the outside stuff
 +        for(y2= y; y2<0; y2++)
 +            memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
 +        for(y2= h; y2<y+block_h; y2++)
 +            memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
 +        if(x<0){
 +            for(y2= y; y2<y+block_h; y2++)
 +                memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x);
 +        }
 +        if(x+block_w > w){
 +            for(y2= y; y2<y+block_h; y2++)
 +                memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w);
 +        }
 +
 +        av_assert1(block_w== 8 || block_w==16);
 +        distortion += s->mecc.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
 +    }
 +
 +    if(plane_index==0){
 +        BlockNode *b= &s->block[mb_x+mb_y*b_stride];
 +        int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1);
 +
 +/* ..RRRr
 + * .RXXx.
 + * .RXXx.
 + * rxxx.
 + */
 +        if(merged)
 +            rate = get_block_bits(s, mb_x, mb_y, 2);
 +        for(i=merged?4:0; i<9; i++){
 +            static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}};
 +            rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1);
 +        }
 +    }
 +    return distortion + rate*penalty_factor;
 +}
 +
 +static int encode_subband_c0run(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){
 +    const int w= b->width;
 +    const int h= b->height;
 +    int x, y;
 +
 +    if(1){
 +        int run=0;
 +        int *runs = s->run_buffer;
 +        int run_index=0;
 +        int max_index;
 +
 +        for(y=0; y<h; y++){
 +            for(x=0; x<w; x++){
 +                int v, p=0;
 +                int /*ll=0, */l=0, lt=0, t=0, rt=0;
 +                v= src[x + y*stride];
 +
 +                if(y){
 +                    t= src[x + (y-1)*stride];
 +                    if(x){
 +                        lt= src[x - 1 + (y-1)*stride];
 +                    }
 +                    if(x + 1 < w){
 +                        rt= src[x + 1 + (y-1)*stride];
 +                    }
 +                }
 +                if(x){
 +                    l= src[x - 1 + y*stride];
 +                    /*if(x > 1){
 +                        if(orientation==1) ll= src[y + (x-2)*stride];
 +                        else               ll= src[x - 2 + y*stride];
 +                    }*/
 +                }
 +                if(parent){
 +                    int px= x>>1;
 +                    int py= y>>1;
 +                    if(px<b->parent->width && py<b->parent->height)
 +                        p= parent[px + py*2*stride];
 +                }
 +                if(!(/*ll|*/l|lt|t|rt|p)){
 +                    if(v){
 +                        runs[run_index++]= run;
 +                        run=0;
 +                    }else{
 +                        run++;
 +                    }
 +                }
 +            }
 +        }
 +        max_index= run_index;
 +        runs[run_index++]= run;
 +        run_index=0;
 +        run= runs[run_index++];
 +
 +        put_symbol2(&s->c, b->state[30], max_index, 0);
 +        if(run_index <= max_index)
 +            put_symbol2(&s->c, b->state[1], run, 3);
 +
 +        for(y=0; y<h; y++){
 +            if(s->c.bytestream_end - s->c.bytestream < w*40){
 +                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
 +                return -1;
 +            }
 +            for(x=0; x<w; x++){
 +                int v, p=0;
 +                int /*ll=0, */l=0, lt=0, t=0, rt=0;
 +                v= src[x + y*stride];
 +
 +                if(y){
 +                    t= src[x + (y-1)*stride];
 +                    if(x){
 +                        lt= src[x - 1 + (y-1)*stride];
 +                    }
 +                    if(x + 1 < w){
 +                        rt= src[x + 1 + (y-1)*stride];
 +                    }
 +                }
 +                if(x){
 +                    l= src[x - 1 + y*stride];
 +                    /*if(x > 1){
 +                        if(orientation==1) ll= src[y + (x-2)*stride];
 +                        else               ll= src[x - 2 + y*stride];
 +                    }*/
 +                }
 +                if(parent){
 +                    int px= x>>1;
 +                    int py= y>>1;
 +                    if(px<b->parent->width && py<b->parent->height)
 +                        p= parent[px + py*2*stride];
 +                }
 +                if(/*ll|*/l|lt|t|rt|p){
 +                    int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
 +
 +                    put_rac(&s->c, &b->state[0][context], !!v);
 +                }else{
 +                    if(!run){
 +                        run= runs[run_index++];
 +
 +                        if(run_index <= max_index)
 +                            put_symbol2(&s->c, b->state[1], run, 3);
 +                        av_assert2(v);
 +                    }else{
 +                        run--;
 +                        av_assert2(!v);
 +                    }
 +                }
 +                if(v){
 +                    int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
 +                    int l2= 2*FFABS(l) + (l<0);
 +                    int t2= 2*FFABS(t) + (t<0);
 +
 +                    put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4);
 +                    put_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l2&0xFF] + 3*ff_quant3bA[t2&0xFF]], v<0);
 +                }
 +            }
 +        }
 +    }
 +    return 0;
 +}
 +
 +static int encode_subband(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){
 +//    encode_subband_qtree(s, b, src, parent, stride, orientation);
 +//    encode_subband_z0run(s, b, src, parent, stride, orientation);
 +    return encode_subband_c0run(s, b, src, parent, stride, orientation);
 +//    encode_subband_dzr(s, b, src, parent, stride, orientation);
 +}
 +
 +static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){
 +    const int b_stride= s->b_width << s->block_max_depth;
 +    BlockNode *block= &s->block[mb_x + mb_y * b_stride];
 +    BlockNode backup= *block;
 +    unsigned value;
 +    int rd, index;
 +
 +    av_assert2(mb_x>=0 && mb_y>=0);
 +    av_assert2(mb_x<b_stride);
 +
 +    if(intra){
 +        block->color[0] = p[0];
 +        block->color[1] = p[1];
 +        block->color[2] = p[2];
 +        block->type |= BLOCK_INTRA;
 +    }else{
 +        index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1);
 +        value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12);
 +        if(s->me_cache[index] == value)
 +            return 0;
 +        s->me_cache[index]= value;
 +
 +        block->mx= p[0];
 +        block->my= p[1];
 +        block->type &= ~BLOCK_INTRA;
 +    }
 +
 +    rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged) + s->intra_penalty * !!intra;
 +
 +//FIXME chroma
 +    if(rd < *best_rd){
 +        *best_rd= rd;
 +        return 1;
 +    }else{
 +        *block= backup;
 +        return 0;
 +    }
 +}
 +
 +/* special case for int[2] args we discard afterwards,
 + * fixes compilation problem with gcc 2.95 */
 +static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){
 +    int p[2] = {p0, p1};
 +    return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd);
 +}
 +
 +static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){
 +    const int b_stride= s->b_width << s->block_max_depth;
 +    BlockNode *block= &s->block[mb_x + mb_y * b_stride];
 +    BlockNode backup[4];
 +    unsigned value;
 +    int rd, index;
 +
 +    /* We don't initialize backup[] during variable declaration, because
 +     * that fails to compile on MSVC: "cannot convert from 'BlockNode' to
 +     * 'int16_t'". */
 +    backup[0] = block[0];
 +    backup[1] = block[1];
 +    backup[2] = block[b_stride];
 +    backup[3] = block[b_stride + 1];
 +
 +    av_assert2(mb_x>=0 && mb_y>=0);
 +    av_assert2(mb_x<b_stride);
 +    av_assert2(((mb_x|mb_y)&1) == 0);
 +
 +    index= (p0 + 31*p1) & (ME_CACHE_SIZE-1);
 +    value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12);
 +    if(s->me_cache[index] == value)
 +        return 0;
 +    s->me_cache[index]= value;
 +
 +    block->mx= p0;
 +    block->my= p1;
 +    block->ref= ref;
 +    block->type &= ~BLOCK_INTRA;
 +    block[1]= block[b_stride]= block[b_stride+1]= *block;
 +
 +    rd= get_4block_rd(s, mb_x, mb_y, 0);
 +
 +//FIXME chroma
 +    if(rd < *best_rd){
 +        *best_rd= rd;
 +        return 1;
 +    }else{
 +        block[0]= backup[0];
 +        block[1]= backup[1];
 +        block[b_stride]= backup[2];
 +        block[b_stride+1]= backup[3];
 +        return 0;
 +    }
 +}
 +
 +static void iterative_me(SnowContext *s){
 +    int pass, mb_x, mb_y;
 +    const int b_width = s->b_width  << s->block_max_depth;
 +    const int b_height= s->b_height << s->block_max_depth;
 +    const int b_stride= b_width;
 +    int color[3];
 +
 +    {
 +        RangeCoder r = s->c;
 +        uint8_t state[sizeof(s->block_state)];
 +        memcpy(state, s->block_state, sizeof(s->block_state));
 +        for(mb_y= 0; mb_y<s->b_height; mb_y++)
 +            for(mb_x= 0; mb_x<s->b_width; mb_x++)
 +                encode_q_branch(s, 0, mb_x, mb_y);
 +        s->c = r;
 +        memcpy(s->block_state, state, sizeof(s->block_state));
 +    }
 +
 +    for(pass=0; pass<25; pass++){
 +        int change= 0;
 +
 +        for(mb_y= 0; mb_y<b_height; mb_y++){
 +            for(mb_x= 0; mb_x<b_width; mb_x++){
 +                int dia_change, i, j, ref;
 +                int best_rd= INT_MAX, ref_rd;
 +                BlockNode backup, ref_b;
 +                const int index= mb_x + mb_y * b_stride;
 +                BlockNode *block= &s->block[index];
 +                BlockNode *tb =                   mb_y            ? &s->block[index-b_stride  ] : NULL;
 +                BlockNode *lb = mb_x                              ? &s->block[index         -1] : NULL;
 +                BlockNode *rb = mb_x+1<b_width                    ? &s->block[index         +1] : NULL;
 +                BlockNode *bb =                   mb_y+1<b_height ? &s->block[index+b_stride  ] : NULL;
 +                BlockNode *tlb= mb_x           && mb_y            ? &s->block[index-b_stride-1] : NULL;
 +                BlockNode *trb= mb_x+1<b_width && mb_y            ? &s->block[index-b_stride+1] : NULL;
 +                BlockNode *blb= mb_x           && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
 +                BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
 +                const int b_w= (MB_SIZE >> s->block_max_depth);
 +                uint8_t obmc_edged[MB_SIZE * 2][MB_SIZE * 2];
 +
 +                if(pass && (block->type & BLOCK_OPT))
 +                    continue;
 +                block->type |= BLOCK_OPT;
 +
 +                backup= *block;
 +
 +                if(!s->me_cache_generation)
 +                    memset(s->me_cache, 0, sizeof(s->me_cache));
 +                s->me_cache_generation += 1<<22;
 +
 +                //FIXME precalculate
 +                {
 +                    int x, y;
 +                    for (y = 0; y < b_w * 2; y++)
 +                        memcpy(obmc_edged[y], ff_obmc_tab[s->block_max_depth] + y * b_w * 2, b_w * 2);
 +                    if(mb_x==0)
 +                        for(y=0; y<b_w*2; y++)
 +                            memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w);
 +                    if(mb_x==b_stride-1)
 +                        for(y=0; y<b_w*2; y++)
 +                            memset(obmc_edged[y]+b_w, obmc_edged[y][b_w] + obmc_edged[y][b_w*2-1], b_w);
 +                    if(mb_y==0){
 +                        for(x=0; x<b_w*2; x++)
 +                            obmc_edged[0][x] += obmc_edged[b_w-1][x];
 +                        for(y=1; y<b_w; y++)
 +                            memcpy(obmc_edged[y], obmc_edged[0], b_w*2);
 +                    }
 +                    if(mb_y==b_height-1){
 +                        for(x=0; x<b_w*2; x++)
 +                            obmc_edged[b_w*2-1][x] += obmc_edged[b_w][x];
 +                        for(y=b_w; y<b_w*2-1; y++)
 +                            memcpy(obmc_edged[y], obmc_edged[b_w*2-1], b_w*2);
 +                    }
 +                }
 +
 +                //skip stuff outside the picture
 +                if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){
 +                    uint8_t *src= s->  input_picture->data[0];
 +                    uint8_t *dst= s->current_picture->data[0];
 +                    const int stride= s->current_picture->linesize[0];
 +                    const int block_w= MB_SIZE >> s->block_max_depth;
 +                    const int block_h= MB_SIZE >> s->block_max_depth;
 +                    const int sx= block_w*mb_x - block_w/2;
 +                    const int sy= block_h*mb_y - block_h/2;
 +                    const int w= s->plane[0].width;
 +                    const int h= s->plane[0].height;
 +                    int y;
 +
 +                    for(y=sy; y<0; y++)
 +                        memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
 +                    for(y=h; y<sy+block_h*2; y++)
 +                        memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
 +                    if(sx<0){
 +                        for(y=sy; y<sy+block_h*2; y++)
 +                            memcpy(dst + sx + y*stride, src + sx + y*stride, -sx);
 +                    }
 +                    if(sx+block_w*2 > w){
 +                        for(y=sy; y<sy+block_h*2; y++)
 +                            memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w);
 +                    }
 +                }
 +
 +                // intra(black) = neighbors' contribution to the current block
 +                for(i=0; i < s->nb_planes; i++)
 +                    color[i]= get_dc(s, mb_x, mb_y, i);
 +
 +                // get previous score (cannot be cached due to OBMC)
 +                if(pass > 0 && (block->type&BLOCK_INTRA)){
 +                    int color0[3]= {block->color[0], block->color[1], block->color[2]};
 +                    check_block(s, mb_x, mb_y, color0, 1, obmc_edged, &best_rd);
 +                }else
 +                    check_block_inter(s, mb_x, mb_y, block->mx, block->my, obmc_edged, &best_rd);
 +
 +                ref_b= *block;
 +                ref_rd= best_rd;
 +                for(ref=0; ref < s->ref_frames; ref++){
 +                    int16_t (*mvr)[2]= &s->ref_mvs[ref][index];
 +                    if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold
 +                        continue;
 +                    block->ref= ref;
 +                    best_rd= INT_MAX;
 +
 +                    check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], obmc_edged, &best_rd);
 +                    check_block_inter(s, mb_x, mb_y, 0, 0, obmc_edged, &best_rd);
 +                    if(tb)
 +                        check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], obmc_edged, &best_rd);
 +                    if(lb)
 +                        check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], obmc_edged, &best_rd);
 +                    if(rb)
 +                        check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], obmc_edged, &best_rd);
 +                    if(bb)
 +                        check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], obmc_edged, &best_rd);
 +
 +                    /* fullpel ME */
 +                    //FIXME avoid subpel interpolation / round to nearest integer
 +                    do{
 +                        int newx = block->mx;
 +                        int newy = block->my;
 +                        int dia_size = s->iterative_dia_size ? s->iterative_dia_size : FFMAX(s->avctx->dia_size, 1);
 +                        dia_change=0;
 +                        for(i=0; i < dia_size; i++){
 +                            for(j=0; j<i; j++){
 +                                dia_change |= check_block_inter(s, mb_x, mb_y, newx+4*(i-j), newy+(4*j), obmc_edged, &best_rd);
 +                                dia_change |= check_block_inter(s, mb_x, mb_y, newx-4*(i-j), newy-(4*j), obmc_edged, &best_rd);
 +                                dia_change |= check_block_inter(s, mb_x, mb_y, newx-(4*j), newy+4*(i-j), obmc_edged, &best_rd);
 +                                dia_change |= check_block_inter(s, mb_x, mb_y, newx+(4*j), newy-4*(i-j), obmc_edged, &best_rd);
 +                            }
 +                        }
 +                    }while(dia_change);
 +                    /* subpel ME */
 +                    do{
 +                        static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},};
 +                        dia_change=0;
 +                        for(i=0; i<8; i++)
 +                            dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], obmc_edged, &best_rd);
 +                    }while(dia_change);
 +                    //FIXME or try the standard 2 pass qpel or similar
 +
 +                    mvr[0][0]= block->mx;
 +                    mvr[0][1]= block->my;
 +                    if(ref_rd > best_rd){
 +                        ref_rd= best_rd;
 +                        ref_b= *block;
 +                    }
 +                }
 +                best_rd= ref_rd;
 +                *block= ref_b;
 +                check_block(s, mb_x, mb_y, color, 1, obmc_edged, &best_rd);
 +                //FIXME RD style color selection
 +                if(!same_block(block, &backup)){
 +                    if(tb ) tb ->type &= ~BLOCK_OPT;
 +                    if(lb ) lb ->type &= ~BLOCK_OPT;
 +                    if(rb ) rb ->type &= ~BLOCK_OPT;
 +                    if(bb ) bb ->type &= ~BLOCK_OPT;
 +                    if(tlb) tlb->type &= ~BLOCK_OPT;
 +                    if(trb) trb->type &= ~BLOCK_OPT;
 +                    if(blb) blb->type &= ~BLOCK_OPT;
 +                    if(brb) brb->type &= ~BLOCK_OPT;
 +                    change ++;
 +                }
 +            }
 +        }
 +        av_log(s->avctx, AV_LOG_DEBUG, "pass:%d changed:%d\n", pass, change);
 +        if(!change)
 +            break;
 +    }
 +
 +    if(s->block_max_depth == 1){
 +        int change= 0;
 +        for(mb_y= 0; mb_y<b_height; mb_y+=2){
 +            for(mb_x= 0; mb_x<b_width; mb_x+=2){
 +                int i;
 +                int best_rd, init_rd;
 +                const int index= mb_x + mb_y * b_stride;
 +                BlockNode *b[4];
 +
 +                b[0]= &s->block[index];
 +                b[1]= b[0]+1;
 +                b[2]= b[0]+b_stride;
 +                b[3]= b[2]+1;
 +                if(same_block(b[0], b[1]) &&
 +                   same_block(b[0], b[2]) &&
 +                   same_block(b[0], b[3]))
 +                    continue;
 +
 +                if(!s->me_cache_generation)
 +                    memset(s->me_cache, 0, sizeof(s->me_cache));
 +                s->me_cache_generation += 1<<22;
 +
 +                init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0);
 +
 +                //FIXME more multiref search?
 +                check_4block_inter(s, mb_x, mb_y,
 +                                   (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2,
 +                                   (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd);
 +
 +                for(i=0; i<4; i++)
 +                    if(!(b[i]->type&BLOCK_INTRA))
 +                        check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd);
 +
 +                if(init_rd != best_rd)
 +                    change++;
 +            }
 +        }
 +        av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4);
 +    }
 +}
 +
 +static void encode_blocks(SnowContext *s, int search){
 +    int x, y;
 +    int w= s->b_width;
 +    int h= s->b_height;
 +
 +    if(s->motion_est == FF_ME_ITER && !s->keyframe && search)
 +        iterative_me(s);
 +
 +    for(y=0; y<h; y++){
 +        if(s->c.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit
 +            av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
 +            return;
 +        }
 +        for(x=0; x<w; x++){
 +            if(s->motion_est == FF_ME_ITER || !search)
 +                encode_q_branch2(s, 0, x, y);
 +            else
 +                encode_q_branch (s, 0, x, y);
 +        }
 +    }
 +}
 +
 +static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){
 +    const int w= b->width;
 +    const int h= b->height;
 +    const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
 +    const int qmul= ff_qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS);
 +    int x,y, thres1, thres2;
 +
 +    if(s->qlog == LOSSLESS_QLOG){
 +        for(y=0; y<h; y++)
 +            for(x=0; x<w; x++)
 +                dst[x + y*stride]= src[x + y*stride];
 +        return;
 +    }
 +
 +    bias= bias ? 0 : (3*qmul)>>3;
 +    thres1= ((qmul - bias)>>QEXPSHIFT) - 1;
 +    thres2= 2*thres1;
 +
 +    if(!bias){
 +        for(y=0; y<h; y++){
 +            for(x=0; x<w; x++){
 +                int i= src[x + y*stride];
 +
 +                if((unsigned)(i+thres1) > thres2){
 +                    if(i>=0){
 +                        i<<= QEXPSHIFT;
 +                        i/= qmul; //FIXME optimize
 +                        dst[x + y*stride]=  i;
 +                    }else{
 +                        i= -i;
 +                        i<<= QEXPSHIFT;
 +                        i/= qmul; //FIXME optimize
 +                        dst[x + y*stride]= -i;
 +                    }
 +                }else
 +                    dst[x + y*stride]= 0;
 +            }
 +        }
 +    }else{
 +        for(y=0; y<h; y++){
 +            for(x=0; x<w; x++){
 +                int i= src[x + y*stride];
 +
 +                if((unsigned)(i+thres1) > thres2){
 +                    if(i>=0){
 +                        i<<= QEXPSHIFT;
 +                        i= (i + bias) / qmul; //FIXME optimize
 +                        dst[x + y*stride]=  i;
 +                    }else{
 +                        i= -i;
 +                        i<<= QEXPSHIFT;
 +                        i= (i + bias) / qmul; //FIXME optimize
 +                        dst[x + y*stride]= -i;
 +                    }
 +                }else
 +                    dst[x + y*stride]= 0;
 +            }
 +        }
 +    }
 +}
 +
 +static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){
 +    const int w= b->width;
 +    const int h= b->height;
 +    const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
 +    const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
 +    const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
 +    int x,y;
 +
 +    if(s->qlog == LOSSLESS_QLOG) return;
 +
 +    for(y=0; y<h; y++){
 +        for(x=0; x<w; x++){
 +            int i= src[x + y*stride];
 +            if(i<0){
 +                src[x + y*stride]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
 +            }else if(i>0){
 +                src[x + y*stride]=  (( i*qmul + qadd)>>(QEXPSHIFT));
 +            }
 +        }
 +    }
 +}
 +
 +static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
 +    const int w= b->width;
 +    const int h= b->height;
 +    int x,y;
 +
 +    for(y=h-1; y>=0; y--){
 +        for(x=w-1; x>=0; x--){
 +            int i= x + y*stride;
 +
 +            if(x){
 +                if(use_median){
 +                    if(y && x+1<w) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
 +                    else  src[i] -= src[i - 1];
 +                }else{
 +                    if(y) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
 +                    else  src[i] -= src[i - 1];
 +                }
 +            }else{
 +                if(y) src[i] -= src[i - stride];
 +            }
 +        }
 +    }
 +}
 +
 +static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
 +    const int w= b->width;
 +    const int h= b->height;
 +    int x,y;
 +
 +    for(y=0; y<h; y++){
 +        for(x=0; x<w; x++){
 +            int i= x + y*stride;
 +
 +            if(x){
 +                if(use_median){
 +                    if(y && x+1<w) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
 +                    else  src[i] += src[i - 1];
 +                }else{
 +                    if(y) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
 +                    else  src[i] += src[i - 1];
 +                }
 +            }else{
 +                if(y) src[i] += src[i - stride];
 +            }
 +        }
 +    }
 +}
 +
 +static void encode_qlogs(SnowContext *s){
 +    int plane_index, level, orientation;
 +
 +    for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){
 +        for(level=0; level<s->spatial_decomposition_count; level++){
 +            for(orientation=level ? 1:0; orientation<4; orientation++){
 +                if(orientation==2) continue;
 +                put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1);
 +            }
 +        }
 +    }
 +}
 +
 +static void encode_header(SnowContext *s){
 +    int plane_index, i;
 +    uint8_t kstate[32];
 +
 +    memset(kstate, MID_STATE, sizeof(kstate));
 +
 +    put_rac(&s->c, kstate, s->keyframe);
 +    if(s->keyframe || s->always_reset){
 +        ff_snow_reset_contexts(s);
 +        s->last_spatial_decomposition_type=
 +        s->last_qlog=
 +        s->last_qbias=
 +        s->last_mv_scale=
 +        s->last_block_max_depth= 0;
 +        for(plane_index=0; plane_index<2; plane_index++){
 +            Plane *p= &s->plane[plane_index];
 +            p->last_htaps=0;
 +            p->last_diag_mc=0;
 +            memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff));
 +        }
 +    }
 +    if(s->keyframe){
 +        put_symbol(&s->c, s->header_state, s->version, 0);
 +        put_rac(&s->c, s->header_state, s->always_reset);
 +        put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0);
 +        put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0);
 +        put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
 +        put_symbol(&s->c, s->header_state, s->colorspace_type, 0);
 +        if (s->nb_planes > 2) {
 +            put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0);
 +            put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0);
 +        }
 +        put_rac(&s->c, s->header_state, s->spatial_scalability);
 +//        put_rac(&s->c, s->header_state, s->rate_scalability);
 +        put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0);
 +
 +        encode_qlogs(s);
 +    }
 +
 +    if(!s->keyframe){
 +        int update_mc=0;
 +        for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){
 +            Plane *p= &s->plane[plane_index];
 +            update_mc |= p->last_htaps   != p->htaps;
 +            update_mc |= p->last_diag_mc != p->diag_mc;
 +            update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
 +        }
 +        put_rac(&s->c, s->header_state, update_mc);
 +        if(update_mc){
 +            for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){
 +                Plane *p= &s->plane[plane_index];
 +                put_rac(&s->c, s->header_state, p->diag_mc);
 +                put_symbol(&s->c, s->header_state, p->htaps/2-1, 0);
 +                for(i= p->htaps/2; i; i--)
 +                    put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0);
 +            }
 +        }
 +        if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
 +            put_rac(&s->c, s->header_state, 1);
 +            put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
 +            encode_qlogs(s);
 +        }else
 +            put_rac(&s->c, s->header_state, 0);
 +    }
 +
 +    put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1);
 +    put_symbol(&s->c, s->header_state, s->qlog            - s->last_qlog    , 1);
 +    put_symbol(&s->c, s->header_state, s->mv_scale        - s->last_mv_scale, 1);
 +    put_symbol(&s->c, s->header_state, s->qbias           - s->last_qbias   , 1);
 +    put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1);
 +
 +}
 +
 +static void update_last_header_values(SnowContext *s){
 +    int plane_index;
 +
 +    if(!s->keyframe){
 +        for(plane_index=0; plane_index<2; plane_index++){
 +            Plane *p= &s->plane[plane_index];
 +            p->last_diag_mc= p->diag_mc;
 +            p->last_htaps  = p->htaps;
 +            memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
 +        }
 +    }
 +
 +    s->last_spatial_decomposition_type  = s->spatial_decomposition_type;
 +    s->last_qlog                        = s->qlog;
 +    s->last_qbias                       = s->qbias;
 +    s->last_mv_scale                    = s->mv_scale;
 +    s->last_block_max_depth             = s->block_max_depth;
 +    s->last_spatial_decomposition_count = s->spatial_decomposition_count;
 +}
 +
 +static int qscale2qlog(int qscale){
 +    return lrint(QROOT*log2(qscale / (float)FF_QP2LAMBDA))
 +           + 61*QROOT/8; ///< 64 > 60
 +}
 +
 +static int ratecontrol_1pass(SnowContext *s, AVFrame *pict)
 +{
 +    /* Estimate the frame's complexity as a sum of weighted dwt coefficients.
 +     * FIXME we know exact mv bits at this point,
 +     * but ratecontrol isn't set up to include them. */
 +    uint32_t coef_sum= 0;
 +    int level, orientation, delta_qlog;
 +
 +    for(level=0; level<s->spatial_decomposition_count; level++){
 +        for(orientation=level ? 1 : 0; orientation<4; orientation++){
 +            SubBand *b= &s->plane[0].band[level][orientation];
 +            IDWTELEM *buf= b->ibuf;
 +            const int w= b->width;
 +            const int h= b->height;
 +            const int stride= b->stride;
 +            const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16);
 +            const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
 +            const int qdiv= (1<<16)/qmul;
 +            int x, y;
 +            //FIXME this is ugly
 +            for(y=0; y<h; y++)
 +                for(x=0; x<w; x++)
 +                    buf[x+y*stride]= b->buf[x+y*stride];
 +            if(orientation==0)
 +                decorrelate(s, b, buf, stride, 1, 0);
 +            for(y=0; y<h; y++)
 +                for(x=0; x<w; x++)
 +                    coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16;
 +        }
 +    }
 +
 +    /* ugly, ratecontrol just takes a sqrt again */
 +    av_assert0(coef_sum < INT_MAX);
 +    coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
 +
 +    if(pict->pict_type == AV_PICTURE_TYPE_I){
 +        s->m.current_picture.mb_var_sum= coef_sum;
 +        s->m.current_picture.mc_mb_var_sum= 0;
 +    }else{
 +        s->m.current_picture.mc_mb_var_sum= coef_sum;
 +        s->m.current_picture.mb_var_sum= 0;
 +    }
 +
 +    pict->quality= ff_rate_estimate_qscale(&s->m, 1);
 +    if (pict->quality < 0)
 +        return INT_MIN;
 +    s->lambda= pict->quality * 3/2;
 +    delta_qlog= qscale2qlog(pict->quality) - s->qlog;
 +    s->qlog+= delta_qlog;
 +    return delta_qlog;
 +}
 +
 +static void calculate_visual_weight(SnowContext *s, Plane *p){
 +    int width = p->width;
 +    int height= p->height;
 +    int level, orientation, x, y;
 +
 +    for(level=0; level<s->spatial_decomposition_count; level++){
 +        for(orientation=level ? 1 : 0; orientation<4; orientation++){
 +            SubBand *b= &p->band[level][orientation];
 +            IDWTELEM *ibuf= b->ibuf;
 +            int64_t error=0;
 +
 +            memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height);
 +            ibuf[b->width/2 + b->height/2*b->stride]= 256*16;
 +            ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count);
 +            for(y=0; y<height; y++){
 +                for(x=0; x<width; x++){
 +                    int64_t d= s->spatial_idwt_buffer[x + y*width]*16;
 +                    error += d*d;
 +                }
 +            }
 +
 +            b->qlog= (int)(QROOT * log2(352256.0/sqrt(error)) + 0.5);
 +        }
 +    }
 +}
 +
 +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 +                        const AVFrame *pict, int *got_packet)
 +{
 +    SnowContext *s = avctx->priv_data;
 +    RangeCoder * const c= &s->c;
 +    AVFrame *pic;
 +    const int width= s->avctx->width;
 +    const int height= s->avctx->height;
 +    int level, orientation, plane_index, i, y, ret;
 +    uint8_t rc_header_bak[sizeof(s->header_state)];
 +    uint8_t rc_block_bak[sizeof(s->block_state)];
 +
 +    if ((ret = ff_alloc_packet2(avctx, pkt, s->b_width*s->b_height*MB_SIZE*MB_SIZE*3 + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
 +        return ret;
 +
 +    ff_init_range_encoder(c, pkt->data, pkt->size);
 +    ff_build_rac_states(c, (1LL<<32)/20, 256-8);
 +
 +    for(i=0; i < s->nb_planes; i++){
 +        int hshift= i ? s->chroma_h_shift : 0;
 +        int vshift= i ? s->chroma_v_shift : 0;
 +        for(y=0; y<AV_CEIL_RSHIFT(height, vshift); y++)
 +            memcpy(&s->input_picture->data[i][y * s->input_picture->linesize[i]],
 +                   &pict->data[i][y * pict->linesize[i]],
 +                   AV_CEIL_RSHIFT(width, hshift));
 +        s->mpvencdsp.draw_edges(s->input_picture->data[i], s->input_picture->linesize[i],
 +                                AV_CEIL_RSHIFT(width, hshift), AV_CEIL_RSHIFT(height, vshift),
 +                                EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
 +                                EDGE_TOP | EDGE_BOTTOM);
 +
 +    }
 +    emms_c();
 +    pic = s->input_picture;
 +    pic->pict_type = pict->pict_type;
 +    pic->quality = pict->quality;
 +
 +    s->m.picture_number= avctx->frame_number;
 +    if(avctx->flags&AV_CODEC_FLAG_PASS2){
 +        s->m.pict_type = pic->pict_type = s->m.rc_context.entry[avctx->frame_number].new_pict_type;
 +        s->keyframe = pic->pict_type == AV_PICTURE_TYPE_I;
 +        if(!(avctx->flags&AV_CODEC_FLAG_QSCALE)) {
 +            pic->quality = ff_rate_estimate_qscale(&s->m, 0);
 +            if (pic->quality < 0)
 +                return -1;
 +        }
 +    }else{
 +        s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;
 +        s->m.pict_type = pic->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
 +    }
 +
 +    if(s->pass1_rc && avctx->frame_number == 0)
 +        pic->quality = 2*FF_QP2LAMBDA;
 +    if (pic->quality) {
 +        s->qlog   = qscale2qlog(pic->quality);
 +        s->lambda = pic->quality * 3/2;
 +    }
 +    if (s->qlog < 0 || (!pic->quality && (avctx->flags & AV_CODEC_FLAG_QSCALE))) {
 +        s->qlog= LOSSLESS_QLOG;
 +        s->lambda = 0;
 +    }//else keep previous frame's qlog until after motion estimation
 +
 +    if (s->current_picture->data[0]
 +#if FF_API_EMU_EDGE
 +        && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)
 +#endif
 +        ) {
 +        int w = s->avctx->width;
 +        int h = s->avctx->height;
 +
 +        s->mpvencdsp.draw_edges(s->current_picture->data[0],
 +                                s->current_picture->linesize[0], w   , h   ,
 +                                EDGE_WIDTH  , EDGE_WIDTH  , EDGE_TOP | EDGE_BOTTOM);
 +        if (s->current_picture->data[2]) {
 +            s->mpvencdsp.draw_edges(s->current_picture->data[1],
 +                                    s->current_picture->linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
 +                                    EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
 +            s->mpvencdsp.draw_edges(s->current_picture->data[2],
 +                                    s->current_picture->linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
 +                                    EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
 +        }
 +    }
 +
 +    ff_snow_frame_start(s);
 +    av_frame_unref(avctx->coded_frame);
 +    ret = av_frame_ref(avctx->coded_frame, s->current_picture);
 +    if (ret < 0)
 +        return ret;
 +
 +    s->m.current_picture_ptr= &s->m.current_picture;
 +    s->m.current_picture.f = s->current_picture;
 +    s->m.current_picture.f->pts = pict->pts;
 +    if(pic->pict_type == AV_PICTURE_TYPE_P){
 +        int block_width = (width +15)>>4;
 +        int block_height= (height+15)>>4;
 +        int stride= s->current_picture->linesize[0];
 +
 +        av_assert0(s->current_picture->data[0]);
 +        av_assert0(s->last_picture[0]->data[0]);
 +
 +        s->m.avctx= s->avctx;
 +        s->m.   last_picture.f = s->last_picture[0];
 +        s->m.    new_picture.f = s->input_picture;
 +        s->m.   last_picture_ptr= &s->m.   last_picture;
 +        s->m.linesize = stride;
 +        s->m.uvlinesize= s->current_picture->linesize[1];
 +        s->m.width = width;
 +        s->m.height= height;
 +        s->m.mb_width = block_width;
 +        s->m.mb_height= block_height;
 +        s->m.mb_stride=   s->m.mb_width+1;
 +        s->m.b8_stride= 2*s->m.mb_width+1;
 +        s->m.f_code=1;
 +        s->m.pict_type = pic->pict_type;
 +#if FF_API_MOTION_EST
 +        s->m.me_method= s->avctx->me_method;
 +#endif
 +        s->m.motion_est= s->motion_est;
 +        s->m.me.scene_change_score=0;
 +        s->m.me.dia_size = avctx->dia_size;
 +        s->m.quarter_sample= (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0;
 +        s->m.out_format= FMT_H263;
 +        s->m.unrestricted_mv= 1;
 +
 +        s->m.lambda = s->lambda;
 +        s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
 +        s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
 +
 +        s->m.mecc= s->mecc; //move
 +        s->m.qdsp= s->qdsp; //move
 +        s->m.hdsp = s->hdsp;
 +        ff_init_me(&s->m);
 +        s->hdsp = s->m.hdsp;
 +        s->mecc= s->m.mecc;
 +    }
 +
 +    if(s->pass1_rc){
 +        memcpy(rc_header_bak, s->header_state, sizeof(s->header_state));
 +        memcpy(rc_block_bak, s->block_state, sizeof(s->block_state));
 +    }
 +
 +redo_frame:
 +
 +    s->spatial_decomposition_count= 5;
 +
 +    while(   !(width >>(s->chroma_h_shift + s->spatial_decomposition_count))
 +          || !(height>>(s->chroma_v_shift + s->spatial_decomposition_count)))
 +        s->spatial_decomposition_count--;
 +
 +    if (s->spatial_decomposition_count <= 0) {
 +        av_log(avctx, AV_LOG_ERROR, "Resolution too low\n");
 +        return AVERROR(EINVAL);
 +    }
 +
 +    s->m.pict_type = pic->pict_type;
 +    s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
 +
 +    ff_snow_common_init_after_header(avctx);
 +
 +    if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
 +        for(plane_index=0; plane_index < s->nb_planes; plane_index++){
 +            calculate_visual_weight(s, &s->plane[plane_index]);
 +        }
 +    }
 +
 +    encode_header(s);
 +    s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start);
 +    encode_blocks(s, 1);
 +    s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits;
 +
 +    for(plane_index=0; plane_index < s->nb_planes; plane_index++){
 +        Plane *p= &s->plane[plane_index];
 +        int w= p->width;
 +        int h= p->height;
 +        int x, y;
 +//        int bits= put_bits_count(&s->c.pb);
 +
 +        if (!s->memc_only) {
 +            //FIXME optimize
 +            if(pict->data[plane_index]) //FIXME gray hack
 +                for(y=0; y<h; y++){
 +                    for(x=0; x<w; x++){
 +                        s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS;
 +                    }
 +                }
 +            predict_plane(s, s->spatial_idwt_buffer, plane_index, 0);
 +
 +#if FF_API_PRIVATE_OPT
 +FF_DISABLE_DEPRECATION_WARNINGS
 +            if(s->avctx->scenechange_threshold)
 +                s->scenechange_threshold = s->avctx->scenechange_threshold;
 +FF_ENABLE_DEPRECATION_WARNINGS
 +#endif
 +
 +            if(   plane_index==0
 +               && pic->pict_type == AV_PICTURE_TYPE_P
 +               && !(avctx->flags&AV_CODEC_FLAG_PASS2)
 +               && s->m.me.scene_change_score > s->scenechange_threshold){
 +                ff_init_range_encoder(c, pkt->data, pkt->size);
 +                ff_build_rac_states(c, (1LL<<32)/20, 256-8);
 +                pic->pict_type= AV_PICTURE_TYPE_I;
 +                s->keyframe=1;
 +                s->current_picture->key_frame=1;
 +                goto redo_frame;
 +            }
 +
 +            if(s->qlog == LOSSLESS_QLOG){
 +                for(y=0; y<h; y++){
 +                    for(x=0; x<w; x++){
 +                        s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS;
 +                    }
 +                }
 +            }else{
 +                for(y=0; y<h; y++){
 +                    for(x=0; x<w; x++){
 +                        s->spatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<<ENCODER_EXTRA_BITS;
 +                    }
 +                }
 +            }
 +
 +            ff_spatial_dwt(s->spatial_dwt_buffer, s->temp_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
 +
 +            if(s->pass1_rc && plane_index==0){
 +                int delta_qlog = ratecontrol_1pass(s, pic);
 +                if (delta_qlog <= INT_MIN)
 +                    return -1;
 +                if(delta_qlog){
 +                    //reordering qlog in the bitstream would eliminate this reset
 +                    ff_init_range_encoder(c, pkt->data, pkt->size);
 +                    memcpy(s->header_state, rc_header_bak, sizeof(s->header_state));
 +                    memcpy(s->block_state, rc_block_bak, sizeof(s->block_state));
 +                    encode_header(s);
 +                    encode_blocks(s, 0);
 +                }
 +            }
 +
 +            for(level=0; level<s->spatial_decomposition_count; level++){
 +                for(orientation=level ? 1 : 0; orientation<4; orientation++){
 +                    SubBand *b= &p->band[level][orientation];
 +
 +                    quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias);
 +                    if(orientation==0)
 +                        decorrelate(s, b, b->ibuf, b->stride, pic->pict_type == AV_PICTURE_TYPE_P, 0);
 +                    if (!s->no_bitstream)
 +                    encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation);
 +                    av_assert0(b->parent==NULL || b->parent->stride == b->stride*2);
 +                    if(orientation==0)
 +                        correlate(s, b, b->ibuf, b->stride, 1, 0);
 +                }
 +            }
 +
 +            for(level=0; level<s->spatial_decomposition_count; level++){
 +                for(orientation=level ? 1 : 0; orientation<4; orientation++){
 +                    SubBand *b= &p->band[level][orientation];
 +
 +                    dequantize(s, b, b->ibuf, b->stride);
 +                }
 +            }
 +
 +            ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
 +            if(s->qlog == LOSSLESS_QLOG){
 +                for(y=0; y<h; y++){
 +                    for(x=0; x<w; x++){
 +                        s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS;
 +                    }
 +                }
 +            }
 +            predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
 +        }else{
 +            //ME/MC only
 +            if(pic->pict_type == AV_PICTURE_TYPE_I){
 +                for(y=0; y<h; y++){
 +                    for(x=0; x<w; x++){
 +                        s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x]=
 +                            pict->data[plane_index][y*pict->linesize[plane_index] + x];
 +                    }
 +                }
 +            }else{
 +                memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h);
 +                predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
 +            }
 +        }
 +        if(s->avctx->flags&AV_CODEC_FLAG_PSNR){
 +            int64_t error= 0;
 +
 +            if(pict->data[plane_index]) //FIXME gray hack
 +                for(y=0; y<h; y++){
 +                    for(x=0; x<w; x++){
 +                        int d= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];
 +                        error += d*d;
 +                    }
 +                }
 +            s->avctx->error[plane_index] += error;
 +            s->encoding_error[plane_index] = error;
 +        }
 +
 +    }
 +
 +    update_last_header_values(s);
 +
 +    ff_snow_release_buffer(avctx);
 +
 +    s->current_picture->coded_picture_number = avctx->frame_number;
 +    s->current_picture->pict_type = pic->pict_type;
 +    s->current_picture->quality = pic->quality;
 +    s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start);
 +    s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits;
 +    s->m.current_picture.f->display_picture_number =
 +    s->m.current_picture.f->coded_picture_number   = avctx->frame_number;
 +    s->m.current_picture.f->quality                = pic->quality;
 +    s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
 +    if(s->pass1_rc)
 +        if (ff_rate_estimate_qscale(&s->m, 0) < 0)
 +            return -1;
 +    if(avctx->flags&AV_CODEC_FLAG_PASS1)
 +        ff_write_pass1_stats(&s->m);
 +    s->m.last_pict_type = s->m.pict_type;
 +    avctx->frame_bits = s->m.frame_bits;
 +    avctx->mv_bits = s->m.mv_bits;
 +    avctx->misc_bits = s->m.misc_bits;
 +    avctx->p_tex_bits = s->m.p_tex_bits;
 +
 +    emms_c();
 +
 +    ff_side_data_set_encoder_stats(pkt, s->current_picture->quality,
 +                                   s->encoding_error,
 +                                   (s->avctx->flags&AV_CODEC_FLAG_PSNR) ? 4 : 0,
 +                                   s->current_picture->pict_type);
 +
 +#if FF_API_ERROR_FRAME
 +FF_DISABLE_DEPRECATION_WARNINGS
 +    memcpy(s->current_picture->error, s->encoding_error, sizeof(s->encoding_error));
 +FF_ENABLE_DEPRECATION_WARNINGS
 +#endif
 +
 +    pkt->size = ff_rac_terminate(c);
 +    if (s->current_picture->key_frame)
 +        pkt->flags |= AV_PKT_FLAG_KEY;
 +    *got_packet = 1;
 +
 +    return 0;
 +}
 +
 +static av_cold int encode_end(AVCodecContext *avctx)
 +{
 +    SnowContext *s = avctx->priv_data;
 +
 +    ff_snow_common_end(s);
 +    ff_rate_control_uninit(&s->m);
 +    av_frame_free(&s->input_picture);
 +    av_freep(&avctx->stats_out);
 +
 +    return 0;
 +}
 +
 +#define OFFSET(x) offsetof(SnowContext, x)
 +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 +static const AVOption options[] = {
 +    FF_MPV_COMMON_OPTS
 +    { "iter",           NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ITER }, 0, 0, FF_MPV_OPT_FLAGS, "motion_est" },
 +    { "memc_only",      "Only do ME/MC (I frames -> ref, P frame -> ME+MC).",   OFFSET(memc_only), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
 +    { "no_bitstream",   "Skip final bitstream writeout.",                    OFFSET(no_bitstream), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
 +    { "intra_penalty",  "Penalty for intra blocks in block decission",      OFFSET(intra_penalty), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
 +    { "iterative_dia_size",  "Dia size for the iterative ME",          OFFSET(iterative_dia_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
 +    { "sc_threshold",   "Scene change threshold",                   OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE },
 +    { "pred",           "Spatial decomposition type",                                OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, DWT_97, DWT_53, VE, "pred" },
 +        { "dwt97", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" },
 +        { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" },
 +    { NULL },
 +};
 +
 +static const AVClass snowenc_class = {
 +    .class_name = "snow encoder",
 +    .item_name  = av_default_item_name,
 +    .option     = options,
 +    .version    = LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_snow_encoder = {
 +    .name           = "snow",
 +    .long_name      = NULL_IF_CONFIG_SMALL("Snow"),
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_SNOW,
 +    .priv_data_size = sizeof(SnowContext),
 +    .init           = encode_init,
 +    .encode2        = encode_frame,
 +    .close          = encode_end,
 +    .pix_fmts       = (const enum AVPixelFormat[]){
 +        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV444P,
 +        AV_PIX_FMT_GRAY8,
 +        AV_PIX_FMT_NONE
 +    },
 +    .priv_class     = &snowenc_class,
 +    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
 +                      FF_CODEC_CAP_INIT_CLEANUP,
 +};
index 0000000,0000000..7b3b718
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,37 @@@
++/*
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "avcodec.h"
++
++int main(void){
++    AVCodec *codec = NULL;
++    int ret = 0;
++    avcodec_register_all();
++
++    while (codec = av_codec_next(codec)) {
++        if (av_codec_is_encoder(codec)) {
++            if (codec->type == AVMEDIA_TYPE_AUDIO) {
++                if (!codec->sample_fmts) {
++                    av_log(NULL, AV_LOG_FATAL, "Encoder %s is missing the sample_fmts field\n", codec->name);
++                    ret = 1;
++                }
++            }
++        }
++    }
++    return ret;
++}
Simple merge
index 0000000,5e93f3c..39432d5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,92 +1,98 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -            double bestpar0   = 1;
 -            double bestpar1   = 0.001;
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdio.h>
+ #include "libavutil/common.h"
+ #include "libavutil/lfg.h"
+ #include "timefilter.h"
+ #define LFG_MAX ((1LL << 32) - 1)
+ int main(void)
+ {
+     AVLFG prng;
+     double n0, n1;
+ #define SAMPLES 1000
+     double ideal[SAMPLES];
+     double samples[SAMPLES];
++    double samplet[SAMPLES];
+     for (n0 = 0; n0 < 40; n0 = 2 * n0 + 1) {
+         for (n1 = 0; n1 < 10; n1 = 2 * n1 + 1) {
+             double best_error = 1000000000;
 -                ideal[i]   = 10 + i + n1 * i / (1000);
++            double bestpar0   = n0 ? 1 : 100000;
++            double bestpar1   = 1;
+             int better, i;
+             av_lfg_init(&prng, 123);
+             for (i = 0; i < SAMPLES; i++) {
 -                            filtered = ff_timefilter_update(tf, samples[i], 1);
++                samplet[i] = 10 + i + (av_lfg_get(&prng) < LFG_MAX/2 ? 0 : 0.999);
++                ideal[i]   = samplet[i] + n1 * i / (1000);
+                 samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) / (LFG_MAX * 10LL);
++                if(i && samples[i]<samples[i-1])
++                    samples[i]=samples[i-1]+0.001;
+             }
+             do {
+                 double par0, par1;
+                 better = 0;
+                 for (par0 = bestpar0 * 0.8; par0 <= bestpar0 * 1.21; par0 += bestpar0 * 0.05) {
+                     for (par1 = bestpar1 * 0.8; par1 <= bestpar1 * 1.21; par1 += bestpar1 * 0.05) {
+                         double error   = 0;
+                         TimeFilter *tf = ff_timefilter_new(1, par0, par1);
+                         if (!tf) {
+                             printf("Could not allocate memory for timefilter.\n");
+                             exit(1);
+                         }
+                         for (i = 0; i < SAMPLES; i++) {
+                             double filtered;
 -            printf(" [%f %f %9f]", bestpar0, bestpar1, best_error);
++                            filtered = ff_timefilter_update(tf, samples[i], i ? (samplet[i] - samplet[i-1]) : 1);
++                            if(filtered < 0 || filtered > 1000000000)
++                                printf("filter is unstable\n");
+                             error   += (filtered - ideal[i]) * (filtered - ideal[i]);
+                         }
+                         ff_timefilter_destroy(tf);
+                         if (error < best_error) {
+                             best_error = error;
+                             bestpar0   = par0;
+                             bestpar1   = par1;
+                             better     = 1;
+                         }
+                     }
+                 }
+             } while (better);
+ #if 0
+             double lastfil = 9;
+             TimeFilter *tf = ff_timefilter_new(1, bestpar0, bestpar1);
+             for (i = 0; i < SAMPLES; i++) {
+                 double filtered;
+                 filtered = ff_timefilter_update(tf, samples[i], 1);
+                 printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i],
+                        samples[FFMAX(i, 1)] - samples[FFMAX(i - 1, 0)], filtered - lastfil);
+                 lastfil = filtered;
+             }
+             ff_timefilter_destroy(tf);
+ #else
++            printf(" [%12f %11f %9f]", bestpar0, bestpar1, best_error);
+ #endif
+         }
+         printf("\n");
+     }
+     return 0;
+ }
@@@ -84,85 -77,3 +84,8 @@@ double ff_timefilter_update(TimeFilter 
      }
      return self->cycle_time;
  }
- #ifdef TEST
- #include "libavutil/lfg.h"
- #define LFG_MAX ((1LL << 32) - 1)
- int main(void)
- {
-     AVLFG prng;
-     double n0, n1;
- #define SAMPLES 1000
-     double ideal[SAMPLES];
-     double samples[SAMPLES];
-     double samplet[SAMPLES];
-     for (n0 = 0; n0 < 40; n0 = 2 * n0 + 1) {
-         for (n1 = 0; n1 < 10; n1 = 2 * n1 + 1) {
-             double best_error = 1000000000;
-             double bestpar0   = n0 ? 1 : 100000;
-             double bestpar1   = 1;
-             int better, i;
-             av_lfg_init(&prng, 123);
-             for (i = 0; i < SAMPLES; i++) {
-                 samplet[i] = 10 + i + (av_lfg_get(&prng) < LFG_MAX/2 ? 0 : 0.999);
-                 ideal[i]   = samplet[i] + n1 * i / (1000);
-                 samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) / (LFG_MAX * 10LL);
-                 if(i && samples[i]<samples[i-1])
-                     samples[i]=samples[i-1]+0.001;
-             }
-             do {
-                 double par0, par1;
-                 better = 0;
-                 for (par0 = bestpar0 * 0.8; par0 <= bestpar0 * 1.21; par0 += bestpar0 * 0.05) {
-                     for (par1 = bestpar1 * 0.8; par1 <= bestpar1 * 1.21; par1 += bestpar1 * 0.05) {
-                         double error   = 0;
-                         TimeFilter *tf = ff_timefilter_new(1, par0, par1);
-                         if (!tf) {
-                             printf("Could not allocate memory for timefilter.\n");
-                             exit(1);
-                         }
-                         for (i = 0; i < SAMPLES; i++) {
-                             double filtered;
-                             filtered = ff_timefilter_update(tf, samples[i], i ? (samplet[i] - samplet[i-1]) : 1);
-                             if(filtered < 0 || filtered > 1000000000)
-                                 printf("filter is unstable\n");
-                             error   += (filtered - ideal[i]) * (filtered - ideal[i]);
-                         }
-                         ff_timefilter_destroy(tf);
-                         if (error < best_error) {
-                             best_error = error;
-                             bestpar0   = par0;
-                             bestpar1   = par1;
-                             better     = 1;
-                         }
-                     }
-                 }
-             } while (better);
- #if 0
-             double lastfil = 9;
-             TimeFilter *tf = ff_timefilter_new(1, bestpar0, bestpar1);
-             for (i = 0; i < SAMPLES; i++) {
-                 double filtered;
-                 filtered = ff_timefilter_update(tf, samples[i], 1);
-                 printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i],
-                        samples[FFMAX(i, 1)] - samples[FFMAX(i - 1, 0)], filtered - lastfil);
-                 lastfil = filtered;
-             }
-             ff_timefilter_destroy(tf);
- #else
-             printf(" [%12f %11f %9f]", bestpar0, bestpar1, best_error);
- #endif
-         }
-         printf("\n");
-     }
-     return 0;
- }
- #endif
 +
 +double ff_timefilter_eval(TimeFilter *self, double delta)
 +{
 +    return self->cycle_time + self->clock_period * delta;
 +}
Simple merge
index 0000000,0000000..a891638
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,65 @@@
++/*
++ * Copyright (c) 2007 Bobby Bingham
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "formats.c"
++
++#undef printf
++
++int main(void)
++{
++    const int64_t *cl;
++    char buf[512];
++    int i;
++    const char *teststrings[] ={
++        "blah",
++        "1",
++        "2",
++        "-1",
++        "60",
++        "65",
++        "1c",
++        "2c",
++        "-1c",
++        "60c",
++        "65c",
++        "5.1",
++        "stereo",
++        "1+1+1+1",
++        "1c+1c+1c+1c",
++        "2c+1c",
++        "0x3",
++    };
++
++    for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
++        av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
++        printf("%s\n", buf);
++    }
++
++    for ( i = 0; i<FF_ARRAY_ELEMS(teststrings); i++) {
++        int64_t layout = -1;
++        int count = -1;
++        int ret;
++        ret = ff_parse_channel_layout(&layout, &count, teststrings[i], NULL);
++
++        printf ("%d = ff_parse_channel_layout(%016"PRIX64", %2d, %s);\n", ret ? -1 : 0, layout, count, teststrings[i]);
++    }
++
++    return 0;
++}
@@@ -593,142 -406,3 +593,93 @@@ static int default_query_formats_common
  
      return 0;
  }
- #ifdef TEST
- #undef printf
- int main(void)
- {
-     const int64_t *cl;
-     char buf[512];
-     int i;
-     const char *teststrings[] ={
-         "blah",
-         "1",
-         "2",
-         "-1",
-         "60",
-         "65",
-         "1c",
-         "2c",
-         "-1c",
-         "60c",
-         "65c",
-         "5.1",
-         "stereo",
-         "1+1+1+1",
-         "1c+1c+1c+1c",
-         "2c+1c",
-         "0x3",
-     };
-     for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
-         av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
-         printf("%s\n", buf);
-     }
-     for ( i = 0; i<FF_ARRAY_ELEMS(teststrings); i++) {
-         int64_t layout = -1;
-         int count = -1;
-         int ret;
-         ret = ff_parse_channel_layout(&layout, &count, teststrings[i], NULL);
-         printf ("%d = ff_parse_channel_layout(%016"PRIX64", %2d, %s);\n", ret ? -1 : 0, layout, count, teststrings[i]);
-     }
-     return 0;
- }
- #endif
 +
 +int ff_default_query_formats(AVFilterContext *ctx)
 +{
 +    return default_query_formats_common(ctx, ff_all_channel_layouts);
 +}
 +
 +int ff_query_formats_all(AVFilterContext *ctx)
 +{
 +    return default_query_formats_common(ctx, ff_all_channel_counts);
 +}
 +
 +/* internal functions for parsing audio format arguments */
 +
 +int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
 +{
 +    char *tail;
 +    int pix_fmt = av_get_pix_fmt(arg);
 +    if (pix_fmt == AV_PIX_FMT_NONE) {
 +        pix_fmt = strtol(arg, &tail, 0);
 +        if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
 +            av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
 +            return AVERROR(EINVAL);
 +        }
 +    }
 +    *ret = pix_fmt;
 +    return 0;
 +}
 +
 +int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
 +{
 +    char *tail;
 +    int sfmt = av_get_sample_fmt(arg);
 +    if (sfmt == AV_SAMPLE_FMT_NONE) {
 +        sfmt = strtol(arg, &tail, 0);
 +        if (*tail || av_get_bytes_per_sample(sfmt)<=0) {
 +            av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
 +            return AVERROR(EINVAL);
 +        }
 +    }
 +    *ret = sfmt;
 +    return 0;
 +}
 +
 +int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
 +{
 +    AVRational r;
 +    if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
 +        av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
 +        return AVERROR(EINVAL);
 +    }
 +    *ret = r;
 +    return 0;
 +}
 +
 +int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
 +{
 +    char *tail;
 +    double srate = av_strtod(arg, &tail);
 +    if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
 +        av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
 +        return AVERROR(EINVAL);
 +    }
 +    *ret = srate;
 +    return 0;
 +}
 +
 +int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
 +                            void *log_ctx)
 +{
 +    char *tail;
 +    int64_t chlayout;
 +
 +    chlayout = av_get_channel_layout(arg);
 +    if (chlayout == 0) {
 +        chlayout = strtol(arg, &tail, 10);
 +        if (!(*tail == '\0' || *tail == 'c' && *(tail + 1) == '\0') || chlayout <= 0 || chlayout > 63) {
 +            av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
 +            return AVERROR(EINVAL);
 +        }
 +        if (nret) {
 +            *nret = chlayout;
 +            *ret = 0;
 +            return 0;
 +        }
 +    }
 +    *ret = chlayout;
 +    if (nret)
 +        *nret = av_get_channel_layout_nb_channels(chlayout);
 +    return 0;
 +}
index 0000000,603bb79..e86fb18
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,158 +1,158 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "rtmpdh.c"
+ #include <stdio.h>
+ static int test_random_shared_secret(void)
+ {
+     FF_DH *peer1 = NULL, *peer2 = NULL;
+     int ret;
+     uint8_t pubkey1[128], pubkey2[128];
+     uint8_t sharedkey1[128], sharedkey2[128];
+     peer1 = ff_dh_init(1024);
+     peer2 = ff_dh_init(1024);
+     if (!peer1 || !peer2) {
+         ret = AVERROR(ENOMEM);
+         goto fail;
+     }
+     if ((ret = ff_dh_generate_public_key(peer1)) < 0)
+         goto fail;
+     if ((ret = ff_dh_generate_public_key(peer2)) < 0)
+         goto fail;
+     if ((ret = ff_dh_write_public_key(peer1, pubkey1, sizeof(pubkey1))) < 0)
+         goto fail;
+     if ((ret = ff_dh_write_public_key(peer2, pubkey2, sizeof(pubkey2))) < 0)
+         goto fail;
+     if ((ret = ff_dh_compute_shared_secret_key(peer1, pubkey2, sizeof(pubkey2),
+                                                sharedkey1, sizeof(sharedkey1))) < 0)
+         goto fail;
+     if ((ret = ff_dh_compute_shared_secret_key(peer2, pubkey1, sizeof(pubkey1),
+                                                sharedkey2, sizeof(sharedkey2))) < 0)
+         goto fail;
+     if (memcmp(sharedkey1, sharedkey2, sizeof(sharedkey1))) {
+         printf("Mismatched generated shared key\n");
+         ret = AVERROR_INVALIDDATA;
+     } else {
+         printf("Generated shared key ok\n");
+     }
+ fail:
+     ff_dh_free(peer1);
+     ff_dh_free(peer2);
+     return ret;
+ }
+ static const char *private_key =
+     "976C18FCADC255B456564F74F3EEDA59D28AF6B744D743F2357BFD2404797EF896EF1A"
+     "7C1CBEAAA3AB60AF3192D189CFF3F991C9CBBFD78119FCA2181384B94011943B6D6F28"
+     "9E1B708E2D1A0C7771169293F03DA27E561F15F16F0AC9BC858C77A80FA98FD088A232"
+     "19D08BE6F165DE0B02034B18705829FAD0ACB26A5B75EF";
+ static const char *public_key =
+     "F272ECF8362257C5D2C3CC2229CF9C0A03225BC109B1DBC76A68C394F256ACA3EF5F64"
+     "FC270C26382BF315C19E97A76104A716FC998A651E8610A3AE6CF65D8FAE5D3F32EEA0"
+     "0B32CB9609B494116A825D7142D17B88E3D20EDD98743DE29CF37A23A9F6A58B960591"
+     "3157D5965FCB46DDA73A1F08DD897BAE88DFE6FC937CBA";
+ static const uint8_t public_key_bin[] = {
+     0xf2, 0x72, 0xec, 0xf8, 0x36, 0x22, 0x57, 0xc5, 0xd2, 0xc3, 0xcc, 0x22,
+     0x29, 0xcf, 0x9c, 0x0a, 0x03, 0x22, 0x5b, 0xc1, 0x09, 0xb1, 0xdb, 0xc7,
+     0x6a, 0x68, 0xc3, 0x94, 0xf2, 0x56, 0xac, 0xa3, 0xef, 0x5f, 0x64, 0xfc,
+     0x27, 0x0c, 0x26, 0x38, 0x2b, 0xf3, 0x15, 0xc1, 0x9e, 0x97, 0xa7, 0x61,
+     0x04, 0xa7, 0x16, 0xfc, 0x99, 0x8a, 0x65, 0x1e, 0x86, 0x10, 0xa3, 0xae,
+     0x6c, 0xf6, 0x5d, 0x8f, 0xae, 0x5d, 0x3f, 0x32, 0xee, 0xa0, 0x0b, 0x32,
+     0xcb, 0x96, 0x09, 0xb4, 0x94, 0x11, 0x6a, 0x82, 0x5d, 0x71, 0x42, 0xd1,
+     0x7b, 0x88, 0xe3, 0xd2, 0x0e, 0xdd, 0x98, 0x74, 0x3d, 0xe2, 0x9c, 0xf3,
+     0x7a, 0x23, 0xa9, 0xf6, 0xa5, 0x8b, 0x96, 0x05, 0x91, 0x31, 0x57, 0xd5,
+     0x96, 0x5f, 0xcb, 0x46, 0xdd, 0xa7, 0x3a, 0x1f, 0x08, 0xdd, 0x89, 0x7b,
+     0xae, 0x88, 0xdf, 0xe6, 0xfc, 0x93, 0x7c, 0xba
+ };
+ static const uint8_t peer_public_key[] = {
+     0x58, 0x66, 0x05, 0x49, 0x94, 0x23, 0x2b, 0x66, 0x52, 0x13, 0xff, 0x46,
+     0xf2, 0xb3, 0x79, 0xa9, 0xee, 0xae, 0x1a, 0x13, 0xf0, 0x71, 0x52, 0xfb,
+     0x93, 0x4e, 0xee, 0x97, 0x05, 0x73, 0x50, 0x7d, 0xaf, 0x02, 0x07, 0x72,
+     0xac, 0xdc, 0xa3, 0x95, 0x78, 0xee, 0x9a, 0x19, 0x71, 0x7e, 0x99, 0x9f,
+     0x2a, 0xd4, 0xb3, 0xe2, 0x0c, 0x1d, 0x1a, 0x78, 0x4c, 0xde, 0xf1, 0xad,
+     0xb4, 0x60, 0xa8, 0x51, 0xac, 0x71, 0xec, 0x86, 0x70, 0xa2, 0x63, 0x36,
+     0x92, 0x7c, 0xe3, 0x87, 0xee, 0xe4, 0xf1, 0x62, 0x24, 0x74, 0xb4, 0x04,
+     0xfa, 0x5c, 0xdf, 0xba, 0xfa, 0xa3, 0xc2, 0xbb, 0x62, 0x27, 0xd0, 0xf4,
+     0xe4, 0x43, 0xda, 0x8a, 0x88, 0x69, 0x60, 0xe2, 0xdb, 0x75, 0x2a, 0x98,
+     0x9d, 0xb5, 0x50, 0xe3, 0x99, 0xda, 0xe0, 0xa6, 0x14, 0xc9, 0x80, 0x12,
+     0xf9, 0x3c, 0xac, 0x06, 0x02, 0x7a, 0xde, 0x74
+ };
+ static const uint8_t shared_secret[] = {
+     0xb2, 0xeb, 0xcb, 0x71, 0xf3, 0x61, 0xfb, 0x5b, 0x4e, 0x5c, 0x4c, 0xcf,
+     0x5c, 0x08, 0x5f, 0x96, 0x26, 0x77, 0x1d, 0x31, 0xf1, 0xe1, 0xf7, 0x4b,
+     0x92, 0xac, 0x82, 0x2a, 0x88, 0xc7, 0x83, 0xe1, 0xc7, 0xf3, 0xd3, 0x1a,
+     0x7d, 0xc8, 0x31, 0xe3, 0x97, 0xe4, 0xec, 0x31, 0x0e, 0x8f, 0x73, 0x1a,
+     0xe4, 0xf6, 0xd8, 0xc8, 0x94, 0xff, 0xa0, 0x03, 0x84, 0x03, 0x0f, 0xa5,
+     0x30, 0x5d, 0x67, 0xe0, 0x7a, 0x3b, 0x5f, 0xed, 0x4c, 0xf5, 0xbc, 0x18,
+     0xea, 0xd4, 0x77, 0xa9, 0x07, 0xb3, 0x54, 0x0b, 0x02, 0xd9, 0xc6, 0xb8,
+     0x66, 0x5e, 0xec, 0xa4, 0xcd, 0x47, 0xed, 0xc9, 0x38, 0xc6, 0x91, 0x08,
+     0xf3, 0x85, 0x9b, 0x69, 0x16, 0x78, 0x0d, 0xb7, 0x74, 0x51, 0xaa, 0x5b,
+     0x4d, 0x74, 0xe4, 0x29, 0x2e, 0x9e, 0x8e, 0xf7, 0xe5, 0x42, 0x83, 0xb0,
+     0x65, 0xb0, 0xce, 0xc6, 0xb2, 0x8f, 0x5b, 0xb0
+ };
+ static int test_ref_data(void)
+ {
+     FF_DH *dh;
+     int ret = AVERROR(ENOMEM);
+     uint8_t pubkey_test[128];
+     uint8_t sharedkey_test[128];
+     dh = ff_dh_init(1024);
+     if (!dh)
+         goto fail;
+     bn_hex2bn(dh->priv_key, private_key, ret);
+     if (!ret)
+         goto fail;
+     bn_hex2bn(dh->pub_key, public_key, ret);
+     if (!ret)
+         goto fail;
+     if ((ret = ff_dh_write_public_key(dh, pubkey_test, sizeof(pubkey_test))) < 0)
+         goto fail;
+     if (memcmp(pubkey_test, public_key_bin, sizeof(pubkey_test))) {
+         printf("Mismatched generated public key\n");
+         ret = AVERROR_INVALIDDATA;
+         goto fail;
+     } else {
+         printf("Generated public key ok\n");
+     }
+     if ((ret = ff_dh_compute_shared_secret_key(dh, peer_public_key, sizeof(peer_public_key),
+                                                sharedkey_test, sizeof(sharedkey_test))) < 0)
+         goto fail;
+     if (memcmp(shared_secret, sharedkey_test, sizeof(sharedkey_test))) {
+         printf("Mismatched generated shared key\n");
+         ret = AVERROR_INVALIDDATA;
+     } else {
+         printf("Generated shared key ok\n");
+     }
+ fail:
+     ff_dh_free(dh);
+     return ret;
+ }
+ int main(void)
+ {
+     if (test_random_shared_secret() < 0)
+         return 1;
+     if (test_ref_data() < 0)
+         return 1;
+     return 0;
+ }
Simple merge
index 0000000,fe8749c..1198f59
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,167 +1,167 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdint.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include "rtpdec.h"
+ #include "srtp.h"
+ static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+ static const uint8_t rtp_aes128_80[] = {
+     // RTP header
+     0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+     // encrypted payload
+     0x62, 0x69, 0x76, 0xca, 0xc5,
+     // HMAC
+     0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
+ };
+ static const uint8_t rtcp_aes128_80[] = {
+     // RTCP header
+     0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+     // encrypted payload
+     0x8a, 0xac, 0xdc, 0xa5, 0x4c, 0xf6, 0x78, 0xa6, 0x62, 0x8f, 0x24, 0xda,
+     0x6c, 0x09, 0x3f, 0xa9, 0x28, 0x7a, 0xb5, 0x7f, 0x1f, 0x0f, 0xc9, 0x35,
+     // RTCP index
+     0x80, 0x00, 0x00, 0x03,
+     // HMAC
+     0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
+ };
+ static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+ static const uint8_t rtp_aes128_32[] = {
+     // RTP header
+     0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+     // encrypted payload
+     0x62, 0x69, 0x76, 0xca, 0xc5,
+     // HMAC
+     0xa1, 0xac, 0x1b, 0xb4,
+ };
+ static const uint8_t rtcp_aes128_32[] = {
+     // RTCP header
+     0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+     // encrypted payload
+     0x35, 0xe9, 0xb5, 0xff, 0x0d, 0xd1, 0xde, 0x70, 0x74, 0x10, 0xaa, 0x1b,
+     0xb2, 0x8d, 0xf0, 0x20, 0x02, 0x99, 0x6b, 0x1b, 0x0b, 0xd0, 0x47, 0x34,
+     // RTCP index
+     0x80, 0x00, 0x00, 0x04,
+     // HMAC
+     0x5b, 0xd2, 0xa9, 0x9d,
+ };
+ static const char *aes128_80_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+ static const uint8_t rtp_aes128_80_32[] = {
+     // RTP header
+     0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+     // encrypted payload
+     0x62, 0x69, 0x76, 0xca, 0xc5,
+     // HMAC
+     0xa1, 0xac, 0x1b, 0xb4,
+ };
+ static const uint8_t rtcp_aes128_80_32[] = {
+     // RTCP header
+     0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+     // encrypted payload
+     0xd6, 0xae, 0xc1, 0x58, 0x63, 0x70, 0xc9, 0x88, 0x66, 0x26, 0x1c, 0x53,
+     0xff, 0x5d, 0x5d, 0x2b, 0x0f, 0x8c, 0x72, 0x3e, 0xc9, 0x1d, 0x43, 0xf9,
+     // RTCP index
+     0x80, 0x00, 0x00, 0x05,
+     // HMAC
+     0x09, 0x16, 0xb4, 0x27, 0x9a, 0xe9, 0x92, 0x26, 0x4e, 0x10,
+ };
+ static void print_data(const uint8_t *buf, int len)
+ {
+     int i;
+     for (i = 0; i < len; i++)
+         printf("%02x", buf[i]);
+     printf("\n");
+ }
+ static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
+                         uint8_t *out)
+ {
+     memcpy(out, in, len);
+     if (!ff_srtp_decrypt(srtp, out, &len)) {
+         print_data(out, len);
+         return len;
+     } else
+         return -1;
+ }
+ static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
+                          const char *key)
+ {
+     struct SRTPContext enc = { 0 }, dec = { 0 };
+     int len;
+     char buf[RTP_MAX_PACKET_LENGTH];
+     ff_srtp_set_crypto(&enc, suite, key);
+     ff_srtp_set_crypto(&dec, suite, key);
+     len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
+     if (!ff_srtp_decrypt(&dec, buf, &len)) {
+         if (len == in_len && !memcmp(buf, data, len))
+             printf("Decrypted content matches input\n");
+         else
+             printf("Decrypted content doesn't match input\n");
+     } else {
+         printf("Decryption failed\n");
+     }
+     ff_srtp_free(&enc);
+     ff_srtp_free(&dec);
+ }
+ int main(void)
+ {
+     static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
+     static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
+     static const char *aes128_80_32_suite = "SRTP_AES128_CM_HMAC_SHA1_32";
+     static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
+     uint8_t buf[RTP_MAX_PACKET_LENGTH];
+     struct SRTPContext srtp = { 0 };
+     int len;
+     ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
+     len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
+     test_encrypt(buf, len, aes128_80_suite, test_key);
+     test_encrypt(buf, len, aes128_32_suite, test_key);
+     test_encrypt(buf, len, aes128_80_32_suite, test_key);
+     test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
+     test_encrypt(buf, len, aes128_80_suite, test_key);
+     test_encrypt(buf, len, aes128_32_suite, test_key);
+     test_encrypt(buf, len, aes128_80_32_suite, test_key);
+     ff_srtp_free(&srtp);
+     memset(&srtp, 0, sizeof(srtp)); // Clear the context
+     ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
+     test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
+     test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);
+     ff_srtp_free(&srtp);
+     memset(&srtp, 0, sizeof(srtp)); // Clear the context
+     ff_srtp_set_crypto(&srtp, aes128_80_32_suite, aes128_80_32_key);
+     test_decrypt(&srtp, rtp_aes128_80_32, sizeof(rtp_aes128_80_32), buf);
+     test_decrypt(&srtp, rtcp_aes128_80_32, sizeof(rtcp_aes128_80_32), buf);
+     ff_srtp_free(&srtp);
+     return 0;
+ }
Simple merge
index 0000000,ab109f9..f93cf9d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,51 +1,53 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    char data[LEN];
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
++// LCOV_EXCL_START
+ #include <string.h>
+ #include "log.h"
+ #include "timer.h"
+ #include "adler32.h"
+ #define LEN 7001
+ static volatile int checksum;
+ int main(int argc, char **argv)
+ {
+     int i;
++    uint8_t data[LEN];
+     av_log_set_level(AV_LOG_DEBUG);
+     for (i = 0; i < LEN; i++)
+         data[i] = ((i * i) >> 3) + 123 * i;
+     if (argc > 1 && !strcmp(argv[1], "-t")) {
+         for (i = 0; i < 1000; i++) {
+             START_TIMER;
+             checksum = av_adler32_update(1, data, LEN);
+             STOP_TIMER("adler");
+         }
+     } else {
+         checksum = av_adler32_update(1, data, LEN);
+     }
+     av_log(NULL, AV_LOG_DEBUG, "%X (expected 50E6E508)\n", checksum);
+     return checksum == 0x50e6e508 ? 0 : 1;
+ }
++// LCOV_EXCL_STOP
Simple merge
index 0000000,92404e4..a71b7fe
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,92 +1,102 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    uint8_t pt[16], rpt[2][16] = {
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "aes.c"
++// LCOV_EXCL_START
+ #include <string.h>
+ #include "lfg.h"
+ #include "log.h"
+ int main(int argc, char **argv)
+ {
+     int i, j;
+     AVAES b;
+     uint8_t rkey[2][16] = {
+         { 0 },
+         { 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,
+           0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 }
+     };
 -    uint8_t temp[16];
++    uint8_t pt[32], rpt[2][16] = {
+         { 0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad,
+           0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3 },
+         { 0 }
+     };
+     uint8_t rct[2][16] = {
+         { 0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7,
+           0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf },
+         { 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0,
+           0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 }
+     };
 -        av_aes_init(&ae, "PI=3.141592654..", 128, 0);
 -        av_aes_init(&ad, "PI=3.141592654..", 128, 1);
++    uint8_t temp[32];
++    uint8_t iv[2][16];
+     int err = 0;
+     av_log_set_level(AV_LOG_DEBUG);
+     for (i = 0; i < 2; i++) {
+         av_aes_init(&b, rkey[i], 128, 1);
+         av_aes_crypt(&b, temp, rct[i], 1, NULL, 1);
+         for (j = 0; j < 16; j++) {
+             if (rpt[i][j] != temp[j]) {
+                 av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n",
+                        j, rpt[i][j], temp[j]);
+                 err = 1;
+             }
+         }
+     }
+     if (argc > 1 && !strcmp(argv[1], "-t")) {
+         AVAES ae, ad;
+         AVLFG prng;
 -            for (j = 0; j < 16; j++)
++        av_aes_init(&ae, (const uint8_t*)"PI=3.141592654..", 128, 0);
++        av_aes_init(&ad, (const uint8_t*)"PI=3.141592654..", 128, 1);
+         av_lfg_init(&prng, 1);
+         for (i = 0; i < 10000; i++) {
 -                av_aes_crypt(&ae, temp, pt, 1, NULL, 0);
++            for (j = 0; j < 32; j++)
+                 pt[j] = av_lfg_get(&prng);
++            for (j = 0; j < 16; j++)
++                iv[0][j] = iv[1][j] = av_lfg_get(&prng);
+             {
+                 START_TIMER;
 -                av_aes_crypt(&ad, temp, temp, 1, NULL, 1);
++                av_aes_crypt(&ae, temp, pt, 2, iv[0], 0);
++                if (!(i & (i - 1)))
++                    av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n",
++                           temp[0], temp[5], temp[10], temp[15]);
++                av_aes_crypt(&ad, temp, temp, 2, iv[1], 1);
++                av_aes_crypt(&ae, temp, pt, 2, NULL, 0);
+                 if (!(i & (i - 1)))
+                     av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n",
+                            temp[0], temp[5], temp[10], temp[15]);
++                av_aes_crypt(&ad, temp, temp, 2, NULL, 1);
+                 STOP_TIMER("aes");
+             }
+             for (j = 0; j < 16; j++) {
+                 if (pt[j] != temp[j]) {
+                     av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n",
+                            i, j, pt[j], temp[j]);
+                 }
+             }
+         }
+     }
+     return err;
+ }
++// LCOV_EXCL_STOP
diff --cc libavutil/aes.c
@@@ -265,88 -262,3 +265,4 @@@ int av_aes_init(AVAES *a, const uint8_
  
      return 0;
  }
- #ifdef TEST
- // LCOV_EXCL_START
- #include <string.h>
- #include "lfg.h"
- #include "log.h"
- int main(int argc, char **argv)
- {
-     int i, j;
-     AVAES b;
-     uint8_t rkey[2][16] = {
-         { 0 },
-         { 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,
-           0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 }
-     };
-     uint8_t pt[32], rpt[2][16] = {
-         { 0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad,
-           0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3 },
-         { 0 }
-     };
-     uint8_t rct[2][16] = {
-         { 0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7,
-           0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf },
-         { 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0,
-           0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 }
-     };
-     uint8_t temp[32];
-     uint8_t iv[2][16];
-     int err = 0;
-     av_log_set_level(AV_LOG_DEBUG);
-     for (i = 0; i < 2; i++) {
-         av_aes_init(&b, rkey[i], 128, 1);
-         av_aes_crypt(&b, temp, rct[i], 1, NULL, 1);
-         for (j = 0; j < 16; j++) {
-             if (rpt[i][j] != temp[j]) {
-                 av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n",
-                        j, rpt[i][j], temp[j]);
-                 err = 1;
-             }
-         }
-     }
-     if (argc > 1 && !strcmp(argv[1], "-t")) {
-         AVAES ae, ad;
-         AVLFG prng;
-         av_aes_init(&ae, (const uint8_t*)"PI=3.141592654..", 128, 0);
-         av_aes_init(&ad, (const uint8_t*)"PI=3.141592654..", 128, 1);
-         av_lfg_init(&prng, 1);
-         for (i = 0; i < 10000; i++) {
-             for (j = 0; j < 32; j++)
-                 pt[j] = av_lfg_get(&prng);
-             for (j = 0; j < 16; j++)
-                 iv[0][j] = iv[1][j] = av_lfg_get(&prng);
-             {
-                 START_TIMER;
-                 av_aes_crypt(&ae, temp, pt, 2, iv[0], 0);
-                 if (!(i & (i - 1)))
-                     av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n",
-                            temp[0], temp[5], temp[10], temp[15]);
-                 av_aes_crypt(&ad, temp, temp, 2, iv[1], 1);
-                 av_aes_crypt(&ae, temp, pt, 2, NULL, 0);
-                 if (!(i & (i - 1)))
-                     av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n",
-                            temp[0], temp[5], temp[10], temp[15]);
-                 av_aes_crypt(&ad, temp, temp, 2, NULL, 1);
-                 STOP_TIMER("aes");
-             }
-             for (j = 0; j < 16; j++) {
-                 if (pt[j] != temp[j]) {
-                     av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n",
-                            i, j, pt[j], temp[j]);
-                 }
-             }
-         }
-     }
-     return err;
- }
- // LCOV_EXCL_STOP
- #endif
 +
index 0000000,c0a89a4..397d8c9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,35 +1,34 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -#include <assert.h>
 -
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
 -    assert(res == 2);
+ #include "atomic.h"
++#include "avassert.h"
+ int main(void)
+ {
+     volatile int val = 1;
+     int res;
+     res = avpriv_atomic_int_add_and_fetch(&val, 1);
 -    assert(res == 3);
++    av_assert0(res == 2);
+     avpriv_atomic_int_set(&val, 3);
+     res = avpriv_atomic_int_get(&val);
++    av_assert0(res == 3);
+     return 0;
+ }
Simple merge
index 0000000,7732c22..3e29661
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,69 +1,83 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    const char *strings[] = {
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdio.h>
+ #include "common.h"
+ #include "mem.h"
+ #include "avstring.h"
+ int main(void)
+ {
+     int i;
++    char *fullpath;
++    static const char * const strings[] = {
+         "''",
+         "",
+         ":",
+         "\\",
+         "'",
+         "    ''    :",
+         "    ''  ''  :",
+         "foo   '' :",
+         "'foo'",
+         "foo     ",
+         "  '  foo  '  ",
+         "foo\\",
+         "foo':  blah:blah",
+         "foo\\:  blah:blah",
+         "foo\'",
+         "'foo :  '  :blahblah",
+         "\\ :blah",
+         "     foo",
+         "      foo       ",
+         "      foo     \\ ",
+         "foo ':blah",
+         " foo   bar    :   blahblah",
+         "\\f\\o\\o",
+         "'foo : \\ \\  '   : blahblah",
+         "'\\fo\\o:': blahblah",
+         "\\'fo\\o\\:':  foo  '  :blahblah"
+     };
+     printf("Testing av_get_token()\n");
+     for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) {
+         const char *p = strings[i];
+         char *q;
+         printf("|%s|", p);
+         q = av_get_token(&p, ":");
+         printf(" -> |%s|", q);
+         printf(" + |%s|\n", p);
+         av_free(q);
+     }
++    printf("Testing av_append_path_component()\n");
++    #define TEST_APPEND_PATH_COMPONENT(path, component, expected) \
++        fullpath = av_append_path_component((path), (component)); \
++        printf("%s = %s\n", fullpath ? fullpath : "(null)", expected); \
++        av_free(fullpath);
++    TEST_APPEND_PATH_COMPONENT(NULL, NULL, "(null)")
++    TEST_APPEND_PATH_COMPONENT("path", NULL, "path");
++    TEST_APPEND_PATH_COMPONENT(NULL, "comp", "comp");
++    TEST_APPEND_PATH_COMPONENT("path", "comp", "path/comp");
++    TEST_APPEND_PATH_COMPONENT("path/", "comp", "path/comp");
++    TEST_APPEND_PATH_COMPONENT("path", "/comp", "path/comp");
++    TEST_APPEND_PATH_COMPONENT("path/", "/comp", "path/comp");
++    TEST_APPEND_PATH_COMPONENT("path/path2/", "/comp/comp2", "path/path2/comp/comp2");
+     return 0;
+ }
@@@ -326,176 -221,11 +326,112 @@@ int av_match_name(const char *name, con
          return 0;
  
      namelen = strlen(name);
 -    while ((p = strchr(names, ','))) {
 +    while (*names) {
 +        int negate = '-' == *names;
 +        p = strchr(names, ',');
 +        if (!p)
 +            p = names + strlen(names);
 +        names += negate;
          len = FFMAX(p - names, namelen);
 -        if (!av_strncasecmp(name, names, len))
 -            return 1;
 -        names = p + 1;
 +        if (!av_strncasecmp(name, names, len) || !strncmp("ALL", names, FFMAX(3, p - names)))
 +            return !negate;
 +        names = p + (*p == ',');
      }
 -    return !av_strcasecmp(name, names);
 +    return 0;
 +}
 +
 +int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end,
 +                   unsigned int flags)
 +{
 +    const uint8_t *p = *bufp;
 +    uint32_t top;
 +    uint64_t code;
 +    int ret = 0, tail_len;
 +    uint32_t overlong_encoding_mins[6] = {
 +        0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000,
 +    };
 +
 +    if (p >= buf_end)
 +        return 0;
 +
 +    code = *p++;
 +
 +    /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111,
 +       which is not admitted */
 +    if ((code & 0xc0) == 0x80 || code >= 0xFE) {
 +        ret = AVERROR(EILSEQ);
 +        goto end;
 +    }
 +    top = (code & 128) >> 1;
 +
 +    tail_len = 0;
 +    while (code & top) {
 +        int tmp;
 +        tail_len++;
 +        if (p >= buf_end) {
 +            (*bufp) ++;
 +            return AVERROR(EILSEQ); /* incomplete sequence */
 +        }
 +
 +        /* we assume the byte to be in the form 10xx-xxxx */
 +        tmp = *p++ - 128;   /* strip leading 1 */
 +        if (tmp>>6) {
 +            (*bufp) ++;
 +            return AVERROR(EILSEQ);
 +        }
 +        code = (code<<6) + tmp;
 +        top <<= 5;
 +    }
 +    code &= (top << 1) - 1;
 +
 +    /* check for overlong encodings */
 +    av_assert0(tail_len <= 5);
 +    if (code < overlong_encoding_mins[tail_len]) {
 +        ret = AVERROR(EILSEQ);
 +        goto end;
 +    }
 +
 +    if (code >= 1U<<31) {
 +        ret = AVERROR(EILSEQ);  /* out-of-range value */
 +        goto end;
 +    }
 +
 +    *codep = code;
 +
 +    if (code > 0x10FFFF &&
 +        !(flags & AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES))
 +        ret = AVERROR(EILSEQ);
 +    if (code < 0x20 && code != 0x9 && code != 0xA && code != 0xD &&
 +        flags & AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES)
 +        ret = AVERROR(EILSEQ);
 +    if (code >= 0xD800 && code <= 0xDFFF &&
 +        !(flags & AV_UTF8_FLAG_ACCEPT_SURROGATES))
 +        ret = AVERROR(EILSEQ);
 +    if ((code == 0xFFFE || code == 0xFFFF) &&
 +        !(flags & AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS))
 +        ret = AVERROR(EILSEQ);
 +
 +end:
 +    *bufp = p;
 +    return ret;
 +}
 +
 +int av_match_list(const char *name, const char *list, char separator)
 +{
 +    const char *p, *q;
 +
 +    for (p = name; p && *p; ) {
 +        for (q = list; q && *q; ) {
 +            int k;
 +            for (k = 0; p[k] == q[k] || (p[k]*q[k] == 0 && p[k]+q[k] == separator); k++)
 +                if (k && (!p[k] || p[k] == separator))
 +                    return 1;
 +            q = strchr(q, separator);
 +            q += !!q;
 +        }
 +        p = strchr(p, separator);
 +        p += !!p;
 +    }
 +
 +    return 0;
  }
- #ifdef TEST
- int main(void)
- {
-     int i;
-     char *fullpath;
-     static const char * const strings[] = {
-         "''",
-         "",
-         ":",
-         "\\",
-         "'",
-         "    ''    :",
-         "    ''  ''  :",
-         "foo   '' :",
-         "'foo'",
-         "foo     ",
-         "  '  foo  '  ",
-         "foo\\",
-         "foo':  blah:blah",
-         "foo\\:  blah:blah",
-         "foo\'",
-         "'foo :  '  :blahblah",
-         "\\ :blah",
-         "     foo",
-         "      foo       ",
-         "      foo     \\ ",
-         "foo ':blah",
-         " foo   bar    :   blahblah",
-         "\\f\\o\\o",
-         "'foo : \\ \\  '   : blahblah",
-         "'\\fo\\o:': blahblah",
-         "\\'fo\\o\\:':  foo  '  :blahblah"
-     };
-     printf("Testing av_get_token()\n");
-     for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) {
-         const char *p = strings[i];
-         char *q;
-         printf("|%s|", p);
-         q = av_get_token(&p, ":");
-         printf(" -> |%s|", q);
-         printf(" + |%s|\n", p);
-         av_free(q);
-     }
-     printf("Testing av_append_path_component()\n");
-     #define TEST_APPEND_PATH_COMPONENT(path, component, expected) \
-         fullpath = av_append_path_component((path), (component)); \
-         printf("%s = %s\n", fullpath ? fullpath : "(null)", expected); \
-         av_free(fullpath);
-     TEST_APPEND_PATH_COMPONENT(NULL, NULL, "(null)")
-     TEST_APPEND_PATH_COMPONENT("path", NULL, "path");
-     TEST_APPEND_PATH_COMPONENT(NULL, "comp", "comp");
-     TEST_APPEND_PATH_COMPONENT("path", "comp", "path/comp");
-     TEST_APPEND_PATH_COMPONENT("path/", "comp", "path/comp");
-     TEST_APPEND_PATH_COMPONENT("path", "/comp", "path/comp");
-     TEST_APPEND_PATH_COMPONENT("path/", "/comp", "path/comp");
-     TEST_APPEND_PATH_COMPONENT("path/path2/", "/comp/comp2", "path/path2/comp/comp2");
-     return 0;
- }
- #endif /* TEST */
index 0000000,3ce0518..19ecd2b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,84 +1,128 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) {
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
++// LCOV_EXCL_START
+ #include <stdint.h>
+ #include <stdio.h>
+ #include "common.h"
+ #include "base64.h"
++#include "timer.h"
+ #define MAX_DATA_SIZE    1024
+ #define MAX_ENCODED_SIZE 2048
+ static int test_encode_decode(const uint8_t *data, unsigned int data_size,
+                               const char *encoded_ref)
+ {
+     char  encoded[MAX_ENCODED_SIZE];
+     uint8_t data2[MAX_DATA_SIZE];
+     int data2_size, max_data2_size = MAX_DATA_SIZE;
+     if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) {
+         printf("Failed: cannot encode the input data\n");
+         return 1;
+     }
+     if (encoded_ref && strcmp(encoded, encoded_ref)) {
+         printf("Failed: encoded string differs from reference\n"
+                "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref);
+         return 1;
+     }
 -int main(void)
++    if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) != data_size) {
+         printf("Failed: cannot decode the encoded string\n"
+                "Encoded:\n%s\n", encoded);
+         return 1;
+     }
++    if ((data2_size = av_base64_decode(data2, encoded, data_size)) != data_size) {
++        printf("Failed: cannot decode with minimal buffer\n"
++               "Encoded:\n%s\n", encoded);
++        return 1;
++    }
+     if (memcmp(data2, data, data_size)) {
+         printf("Failed: encoded/decoded data differs from original data\n");
+         return 1;
+     }
++    if (av_base64_decode(NULL, encoded, 0) != 0) {
++        printf("Failed: decode to NULL buffer\n");
++        return 1;
++    }
++    if (strlen(encoded)) {
++        char *end = strchr(encoded, '=');
++        if (!end)
++            end = encoded + strlen(encoded) - 1;
++        *end = '%';
++        if (av_base64_decode(NULL, encoded, 0) >= 0) {
++            printf("Failed: error detection\n");
++            return 1;
++        }
++    }
+     printf("Passed!\n");
+     return 0;
+ }
++int main(int argc, char ** argv)
+ {
+     int i, error_count = 0;
+     struct test {
+         const uint8_t *data;
+         const char *encoded_ref;
+     } tests[] = {
+         { "",        ""},
+         { "1",       "MQ=="},
+         { "22",      "MjI="},
+         { "333",     "MzMz"},
+         { "4444",    "NDQ0NA=="},
+         { "55555",   "NTU1NTU="},
+         { "666666",  "NjY2NjY2"},
+         { "abc:def", "YWJjOmRlZg=="},
+     };
++    char in[1024], out[2048];
+     printf("Encoding/decoding tests\n");
+     for (i = 0; i < FF_ARRAY_ELEMS(tests); i++)
+         error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref);
++    if (argc>1 && !strcmp(argv[1], "-t")) {
++        memset(in, 123, sizeof(in));
++        for(i=0; i<10000; i++){
++            START_TIMER
++            av_base64_encode(out, sizeof(out), in, sizeof(in));
++            STOP_TIMER("encode")
++        }
++        for(i=0; i<10000; i++){
++            START_TIMER
++            av_base64_decode(in, out, sizeof(in));
++            STOP_TIMER("decode")
++        }
++
++        for(i=0; i<10000; i++){
++            START_TIMER
++            av_base64_decode(NULL, out, 0);
++            STOP_TIMER("syntax check")
++        }
++    }
++
+     if (error_count)
+         printf("Error Count: %d.\n", error_count);
+     return !!error_count;
+ }
++
++// LCOV_EXCL_STOP
Simple merge
index 0000000,4281ca2..3ad7cd7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,190 +1,190 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "blowfish.h"
+ #define NUM_VARIABLE_KEY_TESTS 34
+ /* plaintext bytes -- left halves */
+ static const uint32_t plaintext_l[NUM_VARIABLE_KEY_TESTS] = {
+     0x00000000, 0xFFFFFFFF, 0x10000000, 0x11111111, 0x11111111,
+     0x01234567, 0x00000000, 0x01234567, 0x01A1D6D0, 0x5CD54CA8,
+     0x0248D438, 0x51454B58, 0x42FD4430, 0x059B5E08, 0x0756D8E0,
+     0x762514B8, 0x3BDD1190, 0x26955F68, 0x164D5E40, 0x6B056E18,
+     0x004BD6EF, 0x480D3900, 0x437540C8, 0x072D43A0, 0x02FE5577,
+     0x1D9D5C50, 0x30553228, 0x01234567, 0x01234567, 0x01234567,
+     0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF
+ };
+ /* plaintext bytes -- right halves */
+ static const uint32_t plaintext_r[NUM_VARIABLE_KEY_TESTS] = {
+     0x00000000, 0xFFFFFFFF, 0x00000001, 0x11111111, 0x11111111,
+     0x89ABCDEF, 0x00000000, 0x89ABCDEF, 0x39776742, 0x3DEF57DA,
+     0x06F67172, 0x2DDF440A, 0x59577FA2, 0x51CF143A, 0x774761D2,
+     0x29BF486A, 0x49372802, 0x35AF609A, 0x4F275232, 0x759F5CCA,
+     0x09176062, 0x6EE762F2, 0x698F3CFA, 0x77075292, 0x8117F12A,
+     0x18F728C2, 0x6D6F295A, 0x89ABCDEF, 0x89ABCDEF, 0x89ABCDEF,
+     0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF
+ };
+ /* key bytes for variable key tests */
+ static const uint8_t variable_key[NUM_VARIABLE_KEY_TESTS][8] = {
+     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+     { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+     { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+     { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 },
+     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+     { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 },
+     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+     { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+     { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
+     { 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E },
+     { 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86 },
+     { 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E },
+     { 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6 },
+     { 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE },
+     { 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6 },
+     { 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE },
+     { 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16 },
+     { 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F },
+     { 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46 },
+     { 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E },
+     { 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76 },
+     { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07 },
+     { 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F },
+     { 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7 },
+     { 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF },
+     { 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6 },
+     { 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF },
+     { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
+     { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
+     { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
+     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+     { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+     { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+ };
+ /* ciphertext bytes -- left halves */
+ static const uint32_t ciphertext_l[NUM_VARIABLE_KEY_TESTS] = {
+     0x4EF99745, 0x51866FD5, 0x7D856F9A, 0x2466DD87, 0x61F9C380,
+     0x7D0CC630, 0x4EF99745, 0x0ACEAB0F, 0x59C68245, 0xB1B8CC0B,
+     0x1730E577, 0xA25E7856, 0x353882B1, 0x48F4D088, 0x432193B7,
+     0x13F04154, 0x2EEDDA93, 0xD887E039, 0x5F99D04F, 0x4A057A3B,
+     0x452031C1, 0x7555AE39, 0x53C55F9C, 0x7A8E7BFA, 0xCF9C5D7A,
+     0xD1ABB290, 0x55CB3774, 0xFA34EC48, 0xA7907951, 0xC39E072D,
+     0x014933E0, 0xF21E9A77, 0x24594688, 0x6B5C5A9C
+ };
+ /* ciphertext bytes -- right halves */
+ static const uint32_t ciphertext_r[NUM_VARIABLE_KEY_TESTS] = {
+     0x6198DD78, 0xB85ECB8A, 0x613063F2, 0x8B963C9D, 0x2281B096,
+     0xAFDA1EC7, 0x6198DD78, 0xC6A0A28D, 0xEB05282B, 0x250F09A0,
+     0x8BEA1DA4, 0xCF2651EB, 0x09CE8F1A, 0x4C379918, 0x8951FC98,
+     0xD69D1AE5, 0xFFD39C79, 0x3C2DA6E3, 0x5B163969, 0x24D3977B,
+     0xE4FADA8E, 0xF59B87BD, 0xB49FC019, 0x937E89A3, 0x4986ADB5,
+     0x658BC778, 0xD13EF201, 0x47B268B2, 0x08EA3CAE, 0x9FAC631D,
+     0xCDAFF6E4, 0xB71C49BC, 0x5754369A, 0x5D9E0A5A
+ };
+ /* plaintext bytes */
+ static const uint8_t plaintext[8] = "BLOWFISH";
+ static const uint8_t plaintext2[16] = "BLOWFISHBLOWFISH";
+ /* ciphertext bytes */
+ static const uint8_t ciphertext[8] = {
+     0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03
+ };
+ static const uint8_t ciphertext2[16] = {
+     0x53, 0x00, 0x40, 0x06, 0x63, 0xf2, 0x1d, 0x99,
+     0x3b, 0x9b, 0x27, 0x64, 0x46, 0xfd, 0x20, 0xc1,
+ };
+ #define IV "blowfish"
+ static void test_blowfish(AVBlowfish *ctx, uint8_t *dst, const uint8_t *src,
+                           const uint8_t *ref, int len, uint8_t *iv, int dir,
+                           const char *test)
+ {
+     av_blowfish_crypt(ctx, dst, src, len, iv, dir);
+     if (memcmp(dst, ref, 8*len)) {
+         int i;
+         printf("%s failed\ngot      ", test);
+         for (i = 0; i < 8*len; i++)
+             printf("%02x ", dst[i]);
+         printf("\nexpected ");
+         for (i = 0; i < 8*len; i++)
+             printf("%02x ", ref[i]);
+         printf("\n");
+         exit(1);
+     }
+ }
+ int main(void)
+ {
+     AVBlowfish ctx;
+     uint32_t tmptext_l[NUM_VARIABLE_KEY_TESTS];
+     uint32_t tmptext_r[NUM_VARIABLE_KEY_TESTS];
+     uint8_t tmp[16], iv[8];
+     int i;
+     av_blowfish_init(&ctx, "abcdefghijklmnopqrstuvwxyz", 26);
+     test_blowfish(&ctx, tmp, plaintext, ciphertext, 1, NULL, 0, "encryption");
+     test_blowfish(&ctx, tmp, ciphertext, plaintext, 1, NULL, 1, "decryption");
+     test_blowfish(&ctx, tmp, tmp, ciphertext, 1, NULL, 0, "Inplace encryption");
+     test_blowfish(&ctx, tmp, tmp, plaintext,  1, NULL, 1, "Inplace decryption");
+     memcpy(iv, IV, 8);
+     test_blowfish(&ctx, tmp, plaintext2, ciphertext2, 2, iv, 0, "CBC encryption");
+     memcpy(iv, IV, 8);
+     test_blowfish(&ctx, tmp, ciphertext2, plaintext2, 2, iv, 1, "CBC decryption");
+     memcpy(iv, IV, 8);
+     test_blowfish(&ctx, tmp, tmp, ciphertext2, 2, iv, 0, "Inplace CBC encryption");
+     memcpy(iv, IV, 8);
+     test_blowfish(&ctx, tmp, tmp, plaintext2,  2, iv, 1, "Inplace CBC decryption");
+     memcpy(tmptext_l, plaintext_l, sizeof(*plaintext_l) * NUM_VARIABLE_KEY_TESTS);
+     memcpy(tmptext_r, plaintext_r, sizeof(*plaintext_r) * NUM_VARIABLE_KEY_TESTS);
+     for (i = 0; i < NUM_VARIABLE_KEY_TESTS; i++) {
+         av_blowfish_init(&ctx, variable_key[i], 8);
+         av_blowfish_crypt_ecb(&ctx, &tmptext_l[i], &tmptext_r[i], 0);
+         if (tmptext_l[i] != ciphertext_l[i] || tmptext_r[i] != ciphertext_r[i]) {
+             printf("Test encryption failed.\n");
+             return 1;
+         }
+         av_blowfish_crypt_ecb(&ctx, &tmptext_l[i], &tmptext_r[i], 1);
+         if (tmptext_l[i] != plaintext_l[i] || tmptext_r[i] != plaintext_r[i]) {
+             printf("Test decryption failed.\n");
+             return 1;
+         }
+     }
+     printf("Test encryption/decryption success.\n");
+     return 0;
+ }
Simple merge
index 0000000,0000000..f081c44
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,93 @@@
++/*
++ * Copyright (c) 2012 Nicolas George
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "bprint.c"
++
++#undef printf
++
++static void bprint_pascal(AVBPrint *b, unsigned size)
++{
++    unsigned i, j;
++    unsigned p[42];
++
++    av_assert0(size < FF_ARRAY_ELEMS(p));
++
++    p[0] = 1;
++    av_bprintf(b, "%8d\n", 1);
++    for (i = 1; i <= size; i++) {
++        p[i] = 1;
++        for (j = i - 1; j > 0; j--)
++            p[j] = p[j] + p[j - 1];
++        for (j = 0; j <= i; j++)
++            av_bprintf(b, "%8d", p[j]);
++        av_bprintf(b, "\n");
++    }
++}
++
++int main(void)
++{
++    AVBPrint b;
++    char buf[256];
++    struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 };
++
++    av_bprint_init(&b, 0, -1);
++    bprint_pascal(&b, 5);
++    printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
++    printf("%s\n", b.str);
++    av_bprint_finalize(&b, NULL);
++
++    av_bprint_init(&b, 0, -1);
++    bprint_pascal(&b, 25);
++    printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
++    av_bprint_finalize(&b, NULL);
++
++    av_bprint_init(&b, 0, 2048);
++    bprint_pascal(&b, 25);
++    printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
++    av_bprint_finalize(&b, NULL);
++
++    av_bprint_init(&b, 0, 1);
++    bprint_pascal(&b, 5);
++    printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
++
++    av_bprint_init(&b, 0, 1);
++    bprint_pascal(&b, 25);
++    printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len);
++    /* Note that the size of the automatic buffer is arch-dependent. */
++
++    av_bprint_init(&b, 0, 0);
++    bprint_pascal(&b, 25);
++    printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
++
++    av_bprint_init_for_buffer(&b, buf, sizeof(buf));
++    bprint_pascal(&b, 25);
++    printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len);
++
++    av_bprint_init(&b, 0, -1);
++    av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
++    printf("strftime full: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
++    av_bprint_finalize(&b, NULL);
++
++    av_bprint_init(&b, 0, 8);
++    av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
++    printf("strftime truncated: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
++
++    return 0;
++}
index 7ef84d4,0000000..2f059c5
mode 100644,000000..100644
--- /dev/null
@@@ -1,381 -1,0 +1,305 @@@
- #ifdef TEST
- #undef printf
- static void bprint_pascal(AVBPrint *b, unsigned size)
- {
-     unsigned i, j;
-     unsigned p[42];
-     av_assert0(size < FF_ARRAY_ELEMS(p));
-     p[0] = 1;
-     av_bprintf(b, "%8d\n", 1);
-     for (i = 1; i <= size; i++) {
-         p[i] = 1;
-         for (j = i - 1; j > 0; j--)
-             p[j] = p[j] + p[j - 1];
-         for (j = 0; j <= i; j++)
-             av_bprintf(b, "%8d", p[j]);
-         av_bprintf(b, "\n");
-     }
- }
- int main(void)
- {
-     AVBPrint b;
-     char buf[256];
-     struct tm testtime = { .tm_year = 100, .tm_mon = 11, .tm_mday = 20 };
-     av_bprint_init(&b, 0, -1);
-     bprint_pascal(&b, 5);
-     printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
-     printf("%s\n", b.str);
-     av_bprint_finalize(&b, NULL);
-     av_bprint_init(&b, 0, -1);
-     bprint_pascal(&b, 25);
-     printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
-     av_bprint_finalize(&b, NULL);
-     av_bprint_init(&b, 0, 2048);
-     bprint_pascal(&b, 25);
-     printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
-     av_bprint_finalize(&b, NULL);
-     av_bprint_init(&b, 0, 1);
-     bprint_pascal(&b, 5);
-     printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
-     av_bprint_init(&b, 0, 1);
-     bprint_pascal(&b, 25);
-     printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len);
-     /* Note that the size of the automatic buffer is arch-dependent. */
-     av_bprint_init(&b, 0, 0);
-     bprint_pascal(&b, 25);
-     printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
-     av_bprint_init_for_buffer(&b, buf, sizeof(buf));
-     bprint_pascal(&b, 25);
-     printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len);
-     av_bprint_init(&b, 0, -1);
-     av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
-     printf("strftime full: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
-     av_bprint_finalize(&b, NULL);
-     av_bprint_init(&b, 0, 8);
-     av_bprint_strftime(&b, "%Y-%m-%d", &testtime);
-     printf("strftime truncated: %u/%u \"%s\"\n", (unsigned)strlen(buf), b.len, b.str);
-     return 0;
- }
- #endif
 +/*
 + * Copyright (c) 2012 Nicolas George
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include <stdarg.h>
 +#include <stdio.h>
 +#include <string.h>
 +#include <time.h>
 +#include "avassert.h"
 +#include "avstring.h"
 +#include "bprint.h"
 +#include "common.h"
 +#include "compat/va_copy.h"
 +#include "error.h"
 +#include "mem.h"
 +
 +#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size))
 +#define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer)
 +
 +static int av_bprint_alloc(AVBPrint *buf, unsigned room)
 +{
 +    char *old_str, *new_str;
 +    unsigned min_size, new_size;
 +
 +    if (buf->size == buf->size_max)
 +        return AVERROR(EIO);
 +    if (!av_bprint_is_complete(buf))
 +        return AVERROR_INVALIDDATA; /* it is already truncated anyway */
 +    min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room);
 +    new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2;
 +    if (new_size < min_size)
 +        new_size = FFMIN(buf->size_max, min_size);
 +    old_str = av_bprint_is_allocated(buf) ? buf->str : NULL;
 +    new_str = av_realloc(old_str, new_size);
 +    if (!new_str)
 +        return AVERROR(ENOMEM);
 +    if (!old_str)
 +        memcpy(new_str, buf->str, buf->len + 1);
 +    buf->str  = new_str;
 +    buf->size = new_size;
 +    return 0;
 +}
 +
 +static void av_bprint_grow(AVBPrint *buf, unsigned extra_len)
 +{
 +    /* arbitrary margin to avoid small overflows */
 +    extra_len = FFMIN(extra_len, UINT_MAX - 5 - buf->len);
 +    buf->len += extra_len;
 +    if (buf->size)
 +        buf->str[FFMIN(buf->len, buf->size - 1)] = 0;
 +}
 +
 +void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
 +{
 +    unsigned size_auto = (char *)buf + sizeof(*buf) -
 +                         buf->reserved_internal_buffer;
 +
 +    if (size_max == 1)
 +        size_max = size_auto;
 +    buf->str      = buf->reserved_internal_buffer;
 +    buf->len      = 0;
 +    buf->size     = FFMIN(size_auto, size_max);
 +    buf->size_max = size_max;
 +    *buf->str = 0;
 +    if (size_init > buf->size)
 +        av_bprint_alloc(buf, size_init - 1);
 +}
 +
 +void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
 +{
 +    buf->str      = buffer;
 +    buf->len      = 0;
 +    buf->size     = size;
 +    buf->size_max = size;
 +    *buf->str = 0;
 +}
 +
 +void av_bprintf(AVBPrint *buf, const char *fmt, ...)
 +{
 +    unsigned room;
 +    char *dst;
 +    va_list vl;
 +    int extra_len;
 +
 +    while (1) {
 +        room = av_bprint_room(buf);
 +        dst = room ? buf->str + buf->len : NULL;
 +        va_start(vl, fmt);
 +        extra_len = vsnprintf(dst, room, fmt, vl);
 +        va_end(vl);
 +        if (extra_len <= 0)
 +            return;
 +        if (extra_len < room)
 +            break;
 +        if (av_bprint_alloc(buf, extra_len))
 +            break;
 +    }
 +    av_bprint_grow(buf, extra_len);
 +}
 +
 +void av_vbprintf(AVBPrint *buf, const char *fmt, va_list vl_arg)
 +{
 +    unsigned room;
 +    char *dst;
 +    int extra_len;
 +    va_list vl;
 +
 +    while (1) {
 +        room = av_bprint_room(buf);
 +        dst = room ? buf->str + buf->len : NULL;
 +        va_copy(vl, vl_arg);
 +        extra_len = vsnprintf(dst, room, fmt, vl);
 +        va_end(vl);
 +        if (extra_len <= 0)
 +            return;
 +        if (extra_len < room)
 +            break;
 +        if (av_bprint_alloc(buf, extra_len))
 +            break;
 +    }
 +    av_bprint_grow(buf, extra_len);
 +}
 +
 +void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
 +{
 +    unsigned room, real_n;
 +
 +    while (1) {
 +        room = av_bprint_room(buf);
 +        if (n < room)
 +            break;
 +        if (av_bprint_alloc(buf, n))
 +            break;
 +    }
 +    if (room) {
 +        real_n = FFMIN(n, room - 1);
 +        memset(buf->str + buf->len, c, real_n);
 +    }
 +    av_bprint_grow(buf, n);
 +}
 +
 +void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
 +{
 +    unsigned room, real_n;
 +
 +    while (1) {
 +        room = av_bprint_room(buf);
 +        if (size < room)
 +            break;
 +        if (av_bprint_alloc(buf, size))
 +            break;
 +    }
 +    if (room) {
 +        real_n = FFMIN(size, room - 1);
 +        memcpy(buf->str + buf->len, data, real_n);
 +    }
 +    av_bprint_grow(buf, size);
 +}
 +
 +void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm)
 +{
 +    unsigned room;
 +    size_t l;
 +
 +    if (!*fmt)
 +        return;
 +    while (1) {
 +        room = av_bprint_room(buf);
 +        if (room && (l = strftime(buf->str + buf->len, room, fmt, tm)))
 +            break;
 +        /* strftime does not tell us how much room it would need: let us
 +           retry with twice as much until the buffer is large enough */
 +        room = !room ? strlen(fmt) + 1 :
 +               room <= INT_MAX / 2 ? room * 2 : INT_MAX;
 +        if (av_bprint_alloc(buf, room)) {
 +            /* impossible to grow, try to manage something useful anyway */
 +            room = av_bprint_room(buf);
 +            if (room < 1024) {
 +                /* if strftime fails because the buffer has (almost) reached
 +                   its maximum size, let us try in a local buffer; 1k should
 +                   be enough to format any real date+time string */
 +                char buf2[1024];
 +                if ((l = strftime(buf2, sizeof(buf2), fmt, tm))) {
 +                    av_bprintf(buf, "%s", buf2);
 +                    return;
 +                }
 +            }
 +            if (room) {
 +                /* if anything else failed and the buffer is not already
 +                   truncated, let us add a stock string and force truncation */
 +                static const char txt[] = "[truncated strftime output]";
 +                memset(buf->str + buf->len, '!', room);
 +                memcpy(buf->str + buf->len, txt, FFMIN(sizeof(txt) - 1, room));
 +                av_bprint_grow(buf, room); /* force truncation */
 +            }
 +            return;
 +        }
 +    }
 +    av_bprint_grow(buf, l);
 +}
 +
 +void av_bprint_get_buffer(AVBPrint *buf, unsigned size,
 +                          unsigned char **mem, unsigned *actual_size)
 +{
 +    if (size > av_bprint_room(buf))
 +        av_bprint_alloc(buf, size);
 +    *actual_size = av_bprint_room(buf);
 +    *mem = *actual_size ? buf->str + buf->len : NULL;
 +}
 +
 +void av_bprint_clear(AVBPrint *buf)
 +{
 +    if (buf->len) {
 +        *buf->str = 0;
 +        buf->len  = 0;
 +    }
 +}
 +
 +int av_bprint_finalize(AVBPrint *buf, char **ret_str)
 +{
 +    unsigned real_size = FFMIN(buf->len + 1, buf->size);
 +    char *str;
 +    int ret = 0;
 +
 +    if (ret_str) {
 +        if (av_bprint_is_allocated(buf)) {
 +            str = av_realloc(buf->str, real_size);
 +            if (!str)
 +                str = buf->str;
 +            buf->str = NULL;
 +        } else {
 +            str = av_malloc(real_size);
 +            if (str)
 +                memcpy(str, buf->str, real_size);
 +            else
 +                ret = AVERROR(ENOMEM);
 +        }
 +        *ret_str = str;
 +    } else {
 +        if (av_bprint_is_allocated(buf))
 +            av_freep(&buf->str);
 +    }
 +    buf->size = real_size;
 +    return ret;
 +}
 +
 +#define WHITESPACES " \n\t\r"
 +
 +void av_bprint_escape(AVBPrint *dstbuf, const char *src, const char *special_chars,
 +                      enum AVEscapeMode mode, int flags)
 +{
 +    const char *src0 = src;
 +
 +    if (mode == AV_ESCAPE_MODE_AUTO)
 +        mode = AV_ESCAPE_MODE_BACKSLASH; /* TODO: implement a heuristic */
 +
 +    switch (mode) {
 +    case AV_ESCAPE_MODE_QUOTE:
 +        /* enclose the string between '' */
 +        av_bprint_chars(dstbuf, '\'', 1);
 +        for (; *src; src++) {
 +            if (*src == '\'')
 +                av_bprintf(dstbuf, "'\\''");
 +            else
 +                av_bprint_chars(dstbuf, *src, 1);
 +        }
 +        av_bprint_chars(dstbuf, '\'', 1);
 +        break;
 +
 +    /* case AV_ESCAPE_MODE_BACKSLASH or unknown mode */
 +    default:
 +        /* \-escape characters */
 +        for (; *src; src++) {
 +            int is_first_last       = src == src0 || !*(src+1);
 +            int is_ws               = !!strchr(WHITESPACES, *src);
 +            int is_strictly_special = special_chars && strchr(special_chars, *src);
 +            int is_special          =
 +                is_strictly_special || strchr("'\\", *src) ||
 +                (is_ws && (flags & AV_ESCAPE_FLAG_WHITESPACE));
 +
 +            if (is_strictly_special ||
 +                (!(flags & AV_ESCAPE_FLAG_STRICT) &&
 +                 (is_special || (is_ws && is_first_last))))
 +                av_bprint_chars(dstbuf, '\\', 1);
 +            av_bprint_chars(dstbuf, *src, 1);
 +        }
 +        break;
 +    }
 +}
index 0000000,0000000..ad90587
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,78 @@@
++/*
++ * An implementation of the CAMELLIA algorithm as mentioned in RFC3713
++ * Copyright (c) 2014 Supraja Meedinti
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "camellia.c"
++#include "log.h"
++
++#include <stdio.h>
++#include <stdlib.h>
++
++int main(int argc, char *argv[])
++{
++    const uint8_t Key[3][32] = {
++        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
++        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77},
++        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
++    };
++    const uint8_t rct[3][16] = {
++        {0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43},
++        {0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9,0x96, 0xf8, 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9},
++        {0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09}
++    };
++    const uint8_t rpt[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
++    const int kbits[3] = {128, 192, 256};
++    int i, j, err = 0;
++    uint8_t temp[32], iv[16];
++    AVCAMELLIA *cs;
++    cs = av_camellia_alloc();
++    if (!cs)
++        return 1;
++    for (j = 0; j < 3; j++) {
++        av_camellia_init(cs, Key[j], kbits[j]);
++        av_camellia_crypt(cs, temp, rpt, 1, NULL, 0);
++        for (i = 0; i < 16; i++) {
++            if (rct[j][i] != temp[i]) {
++                av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]);
++                err = 1;
++            }
++        }
++        av_camellia_crypt(cs, temp, rct[j], 1, NULL, 1);
++        for (i = 0; i < 16; i++) {
++            if (rpt[i] != temp[i]) {
++                av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
++                err = 1;
++            }
++        }
++    }
++    av_camellia_init(cs, Key[0], 128);
++    memcpy(iv, "HALLO123HALLO123", 16);
++    av_camellia_crypt(cs, temp, rpt, 2, iv, 0);
++    memcpy(iv, "HALLO123HALLO123", 16);
++    av_camellia_crypt(cs, temp, temp, 2, iv, 1);
++    for (i = 0; i < 32; i++) {
++        if (rpt[i] != temp[i]) {
++            av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
++            err = 1;
++        }
++    }
++    av_free(cs);
++    return err;
++}
index f21ca12,0000000..f33ee9b
mode 100644,000000..100644
--- /dev/null
@@@ -1,470 -1,0 +1,412 @@@
- #ifdef TEST
- #include<stdio.h>
- #include<stdlib.h>
- #include"log.h"
- int main(int argc, char *argv[])
- {
-     const uint8_t Key[3][32] = {
-         {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
-         {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77},
-         {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
-     };
-     const uint8_t rct[3][16] = {
-         {0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43},
-         {0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9,0x96, 0xf8, 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9},
-         {0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09}
-     };
-     const uint8_t rpt[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
-     const int kbits[3] = {128, 192, 256};
-     int i, j, err = 0;
-     uint8_t temp[32], iv[16];
-     AVCAMELLIA *cs;
-     cs = av_camellia_alloc();
-     if (!cs)
-         return 1;
-     for (j = 0; j < 3; j++) {
-         av_camellia_init(cs, Key[j], kbits[j]);
-         av_camellia_crypt(cs, temp, rpt, 1, NULL, 0);
-         for (i = 0; i < 16; i++) {
-             if (rct[j][i] != temp[i]) {
-                 av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]);
-                 err = 1;
-             }
-         }
-         av_camellia_crypt(cs, temp, rct[j], 1, NULL, 1);
-         for (i = 0; i < 16; i++) {
-             if (rpt[i] != temp[i]) {
-                 av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
-                 err = 1;
-             }
-         }
-     }
-     av_camellia_init(cs, Key[0], 128);
-     memcpy(iv, "HALLO123HALLO123", 16);
-     av_camellia_crypt(cs, temp, rpt, 2, iv, 0);
-     memcpy(iv, "HALLO123HALLO123", 16);
-     av_camellia_crypt(cs, temp, temp, 2, iv, 1);
-     for (i = 0; i < 32; i++) {
-         if (rpt[i] != temp[i]) {
-             av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
-             err = 1;
-         }
-     }
-     av_free(cs);
-     return err;
- }
- #endif
 +/*
 + * An implementation of the CAMELLIA algorithm as mentioned in RFC3713
 + * Copyright (c) 2014 Supraja Meedinti
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +#include "camellia.h"
 +#include "common.h"
 +#include "intreadwrite.h"
 +#include "attributes.h"
 +
 +#define LR32(x,c) ((x) << (c) | (x) >> (32 - (c)))
 +#define RR32(x,c) ((x) >> (c) | (x) << (32 - (c)))
 +
 +#define MASK8 0xff
 +#define MASK32 0xffffffff
 +#define MASK64 0xffffffffffffffff
 +
 +#define Sigma1  0xA09E667F3BCC908B
 +#define Sigma2  0xB67AE8584CAA73B2
 +#define Sigma3  0xC6EF372FE94F82BE
 +#define Sigma4  0x54FF53A5F1D36F1C
 +#define Sigma5  0x10E527FADE682D1D
 +#define Sigma6  0xB05688C2B3E6C1FD
 +
 +static uint64_t SP[8][256];
 +
 +typedef struct AVCAMELLIA {
 +    uint64_t Kw[4];
 +    uint64_t Ke[6];
 +    uint64_t K[24];
 +    int key_bits;
 +} AVCAMELLIA;
 +
 +static const uint8_t SBOX1[256] = {
 +112, 130,  44, 236, 179,  39, 192, 229, 228, 133,  87,  53, 234,  12, 174,  65,
 + 35, 239, 107, 147,  69,  25, 165,  33, 237,  14,  79,  78,  29, 101, 146, 189,
 +134, 184, 175, 143, 124, 235,  31, 206,  62,  48, 220,  95,  94, 197,  11,  26,
 +166, 225,  57, 202, 213,  71,  93,  61, 217,   1,  90, 214,  81,  86, 108,  77,
 +139,  13, 154, 102, 251, 204, 176,  45, 116,  18,  43,  32, 240, 177, 132, 153,
 +223,  76, 203, 194,  52, 126, 118,   5, 109, 183, 169,  49, 209,  23,   4, 215,
 + 20,  88,  58,  97, 222,  27,  17,  28,  50,  15, 156,  22,  83,  24, 242,  34,
 +254,  68, 207, 178, 195, 181, 122, 145,  36,   8, 232, 168,  96, 252, 105,  80,
 +170, 208, 160, 125, 161, 137,  98, 151,  84,  91,  30, 149, 224, 255, 100, 210,
 + 16, 196,   0,  72, 163, 247, 117, 219, 138,   3, 230, 218,   9,  63, 221, 148,
 +135,  92, 131,   2, 205,  74, 144,  51, 115, 103, 246, 243, 157, 127, 191, 226,
 + 82, 155, 216,  38, 200,  55, 198,  59, 129, 150, 111,  75,  19, 190,  99,  46,
 +233, 121, 167, 140, 159, 110, 188, 142,  41, 245, 249, 182,  47, 253, 180,  89,
 +120, 152,   6, 106, 231,  70, 113, 186, 212,  37, 171,  66, 136, 162, 141, 250,
 +114,   7, 185,  85, 248, 238, 172,  10,  54,  73,  42, 104,  60,  56, 241, 164,
 + 64,  40, 211, 123, 187, 201,  67, 193,  21, 227, 173, 244, 119, 199, 128, 158
 +};
 +
 +static const uint8_t SBOX2[256] = {
 +224,   5,  88, 217, 103,  78, 129, 203, 201,  11, 174, 106, 213,  24,  93, 130,
 + 70, 223, 214,  39, 138,  50,  75,  66, 219,  28, 158, 156,  58, 202,  37, 123,
 + 13, 113,  95,  31, 248, 215,  62, 157, 124,  96, 185, 190, 188, 139,  22,  52,
 + 77, 195, 114, 149, 171, 142, 186, 122, 179,   2, 180, 173, 162, 172, 216, 154,
 + 23,  26,  53, 204, 247, 153,  97,  90, 232,  36,  86,  64, 225,  99,   9,  51,
 +191, 152, 151, 133, 104, 252, 236,  10, 218, 111,  83,  98, 163,  46,   8, 175,
 + 40, 176, 116, 194, 189,  54,  34,  56, 100,  30,  57,  44, 166,  48, 229,  68,
 +253, 136, 159, 101, 135, 107, 244,  35,  72,  16, 209,  81, 192, 249, 210, 160,
 + 85, 161,  65, 250,  67,  19, 196,  47, 168, 182,  60,  43, 193, 255, 200, 165,
 + 32, 137,   0, 144,  71, 239, 234, 183,  21,   6, 205, 181,  18, 126, 187,  41,
 + 15, 184,   7,   4, 155, 148,  33, 102, 230, 206, 237, 231,  59, 254, 127, 197,
 +164,  55, 177,  76, 145, 110, 141, 118,   3,  45, 222, 150,  38, 125, 198,  92,
 +211, 242,  79,  25,  63, 220, 121,  29,  82, 235, 243, 109,  94, 251, 105, 178,
 +240,  49,  12, 212, 207, 140, 226, 117, 169,  74,  87, 132,  17,  69,  27, 245,
 +228,  14, 115, 170, 241, 221,  89,  20, 108, 146,  84, 208, 120, 112, 227,  73,
 +128,  80, 167, 246, 119, 147, 134, 131,  42, 199,  91, 233, 238, 143,   1,  61
 +};
 +
 +static const uint8_t SBOX3[256] = {
 + 56,  65,  22, 118, 217, 147,  96, 242, 114, 194, 171, 154, 117,   6,  87, 160,
 +145, 247, 181, 201, 162, 140, 210, 144, 246,   7, 167,  39, 142, 178,  73, 222,
 + 67,  92, 215, 199,  62, 245, 143, 103,  31,  24, 110, 175,  47, 226, 133,  13,
 + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128,  45, 107, 168,  43,  54, 166,
 +197, 134,  77,  51, 253, 102,  88, 150,  58,   9, 149,  16, 120, 216,  66, 204,
 +239,  38, 229,  97,  26,  63,  59, 130, 182, 219, 212, 152, 232, 139,   2, 235,
 + 10,  44,  29, 176, 111, 141, 136,  14,  25, 135,  78,  11, 169,  12, 121,  17,
 +127,  34, 231,  89, 225, 218,  61, 200,  18,   4, 116,  84,  48, 126, 180,  40,
 + 85, 104,  80, 190, 208, 196,  49, 203,  42, 173,  15, 202, 112, 255,  50, 105,
 +  8,  98,   0,  36, 209, 251, 186, 237,  69, 129, 115, 109, 132, 159, 238,  74,
 +195,  46, 193,   1, 230,  37,  72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
 + 41, 205, 108,  19, 100, 155,  99, 157, 192,  75, 183, 165, 137,  95, 177,  23,
 +244, 188, 211,  70, 207,  55,  94,  71, 148, 250, 252,  91, 151, 254,  90, 172,
 + 60,  76,   3,  53, 243,  35, 184,  93, 106, 146, 213,  33,  68,  81, 198, 125,
 + 57, 131, 220, 170, 124, 119,  86,   5,  27, 164,  21,  52,  30,  28, 248,  82,
 + 32,  20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227,  64,  79
 +};
 +
 +static const uint8_t SBOX4[256] = {
 +112,  44, 179, 192, 228,  87, 234, 174,  35, 107,  69, 165, 237,  79,  29, 146,
 +134, 175, 124,  31,  62, 220,  94,  11, 166,  57, 213,  93, 217,  90,  81, 108,
 +139, 154, 251, 176, 116,  43, 240, 132, 223, 203,  52, 118, 109, 169, 209,   4,
 + 20,  58, 222,  17,  50, 156,  83, 242, 254, 207, 195, 122,  36, 232,  96, 105,
 +170, 160, 161,  98,  84,  30, 224, 100,  16,   0, 163, 117, 138, 230,   9, 221,
 +135, 131, 205, 144, 115, 246, 157, 191,  82, 216, 200, 198, 129, 111,  19,  99,
 +233, 167, 159, 188,  41, 249,  47, 180, 120,   6, 231, 113, 212, 171, 136, 141,
 +114, 185, 248, 172,  54,  42,  60, 241,  64, 211, 187,  67,  21, 173, 119, 128,
 +130, 236,  39, 229, 133,  53,  12,  65, 239, 147,  25,  33,  14,  78, 101, 189,
 +184, 143, 235, 206,  48,  95, 197,  26, 225, 202,  71,  61,   1, 214,  86,  77,
 + 13, 102, 204,  45,  18,  32, 177, 153,  76, 194, 126,   5, 183,  49,  23, 215,
 + 88,  97,  27,  28,  15,  22,  24,  34,  68, 178, 181, 145,   8, 168, 252,  80,
 +208, 125, 137, 151,  91, 149, 255, 210, 196,  72, 247, 219,   3, 218,  63, 148,
 + 92,   2,  74,  51, 103, 243, 127, 226, 155,  38,  55,  59, 150,  75, 190,  46,
 +121, 140, 110, 142, 245, 182, 253,  89, 152, 106,  70, 186,  37,  66, 162, 250,
 +  7,  85, 238,  10,  73, 104,  56, 164,  40, 123, 201, 193, 227, 244, 199, 158
 +};
 +
 +const int av_camellia_size = sizeof(AVCAMELLIA);
 +
 +static void LR128(uint64_t d[2], const uint64_t K[2], int x)
 +{
 +    int i = 0;
 +    if (64 <= x && x < 128) {
 +        i = 1;
 +        x -= 64;
 +    }
 +    if (x <= 0 || x >= 128) {
 +        d[0] = K[i];
 +        d[1] = K[!i];
 +        return;
 +    }
 +    d[0] = (K[i] << x | K[!i] >> (64 - x));
 +    d[1] = (K[!i] << x | K[i] >> (64 - x));
 +}
 +
 +static uint64_t F(uint64_t F_IN, uint64_t KE)
 +{
 +    KE ^= F_IN;
 +    F_IN=SP[0][KE >> 56]^SP[1][(KE >> 48) & MASK8]^SP[2][(KE >> 40) & MASK8]^SP[3][(KE >> 32) & MASK8]^SP[4][(KE >> 24) & MASK8]^SP[5][(KE >> 16) & MASK8]^SP[6][(KE >> 8) & MASK8]^SP[7][KE & MASK8];
 +    return F_IN;
 +}
 +
 +static uint64_t FL(uint64_t FL_IN, uint64_t KE)
 +{
 +    uint32_t x1, x2, k1, k2;
 +    x1 = FL_IN >> 32;
 +    x2 = FL_IN & MASK32;
 +    k1 = KE >> 32;
 +    k2 = KE & MASK32;
 +    x2 = x2 ^ LR32((x1 & k1), 1);
 +    x1 = x1 ^ (x2 | k2);
 +    return ((uint64_t)x1 << 32) | (uint64_t)x2;
 +}
 +
 +static uint64_t FLINV(uint64_t FLINV_IN, uint64_t KE)
 +{
 +    uint32_t x1, x2, k1, k2;
 +    x1 = FLINV_IN >> 32;
 +    x2 = FLINV_IN & MASK32;
 +    k1 = KE >> 32;
 +    k2 = KE & MASK32;
 +    x1 = x1 ^ (x2 | k2);
 +    x2 = x2 ^ LR32((x1 & k1), 1);
 +    return ((uint64_t)x1 << 32) | (uint64_t)x2;
 +}
 +
 +static const uint8_t shifts[2][12] = {
 +    {0, 15, 15, 45, 45, 60, 94, 94, 111},
 +    {0, 15, 15, 30, 45, 45, 60, 60,  77, 94, 94, 111}
 +};
 +
 +static const uint8_t vars[2][12] = {
 +    {2, 0, 2, 0, 2, 2, 0, 2, 0},
 +    {3, 1, 2, 3, 0, 2, 1, 3, 0, 1, 2, 0}
 +};
 +
 +static void generate_round_keys(AVCAMELLIA *cs, uint64_t Kl[2], uint64_t Kr[2], uint64_t Ka[2], uint64_t Kb[2])
 +{
 +    int i;
 +    uint64_t *Kd[4], d[2];
 +    Kd[0] = Kl;
 +    Kd[1] = Kr;
 +    Kd[2] = Ka;
 +    Kd[3] = Kb;
 +    cs->Kw[0] = Kl[0];
 +    cs->Kw[1] = Kl[1];
 +    if (cs->key_bits == 128) {
 +        for (i = 0; i < 9; i++) {
 +            LR128(d, Kd[vars[0][i]], shifts[0][i]);
 +            cs->K[2*i] = d[0];
 +            cs->K[2*i+1] = d[1];
 +        }
 +        LR128(d, Kd[0], 60);
 +        cs->K[9] = d[1];
 +        LR128(d, Kd[2], 30);
 +        cs->Ke[0] = d[0];
 +        cs->Ke[1] = d[1];
 +        LR128(d, Kd[0], 77);
 +        cs->Ke[2] = d[0];
 +        cs->Ke[3] = d[1];
 +        LR128(d, Kd[2], 111);
 +        cs->Kw[2] = d[0];
 +        cs->Kw[3] = d[1];
 +    } else {
 +        for (i = 0; i < 12; i++) {
 +            LR128(d, Kd[vars[1][i]], shifts[1][i]);
 +            cs->K[2*i] = d[0];
 +            cs->K[2*i+1] = d[1];
 +        }
 +        LR128(d, Kd[1], 30);
 +        cs->Ke[0] = d[0];
 +        cs->Ke[1] = d[1];
 +        LR128(d, Kd[0], 60);
 +        cs->Ke[2] = d[0];
 +        cs->Ke[3] = d[1];
 +        LR128(d, Kd[2], 77);
 +        cs->Ke[4] = d[0];
 +        cs->Ke[5] = d[1];
 +        LR128(d, Kd[3], 111);
 +        cs->Kw[2] = d[0];
 +        cs->Kw[3] = d[1];
 +    }
 +}
 +
 +static void camellia_encrypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src)
 +{
 +    uint64_t D1, D2;
 +    D1 = AV_RB64(src);
 +    D2 = AV_RB64(src + 8);
 +    D1 ^= cs->Kw[0];
 +    D2 ^= cs->Kw[1];
 +    D2 ^= F(D1, cs->K[0]);
 +    D1 ^= F(D2, cs->K[1]);
 +    D2 ^= F(D1, cs->K[2]);
 +    D1 ^= F(D2, cs->K[3]);
 +    D2 ^= F(D1, cs->K[4]);
 +    D1 ^= F(D2, cs->K[5]);
 +    D1 = FL(D1, cs->Ke[0]);
 +    D2 = FLINV(D2, cs->Ke[1]);
 +    D2 ^= F(D1, cs->K[6]);
 +    D1 ^= F(D2, cs->K[7]);
 +    D2 ^= F(D1, cs->K[8]);
 +    D1 ^= F(D2, cs->K[9]);
 +    D2 ^= F(D1, cs->K[10]);
 +    D1 ^= F(D2, cs->K[11]);
 +    D1 = FL(D1, cs->Ke[2]);
 +    D2 = FLINV(D2, cs->Ke[3]);
 +    D2 ^= F(D1, cs->K[12]);
 +    D1 ^= F(D2, cs->K[13]);
 +    D2 ^= F(D1, cs->K[14]);
 +    D1 ^= F(D2, cs->K[15]);
 +    D2 ^= F(D1, cs->K[16]);
 +    D1 ^= F(D2, cs->K[17]);
 +    if (cs->key_bits != 128) {
 +        D1 = FL(D1, cs->Ke[4]);
 +        D2 = FLINV(D2, cs->Ke[5]);
 +        D2 ^= F(D1, cs->K[18]);
 +        D1 ^= F(D2, cs->K[19]);
 +        D2 ^= F(D1, cs->K[20]);
 +        D1 ^= F(D2, cs->K[21]);
 +        D2 ^= F(D1, cs->K[22]);
 +        D1 ^= F(D2, cs->K[23]);
 +    }
 +    D2 ^= cs->Kw[2];
 +    D1 ^= cs->Kw[3];
 +    AV_WB64(dst, D2);
 +    AV_WB64(dst + 8, D1);
 +}
 +
 +static void camellia_decrypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src, uint8_t *iv)
 +{
 +    uint64_t D1, D2;
 +    D1 = AV_RB64(src);
 +    D2 = AV_RB64(src + 8);
 +    D1 ^= cs->Kw[2];
 +    D2 ^= cs->Kw[3];
 +    if (cs->key_bits != 128) {
 +        D2 ^= F(D1, cs->K[23]);
 +        D1 ^= F(D2, cs->K[22]);
 +        D2 ^= F(D1, cs->K[21]);
 +        D1 ^= F(D2, cs->K[20]);
 +        D2 ^= F(D1, cs->K[19]);
 +        D1 ^= F(D2, cs->K[18]);
 +        D1 = FL(D1, cs->Ke[5]);
 +        D2 = FLINV(D2, cs->Ke[4]);
 +    }
 +    D2 ^= F(D1, cs->K[17]);
 +    D1 ^= F(D2, cs->K[16]);
 +    D2 ^= F(D1, cs->K[15]);
 +    D1 ^= F(D2, cs->K[14]);
 +    D2 ^= F(D1, cs->K[13]);
 +    D1 ^= F(D2, cs->K[12]);
 +    D1 = FL(D1, cs->Ke[3]);
 +    D2 = FLINV(D2, cs->Ke[2]);
 +    D2 ^= F(D1, cs->K[11]);
 +    D1 ^= F(D2, cs->K[10]);
 +    D2 ^= F(D1, cs->K[9]);
 +    D1 ^= F(D2, cs->K[8]);
 +    D2 ^= F(D1, cs->K[7]);
 +    D1 ^= F(D2, cs->K[6]);
 +    D1 = FL(D1, cs->Ke[1]);
 +    D2 = FLINV(D2, cs->Ke[0]);
 +    D2 ^= F(D1, cs->K[5]);
 +    D1 ^= F(D2, cs->K[4]);
 +    D2 ^= F(D1, cs->K[3]);
 +    D1 ^= F(D2, cs->K[2]);
 +    D2 ^= F(D1, cs->K[1]);
 +    D1 ^= F(D2, cs->K[0]);
 +    D2 ^= cs->Kw[0];
 +    D1 ^= cs->Kw[1];
 +    if (iv) {
 +        D2 ^= AV_RB64(iv);
 +        D1 ^= AV_RB64(iv + 8);
 +        memcpy(iv, src, 16);
 +    }
 +    AV_WB64(dst, D2);
 +    AV_WB64(dst + 8, D1);
 +}
 +
 +static void computeSP(void)
 +{
 +    uint64_t z;
 +    int i;
 +    for (i = 0; i < 256; i++) {
 +        z = SBOX1[i];
 +        SP[0][i] = (z << 56) ^ (z << 48) ^ (z << 40) ^ (z << 24) ^ z;
 +        SP[7][i] = (z << 56) ^ (z << 48) ^ (z << 40) ^ (z << 24) ^ (z << 16) ^ (z << 8);
 +        z = SBOX2[i];
 +        SP[1][i] = (z << 48) ^ (z << 40) ^ (z << 32) ^ (z << 24) ^ (z << 16);
 +        SP[4][i] = (z << 48) ^ (z << 40) ^ (z << 32) ^ (z << 16) ^ (z << 8) ^ z;
 +        z = SBOX3[i];
 +        SP[2][i] = (z << 56) ^ (z << 40) ^ (z << 32) ^ (z << 16) ^ (z << 8);
 +        SP[5][i] = (z << 56) ^ (z << 40) ^ (z << 32) ^ (z << 24) ^ (z << 8) ^ z;
 +        z = SBOX4[i];
 +        SP[3][i] = (z << 56) ^ (z << 48) ^ (z << 32) ^ (z << 8) ^ z;
 +        SP[6][i] = (z << 56) ^ (z << 48) ^ (z << 32) ^ (z << 24) ^ (z << 16) ^ z;
 +    }
 +}
 +
 +struct AVCAMELLIA *av_camellia_alloc(void)
 +{
 +    return av_mallocz(sizeof(struct AVCAMELLIA));
 +}
 +
 +av_cold int av_camellia_init(AVCAMELLIA *cs, const uint8_t *key, int key_bits)
 +{
 +    uint64_t Kl[2], Kr[2], Ka[2], Kb[2];
 +    uint64_t D1, D2;
 +    if (key_bits != 128 && key_bits != 192 && key_bits != 256)
 +        return AVERROR(EINVAL);
 +    memset(Kb, 0, sizeof(Kb));
 +    memset(Kr, 0, sizeof(Kr));
 +    cs->key_bits = key_bits;
 +    Kl[0] = AV_RB64(key);
 +    Kl[1] = AV_RB64(key + 8);
 +    if (key_bits == 192) {
 +        Kr[0] = AV_RB64(key + 16);
 +        Kr[1] = ~Kr[0];
 +    } else if (key_bits == 256) {
 +        Kr[0] = AV_RB64(key + 16);
 +        Kr[1] = AV_RB64(key + 24);
 +    }
 +    computeSP();
 +    D1 = Kl[0] ^ Kr[0];
 +    D2 = Kl[1] ^ Kr[1];
 +    D2 ^= F(D1, Sigma1);
 +    D1 ^= F(D2, Sigma2);
 +    D1 ^= Kl[0];
 +    D2 ^= Kl[1];
 +    D2 ^= F(D1, Sigma3);
 +    D1 ^= F(D2, Sigma4);
 +    Ka[0] = D1;
 +    Ka[1] = D2;
 +    if (key_bits != 128) {
 +        D1 = Ka[0] ^ Kr[0];
 +        D2 = Ka[1] ^ Kr[1];
 +        D2 ^= F(D1, Sigma5);
 +        D1 ^= F(D2, Sigma6);
 +        Kb[0] = D1;
 +        Kb[1] = D2;
 +    }
 +    generate_round_keys(cs, Kl, Kr, Ka, Kb);
 +    return 0;
 +}
 +
 +void av_camellia_crypt(AVCAMELLIA *cs, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
 +{
 +    int i;
 +    while (count--) {
 +        if (decrypt) {
 +            camellia_decrypt(cs, dst, src, iv);
 +        } else {
 +            if (iv) {
 +                for (i = 0; i < 16; i++)
 +                    dst[i] = src[i] ^ iv[i];
 +                camellia_encrypt(cs, dst, dst);
 +                memcpy(iv, dst, 16);
 +            } else {
 +                camellia_encrypt(cs, dst, src);
 +            }
 +        }
 +        src = src + 16;
 +        dst = dst + 16;
 +    }
 +}
index 0000000,0000000..3776d11
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,106 @@@
++/*
++ * An implementation of the CAST128 algorithm as mentioned in RFC2144
++ * Copyright (c) 2014 Supraja Meedinti
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "cast5.c"
++#include "log.h"
++
++#include <stdio.h>
++#include <stdlib.h>
++
++int main(int argc, char** argv)
++{
++
++    static const uint8_t Key[3][16] = {
++        {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a},
++        {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45},
++        {0x01, 0x23, 0x45, 0x67, 0x12}
++    };
++    static const uint8_t rpt[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
++    static const uint8_t rct[3][8] = {
++        {0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2},
++        {0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b},
++        {0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e}
++    };
++    static const uint8_t rct2[2][16] = {
++        {0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6, 0xb3, 0x43, 0x6f, 0xb8, 0x9d, 0x6d, 0xca, 0x92},
++        {0xb2, 0xc9, 0x5e, 0xb0, 0x0c, 0x31, 0xad, 0x71, 0x80, 0xac, 0x05, 0xb8, 0xe8, 0x3d, 0x69, 0x6e}
++    };
++    static const uint8_t iv[8] = {0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6};
++    static uint8_t rpt2[2][16];
++    int i, j, err = 0;
++    static const int key_bits[3] = {128, 80, 40};
++    uint8_t temp[8];
++    AVCAST5 *cs;
++    cs = av_cast5_alloc();
++    if (!cs)
++        return 1;
++    for (j = 0; j < 3; j++){
++
++        av_cast5_init(cs, Key[j], key_bits[j]);
++        av_cast5_crypt(cs, temp, rpt, 1, 0);
++        for (i = 0;i < 8; i++){
++            if (rct[j][i] != temp[i]){
++                av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]);
++                err = 1;
++            }
++        }
++
++        av_cast5_crypt(cs, temp, rct[j], 1, 1);
++        for (i =0; i < 8; i++) {
++            if (rpt[i] != temp[i]) {
++                av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
++                err = 1;
++            }
++        }
++    }
++    memcpy(rpt2[0], Key[0], 16);
++    memcpy(rpt2[1], Key[0], 16);
++    for (i = 0; i < 1000000; i++){
++        av_cast5_init(cs, rpt2[1], 128);
++        av_cast5_crypt(cs, rpt2[0], rpt2[0], 2, 0);
++        av_cast5_init(cs, rpt2[0], 128);
++        av_cast5_crypt(cs, rpt2[1], rpt2[1], 2, 0);
++    }
++    for (j = 0; j < 2; j++) {
++        for (i = 0; i < 16; i++) {
++            if (rct2[j][i] != rpt2[j][i]) {
++                av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct2[j][i], rpt2[j][i]);
++                err = 1;
++            }
++        }
++    }
++    for (j = 0; j < 3; j++) {
++
++        av_cast5_init(cs, Key[j], key_bits[j]);
++        memcpy(temp, iv, 8);
++        av_cast5_crypt2(cs, rpt2[0], rct2[0], 2, temp, 0);
++        memcpy(temp, iv, 8);
++        av_cast5_crypt2(cs, rpt2[0], rpt2[0], 2, temp, 1);
++        for (i = 0; i < 16; i++) {
++            if (rct2[0][i] != rpt2[0][i]) {
++                av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct2[0][i], rpt2[0][i]);
++                err = 1;
++            }
++        }
++    }
++    av_free(cs);
++    return err;
++}
index a47697b,0000000..445eb55
mode 100644,000000..100644
--- /dev/null
@@@ -1,593 -1,0 +1,507 @@@
- #ifdef TEST
- #include<stdio.h>
- #include<stdlib.h>
- #include"log.h"
- int main(int argc, char** argv)
- {
-     static const uint8_t Key[3][16] = {
-         {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a},
-         {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45},
-         {0x01, 0x23, 0x45, 0x67, 0x12}
-     };
-     static const uint8_t rpt[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
-     static const uint8_t rct[3][8] = {
-         {0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2},
-         {0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b},
-         {0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e}
-     };
-     static const uint8_t rct2[2][16] = {
-         {0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6, 0xb3, 0x43, 0x6f, 0xb8, 0x9d, 0x6d, 0xca, 0x92},
-         {0xb2, 0xc9, 0x5e, 0xb0, 0x0c, 0x31, 0xad, 0x71, 0x80, 0xac, 0x05, 0xb8, 0xe8, 0x3d, 0x69, 0x6e}
-     };
-     static const uint8_t iv[8] = {0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6};
-     static uint8_t rpt2[2][16];
-     int i, j, err = 0;
-     static const int key_bits[3] = {128, 80, 40};
-     uint8_t temp[8];
-     AVCAST5 *cs;
-     cs = av_cast5_alloc();
-     if (!cs)
-         return 1;
-     for (j = 0; j < 3; j++){
-         av_cast5_init(cs, Key[j], key_bits[j]);
-         av_cast5_crypt(cs, temp, rpt, 1, 0);
-         for (i = 0;i < 8; i++){
-             if (rct[j][i] != temp[i]){
-                 av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct[j][i], temp[i]);
-                 err = 1;
-             }
-         }
-         av_cast5_crypt(cs, temp, rct[j], 1, 1);
-         for (i =0; i < 8; i++) {
-             if (rpt[i] != temp[i]) {
-                 av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rpt[i], temp[i]);
-                 err = 1;
-             }
-         }
-     }
-     memcpy(rpt2[0], Key[0], 16);
-     memcpy(rpt2[1], Key[0], 16);
-     for (i = 0; i < 1000000; i++){
-         av_cast5_init(cs, rpt2[1], 128);
-         av_cast5_crypt(cs, rpt2[0], rpt2[0], 2, 0);
-         av_cast5_init(cs, rpt2[0], 128);
-         av_cast5_crypt(cs, rpt2[1], rpt2[1], 2, 0);
-     }
-     for (j = 0; j < 2; j++) {
-         for (i = 0; i < 16; i++) {
-             if (rct2[j][i] != rpt2[j][i]) {
-                 av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct2[j][i], rpt2[j][i]);
-                 err = 1;
-             }
-         }
-     }
-     for (j = 0; j < 3; j++) {
-         av_cast5_init(cs, Key[j], key_bits[j]);
-         memcpy(temp, iv, 8);
-         av_cast5_crypt2(cs, rpt2[0], rct2[0], 2, temp, 0);
-         memcpy(temp, iv, 8);
-         av_cast5_crypt2(cs, rpt2[0], rpt2[0], 2, temp, 1);
-         for (i = 0; i < 16; i++) {
-             if (rct2[0][i] != rpt2[0][i]) {
-                 av_log(NULL, AV_LOG_ERROR, "%d %02x %02x\n", i, rct2[0][i], rpt2[0][i]);
-                 err = 1;
-             }
-         }
-     }
-     av_free(cs);
-     return err;
- }
- #endif
 +/*
 + * An implementation of the CAST128 algorithm as mentioned in RFC2144
 + * Copyright (c) 2014 Supraja Meedinti
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +#include "cast5.h"
 +#include "common.h"
 +#include "intreadwrite.h"
 +#include "attributes.h"
 +
 +#define IA(x) ((x) >> 24)
 +#define IB(x) (((x) >> 16) & 0xff)
 +#define IC(x) (((x) >> 8) & 0xff)
 +#define ID(x) ((x) & 0xff)
 +
 +#define LR(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
 +
 +#define F3(l, r, i)                                                                                  \
 +    do {                                                                                             \
 +        I = LR(cs->Km[i] - r, cs->Kr[i]);                                                            \
 +        f = ((S1[IA(I)] + S2[IB(I)]) ^ S3[IC(I)]) - S4[ID(I)];                                       \
 +        l = f ^ l;                                                                                   \
 +    } while (0)
 +
 +#define F2(l, r, i)                                                                                  \
 +    do {                                                                                             \
 +        I = LR(cs->Km[i] ^ r, cs->Kr[i]);                                                            \
 +        f = ((S1[IA(I)] - S2[IB(I)]) + S3[IC(I)]) ^ S4[ID(I)];                                       \
 +        l = f ^ l;                                                                                   \
 +    } while (0)
 +
 +#define F1(l, r, i)                                                                                  \
 +    do {                                                                                             \
 +        I = LR(cs->Km[i] + r, cs->Kr[i]);                                                            \
 +        f = ((S1[IA(I)] ^ S2[IB(I)]) - S3[IC(I)]) + S4[ID(I)];                                       \
 +        l = f ^ l;                                                                                   \
 +    } while (0)
 +
 +#define COMPUTE_Z                                                                                    \
 +    do {                                                                                             \
 +        z[0] = x[0] ^ S5[IB(x[3])] ^ S6[ID(x[3])] ^ S7[IA(x[3])] ^ S8[IC(x[3])] ^ S7[IA(x[2])];      \
 +        z[1] = x[2] ^ S5[IA(z[0])] ^ S6[IC(z[0])] ^ S7[IB(z[0])] ^ S8[ID(z[0])] ^ S8[IC(x[2])];      \
 +        z[2] = x[3] ^ S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S5[IB(x[2])];      \
 +        z[3] = x[1] ^ S5[IC(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[2])] ^ S8[IA(z[2])] ^ S6[ID(x[2])];      \
 +    } while (0)
 +
 +#define COMPUTE_X                                                                                    \
 +    do {                                                                                             \
 +        x[0] = z[2] ^ S5[IB(z[1])] ^ S6[ID(z[1])] ^ S7[IA(z[1])] ^ S8[IC(z[1])] ^ S7[IA(z[0])];      \
 +        x[1] = z[0] ^ S5[IA(x[0])] ^ S6[IC(x[0])] ^ S7[IB(x[0])] ^ S8[ID(x[0])] ^ S8[IC(z[0])];      \
 +        x[2] = z[1] ^ S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S5[IB(z[0])];      \
 +        x[3] = z[3] ^ S5[IC(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[2])] ^ S8[IA(x[2])] ^ S6[ID(z[0])];      \
 +    } while (0)
 +
 +
 +typedef struct AVCAST5 {
 +    uint32_t Km[17];
 +    uint32_t Kr[17];
 +    int rounds;
 +} AVCAST5;
 +
 +const int av_cast5_size = sizeof(AVCAST5);
 +
 +static const uint32_t S1[256] = {
 +    0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
 +    0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
 +    0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
 +    0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
 +    0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
 +    0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
 +    0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
 +    0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
 +    0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
 +    0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
 +    0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
 +    0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
 +    0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
 +    0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
 +    0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
 +    0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
 +    0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
 +    0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
 +    0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
 +    0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
 +    0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
 +    0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
 +    0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
 +    0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
 +    0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
 +    0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
 +    0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
 +    0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
 +    0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
 +    0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
 +    0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
 +    0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
 +};
 +
 +static const uint32_t S2[256] = {
 +    0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
 +    0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
 +    0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
 +    0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
 +    0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
 +    0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
 +    0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
 +    0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
 +    0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
 +    0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
 +    0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
 +    0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
 +    0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
 +    0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
 +    0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
 +    0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
 +    0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
 +    0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
 +    0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
 +    0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
 +    0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
 +    0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
 +    0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
 +    0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
 +    0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
 +    0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
 +    0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
 +    0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
 +    0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
 +    0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
 +    0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
 +    0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
 +};
 +
 +static const uint32_t S3[256] = {
 +    0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
 +    0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
 +    0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
 +    0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
 +    0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
 +    0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
 +    0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
 +    0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
 +    0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
 +    0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
 +    0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
 +    0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
 +    0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
 +    0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
 +    0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
 +    0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
 +    0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
 +    0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
 +    0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
 +    0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
 +    0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
 +    0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
 +    0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
 +    0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
 +    0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
 +    0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
 +    0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
 +    0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
 +    0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
 +    0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
 +    0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
 +    0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
 +};
 +
 +static const uint32_t S4[256] = {
 +    0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
 +    0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
 +    0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
 +    0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
 +    0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
 +    0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
 +    0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
 +    0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
 +    0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
 +    0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
 +    0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
 +    0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
 +    0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
 +    0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
 +    0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
 +    0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
 +    0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
 +    0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
 +    0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
 +    0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
 +    0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
 +    0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
 +    0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
 +    0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
 +    0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
 +    0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
 +    0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
 +    0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
 +    0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
 +    0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
 +    0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
 +    0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
 +};
 +
 +static const uint32_t S5[256] = {
 +    0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
 +    0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
 +    0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
 +    0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
 +    0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
 +    0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
 +    0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
 +    0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
 +    0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
 +    0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
 +    0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
 +    0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
 +    0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
 +    0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
 +    0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
 +    0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
 +    0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
 +    0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
 +    0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
 +    0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
 +    0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
 +    0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
 +    0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
 +    0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
 +    0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
 +    0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
 +    0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
 +    0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
 +    0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
 +    0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
 +    0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
 +    0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
 +};
 +
 +static const uint32_t S6[256] = {
 +    0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
 +    0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
 +    0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
 +    0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
 +    0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
 +    0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
 +    0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
 +    0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
 +    0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
 +    0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
 +    0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
 +    0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
 +    0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
 +    0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
 +    0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
 +    0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
 +    0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
 +    0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
 +    0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
 +    0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
 +    0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
 +    0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
 +    0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
 +    0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
 +    0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
 +    0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
 +    0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
 +    0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
 +    0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
 +    0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
 +    0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
 +    0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
 +};
 +
 +static const uint32_t S7[256] = {
 +    0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
 +    0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
 +    0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
 +    0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
 +    0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
 +    0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
 +    0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
 +    0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
 +    0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
 +    0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
 +    0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
 +    0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
 +    0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
 +    0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
 +    0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
 +    0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
 +    0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
 +    0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
 +    0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
 +    0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
 +    0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
 +    0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
 +    0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
 +    0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
 +    0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
 +    0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
 +    0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
 +    0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
 +    0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
 +    0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
 +    0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
 +    0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
 +};
 +
 +static const uint32_t S8[256] = {
 +    0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
 +    0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
 +    0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
 +    0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
 +    0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
 +    0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
 +    0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
 +    0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
 +    0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
 +    0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
 +    0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
 +    0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
 +    0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
 +    0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
 +    0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
 +    0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
 +    0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
 +    0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
 +    0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
 +    0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
 +    0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
 +    0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
 +    0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
 +    0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
 +    0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
 +    0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
 +    0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
 +    0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
 +    0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
 +    0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
 +    0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
 +    0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
 +};
 +
 +static void generate_round_keys(int rnds, uint32_t* K, uint32_t* x, uint32_t* z)
 +{
 +    COMPUTE_Z;
 +
 +    K[1] = S5[IA(z[2])] ^ S6[IB(z[2])] ^ S7[ID(z[1])] ^ S8[IC(z[1])] ^ S5[IC(z[0])];
 +    K[2] = S5[IC(z[2])] ^ S6[ID(z[2])] ^ S7[IB(z[1])] ^ S8[IA(z[1])] ^ S6[IC(z[1])];
 +    K[3] = S5[IA(z[3])] ^ S6[IB(z[3])] ^ S7[ID(z[0])] ^ S8[IC(z[0])] ^ S7[IB(z[2])];
 +    K[4] = S5[IC(z[3])] ^ S6[ID(z[3])] ^ S7[IB(z[0])] ^ S8[IA(z[0])] ^ S8[IA(z[3])];
 +
 +    COMPUTE_X;
 +
 +    K[5] = S5[ID(x[0])] ^ S6[IC(x[0])] ^ S7[IA(x[3])] ^ S8[IB(x[3])] ^ S5[IA(x[2])];
 +    K[6] = S5[IB(x[0])] ^ S6[IA(x[0])] ^ S7[IC(x[3])] ^ S8[ID(x[3])] ^ S6[IB(x[3])];
 +    K[7] = S5[ID(x[1])] ^ S6[IC(x[1])] ^ S7[IA(x[2])] ^ S8[IB(x[2])] ^ S7[ID(x[0])];
 +    K[8] = S5[IB(x[1])] ^ S6[IA(x[1])] ^ S7[IC(x[2])] ^ S8[ID(x[2])] ^ S8[ID(x[1])];
 +
 +    COMPUTE_Z;
 +
 +    K[9] = S5[ID(z[0])] ^ S6[IC(z[0])] ^ S7[IA(z[3])] ^ S8[IB(z[3])] ^ S5[IB(z[2])];
 +    K[10] = S5[IB(z[0])] ^ S6[IA(z[0])] ^ S7[IC(z[3])] ^ S8[ID(z[3])] ^ S6[IA(z[3])];
 +    K[11] = S5[ID(z[1])] ^ S6[IC(z[1])] ^ S7[IA(z[2])] ^ S8[IB(z[2])] ^ S7[IC(z[0])];
 +    K[12] = S5[IB(z[1])] ^ S6[IA(z[1])] ^ S7[IC(z[2])] ^ S8[ID(z[2])] ^ S8[IC(z[1])];
 +
 +    COMPUTE_X;
 +
 +    if (rnds == 16) {
 +        K[13] = S5[IA(x[2])] ^ S6[IB(x[2])] ^ S7[ID(x[1])] ^ S8[IC(x[1])] ^ S5[ID(x[0])];
 +        K[14] = S5[IC(x[2])] ^ S6[ID(x[2])] ^ S7[IB(x[1])] ^ S8[IA(x[1])] ^ S6[ID(x[1])];
 +        K[15] = S5[IA(x[3])] ^ S6[IB(x[3])] ^ S7[ID(x[0])] ^ S8[IC(x[0])] ^ S7[IA(x[2])];
 +        K[16] = S5[IC(x[3])] ^ S6[ID(x[3])] ^ S7[IB(x[0])] ^ S8[IA(x[0])] ^ S8[IB(x[3])];
 +    }
 +}
 +
 +static void encipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src)
 +{
 +    uint32_t r, l, f, I;
 +    l = AV_RB32(src);
 +    r = AV_RB32(src + 4);
 +    F1(l, r, 1);
 +    F2(r, l, 2);
 +    F3(l, r, 3);
 +    F1(r, l, 4);
 +    F2(l, r, 5);
 +    F3(r, l, 6);
 +    F1(l, r, 7);
 +    F2(r, l, 8);
 +    F3(l, r, 9);
 +    F1(r, l, 10);
 +    F2(l, r, 11);
 +    F3(r, l, 12);
 +    if (cs->rounds == 16) {
 +        F1(l, r, 13);
 +        F2(r, l, 14);
 +        F3(l, r, 15);
 +        F1(r, l, 16);
 +    }
 +    AV_WB32(dst, r);
 +    AV_WB32(dst + 4, l);
 +}
 +
 +static void decipher(AVCAST5* cs, uint8_t* dst, const uint8_t* src, uint8_t *iv)
 +{
 +    uint32_t f, I, r, l;
 +    l = AV_RB32(src);
 +    r = AV_RB32(src + 4);
 +    if (cs->rounds == 16) {
 +        F1(l, r, 16);
 +        F3(r, l, 15);
 +        F2(l, r, 14);
 +        F1(r, l, 13);
 +    }
 +    F3(l, r, 12);
 +    F2(r, l, 11);
 +    F1(l, r, 10);
 +    F3(r, l, 9);
 +    F2(l, r, 8);
 +    F1(r, l, 7);
 +    F3(l, r, 6);
 +    F2(r, l, 5);
 +    F1(l, r, 4);
 +    F3(r, l, 3);
 +    F2(l, r, 2);
 +    F1(r, l, 1);
 +    if (iv) {
 +        r ^= AV_RB32(iv);
 +        l ^= AV_RB32(iv + 4);
 +        memcpy(iv, src, 8);
 +    }
 +    AV_WB32(dst, r);
 +    AV_WB32(dst + 4, l);
 +}
 +
 +struct AVCAST5 *av_cast5_alloc(void)
 +{
 +    return av_mallocz(sizeof(struct AVCAST5));
 +}
 +
 +av_cold int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits)
 +{
 +    uint8_t newKey[16];
 +    int i;
 +    uint32_t p[4], q[4];
 +    if (key_bits % 8 || key_bits < 40 || key_bits > 128)
 +        return AVERROR(EINVAL);
 +    memset(newKey, 0, sizeof(newKey));
 +    memcpy(newKey, key, key_bits >> 3);
 +
 +    cs->rounds = key_bits <= 80 ? 12 : 16;
 +    for (i = 0; i < 4; i++)
 +        q[i] = AV_RB32(newKey + (4 * i));
 +    generate_round_keys(cs->rounds, cs->Km, q, p);
 +    generate_round_keys(cs->rounds, cs->Kr, q, p);
 +    for (i = 0; i <= cs->rounds; i++)
 +        cs->Kr[i] = cs->Kr[i] & 0x1f;
 +    return 0;
 +}
 +
 +void av_cast5_crypt2(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, uint8_t *iv, int decrypt)
 +{
 +    int i;
 +    while (count--) {
 +        if (decrypt) {
 +            decipher(cs, dst, src, iv);
 +        } else {
 +            if (iv) {
 +                for (i = 0; i < 8; i++)
 +                    dst[i] = src[i] ^ iv[i];
 +                encipher(cs, dst, dst);
 +                memcpy(iv, dst, 8);
 +            } else {
 +                encipher(cs, dst, src);
 +            }
 +        }
 +        src = src + 8;
 +        dst = dst + 8;
 +    }
 +}
 +void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int count, int decrypt)
 +{
 +    while (count--) {
 +        if (decrypt){
 +            decipher(cs, dst, src, NULL);
 +        } else {
 +            encipher(cs, dst, src);
 +        }
 +        src = src + 8;
 +        dst = dst + 8;
 +    }
 +}
index 0000000,0000000..083872c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,43 @@@
++/*
++ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "color_utils.c"
++
++int main(int argc, char *argv[])
++{
++  int i, j;
++  static const double test_data[] = {
++      -0.1, -0.018053968510807, -0.01, -0.00449, 0.0, 0.00316227760, 0.005,
++      0.009, 0.015, 0.1, 1.0, 52.37, 125.098765, 1999.11123, 6945.443,
++      15123.4567, 19845.88923, 98678.4231, 99999.899998
++  };
++
++  for(i = 0; i < AVCOL_TRC_NB; i++) {
++      avpriv_trc_function func = avpriv_get_trc_function_from_trc(i);
++      for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) {
++          if(func != NULL) {
++              double result = func(test_data[j]);
++              printf("AVColorTransferCharacteristic=%d calling func(%f) expected=%f\n",
++                     i, test_data[j], result);
++          }
++      }
++  }
++
++}
index 6dba46a,0000000..63f2230
mode 100644,000000..100644
--- /dev/null
@@@ -1,247 -1,0 +1,219 @@@
- #ifdef TEST
- // LCOV_EXCL_START
- int main(int argc, char *argv[])
- {
-   int i, j;
-   static const double test_data[] = {
-       -0.1, -0.018053968510807, -0.01, -0.00449, 0.0, 0.00316227760, 0.005,
-       0.009, 0.015, 0.1, 1.0, 52.37, 125.098765, 1999.11123, 6945.443,
-       15123.4567, 19845.88923, 98678.4231, 99999.899998
-   };
-   for(i = 0; i < AVCOL_TRC_NB; i++) {
-       avpriv_trc_function func = avpriv_get_trc_function_from_trc(i);
-       for(j = 0; j < FF_ARRAY_ELEMS(test_data); j++) {
-           if(func != NULL) {
-               double result = func(test_data[j]);
-               printf("AVColorTransferCharacteristic=%d calling func(%f) expected=%f\n",
-                      i, test_data[j], result);
-           }
-       }
-   }
- }
- // LCOV_EXCL_STOP
- #endif
 +/*
 + * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include <stddef.h>
 +#include <math.h>
 +
 +#include "common.h"
 +#include "libavutil/color_utils.h"
 +#include "libavutil/pixfmt.h"
 +
 +double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
 +{
 +    double gamma;
 +    switch (trc) {
 +        case AVCOL_TRC_BT709:
 +        case AVCOL_TRC_SMPTE170M:
 +        case AVCOL_TRC_SMPTE240M:
 +        case AVCOL_TRC_BT1361_ECG:
 +        case AVCOL_TRC_BT2020_10:
 +        case AVCOL_TRC_BT2020_12:
 +            /* these share a segmented TRC, but gamma 1.961 is a close
 +              approximation, and also more correct for decoding content */
 +            gamma = 1.961;
 +            break;
 +        case AVCOL_TRC_GAMMA22:
 +        case AVCOL_TRC_IEC61966_2_1:
 +            gamma = 2.2;
 +            break;
 +        case AVCOL_TRC_GAMMA28:
 +            gamma = 2.8;
 +            break;
 +        case AVCOL_TRC_LINEAR:
 +            gamma = 1.0;
 +            break;
 +        default:
 +            gamma = 0.0; // Unknown value representation
 +    }
 +    return gamma;
 +}
 +
 +#define BT709_alpha 1.099296826809442
 +#define BT709_beta 0.018053968510807
 +
 +static double avpriv_trc_bt709(double Lc)
 +{
 +    const double a = BT709_alpha;
 +    const double b = BT709_beta;
 +
 +    return (0.0 > Lc) ? 0.0
 +         : (  b > Lc) ? 4.500 * Lc
 +         :              a * pow(Lc, 0.45) - (a - 1.0);
 +}
 +
 +static double avpriv_trc_gamma22(double Lc)
 +{
 +    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
 +}
 +
 +static double avpriv_trc_gamma28(double Lc)
 +{
 +    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
 +}
 +
 +static double avpriv_trc_smpte240M(double Lc)
 +{
 +    const double a = 1.1115;
 +    const double b = 0.0228;
 +
 +    return (0.0 > Lc) ? 0.0
 +         : (  b > Lc) ? 4.000 * Lc
 +         :              a * pow(Lc, 0.45) - (a - 1.0);
 +}
 +
 +static double avpriv_trc_linear(double Lc)
 +{
 +    return Lc;
 +}
 +
 +static double avpriv_trc_log(double Lc)
 +{
 +    return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
 +}
 +
 +static double avpriv_trc_log_sqrt(double Lc)
 +{
 +    // sqrt(10) / 1000
 +    return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
 +}
 +
 +static double avpriv_trc_iec61966_2_4(double Lc)
 +{
 +    const double a = BT709_alpha;
 +    const double b = BT709_beta;
 +
 +    return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
 +         : ( b >  Lc) ? 4.500 * Lc
 +         :               a * pow( Lc, 0.45) - (a - 1.0);
 +}
 +
 +static double avpriv_trc_bt1361(double Lc)
 +{
 +    const double a = BT709_alpha;
 +    const double b = BT709_beta;
 +
 +    return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
 +         : ( b >  Lc) ? 4.500 * Lc
 +         :               a * pow( Lc, 0.45) - (a - 1.0);
 +}
 +
 +static double avpriv_trc_iec61966_2_1(double Lc)
 +{
 +    const double a = 1.055;
 +    const double b = 0.0031308;
 +
 +    return (0.0 > Lc) ? 0.0
 +         : (  b > Lc) ? 12.92 * Lc
 +         :              a * pow(Lc, 1.0  / 2.4) - (a - 1.0);
 +}
 +
 +static double avpriv_trc_smpte_st2084(double Lc)
 +{
 +    const double c1 =         3424.0 / 4096.0; // c3-c2 + 1
 +    const double c2 =  32.0 * 2413.0 / 4096.0;
 +    const double c3 =  32.0 * 2392.0 / 4096.0;
 +    const double m  = 128.0 * 2523.0 / 4096.0;
 +    const double n  =  0.25 * 2610.0 / 4096.0;
 +    const double L  = Lc / 10000.0;
 +    const double Ln = pow(L, n);
 +
 +    return (0.0 > Lc) ? 0.0
 +         :              pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
 +
 +}
 +
 +static double avpriv_trc_smpte_st428_1(double Lc)
 +{
 +    return (0.0 > Lc) ? 0.0
 +         :              pow(48.0 * Lc / 52.37, 1.0 / 2.6);
 +}
 +
 +avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc)
 +{
 +    avpriv_trc_function func = NULL;
 +    switch (trc) {
 +        case AVCOL_TRC_BT709:
 +        case AVCOL_TRC_SMPTE170M:
 +        case AVCOL_TRC_BT2020_10:
 +        case AVCOL_TRC_BT2020_12:
 +            func = avpriv_trc_bt709;
 +            break;
 +
 +        case AVCOL_TRC_GAMMA22:
 +            func = avpriv_trc_gamma22;
 +            break;
 +        case AVCOL_TRC_GAMMA28:
 +            func = avpriv_trc_gamma28;
 +            break;
 +
 +        case AVCOL_TRC_SMPTE240M:
 +            func = avpriv_trc_smpte240M;
 +            break;
 +
 +        case AVCOL_TRC_LINEAR:
 +            func = avpriv_trc_linear;
 +            break;
 +
 +        case AVCOL_TRC_LOG:
 +            func = avpriv_trc_log;
 +            break;
 +
 +        case AVCOL_TRC_LOG_SQRT:
 +            func = avpriv_trc_log_sqrt;
 +            break;
 +
 +        case AVCOL_TRC_IEC61966_2_4:
 +            func = avpriv_trc_iec61966_2_4;
 +            break;
 +
 +        case AVCOL_TRC_BT1361_ECG:
 +            func = avpriv_trc_bt1361;
 +            break;
 +
 +        case AVCOL_TRC_IEC61966_2_1:
 +            func = avpriv_trc_iec61966_2_1;
 +            break;
 +
 +        case AVCOL_TRC_SMPTEST2084:
 +            func = avpriv_trc_smpte_st2084;
 +            break;
 +
 +        case AVCOL_TRC_SMPTEST428_1:
 +            func = avpriv_trc_smpte_st428_1;
 +            break;
 +
 +        case AVCOL_TRC_RESERVED0:
 +        case AVCOL_TRC_UNSPECIFIED:
 +        case AVCOL_TRC_RESERVED:
 +        default:
 +            break;
 +    }
 +    return func;
 +}
index 0000000,a2c3b38..3eca6d2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,136 +1,147 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -#include "config.h"
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
 -#if HAVE_UNISTD_H
 -#include <unistd.h>
 -#elif !HAVE_GETOPT
++#include <stdio.h>
++#include "avstring.h"
 -    { AV_CPU_FLAG_SSE2SLOW,  "sse2(slow)" },
++#if !HAVE_GETOPT
+ #include "compat/getopt.c"
+ #endif
+ #include <stdint.h>
+ #include <stdio.h>
+ #include "avstring.h"
+ #include "common.h"
+ #include "cpu.h"
+ static const struct {
+     int flag;
+     const char *name;
+ } cpu_flag_tab[] = {
+ #if   ARCH_AARCH64
+     { AV_CPU_FLAG_ARMV8,     "armv8"      },
+     { AV_CPU_FLAG_NEON,      "neon"       },
+     { AV_CPU_FLAG_VFP,       "vfp"        },
+ #elif ARCH_ARM
+     { AV_CPU_FLAG_ARMV5TE,   "armv5te"    },
+     { AV_CPU_FLAG_ARMV6,     "armv6"      },
+     { AV_CPU_FLAG_ARMV6T2,   "armv6t2"    },
+     { AV_CPU_FLAG_VFP,       "vfp"        },
+     { AV_CPU_FLAG_VFP_VM,    "vfp_vm"     },
+     { AV_CPU_FLAG_VFPV3,     "vfpv3"      },
+     { AV_CPU_FLAG_NEON,      "neon"       },
++    { AV_CPU_FLAG_SETEND,    "setend"     },
+ #elif ARCH_PPC
+     { AV_CPU_FLAG_ALTIVEC,   "altivec"    },
+ #elif ARCH_X86
+     { AV_CPU_FLAG_MMX,       "mmx"        },
+     { AV_CPU_FLAG_MMXEXT,    "mmxext"     },
+     { AV_CPU_FLAG_SSE,       "sse"        },
+     { AV_CPU_FLAG_SSE2,      "sse2"       },
 -    { AV_CPU_FLAG_SSE3SLOW,  "sse3(slow)" },
++    { AV_CPU_FLAG_SSE2SLOW,  "sse2slow"   },
+     { AV_CPU_FLAG_SSE3,      "sse3"       },
 -    fprintf(stderr, "cpu_flags(%s) = 0x%08X\n", type, cpu_flags);
 -    fprintf(stderr, "cpu_flags_str(%s) =", type);
++    { AV_CPU_FLAG_SSE3SLOW,  "sse3slow"   },
+     { AV_CPU_FLAG_SSSE3,     "ssse3"      },
+     { AV_CPU_FLAG_ATOM,      "atom"       },
+     { AV_CPU_FLAG_SSE4,      "sse4.1"     },
+     { AV_CPU_FLAG_SSE42,     "sse4.2"     },
+     { AV_CPU_FLAG_AVX,       "avx"        },
+     { AV_CPU_FLAG_AVXSLOW,   "avxslow"    },
+     { AV_CPU_FLAG_XOP,       "xop"        },
+     { AV_CPU_FLAG_FMA3,      "fma3"       },
+     { AV_CPU_FLAG_FMA4,      "fma4"       },
+     { AV_CPU_FLAG_3DNOW,     "3dnow"      },
+     { AV_CPU_FLAG_3DNOWEXT,  "3dnowext"   },
+     { AV_CPU_FLAG_CMOV,      "cmov"       },
+     { AV_CPU_FLAG_AVX2,      "avx2"       },
+     { AV_CPU_FLAG_BMI1,      "bmi1"       },
+     { AV_CPU_FLAG_BMI2,      "bmi2"       },
++    { AV_CPU_FLAG_AESNI,     "aesni"      },
+ #endif
+     { 0 }
+ };
+ static void print_cpu_flags(int cpu_flags, const char *type)
+ {
+     int i;
 -            fprintf(stderr, " %s", cpu_flag_tab[i].name);
 -    fprintf(stderr, "\n");
++    printf("cpu_flags(%s) = 0x%08X\n", type, cpu_flags);
++    printf("cpu_flags_str(%s) =", type);
+     for (i = 0; cpu_flag_tab[i].flag; i++)
+         if (cpu_flags & cpu_flag_tab[i].flag)
 -            int cpuflags = av_parse_cpu_flags(optarg);
 -            if (cpuflags < 0)
++            printf(" %s", cpu_flag_tab[i].name);
++    printf("\n");
+ }
+ int main(int argc, char **argv)
+ {
+     int cpu_flags_raw = av_get_cpu_flags();
+     int cpu_flags_eff;
+     int cpu_count = av_cpu_count();
+     char threads[5] = "auto";
++    int i;
++
++    for(i = 0; cpu_flag_tab[i].flag; i++) {
++        unsigned tmp = 0;
++        if (av_parse_cpu_caps(&tmp, cpu_flag_tab[i].name) < 0) {
++            fprintf(stderr, "Table missing %s\n", cpu_flag_tab[i].name);
++            return 4;
++        }
++    }
+     if (cpu_flags_raw < 0)
+         return 1;
+     for (;;) {
+         int c = getopt(argc, argv, "c:t:");
+         if (c == -1)
+             break;
+         switch (c) {
+         case 'c':
+         {
 -            av_set_cpu_flags_mask(cpuflags);
++            unsigned flags = av_get_cpu_flags();
++            if (av_parse_cpu_caps(&flags, optarg) < 0)
+                 return 2;
 -    fprintf(stderr, "threads = %s (cpu_count = %d)\n", threads, cpu_count);
++
++            av_force_cpu_flags(flags);
+             break;
+         }
+         case 't':
+         {
+             int len = av_strlcpy(threads, optarg, sizeof(threads));
+             if (len >= sizeof(threads)) {
+                 fprintf(stderr, "Invalid thread count '%s'\n", optarg);
+                 return 2;
+             }
+         }
+         }
+     }
+     cpu_flags_eff = av_get_cpu_flags();
+     if (cpu_flags_eff < 0)
+         return 3;
+     print_cpu_flags(cpu_flags_raw, "raw");
+     print_cpu_flags(cpu_flags_eff, "effective");
++    printf("threads = %s (cpu_count = %d)\n", threads, cpu_count);
+     return 0;
+ }
diff --cc libavutil/cpu.c
@@@ -282,142 -174,7 +282,15 @@@ int av_cpu_count(void
      nb_cpus = sysconf(_SC_NPROC_ONLN);
  #elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
      nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 +#elif HAVE_WINRT
 +    GetNativeSystemInfo(&sysinfo);
 +    nb_cpus = sysinfo.dwNumberOfProcessors;
  #endif
  
 +    if (!printed) {
 +        av_log(NULL, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
 +        printed = 1;
 +    }
 +
      return nb_cpus;
  }
- #ifdef TEST
- #include <stdio.h>
- #include "avstring.h"
- #if !HAVE_GETOPT
- #include "compat/getopt.c"
- #endif
- static const struct {
-     int flag;
-     const char *name;
- } cpu_flag_tab[] = {
- #if   ARCH_AARCH64
-     { AV_CPU_FLAG_ARMV8,     "armv8"      },
-     { AV_CPU_FLAG_NEON,      "neon"       },
-     { AV_CPU_FLAG_VFP,       "vfp"        },
- #elif ARCH_ARM
-     { AV_CPU_FLAG_ARMV5TE,   "armv5te"    },
-     { AV_CPU_FLAG_ARMV6,     "armv6"      },
-     { AV_CPU_FLAG_ARMV6T2,   "armv6t2"    },
-     { AV_CPU_FLAG_VFP,       "vfp"        },
-     { AV_CPU_FLAG_VFP_VM,    "vfp_vm"     },
-     { AV_CPU_FLAG_VFPV3,     "vfpv3"      },
-     { AV_CPU_FLAG_NEON,      "neon"       },
-     { AV_CPU_FLAG_SETEND,    "setend"     },
- #elif ARCH_PPC
-     { AV_CPU_FLAG_ALTIVEC,   "altivec"    },
- #elif ARCH_X86
-     { AV_CPU_FLAG_MMX,       "mmx"        },
-     { AV_CPU_FLAG_MMXEXT,    "mmxext"     },
-     { AV_CPU_FLAG_SSE,       "sse"        },
-     { AV_CPU_FLAG_SSE2,      "sse2"       },
-     { AV_CPU_FLAG_SSE2SLOW,  "sse2slow"   },
-     { AV_CPU_FLAG_SSE3,      "sse3"       },
-     { AV_CPU_FLAG_SSE3SLOW,  "sse3slow"   },
-     { AV_CPU_FLAG_SSSE3,     "ssse3"      },
-     { AV_CPU_FLAG_ATOM,      "atom"       },
-     { AV_CPU_FLAG_SSE4,      "sse4.1"     },
-     { AV_CPU_FLAG_SSE42,     "sse4.2"     },
-     { AV_CPU_FLAG_AVX,       "avx"        },
-     { AV_CPU_FLAG_AVXSLOW,   "avxslow"    },
-     { AV_CPU_FLAG_XOP,       "xop"        },
-     { AV_CPU_FLAG_FMA3,      "fma3"       },
-     { AV_CPU_FLAG_FMA4,      "fma4"       },
-     { AV_CPU_FLAG_3DNOW,     "3dnow"      },
-     { AV_CPU_FLAG_3DNOWEXT,  "3dnowext"   },
-     { AV_CPU_FLAG_CMOV,      "cmov"       },
-     { AV_CPU_FLAG_AVX2,      "avx2"       },
-     { AV_CPU_FLAG_BMI1,      "bmi1"       },
-     { AV_CPU_FLAG_BMI2,      "bmi2"       },
-     { AV_CPU_FLAG_AESNI,     "aesni"      },
- #endif
-     { 0 }
- };
- static void print_cpu_flags(int cpu_flags, const char *type)
- {
-     int i;
-     printf("cpu_flags(%s) = 0x%08X\n", type, cpu_flags);
-     printf("cpu_flags_str(%s) =", type);
-     for (i = 0; cpu_flag_tab[i].flag; i++)
-         if (cpu_flags & cpu_flag_tab[i].flag)
-             printf(" %s", cpu_flag_tab[i].name);
-     printf("\n");
- }
- int main(int argc, char **argv)
- {
-     int cpu_flags_raw = av_get_cpu_flags();
-     int cpu_flags_eff;
-     int cpu_count = av_cpu_count();
-     char threads[5] = "auto";
-     int i;
-     for(i = 0; cpu_flag_tab[i].flag; i++) {
-         unsigned tmp = 0;
-         if (av_parse_cpu_caps(&tmp, cpu_flag_tab[i].name) < 0) {
-             fprintf(stderr, "Table missing %s\n", cpu_flag_tab[i].name);
-             return 4;
-         }
-     }
-     if (cpu_flags_raw < 0)
-         return 1;
-     for (;;) {
-         int c = getopt(argc, argv, "c:t:");
-         if (c == -1)
-             break;
-         switch (c) {
-         case 'c':
-         {
-             unsigned flags = av_get_cpu_flags();
-             if (av_parse_cpu_caps(&flags, optarg) < 0)
-                 return 2;
-             av_force_cpu_flags(flags);
-             break;
-         }
-         case 't':
-         {
-             int len = av_strlcpy(threads, optarg, sizeof(threads));
-             if (len >= sizeof(threads)) {
-                 fprintf(stderr, "Invalid thread count '%s'\n", optarg);
-                 return 2;
-             }
-         }
-         }
-     }
-     cpu_flags_eff = av_get_cpu_flags();
-     if (cpu_flags_eff < 0)
-         return 3;
-     print_cpu_flags(cpu_flags_raw, "raw");
-     print_cpu_flags(cpu_flags_eff, "effective");
-     printf("threads = %s (cpu_count = %d)\n", threads, cpu_count);
-     return 0;
- }
- #endif
index 0000000,41601c5..3c250df
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,45 +1,46 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    int p[5][3] = {
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdint.h>
+ #include <stdio.h>
+ #include "crc.h"
+ int main(void)
+ {
+     uint8_t buf[1999];
+     int i;
 -        { AV_CRC_32_IEEE,    0x04C11DB7, 0xC0F5BAE0 },
 -        { AV_CRC_16_ANSI_LE,     0xA001,     0xBFD8 },
 -        { AV_CRC_16_ANSI,        0x8005,     0x1FBB },
 -        { AV_CRC_8_ATM,            0x07,       0xE3 }
++    unsigned p[6][3] = {
+         { AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04 },
 -    for (i = 0; i < 5; i++) {
++        { AV_CRC_32_IEEE   , 0x04C11DB7, 0xC0F5BAE0 },
++        { AV_CRC_24_IEEE   , 0x864CFB  , 0xB704CE   },
++        { AV_CRC_16_ANSI_LE, 0xA001    , 0xBFD8     },
++        { AV_CRC_16_ANSI   , 0x8005    , 0x1FBB     },
++        { AV_CRC_8_ATM     , 0x07      , 0xE3       }
+     };
+     const AVCRC *ctx;
+     for (i = 0; i < sizeof(buf); i++)
+         buf[i] = i + i * i;
++    for (i = 0; i < 6; i++) {
+         ctx = av_crc_get_table(p[i][0]);
+         printf("crc %08X = %X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf)));
+     }
+     return 0;
+ }
diff --cc libavutil/crc.c
Simple merge
index 0000000,a372035..99453af
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,128 +1,128 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -        av_des_init(&d, key, 192, 0);
 -        av_des_crypt(&d, &ct, &data, 1, NULL, 0);
 -        av_des_init(&d, key, 192, 1);
 -        av_des_crypt(&d, &ct, &ct, 1, NULL, 1);
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "des.c"
+ #include <stdint.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "time.h"
+ static uint64_t rand64(void)
+ {
+     uint64_t r = rand();
+     r = (r << 32) | rand();
+     return r;
+ }
+ static const uint8_t test_key[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
+ static const DECLARE_ALIGNED(8, uint8_t, plain)[] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };
+ static const DECLARE_ALIGNED(8, uint8_t, crypt)[] = { 0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18 };
+ static DECLARE_ALIGNED(8, uint8_t, tmp)[8];
+ static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8];
+ static const uint8_t cbc_key[] = {
+     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+     0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
+     0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
+ };
+ static int run_test(int cbc, int decrypt)
+ {
+     AVDES d;
+     int delay = cbc && !decrypt ? 2 : 1;
+     uint64_t res;
+     AV_WB64(large_buffer[0], 0x4e6f772069732074ULL);
+     AV_WB64(large_buffer[1], 0x1234567890abcdefULL);
+     AV_WB64(tmp,             0x1234567890abcdefULL);
+     av_des_init(&d, cbc_key, 192, decrypt);
+     av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt);
+     res = AV_RB64(large_buffer[9999 + delay]);
+     if (cbc) {
+         if (decrypt)
+             return res == 0xc5cecf63ecec514cULL;
+         else
+             return res == 0xcb191f85d1ed8439ULL;
+     } else {
+         if (decrypt)
+             return res == 0x8325397644091a0aULL;
+         else
+             return res == 0xdd17e8b8b437d232ULL;
+     }
+ }
+ int main(void)
+ {
+     AVDES d;
+     int i;
+     uint64_t key[3];
+     uint64_t data;
+     uint64_t ct;
+     uint64_t roundkeys[16];
+     srand(av_gettime());
+     key[0] = AV_RB64(test_key);
+     data   = AV_RB64(plain);
+     gen_roundkeys(roundkeys, key[0]);
+     if (des_encdec(data, roundkeys, 0) != AV_RB64(crypt)) {
+         printf("Test 1 failed\n");
+         return 1;
+     }
+     av_des_init(&d, test_key, 64, 0);
+     av_des_crypt(&d, tmp, plain, 1, NULL, 0);
+     if (memcmp(tmp, crypt, sizeof(crypt))) {
+         printf("Public API decryption failed\n");
+         return 1;
+     }
+     if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) {
+         printf("Partial Monte-Carlo test failed\n");
+         return 1;
+     }
+     for (i = 0; i < 1000; i++) {
+         key[0] = rand64();
+         key[1] = rand64();
+         key[2] = rand64();
+         data   = rand64();
++        av_des_init(&d, (uint8_t *) key, 192, 0);
++        av_des_crypt(&d, (uint8_t *) &ct, (uint8_t *) &data, 1, NULL, 0);
++        av_des_init(&d, (uint8_t *) key, 192, 1);
++        av_des_crypt(&d, (uint8_t *) &ct, (uint8_t *) &ct, 1, NULL, 1);
+         if (ct != data) {
+             printf("Test 2 failed\n");
+             return 1;
+         }
+     }
+ #ifdef GENTABLES
+     printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n");
+     for (i = 0; i < 8; i++) {
+         int j;
+         printf("    {");
+         for (j = 0; j < 64; j++) {
+