| 8577 | } nodeElt; |
| 8578 | |
| 8579 | static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits) |
| 8580 | { |
| 8581 | const U32 largestBits = huffNode[lastNonNull].nbBits; |
| 8582 | if (largestBits <= maxNbBits) return largestBits; /* early exit : no elt > maxNbBits */ |
| 8583 | |
| 8584 | /* there are several too large elements (at least >= 2) */ |
| 8585 | { int totalCost = 0; |
| 8586 | const U32 baseCost = 1 << (largestBits - maxNbBits); |
| 8587 | int n = (int)lastNonNull; |
| 8588 | |
| 8589 | while (huffNode[n].nbBits > maxNbBits) { |
| 8590 | totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)); |
| 8591 | huffNode[n].nbBits = (BYTE)maxNbBits; |
| 8592 | n --; |
| 8593 | } /* n stops at huffNode[n].nbBits <= maxNbBits */ |
| 8594 | while (huffNode[n].nbBits == maxNbBits) n--; /* n end at index of smallest symbol using < maxNbBits */ |
| 8595 | |
| 8596 | /* renorm totalCost */ |
| 8597 | totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */ |
| 8598 | |
| 8599 | /* repay normalized cost */ |
| 8600 | { U32 const noSymbol = 0xF0F0F0F0; |
| 8601 | U32 rankLast[HUF_TABLELOG_MAX+2]; |
| 8602 | |
| 8603 | /* Get pos of last (smallest) symbol per rank */ |
| 8604 | memset(rankLast, 0xF0, sizeof(rankLast)); |
| 8605 | { U32 currentNbBits = maxNbBits; |
| 8606 | int pos; |
| 8607 | for (pos=n ; pos >= 0; pos--) { |
| 8608 | if (huffNode[pos].nbBits >= currentNbBits) continue; |
| 8609 | currentNbBits = huffNode[pos].nbBits; /* < maxNbBits */ |
| 8610 | rankLast[maxNbBits-currentNbBits] = (U32)pos; |
| 8611 | } } |
| 8612 | |
| 8613 | while (totalCost > 0) { |
| 8614 | U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1; |
| 8615 | for ( ; nBitsToDecrease > 1; nBitsToDecrease--) { |
| 8616 | U32 const highPos = rankLast[nBitsToDecrease]; |
| 8617 | U32 const lowPos = rankLast[nBitsToDecrease-1]; |
| 8618 | if (highPos == noSymbol) continue; |
| 8619 | if (lowPos == noSymbol) break; |
| 8620 | { U32 const highTotal = huffNode[highPos].count; |
| 8621 | U32 const lowTotal = 2 * huffNode[lowPos].count; |
| 8622 | if (highTotal <= lowTotal) break; |
| 8623 | } } |
| 8624 | /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */ |
| 8625 | /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */ |
| 8626 | while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) |
| 8627 | nBitsToDecrease ++; |
| 8628 | totalCost -= 1 << (nBitsToDecrease-1); |
| 8629 | if (rankLast[nBitsToDecrease-1] == noSymbol) |
| 8630 | rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */ |
| 8631 | huffNode[rankLast[nBitsToDecrease]].nbBits ++; |
| 8632 | if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */ |
| 8633 | rankLast[nBitsToDecrease] = noSymbol; |
| 8634 | else { |
| 8635 | rankLast[nBitsToDecrease]--; |
| 8636 | if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease) |
no test coverage detected