mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
583 lines
26 KiB
C
583 lines
26 KiB
C
|
|
#include <stdlib.h>
|
||
|
|
#include "bpe_internal.h"
|
||
|
|
|
||
|
|
const int bit2_pattern[] = {0, 2, 1, 3};
|
||
|
|
const int bit3_pattern[] = {1, 4, 0, 5, 2, 6, 3, 7};
|
||
|
|
const int bit3_pattern_TranD[] = {0, 3, 0, 4, 1, 5, 2, 6};
|
||
|
|
const int bit4_pattern_TypeCi[] = {10, 1, 3, 6, 2, 5, 9, 12, 0, 8, 7, 13, 4, 14, 11, 15};
|
||
|
|
const int bit4_pattern_TypeHij_TranHi[] = {0, 1, 3, 6, 2, 5, 9, 11, 0, 8, 7, 12, 4, 13, 10, 14};
|
||
|
|
|
||
|
|
extern void StagesEnCodingGaggles1(StructCodingPara *, BitPlaneBits *,
|
||
|
|
UCHAR8, UCHAR8[], BOOL[]);
|
||
|
|
extern void StagesEnCodingGaggles2(StructCodingPara *, BitPlaneBits *,
|
||
|
|
UCHAR8, UCHAR8[], BOOL[]);
|
||
|
|
extern void StagesEnCodingGaggles3(StructCodingPara *, BitPlaneBits *,
|
||
|
|
UCHAR8, UCHAR8[], BOOL[]);
|
||
|
|
|
||
|
|
extern void StagesDeCodingGaggles1(StructCodingPara *, BitPlaneBits *,
|
||
|
|
UCHAR8, UCHAR8 *, BOOL *);
|
||
|
|
extern void StagesDeCodingGaggles2(StructCodingPara *, BitPlaneBits *,
|
||
|
|
UCHAR8, UCHAR8 *, BOOL *);
|
||
|
|
extern void StagesDeCodingGaggles3(StructCodingPara *, BitPlaneBits *,
|
||
|
|
UCHAR8, UCHAR8 *, BOOL *);
|
||
|
|
|
||
|
|
void PatternMapping(StrSymbolDetails *StrSymbol)
|
||
|
|
{
|
||
|
|
switch (StrSymbol->sym_len) {
|
||
|
|
case 0: return;
|
||
|
|
case 1: StrSymbol->sym_mapped_pattern = StrSymbol->sym_val; break;
|
||
|
|
case 2: StrSymbol->sym_mapped_pattern = bit2_pattern[StrSymbol->sym_val]; break;
|
||
|
|
case 3:
|
||
|
|
if (StrSymbol->type == ENUM_TRAN_D)
|
||
|
|
StrSymbol->sym_mapped_pattern = bit3_pattern_TranD[StrSymbol->sym_val];
|
||
|
|
else
|
||
|
|
StrSymbol->sym_mapped_pattern = bit3_pattern[StrSymbol->sym_val];
|
||
|
|
break;
|
||
|
|
case 4:
|
||
|
|
if (StrSymbol->type == ENUM_TYPE_CI)
|
||
|
|
StrSymbol->sym_mapped_pattern = bit4_pattern_TypeCi[StrSymbol->sym_val];
|
||
|
|
else if (StrSymbol->type == ENUM_TRAN_HI || StrSymbol->type == ENUM_TYPE_HIJ)
|
||
|
|
StrSymbol->sym_mapped_pattern = bit4_pattern_TypeHij_TranHi[StrSymbol->sym_val];
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void DeMappingPattern(StrSymbolDetails *StrSymbol)
|
||
|
|
{
|
||
|
|
UCHAR8 i;
|
||
|
|
switch (StrSymbol->sym_len) {
|
||
|
|
case 1:
|
||
|
|
StrSymbol->sym_val = StrSymbol->sym_mapped_pattern;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
for (i = 0; i < 4; i++) {
|
||
|
|
if (StrSymbol->sym_mapped_pattern == bit2_pattern[i]) {
|
||
|
|
StrSymbol->sym_val = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
if (StrSymbol->type == ENUM_TRAN_D) {
|
||
|
|
for (i = 1; i < 8; i++) {
|
||
|
|
if (StrSymbol->sym_mapped_pattern == bit3_pattern_TranD[i]) {
|
||
|
|
StrSymbol->sym_val = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
for (i = 0; i < 8; i++) {
|
||
|
|
if (StrSymbol->sym_mapped_pattern == bit3_pattern[i]) {
|
||
|
|
StrSymbol->sym_val = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case 4:
|
||
|
|
if (StrSymbol->type == ENUM_TYPE_CI) {
|
||
|
|
for (i = 0; i < 16; i++) {
|
||
|
|
if (StrSymbol->sym_mapped_pattern == bit4_pattern_TypeCi[i]) {
|
||
|
|
StrSymbol->sym_val = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else if (StrSymbol->type == ENUM_TRAN_HI || StrSymbol->type == ENUM_TYPE_HIJ) {
|
||
|
|
for (i = 1; i < 16; i++) {
|
||
|
|
if (StrSymbol->sym_mapped_pattern == bit4_pattern_TypeHij_TranHi[i]) {
|
||
|
|
StrSymbol->sym_val = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void BitPlaneSymbolReset(StrSymbolDetails *SymbolStr)
|
||
|
|
{
|
||
|
|
SymbolStr->sign = 0;
|
||
|
|
SymbolStr->sym_len = 0;
|
||
|
|
SymbolStr->sym_mapped_pattern = 0;
|
||
|
|
SymbolStr->sym_val = 0;
|
||
|
|
SymbolStr->type = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CodingOptions(StructCodingPara *PtrCoding,
|
||
|
|
BitPlaneBits *BlockInfo,
|
||
|
|
UINT32 BlocksInGaggle,
|
||
|
|
UCHAR8 Option[])
|
||
|
|
{
|
||
|
|
DWORD32 BlockSeq = 0;
|
||
|
|
DWORD32 bitsCounter_2Bits[2] = {0};
|
||
|
|
DWORD32 bitsCounter_3Bits[3] = {0};
|
||
|
|
DWORD32 bitsCounter_4Bits[4] = {0};
|
||
|
|
|
||
|
|
for (BlockSeq = 0; BlockSeq < BlocksInGaggle; BlockSeq++) {
|
||
|
|
UCHAR8 SymbolIndex = 0;
|
||
|
|
if (BlockInfo[BlockSeq].BitMaxAC < PtrCoding->BitPlane)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
for (SymbolIndex = 0; SymbolIndex < MAX_SYMBOLS_IN_BLOCK; SymbolIndex++) {
|
||
|
|
if (BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].type == ENUM_NONE)
|
||
|
|
continue;
|
||
|
|
else if (BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_len == 1) {
|
||
|
|
PatternMapping(&BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex]);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
PatternMapping(&BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex]);
|
||
|
|
|
||
|
|
if (BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_len == 2) {
|
||
|
|
switch (BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_mapped_pattern) {
|
||
|
|
case 0: bitsCounter_2Bits[0] += 1; break;
|
||
|
|
case 1: bitsCounter_2Bits[0] += 2; break;
|
||
|
|
case 2: bitsCounter_2Bits[0] += 3; break;
|
||
|
|
case 3: bitsCounter_2Bits[0] += 3; break;
|
||
|
|
default: ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
}
|
||
|
|
bitsCounter_2Bits[1] += 2;
|
||
|
|
} else if (BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_len == 3) {
|
||
|
|
UCHAR8 p = BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_mapped_pattern;
|
||
|
|
if (p <= 2) bitsCounter_3Bits[0] += p + 1;
|
||
|
|
else if (p <= 5) bitsCounter_3Bits[0] += 5;
|
||
|
|
else if (p <= 7) bitsCounter_3Bits[0] += 6;
|
||
|
|
else ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
|
||
|
|
if (p <= 1) bitsCounter_3Bits[1] += 2;
|
||
|
|
else if (p <= 3) bitsCounter_3Bits[1] += 3;
|
||
|
|
else if (p <= 7) bitsCounter_3Bits[1] += 4;
|
||
|
|
else ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
|
||
|
|
bitsCounter_3Bits[2] += 3;
|
||
|
|
} else if (BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_len == 4) {
|
||
|
|
UCHAR8 p = BlockInfo[BlockSeq].SymbolsBlock[SymbolIndex].sym_mapped_pattern;
|
||
|
|
|
||
|
|
if (p <= 3) bitsCounter_4Bits[0] += p + 1;
|
||
|
|
else if (p <= 7) bitsCounter_4Bits[0] += 7;
|
||
|
|
else if (p <= 15) bitsCounter_4Bits[0] += 8;
|
||
|
|
else ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
|
||
|
|
if (p <= 1) bitsCounter_4Bits[1] += 2;
|
||
|
|
else if (p <= 3) bitsCounter_4Bits[1] += 3;
|
||
|
|
else if (p <= 5) bitsCounter_4Bits[1] += 4;
|
||
|
|
else if (p <= 11) bitsCounter_4Bits[1] += 6;
|
||
|
|
else if (p <= 15) bitsCounter_4Bits[1] += 7;
|
||
|
|
else ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
|
||
|
|
if (p <= 3) bitsCounter_4Bits[2] += 3;
|
||
|
|
else if (p <= 7) bitsCounter_4Bits[2] += 4;
|
||
|
|
else if (p <= 15) bitsCounter_4Bits[2] += 5;
|
||
|
|
else ErrorMsg(BPE_PATTERNING_CODING_ERROR);
|
||
|
|
|
||
|
|
bitsCounter_4Bits[3] += 4;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Option[0] = (bitsCounter_2Bits[0] < bitsCounter_2Bits[1]) ? 0 : 1;
|
||
|
|
|
||
|
|
if (bitsCounter_3Bits[2] <= bitsCounter_3Bits[0] &&
|
||
|
|
bitsCounter_3Bits[2] <= bitsCounter_3Bits[1])
|
||
|
|
Option[1] = 3;
|
||
|
|
else if (bitsCounter_3Bits[0] <= bitsCounter_3Bits[1] &&
|
||
|
|
bitsCounter_3Bits[0] <= bitsCounter_3Bits[2])
|
||
|
|
Option[1] = 0;
|
||
|
|
else
|
||
|
|
Option[1] = 1;
|
||
|
|
|
||
|
|
if (bitsCounter_4Bits[3] <= bitsCounter_4Bits[0] &&
|
||
|
|
bitsCounter_4Bits[3] <= bitsCounter_4Bits[1] &&
|
||
|
|
bitsCounter_4Bits[3] <= bitsCounter_4Bits[2])
|
||
|
|
Option[2] = 3;
|
||
|
|
else if (bitsCounter_4Bits[0] <= bitsCounter_4Bits[1] &&
|
||
|
|
bitsCounter_4Bits[0] <= bitsCounter_4Bits[2] &&
|
||
|
|
bitsCounter_4Bits[0] <= bitsCounter_4Bits[3])
|
||
|
|
Option[2] = 0;
|
||
|
|
else if (bitsCounter_4Bits[1] <= bitsCounter_4Bits[0] &&
|
||
|
|
bitsCounter_4Bits[1] <= bitsCounter_4Bits[2] &&
|
||
|
|
bitsCounter_4Bits[1] <= bitsCounter_4Bits[3])
|
||
|
|
Option[2] = 1;
|
||
|
|
else
|
||
|
|
Option[2] = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
void RefBitsDe(StructCodingPara *PtrCoding, BitPlaneBits *BlockInfo)
|
||
|
|
{
|
||
|
|
UINT32 BlockSeq;
|
||
|
|
UCHAR8 i, j, k, p;
|
||
|
|
DWORD32 TempWord;
|
||
|
|
long **block;
|
||
|
|
UCHAR8 BitPlane = PtrCoding->BitPlane;
|
||
|
|
|
||
|
|
if (PtrCoding->PtrHeader->Header.Part2.StageStop_2Bits < 3 &&
|
||
|
|
(PtrCoding->PtrHeader->Header.Part2.BitPlaneStop_5Bits == BitPlane - 1 ||
|
||
|
|
PtrCoding->altStrageStop))
|
||
|
|
return;
|
||
|
|
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding = 0;
|
||
|
|
|
||
|
|
for (BlockSeq = 0; BlockSeq < PtrCoding->PtrHeader->Header.Part3.S_20Bits; BlockSeq++) {
|
||
|
|
if (BlockInfo[BlockSeq].BitMaxAC < BitPlane)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
block = BlockInfo[BlockSeq].PtrBlockAddress;
|
||
|
|
|
||
|
|
if (BlockInfo[BlockSeq].RefineBits.RefineParent.ParentSymbolLength > 0) {
|
||
|
|
if (PtrCoding->SegmentFull == TRUE || PtrCoding->RateReached == TRUE)
|
||
|
|
return;
|
||
|
|
|
||
|
|
for (i = 0; i < 3; i++) {
|
||
|
|
UCHAR8 temp_x = 0, temp_y = 0;
|
||
|
|
if ((BlockInfo[BlockSeq].RefineBits.RefineParent.ParentRefSymbol & (1 << (2 - i))) > 0) {
|
||
|
|
UCHAR8 code = 0;
|
||
|
|
BitsRead(PtrCoding, &TempWord, 1);
|
||
|
|
code = (UCHAR8)TempWord;
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineParent.ParentSymbolLength--;
|
||
|
|
temp_x = (i >= 1 ? 1 : 0);
|
||
|
|
temp_y = (i != 1 ? 1 : 0);
|
||
|
|
if (code > 0) {
|
||
|
|
if (block[temp_x][temp_y] > 0)
|
||
|
|
block[temp_x][temp_y] += (1 << (BitPlane - 1));
|
||
|
|
else
|
||
|
|
block[temp_x][temp_y] -= (1 << (BitPlane - 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE &&
|
||
|
|
!PtrCoding->DecodingStopLocations.LocationFind) {
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding = BlockSeq;
|
||
|
|
PtrCoding->DecodingStopLocations.X_LocationStopDecoding = temp_x;
|
||
|
|
PtrCoding->DecodingStopLocations.Y_LocationStopDecoding = temp_y;
|
||
|
|
PtrCoding->DecodingStopLocations.LocationFind = TRUE;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineParent.ParentRefSymbol = 0;
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineParent.ParentSymbolLength = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (BlockInfo[BlockSeq].RefineBits.RefineChildren.ChildrenSymbolLength > 0) {
|
||
|
|
if (PtrCoding->SegmentFull == TRUE || PtrCoding->RateReached == TRUE)
|
||
|
|
break;
|
||
|
|
for (k = 0; k < 3; k++) {
|
||
|
|
UCHAR8 counter = 3;
|
||
|
|
UCHAR8 temp_x = (UCHAR8)((k >= 1 ? 1 : 0) * 2);
|
||
|
|
UCHAR8 temp_y = (UCHAR8)((k != 1 ? 1 : 0) * 2);
|
||
|
|
for (i = temp_x; i < temp_x + 2; i++)
|
||
|
|
for (j = temp_y; j < temp_y + 2; j++) {
|
||
|
|
if ((BlockInfo[BlockSeq].RefineBits.RefineChildren.ChildrenRefSymbol &
|
||
|
|
(1 << (8 - k * 4 + counter))) > 0) {
|
||
|
|
UCHAR8 code = 0;
|
||
|
|
BitsRead(PtrCoding, &TempWord, 1);
|
||
|
|
code = (UCHAR8)TempWord;
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineChildren.ChildrenSymbolLength--;
|
||
|
|
if (code > 0) {
|
||
|
|
if (block[i][j] > 0)
|
||
|
|
block[i][j] += (1 << (BitPlane - 1));
|
||
|
|
else
|
||
|
|
block[i][j] -= (1 << (BitPlane - 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
counter--;
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE &&
|
||
|
|
!PtrCoding->DecodingStopLocations.LocationFind) {
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding = BlockSeq;
|
||
|
|
PtrCoding->DecodingStopLocations.X_LocationStopDecoding = i;
|
||
|
|
PtrCoding->DecodingStopLocations.Y_LocationStopDecoding = j;
|
||
|
|
PtrCoding->DecodingStopLocations.LocationFind = TRUE;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineChildren.ChildrenRefSymbol = 0;
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineChildren.ChildrenSymbolLength = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < 3; i++) {
|
||
|
|
if (BlockInfo[BlockSeq].RefineBits.RefineGrandChildren[i].GrandChildrenSymbolLength > 0) {
|
||
|
|
if (PtrCoding->SegmentFull == TRUE || PtrCoding->RateReached == TRUE)
|
||
|
|
break;
|
||
|
|
for (j = 0; j < 4; j++) {
|
||
|
|
UCHAR8 counter = 3;
|
||
|
|
UCHAR8 temp_x = (UCHAR8)((i >= 1 ? 1 : 0) * 4 + (j >= 2 ? 1 : 0) * 2);
|
||
|
|
UCHAR8 temp_y = (UCHAR8)((i != 1 ? 1 : 0) * 4 + (j % 2) * 2);
|
||
|
|
for (k = temp_x; k < temp_x + 2; k++)
|
||
|
|
for (p = temp_y; p < temp_y + 2; p++) {
|
||
|
|
if ((BlockInfo[BlockSeq].RefineBits.RefineGrandChildren[i].GrandChildrenRefSymbol &
|
||
|
|
(1 << (12 - j * 4 + counter))) > 0) {
|
||
|
|
UCHAR8 code = 0;
|
||
|
|
BitsRead(PtrCoding, &TempWord, 1);
|
||
|
|
code = (UCHAR8)TempWord;
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineGrandChildren[i].GrandChildrenSymbolLength--;
|
||
|
|
if (code > 0) {
|
||
|
|
if (block[k][p] > 0)
|
||
|
|
block[k][p] += (1 << (BitPlane - 1));
|
||
|
|
else
|
||
|
|
block[k][p] -= (1 << (BitPlane - 1));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
counter--;
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE &&
|
||
|
|
!PtrCoding->DecodingStopLocations.LocationFind) {
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding = BlockSeq;
|
||
|
|
PtrCoding->DecodingStopLocations.X_LocationStopDecoding = k;
|
||
|
|
PtrCoding->DecodingStopLocations.Y_LocationStopDecoding = p;
|
||
|
|
PtrCoding->DecodingStopLocations.LocationFind = TRUE;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineGrandChildren[i].GrandChildrenRefSymbol = 0;
|
||
|
|
BlockInfo[BlockSeq].RefineBits.RefineGrandChildren[i].GrandChildrenSymbolLength = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE)
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding = BlockSeq;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void RefBitsEn(BitPlaneBits *BlockInfo, StructCodingPara *PtrCoding)
|
||
|
|
{
|
||
|
|
UINT32 i;
|
||
|
|
UCHAR8 j;
|
||
|
|
|
||
|
|
if (PtrCoding->PtrHeader->Header.Part2.StageStop_2Bits < 3 &&
|
||
|
|
(PtrCoding->PtrHeader->Header.Part2.BitPlaneStop_5Bits == PtrCoding->BitPlane - 1 ||
|
||
|
|
PtrCoding->altStrageStop))
|
||
|
|
return;
|
||
|
|
|
||
|
|
for (i = 0; i < PtrCoding->PtrHeader->Header.Part3.S_20Bits; i++) {
|
||
|
|
if (BlockInfo[i].RefineBits.RefineParent.ParentSymbolLength > 0) {
|
||
|
|
BitsOutput(PtrCoding,
|
||
|
|
BlockInfo[i].RefineBits.RefineParent.ParentRefSymbol,
|
||
|
|
BlockInfo[i].RefineBits.RefineParent.ParentSymbolLength);
|
||
|
|
BlockInfo[i].RefineBits.RefineParent.ParentRefSymbol = 0;
|
||
|
|
BlockInfo[i].RefineBits.RefineParent.ParentSymbolLength = 0;
|
||
|
|
}
|
||
|
|
if (BlockInfo[i].RefineBits.RefineChildren.ChildrenSymbolLength > 0) {
|
||
|
|
BitsOutput(PtrCoding,
|
||
|
|
BlockInfo[i].RefineBits.RefineChildren.ChildrenRefSymbol,
|
||
|
|
BlockInfo[i].RefineBits.RefineChildren.ChildrenSymbolLength);
|
||
|
|
BlockInfo[i].RefineBits.RefineChildren.ChildrenRefSymbol = 0;
|
||
|
|
BlockInfo[i].RefineBits.RefineChildren.ChildrenSymbolLength = 0;
|
||
|
|
}
|
||
|
|
for (j = 0; j < 3; j++) {
|
||
|
|
if (BlockInfo[i].RefineBits.RefineGrandChildren[j].GrandChildrenSymbolLength > 0)
|
||
|
|
BitsOutput(PtrCoding,
|
||
|
|
BlockInfo[i].RefineBits.RefineGrandChildren[j].GrandChildrenRefSymbol,
|
||
|
|
BlockInfo[i].RefineBits.RefineGrandChildren[j].GrandChildrenSymbolLength);
|
||
|
|
BlockInfo[i].RefineBits.RefineGrandChildren[j].GrandChildrenRefSymbol = 0;
|
||
|
|
BlockInfo[i].RefineBits.RefineGrandChildren[j].GrandChildrenSymbolLength = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void StagesEnCoding(StructCodingPara *PtrCoding, BitPlaneBits *BlockInfo)
|
||
|
|
{
|
||
|
|
UCHAR8 BlocksInLastGaggle = 0;
|
||
|
|
DWORD32 TotalGaggles;
|
||
|
|
DWORD32 GaggleIndex = 0;
|
||
|
|
UCHAR8 **CodeOptionsAllGaggles;
|
||
|
|
UCHAR8 BlocksInGaggle = 0;
|
||
|
|
UINT32 BlockStartIndex = 0;
|
||
|
|
BOOL **OptionHitFlag;
|
||
|
|
UINT32 SymbolIndex;
|
||
|
|
|
||
|
|
BlocksInLastGaggle = (UCHAR8)(PtrCoding->PtrHeader->Header.Part3.S_20Bits % GAGGLE_SIZE);
|
||
|
|
TotalGaggles = PtrCoding->PtrHeader->Header.Part3.S_20Bits / GAGGLE_SIZE;
|
||
|
|
if (BlocksInLastGaggle != 0) TotalGaggles++;
|
||
|
|
|
||
|
|
CodeOptionsAllGaggles = (UCHAR8 **)calloc(TotalGaggles, sizeof(UCHAR8 *));
|
||
|
|
OptionHitFlag = (BOOL **) calloc(TotalGaggles, sizeof(BOOL *));
|
||
|
|
if (!CodeOptionsAllGaggles || !OptionHitFlag) {
|
||
|
|
free(CodeOptionsAllGaggles);
|
||
|
|
free(OptionHitFlag);
|
||
|
|
ErrorMsg(BPE_MEM_ERROR);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
BlockStartIndex = GaggleIndex * GAGGLE_SIZE;
|
||
|
|
CodeOptionsAllGaggles[GaggleIndex] = (UCHAR8 *)calloc(3, sizeof(UCHAR8));
|
||
|
|
OptionHitFlag[GaggleIndex] = (BOOL *) calloc(3, sizeof(BOOL));
|
||
|
|
if (!CodeOptionsAllGaggles[GaggleIndex] || !OptionHitFlag[GaggleIndex])
|
||
|
|
goto en_cleanup;
|
||
|
|
OptionHitFlag[GaggleIndex][0] = FALSE;
|
||
|
|
OptionHitFlag[GaggleIndex][1] = FALSE;
|
||
|
|
OptionHitFlag[GaggleIndex][2] = FALSE;
|
||
|
|
BlocksInGaggle = (UCHAR8)((BlockStartIndex + GAGGLE_SIZE <
|
||
|
|
PtrCoding->PtrHeader->Header.Part3.S_20Bits)
|
||
|
|
? GAGGLE_SIZE
|
||
|
|
: (PtrCoding->PtrHeader->Header.Part3.S_20Bits - BlockStartIndex));
|
||
|
|
CodingOptions(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex]);
|
||
|
|
StagesEnCodingGaggles1(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex],
|
||
|
|
OptionHitFlag[GaggleIndex]);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
BlockStartIndex = GaggleIndex * GAGGLE_SIZE;
|
||
|
|
BlocksInGaggle = (UCHAR8)((BlockStartIndex + GAGGLE_SIZE <
|
||
|
|
PtrCoding->PtrHeader->Header.Part3.S_20Bits)
|
||
|
|
? GAGGLE_SIZE
|
||
|
|
: (PtrCoding->PtrHeader->Header.Part3.S_20Bits - BlockStartIndex));
|
||
|
|
StagesEnCodingGaggles2(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex],
|
||
|
|
OptionHitFlag[GaggleIndex]);
|
||
|
|
}
|
||
|
|
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
BlockStartIndex = GaggleIndex * GAGGLE_SIZE;
|
||
|
|
BlocksInGaggle = (UCHAR8)((BlockStartIndex + GAGGLE_SIZE <
|
||
|
|
PtrCoding->PtrHeader->Header.Part3.S_20Bits)
|
||
|
|
? GAGGLE_SIZE
|
||
|
|
: (PtrCoding->PtrHeader->Header.Part3.S_20Bits - BlockStartIndex));
|
||
|
|
StagesEnCodingGaggles3(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex],
|
||
|
|
OptionHitFlag[GaggleIndex]);
|
||
|
|
}
|
||
|
|
|
||
|
|
RefBitsEn(BlockInfo, PtrCoding);
|
||
|
|
|
||
|
|
for (BlockStartIndex = 0;
|
||
|
|
BlockStartIndex < PtrCoding->PtrHeader->Header.Part3.S_20Bits;
|
||
|
|
BlockStartIndex++) {
|
||
|
|
int j;
|
||
|
|
for (SymbolIndex = 0; SymbolIndex < MAX_SYMBOLS_IN_BLOCK; SymbolIndex++)
|
||
|
|
BitPlaneSymbolReset(&BlockInfo[BlockStartIndex].SymbolsBlock[SymbolIndex]);
|
||
|
|
BlockInfo[BlockStartIndex].RefineBits.RefineParent.ParentRefSymbol = 0;
|
||
|
|
BlockInfo[BlockStartIndex].RefineBits.RefineParent.ParentSymbolLength = 0;
|
||
|
|
BlockInfo[BlockStartIndex].RefineBits.RefineChildren.ChildrenRefSymbol = 0;
|
||
|
|
BlockInfo[BlockStartIndex].RefineBits.RefineChildren.ChildrenSymbolLength = 0;
|
||
|
|
for (j = 0; j < 3; j++) {
|
||
|
|
BlockInfo[BlockStartIndex].RefineBits.RefineGrandChildren[j].GrandChildrenRefSymbol = 0;
|
||
|
|
BlockInfo[BlockStartIndex].RefineBits.RefineGrandChildren[j].GrandChildrenSymbolLength = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
en_cleanup:
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
free(CodeOptionsAllGaggles[GaggleIndex]);
|
||
|
|
free(OptionHitFlag[GaggleIndex]);
|
||
|
|
}
|
||
|
|
free(CodeOptionsAllGaggles);
|
||
|
|
free(OptionHitFlag);
|
||
|
|
}
|
||
|
|
|
||
|
|
void StagesDeCoding(StructCodingPara *PtrCoding, BitPlaneBits *BlockInfo)
|
||
|
|
{
|
||
|
|
UCHAR8 BlocksInLastGaggle = 0;
|
||
|
|
DWORD32 TotalGaggles;
|
||
|
|
DWORD32 GaggleIndex = 0;
|
||
|
|
UCHAR8 **CodeOptionsAllGaggles;
|
||
|
|
UCHAR8 BlocksInGaggle = 0;
|
||
|
|
UINT32 BlockStartIndex = 0;
|
||
|
|
BOOL **OptionHitFlag;
|
||
|
|
|
||
|
|
BlocksInLastGaggle = (UCHAR8)(PtrCoding->PtrHeader->Header.Part3.S_20Bits % GAGGLE_SIZE);
|
||
|
|
TotalGaggles = PtrCoding->PtrHeader->Header.Part3.S_20Bits / GAGGLE_SIZE;
|
||
|
|
if (BlocksInLastGaggle != 0) TotalGaggles++;
|
||
|
|
|
||
|
|
CodeOptionsAllGaggles = (UCHAR8 **)calloc(TotalGaggles, sizeof(UCHAR8 *));
|
||
|
|
OptionHitFlag = (BOOL **) calloc(TotalGaggles, sizeof(BOOL *));
|
||
|
|
if (!CodeOptionsAllGaggles || !OptionHitFlag) {
|
||
|
|
free(CodeOptionsAllGaggles);
|
||
|
|
free(OptionHitFlag);
|
||
|
|
ErrorMsg(BPE_MEM_ERROR);
|
||
|
|
}
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding = 0;
|
||
|
|
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
BlockStartIndex = GaggleIndex * GAGGLE_SIZE;
|
||
|
|
CodeOptionsAllGaggles[GaggleIndex] = (UCHAR8 *)calloc(3, sizeof(UCHAR8));
|
||
|
|
OptionHitFlag[GaggleIndex] = (BOOL *) calloc(3, sizeof(BOOL));
|
||
|
|
if (!CodeOptionsAllGaggles[GaggleIndex] || !OptionHitFlag[GaggleIndex])
|
||
|
|
goto cleanup;
|
||
|
|
OptionHitFlag[GaggleIndex][0] = FALSE;
|
||
|
|
OptionHitFlag[GaggleIndex][1] = FALSE;
|
||
|
|
OptionHitFlag[GaggleIndex][2] = FALSE;
|
||
|
|
BlocksInGaggle = (UCHAR8)((BlockStartIndex + GAGGLE_SIZE <
|
||
|
|
PtrCoding->PtrHeader->Header.Part3.S_20Bits)
|
||
|
|
? GAGGLE_SIZE
|
||
|
|
: (PtrCoding->PtrHeader->Header.Part3.S_20Bits - BlockStartIndex));
|
||
|
|
StagesDeCodingGaggles1(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex],
|
||
|
|
OptionHitFlag[GaggleIndex]);
|
||
|
|
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE) {
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding += GaggleIndex * 16;
|
||
|
|
PtrCoding->DecodingStopLocations.stoppedstage = 1;
|
||
|
|
goto cleanup;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
BlockStartIndex = GaggleIndex * GAGGLE_SIZE;
|
||
|
|
BlocksInGaggle = (UCHAR8)((BlockStartIndex + GAGGLE_SIZE <
|
||
|
|
PtrCoding->PtrHeader->Header.Part3.S_20Bits)
|
||
|
|
? GAGGLE_SIZE
|
||
|
|
: (PtrCoding->PtrHeader->Header.Part3.S_20Bits - BlockStartIndex));
|
||
|
|
StagesDeCodingGaggles2(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex],
|
||
|
|
OptionHitFlag[GaggleIndex]);
|
||
|
|
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE) {
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding += GaggleIndex * 16;
|
||
|
|
PtrCoding->DecodingStopLocations.stoppedstage = 2;
|
||
|
|
goto cleanup;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (PtrCoding->RateReached == TRUE) {
|
||
|
|
PtrCoding->DecodingStopLocations.stoppedstage = 2;
|
||
|
|
goto cleanup;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
BlockStartIndex = GaggleIndex * GAGGLE_SIZE;
|
||
|
|
BlocksInGaggle = (UCHAR8)((BlockStartIndex + GAGGLE_SIZE <
|
||
|
|
PtrCoding->PtrHeader->Header.Part3.S_20Bits)
|
||
|
|
? GAGGLE_SIZE
|
||
|
|
: (PtrCoding->PtrHeader->Header.Part3.S_20Bits - BlockStartIndex));
|
||
|
|
StagesDeCodingGaggles3(PtrCoding, &BlockInfo[BlockStartIndex],
|
||
|
|
BlocksInGaggle, CodeOptionsAllGaggles[GaggleIndex],
|
||
|
|
OptionHitFlag[GaggleIndex]);
|
||
|
|
|
||
|
|
if ((PtrCoding->DecodingStopLocations.BitPlaneStopDecoding != -1) &&
|
||
|
|
PtrCoding->RateReached == TRUE) {
|
||
|
|
PtrCoding->DecodingStopLocations.BlockNoStopDecoding += GaggleIndex * 16;
|
||
|
|
PtrCoding->DecodingStopLocations.stoppedstage = 3;
|
||
|
|
goto cleanup;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (PtrCoding->RateReached == TRUE) {
|
||
|
|
PtrCoding->DecodingStopLocations.stoppedstage = 3;
|
||
|
|
goto cleanup;
|
||
|
|
}
|
||
|
|
|
||
|
|
RefBitsDe(PtrCoding, BlockInfo);
|
||
|
|
|
||
|
|
if (PtrCoding->RateReached == TRUE)
|
||
|
|
PtrCoding->DecodingStopLocations.stoppedstage = 4;
|
||
|
|
|
||
|
|
cleanup:
|
||
|
|
/* Free the per-gaggle arrays */
|
||
|
|
for (GaggleIndex = 0; GaggleIndex < TotalGaggles; GaggleIndex++) {
|
||
|
|
free(CodeOptionsAllGaggles[GaggleIndex]); /* free(NULL) is safe for unallocated entries */
|
||
|
|
free(OptionHitFlag[GaggleIndex]);
|
||
|
|
}
|
||
|
|
free(CodeOptionsAllGaggles);
|
||
|
|
free(OptionHitFlag);
|
||
|
|
}
|