// returns the entry number or -1 on eof int decode(Buffer b) { int ptr = 0; DecodeAux t = decode_tree; int lok = b.look(t.tabn); // System.err.println(this+" "+t+" lok="+lok+", tabn="+t.tabn); if (lok >= 0) { ptr = t.tab[lok]; b.adv(t.tabl[lok]); if (ptr <= 0) { return -ptr; } } do { switch (b.read1()) { case 0: ptr = t.ptr0[ptr]; break; case 1: ptr = t.ptr1[ptr]; break; case -1: default: return (-1); } } while (ptr > 0); return (-ptr); }
Object unpack(Info vi, Buffer opb) { int acc = 0; InfoResidue0 info = new InfoResidue0(); info.begin = opb.read(24); info.end = opb.read(24); info.grouping = opb.read(24) + 1; info.partitions = opb.read(6) + 1; info.groupbook = opb.read(8); for (int j = 0; j < info.partitions; j++) { int cascade = opb.read(3); if (opb.read(1) != 0) { cascade |= (opb.read(5) << 3); } info.secondstages[j] = cascade; acc += Util.icount(cascade); } for (int j = 0; j < acc; j++) { info.booklist[j] = opb.read(8); } if (info.groupbook >= vi.books) { free_info(info); return (null); } for (int j = 0; j < acc; j++) { if (info.booklist[j] >= vi.books) { free_info(info); return (null); } } return (info); }
void pack(Object vr, Buffer opb) { InfoResidue0 info = (InfoResidue0) vr; int acc = 0; opb.write(info.begin, 24); opb.write(info.end, 24); opb.write(info.grouping - 1, 24); /* * residue vectors to group and code * with a partitioned book */ opb.write(info.partitions - 1, 6); /* possible partition choices */ opb.write(info.groupbook, 8); /* group huffman book */ /* * secondstages is a bitmask; as encoding progresses pass by pass, a * bitmask of one indicates this partition class has bits to write this * pass */ for (int j = 0; j < info.partitions; j++) { int i = info.secondstages[j]; if (Util.ilog(i) > 3) { /* yes, this is a minor hack due to not thinking ahead */ opb.write(i, 3); opb.write(1, 1); opb.write(i >>> 3, 5); } else { opb.write(i, 4); /* trailing zero */ } acc += Util.icount(i); } for (int j = 0; j < acc; j++) { opb.write(info.booklist[j], 8); } }
void pack(Info vi, Object imap, Buffer opb) { InfoMapping0 info = (InfoMapping0) imap; /* another 'we meant to do it this way' hack... up to beta 4, we packed 4 binary zeros here to signify one submapping in use. We now redefine that to mean four bitflags that indicate use of deeper features; bit0:submappings, bit1:coupling, bit2,3:reserved. This is backward compatable with all actual uses of the beta code. */ if (info.submaps > 1) { opb.write(1, 1); opb.write(info.submaps - 1, 4); } else { opb.write(0, 1); } if (info.coupling_steps > 0) { opb.write(1, 1); opb.write(info.coupling_steps - 1, 8); for (int i = 0; i < info.coupling_steps; i++) { opb.write(info.coupling_mag[i], Util.ilog2(vi.channels)); opb.write(info.coupling_ang[i], Util.ilog2(vi.channels)); } } else { opb.write(0, 1); } opb.write(0, 2); /* 2,3:reserved */ /* we don't write the channel submappings if we only have one... */ if (info.submaps > 1) { for (int i = 0; i < vi.channels; i++) opb.write(info.chmuxlist[i], 4); } for (int i = 0; i < info.submaps; i++) { opb.write(info.timesubmap[i], 8); opb.write(info.floorsubmap[i], 8); opb.write(info.residuesubmap[i], 8); } }
// also responsible for range checking Object unpack(Info vi, Buffer opb) { InfoMapping0 info = new InfoMapping0(); if (opb.read(1) != 0) { info.submaps = opb.read(4) + 1; } else { info.submaps = 1; } if (opb.read(1) != 0) { info.coupling_steps = opb.read(8) + 1; for (int i = 0; i < info.coupling_steps; i++) { int testM = info.coupling_mag[i] = opb.read(Util.ilog2(vi.channels)); int testA = info.coupling_ang[i] = opb.read(Util.ilog2(vi.channels)); if (testM < 0 || testA < 0 || testM == testA || testM >= vi.channels || testA >= vi.channels) { // goto err_out; info.free(); return (null); } } } if (opb.read(2) > 0) { /* 2,3:reserved */ info.free(); return (null); } if (info.submaps > 1) { for (int i = 0; i < vi.channels; i++) { info.chmuxlist[i] = opb.read(4); if (info.chmuxlist[i] >= info.submaps) { info.free(); return (null); } } } for (int i = 0; i < info.submaps; i++) { info.timesubmap[i] = opb.read(8); if (info.timesubmap[i] >= vi.times) { info.free(); return (null); } info.floorsubmap[i] = opb.read(8); if (info.floorsubmap[i] >= vi.floors) { info.free(); return (null); } info.residuesubmap[i] = opb.read(8); if (info.residuesubmap[i] >= vi.residues) { info.free(); return (null); } } return info; }
int pack(Buffer opb) { int i; boolean ordered = false; opb.write(0x564342, 24); opb.write(dim, 16); opb.write(entries, 24); // pack the codewords. There are two packings; length ordered and // length random. Decide between the two now. for (i = 1; i < entries; i++) { if (lengthlist[i] < lengthlist[i - 1]) break; } if (i == entries) ordered = true; if (ordered) { // length ordered. We only need to say how many codewords of // each length. The actual codewords are generated // deterministically int count = 0; opb.write(1, 1); // ordered opb.write(lengthlist[0] - 1, 5); // 1 to 32 for (i = 1; i < entries; i++) { int _this = lengthlist[i]; int _last = lengthlist[i - 1]; if (_this > _last) { for (int j = _last; j < _this; j++) { opb.write(i - count, ilog(entries - count)); count = i; } } } opb.write(i - count, ilog(entries - count)); } else { // length random. Again, we don't code the codeword itself, just // the length. This time, though, we have to encode each length opb.write(0, 1); // unordered // algortihmic mapping has use for 'unused entries', which we tag // here. The algorithmic mapping happens as usual, but the unused // entry has no codeword. for (i = 0; i < entries; i++) { if (lengthlist[i] == 0) break; } if (i == entries) { opb.write(0, 1); // no unused entries for (i = 0; i < entries; i++) { opb.write(lengthlist[i] - 1, 5); } } else { opb.write(1, 1); // we have unused entries; thus we tag for (i = 0; i < entries; i++) { if (lengthlist[i] == 0) { opb.write(0, 1); } else { opb.write(1, 1); opb.write(lengthlist[i] - 1, 5); } } } } // is the entry number the desired return value, or do we have a // mapping? If we have a mapping, what type? opb.write(maptype, 4); switch (maptype) { case 0: // no mapping break; case 1: case 2: // implicitly populated value mapping // explicitly populated value mapping if (quantlist == null) { // no quantlist? error return (-1); } // values that define the dequantization opb.write(q_min, 32); opb.write(q_delta, 32); opb.write(q_quant - 1, 4); opb.write(q_sequencep, 1); { int quantvals = 0; switch (maptype) { case 1: // a single column of (c->entries/c->dim) quantized values for // building a full value list algorithmically (square lattice) quantvals = maptype1_quantvals(); break; case 2: // every value (c->entries*c->dim total) specified explicitly quantvals = entries * dim; break; } // quantized values for (i = 0; i < quantvals; i++) { opb.write(Math.abs(quantlist[i]), q_quant); } } break; default: // error case; we don't have any other map types now return (-1); } return (0); }
// unpacks a codebook from the packet buffer into the codebook struct, // readies the codebook auxiliary structures for decode int unpack(Buffer opb) { int i; // memset(s,0,sizeof(static_codebook)); // make sure alignment is correct if (opb.read(24) != 0x564342) { // goto _eofout; clear(); return (-1); } // first the basic parameters dim = opb.read(16); entries = opb.read(24); if (entries == -1) { // goto _eofout; clear(); return (-1); } // codeword ordering.... length ordered or unordered? switch (opb.read(1)) { case 0: // unordered lengthlist = new int[entries]; // allocated but unused entries? if (opb.read(1) != 0) { // yes, unused entries for (i = 0; i < entries; i++) { if (opb.read(1) != 0) { int num = opb.read(5); if (num == -1) { // goto _eofout; clear(); return (-1); } lengthlist[i] = num + 1; } else { lengthlist[i] = 0; } } } else { // all entries used; no tagging for (i = 0; i < entries; i++) { int num = opb.read(5); if (num == -1) { // goto _eofout; clear(); return (-1); } lengthlist[i] = num + 1; } } break; case 1: // ordered { int length = opb.read(5) + 1; lengthlist = new int[entries]; for (i = 0; i < entries; ) { int num = opb.read(ilog(entries - i)); if (num == -1) { // goto _eofout; clear(); return (-1); } for (int j = 0; j < num; j++, i++) { lengthlist[i] = length; } length++; } } break; default: // EOF return (-1); } // Do we have a mapping to unpack? switch ((maptype = opb.read(4))) { case 0: // no mapping break; case 1: case 2: // implicitly populated value mapping // explicitly populated value mapping q_min = opb.read(32); q_delta = opb.read(32); q_quant = opb.read(4) + 1; q_sequencep = opb.read(1); { int quantvals = 0; switch (maptype) { case 1: quantvals = maptype1_quantvals(); break; case 2: quantvals = entries * dim; break; } // quantized values quantlist = new int[quantvals]; for (i = 0; i < quantvals; i++) { quantlist[i] = opb.read(q_quant); } if (quantlist[quantvals - 1] == -1) { // goto _eofout; clear(); return (-1); } } break; default: // goto _eofout; clear(); return (-1); } // all set return (0); // _errout: // _eofout: // vorbis_staticbook_clear(s); // return(-1); }
// returns the number of bits int encode(int a, Buffer b) { b.write(codelist[a], c.lengthlist[a]); return (c.lengthlist[a]); }