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