Revision ff06e067 libavcodec/snow.c

View differences:

libavcodec/snow.c
760 760
    }
761 761
}
762 762

  
763

  
764
#ifndef lift5
765
static av_always_inline void lift5(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){
766
    const int mirror_left= !highpass;
767
    const int mirror_right= (width&1) ^ highpass;
768
    const int w= (width>>1) - 1 + (highpass & width);
769
    int i;
770

  
771
    if(mirror_left){
772
        int r= 3*2*ref[0];
773
        r += r>>4;
774
        r += r>>8;
775
        dst[0] = LIFT(src[0], ((r+add)>>shift), inverse);
776
        dst += dst_step;
777
        src += src_step;
778
    }
779

  
780
    for(i=0; i<w; i++){
781
        int r= 3*(ref[i*ref_step] + ref[(i+1)*ref_step]);
782
        r += r>>4;
783
        r += r>>8;
784
        dst[i*dst_step] = LIFT(src[i*src_step], ((r+add)>>shift), inverse);
785
    }
786

  
787
    if(mirror_right){
788
        int r= 3*2*ref[w*ref_step];
789
        r += r>>4;
790
        r += r>>8;
791
        dst[w*dst_step] = LIFT(src[w*src_step], ((r+add)>>shift), inverse);
792
    }
793
}
794
#endif
795

  
796 763
#ifndef liftS
797 764
static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){
798 765
    const int mirror_left= !highpass;
......
840 807
}
841 808
#endif
842 809

  
843

  
844
static void inplace_lift(DWTELEM *dst, int width, int *coeffs, int n, int shift, int start, int inverse){
845
    int x, i;
846

  
847
    for(x=start; x<width; x+=2){
848
        int64_t sum=0;
849

  
850
        for(i=0; i<n; i++){
851
            int x2= x + 2*i - n + 1;
852
            if     (x2<     0) x2= -x2;
853
            else if(x2>=width) x2= 2*width-x2-2;
854
            sum += coeffs[i]*(int64_t)dst[x2];
855
        }
856
        if(inverse) dst[x] -= (sum + (1<<shift)/2)>>shift;
857
        else        dst[x] += (sum + (1<<shift)/2)>>shift;
858
    }
859
}
860

  
861
static void inplace_liftV(DWTELEM *dst, int width, int height, int stride, int *coeffs, int n, int shift, int start, int inverse){
862
    int x, y, i;
863
    for(y=start; y<height; y+=2){
864
        for(x=0; x<width; x++){
865
            int64_t sum=0;
866

  
867
            for(i=0; i<n; i++){
868
                int y2= y + 2*i - n + 1;
869
                if     (y2<      0) y2= -y2;
870
                else if(y2>=height) y2= 2*height-y2-2;
871
                sum += coeffs[i]*(int64_t)dst[x + y2*stride];
872
            }
873
            if(inverse) dst[x + y*stride] -= (sum + (1<<shift)/2)>>shift;
874
            else        dst[x + y*stride] += (sum + (1<<shift)/2)>>shift;
875
        }
876
    }
877
}
878

  
879
#define SCALEX 1
880
#define LX0 0
881
#define LX1 1
882

  
883
#if 0 // more accurate 9/7
884
#define N1 2
885
#define SHIFT1 14
886
#define COEFFS1 (int[]){-25987,-25987}
887
#define N2 2
888
#define SHIFT2 19
889
#define COEFFS2 (int[]){-27777,-27777}
890
#define N3 2
891
#define SHIFT3 15
892
#define COEFFS3 (int[]){28931,28931}
893
#define N4 2
894
#define SHIFT4 15
895
#define COEFFS4 (int[]){14533,14533}
896
#elif 1 // 13/7 CRF
897
#define N1 4
898
#define SHIFT1 4
899
#define COEFFS1 (int[]){1,-9,-9,1}
900
#define N2 4
901
#define SHIFT2 4
902
#define COEFFS2 (int[]){-1,5,5,-1}
903
#define N3 0
904
#define SHIFT3 1
905
#define COEFFS3 NULL
906
#define N4 0
907
#define SHIFT4 1
908
#define COEFFS4 NULL
909
#elif 1 // 3/5
910
#define LX0 1
911
#define LX1 0
912
#define SCALEX 0.5
913
#define N1 2
914
#define SHIFT1 1
915
#define COEFFS1 (int[]){1,1}
916
#define N2 2
917
#define SHIFT2 2
918
#define COEFFS2 (int[]){-1,-1}
919
#define N3 0
920
#define SHIFT3 0
921
#define COEFFS3 NULL
922
#define N4 0
923
#define SHIFT4 0
924
#define COEFFS4 NULL
925
#elif 1 // 11/5
926
#define N1 0
927
#define SHIFT1 1
928
#define COEFFS1 NULL
929
#define N2 2
930
#define SHIFT2 2
931
#define COEFFS2 (int[]){-1,-1}
932
#define N3 2
933
#define SHIFT3 0
934
#define COEFFS3 (int[]){-1,-1}
935
#define N4 4
936
#define SHIFT4 7
937
#define COEFFS4 (int[]){-5,29,29,-5}
938
#define SCALEX 4
939
#elif 1 // 9/7 CDF
940
#define N1 2
941
#define SHIFT1 7
942
#define COEFFS1 (int[]){-203,-203}
943
#define N2 2
944
#define SHIFT2 12
945
#define COEFFS2 (int[]){-217,-217}
946
#define N3 2
947
#define SHIFT3 7
948
#define COEFFS3 (int[]){113,113}
949
#define N4 2
950
#define SHIFT4 9
951
#define COEFFS4 (int[]){227,227}
952
#define SCALEX 1
953
#elif 1 // 7/5 CDF
954
#define N1 0
955
#define SHIFT1 1
956
#define COEFFS1 NULL
957
#define N2 2
958
#define SHIFT2 2
959
#define COEFFS2 (int[]){-1,-1}
960
#define N3 2
961
#define SHIFT3 0
962
#define COEFFS3 (int[]){-1,-1}
963
#define N4 2
964
#define SHIFT4 4
965
#define COEFFS4 (int[]){3,3}
966
#elif 1 // 9/7 MN
967
#define N1 4
968
#define SHIFT1 4
969
#define COEFFS1 (int[]){1,-9,-9,1}
970
#define N2 2
971
#define SHIFT2 2
972
#define COEFFS2 (int[]){1,1}
973
#define N3 0
974
#define SHIFT3 1
975
#define COEFFS3 NULL
976
#define N4 0
977
#define SHIFT4 1
978
#define COEFFS4 NULL
979
#else // 13/7 CRF
980
#define N1 4
981
#define SHIFT1 4
982
#define COEFFS1 (int[]){1,-9,-9,1}
983
#define N2 4
984
#define SHIFT2 4
985
#define COEFFS2 (int[]){-1,5,5,-1}
986
#define N3 0
987
#define SHIFT3 1
988
#define COEFFS3 NULL
989
#define N4 0
990
#define SHIFT4 1
991
#define COEFFS4 NULL
992
#endif
993
static void horizontal_decomposeX(DWTELEM *b, int width){
994
    DWTELEM temp[width];
995
    const int width2= width>>1;
996
    const int w2= (width+1)>>1;
997
    int x;
998

  
999
    inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 0);
1000
    inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 0);
1001
    inplace_lift(b, width, COEFFS3, N3, SHIFT3, LX1, 0);
1002
    inplace_lift(b, width, COEFFS4, N4, SHIFT4, LX0, 0);
1003

  
1004
    for(x=0; x<width2; x++){
1005
        temp[x   ]= b[2*x    ];
1006
        temp[x+w2]= b[2*x + 1];
1007
    }
1008
    if(width&1)
1009
        temp[x   ]= b[2*x    ];
1010
    memcpy(b, temp, width*sizeof(int));
1011
}
1012

  
1013
static void horizontal_composeX(IDWTELEM *b, int width){
1014
    IDWTELEM temp[width];
1015
    const int width2= width>>1;
1016
    int x;
1017
    const int w2= (width+1)>>1;
1018

  
1019
    memcpy(temp, b, width*sizeof(IDWTELEM));
1020
    for(x=0; x<width2; x++){
1021
        b[2*x    ]= temp[x   ];
1022
        b[2*x + 1]= temp[x+w2];
1023
    }
1024
    if(width&1)
1025
        b[2*x    ]= temp[x   ];
1026

  
1027
    inplace_lift(b, width, COEFFS4, N4, SHIFT4, LX0, 1);
1028
    inplace_lift(b, width, COEFFS3, N3, SHIFT3, LX1, 1);
1029
    inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 1);
1030
    inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 1);
1031
}
1032

  
1033
static void spatial_decomposeX(DWTELEM *buffer, int width, int height, int stride){
1034
    int x, y;
1035

  
1036
    for(y=0; y<height; y++){
1037
        for(x=0; x<width; x++){
1038
            buffer[y*stride + x] *= SCALEX;
1039
        }
1040
    }
1041

  
1042
    for(y=0; y<height; y++){
1043
        horizontal_decomposeX(buffer + y*stride, width);
1044
    }
1045

  
1046
    inplace_liftV(buffer, width, height, stride, COEFFS1, N1, SHIFT1, LX1, 0);
1047
    inplace_liftV(buffer, width, height, stride, COEFFS2, N2, SHIFT2, LX0, 0);
1048
    inplace_liftV(buffer, width, height, stride, COEFFS3, N3, SHIFT3, LX1, 0);
1049
    inplace_liftV(buffer, width, height, stride, COEFFS4, N4, SHIFT4, LX0, 0);
1050
}
1051

  
1052
static void spatial_composeX(IDWTELEM *buffer, int width, int height, int stride){
1053
    int x, y;
1054

  
1055
    inplace_liftV(buffer, width, height, stride, COEFFS4, N4, SHIFT4, LX0, 1);
1056
    inplace_liftV(buffer, width, height, stride, COEFFS3, N3, SHIFT3, LX1, 1);
1057
    inplace_liftV(buffer, width, height, stride, COEFFS2, N2, SHIFT2, LX0, 1);
1058
    inplace_liftV(buffer, width, height, stride, COEFFS1, N1, SHIFT1, LX1, 1);
1059

  
1060
    for(y=0; y<height; y++){
1061
        horizontal_composeX(buffer + y*stride, width);
1062
    }
1063

  
1064
    for(y=0; y<height; y++){
1065
        for(x=0; x<width; x++){
1066
            buffer[y*stride + x] /= SCALEX;
1067
        }
1068
    }
1069
}
1070

  
1071 810
static void horizontal_decompose53i(DWTELEM *b, int width){
1072 811
    DWTELEM temp[width];
1073 812
    const int width2= width>>1;
......
1163 902

  
1164 903
    lift (temp+w2, b    +1, b      , 1, 2, 2, width,  W_AM, W_AO, W_AS, 1, 1);
1165 904
    liftS(temp   , b      , temp+w2, 1, 2, 1, width,  W_BM, W_BO, W_BS, 0, 0);
1166
    lift5(b   +w2, temp+w2, temp   , 1, 1, 1, width,  W_CM, W_CO, W_CS, 1, 0);
905
    lift (b   +w2, temp+w2, temp   , 1, 1, 1, width,  W_CM, W_CO, W_CS, 1, 0);
1167 906
    lift (b      , temp   , b   +w2, 1, 1, 1, width,  W_DM, W_DO, W_DS, 0, 0);
1168 907
}
1169 908

  
......
1180 919
    int i;
1181 920

  
1182 921
    for(i=0; i<width; i++){
1183
#ifdef lift5
1184 922
        b1[i] += (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
1185
#else
1186
        int r= 3*(b0[i] + b2[i]);
1187
        r+= r>>4;
1188
        r+= r>>8;
1189
        b1[i] += (r+W_CO)>>W_CS;
1190
#endif
1191 923
    }
1192 924
}
1193 925

  
......
1253 985
        switch(type){
1254 986
        case DWT_97: spatial_decompose97i(buffer, width>>level, height>>level, stride<<level); break;
1255 987
        case DWT_53: spatial_decompose53i(buffer, width>>level, height>>level, stride<<level); break;
1256
        case DWT_X: spatial_decomposeX  (buffer, width>>level, height>>level, stride<<level); break;
1257 988
        }
1258 989
    }
1259 990
}
......
1391 1122
    const int w2= (width+1)>>1;
1392 1123

  
1393 1124
    inv_lift (temp   , b      , b   +w2, 1, 1, 1, width,  W_DM, W_DO, W_DS, 0, 1);
1394
    inv_lift5(temp+w2, b   +w2, temp   , 1, 1, 1, width,  W_CM, W_CO, W_CS, 1, 1);
1125
    inv_lift (temp+w2, b   +w2, temp   , 1, 1, 1, width,  W_CM, W_CO, W_CS, 1, 1);
1395 1126
    inv_liftS(b      , temp   , temp+w2, 2, 1, 1, width,  W_BM, W_BO, W_BS, 0, 1);
1396 1127
    inv_lift (b+1    , temp+w2, b      , 2, 1, 2, width,  W_AM, W_AO, W_AS, 1, 0);
1397 1128
}
......
1408 1139
    int i;
1409 1140

  
1410 1141
    for(i=0; i<width; i++){
1411
#ifdef lift5
1412 1142
        b1[i] -= (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
1413
#else
1414
        int r= 3*(b0[i] + b2[i]);
1415
        r+= r>>4;
1416
        r+= r>>8;
1417
        b1[i] -= (r+W_CO)>>W_CS;
1418
#endif
1419 1143
    }
1420 1144
}
1421 1145

  
......
1443 1167
    int i;
1444 1168

  
1445 1169
    for(i=0; i<width; i++){
1446
#ifndef lift5
1447
        int r;
1448
#endif
1449 1170
        b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
1450
#ifdef lift5
1451 1171
        b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
1452
#else
1453
        r= 3*(b2[i] + b4[i]);
1454
        r+= r>>4;
1455
        r+= r>>8;
1456
        b3[i] -= (r+W_CO)>>W_CS;
1457
#endif
1458 1172
#ifdef liftS
1459 1173
        b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS;
1460 1174
#else
......
1558 1272
        switch(type){
1559 1273
        case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
1560 1274
        case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
1561
        /* not slicified yet */
1562
        case DWT_X: /*spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;*/
1563
          av_log(NULL, AV_LOG_ERROR, "spatial_composeX neither buffered nor slicified yet.\n"); break;
1564 1275
        }
1565 1276
    }
1566 1277
}
......
1571 1282
        switch(type){
1572 1283
        case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
1573 1284
        case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
1574
        /* not slicified yet */
1575
        case DWT_X: spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;
1576 1285
        }
1577 1286
    }
1578 1287
}
......
1589 1298
                    break;
1590 1299
            case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
1591 1300
                    break;
1592
            case DWT_X: break;
1593 1301
            }
1594 1302
        }
1595 1303
    }
......
1607 1315
                    break;
1608 1316
            case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
1609 1317
                    break;
1610
            case DWT_X: break;
1611 1318
            }
1612 1319
        }
1613 1320
    }
1614 1321
}
1615 1322

  
1616 1323
static void ff_spatial_idwt(IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
1617
    if(type==2){
1618
        int level;
1619
        for(level=decomposition_count-1; level>=0; level--)
1620
            spatial_composeX  (buffer, width>>level, height>>level, stride<<level);
1621
    }else{
1622 1324
        dwt_compose_t cs[MAX_DECOMPOSITIONS];
1623 1325
        int y;
1624 1326
        ff_spatial_idwt_init(cs, buffer, width, height, stride, type, decomposition_count);
1625 1327
        for(y=0; y<height; y+=4)
1626 1328
            ff_spatial_idwt_slice(cs, buffer, width, height, stride, type, decomposition_count, y);
1627
    }
1628 1329
}
1629 1330

  
1630 1331
static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){

Also available in: Unified diff