Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
  3.  * Copyright (C) 2008 David Conrad
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include "libavutil/attributes.h"
  23. #include "libavutil/avassert.h"
  24. #include "libavutil/common.h"
  25. #include "dsputil.h"
  26. #include "dirac_dwt.h"
  27. #include "libavcodec/x86/dirac_dwt.h"
  28.  
  29.  
  30. static inline int mirror(int v, int m)
  31. {
  32.     while ((unsigned)v > (unsigned)m) {
  33.         v = -v;
  34.         if (v < 0)
  35.             v += 2 * m;
  36.     }
  37.     return v;
  38. }
  39.  
  40. static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  41.                                   int width)
  42. {
  43.     int i;
  44.  
  45.     for (i = 0; i < width; i++)
  46.         b1[i] -= (b0[i] + b2[i] + 2) >> 2;
  47. }
  48.  
  49.  
  50. static av_always_inline
  51. void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
  52. {
  53.     int i;
  54.     for (i = 0; i < w2; i++) {
  55.         dst[2*i  ] = (src0[i] + add) >> shift;
  56.         dst[2*i+1] = (src1[i] + add) >> shift;
  57.     }
  58. }
  59.  
  60. static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
  61. {
  62.     const int w2 = w >> 1;
  63.     int x;
  64.  
  65.     temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
  66.     for (x = 1; x < w2; x++) {
  67.         temp[x     ] = COMPOSE_53iL0     (b[x+w2-1], b[x     ], b[x+w2]);
  68.         temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
  69.     }
  70.     temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
  71.  
  72.     interleave(b, temp, temp+w2, w2, 1, 1);
  73. }
  74.  
  75. static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
  76. {
  77.     const int w2 = w >> 1;
  78.     int x;
  79.  
  80.     tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
  81.     for (x = 1; x < w2; x++)
  82.         tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
  83.  
  84.     // extend the edges
  85.     tmp[-1]   = tmp[0];
  86.     tmp[w2+1] = tmp[w2] = tmp[w2-1];
  87.  
  88.     for (x = 0; x < w2; x++) {
  89.         b[2*x  ] = (tmp[x] + 1)>>1;
  90.         b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
  91.     }
  92. }
  93.  
  94. static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
  95. {
  96.     const int w2 = w >> 1;
  97.     int x;
  98.  
  99.     tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2  ], b[w2+1]);
  100.     tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
  101.     for (x = 2; x < w2-1; x++)
  102.         tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
  103.     tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
  104.  
  105.     // extend the edges
  106.     tmp[-1]   = tmp[0];
  107.     tmp[w2+1] = tmp[w2] = tmp[w2-1];
  108.  
  109.     for (x = 0; x < w2; x++) {
  110.         b[2*x  ] = (tmp[x] + 1)>>1;
  111.         b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
  112.     }
  113. }
  114.  
  115. static av_always_inline
  116. void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
  117. {
  118.     const int w2 = w >> 1;
  119.     int x;
  120.  
  121.     for (x = 0; x < w2; x++) {
  122.         temp[x   ] = COMPOSE_HAARiL0(b[x   ], b[x+w2]);
  123.         temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
  124.     }
  125.  
  126.     interleave(b, temp, temp+w2, w2, shift, shift);
  127. }
  128.  
  129. static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
  130. {
  131.     horizontal_compose_haari(b, temp, w, 0);
  132. }
  133.  
  134. static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
  135. {
  136.     horizontal_compose_haari(b, temp, w, 1);
  137. }
  138.  
  139. static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
  140. {
  141.     const int w2 = w >> 1;
  142.     int i, x;
  143.     IDWTELEM v[8];
  144.  
  145.     for (x = 0; x < w2; x++) {
  146.         for (i = 0; i < 8; i++)
  147.             v[i] = b[av_clip(x-3+i, 0, w2-1)];
  148.         tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
  149.     }
  150.  
  151.     for (x = 0; x < w2; x++) {
  152.         for (i = 0; i < 8; i++)
  153.             v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
  154.         tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
  155.     }
  156.  
  157.     interleave(b, tmp+w2, tmp, w2, 0, 0);
  158. }
  159.  
  160. static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
  161. {
  162.     const int w2 = w >> 1;
  163.     int x, b0, b1, b2;
  164.  
  165.     temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
  166.     for (x = 1; x < w2; x++) {
  167.         temp[x     ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x     ], b[x+w2]);
  168.         temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
  169.     }
  170.     temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
  171.  
  172.     // second stage combined with interleave and shift
  173.     b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
  174.     b[0] = (b0 + 1) >> 1;
  175.     for (x = 1; x < w2; x++) {
  176.         b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x     ], temp[x+w2]);
  177.         b1 = COMPOSE_DAUB97iH0(          b0, temp[x+w2-1], b2        );
  178.         b[2*x-1] = (b1 + 1) >> 1;
  179.         b[2*x  ] = (b2 + 1) >> 1;
  180.         b0 = b2;
  181.     }
  182.     b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
  183. }
  184.  
  185. static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
  186. {
  187.     int i;
  188.  
  189.     for(i=0; i<width; i++){
  190.         b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
  191.     }
  192. }
  193.  
  194. static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  195.                                   IDWTELEM *b3, IDWTELEM *b4, int width)
  196. {
  197.     int i;
  198.  
  199.     for(i=0; i<width; i++){
  200.         b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
  201.     }
  202. }
  203.  
  204. static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  205.                                       IDWTELEM *b3, IDWTELEM *b4, int width)
  206. {
  207.     int i;
  208.  
  209.     for(i=0; i<width; i++){
  210.         b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
  211.     }
  212. }
  213.  
  214. static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
  215. {
  216.     int i;
  217.  
  218.     for (i = 0; i < width; i++) {
  219.         b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
  220.         b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
  221.     }
  222. }
  223.  
  224. static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
  225. {
  226.     int i;
  227.  
  228.     for(i=0; i<width; i++){
  229.         dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
  230.     }
  231. }
  232.  
  233. static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
  234. {
  235.     int i;
  236.  
  237.     for(i=0; i<width; i++){
  238.         dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
  239.     }
  240. }
  241.  
  242. static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
  243. {
  244.     int i;
  245.  
  246.     for(i=0; i<width; i++){
  247.         b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
  248.     }
  249. }
  250.  
  251. static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
  252. {
  253.     int i;
  254.  
  255.     for(i=0; i<width; i++){
  256.         b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
  257.     }
  258. }
  259.  
  260. static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
  261. {
  262.     int i;
  263.  
  264.     for(i=0; i<width; i++){
  265.         b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
  266.     }
  267. }
  268.  
  269. static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
  270. {
  271.     int i;
  272.  
  273.     for(i=0; i<width; i++){
  274.         b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
  275.     }
  276. }
  277.  
  278.  
  279. static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
  280. {
  281.     vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
  282.     vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
  283.     DWTCompose *cs = d->cs + level;
  284.  
  285.     int i, y = cs->y;
  286.     IDWTELEM *b[8];
  287.     for (i = 0; i < 6; i++)
  288.         b[i] = cs->b[i];
  289.     b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
  290.     b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
  291.  
  292.         if(y+5<(unsigned)height) vertical_compose_l0(      b[5], b[6], b[7],       width);
  293.         if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
  294.  
  295.         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
  296.         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
  297.  
  298.     for (i = 0; i < 6; i++)
  299.         cs->b[i] = b[i+2];
  300.     cs->y += 2;
  301. }
  302.  
  303. static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
  304. {
  305.     vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
  306.     vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
  307.     DWTCompose *cs = d->cs + level;
  308.  
  309.     int y= cs->y;
  310.     IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
  311.     b[2] = d->buffer + mirror(y+1, height-1)*stride;
  312.     b[3] = d->buffer + mirror(y+2, height-1)*stride;
  313.  
  314.         if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
  315.         if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
  316.  
  317.         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
  318.         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
  319.  
  320.     cs->b[0] = b[2];
  321.     cs->b[1] = b[3];
  322.     cs->y += 2;
  323. }
  324.  
  325.  
  326. static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
  327. {
  328.     vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
  329.     vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
  330.     DWTCompose *cs = d->cs + level;
  331.  
  332.     int i, y = cs->y;
  333.     IDWTELEM *b[10];
  334.     for (i = 0; i < 8; i++)
  335.         b[i] = cs->b[i];
  336.     b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
  337.     b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
  338.  
  339.         if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
  340.         if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
  341.  
  342.         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
  343.         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
  344.  
  345.     for (i = 0; i < 8; i++)
  346.         cs->b[i] = b[i+2];
  347.     cs->y += 2;
  348. }
  349.  
  350. // haar makes the assumption that height is even (always true for dirac)
  351. static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
  352. {
  353.     vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
  354.     int y = d->cs[level].y;
  355.     IDWTELEM *b0 = d->buffer + (y-1)*stride;
  356.     IDWTELEM *b1 = d->buffer + (y  )*stride;
  357.  
  358.     vertical_compose(b0, b1, width);
  359.     d->horizontal_compose(b0, d->temp, width);
  360.     d->horizontal_compose(b1, d->temp, width);
  361.  
  362.     d->cs[level].y += 2;
  363. }
  364.  
  365. // Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
  366. // Fortunately, this filter isn't used in practice.
  367. static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
  368. {
  369.     vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
  370.     vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
  371.     int i, y;
  372.     IDWTELEM *b[8];
  373.  
  374.     for (y = 1; y < height; y += 2) {
  375.         for (i = 0; i < 8; i++)
  376.             b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
  377.         vertical_compose_h0(d->buffer + y*stride, b, width);
  378.     }
  379.  
  380.     for (y = 0; y < height; y += 2) {
  381.         for (i = 0; i < 8; i++)
  382.             b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
  383.         vertical_compose_l0(d->buffer + y*stride, b, width);
  384.     }
  385.  
  386.     for (y = 0; y < height; y++)
  387.         d->horizontal_compose(d->buffer + y*stride, d->temp, width);
  388.  
  389.     d->cs[level].y = height+1;
  390. }
  391.  
  392. static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
  393. {
  394.     vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
  395.     vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
  396.     vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
  397.     vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
  398.     DWTCompose *cs = d->cs + level;
  399.  
  400.     int i, y = cs->y;
  401.     IDWTELEM *b[6];
  402.     for (i = 0; i < 4; i++)
  403.         b[i] = cs->b[i];
  404.     b[4] = d->buffer + mirror(y+3, height-1)*stride;
  405.     b[5] = d->buffer + mirror(y+4, height-1)*stride;
  406.  
  407.         if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
  408.         if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
  409.         if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
  410.         if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
  411.  
  412.         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
  413.         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
  414.  
  415.     for (i = 0; i < 4; i++)
  416.         cs->b[i] = b[i+2];
  417.     cs->y += 2;
  418. }
  419.  
  420.  
  421. static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
  422. {
  423.     cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
  424.     cs->b[1] = buffer + mirror(-3  , height-1)*stride;
  425.     cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
  426.     cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
  427.     cs->y = -3;
  428. }
  429.  
  430. static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
  431. {
  432.     cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
  433.     cs->b[1] = buffer + mirror(-1  , height-1)*stride;
  434.     cs->y = -1;
  435. }
  436.  
  437. static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
  438. {
  439.     cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
  440.     cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
  441.     cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
  442.     cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
  443.     cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
  444.     cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
  445.     cs->y = -5;
  446. }
  447.  
  448. static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
  449. {
  450.     cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
  451.     cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
  452.     cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
  453.     cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
  454.     cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
  455.     cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
  456.     cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
  457.     cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
  458.     cs->y = -5;
  459. }
  460.  
  461. int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
  462.                           int stride, enum dwt_type type, int decomposition_count,
  463.                           IDWTELEM *temp)
  464. {
  465.     int level;
  466.  
  467.     d->buffer = buffer;
  468.     d->width = width;
  469.     d->height = height;
  470.     d->stride = stride;
  471.     d->decomposition_count = decomposition_count;
  472.     d->temp = temp + 8;
  473.  
  474.     for(level=decomposition_count-1; level>=0; level--){
  475.         int hl = height >> level;
  476.         int stride_l = stride << level;
  477.  
  478.         switch(type){
  479.         case DWT_DIRAC_DD9_7:
  480.             spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
  481.             break;
  482.         case DWT_DIRAC_LEGALL5_3:
  483.             spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
  484.             break;
  485.         case DWT_DIRAC_DD13_7:
  486.             spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
  487.             break;
  488.         case DWT_DIRAC_HAAR0:
  489.         case DWT_DIRAC_HAAR1:
  490.             d->cs[level].y = 1;
  491.             break;
  492.         case DWT_DIRAC_DAUB9_7:
  493.             spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
  494.             break;
  495.         default:
  496.             d->cs[level].y = 0;
  497.             break;
  498.         }
  499.     }
  500.  
  501.     switch (type) {
  502.     case DWT_DIRAC_DD9_7:
  503.         d->spatial_compose = spatial_compose_dd97i_dy;
  504.         d->vertical_compose_l0 = (void*)vertical_compose53iL0;
  505.         d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
  506.         d->horizontal_compose = horizontal_compose_dd97i;
  507.         d->support = 7;
  508.         break;
  509.     case DWT_DIRAC_LEGALL5_3:
  510.         d->spatial_compose = spatial_compose_dirac53i_dy;
  511.         d->vertical_compose_l0 = (void*)vertical_compose53iL0;
  512.         d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0;
  513.         d->horizontal_compose = horizontal_compose_dirac53i;
  514.         d->support = 3;
  515.         break;
  516.     case DWT_DIRAC_DD13_7:
  517.         d->spatial_compose = spatial_compose_dd137i_dy;
  518.         d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0;
  519.         d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
  520.         d->horizontal_compose = horizontal_compose_dd137i;
  521.         d->support = 7;
  522.         break;
  523.     case DWT_DIRAC_HAAR0:
  524.     case DWT_DIRAC_HAAR1:
  525.         d->spatial_compose = spatial_compose_haari_dy;
  526.         d->vertical_compose = (void*)vertical_compose_haar;
  527.         if (type == DWT_DIRAC_HAAR0)
  528.             d->horizontal_compose = horizontal_compose_haar0i;
  529.         else
  530.             d->horizontal_compose = horizontal_compose_haar1i;
  531.         d->support = 1;
  532.         break;
  533.     case DWT_DIRAC_FIDELITY:
  534.         d->spatial_compose = spatial_compose_fidelity;
  535.         d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0;
  536.         d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0;
  537.         d->horizontal_compose = horizontal_compose_fidelityi;
  538.         break;
  539.     case DWT_DIRAC_DAUB9_7:
  540.         d->spatial_compose = spatial_compose_daub97i_dy;
  541.         d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0;
  542.         d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0;
  543.         d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1;
  544.         d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1;
  545.         d->horizontal_compose = horizontal_compose_daub97i;
  546.         d->support = 5;
  547.         break;
  548.     default:
  549.         av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
  550.         return -1;
  551.     }
  552.  
  553.     if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
  554.  
  555.     return 0;
  556. }
  557.  
  558. void ff_spatial_idwt_slice2(DWTContext *d, int y)
  559. {
  560.     int level, support = d->support;
  561.  
  562.     for (level = d->decomposition_count-1; level >= 0; level--) {
  563.         int wl = d->width  >> level;
  564.         int hl = d->height >> level;
  565.         int stride_l = d->stride << level;
  566.  
  567.         while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
  568.             d->spatial_compose(d, level, wl, hl, stride_l);
  569.     }
  570. }
  571.  
  572.