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