00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00029 #define BITSTREAM_READER_LE
00030 #include "avcodec.h"
00031 #include "get_bits.h"
00032 #include "ivi_common.h"
00033 #include "libavutil/common.h"
00034 #include "ivi_dsp.h"
00035
00036 extern const IVIHuffDesc ff_ivi_mb_huff_desc[8];
00037 extern const IVIHuffDesc ff_ivi_blk_huff_desc[8];
00038
00039 VLC ff_ivi_mb_vlc_tabs [8];
00040 VLC ff_ivi_blk_vlc_tabs[8];
00041
00046 static uint16_t inv_bits(uint16_t val, int nbits)
00047 {
00048 uint16_t res;
00049
00050 if (nbits <= 8) {
00051 res = av_reverse[val] >> (8-nbits);
00052 } else
00053 res = ((av_reverse[val & 0xFF] << 8) + (av_reverse[val >> 8])) >> (16-nbits);
00054
00055 return res;
00056 }
00057
00058 int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag)
00059 {
00060 int pos, i, j, codes_per_row, prefix, not_last_row;
00061 uint16_t codewords[256];
00062 uint8_t bits[256];
00063
00064 pos = 0;
00065
00066 for (i = 0; i < cb->num_rows; i++) {
00067 codes_per_row = 1 << cb->xbits[i];
00068 not_last_row = (i != cb->num_rows - 1);
00069 prefix = ((1 << i) - 1) << (cb->xbits[i] + not_last_row);
00070
00071 for (j = 0; j < codes_per_row; j++) {
00072 if (pos >= 256)
00073 break;
00074
00075 bits[pos] = i + cb->xbits[i] + not_last_row;
00076 if (bits[pos] > IVI_VLC_BITS)
00077 return -1;
00078
00079 codewords[pos] = inv_bits((prefix | j), bits[pos]);
00080 if (!bits[pos])
00081 bits[pos] = 1;
00082
00083 pos++;
00084 }
00085 }
00086
00087
00088 return init_vlc(vlc, IVI_VLC_BITS, pos, bits, 1, 1, codewords, 2, 2,
00089 (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE);
00090 }
00091
00092 void ff_ivi_init_static_vlc(void)
00093 {
00094 int i;
00095 static VLC_TYPE table_data[8192 * 16][2];
00096 static int initialized_vlcs = 0;
00097
00098 if (initialized_vlcs)
00099 return;
00100 for (i = 0; i < 8; i++) {
00101 ff_ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192;
00102 ff_ivi_mb_vlc_tabs[i].table_allocated = 8192;
00103 ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &ff_ivi_mb_vlc_tabs[i], 1);
00104 ff_ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192;
00105 ff_ivi_blk_vlc_tabs[i].table_allocated = 8192;
00106 ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ff_ivi_blk_vlc_tabs[i], 1);
00107 }
00108 initialized_vlcs = 1;
00109 }
00110
00111 int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab,
00112 IVIHuffTab *huff_tab, AVCodecContext *avctx)
00113 {
00114 int i, result;
00115 IVIHuffDesc new_huff;
00116
00117 if (!desc_coded) {
00118
00119 huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[7]
00120 : &ff_ivi_mb_vlc_tabs [7];
00121 } else {
00122 huff_tab->tab_sel = get_bits(gb, 3);
00123 if (huff_tab->tab_sel == 7) {
00124
00125 new_huff.num_rows = get_bits(gb, 4);
00126 if (!new_huff.num_rows) {
00127 av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n");
00128 return AVERROR_INVALIDDATA;
00129 }
00130
00131 for (i = 0; i < new_huff.num_rows; i++)
00132 new_huff.xbits[i] = get_bits(gb, 4);
00133
00134
00135 if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) {
00136 ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff);
00137
00138 if (huff_tab->cust_tab.table)
00139 ff_free_vlc(&huff_tab->cust_tab);
00140 result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc,
00141 &huff_tab->cust_tab, 0);
00142 if (result) {
00143 huff_tab->cust_desc.num_rows = 0;
00144 av_log(avctx, AV_LOG_ERROR,
00145 "Error while initializing custom vlc table!\n");
00146 return result;
00147 }
00148 }
00149 huff_tab->tab = &huff_tab->cust_tab;
00150 } else {
00151
00152 huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[huff_tab->tab_sel]
00153 : &ff_ivi_mb_vlc_tabs [huff_tab->tab_sel];
00154 }
00155 }
00156
00157 return 0;
00158 }
00159
00160 int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2)
00161 {
00162 return desc1->num_rows != desc2->num_rows
00163 || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows);
00164 }
00165
00166 void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src)
00167 {
00168 dst->num_rows = src->num_rows;
00169 memcpy(dst->xbits, src->xbits, src->num_rows);
00170 }
00171
00172 int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg)
00173 {
00174 int p, b;
00175 uint32_t b_width, b_height, align_fac, width_aligned, height_aligned, buf_size;
00176 IVIBandDesc *band;
00177
00178 ff_ivi_free_buffers(planes);
00179
00180
00181 planes[0].width = cfg->pic_width;
00182 planes[0].height = cfg->pic_height;
00183 planes[0].num_bands = cfg->luma_bands;
00184
00185
00186 planes[1].width = planes[2].width = (cfg->pic_width + 3) >> 2;
00187 planes[1].height = planes[2].height = (cfg->pic_height + 3) >> 2;
00188 planes[1].num_bands = planes[2].num_bands = cfg->chroma_bands;
00189
00190 for (p = 0; p < 3; p++) {
00191 planes[p].bands = av_mallocz(planes[p].num_bands * sizeof(IVIBandDesc));
00192 if (!planes[p].bands)
00193 return AVERROR(ENOMEM);
00194
00195
00196
00197
00198 b_width = planes[p].num_bands == 1 ? planes[p].width : (planes[p].width + 1) >> 1;
00199 b_height = planes[p].num_bands == 1 ? planes[p].height : (planes[p].height + 1) >> 1;
00200
00201
00202
00203 align_fac = p ? 8 : 16;
00204 width_aligned = FFALIGN(b_width , align_fac);
00205 height_aligned = FFALIGN(b_height, align_fac);
00206 buf_size = width_aligned * height_aligned * sizeof(int16_t);
00207
00208 for (b = 0; b < planes[p].num_bands; b++) {
00209 band = &planes[p].bands[b];
00210 band->plane = p;
00211 band->band_num = b;
00212 band->width = b_width;
00213 band->height = b_height;
00214 band->pitch = width_aligned;
00215 band->aheight = height_aligned;
00216 band->bufs[0] = av_mallocz(buf_size);
00217 band->bufs[1] = av_mallocz(buf_size);
00218 if (!band->bufs[0] || !band->bufs[1])
00219 return AVERROR(ENOMEM);
00220
00221
00222 if (cfg->luma_bands > 1) {
00223 band->bufs[2] = av_mallocz(buf_size);
00224 if (!band->bufs[2])
00225 return AVERROR(ENOMEM);
00226 }
00227
00228 planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0;
00229 }
00230 }
00231
00232 return 0;
00233 }
00234
00235 void av_cold ff_ivi_free_buffers(IVIPlaneDesc *planes)
00236 {
00237 int p, b, t;
00238
00239 for (p = 0; p < 3; p++) {
00240 for (b = 0; b < planes[p].num_bands; b++) {
00241 av_freep(&planes[p].bands[b].bufs[0]);
00242 av_freep(&planes[p].bands[b].bufs[1]);
00243 av_freep(&planes[p].bands[b].bufs[2]);
00244
00245 if (planes[p].bands[b].blk_vlc.cust_tab.table)
00246 ff_free_vlc(&planes[p].bands[b].blk_vlc.cust_tab);
00247 for (t = 0; t < planes[p].bands[b].num_tiles; t++)
00248 av_freep(&planes[p].bands[b].tiles[t].mbs);
00249 av_freep(&planes[p].bands[b].tiles);
00250 }
00251 av_freep(&planes[p].bands);
00252 }
00253 }
00254
00255 int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height)
00256 {
00257 int p, b, x, y, x_tiles, y_tiles, t_width, t_height;
00258 IVIBandDesc *band;
00259 IVITile *tile, *ref_tile;
00260
00261 for (p = 0; p < 3; p++) {
00262 t_width = !p ? tile_width : (tile_width + 3) >> 2;
00263 t_height = !p ? tile_height : (tile_height + 3) >> 2;
00264
00265 if (!p && planes[0].num_bands == 4) {
00266 t_width >>= 1;
00267 t_height >>= 1;
00268 }
00269
00270 for (b = 0; b < planes[p].num_bands; b++) {
00271 band = &planes[p].bands[b];
00272 x_tiles = IVI_NUM_TILES(band->width, t_width);
00273 y_tiles = IVI_NUM_TILES(band->height, t_height);
00274 band->num_tiles = x_tiles * y_tiles;
00275
00276 av_freep(&band->tiles);
00277 band->tiles = av_mallocz(band->num_tiles * sizeof(IVITile));
00278 if (!band->tiles)
00279 return AVERROR(ENOMEM);
00280
00281 tile = band->tiles;
00282
00283
00284
00285 ref_tile = planes[0].bands[0].tiles;
00286
00287 for (y = 0; y < band->height; y += t_height) {
00288 for (x = 0; x < band->width; x += t_width) {
00289 tile->xpos = x;
00290 tile->ypos = y;
00291 tile->mb_size = band->mb_size;
00292 tile->width = FFMIN(band->width - x, t_width);
00293 tile->height = FFMIN(band->height - y, t_height);
00294 tile->is_empty = tile->data_size = 0;
00295
00296 tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height,
00297 band->mb_size);
00298
00299 av_freep(&tile->mbs);
00300 tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo));
00301 if (!tile->mbs)
00302 return AVERROR(ENOMEM);
00303
00304 tile->ref_mbs = 0;
00305 if (p || b) {
00306 tile->ref_mbs = ref_tile->mbs;
00307 ref_tile++;
00308 }
00309
00310 tile++;
00311 }
00312 }
00313
00314 }
00315 }
00316
00317 return 0;
00318 }
00319
00320 int ff_ivi_dec_tile_data_size(GetBitContext *gb)
00321 {
00322 int len;
00323
00324 len = 0;
00325 if (get_bits1(gb)) {
00326 len = get_bits(gb, 8);
00327 if (len == 255)
00328 len = get_bits_long(gb, 24);
00329 }
00330
00331
00332 align_get_bits(gb);
00333
00334 return len;
00335 }
00336
00337 int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
00338 {
00339 int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val,
00340 pos, is_intra, mc_type, mv_x, mv_y, col_mask;
00341 uint8_t col_flags[8];
00342 int32_t prev_dc, trvec[64];
00343 uint32_t cbp, sym, lo, hi, quant, buf_offs, q;
00344 IVIMbInfo *mb;
00345 RVMapDesc *rvmap = band->rv_map;
00346 void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type);
00347 void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type);
00348 const uint16_t *base_tab;
00349 const uint8_t *scale_tab;
00350
00351 prev_dc = 0;
00352
00353 blk_size = band->blk_size;
00354 col_mask = blk_size - 1;
00355 num_blocks = (band->mb_size != blk_size) ? 4 : 1;
00356 num_coeffs = blk_size * blk_size;
00357 if (blk_size == 8) {
00358 mc_with_delta_func = ff_ivi_mc_8x8_delta;
00359 mc_no_delta_func = ff_ivi_mc_8x8_no_delta;
00360 } else {
00361 mc_with_delta_func = ff_ivi_mc_4x4_delta;
00362 mc_no_delta_func = ff_ivi_mc_4x4_no_delta;
00363 }
00364
00365 for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {
00366 is_intra = !mb->type;
00367 cbp = mb->cbp;
00368 buf_offs = mb->buf_offs;
00369
00370 quant = av_clip(band->glob_quant + mb->q_delta, 0, 23);
00371
00372 base_tab = is_intra ? band->intra_base : band->inter_base;
00373 scale_tab = is_intra ? band->intra_scale : band->inter_scale;
00374 if (scale_tab)
00375 quant = scale_tab[quant];
00376
00377 if (!is_intra) {
00378 mv_x = mb->mv_x;
00379 mv_y = mb->mv_y;
00380 if (!band->is_halfpel) {
00381 mc_type = 0;
00382 } else {
00383 mc_type = ((mv_y & 1) << 1) | (mv_x & 1);
00384 mv_x >>= 1;
00385 mv_y >>= 1;
00386 }
00387 if (mb->type) {
00388 int dmv_x, dmv_y, cx, cy;
00389
00390 dmv_x = mb->mv_x >> band->is_halfpel;
00391 dmv_y = mb->mv_y >> band->is_halfpel;
00392 cx = mb->mv_x & band->is_halfpel;
00393 cy = mb->mv_y & band->is_halfpel;
00394
00395 if ( mb->xpos + dmv_x < 0
00396 || mb->xpos + dmv_x + band->mb_size + cx > band->pitch
00397 || mb->ypos + dmv_y < 0
00398 || mb->ypos + dmv_y + band->mb_size + cy > band->aheight) {
00399 return AVERROR_INVALIDDATA;
00400 }
00401 }
00402 }
00403
00404 for (blk = 0; blk < num_blocks; blk++) {
00405
00406 if (blk & 1) {
00407 buf_offs += blk_size;
00408 } else if (blk == 2) {
00409 buf_offs -= blk_size;
00410 buf_offs += blk_size * band->pitch;
00411 }
00412
00413 if (cbp & 1) {
00414 if (!band->scan) {
00415 av_log(NULL, AV_LOG_ERROR, "Scan pattern is not set.\n");
00416 return AVERROR_INVALIDDATA;
00417 }
00418
00419 scan_pos = -1;
00420 memset(trvec, 0, num_coeffs*sizeof(trvec[0]));
00421 memset(col_flags, 0, sizeof(col_flags));
00422
00423 while (scan_pos <= num_coeffs) {
00424 sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
00425 if (sym == rvmap->eob_sym)
00426 break;
00427
00428 if (sym == rvmap->esc_sym) {
00429 run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1;
00430 lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
00431 hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1);
00432 val = IVI_TOSIGNED((hi << 6) | lo);
00433 } else {
00434 if (sym >= 256U) {
00435 av_log(NULL, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym);
00436 return -1;
00437 }
00438 run = rvmap->runtab[sym];
00439 val = rvmap->valtab[sym];
00440 }
00441
00442
00443 scan_pos += run;
00444 if (scan_pos >= num_coeffs)
00445 break;
00446 pos = band->scan[scan_pos];
00447
00448 if (!val)
00449 av_dlog(NULL, "Val = 0 encountered!\n");
00450
00451 q = (base_tab[pos] * quant) >> 9;
00452 if (q > 1)
00453 val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1);
00454 trvec[pos] = val;
00455 col_flags[pos & col_mask] |= !!val;
00456 }
00457
00458 if (scan_pos >= num_coeffs && sym != rvmap->eob_sym)
00459 return -1;
00460
00461
00462 if (is_intra && band->is_2d_trans) {
00463 prev_dc += trvec[0];
00464 trvec[0] = prev_dc;
00465 col_flags[0] |= !!prev_dc;
00466 }
00467
00468
00469 band->inv_transform(trvec, band->buf + buf_offs,
00470 band->pitch, col_flags);
00471
00472
00473 if (!is_intra)
00474 mc_with_delta_func(band->buf + buf_offs,
00475 band->ref_buf + buf_offs + mv_y * band->pitch + mv_x,
00476 band->pitch, mc_type);
00477 } else {
00478
00479
00480
00481 if (is_intra) {
00482 if (band->dc_transform)
00483 band->dc_transform(&prev_dc, band->buf + buf_offs,
00484 band->pitch, blk_size);
00485 } else
00486 mc_no_delta_func(band->buf + buf_offs,
00487 band->ref_buf + buf_offs + mv_y * band->pitch + mv_x,
00488 band->pitch, mc_type);
00489 }
00490
00491 cbp >>= 1;
00492 }
00493 }
00494
00495 align_get_bits(gb);
00496
00497 return 0;
00498 }
00499
00509 static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
00510 IVITile *tile, int32_t mv_scale)
00511 {
00512 int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;
00513 int offs, mb_offset, row_offset;
00514 IVIMbInfo *mb, *ref_mb;
00515 const int16_t *src;
00516 int16_t *dst;
00517 void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch,
00518 int mc_type);
00519
00520 if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) {
00521 av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches "
00522 "parameters %d in ivi_process_empty_tile()\n",
00523 tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size));
00524 return AVERROR_INVALIDDATA;
00525 }
00526
00527 offs = tile->ypos * band->pitch + tile->xpos;
00528 mb = tile->mbs;
00529 ref_mb = tile->ref_mbs;
00530 row_offset = band->mb_size * band->pitch;
00531 need_mc = 0;
00532
00533 for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) {
00534 mb_offset = offs;
00535
00536 for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) {
00537 mb->xpos = x;
00538 mb->ypos = y;
00539 mb->buf_offs = mb_offset;
00540
00541 mb->type = 1;
00542 mb->cbp = 0;
00543
00544 if (!band->qdelta_present && !band->plane && !band->band_num) {
00545 mb->q_delta = band->glob_quant;
00546 mb->mv_x = 0;
00547 mb->mv_y = 0;
00548 }
00549
00550 if (band->inherit_qdelta && ref_mb)
00551 mb->q_delta = ref_mb->q_delta;
00552
00553 if (band->inherit_mv) {
00554
00555 if (mv_scale) {
00556 mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
00557 mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
00558 } else {
00559 mb->mv_x = ref_mb->mv_x;
00560 mb->mv_y = ref_mb->mv_y;
00561 }
00562 need_mc |= mb->mv_x || mb->mv_y;
00563 }
00564
00565 mb++;
00566 if (ref_mb)
00567 ref_mb++;
00568 mb_offset += band->mb_size;
00569 }
00570 offs += row_offset;
00571 }
00572
00573 if (band->inherit_mv && need_mc) {
00574 num_blocks = (band->mb_size != band->blk_size) ? 4 : 1;
00575 mc_no_delta_func = (band->blk_size == 8) ? ff_ivi_mc_8x8_no_delta
00576 : ff_ivi_mc_4x4_no_delta;
00577
00578 for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {
00579 mv_x = mb->mv_x;
00580 mv_y = mb->mv_y;
00581 if (!band->is_halfpel) {
00582 mc_type = 0;
00583 } else {
00584 mc_type = ((mv_y & 1) << 1) | (mv_x & 1);
00585 mv_x >>= 1;
00586 mv_y >>= 1;
00587 }
00588
00589 for (blk = 0; blk < num_blocks; blk++) {
00590
00591 offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);
00592 mc_no_delta_func(band->buf + offs,
00593 band->ref_buf + offs + mv_y * band->pitch + mv_x,
00594 band->pitch, mc_type);
00595 }
00596 }
00597 } else {
00598
00599 src = band->ref_buf + tile->ypos * band->pitch + tile->xpos;
00600 dst = band->buf + tile->ypos * band->pitch + tile->xpos;
00601 for (y = 0; y < tile->height; y++) {
00602 memcpy(dst, src, tile->width*sizeof(band->buf[0]));
00603 src += band->pitch;
00604 dst += band->pitch;
00605 }
00606 }
00607
00608 return 0;
00609 }
00610
00611
00612 #ifdef DEBUG
00613 uint16_t ivi_calc_band_checksum (IVIBandDesc *band)
00614 {
00615 int x, y;
00616 int16_t *src, checksum;
00617
00618 src = band->buf;
00619 checksum = 0;
00620
00621 for (y = 0; y < band->height; src += band->pitch, y++)
00622 for (x = 0; x < band->width; x++)
00623 checksum += src[x];
00624
00625 return checksum;
00626 }
00627
00628 int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch)
00629 {
00630 int x, y, result;
00631 uint8_t t1, t2;
00632 int16_t *src;
00633
00634 src = band->buf;
00635 result = 0;
00636
00637 for (y = 0; y < band->height; src += band->pitch, y++) {
00638 for (x = 0; x < band->width; x++) {
00639 t1 = av_clip(src[x] + 128, 0, 255);
00640 t2 = ref[x];
00641 if (t1 != t2) {
00642 av_log(NULL, AV_LOG_ERROR, "Data mismatch: row %d, column %d\n",
00643 y / band->blk_size, x / band->blk_size);
00644 result = -1;
00645 }
00646 }
00647 ref += pitch;
00648 }
00649
00650 return result;
00651 }
00652 #endif
00653
00654 void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
00655 {
00656 int x, y;
00657 const int16_t *src = plane->bands[0].buf;
00658 uint32_t pitch = plane->bands[0].pitch;
00659
00660 if (!src)
00661 return;
00662
00663 for (y = 0; y < plane->height; y++) {
00664 for (x = 0; x < plane->width; x++)
00665 dst[x] = av_clip_uint8(src[x] + 128);
00666 src += pitch;
00667 dst += dst_pitch;
00668 }
00669 }
00670
00679 static int decode_band(IVI45DecContext *ctx, int plane_num,
00680 IVIBandDesc *band, AVCodecContext *avctx)
00681 {
00682 int result, i, t, idx1, idx2, pos;
00683 IVITile *tile;
00684
00685 band->buf = band->bufs[ctx->dst_buf];
00686 band->ref_buf = band->bufs[ctx->ref_buf];
00687 band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
00688
00689 result = ctx->decode_band_hdr(ctx, band, avctx);
00690 if (result) {
00691 av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
00692 result);
00693 return result;
00694 }
00695
00696 if (band->is_empty) {
00697 av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
00698 return AVERROR_INVALIDDATA;
00699 }
00700
00701 band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
00702
00703
00704 for (i = 0; i < band->num_corr; i++) {
00705 idx1 = band->corr[i * 2];
00706 idx2 = band->corr[i * 2 + 1];
00707 FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
00708 FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
00709 }
00710
00711 pos = get_bits_count(&ctx->gb);
00712
00713 for (t = 0; t < band->num_tiles; t++) {
00714 tile = &band->tiles[t];
00715
00716 if (tile->mb_size != band->mb_size) {
00717 av_log(avctx, AV_LOG_ERROR, "MB sizes mismatch: %d vs. %d\n",
00718 band->mb_size, tile->mb_size);
00719 return AVERROR_INVALIDDATA;
00720 }
00721 tile->is_empty = get_bits1(&ctx->gb);
00722 if (tile->is_empty) {
00723 result = ivi_process_empty_tile(avctx, band, tile,
00724 (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
00725 if (result < 0)
00726 break;
00727 av_dlog(avctx, "Empty tile encountered!\n");
00728 } else {
00729 tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
00730 if (!tile->data_size) {
00731 av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
00732 return AVERROR_INVALIDDATA;
00733 }
00734
00735 result = ctx->decode_mb_info(ctx, band, tile, avctx);
00736 if (result < 0)
00737 break;
00738
00739 result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
00740 if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
00741 av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
00742 break;
00743 }
00744
00745 pos += tile->data_size << 3;
00746 }
00747 }
00748
00749
00750 for (i = band->num_corr-1; i >= 0; i--) {
00751 idx1 = band->corr[i*2];
00752 idx2 = band->corr[i*2+1];
00753 FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
00754 FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
00755 }
00756
00757 #ifdef DEBUG
00758 if (band->checksum_present) {
00759 uint16_t chksum = ivi_calc_band_checksum(band);
00760 if (chksum != band->checksum) {
00761 av_log(avctx, AV_LOG_ERROR,
00762 "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
00763 band->plane, band->band_num, band->checksum, chksum);
00764 }
00765 }
00766 #endif
00767
00768 align_get_bits(&ctx->gb);
00769
00770 return result;
00771 }
00772
00773 int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00774 AVPacket *avpkt)
00775 {
00776 IVI45DecContext *ctx = avctx->priv_data;
00777 const uint8_t *buf = avpkt->data;
00778 int buf_size = avpkt->size;
00779 int result, p, b;
00780
00781 init_get_bits(&ctx->gb, buf, buf_size * 8);
00782 ctx->frame_data = buf;
00783 ctx->frame_size = buf_size;
00784
00785 result = ctx->decode_pic_hdr(ctx, avctx);
00786 if (result) {
00787 av_log(avctx, AV_LOG_ERROR,
00788 "Error while decoding picture header: %d\n", result);
00789 return -1;
00790 }
00791 if (ctx->gop_invalid)
00792 return AVERROR_INVALIDDATA;
00793
00794 if (ctx->gop_flags & IVI5_IS_PROTECTED) {
00795 av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
00796 return -1;
00797 }
00798
00799 ctx->switch_buffers(ctx);
00800
00801
00802
00803 if (ctx->is_nonnull_frame(ctx)) {
00804 for (p = 0; p < 3; p++) {
00805 for (b = 0; b < ctx->planes[p].num_bands; b++) {
00806 result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
00807 if (result) {
00808 av_log(avctx, AV_LOG_ERROR,
00809 "Error while decoding band: %d, plane: %d\n", b, p);
00810 return -1;
00811 }
00812 }
00813 }
00814 }
00815
00816
00817
00818
00819
00820
00821 if (avctx->codec_id == CODEC_ID_INDEO4 && ctx->frame_type == 0) {
00822 while (get_bits(&ctx->gb, 8));
00823 skip_bits_long(&ctx->gb, 64);
00824 if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
00825 av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
00826 }
00827
00828 if (ctx->frame.data[0])
00829 avctx->release_buffer(avctx, &ctx->frame);
00830
00831 ctx->frame.reference = 0;
00832 avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
00833 if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
00834 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00835 return result;
00836 }
00837
00838 if (ctx->is_scalable) {
00839 if (avctx->codec_id == CODEC_ID_INDEO4)
00840 ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
00841 else
00842 ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
00843 } else {
00844 ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
00845 }
00846
00847 ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
00848 ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
00849
00850 *data_size = sizeof(AVFrame);
00851 *(AVFrame*)data = ctx->frame;
00852
00853 return buf_size;
00854 }
00855
00859 av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
00860 {
00861 IVI45DecContext *ctx = avctx->priv_data;
00862
00863 ff_ivi_free_buffers(&ctx->planes[0]);
00864
00865 if (ctx->mb_vlc.cust_tab.table)
00866 ff_free_vlc(&ctx->mb_vlc.cust_tab);
00867
00868 if (ctx->frame.data[0])
00869 avctx->release_buffer(avctx, &ctx->frame);
00870
00871 #if IVI4_STREAM_ANALYSER
00872 if (avctx->codec_id == CODEC_ID_INDEO4) {
00873 if (ctx->is_scalable)
00874 av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
00875 if (ctx->uses_tiling)
00876 av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
00877 if (ctx->has_b_frames)
00878 av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
00879 if (ctx->has_transp)
00880 av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
00881 if (ctx->uses_haar)
00882 av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
00883 if (ctx->uses_fullpel)
00884 av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
00885 }
00886 #endif
00887
00888 return 0;
00889 }
00890
00891
00898 const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
00899 {8, {0, 4, 5, 4, 4, 4, 6, 6}},
00900 {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
00901 {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
00902 {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
00903 {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
00904 {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}},
00905 {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
00906 {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
00907 };
00908
00909 const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
00910 {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
00911 {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
00912 {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
00913 {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
00914 {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
00915 {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
00916 {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
00917 {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}}
00918 };
00919
00920
00924 const uint8_t ff_ivi_vertical_scan_8x8[64] = {
00925 0, 8, 16, 24, 32, 40, 48, 56,
00926 1, 9, 17, 25, 33, 41, 49, 57,
00927 2, 10, 18, 26, 34, 42, 50, 58,
00928 3, 11, 19, 27, 35, 43, 51, 59,
00929 4, 12, 20, 28, 36, 44, 52, 60,
00930 5, 13, 21, 29, 37, 45, 53, 61,
00931 6, 14, 22, 30, 38, 46, 54, 62,
00932 7, 15, 23, 31, 39, 47, 55, 63
00933 };
00934
00935 const uint8_t ff_ivi_horizontal_scan_8x8[64] = {
00936 0, 1, 2, 3, 4, 5, 6, 7,
00937 8, 9, 10, 11, 12, 13, 14, 15,
00938 16, 17, 18, 19, 20, 21, 22, 23,
00939 24, 25, 26, 27, 28, 29, 30, 31,
00940 32, 33, 34, 35, 36, 37, 38, 39,
00941 40, 41, 42, 43, 44, 45, 46, 47,
00942 48, 49, 50, 51, 52, 53, 54, 55,
00943 56, 57, 58, 59, 60, 61, 62, 63
00944 };
00945
00946 const uint8_t ff_ivi_direct_scan_4x4[16] = {
00947 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
00948 };
00949
00950
00954 const RVMapDesc ff_ivi_rvmap_tabs[9] = {
00955 {
00956 5,
00957 2,
00958
00959 {1, 1, 0, 1, 1, 0, 1, 1, 2, 2, 1, 1, 1, 1, 3, 3,
00960 1, 1, 2, 2, 1, 1, 4, 4, 1, 1, 1, 1, 2, 2, 5, 5,
00961 1, 1, 3, 3, 1, 1, 6, 6, 1, 2, 1, 2, 7, 7, 1, 1,
00962 8, 8, 1, 1, 4, 2, 1, 4, 2, 1, 3, 3, 1, 1, 1, 9,
00963 9, 1, 2, 1, 2, 1, 5, 5, 1, 1, 10, 10, 1, 1, 3, 3,
00964 2, 2, 1, 1, 11, 11, 6, 4, 4, 1, 6, 1, 2, 1, 2, 12,
00965 8, 1, 12, 7, 8, 7, 1, 16, 1, 16, 1, 3, 3, 13, 1, 13,
00966 2, 2, 1, 15, 1, 5, 14, 15, 1, 5, 14, 1, 17, 8, 17, 8,
00967 1, 4, 4, 2, 2, 1, 25, 25, 24, 24, 1, 3, 1, 3, 1, 8,
00968 6, 7, 6, 1, 18, 8, 18, 1, 7, 23, 2, 2, 23, 1, 1, 21,
00969 22, 9, 9, 22, 19, 1, 21, 5, 19, 5, 1, 33, 20, 33, 20, 8,
00970 4, 4, 1, 32, 2, 2, 8, 3, 32, 26, 3, 1, 7, 7, 26, 6,
00971 1, 6, 1, 1, 16, 1, 10, 1, 10, 2, 16, 29, 28, 2, 29, 28,
00972 1, 27, 5, 8, 5, 27, 1, 8, 3, 7, 3, 31, 41, 31, 1, 41,
00973 6, 1, 6, 7, 4, 4, 1, 1, 2, 1, 2, 11, 34, 30, 11, 1,
00974 30, 15, 15, 34, 36, 40, 36, 40, 35, 35, 37, 37, 39, 39, 38, 38},
00975
00976
00977 { 1, -1, 0, 2, -2, 0, 3, -3, 1, -1, 4, -4, 5, -5, 1, -1,
00978 6, -6, 2, -2, 7, -7, 1, -1, 8, -8, 9, -9, 3, -3, 1, -1,
00979 10, -10, 2, -2, 11, -11, 1, -1, 12, 4, -12, -4, 1, -1, 13, -13,
00980 1, -1, 14, -14, 2, 5, 15, -2, -5, -15, -3, 3, 16, -16, 17, 1,
00981 -1, -17, 6, 18, -6, -18, 2, -2, 19, -19, 1, -1, 20, -20, 4, -4,
00982 7, -7, 21, -21, 1, -1, 2, 3, -3, 22, -2, -22, 8, 23, -8, 1,
00983 2, -23, -1, 2, -2, -2, 24, 1, -24, -1, 25, 5, -5, 1, -25, -1,
00984 9, -9, 26, 1, -26, 3, 1, -1, 27, -3, -1, -27, 1, 3, -1, -3,
00985 28, -4, 4, 10, -10, -28, 1, -1, 1, -1, 29, 6, -29, -6, 30, -4,
00986 3, 3, -3, -30, 1, 4, -1, 31, -3, 1, 11, -11, -1, -31, 32, -1,
00987 -1, 2, -2, 1, 1, -32, 1, 4, -1, -4, 33, -1, 1, 1, -1, 5,
00988 5, -5, -33, -1, -12, 12, -5, -7, 1, 1, 7, 34, 4, -4, -1, 4,
00989 -34, -4, 35, 36, -2, -35, -2, -36, 2, 13, 2, -1, 1, -13, 1, -1,
00990 37, 1, -5, 6, 5, -1, 38, -6, -8, 5, 8, -1, 1, 1, -37, -1,
00991 5, 39, -5, -5, 6, -6, -38, -39, -14, 40, 14, 2, 1, 1, -2, -40,
00992 -1, -2, 2, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1}
00993 },{
00994
00995 0,
00996 38,
00997
00998 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 6, 8, 7,
00999 7, 9, 9, 10, 10, 11, 11, 1, 12, 1, 12, 13, 13, 16, 14, 16,
01000 14, 15, 15, 17, 17, 18, 0, 18, 19, 20, 21, 19, 22, 21, 20, 22,
01001 25, 24, 2, 25, 24, 23, 23, 2, 26, 28, 26, 28, 29, 27, 29, 27,
01002 33, 33, 1, 32, 1, 3, 32, 30, 36, 3, 36, 30, 31, 31, 35, 34,
01003 37, 41, 34, 35, 37, 4, 41, 4, 49, 8, 8, 49, 40, 38, 5, 38,
01004 40, 39, 5, 39, 42, 43, 42, 7, 57, 6, 43, 44, 6, 50, 7, 44,
01005 57, 48, 50, 48, 45, 45, 46, 47, 51, 46, 47, 58, 1, 51, 58, 1,
01006 52, 59, 53, 9, 52, 55, 55, 59, 53, 56, 54, 56, 54, 9, 64, 64,
01007 60, 63, 60, 63, 61, 62, 61, 62, 2, 10, 2, 10, 11, 1, 11, 13,
01008 12, 1, 12, 13, 16, 16, 8, 8, 14, 3, 3, 15, 14, 15, 4, 4,
01009 1, 17, 17, 5, 1, 7, 7, 5, 6, 1, 2, 2, 6, 22, 1, 25,
01010 21, 22, 8, 24, 1, 21, 25, 24, 8, 18, 18, 23, 9, 20, 23, 33,
01011 29, 33, 20, 1, 19, 1, 29, 36, 9, 36, 19, 41, 28, 57, 32, 3,
01012 28, 3, 1, 27, 49, 49, 1, 32, 26, 26, 2, 4, 4, 7, 57, 41,
01013 2, 7, 10, 5, 37, 16, 10, 27, 8, 8, 13, 16, 37, 13, 1, 5},
01014
01015
01016 {0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1,
01017 -1, 1, -1, 1, -1, 1, -1, 2, 1, -2, -1, 1, -1, 1, 1, -1,
01018 -1, 1, -1, 1, -1, 1, 0, -1, 1, 1, 1, -1, 1, -1, -1, -1,
01019 1, 1, 2, -1, -1, 1, -1, -2, 1, 1, -1, -1, 1, 1, -1, -1,
01020 1, -1, 3, 1, -3, 2, -1, 1, 1, -2, -1, -1, -1, 1, 1, 1,
01021 1, 1, -1, -1, -1, 2, -1, -2, 1, 2, -2, -1, 1, 1, 2, -1,
01022 -1, 1, -2, -1, 1, 1, -1, 2, 1, 2, -1, 1, -2, -1, -2, -1,
01023 -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 4, -1, -1, -4,
01024 1, 1, 1, 2, -1, -1, 1, -1, -1, 1, -1, -1, 1, -2, 1, -1,
01025 1, 1, -1, -1, 1, 1, -1, -1, 3, 2, -3, -2, 2, 5, -2, 2,
01026 2, -5, -2, -2, -2, 2, -3, 3, 2, 3, -3, 2, -2, -2, 3, -3,
01027 6, 2, -2, 3, -6, 3, -3, -3, 3, 7, -4, 4, -3, 2, -7, 2,
01028 2, -2, -4, 2, 8, -2, -2, -2, 4, 2, -2, 2, 3, 2, -2, -2,
01029 2, 2, -2, -8, -2, 9, -2, 2, -3, -2, 2, -2, 2, 2, 2, 4,
01030 -2, -4, 10, 2, 2, -2, -9, -2, 2, -2, 5, 4, -4, 4, -2, 2,
01031 -5, -4, -3, 4, 2, -3, 3, -2, -5, 5, 3, 3, -2, -3, -10, -4}
01032 },{
01033
01034 2,
01035 11,
01036
01037 {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 0, 1, 1, 5, 5,
01038 2, 2, 6, 6, 7, 7, 1, 8, 1, 8, 3, 3, 9, 9, 1, 2,
01039 2, 1, 4, 10, 4, 10, 11, 11, 1, 5, 12, 12, 1, 5, 13, 13,
01040 3, 3, 6, 6, 2, 2, 14, 14, 16, 16, 15, 7, 15, 8, 8, 7,
01041 1, 1, 17, 17, 4, 4, 1, 1, 18, 18, 2, 2, 5, 5, 25, 3,
01042 9, 3, 25, 9, 19, 24, 19, 24, 1, 21, 20, 1, 21, 22, 20, 22,
01043 23, 23, 8, 6, 33, 6, 8, 33, 7, 7, 26, 26, 1, 32, 1, 32,
01044 28, 4, 28, 10, 29, 27, 27, 10, 41, 4, 29, 2, 2, 41, 36, 31,
01045 49, 31, 34, 30, 34, 36, 30, 35, 1, 49, 11, 5, 35, 11, 1, 3,
01046 3, 5, 37, 37, 8, 40, 8, 40, 12, 12, 42, 42, 1, 38, 16, 57,
01047 1, 6, 16, 39, 38, 6, 7, 7, 13, 13, 39, 43, 2, 43, 57, 2,
01048 50, 9, 44, 9, 50, 4, 15, 48, 44, 4, 1, 15, 48, 14, 14, 1,
01049 45, 45, 8, 3, 5, 8, 51, 47, 3, 46, 46, 47, 5, 51, 1, 17,
01050 17, 58, 1, 58, 2, 52, 52, 2, 53, 7, 59, 6, 6, 56, 53, 55,
01051 7, 55, 1, 54, 59, 56, 54, 10, 1, 10, 4, 60, 1, 60, 8, 4,
01052 8, 64, 64, 61, 1, 63, 3, 63, 62, 61, 5, 11, 5, 3, 11, 62},
01053
01054
01055 { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 0, 3, -3, 1, -1,
01056 2, -2, 1, -1, 1, -1, 4, 1, -4, -1, 2, -2, 1, -1, 5, 3,
01057 -3, -5, 2, 1, -2, -1, 1, -1, 6, 2, 1, -1, -6, -2, 1, -1,
01058 3, -3, 2, -2, 4, -4, 1, -1, 1, -1, 1, 2, -1, 2, -2, -2,
01059 7, -7, 1, -1, 3, -3, 8, -8, 1, -1, 5, -5, 3, -3, 1, 4,
01060 2, -4, -1, -2, 1, 1, -1, -1, 9, 1, 1, -9, -1, 1, -1, -1,
01061 1, -1, 3, -3, 1, 3, -3, -1, 3, -3, 1, -1, 10, 1, -10, -1,
01062 1, 4, -1, 2, 1, -1, 1, -2, 1, -4, -1, 6, -6, -1, 1, 1,
01063 1, -1, 1, 1, -1, -1, -1, 1, 11, -1, -2, 4, -1, 2, -11, 5,
01064 -5, -4, -1, 1, 4, 1, -4, -1, -2, 2, 1, -1, 12, 1, -2, 1,
01065 -12, 4, 2, 1, -1, -4, 4, -4, 2, -2, -1, 1, 7, -1, -1, -7,
01066 -1, -3, 1, 3, 1, 5, 2, 1, -1, -5, 13, -2, -1, 2, -2, -13,
01067 1, -1, 5, 6, 5, -5, 1, 1, -6, 1, -1, -1, -5, -1, 14, 2,
01068 -2, 1, -14, -1, 8, 1, -1, -8, 1, 5, 1, 5, -5, 1, -1, 1,
01069 -5, -1, 15, 1, -1, -1, -1, 3, -15, -3, 6, 1, 16, -1, 6, -6,
01070 -6, 1, -1, 1, -16, 1, 7, -1, 1, -1, -6, -3, 6, -7, 3, -1}
01071 },{
01072
01073 0,
01074 35,
01075
01076 {0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 5, 5, 6, 6, 7,
01077 7, 8, 8, 9, 9, 2, 2, 10, 10, 1, 1, 11, 11, 12, 12, 3,
01078 3, 13, 13, 0, 14, 14, 16, 15, 16, 15, 4, 4, 17, 1, 17, 1,
01079 5, 5, 18, 18, 2, 2, 6, 6, 8, 19, 7, 8, 7, 19, 20, 20,
01080 21, 21, 22, 24, 22, 24, 23, 23, 1, 1, 25, 25, 3, 3, 26, 26,
01081 9, 9, 27, 27, 28, 28, 33, 29, 4, 33, 29, 1, 4, 1, 32, 32,
01082 2, 2, 31, 10, 30, 10, 30, 31, 34, 34, 5, 5, 36, 36, 35, 41,
01083 35, 11, 41, 11, 37, 1, 8, 8, 37, 6, 1, 6, 40, 7, 7, 40,
01084 12, 38, 12, 39, 39, 38, 49, 13, 49, 13, 3, 42, 3, 42, 16, 16,
01085 43, 43, 14, 14, 1, 1, 44, 15, 44, 15, 2, 2, 57, 48, 50, 48,
01086 57, 50, 4, 45, 45, 4, 46, 47, 47, 46, 1, 51, 1, 17, 17, 51,
01087 8, 9, 9, 5, 58, 8, 58, 5, 52, 52, 55, 56, 53, 56, 55, 59,
01088 59, 53, 54, 1, 6, 54, 7, 7, 6, 1, 2, 3, 2, 3, 64, 60,
01089 60, 10, 10, 64, 61, 62, 61, 63, 1, 63, 62, 1, 18, 24, 18, 4,
01090 25, 4, 8, 21, 21, 1, 24, 22, 25, 22, 8, 11, 19, 11, 23, 1,
01091 20, 23, 19, 20, 5, 12, 5, 1, 16, 2, 12, 13, 2, 13, 1, 16},
01092
01093
01094 { 0, 1, -1, 1, -1, 1, -1, 1, -1, 2, -2, 1, -1, 1, -1, 1,
01095 -1, 1, -1, 1, -1, 2, -2, 1, -1, 3, -3, 1, -1, 1, -1, 2,
01096 -2, 1, -1, 0, 1, -1, 1, 1, -1, -1, 2, -2, 1, 4, -1, -4,
01097 2, -2, 1, -1, -3, 3, 2, -2, 2, 1, 2, -2, -2, -1, 1, -1,
01098 1, -1, 1, 1, -1, -1, 1, -1, 5, -5, 1, -1, 3, -3, 1, -1,
01099 2, -2, 1, -1, 1, -1, 1, 1, 3, -1, -1, 6, -3, -6, -1, 1,
01100 4, -4, 1, 2, 1, -2, -1, -1, 1, -1, 3, -3, 1, -1, 1, 1,
01101 -1, 2, -1, -2, 1, 7, -3, 3, -1, 3, -7, -3, 1, -3, 3, -1,
01102 2, 1, -2, 1, -1, -1, 1, 2, -1, -2, -4, -1, 4, 1, 2, -2,
01103 1, -1, -2, 2, 8, -8, -1, 2, 1, -2, -5, 5, 1, -1, -1, 1,
01104 -1, 1, 4, -1, 1, -4, -1, -1, 1, 1, 9, 1, -9, 2, -2, -1,
01105 -4, 3, -3, -4, -1, 4, 1, 4, 1, -1, 1, -1, 1, 1, -1, 1,
01106 -1, -1, -1, 10, 4, 1, 4, -4, -4, -10, 6, 5, -6, -5, 1, -1,
01107 1, 3, -3, -1, 1, -1, -1, -1, 11, 1, 1, -11, -2, -2, 2, 5,
01108 -2, -5, -5, 2, -2, 12, 2, -2, 2, 2, 5, -3, -2, 3, -2, -12,
01109 -2, 2, 2, 2, -5, 3, 5, 13, -3, 7, -3, -3, -7, 3, -13, 3}
01110 },{
01111
01112 0,
01113 34,
01114
01115 {0, 1, 1, 1, 2, 2, 1, 3, 3, 1, 1, 1, 4, 4, 1, 5,
01116 2, 1, 5, 2, 1, 1, 6, 6, 1, 1, 1, 1, 1, 7, 3, 1,
01117 2, 3, 0, 1, 2, 7, 1, 1, 1, 8, 1, 1, 8, 1, 1, 1,
01118 9, 1, 9, 1, 2, 1, 1, 2, 1, 1, 10, 4, 1, 10, 1, 4,
01119 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 2, 1, 5, 1, 1, 1,
01120 2, 5, 1, 11, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
01121 2, 1, 6, 1, 6, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 12,
01122 3, 1, 12, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1,
01123 4, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 1, 2, 1,
01124 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 5,
01125 1, 1, 1, 1, 1, 7, 1, 7, 1, 1, 2, 3, 1, 1, 1, 1,
01126 5, 1, 1, 1, 1, 1, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1,
01127 1, 1, 1, 1, 1, 1, 1, 1, 13, 2, 1, 1, 4, 1, 1, 1,
01128 3, 1, 6, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 6, 1, 1,
01129 1, 1, 15, 2, 4, 1, 2, 3, 15, 1, 1, 1, 8, 1, 1, 8,
01130 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1},
01131
01132
01133 { 0, 1, -1, 2, 1, -1, -2, 1, -1, 3, -3, 4, 1, -1, -4, 1,
01134 2, 5, -1, -2, -5, 6, 1, -1, -6, 7, -7, 8, -8, 1, 2, 9,
01135 3, -2, 0, -9, -3, -1, 10, -10, 11, 1, -11, 12, -1, -12, 13, -13,
01136 1, 14, -1, -14, 4, 15, -15, -4, 16, -16, 1, 2, 17, -1, -17, -2,
01137 18, -18, 19, -19, 20, 3, -20, 21, -21, -3, 5, 22, 2, -22, -23, 23,
01138 -5, -2, 24, 1, -24, -1, 25, -25, 26, -26, -27, 27, 28, 29, -28, -29,
01139 6, 30, 2, -31, -2, -30, 31, -6, -32, 32, 33, -33, 34, -35, -34, 1,
01140 4, -36, -1, 35, 37, 36, 7, -37, 38, -4, -38, 39, 41, 40, -40, -39,
01141 3, 42, -43, -41, -7, -42, 43, -3, 44, -44, 45, -45, 46, 47, 8, -47,
01142 -48, -46, 50, -50, 48, 49, 51, -49, 52, -52, 5, -51, -8, -53, 53, 3,
01143 -56, 56, 55, 54, -54, 2, 60, -2, -55, 58, 9, -5, 59, 57, -57, -63,
01144 -3, -58, -60, -61, 61, -59, -62, -9, 1, 64, 62, 69, -64, 63, 65, -67,
01145 -68, 66, -65, 68, -66, -69, 67, -70, -1, 10, 71, -71, 4, 73, 72, 70,
01146 6, -76, -3, 74, -78, -74, 1, 78, 80, -72, -75, 76, -1, 3, -73, 79,
01147 75, 77, 1, 11, -4, -79, -10, -6, -1, -77, -83, -80, 2, 81, -84, -2,
01148 83, -81, 82, -82, 84, -87, -86, 85, -11, -85, 86, -89, 87, -88, 88, 89}
01149 },{
01150
01151 2,
01152 33,
01153
01154 {1, 1, 0, 2, 1, 2, 1, 3, 3, 1, 1, 4, 4, 2, 2, 1,
01155 1, 5, 5, 6, 1, 6, 1, 7, 7, 3, 3, 2, 8, 2, 8, 1,
01156 1, 0, 9, 9, 1, 1, 10, 4, 10, 4, 11, 11, 2, 1, 2, 1,
01157 12, 12, 3, 3, 1, 1, 13, 5, 5, 13, 14, 1, 1, 14, 2, 2,
01158 6, 6, 15, 1, 1, 15, 16, 4, 7, 16, 4, 7, 1, 1, 3, 3,
01159 8, 8, 2, 2, 1, 1, 17, 17, 1, 1, 18, 18, 5, 5, 2, 2,
01160 1, 1, 9, 19, 9, 19, 20, 3, 3, 20, 1, 10, 21, 1, 10, 4,
01161 4, 21, 22, 6, 6, 22, 1, 1, 23, 24, 2, 2, 23, 24, 11, 1,
01162 1, 11, 7, 25, 7, 1, 1, 25, 8, 8, 3, 26, 3, 1, 12, 2,
01163 2, 26, 1, 12, 5, 5, 27, 4, 1, 4, 1, 27, 28, 1, 28, 13,
01164 1, 13, 2, 29, 2, 1, 32, 6, 1, 30, 14, 29, 14, 6, 3, 31,
01165 3, 1, 30, 1, 32, 31, 33, 9, 33, 1, 1, 7, 9, 7, 2, 2,
01166 1, 1, 4, 36, 34, 4, 5, 10, 10, 5, 34, 1, 1, 35, 8, 8,
01167 36, 3, 35, 1, 15, 3, 2, 1, 16, 15, 16, 2, 37, 1, 37, 1,
01168 1, 1, 6, 6, 38, 1, 38, 11, 1, 39, 39, 40, 11, 2, 41, 4,
01169 40, 1, 2, 4, 1, 1, 1, 41, 3, 1, 3, 1, 5, 7, 5, 7},
01170
01171
01172 { 1, -1, 0, 1, 2, -1, -2, 1, -1, 3, -3, 1, -1, 2, -2, 4,
01173 -4, 1, -1, 1, 5, -1, -5, 1, -1, 2, -2, 3, 1, -3, -1, 6,
01174 -6, 0, 1, -1, 7, -7, 1, 2, -1, -2, 1, -1, 4, 8, -4, -8,
01175 1, -1, 3, -3, 9, -9, 1, 2, -2, -1, 1, 10, -10, -1, 5, -5,
01176 2, -2, 1, 11, -11, -1, 1, 3, 2, -1, -3, -2, 12, -12, 4, -4,
01177 2, -2, -6, 6, 13, -13, 1, -1, 14, -14, 1, -1, 3, -3, 7, -7,
01178 15, -15, 2, 1, -2, -1, 1, 5, -5, -1, -16, 2, 1, 16, -2, 4,
01179 -4, -1, 1, 3, -3, -1, 17, -17, 1, 1, -8, 8, -1, -1, 2, 18,
01180 -18, -2, 3, 1, -3, 19, -19, -1, 3, -3, 6, 1, -6, 20, 2, 9,
01181 -9, -1, -20, -2, 4, -4, 1, -5, 21, 5, -21, -1, 1, -22, -1, 2,
01182 22, -2, 10, 1, -10, 23, 1, 4, -23, 1, 2, -1, -2, -4, -7, 1,
01183 7, -24, -1, 24, -1, -1, 1, 3, -1, -25, 25, 4, -3, -4, 11, -11,
01184 26, -26, 6, 1, 1, -6, -5, -3, 3, 5, -1, -27, 27, 1, 4, -4,
01185 -1, -8, -1, 28, 2, 8, -12, -28, -2, -2, 2, 12, -1, 29, 1, -29,
01186 30, -30, 5, -5, 1, -31, -1, 3, 31, -1, 1, 1, -3, -13, 1, -7,
01187 -1, -32, 13, 7, 32, 33, -33, -1, -9, -34, 9, 34, -6, 5, 6, -5}
01188 },{
01189
01190 2,
01191 13,
01192
01193 {1, 1, 0, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 0, 2, 2,
01194 4, 1, 4, 1, 1, 1, 5, 5, 1, 1, 6, 6, 2, 2, 1, 1,
01195 3, 3, 7, 7, 1, 1, 8, 8, 1, 1, 2, 2, 1, 9, 1, 9,
01196 4, 4, 10, 1, 1, 10, 1, 1, 11, 11, 3, 3, 1, 2, 1, 2,
01197 1, 1, 12, 12, 5, 5, 1, 1, 13, 1, 1, 13, 2, 2, 1, 1,
01198 6, 6, 1, 1, 4, 14, 4, 14, 3, 1, 3, 1, 1, 1, 15, 7,
01199 15, 2, 2, 7, 1, 1, 1, 8, 1, 8, 16, 16, 1, 1, 1, 1,
01200 2, 1, 1, 2, 1, 1, 3, 5, 5, 3, 4, 1, 1, 4, 1, 1,
01201 17, 17, 9, 1, 1, 9, 2, 2, 1, 1, 10, 10, 1, 6, 1, 1,
01202 6, 18, 1, 1, 18, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 1,
01203 4, 1, 19, 1, 19, 7, 1, 1, 20, 1, 4, 20, 1, 7, 11, 2,
01204 1, 11, 21, 2, 8, 5, 1, 8, 1, 5, 21, 1, 1, 1, 22, 1,
01205 1, 22, 1, 1, 3, 3, 1, 23, 2, 12, 24, 1, 1, 2, 1, 1,
01206 12, 23, 1, 1, 24, 1, 1, 1, 4, 1, 1, 1, 2, 1, 6, 6,
01207 4, 2, 1, 1, 1, 1, 1, 1, 1, 14, 13, 3, 1, 25, 9, 25,
01208 14, 1, 9, 3, 13, 1, 1, 1, 1, 1, 10, 1, 1, 2, 10, 2},
01209
01210
01211 {-20, -1, 0, 2, -2, 1, -1, 3, -3, 1, -1, 4, -4, 0, 2, -2,
01212 1, 5, -1, -5, 6, -6, 1, -1, 7, -7, 1, -1, 3, -3, 8, -8,
01213 2, -2, 1, -1, 9, -9, 1, -1, 10, -10, 4, -4, 11, 1, -11, -1,
01214 2, -2, 1, 12, -12, -1, 13, -13, 1, -1, 3, -3, 14, 5, -14, -5,
01215 -15, 15, -1, 1, 2, -2, 16, -16, 1, 17, -17, -1, 6, -6, 18, -18,
01216 2, -2, -19, 19, -3, 1, 3, -1, 4, 20, -4, 1, -21, 21, 1, 2,
01217 -1, -7, 7, -2, 22, -22, 23, 2, -23, -2, 1, -1, -24, 24, -25, 25,
01218 -8, -26, 26, 8, -27, 27, 5, 3, -3, -5, -4, 28, -28, 4, 29, -29,
01219 1, -1, -2, -30, 30, 2, 9, -9, -31, 31, 2, -2, -32, 3, 32, -33,
01220 -3, 1, 33, -34, -1, 34, -35, 35, -10, 10, -6, 36, 6, -36, 37, -37,
01221 -5, 38, 1, -38, -1, 3, 39, -39, -1, 40, 5, 1, -40, -3, 2, -11,
01222 -41, -2, 1, 11, -3, -4, 41, 3, 42, 4, -1, -43, -42, 43, 1, -44,
01223 45, -1, 44, -45, -7, 7, -46, 1, -12, 2, 1, -47, 46, 12, 47, 48,
01224 -2, -1, -48, 49, -1, -50, -49, 50, -6, -51, 51, 52, -13, 53, -4, 4,
01225 6, 13, -53, -52, -54, 55, 54, -55, -56, -2, 2, -8, 56, 1, -3, -1,
01226 2, 58, 3, 8, -2, 57, -58, -60, -59, -57, -3, 60, 59, -14, 3, 14}
01227 },{
01228
01229 2,
01230 38,
01231
01232 {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 5, 5, 1, 1, 6,
01233 6, 2, 2, 7, 7, 8, 8, 1, 1, 3, 3, 9, 9, 10, 10, 1,
01234 1, 2, 2, 4, 4, 11, 0, 11, 12, 12, 13, 13, 1, 1, 5, 5,
01235 14, 14, 15, 16, 15, 16, 3, 3, 1, 6, 1, 6, 2, 2, 7, 7,
01236 8, 8, 17, 17, 1, 1, 4, 4, 18, 18, 2, 2, 1, 19, 1, 20,
01237 19, 20, 21, 21, 3, 3, 22, 22, 5, 5, 24, 1, 1, 23, 9, 23,
01238 24, 9, 2, 2, 10, 1, 1, 10, 6, 6, 25, 4, 4, 25, 7, 7,
01239 26, 8, 1, 8, 3, 1, 26, 3, 11, 11, 27, 27, 2, 28, 1, 2,
01240 28, 1, 12, 12, 5, 5, 29, 13, 13, 29, 32, 1, 1, 33, 31, 30,
01241 32, 4, 30, 33, 4, 31, 3, 14, 1, 1, 3, 34, 34, 2, 2, 14,
01242 6, 6, 35, 36, 35, 36, 1, 15, 1, 16, 16, 15, 7, 9, 7, 9,
01243 37, 8, 8, 37, 1, 1, 39, 2, 38, 39, 2, 40, 5, 38, 40, 5,
01244 3, 3, 4, 4, 10, 10, 1, 1, 1, 1, 41, 2, 41, 2, 6, 6,
01245 1, 1, 11, 42, 11, 43, 3, 42, 3, 17, 4, 43, 1, 17, 7, 1,
01246 8, 44, 4, 7, 44, 5, 8, 2, 5, 1, 2, 48, 45, 1, 12, 45,
01247 12, 48, 13, 13, 1, 9, 9, 46, 1, 46, 47, 47, 49, 18, 18, 49},
01248
01249
01250 { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 1, -1, 3, -3, 1,
01251 -1, -2, 2, 1, -1, 1, -1, 4, -4, -2, 2, 1, -1, 1, -1, 5,
01252 -5, -3, 3, 2, -2, 1, 0, -1, 1, -1, 1, -1, 6, -6, 2, -2,
01253 1, -1, 1, 1, -1, -1, -3, 3, 7, 2, -7, -2, -4, 4, 2, -2,
01254 2, -2, 1, -1, 8, -8, 3, -3, 1, -1, -5, 5, 9, 1, -9, 1,
01255 -1, -1, 1, -1, -4, 4, 1, -1, 3, -3, 1, -10, 10, 1, 2, -1,
01256 -1, -2, 6, -6, 2, 11, -11, -2, 3, -3, 1, -4, 4, -1, 3, -3,
01257 1, 3, 12, -3, -5, -12, -1, 5, 2, -2, 1, -1, -7, 1, 13, 7,
01258 -1, -13, 2, -2, 4, -4, 1, 2, -2, -1, 1, 14, -14, 1, 1, 1,
01259 -1, -5, -1, -1, 5, -1, -6, 2, -15, 15, 6, 1, -1, -8, 8, -2,
01260 -4, 4, 1, 1, -1, -1, 16, 2, -16, -2, 2, -2, 4, 3, -4, -3,
01261 -1, -4, 4, 1, -17, 17, -1, -9, 1, 1, 9, 1, -5, -1, -1, 5,
01262 -7, 7, 6, -6, 3, -3, 18, -18, 19, -19, 1, -10, -1, 10, -5, 5,
01263 20, -20, -3, 1, 3, 1, 8, -1, -8, 2, 7, -1, -21, -2, 5, 21,
01264 5, -1, -7, -5, 1, -6, -5, -11, 6, 22, 11, 1, 1, -22, -3, -1,
01265 3, -1, 3, -3, -23, 4, -4, 1, 23, -1, 1, -1, 1, -2, 2, -1}
01266 },{
01267
01268 4,
01269 11,
01270
01271 {1, 1, 1, 1, 0, 2, 2, 1, 1, 3, 3, 0, 1, 1, 2, 2,
01272 4, 4, 1, 1, 5, 5, 1, 1, 2, 2, 3, 3, 6, 6, 1, 1,
01273 7, 7, 8, 1, 8, 2, 2, 1, 4, 4, 1, 3, 1, 3, 9, 9,
01274 2, 2, 1, 5, 1, 5, 10, 10, 1, 1, 11, 11, 3, 6, 3, 4,
01275 4, 6, 2, 2, 1, 12, 1, 12, 7, 13, 7, 13, 1, 1, 8, 8,
01276 2, 2, 14, 14, 16, 15, 16, 5, 5, 1, 3, 15, 1, 3, 4, 4,
01277 1, 1, 17, 17, 2, 2, 6, 6, 1, 18, 1, 18, 22, 21, 22, 21,
01278 25, 24, 25, 19, 9, 20, 9, 23, 19, 24, 20, 3, 23, 7, 3, 1,
01279 1, 7, 28, 26, 29, 5, 28, 26, 5, 8, 29, 4, 8, 27, 2, 2,
01280 4, 27, 1, 1, 10, 36, 10, 33, 33, 36, 30, 1, 32, 32, 1, 30,
01281 6, 31, 31, 35, 3, 6, 11, 11, 3, 2, 35, 2, 34, 1, 34, 1,
01282 37, 37, 12, 7, 12, 5, 41, 5, 4, 7, 1, 8, 13, 4, 1, 41,
01283 13, 38, 8, 38, 9, 1, 40, 40, 9, 1, 39, 2, 2, 49, 39, 42,
01284 3, 3, 14, 16, 49, 14, 16, 42, 43, 43, 6, 6, 15, 1, 1, 15,
01285 44, 44, 1, 1, 50, 48, 4, 5, 4, 7, 5, 2, 10, 10, 48, 7,
01286 50, 45, 2, 1, 45, 8, 8, 1, 46, 46, 3, 47, 47, 3, 1, 1},
01287
01288
01289 { 1, -1, 2, -2, 0, 1, -1, 3, -3, 1, -1, 0, 4, -4, 2, -2,
01290 1, -1, 5, -5, 1, -1, 6, -6, 3, -3, 2, -2, 1, -1, 7, -7,
01291 1, -1, 1, 8, -1, 4, -4, -8, 2, -2, 9, 3, -9, -3, 1, -1,
01292 5, -5, 10, 2, -10, -2, 1, -1, 11, -11, 1, -1, -4, 2, 4, 3,
01293 -3, -2, 6, -6, 12, 1, -12, -1, 2, 1, -2, -1, 13, -13, 2, -2,
01294 7, -7, 1, -1, 1, 1, -1, 3, -3, 14, 5, -1, -14, -5, 4, -4,
01295 15, -15, 1, -1, 8, -8, -3, 3, 16, 1, -16, -1, 1, 1, -1, -1,
01296 1, 1, -1, 1, 2, 1, -2, 1, -1, -1, -1, 6, -1, 3, -6, 17,
01297 -17, -3, 1, 1, 1, 4, -1, -1, -4, 3, -1, 5, -3, -1, -9, 9,
01298 -5, 1, 18, -18, 2, 1, -2, 1, -1, -1, 1, 19, -1, 1, -19, -1,
01299 4, 1, -1, 1, 7, -4, -2, 2, -7, 10, -1, -10, 1, 20, -1, -20,
01300 1, -1, 2, 4, -2, 5, 1, -5, 6, -4, 21, 4, 2, -6, -21, -1,
01301 -2, 1, -4, -1, -3, 22, -1, 1, 3, -22, -1, 11, -11, 1, 1, 1,
01302 8, -8, 2, 2, -1, -2, -2, -1, 1, -1, -5, 5, 2, 23, -23, -2,
01303 1, -1, 24, -24, -1, -1, 7, 6, -7, 5, -6, 12, -3, 3, 1, -5,
01304 1, 1, -12, 25, -1, -5, 5, -25, -1, 1, 9, 1, -1, -9, 26, -26}
01305 }
01306 };