1 /* 2 * $RCSfile: CompressionStreamNormal.java,v $ 3 * 4 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistribution of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * - Redistribution in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * Neither the name of Sun Microsystems, Inc. or the names of 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * This software is provided "AS IS," without a warranty of any 23 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 24 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 26 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 27 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 28 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 29 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 30 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 31 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 32 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 33 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGES. 35 * 36 * You acknowledge that this software is not designed, licensed or 37 * intended for use in the design, construction, operation or 38 * maintenance of any nuclear facility. 39 * 40 * $Revision: 1.5 $ 41 * $Date: 2007/02/09 17:20:16 $ 42 * $State: Exp $ 43 */ 44 45 package com.sun.j3d.utils.compression; 46 47 import javax.vecmath.Vector3f; 48 49 /** 50 * This class represents a normal in a compression stream. It maintains both 51 * floating-point and quantized representations. This normal may be bundled 52 * with a vertex or exist separately as a global normal. 53 */ 54 class CompressionStreamNormal extends CompressionStreamElement { 55 private int u, v ; 56 private int specialOctant, specialSextant ; 57 private float normalX, normalY, normalZ ; 58 59 int octant, sextant ; 60 boolean specialNormal ; 61 int uAbsolute, vAbsolute ; 62 63 /** 64 * Create a CompressionStreamNormal. 65 * 66 * @param stream CompressionStream associated with this element 67 * @param normal floating-point representation to be encoded 68 */ CompressionStreamNormal(CompressionStream stream, Vector3f normal)69 CompressionStreamNormal(CompressionStream stream, Vector3f normal) { 70 this.normalX = normal.x ; 71 this.normalY = normal.y ; 72 this.normalZ = normal.z ; 73 stream.byteCount += 12 ; 74 } 75 76 // 77 // Normal Encoding Parameterization 78 // 79 // A floating point normal is quantized to a desired number of bits by 80 // comparing it to candidate entries in a table of every possible normal 81 // at that quantization and finding the closest match. This table of 82 // normals is indexed by the following encoding: 83 // 84 // First, points on a unit radius sphere are parameterized by two angles, 85 // th and psi, using usual spherical coordinates. th is the angle about 86 // the y axis, psi is the inclination to the plane containing the point. 87 // The mapping between rectangular and spherical coordinates is: 88 // 89 // x = cos(th)*cos(psi) 90 // y = sin(psi) 91 // z = sin(th)*cos(psi) 92 // 93 // Points on sphere are folded first by octant, and then by sort order 94 // of xyz into one of six sextants. All the table encoding takes place in 95 // the positive octant, in the region bounded by the half spaces: 96 // 97 // x >= z 98 // z >= y 99 // y >= 0 100 // 101 // This triangular shaped patch runs from 0 to 45 degrees in th, and 102 // from 0 to as much as 0.615479709 (MAX_Y_ANG) in psi. The xyz bounds 103 // of the patch is: 104 // 105 // (1, 0, 0) (1/sqrt(2), 0, 1/sqrt(2)) (1/sqrt(3), 1/sqrt(3), 1/sqrt(3)) 106 // 107 // When dicing this space up into discrete points, the choice for y is 108 // linear quantization in psi. This means that if the y range is to be 109 // divided up into n segments, the angle of segment j is: 110 // 111 // psi(j) = MAX_Y_ANG*(j/n) 112 // 113 // The y height of the patch (in arc length) is *not* the same as the xz 114 // dimension. However, the subdivision quantization needs to treat xz and 115 // y equally. To achieve this, the th angles are re-parameterized as 116 // reflected psi angles. That is, the i-th point's th is: 117 // 118 // th(i) = asin(tan(psi(i))) = asin(tan(MAX_Y_ANG*(i/n))) 119 // 120 // To go the other direction, the angle th corresponds to the real index r 121 // (in the same 0-n range as i): 122 // 123 // r(th) = n*atan(sin(th))/MAX_Y_ANG 124 // 125 // Rounded to the nearest integer, this gives the closest integer index i 126 // to the xz angle th. Because the triangle has a straight edge on the 127 // line x=z, it is more intuitive to index the xz angles in reverse 128 // order. Thus the two equations above are replaced by: 129 // 130 // th(i) = asin(tan(psi(i))) = asin(tan(MAX_Y_ANG*((n-i)/n))) 131 // 132 // r(th) = n*(1 - atan(sin(th))/MAX_Y_ANG) 133 // 134 // Each level of quantization subdivides the triangular patch twice as 135 // densely. The case in which only the three vertices of the triangle are 136 // present is the first logical stage of representation, but because of 137 // how the table is encoded the first usable case starts one level of 138 // sub-division later. This three point level has an n of 2 by the above 139 // conventions. 140 // 141 private static final int MAX_UV_BITS = 6 ; 142 private static final int MAX_UV_ENTRIES = 64 ; 143 144 private static final double cgNormals[][][][] = 145 new double[MAX_UV_BITS+1][MAX_UV_ENTRIES+1][MAX_UV_ENTRIES+1][3] ; 146 147 private static final double MAX_Y_ANG = 0.615479709 ; 148 private static final double UNITY_14 = 16384.0 ; 149 computeNormals()150 private static void computeNormals() { 151 int inx, iny, inz, n ; 152 double th, psi, qnx, qny, qnz ; 153 154 for (int quant = 0 ; quant <= MAX_UV_BITS ; quant++) { 155 n = 1 << quant ; 156 157 for (int j = 0 ; j <= n ; j++) { 158 for (int i = 0 ; i <= n ; i++) { 159 if (i+j > n) continue ; 160 161 psi = MAX_Y_ANG*(j/((double) n)) ; 162 th = Math.asin(Math.tan(MAX_Y_ANG*((n-i)/((double) n)))) ; 163 164 qnx = Math.cos(th)*Math.cos(psi) ; 165 qny = Math.sin(psi) ; 166 qnz = Math.sin(th)*Math.cos(psi) ; 167 168 // The normal table uses 16-bit components and must be 169 // able to represent both +1.0 and -1.0, so convert the 170 // floating point normal components to fixed point with 14 171 // fractional bits, a unity bit, and a sign bit (s1.14). 172 // Set them back to get the float equivalent. 173 qnx = qnx*UNITY_14 ; inx = (int)qnx ; 174 qnx = inx ; qnx = qnx/UNITY_14 ; 175 176 qny = qny*UNITY_14 ; iny = (int)qny ; 177 qny = iny ; qny = qny/UNITY_14 ; 178 179 qnz = qnz*UNITY_14 ; inz = (int)qnz ; 180 qnz = inz ; qnz = qnz/UNITY_14 ; 181 182 cgNormals[quant][j][i][0] = qnx ; 183 cgNormals[quant][j][i][1] = qny ; 184 cgNormals[quant][j][i][2] = qnz ; 185 } 186 } 187 } 188 } 189 190 // 191 // An inverse sine table is used for each quantization level to take the Y 192 // component of a normal (which is the sine of the inclination angle) and 193 // obtain the closest quantized Y angle. 194 // 195 // At any level of compression, there are a fixed number of different Y 196 // angles (between 0 and MAX_Y_ANG). The inverse table is built to have 197 // slightly more than twice as many entries as y angles at any particular 198 // level; this ensures that the inverse look-up will get within one angle 199 // of the right one. The size of the table should be as small as 200 // possible, but with its delta sine still smaller than the delta sine 201 // between the last two angles to be encoded. 202 // 203 // Example: the inverse sine table has a maximum angle of 0.615479709. At 204 // the maximum resolution of 6 bits there are 65 discrete angles used, 205 // but twice as many are needed for thresholding between angles, so the 206 // delta angle is 0.615479709/128. The difference then between the last 207 // two angles to be encoded is: 208 // sin(0.615479709*128.0/128.0) - sin(0.615479709*127.0/128.0) = 0.003932730 209 // 210 // Using 8 significent bits below the binary point, fixed point can 211 // represent sines in increments of 0.003906250, just slightly smaller. 212 // However, because the maximum Y angle sine is 0.577350269, only 148 213 // instead of 256 table entries are needed. 214 // 215 private static final short inverseSine[][] = new short[MAX_UV_BITS+1][] ; 216 217 // UNITY_14 * sin(MAX_Y_ANGLE) 218 private static final short MAX_SIN_14BIT = 9459 ; 219 computeInverseSineTables()220 private static void computeInverseSineTables() { 221 int intSin, deltaSin, intAngle ; 222 double floatSin, floatAngle ; 223 short sin14[] = new short[MAX_UV_ENTRIES+1] ; 224 225 // Build table of sines in s1.14 fixed point for each of the 226 // discrete angles used at maximum resolution. 227 for (int i = 0 ; i <= MAX_UV_ENTRIES ; i++) { 228 sin14[i] = (short)(UNITY_14*Math.sin(i*MAX_Y_ANG/MAX_UV_ENTRIES)) ; 229 } 230 231 for (int quant = 0 ; quant <= MAX_UV_BITS ; quant++) { 232 switch (quant) { 233 default: 234 case 6: 235 // Delta angle: MAX_Y_ANGLE/128.0 236 // Bits below binary point for fixed point delta sine: 8 237 // Integer delta sine: 64 238 // Inverse sine table size: 148 entries 239 deltaSin = 1 << (14 - 8) ; 240 break ; 241 case 5: 242 // Delta angle: MAX_Y_ANGLE/64.0 243 // Bits below binary point for fixed point delta sine: 7 244 // Integer delta sine: 128 245 // Inverse sine table size: 74 entries 246 deltaSin = 1 << (14 - 7) ; 247 break ; 248 case 4: 249 // Delta angle: MAX_Y_ANGLE/32.0 250 // Bits below binary point for fixed point delta sine: 6 251 // Integer delta sine: 256 252 // Inverse sine table size: 37 entries 253 deltaSin = 1 << (14 - 6) ; 254 break ; 255 case 3: 256 // Delta angle: MAX_Y_ANGLE/16.0 257 // Bits below binary point for fixed point delta sine: 5 258 // Integer delta sine: 512 259 // Inverse sine table size: 19 entries 260 deltaSin = 1 << (14 - 5) ; 261 break ; 262 case 2: 263 // Delta angle: MAX_Y_ANGLE/8.0 264 // Bits below binary point for fixed point delta sine: 4 265 // Integer delta sine: 1024 266 // Inverse sine table size: 10 entries 267 deltaSin = 1 << (14 - 4) ; 268 break ; 269 case 1: 270 // Delta angle: MAX_Y_ANGLE/4.0 271 // Bits below binary point for fixed point delta sine: 3 272 // Integer delta sine: 2048 273 // Inverse sine table size: 5 entries 274 deltaSin = 1 << (14 - 3) ; 275 break ; 276 case 0: 277 // Delta angle: MAX_Y_ANGLE/2.0 278 // Bits below binary point for fixed point delta sine: 2 279 // Integer delta sine: 4096 280 // Inverse sine table size: 3 entries 281 deltaSin = 1 << (14 - 2) ; 282 break ; 283 } 284 285 inverseSine[quant] = new short[(MAX_SIN_14BIT/deltaSin) + 1] ; 286 287 intSin = 0 ; 288 for (int i = 0 ; i < inverseSine[quant].length ; i++) { 289 // Compute float representation of integer sine with desired 290 // number of fractional bits by effectively right shifting 14. 291 floatSin = intSin/UNITY_14 ; 292 293 // Compute the angle with this sine value and quantize it. 294 floatAngle = Math.asin(floatSin) ; 295 intAngle = (int)((floatAngle/MAX_Y_ANG) * (1 << quant)) ; 296 297 // Choose the closest of the three nearest quantized values 298 // intAngle-1, intAngle, and intAngle+1. 299 if (intAngle > 0) { 300 if (Math.abs(sin14[intAngle << (6-quant)] - intSin) > 301 Math.abs(sin14[(intAngle-1) << (6-quant)] - intSin)) 302 intAngle = intAngle-1 ; 303 } 304 305 if (intAngle < (1 << quant)) { 306 if (Math.abs(sin14[intAngle << (6-quant)] - intSin) > 307 Math.abs(sin14[(intAngle+1) << (6-quant)] - intSin)) 308 intAngle = intAngle+1 ; 309 } 310 311 inverseSine[quant][i] = (short)intAngle ; 312 intSin += deltaSin ; 313 } 314 } 315 } 316 317 /** 318 * Compute static tables needed for normal quantization. 319 */ 320 static { computeNormals()321 computeNormals() ; computeInverseSineTables()322 computeInverseSineTables() ; 323 } 324 325 /** 326 * Quantize the floating point normal to a 6-bit octant/sextant plus u,v 327 * components of [0..6] bits. Full resolution is 18 bits and the minimum 328 * is 6 bits. 329 * 330 * @param stream CompressionStream associated with this element 331 * @param table HuffmanTable for collecting data about the quantized 332 * representation of this element 333 */ quantize(CompressionStream stream, HuffmanTable huffmanTable)334 void quantize(CompressionStream stream, HuffmanTable huffmanTable) { 335 double nx, ny, nz, t ; 336 337 // Clamp UV quantization. 338 int quant = 339 (stream.normalQuant < 0? 0 : 340 (stream.normalQuant > 6? 6 : stream.normalQuant)) ; 341 342 nx = normalX ; 343 ny = normalY ; 344 nz = normalZ ; 345 346 octant = 0 ; 347 sextant = 0 ; 348 u = 0 ; 349 v = 0 ; 350 351 // Normalize the fixed point normal to the positive signed octant. 352 if (nx < 0.0) { 353 octant |= 4 ; 354 nx = -nx ; 355 } 356 if (ny < 0.0) { 357 octant |= 2 ; 358 ny = -ny ; 359 } 360 if (nz < 0.0) { 361 octant |= 1 ; 362 nz = -nz ; 363 } 364 365 // Normalize the fixed point normal to the proper sextant of the octant. 366 if (nx < ny) { 367 sextant |= 1 ; 368 t = nx ; 369 nx = ny ; 370 ny = t ; 371 } 372 if (nz < ny) { 373 sextant |= 2 ; 374 t = ny ; 375 ny = nz ; 376 nz = t ; 377 } 378 if (nx < nz) { 379 sextant |= 4 ; 380 t = nx ; 381 nx = nz ; 382 nz = t ; 383 } 384 385 // Convert the floating point y component to s1.14 fixed point. 386 int yInt = (int)(ny * UNITY_14) ; 387 388 // The y component of the normal is the sine of the y angle. Quantize 389 // the y angle by using the fixed point y component as an index into 390 // the inverse sine table of the correct size for the quantization 391 // level. (12 - quant) bits of the s1.14 y normal component are 392 // rolled off with a right shift; the remaining bits then match the 393 // number of bits used to represent the delta sine of the table. 394 int yIndex = inverseSine[quant][yInt >> (12-quant)] ; 395 396 // Search the two xz rows near y for the best match. 397 int ii = 0 ; 398 int jj = 0 ; 399 int n = 1 << quant ; 400 double dot, bestDot = -1 ; 401 402 for (int j = yIndex-1 ; j < yIndex+1 && j <= n ; j++) { 403 if (j < 0) 404 continue ; 405 406 for (int i = 0 ; i <= n ; i++) { 407 if (i+j > n) 408 continue ; 409 410 dot = nx * cgNormals[quant][j][i][0] + 411 ny * cgNormals[quant][j][i][1] + 412 nz * cgNormals[quant][j][i][2] ; 413 414 if (dot > bestDot) { 415 bestDot = dot ; 416 ii = i ; 417 jj = j ; 418 } 419 } 420 } 421 422 // Convert u and v to standard grid form. 423 u = ii << (6 - quant) ; 424 v = jj << (6 - quant) ; 425 426 // Check for special normals and specially encode them. 427 specialNormal = false ; 428 if (u == 64 && v == 0) { 429 // six coordinate axes case 430 if (sextant == 0 || sextant == 2) { 431 // +/- x-axis 432 specialSextant = 0x6 ; 433 specialOctant = ((octant & 4) != 0)? 0x2 : 0 ; 434 435 } else if (sextant == 3 || sextant == 1) { 436 // +/- y-axis 437 specialSextant = 0x6 ; 438 specialOctant = 4 | (((octant & 2) != 0)? 0x2 : 0) ; 439 440 } else if (sextant == 5 || sextant == 4) { 441 // +/- z-axis 442 specialSextant = 0x7 ; 443 specialOctant = ((octant & 1) != 0)? 0x2 : 0 ; 444 } 445 specialNormal = true ; 446 u = v = 0 ; 447 448 } else if (u == 0 && v == 64) { 449 // eight mid point case 450 specialSextant = 6 | (octant >> 2) ; 451 specialOctant = ((octant & 0x3) << 1) | 1 ; 452 specialNormal = true ; 453 u = v = 0 ; 454 } 455 456 // Compute deltas if possible. 457 // Use the non-normalized ii and jj indices. 458 int du = 0 ; 459 int dv = 0 ; 460 int uv64 = 64 >> (6 - quant) ; 461 462 absolute = false ; 463 if (stream.firstNormal || stream.normalQuantChanged || 464 stream.lastSpecialNormal || specialNormal) { 465 // The first normal by definition is absolute, and normals cannot 466 // be represented as deltas to or from special normals, nor from 467 // normals with a different quantization. 468 absolute = true ; 469 stream.firstNormal = false ; 470 stream.normalQuantChanged = false ; 471 472 } else if (stream.lastOctant == octant && 473 stream.lastSextant == sextant) { 474 // Deltas are always allowed within the same sextant/octant. 475 du = ii - stream.lastU ; 476 dv = jj - stream.lastV ; 477 478 } else if (stream.lastOctant != octant && 479 stream.lastSextant == sextant && 480 (((sextant == 1 || sextant == 5) && 481 (stream.lastOctant & 3) == (octant & 3)) || 482 ((sextant == 0 || sextant == 4) && 483 (stream.lastOctant & 5) == (octant & 5)) || 484 ((sextant == 2 || sextant == 3) && 485 (stream.lastOctant & 6) == (octant & 6)))) { 486 // If the sextants are the same, the octants can differ only when 487 // they are bordering each other on the same edge that the 488 // sextant has. 489 du = ii - stream.lastU ; 490 dv = -jj - stream.lastV ; 491 492 // Can't delta by less than -64. 493 if (dv < -uv64) absolute = true ; 494 495 // Can't delta doubly defined points. 496 if (jj == 0) absolute = true ; 497 498 } else if (stream.lastOctant == octant && 499 stream.lastSextant != sextant && 500 ((sextant == 0 && stream.lastSextant == 4) || 501 (sextant == 4 && stream.lastSextant == 0) || 502 (sextant == 1 && stream.lastSextant == 5) || 503 (sextant == 5 && stream.lastSextant == 1) || 504 (sextant == 2 && stream.lastSextant == 3) || 505 (sextant == 3 && stream.lastSextant == 2))) { 506 // If the octants are the same, the sextants must border on 507 // the i side (this case) or the j side (next case). 508 du = -ii - stream.lastU ; 509 dv = jj - stream.lastV ; 510 511 // Can't delta by less than -64. 512 if (du < -uv64) absolute = true ; 513 514 // Can't delta doubly defined points. 515 if (ii == 0) absolute = true ; 516 517 } else if (stream.lastOctant == octant && 518 stream.lastSextant != sextant && 519 ((sextant == 0 && stream.lastSextant == 2) || 520 (sextant == 2 && stream.lastSextant == 0) || 521 (sextant == 1 && stream.lastSextant == 3) || 522 (sextant == 3 && stream.lastSextant == 1) || 523 (sextant == 4 && stream.lastSextant == 5) || 524 (sextant == 5 && stream.lastSextant == 4))) { 525 // If the octants are the same, the sextants must border on 526 // the j side (this case) or the i side (previous case). 527 if (((ii + jj ) != uv64) && (ii != 0) && (jj != 0)) { 528 du = uv64 - ii - stream.lastU ; 529 dv = uv64 - jj - stream.lastV ; 530 531 // Can't delta by greater than +63. 532 if ((du >= uv64) || (dv >= uv64)) 533 absolute = true ; 534 } else 535 // Can't delta doubly defined points. 536 absolute = true ; 537 538 } else 539 // Can't delta this normal. 540 absolute = true ; 541 542 if (absolute == false) { 543 // Convert du and dv to standard grid form. 544 u = du << (6 - quant) ; 545 v = dv << (6 - quant) ; 546 } 547 548 // Compute length and shift common to all components. 549 computeLengthShift(u, v) ; 550 551 if (absolute && length > 6) { 552 // Absolute normal u, v components are unsigned 6-bit integers, so 553 // truncate the 0 sign bit for values > 0x001f. 554 length = 6 ; 555 } 556 557 // Add this element to the Huffman table associated with this stream. 558 huffmanTable.addNormalEntry(length, shift, absolute) ; 559 560 // Save current normal as last. 561 stream.lastSextant = sextant ; 562 stream.lastOctant = octant ; 563 stream.lastU = ii ; 564 stream.lastV = jj ; 565 stream.lastSpecialNormal = specialNormal ; 566 567 // Copy and retain absolute normal for mesh buffer lookup. 568 uAbsolute = ii ; 569 vAbsolute = jj ; 570 } 571 572 /** 573 * Output a setNormal command. 574 * 575 * @param table HuffmanTable mapping quantized representations to 576 * compressed encodings 577 * @param output CommandStream for collecting compressed output 578 */ outputCommand(HuffmanTable table, CommandStream output)579 void outputCommand(HuffmanTable table, CommandStream output) { 580 outputNormal(table, output, CommandStream.SET_NORM, 8) ; 581 } 582 583 /** 584 * Output a normal subcommand. 585 * 586 * @param table HuffmanTable mapping quantized representations to 587 * compressed encodings 588 * @param output CommandStream for collecting compressed output 589 */ outputSubcommand(HuffmanTable table, CommandStream output)590 void outputSubcommand(HuffmanTable table, CommandStream output) { 591 outputNormal(table, output, 0, 6) ; 592 } 593 594 // 595 // Output the final compressed bits to the output command stream. 596 // outputNormal(HuffmanTable table, CommandStream output, int header, int headerLength)597 private void outputNormal(HuffmanTable table, CommandStream output, 598 int header, int headerLength) { 599 600 HuffmanNode t ; 601 602 // Look up the Huffman token for this compression stream element. 603 t = table.getNormalEntry(length, shift, absolute) ; 604 605 // Construct the normal subcommand. 606 int componentLength = t.dataLength - t.shift ; 607 int subcommandLength = 0 ; 608 long normalSubcommand = 0 ; 609 610 if (absolute) { 611 // A 3-bit sextant and a 3-bit octant are always present. 612 subcommandLength = t.tagLength + 6 ; 613 614 if (specialNormal) 615 // Use the specially-encoded sextant and octant. 616 normalSubcommand = 617 (t.tag << 6) | (specialSextant << 3) | specialOctant ; 618 else 619 // Use the general encoding rule. 620 normalSubcommand = 621 (t.tag << 6) | (sextant << 3) | octant ; 622 } else { 623 // The tag is immediately followed by the u and v delta components. 624 subcommandLength = t.tagLength ; 625 normalSubcommand = t.tag ; 626 } 627 628 // Add the u and v values to the subcommand. 629 subcommandLength += (2 * componentLength) ; 630 631 u = (u >> t.shift) & (int)lengthMask[componentLength] ; 632 v = (v >> t.shift) & (int)lengthMask[componentLength] ; 633 634 normalSubcommand = 635 (normalSubcommand << (2 * componentLength)) | 636 (u << (1 * componentLength)) | 637 (v << (0 * componentLength)) ; 638 639 if (subcommandLength < 6) { 640 // The header will have some empty bits. The Huffman tag 641 // computation will prevent this if necessary. 642 header |= (int)(normalSubcommand << (6 - subcommandLength)) ; 643 subcommandLength = 0 ; 644 } 645 else { 646 // Move the 1st 6 bits of the subcommand into the header. 647 header |= (int)(normalSubcommand >>> (subcommandLength - 6)) ; 648 subcommandLength -= 6 ; 649 } 650 651 // Add the header and body to the output buffer. 652 output.addCommand(header, headerLength, 653 normalSubcommand, subcommandLength) ; 654 } 655 toString()656 public String toString() { 657 String fixed ; 658 659 if (specialNormal) 660 fixed = " special normal, sextant " + specialSextant + 661 " octant " + specialOctant ; 662 663 else if (absolute) 664 fixed = " sextant " + sextant + " octant " + octant + 665 " u " + u + " v " + v ; 666 else 667 fixed = " du " + u + " dv " + v ; 668 669 return 670 "normal: " + normalX + " " + normalY + " " + normalZ + "\n" 671 + fixed + "\n" + " length " + length + " shift " + shift + 672 (absolute? " absolute" : " relative") ; 673 } 674 } 675