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 && band->dc_transform) {
00482 band->dc_transform(&prev_dc, band->buf + buf_offs,
00483 band->pitch, blk_size);
00484 } else
00485 mc_no_delta_func(band->buf + buf_offs,
00486 band->ref_buf + buf_offs + mv_y * band->pitch + mv_x,
00487 band->pitch, mc_type);
00488 }
00489
00490 cbp >>= 1;
00491 }
00492 }
00493
00494 align_get_bits(gb);
00495
00496 return 0;
00497 }
00498
00508 static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
00509 IVITile *tile, int32_t mv_scale)
00510 {
00511 int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;
00512 int offs, mb_offset, row_offset;
00513 IVIMbInfo *mb, *ref_mb;
00514 const int16_t *src;
00515 int16_t *dst;
00516 void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch,
00517 int mc_type);
00518
00519 if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) {
00520 av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches "
00521 "parameters %d in ivi_process_empty_tile()\n",
00522 tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size));
00523 return AVERROR_INVALIDDATA;
00524 }
00525
00526 offs = tile->ypos * band->pitch + tile->xpos;
00527 mb = tile->mbs;
00528 ref_mb = tile->ref_mbs;
00529 row_offset = band->mb_size * band->pitch;
00530 need_mc = 0;
00531
00532 for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) {
00533 mb_offset = offs;
00534
00535 for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) {
00536 mb->xpos = x;
00537 mb->ypos = y;
00538 mb->buf_offs = mb_offset;
00539
00540 mb->type = 1;
00541 mb->cbp = 0;
00542
00543 if (!band->qdelta_present && !band->plane && !band->band_num) {
00544 mb->q_delta = band->glob_quant;
00545 mb->mv_x = 0;
00546 mb->mv_y = 0;
00547 }
00548
00549 if (band->inherit_qdelta && ref_mb)
00550 mb->q_delta = ref_mb->q_delta;
00551
00552 if (band->inherit_mv) {
00553
00554 if (mv_scale) {
00555 mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
00556 mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
00557 } else {
00558 mb->mv_x = ref_mb->mv_x;
00559 mb->mv_y = ref_mb->mv_y;
00560 }
00561 need_mc |= mb->mv_x || mb->mv_y;
00562 }
00563
00564 mb++;
00565 if (ref_mb)
00566 ref_mb++;
00567 mb_offset += band->mb_size;
00568 }
00569 offs += row_offset;
00570 }
00571
00572 if (band->inherit_mv && need_mc) {
00573 num_blocks = (band->mb_size != band->blk_size) ? 4 : 1;
00574 mc_no_delta_func = (band->blk_size == 8) ? ff_ivi_mc_8x8_no_delta
00575 : ff_ivi_mc_4x4_no_delta;
00576
00577 for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {
00578 mv_x = mb->mv_x;
00579 mv_y = mb->mv_y;
00580 if (!band->is_halfpel) {
00581 mc_type = 0;
00582 } else {
00583 mc_type = ((mv_y & 1) << 1) | (mv_x & 1);
00584 mv_x >>= 1;
00585 mv_y >>= 1;
00586 }
00587
00588 for (blk = 0; blk < num_blocks; blk++) {
00589
00590 offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);
00591 mc_no_delta_func(band->buf + offs,
00592 band->ref_buf + offs + mv_y * band->pitch + mv_x,
00593 band->pitch, mc_type);
00594 }
00595 }
00596 } else {
00597
00598 src = band->ref_buf + tile->ypos * band->pitch + tile->xpos;
00599 dst = band->buf + tile->ypos * band->pitch + tile->xpos;
00600 for (y = 0; y < tile->height; y++) {
00601 memcpy(dst, src, tile->width*sizeof(band->buf[0]));
00602 src += band->pitch;
00603 dst += band->pitch;
00604 }
00605 }
00606
00607 return 0;
00608 }
00609
00610
00611 #ifdef DEBUG
00612 uint16_t ivi_calc_band_checksum (IVIBandDesc *band)
00613 {
00614 int x, y;
00615 int16_t *src, checksum;
00616
00617 src = band->buf;
00618 checksum = 0;
00619
00620 for (y = 0; y < band->height; src += band->pitch, y++)
00621 for (x = 0; x < band->width; x++)
00622 checksum += src[x];
00623
00624 return checksum;
00625 }
00626
00627 int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch)
00628 {
00629 int x, y, result;
00630 uint8_t t1, t2;
00631 int16_t *src;
00632
00633 src = band->buf;
00634 result = 0;
00635
00636 for (y = 0; y < band->height; src += band->pitch, y++) {
00637 for (x = 0; x < band->width; x++) {
00638 t1 = av_clip(src[x] + 128, 0, 255);
00639 t2 = ref[x];
00640 if (t1 != t2) {
00641 av_log(NULL, AV_LOG_ERROR, "Data mismatch: row %d, column %d\n",
00642 y / band->blk_size, x / band->blk_size);
00643 result = -1;
00644 }
00645 }
00646 ref += pitch;
00647 }
00648
00649 return result;
00650 }
00651 #endif
00652
00653 void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
00654 {
00655 int x, y;
00656 const int16_t *src = plane->bands[0].buf;
00657 uint32_t pitch = plane->bands[0].pitch;
00658
00659 if (!src)
00660 return;
00661
00662 for (y = 0; y < plane->height; y++) {
00663 for (x = 0; x < plane->width; x++)
00664 dst[x] = av_clip_uint8(src[x] + 128);
00665 src += pitch;
00666 dst += dst_pitch;
00667 }
00668 }
00669
00678 static int decode_band(IVI45DecContext *ctx, int plane_num,
00679 IVIBandDesc *band, AVCodecContext *avctx)
00680 {
00681 int result, i, t, idx1, idx2, pos;
00682 IVITile *tile;
00683
00684 band->buf = band->bufs[ctx->dst_buf];
00685 band->ref_buf = band->bufs[ctx->ref_buf];
00686 band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
00687
00688 result = ctx->decode_band_hdr(ctx, band, avctx);
00689 if (result) {
00690 av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
00691 result);
00692 return result;
00693 }
00694
00695 if (band->is_empty) {
00696 av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
00697 return AVERROR_INVALIDDATA;
00698 }
00699
00700 band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
00701
00702
00703 for (i = 0; i < band->num_corr; i++) {
00704 idx1 = band->corr[i * 2];
00705 idx2 = band->corr[i * 2 + 1];
00706 FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
00707 FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
00708 }
00709
00710 pos = get_bits_count(&ctx->gb);
00711
00712 for (t = 0; t < band->num_tiles; t++) {
00713 tile = &band->tiles[t];
00714
00715 if (tile->mb_size != band->mb_size) {
00716 av_log(avctx, AV_LOG_ERROR, "MB sizes mismatch: %d vs. %d\n",
00717 band->mb_size, tile->mb_size);
00718 return AVERROR_INVALIDDATA;
00719 }
00720 tile->is_empty = get_bits1(&ctx->gb);
00721 if (tile->is_empty) {
00722 result = ivi_process_empty_tile(avctx, band, tile,
00723 (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
00724 if (result < 0)
00725 break;
00726 av_dlog(avctx, "Empty tile encountered!\n");
00727 } else {
00728 tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
00729 if (!tile->data_size) {
00730 av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
00731 return AVERROR_INVALIDDATA;
00732 }
00733
00734 result = ctx->decode_mb_info(ctx, band, tile, avctx);
00735 if (result < 0)
00736 break;
00737
00738 result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
00739 if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
00740 av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
00741 break;
00742 }
00743
00744 pos += tile->data_size << 3;
00745 }
00746 }
00747
00748
00749 for (i = band->num_corr-1; i >= 0; i--) {
00750 idx1 = band->corr[i*2];
00751 idx2 = band->corr[i*2+1];
00752 FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
00753 FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
00754 }
00755
00756 #ifdef DEBUG
00757 if (band->checksum_present) {
00758 uint16_t chksum = ivi_calc_band_checksum(band);
00759 if (chksum != band->checksum) {
00760 av_log(avctx, AV_LOG_ERROR,
00761 "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
00762 band->plane, band->band_num, band->checksum, chksum);
00763 }
00764 }
00765 #endif
00766
00767 align_get_bits(&ctx->gb);
00768
00769 return result;
00770 }
00771
00772 int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00773 AVPacket *avpkt)
00774 {
00775 IVI45DecContext *ctx = avctx->priv_data;
00776 const uint8_t *buf = avpkt->data;
00777 int buf_size = avpkt->size;
00778 int result, p, b;
00779
00780 init_get_bits(&ctx->gb, buf, buf_size * 8);
00781 ctx->frame_data = buf;
00782 ctx->frame_size = buf_size;
00783
00784 result = ctx->decode_pic_hdr(ctx, avctx);
00785 if (result) {
00786 av_log(avctx, AV_LOG_ERROR,
00787 "Error while decoding picture header: %d\n", result);
00788 return -1;
00789 }
00790 if (ctx->gop_invalid)
00791 return AVERROR_INVALIDDATA;
00792
00793 if (ctx->gop_flags & IVI5_IS_PROTECTED) {
00794 av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
00795 return -1;
00796 }
00797
00798 ctx->switch_buffers(ctx);
00799
00800
00801
00802 if (ctx->is_nonnull_frame(ctx)) {
00803 for (p = 0; p < 3; p++) {
00804 for (b = 0; b < ctx->planes[p].num_bands; b++) {
00805 result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
00806 if (result) {
00807 av_log(avctx, AV_LOG_ERROR,
00808 "Error while decoding band: %d, plane: %d\n", b, p);
00809 return -1;
00810 }
00811 }
00812 }
00813 }
00814
00815
00816
00817
00818
00819
00820 if (avctx->codec_id == CODEC_ID_INDEO4 && ctx->frame_type == 0) {
00821 while (get_bits(&ctx->gb, 8));
00822 skip_bits_long(&ctx->gb, 64);
00823 if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
00824 av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
00825 }
00826
00827 if (ctx->frame.data[0])
00828 avctx->release_buffer(avctx, &ctx->frame);
00829
00830 ctx->frame.reference = 0;
00831 avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
00832 if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
00833 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00834 return result;
00835 }
00836
00837 if (ctx->is_scalable) {
00838 if (avctx->codec_id == CODEC_ID_INDEO4)
00839 ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
00840 else
00841 ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
00842 } else {
00843 ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
00844 }
00845
00846 ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
00847 ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
00848
00849 *data_size = sizeof(AVFrame);
00850 *(AVFrame*)data = ctx->frame;
00851
00852 return buf_size;
00853 }
00854
00858 av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
00859 {
00860 IVI45DecContext *ctx = avctx->priv_data;
00861
00862 ff_ivi_free_buffers(&ctx->planes[0]);
00863
00864 if (ctx->mb_vlc.cust_tab.table)
00865 ff_free_vlc(&ctx->mb_vlc.cust_tab);
00866
00867 if (ctx->frame.data[0])
00868 avctx->release_buffer(avctx, &ctx->frame);
00869
00870 #if IVI4_STREAM_ANALYSER
00871 if (avctx->codec_id == CODEC_ID_INDEO4) {
00872 if (ctx->is_scalable)
00873 av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
00874 if (ctx->uses_tiling)
00875 av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
00876 if (ctx->has_b_frames)
00877 av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
00878 if (ctx->has_transp)
00879 av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
00880 if (ctx->uses_haar)
00881 av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
00882 if (ctx->uses_fullpel)
00883 av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
00884 }
00885 #endif
00886
00887 return 0;
00888 }
00889
00890
00897 const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
00898 {8, {0, 4, 5, 4, 4, 4, 6, 6}},
00899 {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
00900 {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
00901 {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
00902 {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
00903 {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}},
00904 {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
00905 {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
00906 };
00907
00908 const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
00909 {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
00910 {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
00911 {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
00912 {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
00913 {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
00914 {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
00915 {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
00916 {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}}
00917 };
00918
00919
00923 const uint8_t ff_ivi_vertical_scan_8x8[64] = {
00924 0, 8, 16, 24, 32, 40, 48, 56,
00925 1, 9, 17, 25, 33, 41, 49, 57,
00926 2, 10, 18, 26, 34, 42, 50, 58,
00927 3, 11, 19, 27, 35, 43, 51, 59,
00928 4, 12, 20, 28, 36, 44, 52, 60,
00929 5, 13, 21, 29, 37, 45, 53, 61,
00930 6, 14, 22, 30, 38, 46, 54, 62,
00931 7, 15, 23, 31, 39, 47, 55, 63
00932 };
00933
00934 const uint8_t ff_ivi_horizontal_scan_8x8[64] = {
00935 0, 1, 2, 3, 4, 5, 6, 7,
00936 8, 9, 10, 11, 12, 13, 14, 15,
00937 16, 17, 18, 19, 20, 21, 22, 23,
00938 24, 25, 26, 27, 28, 29, 30, 31,
00939 32, 33, 34, 35, 36, 37, 38, 39,
00940 40, 41, 42, 43, 44, 45, 46, 47,
00941 48, 49, 50, 51, 52, 53, 54, 55,
00942 56, 57, 58, 59, 60, 61, 62, 63
00943 };
00944
00945 const uint8_t ff_ivi_direct_scan_4x4[16] = {
00946 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
00947 };
00948
00949
00953 const RVMapDesc ff_ivi_rvmap_tabs[9] = {
00954 {
00955 5,
00956 2,
00957
00958 {1, 1, 0, 1, 1, 0, 1, 1, 2, 2, 1, 1, 1, 1, 3, 3,
00959 1, 1, 2, 2, 1, 1, 4, 4, 1, 1, 1, 1, 2, 2, 5, 5,
00960 1, 1, 3, 3, 1, 1, 6, 6, 1, 2, 1, 2, 7, 7, 1, 1,
00961 8, 8, 1, 1, 4, 2, 1, 4, 2, 1, 3, 3, 1, 1, 1, 9,
00962 9, 1, 2, 1, 2, 1, 5, 5, 1, 1, 10, 10, 1, 1, 3, 3,
00963 2, 2, 1, 1, 11, 11, 6, 4, 4, 1, 6, 1, 2, 1, 2, 12,
00964 8, 1, 12, 7, 8, 7, 1, 16, 1, 16, 1, 3, 3, 13, 1, 13,
00965 2, 2, 1, 15, 1, 5, 14, 15, 1, 5, 14, 1, 17, 8, 17, 8,
00966 1, 4, 4, 2, 2, 1, 25, 25, 24, 24, 1, 3, 1, 3, 1, 8,
00967 6, 7, 6, 1, 18, 8, 18, 1, 7, 23, 2, 2, 23, 1, 1, 21,
00968 22, 9, 9, 22, 19, 1, 21, 5, 19, 5, 1, 33, 20, 33, 20, 8,
00969 4, 4, 1, 32, 2, 2, 8, 3, 32, 26, 3, 1, 7, 7, 26, 6,
00970 1, 6, 1, 1, 16, 1, 10, 1, 10, 2, 16, 29, 28, 2, 29, 28,
00971 1, 27, 5, 8, 5, 27, 1, 8, 3, 7, 3, 31, 41, 31, 1, 41,
00972 6, 1, 6, 7, 4, 4, 1, 1, 2, 1, 2, 11, 34, 30, 11, 1,
00973 30, 15, 15, 34, 36, 40, 36, 40, 35, 35, 37, 37, 39, 39, 38, 38},
00974
00975
00976 { 1, -1, 0, 2, -2, 0, 3, -3, 1, -1, 4, -4, 5, -5, 1, -1,
00977 6, -6, 2, -2, 7, -7, 1, -1, 8, -8, 9, -9, 3, -3, 1, -1,
00978 10, -10, 2, -2, 11, -11, 1, -1, 12, 4, -12, -4, 1, -1, 13, -13,
00979 1, -1, 14, -14, 2, 5, 15, -2, -5, -15, -3, 3, 16, -16, 17, 1,
00980 -1, -17, 6, 18, -6, -18, 2, -2, 19, -19, 1, -1, 20, -20, 4, -4,
00981 7, -7, 21, -21, 1, -1, 2, 3, -3, 22, -2, -22, 8, 23, -8, 1,
00982 2, -23, -1, 2, -2, -2, 24, 1, -24, -1, 25, 5, -5, 1, -25, -1,
00983 9, -9, 26, 1, -26, 3, 1, -1, 27, -3, -1, -27, 1, 3, -1, -3,
00984 28, -4, 4, 10, -10, -28, 1, -1, 1, -1, 29, 6, -29, -6, 30, -4,
00985 3, 3, -3, -30, 1, 4, -1, 31, -3, 1, 11, -11, -1, -31, 32, -1,
00986 -1, 2, -2, 1, 1, -32, 1, 4, -1, -4, 33, -1, 1, 1, -1, 5,
00987 5, -5, -33, -1, -12, 12, -5, -7, 1, 1, 7, 34, 4, -4, -1, 4,
00988 -34, -4, 35, 36, -2, -35, -2, -36, 2, 13, 2, -1, 1, -13, 1, -1,
00989 37, 1, -5, 6, 5, -1, 38, -6, -8, 5, 8, -1, 1, 1, -37, -1,
00990 5, 39, -5, -5, 6, -6, -38, -39, -14, 40, 14, 2, 1, 1, -2, -40,
00991 -1, -2, 2, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1}
00992 },{
00993
00994 0,
00995 38,
00996
00997 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 6, 8, 7,
00998 7, 9, 9, 10, 10, 11, 11, 1, 12, 1, 12, 13, 13, 16, 14, 16,
00999 14, 15, 15, 17, 17, 18, 0, 18, 19, 20, 21, 19, 22, 21, 20, 22,
01000 25, 24, 2, 25, 24, 23, 23, 2, 26, 28, 26, 28, 29, 27, 29, 27,
01001 33, 33, 1, 32, 1, 3, 32, 30, 36, 3, 36, 30, 31, 31, 35, 34,
01002 37, 41, 34, 35, 37, 4, 41, 4, 49, 8, 8, 49, 40, 38, 5, 38,
01003 40, 39, 5, 39, 42, 43, 42, 7, 57, 6, 43, 44, 6, 50, 7, 44,
01004 57, 48, 50, 48, 45, 45, 46, 47, 51, 46, 47, 58, 1, 51, 58, 1,
01005 52, 59, 53, 9, 52, 55, 55, 59, 53, 56, 54, 56, 54, 9, 64, 64,
01006 60, 63, 60, 63, 61, 62, 61, 62, 2, 10, 2, 10, 11, 1, 11, 13,
01007 12, 1, 12, 13, 16, 16, 8, 8, 14, 3, 3, 15, 14, 15, 4, 4,
01008 1, 17, 17, 5, 1, 7, 7, 5, 6, 1, 2, 2, 6, 22, 1, 25,
01009 21, 22, 8, 24, 1, 21, 25, 24, 8, 18, 18, 23, 9, 20, 23, 33,
01010 29, 33, 20, 1, 19, 1, 29, 36, 9, 36, 19, 41, 28, 57, 32, 3,
01011 28, 3, 1, 27, 49, 49, 1, 32, 26, 26, 2, 4, 4, 7, 57, 41,
01012 2, 7, 10, 5, 37, 16, 10, 27, 8, 8, 13, 16, 37, 13, 1, 5},
01013
01014
01015 {0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1,
01016 -1, 1, -1, 1, -1, 1, -1, 2, 1, -2, -1, 1, -1, 1, 1, -1,
01017 -1, 1, -1, 1, -1, 1, 0, -1, 1, 1, 1, -1, 1, -1, -1, -1,
01018 1, 1, 2, -1, -1, 1, -1, -2, 1, 1, -1, -1, 1, 1, -1, -1,
01019 1, -1, 3, 1, -3, 2, -1, 1, 1, -2, -1, -1, -1, 1, 1, 1,
01020 1, 1, -1, -1, -1, 2, -1, -2, 1, 2, -2, -1, 1, 1, 2, -1,
01021 -1, 1, -2, -1, 1, 1, -1, 2, 1, 2, -1, 1, -2, -1, -2, -1,
01022 -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 4, -1, -1, -4,
01023 1, 1, 1, 2, -1, -1, 1, -1, -1, 1, -1, -1, 1, -2, 1, -1,
01024 1, 1, -1, -1, 1, 1, -1, -1, 3, 2, -3, -2, 2, 5, -2, 2,
01025 2, -5, -2, -2, -2, 2, -3, 3, 2, 3, -3, 2, -2, -2, 3, -3,
01026 6, 2, -2, 3, -6, 3, -3, -3, 3, 7, -4, 4, -3, 2, -7, 2,
01027 2, -2, -4, 2, 8, -2, -2, -2, 4, 2, -2, 2, 3, 2, -2, -2,
01028 2, 2, -2, -8, -2, 9, -2, 2, -3, -2, 2, -2, 2, 2, 2, 4,
01029 -2, -4, 10, 2, 2, -2, -9, -2, 2, -2, 5, 4, -4, 4, -2, 2,
01030 -5, -4, -3, 4, 2, -3, 3, -2, -5, 5, 3, 3, -2, -3, -10, -4}
01031 },{
01032
01033 2,
01034 11,
01035
01036 {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 0, 1, 1, 5, 5,
01037 2, 2, 6, 6, 7, 7, 1, 8, 1, 8, 3, 3, 9, 9, 1, 2,
01038 2, 1, 4, 10, 4, 10, 11, 11, 1, 5, 12, 12, 1, 5, 13, 13,
01039 3, 3, 6, 6, 2, 2, 14, 14, 16, 16, 15, 7, 15, 8, 8, 7,
01040 1, 1, 17, 17, 4, 4, 1, 1, 18, 18, 2, 2, 5, 5, 25, 3,
01041 9, 3, 25, 9, 19, 24, 19, 24, 1, 21, 20, 1, 21, 22, 20, 22,
01042 23, 23, 8, 6, 33, 6, 8, 33, 7, 7, 26, 26, 1, 32, 1, 32,
01043 28, 4, 28, 10, 29, 27, 27, 10, 41, 4, 29, 2, 2, 41, 36, 31,
01044 49, 31, 34, 30, 34, 36, 30, 35, 1, 49, 11, 5, 35, 11, 1, 3,
01045 3, 5, 37, 37, 8, 40, 8, 40, 12, 12, 42, 42, 1, 38, 16, 57,
01046 1, 6, 16, 39, 38, 6, 7, 7, 13, 13, 39, 43, 2, 43, 57, 2,
01047 50, 9, 44, 9, 50, 4, 15, 48, 44, 4, 1, 15, 48, 14, 14, 1,
01048 45, 45, 8, 3, 5, 8, 51, 47, 3, 46, 46, 47, 5, 51, 1, 17,
01049 17, 58, 1, 58, 2, 52, 52, 2, 53, 7, 59, 6, 6, 56, 53, 55,
01050 7, 55, 1, 54, 59, 56, 54, 10, 1, 10, 4, 60, 1, 60, 8, 4,
01051 8, 64, 64, 61, 1, 63, 3, 63, 62, 61, 5, 11, 5, 3, 11, 62},
01052
01053
01054 { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 0, 3, -3, 1, -1,
01055 2, -2, 1, -1, 1, -1, 4, 1, -4, -1, 2, -2, 1, -1, 5, 3,
01056 -3, -5, 2, 1, -2, -1, 1, -1, 6, 2, 1, -1, -6, -2, 1, -1,
01057 3, -3, 2, -2, 4, -4, 1, -1, 1, -1, 1, 2, -1, 2, -2, -2,
01058 7, -7, 1, -1, 3, -3, 8, -8, 1, -1, 5, -5, 3, -3, 1, 4,
01059 2, -4, -1, -2, 1, 1, -1, -1, 9, 1, 1, -9, -1, 1, -1, -1,
01060 1, -1, 3, -3, 1, 3, -3, -1, 3, -3, 1, -1, 10, 1, -10, -1,
01061 1, 4, -1, 2, 1, -1, 1, -2, 1, -4, -1, 6, -6, -1, 1, 1,
01062 1, -1, 1, 1, -1, -1, -1, 1, 11, -1, -2, 4, -1, 2, -11, 5,
01063 -5, -4, -1, 1, 4, 1, -4, -1, -2, 2, 1, -1, 12, 1, -2, 1,
01064 -12, 4, 2, 1, -1, -4, 4, -4, 2, -2, -1, 1, 7, -1, -1, -7,
01065 -1, -3, 1, 3, 1, 5, 2, 1, -1, -5, 13, -2, -1, 2, -2, -13,
01066 1, -1, 5, 6, 5, -5, 1, 1, -6, 1, -1, -1, -5, -1, 14, 2,
01067 -2, 1, -14, -1, 8, 1, -1, -8, 1, 5, 1, 5, -5, 1, -1, 1,
01068 -5, -1, 15, 1, -1, -1, -1, 3, -15, -3, 6, 1, 16, -1, 6, -6,
01069 -6, 1, -1, 1, -16, 1, 7, -1, 1, -1, -6, -3, 6, -7, 3, -1}
01070 },{
01071
01072 0,
01073 35,
01074
01075 {0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 5, 5, 6, 6, 7,
01076 7, 8, 8, 9, 9, 2, 2, 10, 10, 1, 1, 11, 11, 12, 12, 3,
01077 3, 13, 13, 0, 14, 14, 16, 15, 16, 15, 4, 4, 17, 1, 17, 1,
01078 5, 5, 18, 18, 2, 2, 6, 6, 8, 19, 7, 8, 7, 19, 20, 20,
01079 21, 21, 22, 24, 22, 24, 23, 23, 1, 1, 25, 25, 3, 3, 26, 26,
01080 9, 9, 27, 27, 28, 28, 33, 29, 4, 33, 29, 1, 4, 1, 32, 32,
01081 2, 2, 31, 10, 30, 10, 30, 31, 34, 34, 5, 5, 36, 36, 35, 41,
01082 35, 11, 41, 11, 37, 1, 8, 8, 37, 6, 1, 6, 40, 7, 7, 40,
01083 12, 38, 12, 39, 39, 38, 49, 13, 49, 13, 3, 42, 3, 42, 16, 16,
01084 43, 43, 14, 14, 1, 1, 44, 15, 44, 15, 2, 2, 57, 48, 50, 48,
01085 57, 50, 4, 45, 45, 4, 46, 47, 47, 46, 1, 51, 1, 17, 17, 51,
01086 8, 9, 9, 5, 58, 8, 58, 5, 52, 52, 55, 56, 53, 56, 55, 59,
01087 59, 53, 54, 1, 6, 54, 7, 7, 6, 1, 2, 3, 2, 3, 64, 60,
01088 60, 10, 10, 64, 61, 62, 61, 63, 1, 63, 62, 1, 18, 24, 18, 4,
01089 25, 4, 8, 21, 21, 1, 24, 22, 25, 22, 8, 11, 19, 11, 23, 1,
01090 20, 23, 19, 20, 5, 12, 5, 1, 16, 2, 12, 13, 2, 13, 1, 16},
01091
01092
01093 { 0, 1, -1, 1, -1, 1, -1, 1, -1, 2, -2, 1, -1, 1, -1, 1,
01094 -1, 1, -1, 1, -1, 2, -2, 1, -1, 3, -3, 1, -1, 1, -1, 2,
01095 -2, 1, -1, 0, 1, -1, 1, 1, -1, -1, 2, -2, 1, 4, -1, -4,
01096 2, -2, 1, -1, -3, 3, 2, -2, 2, 1, 2, -2, -2, -1, 1, -1,
01097 1, -1, 1, 1, -1, -1, 1, -1, 5, -5, 1, -1, 3, -3, 1, -1,
01098 2, -2, 1, -1, 1, -1, 1, 1, 3, -1, -1, 6, -3, -6, -1, 1,
01099 4, -4, 1, 2, 1, -2, -1, -1, 1, -1, 3, -3, 1, -1, 1, 1,
01100 -1, 2, -1, -2, 1, 7, -3, 3, -1, 3, -7, -3, 1, -3, 3, -1,
01101 2, 1, -2, 1, -1, -1, 1, 2, -1, -2, -4, -1, 4, 1, 2, -2,
01102 1, -1, -2, 2, 8, -8, -1, 2, 1, -2, -5, 5, 1, -1, -1, 1,
01103 -1, 1, 4, -1, 1, -4, -1, -1, 1, 1, 9, 1, -9, 2, -2, -1,
01104 -4, 3, -3, -4, -1, 4, 1, 4, 1, -1, 1, -1, 1, 1, -1, 1,
01105 -1, -1, -1, 10, 4, 1, 4, -4, -4, -10, 6, 5, -6, -5, 1, -1,
01106 1, 3, -3, -1, 1, -1, -1, -1, 11, 1, 1, -11, -2, -2, 2, 5,
01107 -2, -5, -5, 2, -2, 12, 2, -2, 2, 2, 5, -3, -2, 3, -2, -12,
01108 -2, 2, 2, 2, -5, 3, 5, 13, -3, 7, -3, -3, -7, 3, -13, 3}
01109 },{
01110
01111 0,
01112 34,
01113
01114 {0, 1, 1, 1, 2, 2, 1, 3, 3, 1, 1, 1, 4, 4, 1, 5,
01115 2, 1, 5, 2, 1, 1, 6, 6, 1, 1, 1, 1, 1, 7, 3, 1,
01116 2, 3, 0, 1, 2, 7, 1, 1, 1, 8, 1, 1, 8, 1, 1, 1,
01117 9, 1, 9, 1, 2, 1, 1, 2, 1, 1, 10, 4, 1, 10, 1, 4,
01118 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 2, 1, 5, 1, 1, 1,
01119 2, 5, 1, 11, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
01120 2, 1, 6, 1, 6, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 12,
01121 3, 1, 12, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1,
01122 4, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 1, 2, 1,
01123 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 5,
01124 1, 1, 1, 1, 1, 7, 1, 7, 1, 1, 2, 3, 1, 1, 1, 1,
01125 5, 1, 1, 1, 1, 1, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1,
01126 1, 1, 1, 1, 1, 1, 1, 1, 13, 2, 1, 1, 4, 1, 1, 1,
01127 3, 1, 6, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 6, 1, 1,
01128 1, 1, 15, 2, 4, 1, 2, 3, 15, 1, 1, 1, 8, 1, 1, 8,
01129 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1},
01130
01131
01132 { 0, 1, -1, 2, 1, -1, -2, 1, -1, 3, -3, 4, 1, -1, -4, 1,
01133 2, 5, -1, -2, -5, 6, 1, -1, -6, 7, -7, 8, -8, 1, 2, 9,
01134 3, -2, 0, -9, -3, -1, 10, -10, 11, 1, -11, 12, -1, -12, 13, -13,
01135 1, 14, -1, -14, 4, 15, -15, -4, 16, -16, 1, 2, 17, -1, -17, -2,
01136 18, -18, 19, -19, 20, 3, -20, 21, -21, -3, 5, 22, 2, -22, -23, 23,
01137 -5, -2, 24, 1, -24, -1, 25, -25, 26, -26, -27, 27, 28, 29, -28, -29,
01138 6, 30, 2, -31, -2, -30, 31, -6, -32, 32, 33, -33, 34, -35, -34, 1,
01139 4, -36, -1, 35, 37, 36, 7, -37, 38, -4, -38, 39, 41, 40, -40, -39,
01140 3, 42, -43, -41, -7, -42, 43, -3, 44, -44, 45, -45, 46, 47, 8, -47,
01141 -48, -46, 50, -50, 48, 49, 51, -49, 52, -52, 5, -51, -8, -53, 53, 3,
01142 -56, 56, 55, 54, -54, 2, 60, -2, -55, 58, 9, -5, 59, 57, -57, -63,
01143 -3, -58, -60, -61, 61, -59, -62, -9, 1, 64, 62, 69, -64, 63, 65, -67,
01144 -68, 66, -65, 68, -66, -69, 67, -70, -1, 10, 71, -71, 4, 73, 72, 70,
01145 6, -76, -3, 74, -78, -74, 1, 78, 80, -72, -75, 76, -1, 3, -73, 79,
01146 75, 77, 1, 11, -4, -79, -10, -6, -1, -77, -83, -80, 2, 81, -84, -2,
01147 83, -81, 82, -82, 84, -87, -86, 85, -11, -85, 86, -89, 87, -88, 88, 89}
01148 },{
01149
01150 2,
01151 33,
01152
01153 {1, 1, 0, 2, 1, 2, 1, 3, 3, 1, 1, 4, 4, 2, 2, 1,
01154 1, 5, 5, 6, 1, 6, 1, 7, 7, 3, 3, 2, 8, 2, 8, 1,
01155 1, 0, 9, 9, 1, 1, 10, 4, 10, 4, 11, 11, 2, 1, 2, 1,
01156 12, 12, 3, 3, 1, 1, 13, 5, 5, 13, 14, 1, 1, 14, 2, 2,
01157 6, 6, 15, 1, 1, 15, 16, 4, 7, 16, 4, 7, 1, 1, 3, 3,
01158 8, 8, 2, 2, 1, 1, 17, 17, 1, 1, 18, 18, 5, 5, 2, 2,
01159 1, 1, 9, 19, 9, 19, 20, 3, 3, 20, 1, 10, 21, 1, 10, 4,
01160 4, 21, 22, 6, 6, 22, 1, 1, 23, 24, 2, 2, 23, 24, 11, 1,
01161 1, 11, 7, 25, 7, 1, 1, 25, 8, 8, 3, 26, 3, 1, 12, 2,
01162 2, 26, 1, 12, 5, 5, 27, 4, 1, 4, 1, 27, 28, 1, 28, 13,
01163 1, 13, 2, 29, 2, 1, 32, 6, 1, 30, 14, 29, 14, 6, 3, 31,
01164 3, 1, 30, 1, 32, 31, 33, 9, 33, 1, 1, 7, 9, 7, 2, 2,
01165 1, 1, 4, 36, 34, 4, 5, 10, 10, 5, 34, 1, 1, 35, 8, 8,
01166 36, 3, 35, 1, 15, 3, 2, 1, 16, 15, 16, 2, 37, 1, 37, 1,
01167 1, 1, 6, 6, 38, 1, 38, 11, 1, 39, 39, 40, 11, 2, 41, 4,
01168 40, 1, 2, 4, 1, 1, 1, 41, 3, 1, 3, 1, 5, 7, 5, 7},
01169
01170
01171 { 1, -1, 0, 1, 2, -1, -2, 1, -1, 3, -3, 1, -1, 2, -2, 4,
01172 -4, 1, -1, 1, 5, -1, -5, 1, -1, 2, -2, 3, 1, -3, -1, 6,
01173 -6, 0, 1, -1, 7, -7, 1, 2, -1, -2, 1, -1, 4, 8, -4, -8,
01174 1, -1, 3, -3, 9, -9, 1, 2, -2, -1, 1, 10, -10, -1, 5, -5,
01175 2, -2, 1, 11, -11, -1, 1, 3, 2, -1, -3, -2, 12, -12, 4, -4,
01176 2, -2, -6, 6, 13, -13, 1, -1, 14, -14, 1, -1, 3, -3, 7, -7,
01177 15, -15, 2, 1, -2, -1, 1, 5, -5, -1, -16, 2, 1, 16, -2, 4,
01178 -4, -1, 1, 3, -3, -1, 17, -17, 1, 1, -8, 8, -1, -1, 2, 18,
01179 -18, -2, 3, 1, -3, 19, -19, -1, 3, -3, 6, 1, -6, 20, 2, 9,
01180 -9, -1, -20, -2, 4, -4, 1, -5, 21, 5, -21, -1, 1, -22, -1, 2,
01181 22, -2, 10, 1, -10, 23, 1, 4, -23, 1, 2, -1, -2, -4, -7, 1,
01182 7, -24, -1, 24, -1, -1, 1, 3, -1, -25, 25, 4, -3, -4, 11, -11,
01183 26, -26, 6, 1, 1, -6, -5, -3, 3, 5, -1, -27, 27, 1, 4, -4,
01184 -1, -8, -1, 28, 2, 8, -12, -28, -2, -2, 2, 12, -1, 29, 1, -29,
01185 30, -30, 5, -5, 1, -31, -1, 3, 31, -1, 1, 1, -3, -13, 1, -7,
01186 -1, -32, 13, 7, 32, 33, -33, -1, -9, -34, 9, 34, -6, 5, 6, -5}
01187 },{
01188
01189 2,
01190 13,
01191
01192 {1, 1, 0, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 0, 2, 2,
01193 4, 1, 4, 1, 1, 1, 5, 5, 1, 1, 6, 6, 2, 2, 1, 1,
01194 3, 3, 7, 7, 1, 1, 8, 8, 1, 1, 2, 2, 1, 9, 1, 9,
01195 4, 4, 10, 1, 1, 10, 1, 1, 11, 11, 3, 3, 1, 2, 1, 2,
01196 1, 1, 12, 12, 5, 5, 1, 1, 13, 1, 1, 13, 2, 2, 1, 1,
01197 6, 6, 1, 1, 4, 14, 4, 14, 3, 1, 3, 1, 1, 1, 15, 7,
01198 15, 2, 2, 7, 1, 1, 1, 8, 1, 8, 16, 16, 1, 1, 1, 1,
01199 2, 1, 1, 2, 1, 1, 3, 5, 5, 3, 4, 1, 1, 4, 1, 1,
01200 17, 17, 9, 1, 1, 9, 2, 2, 1, 1, 10, 10, 1, 6, 1, 1,
01201 6, 18, 1, 1, 18, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 1,
01202 4, 1, 19, 1, 19, 7, 1, 1, 20, 1, 4, 20, 1, 7, 11, 2,
01203 1, 11, 21, 2, 8, 5, 1, 8, 1, 5, 21, 1, 1, 1, 22, 1,
01204 1, 22, 1, 1, 3, 3, 1, 23, 2, 12, 24, 1, 1, 2, 1, 1,
01205 12, 23, 1, 1, 24, 1, 1, 1, 4, 1, 1, 1, 2, 1, 6, 6,
01206 4, 2, 1, 1, 1, 1, 1, 1, 1, 14, 13, 3, 1, 25, 9, 25,
01207 14, 1, 9, 3, 13, 1, 1, 1, 1, 1, 10, 1, 1, 2, 10, 2},
01208
01209
01210 {-20, -1, 0, 2, -2, 1, -1, 3, -3, 1, -1, 4, -4, 0, 2, -2,
01211 1, 5, -1, -5, 6, -6, 1, -1, 7, -7, 1, -1, 3, -3, 8, -8,
01212 2, -2, 1, -1, 9, -9, 1, -1, 10, -10, 4, -4, 11, 1, -11, -1,
01213 2, -2, 1, 12, -12, -1, 13, -13, 1, -1, 3, -3, 14, 5, -14, -5,
01214 -15, 15, -1, 1, 2, -2, 16, -16, 1, 17, -17, -1, 6, -6, 18, -18,
01215 2, -2, -19, 19, -3, 1, 3, -1, 4, 20, -4, 1, -21, 21, 1, 2,
01216 -1, -7, 7, -2, 22, -22, 23, 2, -23, -2, 1, -1, -24, 24, -25, 25,
01217 -8, -26, 26, 8, -27, 27, 5, 3, -3, -5, -4, 28, -28, 4, 29, -29,
01218 1, -1, -2, -30, 30, 2, 9, -9, -31, 31, 2, -2, -32, 3, 32, -33,
01219 -3, 1, 33, -34, -1, 34, -35, 35, -10, 10, -6, 36, 6, -36, 37, -37,
01220 -5, 38, 1, -38, -1, 3, 39, -39, -1, 40, 5, 1, -40, -3, 2, -11,
01221 -41, -2, 1, 11, -3, -4, 41, 3, 42, 4, -1, -43, -42, 43, 1, -44,
01222 45, -1, 44, -45, -7, 7, -46, 1, -12, 2, 1, -47, 46, 12, 47, 48,
01223 -2, -1, -48, 49, -1, -50, -49, 50, -6, -51, 51, 52, -13, 53, -4, 4,
01224 6, 13, -53, -52, -54, 55, 54, -55, -56, -2, 2, -8, 56, 1, -3, -1,
01225 2, 58, 3, 8, -2, 57, -58, -60, -59, -57, -3, 60, 59, -14, 3, 14}
01226 },{
01227
01228 2,
01229 38,
01230
01231 {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 5, 5, 1, 1, 6,
01232 6, 2, 2, 7, 7, 8, 8, 1, 1, 3, 3, 9, 9, 10, 10, 1,
01233 1, 2, 2, 4, 4, 11, 0, 11, 12, 12, 13, 13, 1, 1, 5, 5,
01234 14, 14, 15, 16, 15, 16, 3, 3, 1, 6, 1, 6, 2, 2, 7, 7,
01235 8, 8, 17, 17, 1, 1, 4, 4, 18, 18, 2, 2, 1, 19, 1, 20,
01236 19, 20, 21, 21, 3, 3, 22, 22, 5, 5, 24, 1, 1, 23, 9, 23,
01237 24, 9, 2, 2, 10, 1, 1, 10, 6, 6, 25, 4, 4, 25, 7, 7,
01238 26, 8, 1, 8, 3, 1, 26, 3, 11, 11, 27, 27, 2, 28, 1, 2,
01239 28, 1, 12, 12, 5, 5, 29, 13, 13, 29, 32, 1, 1, 33, 31, 30,
01240 32, 4, 30, 33, 4, 31, 3, 14, 1, 1, 3, 34, 34, 2, 2, 14,
01241 6, 6, 35, 36, 35, 36, 1, 15, 1, 16, 16, 15, 7, 9, 7, 9,
01242 37, 8, 8, 37, 1, 1, 39, 2, 38, 39, 2, 40, 5, 38, 40, 5,
01243 3, 3, 4, 4, 10, 10, 1, 1, 1, 1, 41, 2, 41, 2, 6, 6,
01244 1, 1, 11, 42, 11, 43, 3, 42, 3, 17, 4, 43, 1, 17, 7, 1,
01245 8, 44, 4, 7, 44, 5, 8, 2, 5, 1, 2, 48, 45, 1, 12, 45,
01246 12, 48, 13, 13, 1, 9, 9, 46, 1, 46, 47, 47, 49, 18, 18, 49},
01247
01248
01249 { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 1, -1, 3, -3, 1,
01250 -1, -2, 2, 1, -1, 1, -1, 4, -4, -2, 2, 1, -1, 1, -1, 5,
01251 -5, -3, 3, 2, -2, 1, 0, -1, 1, -1, 1, -1, 6, -6, 2, -2,
01252 1, -1, 1, 1, -1, -1, -3, 3, 7, 2, -7, -2, -4, 4, 2, -2,
01253 2, -2, 1, -1, 8, -8, 3, -3, 1, -1, -5, 5, 9, 1, -9, 1,
01254 -1, -1, 1, -1, -4, 4, 1, -1, 3, -3, 1, -10, 10, 1, 2, -1,
01255 -1, -2, 6, -6, 2, 11, -11, -2, 3, -3, 1, -4, 4, -1, 3, -3,
01256 1, 3, 12, -3, -5, -12, -1, 5, 2, -2, 1, -1, -7, 1, 13, 7,
01257 -1, -13, 2, -2, 4, -4, 1, 2, -2, -1, 1, 14, -14, 1, 1, 1,
01258 -1, -5, -1, -1, 5, -1, -6, 2, -15, 15, 6, 1, -1, -8, 8, -2,
01259 -4, 4, 1, 1, -1, -1, 16, 2, -16, -2, 2, -2, 4, 3, -4, -3,
01260 -1, -4, 4, 1, -17, 17, -1, -9, 1, 1, 9, 1, -5, -1, -1, 5,
01261 -7, 7, 6, -6, 3, -3, 18, -18, 19, -19, 1, -10, -1, 10, -5, 5,
01262 20, -20, -3, 1, 3, 1, 8, -1, -8, 2, 7, -1, -21, -2, 5, 21,
01263 5, -1, -7, -5, 1, -6, -5, -11, 6, 22, 11, 1, 1, -22, -3, -1,
01264 3, -1, 3, -3, -23, 4, -4, 1, 23, -1, 1, -1, 1, -2, 2, -1}
01265 },{
01266
01267 4,
01268 11,
01269
01270 {1, 1, 1, 1, 0, 2, 2, 1, 1, 3, 3, 0, 1, 1, 2, 2,
01271 4, 4, 1, 1, 5, 5, 1, 1, 2, 2, 3, 3, 6, 6, 1, 1,
01272 7, 7, 8, 1, 8, 2, 2, 1, 4, 4, 1, 3, 1, 3, 9, 9,
01273 2, 2, 1, 5, 1, 5, 10, 10, 1, 1, 11, 11, 3, 6, 3, 4,
01274 4, 6, 2, 2, 1, 12, 1, 12, 7, 13, 7, 13, 1, 1, 8, 8,
01275 2, 2, 14, 14, 16, 15, 16, 5, 5, 1, 3, 15, 1, 3, 4, 4,
01276 1, 1, 17, 17, 2, 2, 6, 6, 1, 18, 1, 18, 22, 21, 22, 21,
01277 25, 24, 25, 19, 9, 20, 9, 23, 19, 24, 20, 3, 23, 7, 3, 1,
01278 1, 7, 28, 26, 29, 5, 28, 26, 5, 8, 29, 4, 8, 27, 2, 2,
01279 4, 27, 1, 1, 10, 36, 10, 33, 33, 36, 30, 1, 32, 32, 1, 30,
01280 6, 31, 31, 35, 3, 6, 11, 11, 3, 2, 35, 2, 34, 1, 34, 1,
01281 37, 37, 12, 7, 12, 5, 41, 5, 4, 7, 1, 8, 13, 4, 1, 41,
01282 13, 38, 8, 38, 9, 1, 40, 40, 9, 1, 39, 2, 2, 49, 39, 42,
01283 3, 3, 14, 16, 49, 14, 16, 42, 43, 43, 6, 6, 15, 1, 1, 15,
01284 44, 44, 1, 1, 50, 48, 4, 5, 4, 7, 5, 2, 10, 10, 48, 7,
01285 50, 45, 2, 1, 45, 8, 8, 1, 46, 46, 3, 47, 47, 3, 1, 1},
01286
01287
01288 { 1, -1, 2, -2, 0, 1, -1, 3, -3, 1, -1, 0, 4, -4, 2, -2,
01289 1, -1, 5, -5, 1, -1, 6, -6, 3, -3, 2, -2, 1, -1, 7, -7,
01290 1, -1, 1, 8, -1, 4, -4, -8, 2, -2, 9, 3, -9, -3, 1, -1,
01291 5, -5, 10, 2, -10, -2, 1, -1, 11, -11, 1, -1, -4, 2, 4, 3,
01292 -3, -2, 6, -6, 12, 1, -12, -1, 2, 1, -2, -1, 13, -13, 2, -2,
01293 7, -7, 1, -1, 1, 1, -1, 3, -3, 14, 5, -1, -14, -5, 4, -4,
01294 15, -15, 1, -1, 8, -8, -3, 3, 16, 1, -16, -1, 1, 1, -1, -1,
01295 1, 1, -1, 1, 2, 1, -2, 1, -1, -1, -1, 6, -1, 3, -6, 17,
01296 -17, -3, 1, 1, 1, 4, -1, -1, -4, 3, -1, 5, -3, -1, -9, 9,
01297 -5, 1, 18, -18, 2, 1, -2, 1, -1, -1, 1, 19, -1, 1, -19, -1,
01298 4, 1, -1, 1, 7, -4, -2, 2, -7, 10, -1, -10, 1, 20, -1, -20,
01299 1, -1, 2, 4, -2, 5, 1, -5, 6, -4, 21, 4, 2, -6, -21, -1,
01300 -2, 1, -4, -1, -3, 22, -1, 1, 3, -22, -1, 11, -11, 1, 1, 1,
01301 8, -8, 2, 2, -1, -2, -2, -1, 1, -1, -5, 5, 2, 23, -23, -2,
01302 1, -1, 24, -24, -1, -1, 7, 6, -7, 5, -6, 12, -3, 3, 1, -5,
01303 1, 1, -12, 25, -1, -5, 5, -25, -1, 1, 9, 1, -1, -9, 26, -26}
01304 }
01305 };