func: static void init_block_mapping(Vp3DecodeContext *s) 
  
  {
  
      int i, j;
  
      signed int hilbert_walk_y[16];
  
      signed int hilbert_walk_c[16];
  
      signed int hilbert_walk_mb[4];
  
  
  
      int current_fragment = 0;
  
      int current_width = 0;
  
      int current_height = 0;
  
      int right_edge = 0;
  
      int bottom_edge = 0;
  
      int superblock_row_inc = 0;
  
      int *hilbert = NULL;
  
      int mapping_index = 0;
  
  
  
      int current_macroblock;
  
      int c_fragment;
  
  
  
      signed char travel_width[16] = {
  
           1,  1,  0, -1, 
  
           0,  0,  1,  0,
  
           1,  0,  1,  0,
  
           0, -1,  0,  1
  
      };
  
  
  
      signed char travel_height[16] = {
  
           0,  0,  1,  0,
  
           1,  1,  0, -1,
  
           0,  1,  0, -1,
  
          -1,  0, -1,  0
  
      };
  
  
  
      signed char travel_width_mb[4] = {
  
           1,  0,  1,  0
  
      };
  
  
  
      signed char travel_height_mb[4] = {
  
           0,  1,  0, -1
  
      };
  
  
  
      debug_vp3("  vp3: initialize block mapping tables\n");
  
  
  
      /* figure out hilbert pattern per these frame dimensions */
  
      hilbert_walk_y[0]  = 1;
  
      hilbert_walk_y[1]  = 1;
  
      hilbert_walk_y[2]  = s->fragment_width;
  
      hilbert_walk_y[3]  = -1;
  
      hilbert_walk_y[4]  = s->fragment_width;
  
      hilbert_walk_y[5]  = s->fragment_width;
  
      hilbert_walk_y[6]  = 1;
  
      hilbert_walk_y[7]  = -s->fragment_width;
  
      hilbert_walk_y[8]  = 1;
  
      hilbert_walk_y[9]  = s->fragment_width;
  
      hilbert_walk_y[10]  = 1;
  
      hilbert_walk_y[11] = -s->fragment_width;
  
      hilbert_walk_y[12] = -s->fragment_width;
  
      hilbert_walk_y[13] = -1;
  
      hilbert_walk_y[14] = -s->fragment_width;
  
      hilbert_walk_y[15] = 1;
  
  
  
      hilbert_walk_c[0]  = 1;
  
      hilbert_walk_c[1]  = 1;
  
      hilbert_walk_c[2]  = s->fragment_width / 2;
  
      hilbert_walk_c[3]  = -1;
  
      hilbert_walk_c[4]  = s->fragment_width / 2;
  
      hilbert_walk_c[5]  = s->fragment_width / 2;
  
      hilbert_walk_c[6]  = 1;
  
      hilbert_walk_c[7]  = -s->fragment_width / 2;
  
      hilbert_walk_c[8]  = 1;
  
      hilbert_walk_c[9]  = s->fragment_width / 2;
  
      hilbert_walk_c[10]  = 1;
  
      hilbert_walk_c[11] = -s->fragment_width / 2;
  
      hilbert_walk_c[12] = -s->fragment_width / 2;
  
      hilbert_walk_c[13] = -1;
  
      hilbert_walk_c[14] = -s->fragment_width / 2;
  
      hilbert_walk_c[15] = 1;
  
  
  
      hilbert_walk_mb[0] = 1;
  
      hilbert_walk_mb[1] = s->macroblock_width;
  
      hilbert_walk_mb[2] = 1;
  
      hilbert_walk_mb[3] = -s->macroblock_width;
  
  
  
      /* iterate through each superblock (all planes) and map the fragments */
  
      for (i = 0; i < s->superblock_count; i++) {
  
          debug_init("    superblock %d (u starts @ %d, v starts @ %d)\n",
  
              i, s->u_superblock_start, s->v_superblock_start);
  
  
  
          /* time to re-assign the limits? */
  
          if (i == 0) {
  
  
  
              /* start of Y superblocks */
  
              right_edge = s->fragment_width;
  
              bottom_edge = s->fragment_height;
  
              current_width = 0;
  
              current_height = 0;
  
              superblock_row_inc = 3 * s->fragment_width;
  
              hilbert = hilbert_walk_y;
  
  
  
              /* the first operation for this variable is to advance by 1 */
  
              current_fragment = -1;
  
  
  
          } else if (i == s->u_superblock_start) {
  
  
  
              /* start of U superblocks */
  
              right_edge = s->fragment_width / 2;
  
              bottom_edge = s->fragment_height / 2;
  
              current_width = 0;
  
              current_height = 0;
  
              superblock_row_inc = 3 * (s->fragment_width / 2);
  
              hilbert = hilbert_walk_c;
  
  
  
              /* the first operation for this variable is to advance by 1 */
  
              current_fragment = s->u_fragment_start - 1;
  
  
  
          } else if (i == s->v_superblock_start) {
  
  
  
              /* start of V superblocks */
  
              right_edge = s->fragment_width / 2;
  
              bottom_edge = s->fragment_height / 2;
  
              current_width = 0;
  
              current_height = 0;
  
              superblock_row_inc = 3 * (s->fragment_width / 2);
  
              hilbert = hilbert_walk_c;
  
  
  
              /* the first operation for this variable is to advance by 1 */
  
              current_fragment = s->v_fragment_start - 1;
  
  
  
          }
  
  
  
          if (current_width >= right_edge) {
  
              /* reset width and move to next superblock row */
  
              current_width = 0;
  
              current_height += 4;
  
  
  
              /* fragment is now at the start of a new superblock row */
  
              current_fragment += superblock_row_inc;
  
          }
  
  
  
          /* iterate through all 16 fragments in a superblock */
  
          for (j = 0; j < 16; j++) {
  
              current_fragment += hilbert[j];
  
              current_height += travel_height[j];
  
  
  
              /* check if the fragment is in bounds */
  
              if ((current_width <= right_edge) &&
  
                  (current_height < bottom_edge)) {
  
                  s->superblock_fragments[mapping_index] = current_fragment;
  
                  debug_init("    mapping fragment %d to superblock %d, position %d\n", 
  
                      s->superblock_fragments[mapping_index], i, j);
  
              } else {
  
                  s->superblock_fragments[mapping_index] = -1;
  
                  debug_init("    superblock %d, position %d has no fragment\n", 
  
                      i, j);
  
              }
  
  
  
              current_width += travel_width[j];
  
              mapping_index++;
  
          }
  
      }
  
  
  
      /* initialize the superblock <-> macroblock mapping; iterate through
  
       * all of the Y plane superblocks to build this mapping */
  
      right_edge = s->macroblock_width;
  
      bottom_edge = s->macroblock_height;
  
      current_width = 0;
  
      current_height = 0;
  
      superblock_row_inc = s->macroblock_width;
  
      hilbert = hilbert_walk_mb;
  
      mapping_index = 0;
  
      current_macroblock = -1;
  
      for (i = 0; i < s->u_superblock_start; i++) {
  
  
  
          if (current_width >= right_edge) {
  
              /* reset width and move to next superblock row */
  
              current_width = 0;
  
              current_height += 2;
  
  
  
              /* macroblock is now at the start of a new superblock row */
  
              current_macroblock += superblock_row_inc;
  
          }
  
  
  
          /* iterate through each potential macroblock in the superblock */
  
          for (j = 0; j < 4; j++) {
  
              current_macroblock += hilbert_walk_mb[j];
  
              current_height += travel_height_mb[j];
  
  
  
              /* check if the macroblock is in bounds */
  
              if ((current_width <= right_edge) &&
  
                  (current_height < bottom_edge)) {
  
                  s->superblock_macroblocks[mapping_index] = current_macroblock;
  
                  debug_init("    mapping macroblock %d to superblock %d, position %d\n",
  
                      s->superblock_macroblocks[mapping_index], i, j);
  
              } else {
  
                  s->superblock_macroblocks[mapping_index] = -1;
  
                  debug_init("    superblock %d, position %d has no macroblock\n",
  
                      i, j);
  
              }
  
  
  
              current_width += travel_width_mb[j];
  
              mapping_index++;
  
          }
  
      }
  
  
  
      /* initialize the macroblock <-> fragment mapping */
  
      current_fragment = 0;
  
      current_macroblock = 0;
  
      mapping_index = 0;
  
      for (i = 0; i < s->fragment_height; i += 2) {
  
  
  
          for (j = 0; j < s->fragment_width; j += 2) {
  
  
  
              debug_init("    macroblock %d contains fragments: ", current_macroblock);
  
              s->all_fragments[current_fragment].macroblock = current_macroblock;
  
              s->macroblock_fragments[mapping_index++] = current_fragment;
  
              debug_init("%d ", current_fragment);
  
  
  
              if (j + 1 < s->fragment_width) {
  
                  s->all_fragments[current_fragment + 1].macroblock = current_macroblock;
  
                  s->macroblock_fragments[mapping_index++] = current_fragment + 1;
  
                  debug_init("%d ", current_fragment + 1);
  
              } else
  
                  s->macroblock_fragments[mapping_index++] = -1;
  
  
  
              if (i + 1 < s->fragment_height) {
  
                  s->all_fragments[current_fragment + s->fragment_width].macroblock = 
  
                      current_macroblock;
  
                  s->macroblock_fragments[mapping_index++] = 
  
                      current_fragment + s->fragment_width;
  
                  debug_init("%d ", current_fragment + s->fragment_width);
  
              } else
  
                  s->macroblock_fragments[mapping_index++] = -1;
  
  
  
              if ((j + 1 < s->fragment_width) && (i + 1 < s->fragment_height)) {
  
                  s->all_fragments[current_fragment + s->fragment_width + 1].macroblock = 
  
                      current_macroblock;
  
                  s->macroblock_fragments[mapping_index++] = 
  
                      current_fragment + s->fragment_width + 1;
  
                  debug_init("%d ", current_fragment + s->fragment_width + 1);
  
              } else
  
                  s->macroblock_fragments[mapping_index++] = -1;
  
  
  
              /* C planes */
  
              c_fragment = s->u_fragment_start + 
  
                  (i * s->fragment_width / 4) + (j / 2);
  
          s->all_fragments[c_fragment].macroblock = s->macroblock_count;
  
              s->macroblock_fragments[mapping_index++] = c_fragment;
  
              debug_init("%d ", c_fragment);
  
  
  
              c_fragment = s->v_fragment_start + 
  
                  (i * s->fragment_width / 4) + (j / 2);
  
          s->all_fragments[c_fragment].macroblock = s->macroblock_count;
  
              s->macroblock_fragments[mapping_index++] = c_fragment;
  
              debug_init("%d ", c_fragment);
  
  
  
              debug_init("\n");
  
  
  
              if (j + 2 <= s->fragment_width)
  
                  current_fragment += 2;
  
              else 
  
                  current_fragment++;
  
              current_macroblock++;
  
          }
  
  
  
          current_fragment += s->fragment_width;
  
      }
  
  }
  