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 ctx->switch_buffers(ctx);
00896
00897
00898
00899 if (ctx->is_nonnull_frame(ctx)) {
00900 for (p = 0; p < 3; p++) {
00901 for (b = 0; b < ctx->planes[p].num_bands; b++) {
00902 result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
00903 if (result < 0) {
00904 av_log(avctx, AV_LOG_ERROR,
00905 "Error while decoding band: %d, plane: %d\n", b, p);
00906 return result;
00907 }
00908 }
00909 }
00910 } else {
00911 if (ctx->is_scalable)
00912 return AVERROR_INVALIDDATA;
00913
00914 for (p = 0; p < 3; p++) {
00915 if (!ctx->planes[p].bands[0].buf)
00916 return AVERROR_INVALIDDATA;
00917 }
00918 }
00919
00920
00921
00922
00923
00924
00925 if (avctx->codec_id == CODEC_ID_INDEO4 &&
00926 ctx->frame_type == 0) {
00927 while (get_bits(&ctx->gb, 8));
00928 skip_bits_long(&ctx->gb, 64);
00929 if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
00930 av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
00931 }
00932
00933 if (ctx->frame.data[0])
00934 avctx->release_buffer(avctx, &ctx->frame);
00935
00936 ctx->frame.reference = 0;
00937 avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
00938 if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
00939 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00940 return result;
00941 }
00942
00943 if (ctx->is_scalable) {
00944 if (avctx->codec_id == CODEC_ID_INDEO4)
00945 ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
00946 else
00947 ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
00948 } else {
00949 ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
00950 }
00951
00952 ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
00953 ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
00954
00955 *data_size = sizeof(AVFrame);
00956 *(AVFrame*)data = ctx->frame;
00957
00958 return buf_size;
00959 }
00960
00964 av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
00965 {
00966 IVI45DecContext *ctx = avctx->priv_data;
00967
00968 ff_ivi_free_buffers(&ctx->planes[0]);
00969
00970 if (ctx->mb_vlc.cust_tab.table)
00971 ff_free_vlc(&ctx->mb_vlc.cust_tab);
00972
00973 if (ctx->frame.data[0])
00974 avctx->release_buffer(avctx, &ctx->frame);
00975
00976 #if IVI4_STREAM_ANALYSER
00977 if (avctx->codec_id == CODEC_ID_INDEO4) {
00978 if (ctx->is_scalable)
00979 av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
00980 if (ctx->uses_tiling)
00981 av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
00982 if (ctx->has_b_frames)
00983 av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
00984 if (ctx->has_transp)
00985 av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
00986 if (ctx->uses_haar)
00987 av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
00988 if (ctx->uses_fullpel)
00989 av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
00990 }
00991 #endif
00992
00993 return 0;
00994 }
00995
00996
01003 const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
01004 {8, {0, 4, 5, 4, 4, 4, 6, 6}},
01005 {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
01006 {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
01007 {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
01008 {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
01009 {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}},
01010 {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
01011 {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
01012 };
01013
01014 const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
01015 {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
01016 {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
01017 {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
01018 {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
01019 {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
01020 {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
01021 {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
01022 {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}}
01023 };
01024
01025
01029 const uint8_t ff_ivi_vertical_scan_8x8[64] = {
01030 0, 8, 16, 24, 32, 40, 48, 56,
01031 1, 9, 17, 25, 33, 41, 49, 57,
01032 2, 10, 18, 26, 34, 42, 50, 58,
01033 3, 11, 19, 27, 35, 43, 51, 59,
01034 4, 12, 20, 28, 36, 44, 52, 60,
01035 5, 13, 21, 29, 37, 45, 53, 61,
01036 6, 14, 22, 30, 38, 46, 54, 62,
01037 7, 15, 23, 31, 39, 47, 55, 63
01038 };
01039
01040 const uint8_t ff_ivi_horizontal_scan_8x8[64] = {
01041 0, 1, 2, 3, 4, 5, 6, 7,
01042 8, 9, 10, 11, 12, 13, 14, 15,
01043 16, 17, 18, 19, 20, 21, 22, 23,
01044 24, 25, 26, 27, 28, 29, 30, 31,
01045 32, 33, 34, 35, 36, 37, 38, 39,
01046 40, 41, 42, 43, 44, 45, 46, 47,
01047 48, 49, 50, 51, 52, 53, 54, 55,
01048 56, 57, 58, 59, 60, 61, 62, 63
01049 };
01050
01051 const uint8_t ff_ivi_direct_scan_4x4[16] = {
01052 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
01053 };
01054
01055
01059 const RVMapDesc ff_ivi_rvmap_tabs[9] = {
01060 {
01061 5,
01062 2,
01063
01064 {1, 1, 0, 1, 1, 0, 1, 1, 2, 2, 1, 1, 1, 1, 3, 3,
01065 1, 1, 2, 2, 1, 1, 4, 4, 1, 1, 1, 1, 2, 2, 5, 5,
01066 1, 1, 3, 3, 1, 1, 6, 6, 1, 2, 1, 2, 7, 7, 1, 1,
01067 8, 8, 1, 1, 4, 2, 1, 4, 2, 1, 3, 3, 1, 1, 1, 9,
01068 9, 1, 2, 1, 2, 1, 5, 5, 1, 1, 10, 10, 1, 1, 3, 3,
01069 2, 2, 1, 1, 11, 11, 6, 4, 4, 1, 6, 1, 2, 1, 2, 12,
01070 8, 1, 12, 7, 8, 7, 1, 16, 1, 16, 1, 3, 3, 13, 1, 13,
01071 2, 2, 1, 15, 1, 5, 14, 15, 1, 5, 14, 1, 17, 8, 17, 8,
01072 1, 4, 4, 2, 2, 1, 25, 25, 24, 24, 1, 3, 1, 3, 1, 8,
01073 6, 7, 6, 1, 18, 8, 18, 1, 7, 23, 2, 2, 23, 1, 1, 21,
01074 22, 9, 9, 22, 19, 1, 21, 5, 19, 5, 1, 33, 20, 33, 20, 8,
01075 4, 4, 1, 32, 2, 2, 8, 3, 32, 26, 3, 1, 7, 7, 26, 6,
01076 1, 6, 1, 1, 16, 1, 10, 1, 10, 2, 16, 29, 28, 2, 29, 28,
01077 1, 27, 5, 8, 5, 27, 1, 8, 3, 7, 3, 31, 41, 31, 1, 41,
01078 6, 1, 6, 7, 4, 4, 1, 1, 2, 1, 2, 11, 34, 30, 11, 1,
01079 30, 15, 15, 34, 36, 40, 36, 40, 35, 35, 37, 37, 39, 39, 38, 38},
01080
01081
01082 { 1, -1, 0, 2, -2, 0, 3, -3, 1, -1, 4, -4, 5, -5, 1, -1,
01083 6, -6, 2, -2, 7, -7, 1, -1, 8, -8, 9, -9, 3, -3, 1, -1,
01084 10, -10, 2, -2, 11, -11, 1, -1, 12, 4, -12, -4, 1, -1, 13, -13,
01085 1, -1, 14, -14, 2, 5, 15, -2, -5, -15, -3, 3, 16, -16, 17, 1,
01086 -1, -17, 6, 18, -6, -18, 2, -2, 19, -19, 1, -1, 20, -20, 4, -4,
01087 7, -7, 21, -21, 1, -1, 2, 3, -3, 22, -2, -22, 8, 23, -8, 1,
01088 2, -23, -1, 2, -2, -2, 24, 1, -24, -1, 25, 5, -5, 1, -25, -1,
01089 9, -9, 26, 1, -26, 3, 1, -1, 27, -3, -1, -27, 1, 3, -1, -3,
01090 28, -4, 4, 10, -10, -28, 1, -1, 1, -1, 29, 6, -29, -6, 30, -4,
01091 3, 3, -3, -30, 1, 4, -1, 31, -3, 1, 11, -11, -1, -31, 32, -1,
01092 -1, 2, -2, 1, 1, -32, 1, 4, -1, -4, 33, -1, 1, 1, -1, 5,
01093 5, -5, -33, -1, -12, 12, -5, -7, 1, 1, 7, 34, 4, -4, -1, 4,
01094 -34, -4, 35, 36, -2, -35, -2, -36, 2, 13, 2, -1, 1, -13, 1, -1,
01095 37, 1, -5, 6, 5, -1, 38, -6, -8, 5, 8, -1, 1, 1, -37, -1,
01096 5, 39, -5, -5, 6, -6, -38, -39, -14, 40, 14, 2, 1, 1, -2, -40,
01097 -1, -2, 2, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1}
01098 },{
01099
01100 0,
01101 38,
01102
01103 {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 6, 8, 7,
01104 7, 9, 9, 10, 10, 11, 11, 1, 12, 1, 12, 13, 13, 16, 14, 16,
01105 14, 15, 15, 17, 17, 18, 0, 18, 19, 20, 21, 19, 22, 21, 20, 22,
01106 25, 24, 2, 25, 24, 23, 23, 2, 26, 28, 26, 28, 29, 27, 29, 27,
01107 33, 33, 1, 32, 1, 3, 32, 30, 36, 3, 36, 30, 31, 31, 35, 34,
01108 37, 41, 34, 35, 37, 4, 41, 4, 49, 8, 8, 49, 40, 38, 5, 38,
01109 40, 39, 5, 39, 42, 43, 42, 7, 57, 6, 43, 44, 6, 50, 7, 44,
01110 57, 48, 50, 48, 45, 45, 46, 47, 51, 46, 47, 58, 1, 51, 58, 1,
01111 52, 59, 53, 9, 52, 55, 55, 59, 53, 56, 54, 56, 54, 9, 64, 64,
01112 60, 63, 60, 63, 61, 62, 61, 62, 2, 10, 2, 10, 11, 1, 11, 13,
01113 12, 1, 12, 13, 16, 16, 8, 8, 14, 3, 3, 15, 14, 15, 4, 4,
01114 1, 17, 17, 5, 1, 7, 7, 5, 6, 1, 2, 2, 6, 22, 1, 25,
01115 21, 22, 8, 24, 1, 21, 25, 24, 8, 18, 18, 23, 9, 20, 23, 33,
01116 29, 33, 20, 1, 19, 1, 29, 36, 9, 36, 19, 41, 28, 57, 32, 3,
01117 28, 3, 1, 27, 49, 49, 1, 32, 26, 26, 2, 4, 4, 7, 57, 41,
01118 2, 7, 10, 5, 37, 16, 10, 27, 8, 8, 13, 16, 37, 13, 1, 5},
01119
01120
01121 {0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1,
01122 -1, 1, -1, 1, -1, 1, -1, 2, 1, -2, -1, 1, -1, 1, 1, -1,
01123 -1, 1, -1, 1, -1, 1, 0, -1, 1, 1, 1, -1, 1, -1, -1, -1,
01124 1, 1, 2, -1, -1, 1, -1, -2, 1, 1, -1, -1, 1, 1, -1, -1,
01125 1, -1, 3, 1, -3, 2, -1, 1, 1, -2, -1, -1, -1, 1, 1, 1,
01126 1, 1, -1, -1, -1, 2, -1, -2, 1, 2, -2, -1, 1, 1, 2, -1,
01127 -1, 1, -2, -1, 1, 1, -1, 2, 1, 2, -1, 1, -2, -1, -2, -1,
01128 -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 4, -1, -1, -4,
01129 1, 1, 1, 2, -1, -1, 1, -1, -1, 1, -1, -1, 1, -2, 1, -1,
01130 1, 1, -1, -1, 1, 1, -1, -1, 3, 2, -3, -2, 2, 5, -2, 2,
01131 2, -5, -2, -2, -2, 2, -3, 3, 2, 3, -3, 2, -2, -2, 3, -3,
01132 6, 2, -2, 3, -6, 3, -3, -3, 3, 7, -4, 4, -3, 2, -7, 2,
01133 2, -2, -4, 2, 8, -2, -2, -2, 4, 2, -2, 2, 3, 2, -2, -2,
01134 2, 2, -2, -8, -2, 9, -2, 2, -3, -2, 2, -2, 2, 2, 2, 4,
01135 -2, -4, 10, 2, 2, -2, -9, -2, 2, -2, 5, 4, -4, 4, -2, 2,
01136 -5, -4, -3, 4, 2, -3, 3, -2, -5, 5, 3, 3, -2, -3, -10, -4}
01137 },{
01138
01139 2,
01140 11,
01141
01142 {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 0, 1, 1, 5, 5,
01143 2, 2, 6, 6, 7, 7, 1, 8, 1, 8, 3, 3, 9, 9, 1, 2,
01144 2, 1, 4, 10, 4, 10, 11, 11, 1, 5, 12, 12, 1, 5, 13, 13,
01145 3, 3, 6, 6, 2, 2, 14, 14, 16, 16, 15, 7, 15, 8, 8, 7,
01146 1, 1, 17, 17, 4, 4, 1, 1, 18, 18, 2, 2, 5, 5, 25, 3,
01147 9, 3, 25, 9, 19, 24, 19, 24, 1, 21, 20, 1, 21, 22, 20, 22,
01148 23, 23, 8, 6, 33, 6, 8, 33, 7, 7, 26, 26, 1, 32, 1, 32,
01149 28, 4, 28, 10, 29, 27, 27, 10, 41, 4, 29, 2, 2, 41, 36, 31,
01150 49, 31, 34, 30, 34, 36, 30, 35, 1, 49, 11, 5, 35, 11, 1, 3,
01151 3, 5, 37, 37, 8, 40, 8, 40, 12, 12, 42, 42, 1, 38, 16, 57,
01152 1, 6, 16, 39, 38, 6, 7, 7, 13, 13, 39, 43, 2, 43, 57, 2,
01153 50, 9, 44, 9, 50, 4, 15, 48, 44, 4, 1, 15, 48, 14, 14, 1,
01154 45, 45, 8, 3, 5, 8, 51, 47, 3, 46, 46, 47, 5, 51, 1, 17,
01155 17, 58, 1, 58, 2, 52, 52, 2, 53, 7, 59, 6, 6, 56, 53, 55,
01156 7, 55, 1, 54, 59, 56, 54, 10, 1, 10, 4, 60, 1, 60, 8, 4,
01157 8, 64, 64, 61, 1, 63, 3, 63, 62, 61, 5, 11, 5, 3, 11, 62},
01158
01159
01160 { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 0, 3, -3, 1, -1,
01161 2, -2, 1, -1, 1, -1, 4, 1, -4, -1, 2, -2, 1, -1, 5, 3,
01162 -3, -5, 2, 1, -2, -1, 1, -1, 6, 2, 1, -1, -6, -2, 1, -1,
01163 3, -3, 2, -2, 4, -4, 1, -1, 1, -1, 1, 2, -1, 2, -2, -2,
01164 7, -7, 1, -1, 3, -3, 8, -8, 1, -1, 5, -5, 3, -3, 1, 4,
01165 2, -4, -1, -2, 1, 1, -1, -1, 9, 1, 1, -9, -1, 1, -1, -1,
01166 1, -1, 3, -3, 1, 3, -3, -1, 3, -3, 1, -1, 10, 1, -10, -1,
01167 1, 4, -1, 2, 1, -1, 1, -2, 1, -4, -1, 6, -6, -1, 1, 1,
01168 1, -1, 1, 1, -1, -1, -1, 1, 11, -1, -2, 4, -1, 2, -11, 5,
01169 -5, -4, -1, 1, 4, 1, -4, -1, -2, 2, 1, -1, 12, 1, -2, 1,
01170 -12, 4, 2, 1, -1, -4, 4, -4, 2, -2, -1, 1, 7, -1, -1, -7,
01171 -1, -3, 1, 3, 1, 5, 2, 1, -1, -5, 13, -2, -1, 2, -2, -13,
01172 1, -1, 5, 6, 5, -5, 1, 1, -6, 1, -1, -1, -5, -1, 14, 2,
01173 -2, 1, -14, -1, 8, 1, -1, -8, 1, 5, 1, 5, -5, 1, -1, 1,
01174 -5, -1, 15, 1, -1, -1, -1, 3, -15, -3, 6, 1, 16, -1, 6, -6,
01175 -6, 1, -1, 1, -16, 1, 7, -1, 1, -1, -6, -3, 6, -7, 3, -1}
01176 },{
01177
01178 0,
01179 35,
01180
01181 {0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 5, 5, 6, 6, 7,
01182 7, 8, 8, 9, 9, 2, 2, 10, 10, 1, 1, 11, 11, 12, 12, 3,
01183 3, 13, 13, 0, 14, 14, 16, 15, 16, 15, 4, 4, 17, 1, 17, 1,
01184 5, 5, 18, 18, 2, 2, 6, 6, 8, 19, 7, 8, 7, 19, 20, 20,
01185 21, 21, 22, 24, 22, 24, 23, 23, 1, 1, 25, 25, 3, 3, 26, 26,
01186 9, 9, 27, 27, 28, 28, 33, 29, 4, 33, 29, 1, 4, 1, 32, 32,
01187 2, 2, 31, 10, 30, 10, 30, 31, 34, 34, 5, 5, 36, 36, 35, 41,
01188 35, 11, 41, 11, 37, 1, 8, 8, 37, 6, 1, 6, 40, 7, 7, 40,
01189 12, 38, 12, 39, 39, 38, 49, 13, 49, 13, 3, 42, 3, 42, 16, 16,
01190 43, 43, 14, 14, 1, 1, 44, 15, 44, 15, 2, 2, 57, 48, 50, 48,
01191 57, 50, 4, 45, 45, 4, 46, 47, 47, 46, 1, 51, 1, 17, 17, 51,
01192 8, 9, 9, 5, 58, 8, 58, 5, 52, 52, 55, 56, 53, 56, 55, 59,
01193 59, 53, 54, 1, 6, 54, 7, 7, 6, 1, 2, 3, 2, 3, 64, 60,
01194 60, 10, 10, 64, 61, 62, 61, 63, 1, 63, 62, 1, 18, 24, 18, 4,
01195 25, 4, 8, 21, 21, 1, 24, 22, 25, 22, 8, 11, 19, 11, 23, 1,
01196 20, 23, 19, 20, 5, 12, 5, 1, 16, 2, 12, 13, 2, 13, 1, 16},
01197
01198
01199 { 0, 1, -1, 1, -1, 1, -1, 1, -1, 2, -2, 1, -1, 1, -1, 1,
01200 -1, 1, -1, 1, -1, 2, -2, 1, -1, 3, -3, 1, -1, 1, -1, 2,
01201 -2, 1, -1, 0, 1, -1, 1, 1, -1, -1, 2, -2, 1, 4, -1, -4,
01202 2, -2, 1, -1, -3, 3, 2, -2, 2, 1, 2, -2, -2, -1, 1, -1,
01203 1, -1, 1, 1, -1, -1, 1, -1, 5, -5, 1, -1, 3, -3, 1, -1,
01204 2, -2, 1, -1, 1, -1, 1, 1, 3, -1, -1, 6, -3, -6, -1, 1,
01205 4, -4, 1, 2, 1, -2, -1, -1, 1, -1, 3, -3, 1, -1, 1, 1,
01206 -1, 2, -1, -2, 1, 7, -3, 3, -1, 3, -7, -3, 1, -3, 3, -1,
01207 2, 1, -2, 1, -1, -1, 1, 2, -1, -2, -4, -1, 4, 1, 2, -2,
01208 1, -1, -2, 2, 8, -8, -1, 2, 1, -2, -5, 5, 1, -1, -1, 1,
01209 -1, 1, 4, -1, 1, -4, -1, -1, 1, 1, 9, 1, -9, 2, -2, -1,
01210 -4, 3, -3, -4, -1, 4, 1, 4, 1, -1, 1, -1, 1, 1, -1, 1,
01211 -1, -1, -1, 10, 4, 1, 4, -4, -4, -10, 6, 5, -6, -5, 1, -1,
01212 1, 3, -3, -1, 1, -1, -1, -1, 11, 1, 1, -11, -2, -2, 2, 5,
01213 -2, -5, -5, 2, -2, 12, 2, -2, 2, 2, 5, -3, -2, 3, -2, -12,
01214 -2, 2, 2, 2, -5, 3, 5, 13, -3, 7, -3, -3, -7, 3, -13, 3}
01215 },{
01216
01217 0,
01218 34,
01219
01220 {0, 1, 1, 1, 2, 2, 1, 3, 3, 1, 1, 1, 4, 4, 1, 5,
01221 2, 1, 5, 2, 1, 1, 6, 6, 1, 1, 1, 1, 1, 7, 3, 1,
01222 2, 3, 0, 1, 2, 7, 1, 1, 1, 8, 1, 1, 8, 1, 1, 1,
01223 9, 1, 9, 1, 2, 1, 1, 2, 1, 1, 10, 4, 1, 10, 1, 4,
01224 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 2, 1, 5, 1, 1, 1,
01225 2, 5, 1, 11, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
01226 2, 1, 6, 1, 6, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 12,
01227 3, 1, 12, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1,
01228 4, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 1, 2, 1,
01229 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 5,
01230 1, 1, 1, 1, 1, 7, 1, 7, 1, 1, 2, 3, 1, 1, 1, 1,
01231 5, 1, 1, 1, 1, 1, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1,
01232 1, 1, 1, 1, 1, 1, 1, 1, 13, 2, 1, 1, 4, 1, 1, 1,
01233 3, 1, 6, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 6, 1, 1,
01234 1, 1, 15, 2, 4, 1, 2, 3, 15, 1, 1, 1, 8, 1, 1, 8,
01235 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1},
01236
01237
01238 { 0, 1, -1, 2, 1, -1, -2, 1, -1, 3, -3, 4, 1, -1, -4, 1,
01239 2, 5, -1, -2, -5, 6, 1, -1, -6, 7, -7, 8, -8, 1, 2, 9,
01240 3, -2, 0, -9, -3, -1, 10, -10, 11, 1, -11, 12, -1, -12, 13, -13,
01241 1, 14, -1, -14, 4, 15, -15, -4, 16, -16, 1, 2, 17, -1, -17, -2,
01242 18, -18, 19, -19, 20, 3, -20, 21, -21, -3, 5, 22, 2, -22, -23, 23,
01243 -5, -2, 24, 1, -24, -1, 25, -25, 26, -26, -27, 27, 28, 29, -28, -29,
01244 6, 30, 2, -31, -2, -30, 31, -6, -32, 32, 33, -33, 34, -35, -34, 1,
01245 4, -36, -1, 35, 37, 36, 7, -37, 38, -4, -38, 39, 41, 40, -40, -39,
01246 3, 42, -43, -41, -7, -42, 43, -3, 44, -44, 45, -45, 46, 47, 8, -47,
01247 -48, -46, 50, -50, 48, 49, 51, -49, 52, -52, 5, -51, -8, -53, 53, 3,
01248 -56, 56, 55, 54, -54, 2, 60, -2, -55, 58, 9, -5, 59, 57, -57, -63,
01249 -3, -58, -60, -61, 61, -59, -62, -9, 1, 64, 62, 69, -64, 63, 65, -67,
01250 -68, 66, -65, 68, -66, -69, 67, -70, -1, 10, 71, -71, 4, 73, 72, 70,
01251 6, -76, -3, 74, -78, -74, 1, 78, 80, -72, -75, 76, -1, 3, -73, 79,
01252 75, 77, 1, 11, -4, -79, -10, -6, -1, -77, -83, -80, 2, 81, -84, -2,
01253 83, -81, 82, -82, 84, -87, -86, 85, -11, -85, 86, -89, 87, -88, 88, 89}
01254 },{
01255
01256 2,
01257 33,
01258
01259 {1, 1, 0, 2, 1, 2, 1, 3, 3, 1, 1, 4, 4, 2, 2, 1,
01260 1, 5, 5, 6, 1, 6, 1, 7, 7, 3, 3, 2, 8, 2, 8, 1,
01261 1, 0, 9, 9, 1, 1, 10, 4, 10, 4, 11, 11, 2, 1, 2, 1,
01262 12, 12, 3, 3, 1, 1, 13, 5, 5, 13, 14, 1, 1, 14, 2, 2,
01263 6, 6, 15, 1, 1, 15, 16, 4, 7, 16, 4, 7, 1, 1, 3, 3,
01264 8, 8, 2, 2, 1, 1, 17, 17, 1, 1, 18, 18, 5, 5, 2, 2,
01265 1, 1, 9, 19, 9, 19, 20, 3, 3, 20, 1, 10, 21, 1, 10, 4,
01266 4, 21, 22, 6, 6, 22, 1, 1, 23, 24, 2, 2, 23, 24, 11, 1,
01267 1, 11, 7, 25, 7, 1, 1, 25, 8, 8, 3, 26, 3, 1, 12, 2,
01268 2, 26, 1, 12, 5, 5, 27, 4, 1, 4, 1, 27, 28, 1, 28, 13,
01269 1, 13, 2, 29, 2, 1, 32, 6, 1, 30, 14, 29, 14, 6, 3, 31,
01270 3, 1, 30, 1, 32, 31, 33, 9, 33, 1, 1, 7, 9, 7, 2, 2,
01271 1, 1, 4, 36, 34, 4, 5, 10, 10, 5, 34, 1, 1, 35, 8, 8,
01272 36, 3, 35, 1, 15, 3, 2, 1, 16, 15, 16, 2, 37, 1, 37, 1,
01273 1, 1, 6, 6, 38, 1, 38, 11, 1, 39, 39, 40, 11, 2, 41, 4,
01274 40, 1, 2, 4, 1, 1, 1, 41, 3, 1, 3, 1, 5, 7, 5, 7},
01275
01276
01277 { 1, -1, 0, 1, 2, -1, -2, 1, -1, 3, -3, 1, -1, 2, -2, 4,
01278 -4, 1, -1, 1, 5, -1, -5, 1, -1, 2, -2, 3, 1, -3, -1, 6,
01279 -6, 0, 1, -1, 7, -7, 1, 2, -1, -2, 1, -1, 4, 8, -4, -8,
01280 1, -1, 3, -3, 9, -9, 1, 2, -2, -1, 1, 10, -10, -1, 5, -5,
01281 2, -2, 1, 11, -11, -1, 1, 3, 2, -1, -3, -2, 12, -12, 4, -4,
01282 2, -2, -6, 6, 13, -13, 1, -1, 14, -14, 1, -1, 3, -3, 7, -7,
01283 15, -15, 2, 1, -2, -1, 1, 5, -5, -1, -16, 2, 1, 16, -2, 4,
01284 -4, -1, 1, 3, -3, -1, 17, -17, 1, 1, -8, 8, -1, -1, 2, 18,
01285 -18, -2, 3, 1, -3, 19, -19, -1, 3, -3, 6, 1, -6, 20, 2, 9,
01286 -9, -1, -20, -2, 4, -4, 1, -5, 21, 5, -21, -1, 1, -22, -1, 2,
01287 22, -2, 10, 1, -10, 23, 1, 4, -23, 1, 2, -1, -2, -4, -7, 1,
01288 7, -24, -1, 24, -1, -1, 1, 3, -1, -25, 25, 4, -3, -4, 11, -11,
01289 26, -26, 6, 1, 1, -6, -5, -3, 3, 5, -1, -27, 27, 1, 4, -4,
01290 -1, -8, -1, 28, 2, 8, -12, -28, -2, -2, 2, 12, -1, 29, 1, -29,
01291 30, -30, 5, -5, 1, -31, -1, 3, 31, -1, 1, 1, -3, -13, 1, -7,
01292 -1, -32, 13, 7, 32, 33, -33, -1, -9, -34, 9, 34, -6, 5, 6, -5}
01293 },{
01294
01295 2,
01296 13,
01297
01298 {1, 1, 0, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 0, 2, 2,
01299 4, 1, 4, 1, 1, 1, 5, 5, 1, 1, 6, 6, 2, 2, 1, 1,
01300 3, 3, 7, 7, 1, 1, 8, 8, 1, 1, 2, 2, 1, 9, 1, 9,
01301 4, 4, 10, 1, 1, 10, 1, 1, 11, 11, 3, 3, 1, 2, 1, 2,
01302 1, 1, 12, 12, 5, 5, 1, 1, 13, 1, 1, 13, 2, 2, 1, 1,
01303 6, 6, 1, 1, 4, 14, 4, 14, 3, 1, 3, 1, 1, 1, 15, 7,
01304 15, 2, 2, 7, 1, 1, 1, 8, 1, 8, 16, 16, 1, 1, 1, 1,
01305 2, 1, 1, 2, 1, 1, 3, 5, 5, 3, 4, 1, 1, 4, 1, 1,
01306 17, 17, 9, 1, 1, 9, 2, 2, 1, 1, 10, 10, 1, 6, 1, 1,
01307 6, 18, 1, 1, 18, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 1,
01308 4, 1, 19, 1, 19, 7, 1, 1, 20, 1, 4, 20, 1, 7, 11, 2,
01309 1, 11, 21, 2, 8, 5, 1, 8, 1, 5, 21, 1, 1, 1, 22, 1,
01310 1, 22, 1, 1, 3, 3, 1, 23, 2, 12, 24, 1, 1, 2, 1, 1,
01311 12, 23, 1, 1, 24, 1, 1, 1, 4, 1, 1, 1, 2, 1, 6, 6,
01312 4, 2, 1, 1, 1, 1, 1, 1, 1, 14, 13, 3, 1, 25, 9, 25,
01313 14, 1, 9, 3, 13, 1, 1, 1, 1, 1, 10, 1, 1, 2, 10, 2},
01314
01315
01316 {-20, -1, 0, 2, -2, 1, -1, 3, -3, 1, -1, 4, -4, 0, 2, -2,
01317 1, 5, -1, -5, 6, -6, 1, -1, 7, -7, 1, -1, 3, -3, 8, -8,
01318 2, -2, 1, -1, 9, -9, 1, -1, 10, -10, 4, -4, 11, 1, -11, -1,
01319 2, -2, 1, 12, -12, -1, 13, -13, 1, -1, 3, -3, 14, 5, -14, -5,
01320 -15, 15, -1, 1, 2, -2, 16, -16, 1, 17, -17, -1, 6, -6, 18, -18,
01321 2, -2, -19, 19, -3, 1, 3, -1, 4, 20, -4, 1, -21, 21, 1, 2,
01322 -1, -7, 7, -2, 22, -22, 23, 2, -23, -2, 1, -1, -24, 24, -25, 25,
01323 -8, -26, 26, 8, -27, 27, 5, 3, -3, -5, -4, 28, -28, 4, 29, -29,
01324 1, -1, -2, -30, 30, 2, 9, -9, -31, 31, 2, -2, -32, 3, 32, -33,
01325 -3, 1, 33, -34, -1, 34, -35, 35, -10, 10, -6, 36, 6, -36, 37, -37,
01326 -5, 38, 1, -38, -1, 3, 39, -39, -1, 40, 5, 1, -40, -3, 2, -11,
01327 -41, -2, 1, 11, -3, -4, 41, 3, 42, 4, -1, -43, -42, 43, 1, -44,
01328 45, -1, 44, -45, -7, 7, -46, 1, -12, 2, 1, -47, 46, 12, 47, 48,
01329 -2, -1, -48, 49, -1, -50, -49, 50, -6, -51, 51, 52, -13, 53, -4, 4,
01330 6, 13, -53, -52, -54, 55, 54, -55, -56, -2, 2, -8, 56, 1, -3, -1,
01331 2, 58, 3, 8, -2, 57, -58, -60, -59, -57, -3, 60, 59, -14, 3, 14}
01332 },{
01333
01334 2,
01335 38,
01336
01337 {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 5, 5, 1, 1, 6,
01338 6, 2, 2, 7, 7, 8, 8, 1, 1, 3, 3, 9, 9, 10, 10, 1,
01339 1, 2, 2, 4, 4, 11, 0, 11, 12, 12, 13, 13, 1, 1, 5, 5,
01340 14, 14, 15, 16, 15, 16, 3, 3, 1, 6, 1, 6, 2, 2, 7, 7,
01341 8, 8, 17, 17, 1, 1, 4, 4, 18, 18, 2, 2, 1, 19, 1, 20,
01342 19, 20, 21, 21, 3, 3, 22, 22, 5, 5, 24, 1, 1, 23, 9, 23,
01343 24, 9, 2, 2, 10, 1, 1, 10, 6, 6, 25, 4, 4, 25, 7, 7,
01344 26, 8, 1, 8, 3, 1, 26, 3, 11, 11, 27, 27, 2, 28, 1, 2,
01345 28, 1, 12, 12, 5, 5, 29, 13, 13, 29, 32, 1, 1, 33, 31, 30,
01346 32, 4, 30, 33, 4, 31, 3, 14, 1, 1, 3, 34, 34, 2, 2, 14,
01347 6, 6, 35, 36, 35, 36, 1, 15, 1, 16, 16, 15, 7, 9, 7, 9,
01348 37, 8, 8, 37, 1, 1, 39, 2, 38, 39, 2, 40, 5, 38, 40, 5,
01349 3, 3, 4, 4, 10, 10, 1, 1, 1, 1, 41, 2, 41, 2, 6, 6,
01350 1, 1, 11, 42, 11, 43, 3, 42, 3, 17, 4, 43, 1, 17, 7, 1,
01351 8, 44, 4, 7, 44, 5, 8, 2, 5, 1, 2, 48, 45, 1, 12, 45,
01352 12, 48, 13, 13, 1, 9, 9, 46, 1, 46, 47, 47, 49, 18, 18, 49},
01353
01354
01355 { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 1, -1, 3, -3, 1,
01356 -1, -2, 2, 1, -1, 1, -1, 4, -4, -2, 2, 1, -1, 1, -1, 5,
01357 -5, -3, 3, 2, -2, 1, 0, -1, 1, -1, 1, -1, 6, -6, 2, -2,
01358 1, -1, 1, 1, -1, -1, -3, 3, 7, 2, -7, -2, -4, 4, 2, -2,
01359 2, -2, 1, -1, 8, -8, 3, -3, 1, -1, -5, 5, 9, 1, -9, 1,
01360 -1, -1, 1, -1, -4, 4, 1, -1, 3, -3, 1, -10, 10, 1, 2, -1,
01361 -1, -2, 6, -6, 2, 11, -11, -2, 3, -3, 1, -4, 4, -1, 3, -3,
01362 1, 3, 12, -3, -5, -12, -1, 5, 2, -2, 1, -1, -7, 1, 13, 7,
01363 -1, -13, 2, -2, 4, -4, 1, 2, -2, -1, 1, 14, -14, 1, 1, 1,
01364 -1, -5, -1, -1, 5, -1, -6, 2, -15, 15, 6, 1, -1, -8, 8, -2,
01365 -4, 4, 1, 1, -1, -1, 16, 2, -16, -2, 2, -2, 4, 3, -4, -3,
01366 -1, -4, 4, 1, -17, 17, -1, -9, 1, 1, 9, 1, -5, -1, -1, 5,
01367 -7, 7, 6, -6, 3, -3, 18, -18, 19, -19, 1, -10, -1, 10, -5, 5,
01368 20, -20, -3, 1, 3, 1, 8, -1, -8, 2, 7, -1, -21, -2, 5, 21,
01369 5, -1, -7, -5, 1, -6, -5, -11, 6, 22, 11, 1, 1, -22, -3, -1,
01370 3, -1, 3, -3, -23, 4, -4, 1, 23, -1, 1, -1, 1, -2, 2, -1}
01371 },{
01372
01373 4,
01374 11,
01375
01376 {1, 1, 1, 1, 0, 2, 2, 1, 1, 3, 3, 0, 1, 1, 2, 2,
01377 4, 4, 1, 1, 5, 5, 1, 1, 2, 2, 3, 3, 6, 6, 1, 1,
01378 7, 7, 8, 1, 8, 2, 2, 1, 4, 4, 1, 3, 1, 3, 9, 9,
01379 2, 2, 1, 5, 1, 5, 10, 10, 1, 1, 11, 11, 3, 6, 3, 4,
01380 4, 6, 2, 2, 1, 12, 1, 12, 7, 13, 7, 13, 1, 1, 8, 8,
01381 2, 2, 14, 14, 16, 15, 16, 5, 5, 1, 3, 15, 1, 3, 4, 4,
01382 1, 1, 17, 17, 2, 2, 6, 6, 1, 18, 1, 18, 22, 21, 22, 21,
01383 25, 24, 25, 19, 9, 20, 9, 23, 19, 24, 20, 3, 23, 7, 3, 1,
01384 1, 7, 28, 26, 29, 5, 28, 26, 5, 8, 29, 4, 8, 27, 2, 2,
01385 4, 27, 1, 1, 10, 36, 10, 33, 33, 36, 30, 1, 32, 32, 1, 30,
01386 6, 31, 31, 35, 3, 6, 11, 11, 3, 2, 35, 2, 34, 1, 34, 1,
01387 37, 37, 12, 7, 12, 5, 41, 5, 4, 7, 1, 8, 13, 4, 1, 41,
01388 13, 38, 8, 38, 9, 1, 40, 40, 9, 1, 39, 2, 2, 49, 39, 42,
01389 3, 3, 14, 16, 49, 14, 16, 42, 43, 43, 6, 6, 15, 1, 1, 15,
01390 44, 44, 1, 1, 50, 48, 4, 5, 4, 7, 5, 2, 10, 10, 48, 7,
01391 50, 45, 2, 1, 45, 8, 8, 1, 46, 46, 3, 47, 47, 3, 1, 1},
01392
01393
01394 { 1, -1, 2, -2, 0, 1, -1, 3, -3, 1, -1, 0, 4, -4, 2, -2,
01395 1, -1, 5, -5, 1, -1, 6, -6, 3, -3, 2, -2, 1, -1, 7, -7,
01396 1, -1, 1, 8, -1, 4, -4, -8, 2, -2, 9, 3, -9, -3, 1, -1,
01397 5, -5, 10, 2, -10, -2, 1, -1, 11, -11, 1, -1, -4, 2, 4, 3,
01398 -3, -2, 6, -6, 12, 1, -12, -1, 2, 1, -2, -1, 13, -13, 2, -2,
01399 7, -7, 1, -1, 1, 1, -1, 3, -3, 14, 5, -1, -14, -5, 4, -4,
01400 15, -15, 1, -1, 8, -8, -3, 3, 16, 1, -16, -1, 1, 1, -1, -1,
01401 1, 1, -1, 1, 2, 1, -2, 1, -1, -1, -1, 6, -1, 3, -6, 17,
01402 -17, -3, 1, 1, 1, 4, -1, -1, -4, 3, -1, 5, -3, -1, -9, 9,
01403 -5, 1, 18, -18, 2, 1, -2, 1, -1, -1, 1, 19, -1, 1, -19, -1,
01404 4, 1, -1, 1, 7, -4, -2, 2, -7, 10, -1, -10, 1, 20, -1, -20,
01405 1, -1, 2, 4, -2, 5, 1, -5, 6, -4, 21, 4, 2, -6, -21, -1,
01406 -2, 1, -4, -1, -3, 22, -1, 1, 3, -22, -1, 11, -11, 1, 1, 1,
01407 8, -8, 2, 2, -1, -2, -2, -1, 1, -1, -5, 5, 2, 23, -23, -2,
01408 1, -1, 24, -24, -1, -1, 7, 6, -7, 5, -6, 12, -3, 3, 1, -5,
01409 1, 1, -12, 25, -1, -5, 5, -25, -1, 1, 9, 1, -1, -9, 26, -26}
01410 }
01411 };