vp9_invtrans.c 11.3 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9
10
 */

11
#include "vp9/common/vp9_invtrans.h"
12
#include "./vp9_rtcd.h"
John Koleszar's avatar
John Koleszar committed
13

14
15
16
17
18
void vp9_inverse_transform_b_4x4(MACROBLOCKD *xd, int eob,
                                 int16_t *dqcoeff, int16_t *diff,
                                 int pitch) {
  if (eob <= 1)
    xd->inv_txm4x4_1(dqcoeff, diff, pitch);
John Koleszar's avatar
John Koleszar committed
19
  else
20
    xd->inv_txm4x4(dqcoeff, diff, pitch);
John Koleszar's avatar
John Koleszar committed
21
22
}

23
void vp9_inverse_transform_mby_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
24
  int i;
John Koleszar's avatar
John Koleszar committed
25

John Koleszar's avatar
John Koleszar committed
26
  for (i = 0; i < 16; i++) {
27
    TX_TYPE tx_type = get_tx_type_4x4(xd, i);
28
    if (tx_type != DCT_DCT) {
29
30
      vp9_short_iht4x4(BLOCK_OFFSET(xd->plane[0].dqcoeff, i, 16),
                       xd->block[i].diff, 16, tx_type);
31
    } else {
John Koleszar's avatar
John Koleszar committed
32
33
      vp9_inverse_transform_b_4x4(xd,
                                  xd->plane[0].eobs[i],
34
                                  BLOCK_OFFSET(xd->plane[0].dqcoeff, i, 16),
35
                                  xd->block[i].diff, 32);
36
    }
John Koleszar's avatar
John Koleszar committed
37
  }
John Koleszar's avatar
John Koleszar committed
38
}
39

40
void vp9_inverse_transform_mbuv_4x4(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
41
  int i;
42

43
  for (i = 16; i < 20; i++) {
John Koleszar's avatar
John Koleszar committed
44
    vp9_inverse_transform_b_4x4(xd, xd->plane[1].eobs[i - 16],
45
46
47
48
                                BLOCK_OFFSET(xd->plane[1].dqcoeff, i - 16, 16),
                                xd->block[i].diff, 16);
  }
  for (i = 20; i < 24; i++) {
John Koleszar's avatar
John Koleszar committed
49
    vp9_inverse_transform_b_4x4(xd, xd->plane[2].eobs[i - 20],
50
                                BLOCK_OFFSET(xd->plane[2].dqcoeff, i - 20, 16),
51
                                xd->block[i].diff, 16);
John Koleszar's avatar
John Koleszar committed
52
  }
John Koleszar's avatar
John Koleszar committed
53
54
}

55
56
57
void vp9_inverse_transform_mb_4x4(MACROBLOCKD *xd) {
  vp9_inverse_transform_mby_4x4(xd);
  vp9_inverse_transform_mbuv_4x4(xd);
John Koleszar's avatar
John Koleszar committed
58
}
59

60
void vp9_inverse_transform_b_8x8(int16_t *input_dqcoeff, int16_t *output_coeff,
61
                                 int pitch) {
62
  vp9_short_idct8x8(input_dqcoeff, output_coeff, pitch);
63
64
}

65
void vp9_inverse_transform_mby_8x8(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
66
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
67
  BLOCKD *blockd = xd->block;
John Koleszar's avatar
John Koleszar committed
68
69

  for (i = 0; i < 9; i += 8) {
70
    TX_TYPE tx_type = get_tx_type_8x8(xd, i);
71
    if (tx_type != DCT_DCT) {
72
73
      vp9_short_iht8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, i, 16),
                       xd->block[i].diff, 16, tx_type);
74
    } else {
75
      vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, i, 16),
76
77
                                  &blockd[i].diff[0], 32);
    }
John Koleszar's avatar
John Koleszar committed
78
79
  }
  for (i = 2; i < 11; i += 8) {
80
    TX_TYPE tx_type = get_tx_type_8x8(xd, i);
81
    if (tx_type != DCT_DCT) {
82
83
      vp9_short_iht8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, i + 2, 16),
                       xd->block[i].diff, 16, tx_type);
84
    } else {
85
      vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, i + 2, 16),
86
87
                                  &blockd[i].diff[0], 32);
    }
John Koleszar's avatar
John Koleszar committed
88
  }
89
}
90

91
void vp9_inverse_transform_mbuv_8x8(MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
92
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
93
  BLOCKD *blockd = xd->block;
94

95
96
97
98
99
100
  for (i = 16; i < 20; i += 4) {
    vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[1].dqcoeff, i - 16, 16),
                                &blockd[i].diff[0], 16);
  }
  for (i = 20; i < 24; i += 4) {
    vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[2].dqcoeff, i - 20, 16),
Paul Wilkins's avatar
Paul Wilkins committed
101
                                &blockd[i].diff[0], 16);
John Koleszar's avatar
John Koleszar committed
102
  }
103
104
}

105
106
107
void vp9_inverse_transform_mb_8x8(MACROBLOCKD *xd) {
  vp9_inverse_transform_mby_8x8(xd);
  vp9_inverse_transform_mbuv_8x8(xd);
108
109
}

110
111
void vp9_inverse_transform_b_16x16(int16_t *input_dqcoeff,
                                   int16_t *output_coeff, int pitch) {
112
  vp9_short_idct16x16(input_dqcoeff, output_coeff, pitch);
Daniel Kang's avatar
Daniel Kang committed
113
114
}

115
void vp9_inverse_transform_mby_16x16(MACROBLOCKD *xd) {
116
  BLOCKD *bd = &xd->block[0];
117
  TX_TYPE tx_type = get_tx_type_16x16(xd, 0);
118
  if (tx_type != DCT_DCT) {
119
120
    vp9_short_iht16x16(BLOCK_OFFSET(xd->plane[0].dqcoeff, 0, 16),
                       bd->diff, 16, tx_type);
121
  } else {
122
    vp9_inverse_transform_b_16x16(BLOCK_OFFSET(xd->plane[0].dqcoeff, 0, 16),
123
124
                                  &xd->block[0].diff[0], 32);
  }
Daniel Kang's avatar
Daniel Kang committed
125
126
}

127
128
129
void vp9_inverse_transform_mb_16x16(MACROBLOCKD *xd) {
  vp9_inverse_transform_mby_16x16(xd);
  vp9_inverse_transform_mbuv_8x8(xd);
Daniel Kang's avatar
Daniel Kang committed
130
}
131

132
void vp9_inverse_transform_sby_32x32(MACROBLOCKD *xd) {
133
  vp9_short_idct32x32(BLOCK_OFFSET(xd->plane[0].dqcoeff, 0, 16), xd->diff, 64);
134
135
136
137
138
139
140
}

void vp9_inverse_transform_sby_16x16(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 4; n++) {
    const int x_idx = n & 1, y_idx = n >> 1;
141
    const TX_TYPE tx_type = get_tx_type_16x16(xd, (y_idx * 8 + x_idx) * 4);
142

143
    if (tx_type == DCT_DCT) {
144
      vp9_inverse_transform_b_16x16(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 256),
145
146
147
                                    xd->diff + x_idx * 16 + y_idx * 32 * 16,
                                    64);
    } else {
148
      vp9_short_iht16x16(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 256),
149
150
                         xd->diff + x_idx * 16 + y_idx * 32 * 16, 32, tx_type);
    }
151
152
153
154
155
156
157
158
  }
}

void vp9_inverse_transform_sby_8x8(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 16; n++) {
    const int x_idx = n & 3, y_idx = n >> 2;
159
    const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 8 + x_idx) * 2);
160

161
    if (tx_type == DCT_DCT) {
162
      vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 64),
163
164
                                  xd->diff + x_idx * 8 + y_idx * 32 * 8, 64);
    } else {
165
      vp9_short_iht8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 64),
166
167
                       xd->diff + x_idx * 8 + y_idx * 32 * 8, 32, tx_type);
    }
168
169
170
171
172
173
174
175
  }
}

void vp9_inverse_transform_sby_4x4(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 64; n++) {
    const int x_idx = n & 7, y_idx = n >> 3;
176
    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 8 + x_idx);
177

178
    if (tx_type == DCT_DCT) {
John Koleszar's avatar
John Koleszar committed
179
      vp9_inverse_transform_b_4x4(xd, xd->plane[0].eobs[n],
180
                                  BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 16),
181
182
                                  xd->diff + x_idx * 4 + y_idx * 4 * 32, 64);
    } else {
183
      vp9_short_iht4x4(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 16),
184
185
                       xd->diff + x_idx * 4 + y_idx * 4 * 32, 32, tx_type);
    }
186
187
188
189
  }
}

void vp9_inverse_transform_sbuv_16x16(MACROBLOCKD *xd) {
190
  vp9_inverse_transform_b_16x16(xd->plane[1].dqcoeff,
191
                                xd->diff + 1024, 32);
192
  vp9_inverse_transform_b_16x16(xd->plane[2].dqcoeff,
193
194
195
196
197
198
199
200
201
                                xd->diff + 1280, 32);
}

void vp9_inverse_transform_sbuv_8x8(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 4; n++) {
    const int x_idx = n & 1, y_idx = n >> 1;

202
    vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[1].dqcoeff, n, 64),
203
204
                                xd->diff + 1024 + x_idx * 8 + y_idx * 16 * 8,
                                32);
205
    vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[2].dqcoeff, n, 64),
206
207
208
209
210
211
212
213
214
215
216
                                xd->diff + 1280 + x_idx * 8 + y_idx * 16 * 8,
                                32);
  }
}

void vp9_inverse_transform_sbuv_4x4(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 16; n++) {
    const int x_idx = n & 3, y_idx = n >> 2;

John Koleszar's avatar
John Koleszar committed
217
    vp9_inverse_transform_b_4x4(xd, xd->plane[1].eobs[n],
218
                                BLOCK_OFFSET(xd->plane[1].dqcoeff, n, 16),
219
220
                                xd->diff + 1024 + x_idx * 4 + y_idx * 16 * 4,
                                32);
John Koleszar's avatar
John Koleszar committed
221
    vp9_inverse_transform_b_4x4(xd, xd->plane[2].eobs[n],
222
                                BLOCK_OFFSET(xd->plane[2].dqcoeff, n, 16),
223
224
225
                                xd->diff + 1280 + x_idx * 4 + y_idx * 16 * 4,
                                32);
  }
226
227
}

228
229
230
231
232
233
void vp9_inverse_transform_sb64y_32x32(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 4; n++) {
    const int x_idx = n & 1, y_idx = n >> 1;

234
    vp9_short_idct32x32(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 1024),
235
236
237
238
239
240
241
242
243
                        xd->diff + x_idx * 32 + y_idx * 32 * 64, 128);
  }
}

void vp9_inverse_transform_sb64y_16x16(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 16; n++) {
    const int x_idx = n & 3, y_idx = n >> 2;
244
    const TX_TYPE tx_type = get_tx_type_16x16(xd, (y_idx * 16 + x_idx) * 4);
245

246
    if (tx_type == DCT_DCT) {
247
      vp9_inverse_transform_b_16x16(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 256),
248
249
250
                                    xd->diff + x_idx * 16 + y_idx * 64 * 16,
                                    128);
    } else {
251
      vp9_short_iht16x16(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 256),
252
253
                         xd->diff + x_idx * 16 + y_idx * 64 * 16, 64, tx_type);
    }
254
255
256
257
258
259
260
261
  }
}

void vp9_inverse_transform_sb64y_8x8(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 64; n++) {
    const int x_idx = n & 7, y_idx = n >> 3;
262
    const TX_TYPE tx_type = get_tx_type_8x8(xd, (y_idx * 16 + x_idx) * 2);
263

264
    if (tx_type == DCT_DCT) {
265
      vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 64),
266
267
                                  xd->diff + x_idx * 8 + y_idx * 64 * 8, 128);
    } else {
268
      vp9_short_iht8x8(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 64),
269
270
                       xd->diff + x_idx * 8 + y_idx * 64 * 8, 64, tx_type);
    }
271
272
273
274
275
276
277
278
  }
}

void vp9_inverse_transform_sb64y_4x4(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 256; n++) {
    const int x_idx = n & 15, y_idx = n >> 4;
279
    const TX_TYPE tx_type = get_tx_type_4x4(xd, y_idx * 16 + x_idx);
280

281
    if (tx_type == DCT_DCT) {
John Koleszar's avatar
John Koleszar committed
282
      vp9_inverse_transform_b_4x4(xd, xd->plane[0].eobs[n],
283
                                  BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 16),
284
285
                                  xd->diff + x_idx * 4 + y_idx * 4 * 64, 128);
    } else {
286
      vp9_short_iht4x4(BLOCK_OFFSET(xd->plane[0].dqcoeff, n, 16),
287
288
                       xd->diff + x_idx * 4 + y_idx * 4 * 64, 64, tx_type);
    }
289
290
291
292
  }
}

void vp9_inverse_transform_sb64uv_32x32(MACROBLOCKD *xd) {
293
  vp9_short_idct32x32(xd->plane[1].dqcoeff,
294
                      xd->diff + 4096, 64);
295
  vp9_short_idct32x32(xd->plane[2].dqcoeff,
296
297
298
299
300
301
302
303
304
                      xd->diff + 4096 + 1024, 64);
}

void vp9_inverse_transform_sb64uv_16x16(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 4; n++) {
    const int x_idx = n & 1, y_idx = n >> 1, off = x_idx * 16 + y_idx * 32 * 16;

305
    vp9_inverse_transform_b_16x16(BLOCK_OFFSET(xd->plane[1].dqcoeff, n, 256),
306
                                  xd->diff + 4096 + off, 64);
307
    vp9_inverse_transform_b_16x16(BLOCK_OFFSET(xd->plane[2].dqcoeff, n, 256),
308
309
310
311
312
313
314
315
316
317
                                  xd->diff + 4096 + 1024 + off, 64);
  }
}

void vp9_inverse_transform_sb64uv_8x8(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 16; n++) {
    const int x_idx = n & 3, y_idx = n >> 2, off = x_idx * 8 + y_idx * 32 * 8;

318
    vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[1].dqcoeff, n, 64),
319
                                xd->diff + 4096 + off, 64);
320
    vp9_inverse_transform_b_8x8(BLOCK_OFFSET(xd->plane[2].dqcoeff, n, 64),
321
322
323
324
325
326
327
328
329
330
                                xd->diff + 4096 + 1024 + off, 64);
  }
}

void vp9_inverse_transform_sb64uv_4x4(MACROBLOCKD *xd) {
  int n;

  for (n = 0; n < 64; n++) {
    const int x_idx = n & 7, y_idx = n >> 3, off = x_idx * 4 + y_idx * 32 * 4;

John Koleszar's avatar
John Koleszar committed
331
    vp9_inverse_transform_b_4x4(xd, xd->plane[1].eobs[n],
332
                                BLOCK_OFFSET(xd->plane[1].dqcoeff, n, 16),
333
                                xd->diff + 4096 + off, 64);
John Koleszar's avatar
John Koleszar committed
334
    vp9_inverse_transform_b_4x4(xd, xd->plane[2].eobs[n],
335
                                BLOCK_OFFSET(xd->plane[2].dqcoeff, n, 16),
336
337
                                xd->diff + 4096 + 1024 + off, 64);
  }
338
}