MODULE JPEG2000Decoder;
IMPORT SYSTEM, KernelLog, Streams, J2KCS := JPEG2000DecoderCS, J2KU := JPEG2000DecoderUtil,
Codecs, Raster, Machine;
CONST
CBLK_BUFSIZE = 5;
ENTROPY_DECODER* = 2;
ROI_DESCALER* = 3;
DEQUANTIZER* = 4;
INVERSE_DWT* = 5;
INVERSE_MCT* = 6;
DATA_LONGINT* = 0;
DATA_REAL* = 1;
JP2SIGN = 6A502020H;
JP2FTYP = 66747970H;
JP2HEAD = 6A703268H;
JP2IHDR = 69686472H;
JP2BPCC = 62706363H;
JP2COLR = 636F6C72H;
JP2PCLR = 70636C72H;
JP2CMAP = 636D6170H;
JP2CDEF = 63646566H;
JP2RESL = 72657320H;
JP2RESC = 72657363H;
JP2RESD = 72657364H;
JP2CCST = 6A703263H;
JP2INPR = 6A703269H;
JP2XMLD = 786D6C20H;
JP2UUID = 75756964H;
JP2UINF = 75696E66H;
JP2ULST = 75637374H;
JP2URLS = 75726C20H;
JP2_FTBRAND = 6A703220H;
ENTROPY_SEG_MARKER = SYSTEM.VAL(LONGINT, 0AH);
MQTABSIZ = 47;
ENTROPY_ZERO_BITS = 8;
ENTROPY_SIGN_BITS = 8;
ENTROPY_SIGHL = SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 1);
ENTROPY_SIGHR = SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 2);
ENTROPY_SIGVU = SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 3);
ENTROPY_SIGVD = SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 4);
SIGN_LUT_MASK = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0FH));
STATE_SEP = 16;
STATE_SIG_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 14));
STATE_VISITED_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 13));
STATE_MAGREF_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 12));
STATE_H_L_SIGN_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 11));
STATE_H_R_SIGN_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 10));
STATE_V_U_SIGN_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 9));
STATE_V_D_SIGN_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 8));
STATE_H_L_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 7));
STATE_H_R_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 6));
STATE_V_U_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 5));
STATE_V_D_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 4));
STATE_D_UL_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 3));
STATE_D_UR_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 2));
STATE_D_DL_R1 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 1));
STATE_D_DR_R1 = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1));
STATE_VECT_MASK_R1 = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0FFH));
SIGN_VECT_MASK_R1 = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0FF0H));
SIGN_VECT_SHIFT_R1 = 4;
STATE_SIG_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_SIG_R1), STATE_SEP));
STATE_VISITED_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_VISITED_R1), STATE_SEP));
STATE_MAGREF_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_MAGREF_R1), STATE_SEP));
STATE_H_L_SIGN_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_H_L_SIGN_R1), STATE_SEP));
STATE_H_R_SIGN_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_H_R_SIGN_R1), STATE_SEP));
STATE_V_U_SIGN_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_V_U_SIGN_R1), STATE_SEP));
STATE_V_D_SIGN_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_V_D_SIGN_R1), STATE_SEP));
STATE_H_L_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_H_L_R1), STATE_SEP));
STATE_H_R_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_H_R_R1), STATE_SEP));
STATE_V_U_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_V_U_R1), STATE_SEP));
STATE_V_D_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_V_D_R1), STATE_SEP));
STATE_D_UL_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_D_UL_R1), STATE_SEP));
STATE_D_UR_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_D_UR_R1), STATE_SEP));
STATE_D_DL_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_D_DL_R1), STATE_SEP));
STATE_D_DR_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_D_DR_R1), STATE_SEP));
STATE_VECT_MASK_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, STATE_VECT_MASK_R1), STATE_SEP));
SIGN_VECT_MASK_R2 = SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, SIGN_VECT_MASK_R1), STATE_SEP));
SIGN_VECT_SHIFT_R2 = 4 + STATE_SEP;
ENTROPY_MR_CTX = 16;
ENTROPY_MR_FIRSTNZ_CTX = 15;
ENTROPY_MR_FIRSTZ_CTX = 14;
ENTROPY_UNICTX = 17;
ENTROPY_RUNCTX = 18;
ENTROPY_ARRAYOFF = 1;
ENTROPY_STRIPE_HEIGHT = 4;
ENTROPY_NUM_PASSES = 3;
ENTROPY_NUM_NON_BYPASS_BP = 4;
ENTROPY_FIRST_BYPASS_IDX = 3 * ENTROPY_NUM_PASSES + 1;
MCT_NONE = 0;
MCT_RCT = 1;
MCT_ICT = 2;
FILTER_5X3_LIFTING* = 0;
FILTER_9X7_LIFTING* = 1;
TYPE
DataBlk = OBJECT
VAR
offset : LONGINT;
scanw : LONGINT;
END DataBlk;
DataBlkInt = OBJECT(DataBlk)
VAR
data : J2KU.LongIntArrayPtr;
END DataBlkInt;
DataBlkReal = OBJECT(DataBlk)
VAR
data : J2KU.RealArrayPtr;
END DataBlkReal;
MQDecoder = OBJECT
VAR
a : LONGINT;
c : LONGINT;
ct : LONGINT;
b : LONGINT;
index : J2KU.LongIntArrayPtr;
initIdx : J2KU.LongIntArrayPtr;
mps : J2KU.LongIntArrayPtr;
initMps : J2KU.LongIntArrayPtr;
br : J2KU.ByteArrayReader;
markerFound : BOOLEAN;
PROCEDURE &InitNew *(initIdx, initMps : J2KU.LongIntArrayPtr);
BEGIN
br := NIL;
ReInit(initIdx, initMps);
END InitNew;
PROCEDURE ReInit (initIdx, initMps : J2KU.LongIntArrayPtr);
BEGIN
ASSERT(LEN(initMps^) = LEN(initIdx^));
SELF.initIdx := initIdx;
SELF.initMps := initMps;
NEW(index, LEN(initIdx^));
NEW(mps, LEN(initMps^));
IF br = NIL THEN
NEW(br, NIL, -1, 0);
ELSE
br.ReInit(NIL, -1, 0);
END;
END ReInit;
PROCEDURE NextSegment (data : J2KU.ByteArrayPtr; offset, len : LONGINT);
BEGIN
br.SetArray(data, offset, len);
InitDec();
END NextSegment;
PROCEDURE GetByteReader () : J2KU.ByteArrayReader;
BEGIN
RETURN br;
END GetByteReader;
PROCEDURE ResetContexts;
BEGIN
SYSTEM.MOVE(SYSTEM.ADR(initIdx[0]), SYSTEM.ADR(index[0]), LEN(initIdx)*SYSTEM.SIZEOF(LONGINT));
SYSTEM.MOVE(SYSTEM.ADR(initMps[0]), SYSTEM.ADR(mps[0]), LEN(initMps)*SYSTEM.SIZEOF(LONGINT));
END ResetContexts;
PROCEDURE Decode (cx : LONGINT) : LONGINT;
VAR
chigh, d : LONGINT;
BEGIN
chigh := SYSTEM.LSH(c, -16);
a := a - MQPROB[index[cx]];
IF chigh < a THEN
IF (SYSTEM.VAL(SET, a) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 00008000H))) = {} THEN
d := MpsExchange(cx);
Renormd();
ELSE
d := mps[cx];
END;
ELSE
chigh := chigh - a;
c := SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, c) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000FFFFH))) + SYSTEM.VAL(SET, SYSTEM.LSH(chigh, 16)));
d := LpsExchange(cx);
Renormd();
END;
RETURN d;
END Decode;
PROCEDURE Renormd;
BEGIN
REPEAT
IF ct = 0 THEN
ByteIn();
END;
a := SYSTEM.LSH(a, 1);
c := SYSTEM.LSH(c, 1);
DEC(ct);
UNTIL (SYSTEM.VAL(SET, a) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 00008000H))) # {};
END Renormd;
PROCEDURE LpsExchange (cx : LONGINT) : LONGINT;
VAR
d : LONGINT;
BEGIN
IF a < MQPROB[index[cx]] THEN
a := MQPROB[index[cx]];
d := mps[cx];
index[cx] := MQNMPS[index[cx]];
ELSE
a := MQPROB[index[cx]];
d := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
IF MQSWITCH[index[cx]] = 1 THEN
mps[cx] := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
END;
index[cx] := MQNLPS[index[cx]];
END;
RETURN d;
END LpsExchange;
PROCEDURE MpsExchange (cx : LONGINT) : LONGINT;
VAR
d : LONGINT;
BEGIN
IF a < MQPROB[index[cx]] THEN
d := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
IF MQSWITCH[index[cx]] = 1 THEN
mps[cx] := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
END;
index[cx] := MQNLPS[index[cx]];
ELSE
d := mps[cx];
index[cx] := MQNMPS[index[cx]];
END;
RETURN d;
END MpsExchange;
PROCEDURE ByteIn;
BEGIN
IF ~markerFound THEN
IF b = 255 THEN
b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7});
IF b > 8FH THEN
markerFound := TRUE;
ct := 8;
ELSE
c := c + SYSTEM.VAL(LONGINT, 0FE00H) - SYSTEM.LSH(b, 9);
ct := 7;
END;
ELSE
b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7});
c := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, c) + ({8..15} / SYSTEM.VAL(SET, SYSTEM.LSH(b, 8))));
ct := 8;
END;
ELSE
ct := 8;
END;
END ByteIn;
PROCEDURE InitDec;
BEGIN
markerFound := FALSE;
b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7});
c := SYSTEM.LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, b) / {0..7}), 16);
ByteIn();
c := SYSTEM.LSH(c, 7);
ct := ct - 7;
a := SYSTEM.VAL(LONGINT, 00008000H);
END InitDec;
PROCEDURE CheckPredTerm () : BOOLEAN;
VAR
k : LONGINT;
q : LONGINT;
BEGIN
IF (b # 255) & ~markerFound THEN
RETURN FALSE;
END;
IF (ct # 0) & ~markerFound THEN
RETURN FALSE;
END;
IF ct = 1 THEN
RETURN TRUE;
END;
IF ct = 0 THEN
IF ~markerFound THEN
b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7});
IF b <= 8FH THEN
RETURN FALSE;
END;
END;
ct := 8;
END;
k := ct - 1;
q := SYSTEM.LSH(8000H, -k);
DEC(a, q);
IF SYSTEM.LSH(c, -16) < a THEN
RETURN FALSE;
END;
c := c - SYSTEM.LSH(a, 16);
a := q;
Renormd();
RETURN TRUE;
END CheckPredTerm;
END MQDecoder;
EntropyDecoder = OBJECT
VAR
cr : J2KCS.CodestreamReader;
decSpec : J2KCS.DecoderSpecs;
state : J2KU.SetArrayPtr;
mq : MQDecoder;
dbr : J2KU.DataBitReader;
predTerm, resetCtx, vertCausal, segUsed : BOOLEAN;
concealError : BOOLEAN;
PROCEDURE &InitNew *(edOpt : J2KU.EntropyDecoderOptions;
cr : J2KCS.CodestreamReader;
decSpec : J2KCS.DecoderSpecs);
BEGIN
mq := NIL;
dbr := NIL;
ReInit(edOpt, cr, decSpec);
END InitNew;
PROCEDURE ReInit ( edOpt : J2KU.EntropyDecoderOptions;
cr : J2KCS.CodestreamReader;
decSpec : J2KCS.DecoderSpecs);
BEGIN
concealError := edOpt.concealError;
SELF.cr := cr;
SELF.decSpec := decSpec;
IF mq = NIL THEN
NEW(mq, MQ_INITSTATES, MQ_INITMPS);
ELSE
mq.ReInit(MQ_INITSTATES, MQ_INITMPS);
END;
IF dbr = NIL THEN
NEW(dbr, mq.GetByteReader());
ELSE
dbr.ReInit(mq.GetByteReader());
END;
state := NIL;
END ReInit;
PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
BEGIN
cr.SetMaxLayerRange(maxStartLayer, maxEndLayer);
END SetMaxLayerRange;
PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
BEGIN
cr.SetLayerRange(startLayer, endLayer);
END SetLayerRange;
PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
BEGIN
cr.GetLayerRange(startLayer, endLayer);
END GetLayerRange;
PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
BEGIN
cr.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
END SetMaxDecLevelRange;
PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
BEGIN
cr.SetDecLevelRange(startDecLvl, endDecLvl);
END SetDecLevelRange;
PROCEDURE GetDecLevelRange (VAR startDecLvl, endDecLvl : LONGINT);
BEGIN
cr.GetDecLevelRange(startDecLvl, endDecLvl);
END GetDecLevelRange;
PROCEDURE SetReBuildMode;
BEGIN
cr.SetReBuildMode();
END SetReBuildMode;
PROCEDURE GetCodeBlocks (VAR cblk : ARRAY OF DataBlk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo; ncblks : LONGINT) : LONGINT;
VAR
cblkIdx, ncblksRet : LONGINT;
codedCblk : ARRAY CBLK_BUFSIZE OF J2KU.CodedCblk;
curDataBlk : DataBlkInt;
curCblkInfo : J2KU.CblkInfo;
passes, curBp, lastNonBypassBp, segIdx, tile, comp : LONGINT;
zeroLUT, data : J2KU.LongIntArrayPtr;
bypass, term, cleanupTerm : BOOLEAN;
ok : BOOLEAN;
BEGIN
ASSERT(ncblks <= CBLK_BUFSIZE);
ncblksRet := cr.GetCodeBlocks(codedCblk, cblkInfo, ncblks);
tile := cr.CurrentTile();
FOR cblkIdx := 0 TO ncblksRet - 1 DO
curDataBlk := cblk[cblkIdx](DataBlkInt);
curCblkInfo := cblkInfo[cblkIdx];
curBp := curCblkInfo.curbp;
passes := codedCblk[cblkIdx].cpasses;
data := curDataBlk.data;
IF (data = NIL)
OR (curDataBlk.scanw < curCblkInfo.width)
OR (LEN(data^) < (curDataBlk.scanw*curCblkInfo.height + curDataBlk.offset))
THEN
NEW(data, curCblkInfo.width*curCblkInfo.height);
curDataBlk.data := data;
curDataBlk.offset := 0;
curDataBlk.scanw := curCblkInfo.width;
END;
Machine.Fill32(SYSTEM.ADR(data[0]), LEN(data^)*SYSTEM.SIZEOF(LONGINT), 0);
Machine.Fill32(SYSTEM.ADR(state[0]), LEN(state^)*SYSTEM.SIZEOF(SET), 0);
IF codedCblk[cblkIdx].nseg > 1 THEN
mq.NextSegment(codedCblk[cblkIdx].data, 0, codedCblk[cblkIdx].segLen[0]);
ELSE
mq.NextSegment(codedCblk[cblkIdx].data, 0, codedCblk[cblkIdx].dataLen);
END;
mq.ResetContexts();
segIdx := 1;
CASE curCblkInfo.subbinfo.type OF
J2KU.SUB_LL:
zeroLUT := ENTROPY_ZEROLL_LUT;
| J2KU.SUB_HL:
zeroLUT := ENTROPY_ZEROHL_LUT;
| J2KU.SUB_LH:
zeroLUT := ENTROPY_ZEROLL_LUT;
| J2KU.SUB_HH:
zeroLUT := ENTROPY_ZEROHH_LUT;
END;
comp := curCblkInfo.subbinfo.component;
bypass := decSpec.BypassCoding(tile, comp);
term := decSpec.RegularTermination(tile, comp);
predTerm := decSpec.PredictableTermination(tile, comp);
resetCtx := decSpec.ResetContexts(tile, comp);
segUsed := decSpec.SegmentationSymbols(tile, comp);
vertCausal := decSpec.VerticallyCausalContext(tile, comp);
IF bypass THEN
lastNonBypassBp := J2KU.LONGINT_BITS - 1 - ENTROPY_NUM_NON_BYPASS_BP - curCblkInfo.zerobp;
END;
cleanupTerm := term;
ok := TRUE;
IF (passes > 0) & (curBp >= 0) THEN
ok := CleanupPass(curDataBlk, curCblkInfo, curBp, zeroLUT, cleanupTerm);
DEC(passes);
IF ok OR ~concealError THEN
DEC(curBp);
END;
END;
IF ok OR ~concealError THEN
LOOP
IF (passes <= 0) OR (curBp < 0) THEN EXIT; END;
IF bypass & (curBp < lastNonBypassBp) THEN
dbr.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
INC(segIdx);
ok := RawSigPropPass(curDataBlk, curCblkInfo, curBp, term);
DEC(passes);
IF (passes <= 0) OR (~ok & concealError) THEN EXIT; END;
IF term THEN
dbr.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
INC(segIdx);
END;
ok := RawMagRefPass(curDataBlk, curCblkInfo, curBp, TRUE);
ELSE
IF term THEN
mq.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
INC(segIdx);
END;
ok := SigPropPass(curDataBlk, curCblkInfo, curBp, zeroLUT, term);
DEC(passes);
IF (passes <= 0) OR (~ok & concealError) THEN EXIT; END;
IF term THEN
mq.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
INC(segIdx);
END;
ok := MagRefPass(curDataBlk, curCblkInfo, curBp, term);
END;
DEC(passes);
IF (passes <= 0) OR (~ok & concealError) THEN EXIT; END;
IF term OR (bypass & (curBp < lastNonBypassBp)) THEN
mq.NextSegment(NIL, - 1, codedCblk[cblkIdx].segLen[segIdx]);
INC(segIdx);
END;
IF bypass & (curBp = lastNonBypassBp) THEN
cleanupTerm := TRUE;
END;
ok := CleanupPass(curDataBlk, curCblkInfo, curBp, zeroLUT, cleanupTerm);
DEC(passes);
IF ~ok & concealError THEN EXIT; END;
DEC(curBp);
END;
END;
IF ~ok & concealError THEN
LogConcealMsg(curCblkInfo, curBp);
Conceal(curDataBlk, curCblkInfo, curBp);
END;
END;
RETURN ncblksRet;
END GetCodeBlocks;
PROCEDURE DataAvailable () : BOOLEAN;
BEGIN
RETURN ~cr.EndOfCodestream();
END DataAvailable;
PROCEDURE TilePartAvailable () : BOOLEAN;
BEGIN
RETURN cr.TilePartAvailable();
END TilePartAvailable;
PROCEDURE AllTilePartsRead () : BOOLEAN;
BEGIN
RETURN cr.AllTilePartsRead();
END AllTilePartsRead;
PROCEDURE NextTilePart () : BOOLEAN;
BEGIN
IF ~cr.NextTilePart() THEN
RETURN FALSE;
END;
RETURN InitTile();
END NextTilePart;
PROCEDURE InitTile () : BOOLEAN;
VAR
curTile, maxCblkWidth, maxCblkHeight, maxSize : LONGINT;
BEGIN
IF cr.CurrentTilePart() = 0 THEN
curTile := cr.CurrentTile();
maxCblkWidth := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), decSpec.GetMaxCblkWidthExp(curTile));
maxCblkHeight := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), decSpec.GetMaxCblkHeightExp(curTile));
maxSize := (maxCblkWidth + 2 * ENTROPY_ARRAYOFF) * (((maxCblkHeight + 1 ) DIV 2)+ 2 * ENTROPY_ARRAYOFF);
IF (state = NIL) OR (LEN(state^) < maxSize) THEN
NEW(state, maxSize);
END;
END;
RETURN TRUE;
END InitTile;
PROCEDURE CurrentTile () : LONGINT;
BEGIN
RETURN cr.CurrentTile();
END CurrentTile;
PROCEDURE CurrentTilePart () : LONGINT;
BEGIN
RETURN cr.CurrentTilePart();
END CurrentTilePart;
PROCEDURE GetSubbandInfo (tile, component, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
BEGIN
RETURN cr.GetSubbandInfo(tile, component, reslevel, subband)
END GetSubbandInfo;
PROCEDURE LogConcealMsg (cblkInfo : J2KU.CblkInfo; curBp : LONGINT);
BEGIN
KernelLog.String("WARNING: EntropyDecoder detected error at bit-plane ");
KernelLog.Int(curBp, 0);
KernelLog.String(" in code-block ");
KernelLog.Int(cblkInfo.index, 0);
KernelLog.String(" , subband index ");
KernelLog.Int(cblkInfo.subbinfo.index, 0);
KernelLog.String(", res. level");
KernelLog.Int(cblkInfo.subbinfo.reslevel, 0);
KernelLog.String(", component ");
KernelLog.Int(cblkInfo.subbinfo.component, 0);
KernelLog.String(", tile ");
KernelLog.Int(cr.CurrentTile(), 0);
KernelLog.Ln();
KernelLog.String("Concealing...");
KernelLog.Ln();
END LogConcealMsg;
PROCEDURE SigPropPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; zeroLUT : J2KU.LongIntArrayPtr; term : BOOLEAN) : BOOLEAN;
VAR
i, j : LONGINT;
stripeHeight : LONGINT;
dataIdx, stateIdx : LONGINT;
curState : SET;
rowStartState, rowWidthState, rowStartData : LONGINT;
stateStripeIncr, dataStripeIncr : LONGINT;
ctx : LONGINT;
sign : LONGINT;
setMask : SET;
ok : BOOLEAN;
data : J2KU.LongIntArrayPtr;
scanw : LONGINT;
off_ul, off_ur, off_dl, off_dr : LONGINT;
BEGIN
data := cblk(DataBlkInt).data;
setMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 3), curBp - 1));
rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
scanw := cblk.scanw;
rowStartData := cblk.offset;
stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
off_ul := -rowWidthState - 1;
off_ur := -rowWidthState + 1;
off_dl := rowWidthState - 1;
off_dr := rowWidthState + 1;
i := 0;
WHILE i < cblkInfo.height DO
IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
stripeHeight := cblkInfo.height - i;
ELSE
stripeHeight := ENTROPY_STRIPE_HEIGHT;
END;
FOR j := 0 TO cblkInfo.width - 1 DO
stateIdx := rowStartState + j;
dataIdx := rowStartData + j;
curState := state[stateIdx];
IF (curState * STATE_SIG_R1 = {})
& (curState * STATE_VECT_MASK_R1 # {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
IF ~vertCausal THEN
state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
END;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
IF ~vertCausal THEN
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
END;
state [stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2;
IF ~vertCausal THEN
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2;
END;
state [stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
ELSE
curState := curState + STATE_VISITED_R1;
END;
state[stateIdx] := curState;
END;
INC(dataIdx, scanw);
IF (stripeHeight > 1)
& (curState * STATE_SIG_R2 = {})
& (curState * STATE_VECT_MASK_R2 # {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
ELSE
curState := curState + STATE_VISITED_R2;
END;
state[stateIdx] := curState;
END;
INC(stateIdx, rowWidthState);
INC(dataIdx, scanw);
curState := state[stateIdx];
IF (stripeHeight > 2)
& (curState * STATE_SIG_R1 = {})
& (curState * STATE_VECT_MASK_R1 # {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
state[stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2;
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
ELSE
curState := curState + STATE_VISITED_R1;
END;
state[stateIdx] := curState;
END;
INC(dataIdx, scanw);
IF (stripeHeight > 3)
& (curState * STATE_SIG_R2 = {})
& (curState * STATE_VECT_MASK_R2 # {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
ELSE
curState := curState + STATE_VISITED_R2;
END;
state[stateIdx] := curState;
END;
END;
INC(i, ENTROPY_STRIPE_HEIGHT);
rowStartState := rowStartState + stateStripeIncr;
rowStartData := rowStartData + dataStripeIncr;
END;
IF predTerm & term THEN
ok := mq.CheckPredTerm();
ELSE
ok := TRUE;
END;
IF resetCtx THEN
mq.ResetContexts();
END;
RETURN ok;
END SigPropPass;
PROCEDURE RawSigPropPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; term : BOOLEAN) : BOOLEAN;
VAR
i, j : LONGINT;
stripeHeight : LONGINT;
dataIdx, stateIdx : LONGINT;
curState : SET;
rowStartState, rowWidthState, rowStartData : LONGINT;
stateStripeIncr, dataStripeIncr : LONGINT;
sign : LONGINT;
setMask : SET;
ok : BOOLEAN;
data : J2KU.LongIntArrayPtr;
scanw : LONGINT;
off_ul, off_ur, off_dl, off_dr : LONGINT;
BEGIN
data := cblk(DataBlkInt).data;
setMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 3), curBp - 1));
rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
scanw := cblk.scanw;
rowStartData := cblk.offset;
stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
off_ul := -rowWidthState - 1;
off_ur := -rowWidthState + 1;
off_dl := rowWidthState - 1;
off_dr := rowWidthState + 1;
i := 0;
WHILE i < cblkInfo.height DO
IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
stripeHeight := cblkInfo.height - i;
ELSE
stripeHeight := ENTROPY_STRIPE_HEIGHT;
END;
FOR j := 0 TO cblkInfo.width - 1 DO
stateIdx := rowStartState + j;
dataIdx := rowStartData + j;
curState := state[stateIdx];
IF (curState * STATE_SIG_R1 = {})
& (curState * STATE_VECT_MASK_R1 # {})
THEN
IF dbr.NextBit() = 1 THEN
sign := dbr.NextBit();
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
IF ~vertCausal THEN
state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
END;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
IF ~vertCausal THEN
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
END;
state [stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2;
IF ~vertCausal THEN
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2;
END;
state [stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
ELSE
curState := curState + STATE_VISITED_R1;
END;
state[stateIdx] := curState;
END;
INC(dataIdx, scanw);
IF (stripeHeight > 1)
& (curState * STATE_SIG_R2 = {})
& (curState * STATE_VECT_MASK_R2 # {})
THEN
IF dbr.NextBit() = 1 THEN
sign := dbr.NextBit();
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
ELSE
curState := curState + STATE_VISITED_R2;
END;
state[stateIdx] := curState;
END;
INC(stateIdx, rowWidthState);
INC(dataIdx, scanw);
curState := state[stateIdx];
IF (stripeHeight > 2)
& (curState * STATE_SIG_R1 = {})
& (curState * STATE_VECT_MASK_R1 # {})
THEN
IF dbr.NextBit() = 1 THEN
sign := dbr.NextBit();
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
state[stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
curState := curState
+ STATE_SIG_R1 + STATE_VISITED_R1
+ STATE_V_U_R2;
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
ELSE
curState := curState + STATE_VISITED_R1;
END;
state[stateIdx] := curState;
END;
INC(dataIdx, scanw);
IF (stripeHeight > 3)
& (curState * STATE_SIG_R2 = {})
& (curState * STATE_VECT_MASK_R2 # {})
THEN
IF dbr.NextBit() = 1 THEN
sign := dbr.NextBit();
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
curState := curState
+ STATE_SIG_R2 + STATE_VISITED_R2
+ STATE_V_D_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
ELSE
curState := curState + STATE_VISITED_R2;
END;
state[stateIdx] := curState;
END;
END;
INC(i, ENTROPY_STRIPE_HEIGHT);
rowStartState := rowStartState + stateStripeIncr;
rowStartData := rowStartData + dataStripeIncr;
END;
IF term THEN
ok := dbr.CheckBytePadding();
ELSE
ok := TRUE;
END;
RETURN ok;
END RawSigPropPass;
PROCEDURE MagRefPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; term : BOOLEAN) : BOOLEAN;
VAR
i, j : LONGINT;
stripeHeight : LONGINT;
dataIdx, stateIdx : LONGINT;
curState : SET;
rowStartState, rowWidthState, rowStartData : LONGINT;
stateStripeIncr, dataStripeIncr : LONGINT;
bit : LONGINT;
tmpDataSample : SET;
setMask, resetMask : SET;
ok : BOOLEAN;
data : J2KU.LongIntArrayPtr;
scanw : LONGINT;
off_ul, off_ur, off_dl, off_dr : LONGINT;
BEGIN
data := cblk(DataBlkInt).data;
setMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), curBp - 1));
resetMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, -1), curBp + 1));
rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
scanw := cblk.scanw;
rowStartData := cblk.offset;
stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
off_ul := -rowWidthState - 1;
off_ur := -rowWidthState + 1;
off_dl := rowWidthState - 1;
off_dr := rowWidthState + 1;
i := 0;
WHILE i < cblkInfo.height DO
IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
stripeHeight := cblkInfo.height - i;
ELSE
stripeHeight := ENTROPY_STRIPE_HEIGHT;
END;
FOR j := 0 TO cblkInfo.width - 1 DO
stateIdx := rowStartState + j;
dataIdx := rowStartData + j;
curState := state[stateIdx];
IF ((curState * STATE_SIG_R1) = STATE_SIG_R1)
& ((curState * STATE_VISITED_R1) = {})
THEN
IF (curState * STATE_MAGREF_R1) = STATE_MAGREF_R1 THEN
bit := mq.Decode(ENTROPY_MR_CTX);
ELSE
IF (curState * STATE_VECT_MASK_R1) = {} THEN
bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
ELSE
bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
END;
state[stateIdx] := curState + STATE_MAGREF_R1;
curState := curState + STATE_MAGREF_R1;
END;
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
INC(dataIdx, scanw);
IF (stripeHeight > 1)
& (curState * STATE_SIG_R2 = STATE_SIG_R2)
& (curState * STATE_VISITED_R2 = {})
THEN
IF (curState * STATE_MAGREF_R2) = STATE_MAGREF_R2 THEN
bit := mq.Decode(ENTROPY_MR_CTX);
ELSE
IF curState * STATE_VECT_MASK_R2 = {} THEN
bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
ELSE
bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
END;
state[stateIdx] := curState + STATE_MAGREF_R2;
END;
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
INC(stateIdx, rowWidthState);
INC(dataIdx, scanw);
curState := state[stateIdx];
IF (stripeHeight > 2)
& (curState * STATE_SIG_R1 = STATE_SIG_R1)
& (curState * STATE_VISITED_R1 = {})
THEN
IF (curState * STATE_MAGREF_R1) = STATE_MAGREF_R1 THEN
bit := mq.Decode(ENTROPY_MR_CTX);
ELSE
IF curState * STATE_VECT_MASK_R1 = {} THEN
bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
ELSE
bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
END;
state[stateIdx] := curState + STATE_MAGREF_R1;
curState := curState + STATE_MAGREF_R1;
END;
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
INC(dataIdx, scanw);
IF (stripeHeight > 3)
& (curState * STATE_SIG_R2 = STATE_SIG_R2)
& (curState * STATE_VISITED_R2 = {})
THEN
IF (curState * STATE_MAGREF_R2) = STATE_MAGREF_R2 THEN
bit := mq.Decode(ENTROPY_MR_CTX);
ELSE
IF curState * STATE_VECT_MASK_R2 = {} THEN
bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
ELSE
bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
END;
state[stateIdx] := curState + STATE_MAGREF_R2;
END;
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
END;
INC(i, ENTROPY_STRIPE_HEIGHT);
rowStartState := rowStartState + stateStripeIncr;
rowStartData := rowStartData + dataStripeIncr;
END;
IF predTerm & term THEN
ok := mq.CheckPredTerm();
ELSE
ok := TRUE;
END;
IF resetCtx THEN
mq.ResetContexts();
END;
RETURN ok;
END MagRefPass;
PROCEDURE RawMagRefPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; term : BOOLEAN) : BOOLEAN;
VAR
i, j : LONGINT;
stripeHeight : LONGINT;
dataIdx, stateIdx : LONGINT;
curState : SET;
rowStartState, rowWidthState, rowStartData : LONGINT;
stateStripeIncr, dataStripeIncr : LONGINT;
bit : LONGINT;
tmpDataSample : SET;
setMask, resetMask : SET;
ok : BOOLEAN;
data : J2KU.LongIntArrayPtr;
scanw : LONGINT;
off_ul, off_ur, off_dl, off_dr : LONGINT;
BEGIN
data := cblk(DataBlkInt).data;
setMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), curBp - 1));
resetMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, -1), curBp + 1));
rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
scanw := cblk.scanw;
rowStartData := cblk.offset;
stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
off_ul := -rowWidthState - 1;
off_ur := -rowWidthState + 1;
off_dl := rowWidthState - 1;
off_dr := rowWidthState + 1;
i := 0;
WHILE i < cblkInfo.height DO
IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
stripeHeight := cblkInfo.height - i;
ELSE
stripeHeight := ENTROPY_STRIPE_HEIGHT;
END;
FOR j := 0 TO cblkInfo.width - 1 DO
stateIdx := rowStartState + j;
dataIdx := rowStartData + j;
curState := state[stateIdx];
IF (curState * STATE_SIG_R1 = STATE_SIG_R1)
& (curState * STATE_VISITED_R1 = {})
THEN
bit := dbr.NextBit();
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
INC(dataIdx, scanw);
IF (stripeHeight > 1)
& (curState * STATE_SIG_R2 = STATE_SIG_R2)
& (curState * STATE_VISITED_R2 = {})
THEN
bit := dbr.NextBit();
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
INC(stateIdx, rowWidthState);
INC(dataIdx, scanw);
curState := state[stateIdx];
IF (stripeHeight > 2)
& (curState * STATE_SIG_R1 = STATE_SIG_R1)
& (curState * STATE_VISITED_R1 = {})
THEN
bit := dbr.NextBit();
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
INC(dataIdx, scanw);
IF (stripeHeight > 3)
& (curState * STATE_SIG_R2 = STATE_SIG_R2)
& (curState * STATE_VISITED_R2 = {})
THEN
bit := dbr.NextBit();
tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, SYSTEM.LSH(bit, curBp)) + setMask);
END;
END;
INC(i, ENTROPY_STRIPE_HEIGHT);
rowStartState := rowStartState + stateStripeIncr;
rowStartData := rowStartData + dataStripeIncr;
END;
IF term THEN
ok := dbr.CheckBytePadding();
ELSE
ok := TRUE;
END;
RETURN ok;
END RawMagRefPass;
PROCEDURE CleanupPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; zeroLUT : J2KU.LongIntArrayPtr; term : BOOLEAN) : BOOLEAN;
VAR
sign, symbol : LONGINT;
dataIdx, stateIdx, tmpDataIdx, tmpStateIdx : LONGINT;
stripeStartIdx : LONGINT;
curState, tmpCurState : SET;
rowStartState, rowWidthState, rowStartData : LONGINT;
stateStripeIncr, dataStripeIncr : LONGINT;
stripeHeight : LONGINT;
i, j : LONGINT;
ctx : LONGINT;
setMask : SET;
ok : BOOLEAN;
data : J2KU.LongIntArrayPtr;
scanw : LONGINT;
off_ul, off_ur, off_dl, off_dr : LONGINT;
BEGIN
data := cblk(DataBlkInt).data;
setMask := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 3), curBp - 1));
rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
scanw := cblk.scanw;
rowStartData := cblk.offset;
stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
off_ul := -rowWidthState - 1;
off_ur := -rowWidthState + 1;
off_dl := rowWidthState - 1;
off_dr := rowWidthState + 1;
i := 0;
WHILE i < cblkInfo.height DO
IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
stripeHeight := cblkInfo.height - i;
ELSE
stripeHeight := ENTROPY_STRIPE_HEIGHT;
END;
FOR j := 0 TO cblkInfo.width - 1 DO
stateIdx := rowStartState + j;
dataIdx := rowStartData + j;
curState := state[stateIdx];
IF (stripeHeight = ENTROPY_STRIPE_HEIGHT)
& ((curState = {}) & (state[stateIdx + rowWidthState] = {}))
THEN
IF mq.Decode(ENTROPY_RUNCTX) = 1 THEN
stripeStartIdx := mq.Decode(ENTROPY_UNICTX);
stripeStartIdx := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(stripeStartIdx, 1)) + SYSTEM.VAL(SET, mq.Decode(ENTROPY_UNICTX)));
IF stripeStartIdx > 1 THEN
tmpStateIdx := stateIdx + rowWidthState;
ELSE
tmpStateIdx := stateIdx;
END;
tmpDataIdx := dataIdx + scanw*stripeStartIdx;
tmpCurState := state[tmpStateIdx];
IF ~ODD(stripeStartIdx) THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, tmpCurState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[tmpDataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
IF (stripeStartIdx # 0) OR ~vertCausal THEN
state[tmpStateIdx + off_ul] := state[tmpStateIdx + off_ul] + STATE_D_DR_R2;
state[tmpStateIdx + off_ur] := state[tmpStateIdx + off_ur] + STATE_D_DL_R2;
END;
IF sign # 0 THEN
tmpCurState := tmpCurState
+ STATE_SIG_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
IF (stripeStartIdx # 0) OR ~vertCausal THEN
state [tmpStateIdx - rowWidthState] := state[tmpStateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
END;
state [tmpStateIdx - 1] := state[tmpStateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state [tmpStateIdx + 1] := state[tmpStateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
tmpCurState := tmpCurState
+ STATE_SIG_R1
+ STATE_V_U_R2;
IF (stripeStartIdx # 0) OR ~vertCausal THEN
state [tmpStateIdx - rowWidthState] := state[tmpStateIdx - rowWidthState]
+ STATE_V_D_R2;
END;
state [tmpStateIdx - 1] := state[tmpStateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state [tmpStateIdx + 1] := state[tmpStateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
ELSE
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, tmpCurState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[tmpDataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[tmpStateIdx + off_dl] := state[tmpStateIdx + off_dl] + STATE_D_UR_R1;
state[tmpStateIdx + off_dr] := state[tmpStateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
tmpCurState := tmpCurState
+ STATE_SIG_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[tmpStateIdx + rowWidthState] := state[tmpStateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[tmpStateIdx - 1] := state[tmpStateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[tmpStateIdx + 1] := state[tmpStateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
tmpCurState := tmpCurState
+ STATE_SIG_R2
+ STATE_V_D_R1;
state[tmpStateIdx + rowWidthState] := state[tmpStateIdx + rowWidthState]
+ STATE_V_U_R1;
state[tmpStateIdx - 1] := state[tmpStateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [tmpStateIdx + 1] := state[tmpStateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
END;
state[tmpStateIdx] := tmpCurState;
ELSE
stripeStartIdx := ENTROPY_STRIPE_HEIGHT;
END;
ELSE
stripeStartIdx := -1;
END;
curState := state[stateIdx];
IF (stripeStartIdx < 0)
& (curState * STATE_SIG_R1 = {})
& (curState * STATE_VISITED_R1 = {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
IF ~vertCausal THEN
state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
END;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
IF ~vertCausal THEN
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
END;
state [stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
curState := curState
+ STATE_SIG_R1
+ STATE_V_U_R2;
IF ~vertCausal THEN
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2;
END;
state [stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
END;
END;
INC(dataIdx, scanw);
IF (stripeStartIdx < 1)
& (stripeHeight > 1)
& (curState * STATE_SIG_R2 = {})
& (curState * STATE_VISITED_R2 = {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
curState := curState
+ STATE_SIG_R2
+ STATE_V_D_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
END;
END;
state[stateIdx] := curState * (-(STATE_VISITED_R1 + STATE_VISITED_R2));
INC(stateIdx, rowWidthState);
INC(dataIdx, scanw);
curState := state[stateIdx];
IF (stripeStartIdx < 2)
& (stripeHeight > 2)
& (curState * STATE_SIG_R1 = {})
& (curState * STATE_VISITED_R1 = {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R1
+ STATE_V_U_R2 + STATE_V_U_SIGN_R2;
state[stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2
+ STATE_V_D_SIGN_R2;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_H_R_SIGN_R1
+ STATE_D_UR_R2;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_H_L_SIGN_R1
+ STATE_D_UL_R2;
ELSE
curState := curState
+ STATE_SIG_R1
+ STATE_V_U_R2;
state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
+ STATE_V_D_R2;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R1
+ STATE_D_UR_R2;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R1
+ STATE_D_UL_R2;
END;
END;
END;
INC(dataIdx, scanw);
IF (stripeStartIdx < 3)
& (stripeHeight > 3)
& (curState * STATE_SIG_R2 = {})
& (curState * STATE_VISITED_R2 = {})
THEN
IF mq.Decode(zeroLUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
ctx := ENTROPY_SIGN_LUT[SYSTEM.LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
sign := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
/ SYSTEM.VAL(SET, SYSTEM.LSH(ctx, -J2KU.LONGINT_BITS + 1))
);
data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
IF sign # 0 THEN
curState := curState
+ STATE_SIG_R2
+ STATE_V_D_R1 + STATE_V_D_SIGN_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1
+ STATE_V_U_SIGN_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_H_R_SIGN_R2
+ STATE_D_DR_R1;
state[stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_H_L_SIGN_R2
+ STATE_D_DL_R1;
ELSE
curState := curState
+ STATE_SIG_R2
+ STATE_V_D_R1;
state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
+ STATE_V_U_R1;
state[stateIdx - 1] := state[stateIdx - 1]
+ STATE_H_R_R2
+ STATE_D_DR_R1;
state [stateIdx + 1] := state[stateIdx + 1]
+ STATE_H_L_R2
+ STATE_D_DL_R1;
END;
state[stateIdx] := curState;
END;
END;
state[stateIdx] := curState * (-(STATE_VISITED_R1 + STATE_VISITED_R2));
END;
INC(i, ENTROPY_STRIPE_HEIGHT);
rowStartState := rowStartState + stateStripeIncr;
rowStartData := rowStartData + dataStripeIncr;
END;
IF segUsed THEN
symbol := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, SYSTEM.LSH(mq.Decode(ENTROPY_UNICTX), 3))
+ SYSTEM.VAL(SET, SYSTEM.LSH(mq.Decode(ENTROPY_UNICTX), 2))
+ SYSTEM.VAL(SET, SYSTEM.LSH(mq.Decode(ENTROPY_UNICTX), 1))
+ SYSTEM.VAL(SET, mq.Decode(ENTROPY_UNICTX))
);
IF symbol # ENTROPY_SEG_MARKER THEN
RETURN FALSE;
END;
END;
IF predTerm & term THEN
ok := mq.CheckPredTerm();
ELSE
ok := TRUE;
END;
IF resetCtx THEN
mq.ResetContexts();
END;
RETURN ok;
END CleanupPass;
PROCEDURE Conceal (dataBlk : DataBlk; cblkInfo : J2KU.CblkInfo; bp : LONGINT);
VAR
value, setmask, resetmask, mbmask, i, j, rowStart : LONGINT;
data : J2KU.LongIntArrayPtr;
scanw : LONGINT;
BEGIN
data := dataBlk(DataBlkInt).data;
scanw := dataBlk.scanw;
setmask := SYSTEM.LSH(1, bp);
resetmask := SYSTEM.LSH(-1, bp);
mbmask := SYSTEM.VAL(LONGINT, J2KU.LONGINT_SIGN_BIT / SYSTEM.VAL(SET, resetmask));
FOR i := 0 TO cblkInfo.height - 1 DO
rowStart := i*scanw;
FOR j := 0 TO cblkInfo.width - 1 DO
value := data[rowStart + j];
IF SYSTEM.VAL(SET, value) * SYSTEM.VAL(SET, mbmask) # {} THEN
data[rowStart + j] := SYSTEM.VAL(LONGINT,
(SYSTEM.VAL(SET, value)
* SYSTEM.VAL(SET, resetmask))
+ SYSTEM.VAL(SET, setmask)
);
ELSE
data[rowStart + j] := 0;
END;
END;
END;
END Conceal;
PROCEDURE FreeNonRebuildResources;
BEGIN
cr.FreeNonRebuildResources();
END FreeNonRebuildResources;
PROCEDURE FreeResources;
BEGIN
state := NIL;
mq := NIL;
dbr := NIL;
cr.FreeResources();
END FreeResources;
END EntropyDecoder;
ROIDescaler = OBJECT
VAR
decSpec : J2KCS.DecoderSpecs;
ed : EntropyDecoder;
noROI : BOOLEAN;
PROCEDURE &InitNew *(roiOpt : J2KU.ROIDescalerOptions;
ed : EntropyDecoder;
decSpec : J2KCS.DecoderSpecs);
BEGIN
ReInit(roiOpt, ed, decSpec);
END InitNew;
PROCEDURE ReInit ( roiOpt : J2KU.ROIDescalerOptions;
ed : EntropyDecoder;
decSpec : J2KCS.DecoderSpecs);
BEGIN
SELF.noROI := roiOpt.noROI;
SELF.decSpec := decSpec;
SELF.ed := ed;
END ReInit;
PROCEDURE GetCodeBlocks (VAR cblk : ARRAY OF DataBlk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo; ncblks : LONGINT) : LONGINT;
VAR
cblkIdx, ncblksRet : LONGINT;
data : J2KU.LongIntArrayPtr;
curTile, comp, magBits, idx, i, j : LONGINT;
mask1, mask2, mask3 : SET;
approx : SET;
tmp : SET;
shift : LONGINT;
width, height, scanw : LONGINT;
BEGIN
ncblksRet := ed.GetCodeBlocks(cblk, cblkInfo, ncblks);
curTile := ed.CurrentTile();
FOR cblkIdx := 0 TO ncblksRet - 1 DO
comp := cblkInfo[cblkIdx].subbinfo.component;
IF ~noROI & decSpec.ROIUsed(curTile, comp) THEN
data := cblk[cblkIdx](DataBlkInt).data;
idx := cblk[cblkIdx].offset;
scanw := cblk[cblkIdx].scanw;
width := cblkInfo[cblkIdx].width;
height := cblkInfo[cblkIdx].height;
shift := decSpec.GetROIShift(curTile, comp);
magBits := cblkInfo[cblkIdx].subbinfo.magbits;
mask3 := SYSTEM.VAL(SET, SYSTEM.LSH(J2KU.SWAP_MASK, (J2KU.LONGINT_BITS - 1)- magBits));
mask2 := -mask3;
mask1 := mask3 * (-J2KU.LONGINT_SIGN_BIT);
approx := SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), (J2KU.LONGINT_BITS - 2) - magBits));
FOR i := 0 TO height - 1 DO
FOR j := 0 TO width - 1 DO
tmp := SYSTEM.VAL(SET, data[idx]);
IF (tmp * mask1) = {} THEN
data[idx] := SYSTEM.VAL(LONGINT,
(tmp * J2KU.LONGINT_SIGN_BIT)
+ SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, tmp), shift)));
ELSIF (tmp * mask2) # {} THEN
data[idx] := SYSTEM.VAL(LONGINT, (tmp * mask3) + approx);
END;
INC(idx);
END;
idx := idx - width + scanw;
END;
END;
END;
RETURN ncblksRet;
END GetCodeBlocks;
PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
BEGIN
ed.SetMaxLayerRange(maxStartLayer, maxEndLayer);
END SetMaxLayerRange;
PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
BEGIN
ed.SetLayerRange(startLayer, endLayer);
END SetLayerRange;
PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
BEGIN
ed.GetLayerRange(startLayer, endLayer);
END GetLayerRange;
PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
BEGIN
ed.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
END SetMaxDecLevelRange;
PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
BEGIN
ed.SetDecLevelRange(startDecLvl, endDecLvl);
END SetDecLevelRange;
PROCEDURE GetDecLevelRange (VAR startDec, endDec : LONGINT);
BEGIN
ed.GetDecLevelRange(startDec, endDec);
END GetDecLevelRange;
PROCEDURE SetReBuildMode;
BEGIN
ed.SetReBuildMode();
END SetReBuildMode;
PROCEDURE CurrentTile () : LONGINT;
BEGIN
RETURN ed.CurrentTile();
END CurrentTile;
PROCEDURE CurrentTilePart () : LONGINT;
BEGIN
RETURN ed.CurrentTilePart();
END CurrentTilePart;
PROCEDURE NextTilePart () : BOOLEAN;
BEGIN
RETURN ed.NextTilePart();
END NextTilePart;
PROCEDURE DataAvailable () : BOOLEAN;
BEGIN
RETURN ed.DataAvailable();
END DataAvailable;
PROCEDURE GetSubbandInfo (tile, component, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
BEGIN
RETURN ed.GetSubbandInfo(tile, component, reslevel, subband)
END GetSubbandInfo;
PROCEDURE TilePartAvailable () : BOOLEAN;
BEGIN
RETURN ed.TilePartAvailable();
END TilePartAvailable;
PROCEDURE AllTilePartsRead () : BOOLEAN;
BEGIN
RETURN ed.AllTilePartsRead();
END AllTilePartsRead;
PROCEDURE FreeNonRebuildResources;
BEGIN
ed.FreeNonRebuildResources();
END FreeNonRebuildResources;
PROCEDURE FreeResources;
BEGIN
ed.FreeResources();
END FreeResources;
END ROIDescaler;
Dequantizer = OBJECT
VAR
roi : ROIDescaler;
dataTypes : POINTER TO ARRAY OF ARRAY OF LONGINT;
decSpec : J2KCS.DecoderSpecs;
tBitDepth : J2KU.LongIntArrayPtr;
preStep : POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF ARRAY 3 OF REAL;
cblkBuf : ARRAY CBLK_BUFSIZE OF DataBlk;
overallMinDecLvl : LONGINT;
PROCEDURE &InitNew *(deqOpt : J2KU.DequantizerOptions;
roi : ROIDescaler;
decSpec : J2KCS.DecoderSpecs);
BEGIN
dataTypes := NIL;
tBitDepth := NIL;
preStep := NIL;
ReInit(deqOpt, roi, decSpec);
END InitNew;
PROCEDURE ReInit (deqOpt : J2KU.DequantizerOptions;
roi : ROIDescaler;
decSpec : J2KCS.DecoderSpecs);
VAR
ntiles, ncomp, i, j : LONGINT;
imgInfo : J2KCS.ImageInfo;
utBitDepth : J2KU.LongIntArrayPtr;
cblkInt : DataBlkInt;
BEGIN
SELF.roi := roi;
SELF.decSpec := decSpec;
imgInfo := decSpec.GetImageInfo();
ntiles := imgInfo.GetNumTiles();
ncomp := imgInfo.GetNumComponents();
NEW(dataTypes, ntiles, ncomp);
FOR j := 0 TO ntiles - 1 DO
Machine.Fill32(SYSTEM.ADR(dataTypes[j][0]), ncomp*SYSTEM.SIZEOF(LONGINT), DATA_LONGINT);
END;
NEW(utBitDepth, ncomp);
FOR i := 0 TO ncomp - 1 DO
utBitDepth[i] := imgInfo.GetBitDepth(i);
END;
tBitDepth := utBitDepth;
FOR i := 0 TO CBLK_BUFSIZE - 1 DO
NEW(cblkInt);
cblkBuf[i] := cblkInt;
END;
preStep := NIL;
overallMinDecLvl := 0;
END ReInit;
PROCEDURE SetDataType (tile, component, type : LONGINT);
BEGIN
dataTypes[tile][component] := type;
END SetDataType;
PROCEDURE DataAvailable () : BOOLEAN;
BEGIN
RETURN roi.DataAvailable();
END DataAvailable;
PROCEDURE CurrentTile () : LONGINT;
BEGIN
RETURN roi.CurrentTile();
END CurrentTile;
PROCEDURE CurrentTilePart () : LONGINT;
BEGIN
RETURN roi.CurrentTilePart();
END CurrentTilePart;
PROCEDURE NextTilePart () : BOOLEAN;
BEGIN
IF ~roi.NextTilePart() THEN
RETURN FALSE;
END;
IF roi.CurrentTilePart() = 0 THEN
CalculateStepSizes(roi.CurrentTile());
END;
RETURN TRUE;
END NextTilePart;
PROCEDURE CalculateStepSizes (tile : LONGINT);
CONST
NORM_FACT = SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), 11);
VAR
ntiles, ncomp, i, ndec, r: LONGINT;
qStyle, exp : LONGINT;
mant : REAL;
imgInfo : J2KCS.ImageInfo;
BEGIN
imgInfo := decSpec.GetImageInfo();
ntiles := imgInfo.GetNumTiles();
ncomp := imgInfo.GetNumComponents();
FOR i := 0 TO ncomp - 1 DO
qStyle := decSpec.GetQuantStyle(tile, i);
CASE qStyle OF
| J2KCS.NOQUANT:
| J2KCS.QUANT_EXP:
IF preStep = NIL THEN
NEW(preStep, ntiles);
END;
IF preStep[tile] = NIL THEN
NEW(preStep[tile], ncomp);
END;
ndec := decSpec.GetNumDecLevels(tile, i);
DEC(ndec, overallMinDecLvl);
NEW(preStep[tile][i], ndec + 1);
exp := decSpec.GetQuantExponent(tile, i, 0, J2KU.SUB_LL);
mant := decSpec.GetQuantMantissa(tile, i, 0, J2KU.SUB_LL);
preStep[tile][i][0][0] := ((1 + (mant / NORM_FACT)) / SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), exp));
FOR r := 1 TO ndec DO
exp := decSpec.GetQuantExponent(tile, i, r, J2KU.SUB_HL);
mant := decSpec.GetQuantMantissa(tile, i, r, J2KU.SUB_HL);
preStep[tile][i][r][0] := ((1 + (mant / NORM_FACT)) / SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), exp));
exp := decSpec.GetQuantExponent(tile, i, r, J2KU.SUB_LH);
mant := decSpec.GetQuantMantissa(tile, i, r, J2KU.SUB_LH);
preStep[tile][i][r][1] := ((1 + (mant / NORM_FACT)) / SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), exp));
exp := decSpec.GetQuantExponent(tile, i, r, J2KU.SUB_HH);
mant := decSpec.GetQuantMantissa(tile, i, r, J2KU.SUB_HH);
preStep[tile][i][r][2] := ((1 + (mant / NORM_FACT)) / SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), exp));
END;
| J2KCS.QUANT_DER:
IF preStep = NIL THEN
NEW(preStep, ntiles);
END;
IF preStep[tile] = NIL THEN
NEW(preStep[tile], ncomp);
END;
NEW(preStep[tile][i], 1);
exp := decSpec.GetQuantExponent(tile, i, 0, J2KU.SUB_LL);
mant := decSpec.GetQuantMantissa(tile, i, 0, J2KU.SUB_LL);
preStep[tile][i][0][0] := ((1 + (mant / NORM_FACT)) / SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), exp));
ELSE
KernelLog.String("ERROR (Dequantizer.CalculateStepSizes) : Unknown quantization style");
KernelLog.Ln();
END;
END;
END CalculateStepSizes;
PROCEDURE GetSubbandInfo (tile, component, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
BEGIN
RETURN roi.GetSubbandInfo(tile, component, reslevel, subband)
END GetSubbandInfo;
PROCEDURE TilePartAvailable () : BOOLEAN;
BEGIN
RETURN roi.TilePartAvailable();
END TilePartAvailable;
PROCEDURE AllTilePartsRead () : BOOLEAN;
BEGIN
RETURN roi.AllTilePartsRead();
END AllTilePartsRead;
PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
BEGIN
roi.SetMaxLayerRange(maxStartLayer, maxEndLayer);
END SetMaxLayerRange;
PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
BEGIN
roi.SetLayerRange(startLayer, endLayer);
END SetLayerRange;
PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
BEGIN
roi.GetLayerRange(startLayer, endLayer);
END GetLayerRange;
PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
BEGIN
overallMinDecLvl := maxEndDecLvl;
roi.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
END SetMaxDecLevelRange;
PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
BEGIN
roi.SetDecLevelRange(startDecLvl, endDecLvl);
END SetDecLevelRange;
PROCEDURE GetDecLevelRange (VAR startDec, endDec : LONGINT);
BEGIN
roi.GetDecLevelRange(startDec, endDec);
END GetDecLevelRange;
PROCEDURE SetReBuildMode;
BEGIN
roi.SetReBuildMode();
END SetReBuildMode;
PROCEDURE GetCodeBlocks (VAR cblk : ARRAY OF DataBlk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo; ncblks : LONGINT) : LONGINT;
VAR
cblkIdx, ncblksRet : LONGINT;
qStyle, cblkSize, width, height, shift, i, j, tmp, gainLog : LONGINT;
curTile, comp, ndec : LONGINT;
step : REAL;
realData : J2KU.RealArrayPtr;
srcData : J2KU.LongIntArrayPtr;
cblkReal : DataBlkReal;
subbInfo : J2KU.SubbandInfo;
dataIdxIn, scanwIn, dataIdxOut, scanwOut : LONGINT;
BEGIN
ASSERT(ncblks <= CBLK_BUFSIZE);
ncblksRet := roi.GetCodeBlocks(cblkBuf, cblkInfo, ncblks);
curTile := roi.CurrentTile();
FOR cblkIdx := 0 TO ncblksRet - 1 DO
subbInfo := cblkInfo[cblkIdx].subbinfo;
comp := subbInfo.component;
qStyle := decSpec.GetQuantStyle(curTile, comp);
cblkSize := cblkInfo[cblkIdx].width*cblkInfo[cblkIdx].height;
width := cblkInfo[cblkIdx].width;
height := cblkInfo[cblkIdx].height;
shift := J2KU.LONGINT_BITS - 1 - subbInfo.magbits;
srcData := cblkBuf[cblkIdx](DataBlkInt).data;
dataIdxIn := cblkBuf[cblkIdx].offset;
scanwIn := cblkBuf[cblkIdx].scanw;
CASE dataTypes[curTile][comp] OF
| DATA_LONGINT :
cblk[cblkIdx] := cblkBuf[cblkIdx];
| DATA_REAL :
NEW(cblkReal);
NEW(realData, cblkSize);
cblkReal.data := realData;
cblkReal.offset := 0;
cblkReal.scanw := width;
cblk[cblkIdx] := cblkReal;
END;
IF qStyle = J2KCS.NOQUANT THEN
CASE dataTypes[curTile][comp] OF
| DATA_LONGINT :
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
IF srcData[dataIdxIn] >= 0 THEN
srcData[dataIdxIn] := SYSTEM.LSH(srcData[dataIdxIn], -shift);
ELSE
srcData[dataIdxIn] := -SYSTEM.LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT), -shift);
END;
INC(dataIdxIn);
END;
dataIdxIn := dataIdxIn - width + scanwIn;
END;
| DATA_REAL :
dataIdxOut := cblk[cblkIdx].offset;
scanwOut := cblk[cblkIdx].scanw;
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
IF srcData[dataIdxIn] >= 0 THEN
realData[dataIdxOut] := SYSTEM.LSH(srcData[dataIdxIn], -shift);
ELSE
realData[dataIdxOut] := -SYSTEM.LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT), -shift);
END;
INC(dataIdxIn);
INC(dataIdxOut);
END;
dataIdxIn := dataIdxIn - width + scanwIn;
dataIdxOut := dataIdxOut - width + scanwOut;
END;
END;
ELSE
CASE subbInfo.type OF
| J2KU.SUB_LL:
gainLog := 0;
| J2KU.SUB_HL:
gainLog := 1;
| J2KU.SUB_LH:
gainLog := 1;
| J2KU.SUB_HH:
gainLog := 2;
END;
IF qStyle = J2KCS.QUANT_DER THEN
ndec := decSpec.GetNumDecLevels(curTile, comp);
step := preStep[curTile][comp][0][0]
* SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tBitDepth[comp] + gainLog + ndec - subbInfo.declevel);
ELSE
step := preStep[curTile][comp][subbInfo.reslevel][subbInfo.index]
* SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tBitDepth[comp] + gainLog);
END;
step := step / SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), shift);
CASE dataTypes[curTile][comp] OF
| DATA_LONGINT :
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
IF srcData[dataIdxIn] < 0 THEN
tmp := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT);
srcData[dataIdxIn] := -ENTIER(tmp * step + 0.5);
ELSE
srcData[dataIdxIn] := ENTIER(srcData[dataIdxIn] * step + 0.5);
END;
INC(dataIdxIn);
END;
dataIdxIn := dataIdxIn - width + scanwIn;
END;
| DATA_REAL :
dataIdxOut := cblk[cblkIdx].offset;
scanwOut := cblk[cblkIdx].scanw;
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
IF srcData[dataIdxIn] < 0 THEN
tmp := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT);
realData[dataIdxOut] := -tmp * step;
ELSE
realData[dataIdxOut] := srcData[dataIdxIn] * step;
END;
INC(dataIdxIn);
INC(dataIdxOut);
END;
dataIdxIn := dataIdxIn - width + scanwIn;
dataIdxOut := dataIdxOut - width + scanwOut;
END;
END;
END;
END;
RETURN ncblksRet;
END GetCodeBlocks;
PROCEDURE FreeNonRebuildResources;
BEGIN
roi.FreeNonRebuildResources();
END FreeNonRebuildResources;
PROCEDURE FreeResources;
VAR
i : LONGINT;
BEGIN
FOR i := 0 TO CBLK_BUFSIZE - 1 DO
cblkBuf[i] := NIL;
END;
dataTypes := NIL;
tBitDepth := NIL;
preStep := NIL;
roi.FreeResources();
END FreeResources;
END Dequantizer;
FilterSynInt = OBJECT
PROCEDURE SynthesizeLPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
END SynthesizeLPF;
PROCEDURE SynthesizeHPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
END SynthesizeHPF;
END FilterSynInt;
FilterSynReal = OBJECT
PROCEDURE SynthesizeLPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
END SynthesizeLPF;
PROCEDURE SynthesizeHPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
END SynthesizeHPF;
END FilterSynReal;
FilterSyn5x3Lifting = OBJECT(FilterSynInt)
PROCEDURE SynthesizeLPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
VAR
iOut, iHigh, iLow, jmpOut, i : LONGINT;
oddLen : BOOLEAN;
BEGIN
iOut := outOffset;
jmpOut := 2*outStep;
iHigh := highOffset;
iLow := lowOffset;
oddLen := ODD(len);
IF len > 1 THEN
outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh] + 1, -1);
ELSE
outData[iOut] := lowCoeffs[iLow];
END;
INC(iOut, jmpOut);
INC(iLow, lowStep);
INC(iHigh, highStep);
FOR i := 2 TO len - 2 BY 2 DO
outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh-highStep] + highCoeffs[iHigh] + 2, -2);
INC(iOut, jmpOut);
INC(iHigh, highStep);
INC(iLow, lowStep);
END;
IF oddLen & (len > 2) THEN
outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh - highStep] + 1, -1);
END;
iOut := outOffset + outStep;
iHigh := highOffset;
FOR i:=1 TO len - 2 BY 2 DO
outData[iOut] := highCoeffs[iHigh] + ASH(outData[iOut - outStep] + outData[iOut + outStep], -1);
INC(iOut, jmpOut);
INC(iHigh, highStep);
END;
IF ~oddLen & (len > 1) THEN
outData[iOut] := highCoeffs[iHigh] + outData[iOut-outStep];
END;
END SynthesizeLPF;
PROCEDURE SynthesizeHPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
VAR
iOut, iHigh, iLow, jmpOut, i : LONGINT;
oddLen : BOOLEAN;
BEGIN
iOut := outOffset + outStep;
jmpOut := 2*outStep;
iHigh := highOffset;
iLow := lowOffset;
oddLen := ODD(len);
FOR i := 1 TO len - 2 BY 2 DO
outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh] + highCoeffs[iHigh+highStep] + 2, -2);
INC(iOut, jmpOut);
INC(iHigh, highStep);
INC(iLow, lowStep);
END;
IF ~oddLen & (len > 1) THEN
outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh] + 1, -1);
END;
iOut := outOffset;
iHigh := highOffset;
IF len > 1 THEN
outData[iOut] := highCoeffs[iHigh] + outData[iOut + outStep];
ELSE
outData[iOut] := ASH(highCoeffs[iHigh], -1);
END;
INC(iOut, jmpOut);
INC(iHigh, highStep);
FOR i := 2 TO len - 2 BY 2 DO
outData[iOut] := highCoeffs[iHigh] + ASH(outData[iOut - outStep] + outData[iOut + outStep], -1);
INC(iOut, jmpOut);
INC(iHigh, highStep);
END;
IF oddLen & (len > 1) THEN
outData[iOut] := highCoeffs[iHigh] + outData[iOut - outStep];
END;
END SynthesizeHPF;
END FilterSyn5x3Lifting;
CONST
ALPHA = -1.586134342;
BETA = -0.05298011854;
GAMMA = 0.8829110762;
DELTA = 0.443568522;
KL = 0.8128930655;
KH = 1.230174106;
TYPE
FilterSyn9x7Lifting = OBJECT(FilterSynReal)
PROCEDURE SynthesizeLPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
VAR
iOut, iHigh, iLow, jmpOut, i : LONGINT;
oddLen : BOOLEAN;
BEGIN
iOut := outOffset;
jmpOut := 2*outStep;
iHigh := highOffset;
iLow := lowOffset;
oddLen := ODD(len);
IF len > 1 THEN
outData[iOut] := lowCoeffs[iLow]/KL - 2*DELTA*highCoeffs[iHigh]/KH;
ELSE
outData[iOut] := lowCoeffs[iLow];
END;
INC(iOut, jmpOut);
INC(iHigh, highStep);
INC(iLow, lowStep);
FOR i := 2 TO len - 2 BY 2 DO
outData[iOut] := lowCoeffs[iLow]/KL - DELTA*(highCoeffs[iHigh - highStep] + highCoeffs[iHigh])/KH;
INC(iOut, jmpOut);
INC(iHigh, highStep);
INC(iLow, lowStep);
END;
IF oddLen & (len > 2) THEN
outData[iOut] := lowCoeffs[iLow]/KL - 2*DELTA*(highCoeffs[iHigh - highStep])/KH;
END;
iOut := outOffset + outStep;
iHigh := highOffset;
FOR i := 1 TO len - 2 BY 2 DO
outData[iOut] := highCoeffs[iHigh]/KH - GAMMA*(outData[iOut - outStep] + outData[iOut + outStep]);
INC(iOut, jmpOut);
INC(iHigh, highStep);
END;
IF ~oddLen & (len > 1) THEN
outData[iOut] := highCoeffs[iHigh]/KH - 2*GAMMA*(outData[iOut - outStep]);
END;
iOut := outOffset;
IF len > 1 THEN
outData[iOut] := outData[iOut] - 2*BETA*(outData[iOut + outStep]);
END;
INC(iOut, jmpOut);
FOR i := 2 TO len - 2 BY 2 DO
outData[iOut] := outData[iOut] - BETA*(outData[iOut - outStep] + outData[iOut + outStep]);
INC(iOut, jmpOut);
END;
IF oddLen & (len > 2) THEN
outData[iOut] := outData[iOut] - 2*BETA*outData[iOut - outStep];
END;
iOut := outOffset + outStep;
FOR i := 1 TO len - 2 BY 2 DO
outData[iOut] := outData[iOut] - ALPHA*(outData[iOut - outStep] + outData[iOut + outStep]);
INC(iOut, jmpOut);
END;
IF ~oddLen & (len > 1) THEN
outData[iOut] := outData[iOut] - 2*ALPHA*outData[iOut - outStep];
END;
END SynthesizeLPF;
PROCEDURE SynthesizeHPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
VAR
iOut, iHigh, iLow, jmpOut, i : LONGINT;
oddLen : BOOLEAN;
BEGIN
iOut := outOffset + outStep;
jmpOut := 2*outStep;
iHigh := highOffset;
iLow := lowOffset;
oddLen := ODD(len);
FOR i := 1 TO len - 2 BY 2 DO
outData[iOut] := lowCoeffs[iLow]/KL - DELTA*(highCoeffs[iHigh]/KH + highCoeffs[iHigh + highStep]/KH);
INC(iOut, jmpOut);
INC(iHigh, highStep);
INC(iLow, lowStep);
END;
IF ~oddLen & (len > 1) THEN
outData[iOut] := lowCoeffs[iLow]/KL - 2*DELTA*(highCoeffs[iHigh]/KH);
END;
iOut := outOffset;
iHigh := highOffset;
IF len > 1 THEN
outData[iOut] := highCoeffs[iHigh]/KH - 2*GAMMA*outData[iOut + outStep];
ELSE
outData[iOut] := highCoeffs[iHigh] / 2;
END;
INC(iOut, jmpOut);
INC(iHigh, highStep);
FOR i := 2 TO len - 2 BY 2 DO
outData[iOut] := highCoeffs[iHigh]/KH - GAMMA*(outData[iOut - outStep] + outData[iOut + outStep]);
INC(iOut, jmpOut);
INC(iHigh, highStep);
END;
IF oddLen & (len > 2) THEN
outData[iOut] := highCoeffs[iHigh]/KH - 2*GAMMA*outData[iOut - outStep];
END;
iOut := outOffset + outStep;
FOR i := 1 TO len - 2 BY 2 DO
outData[iOut] := outData[iOut] - BETA*(outData[iOut - outStep] + outData[iOut + outStep]);
INC(iOut, jmpOut);
END;
IF ~oddLen & (len > 1) THEN
outData[iOut] := outData[iOut] - 2*BETA*outData[iOut - outStep];
END;
iOut := outOffset;
IF len > 1 THEN
outData[iOut] := outData[iOut] - 2*ALPHA*outData[iOut + outStep];
END;
INC(iOut, jmpOut);
FOR i := 2 TO len - 2 BY 2 DO
outData[iOut] := outData[iOut] - ALPHA*(outData[iOut - outStep] + outData[iOut + outStep]);
INC(iOut, jmpOut);
END;
IF oddLen & (len > 2) THEN
outData[iOut] := outData[iOut] - 2*ALPHA*outData[iOut - outStep];
END;
END SynthesizeHPF;
END FilterSyn9x7Lifting;
InverseDWT = OBJECT
VAR
deq : Dequantizer;
curTile : LONGINT;
ncomp : LONGINT;
minDecLvl, maxDecLvl, minLayer, maxLayer : LONGINT;
reconstructedComps : POINTER TO ARRAY OF ARRAY OF DataBlk;
reconstructedCompsInfo : POINTER TO ARRAY OF ARRAY OF J2KU.BlkInfo;
reconstructedRange : POINTER TO ARRAY OF ARRAY 4 OF LONGINT;
filterIrrev : FilterSynReal;
filterRev : FilterSynInt;
decSpec : J2KCS.DecoderSpecs;
gotoReBuild : BOOLEAN;
overallMinDecLvl : LONGINT;
PROCEDURE &InitNew *( invDWTOpt : J2KU.InverseDWTOptions;
deq : Dequantizer;
decSpec : J2KCS.DecoderSpecs);
BEGIN
ReInit(invDWTOpt, deq, decSpec);
END InitNew;
PROCEDURE ReInit ( invDWTOpt : J2KU.InverseDWTOptions;
deq : Dequantizer;
decSpec : J2KCS.DecoderSpecs);
VAR
ntiles : LONGINT;
imgInfo : J2KCS.ImageInfo;
BEGIN
imgInfo := decSpec.GetImageInfo();
ncomp := imgInfo.GetNumComponents();
ntiles := imgInfo.GetNumTiles();
SELF.deq := deq;
SELF.decSpec := decSpec;
minDecLvl := 0;
maxDecLvl := MAX(LONGINT);
minLayer := 0;
maxLayer := MAX(LONGINT);
overallMinDecLvl := 0;
NEW(reconstructedComps, ntiles, ncomp);
NEW(reconstructedCompsInfo, ntiles, ncomp);
NEW(reconstructedRange, ntiles);
CASE invDWTOpt.filterRev OF
| FILTER_5X3_LIFTING :
filterRev := filter5x3Lift;
ELSE
KernelLog.String("ERROR (InverseDWT.ReInit): Invalid reversible filter type specified");
KernelLog.Ln();
END;
CASE invDWTOpt.filterIrrev OF
| FILTER_9X7_LIFTING :
filterIrrev := filter9x7Lift;
ELSE
KernelLog.String("ERROR (InverseDWT.ReInit): Invalid irreversible filter type specified");
KernelLog.Ln();
END;
gotoReBuild := FALSE;
END ReInit;
PROCEDURE FullTransform () : BOOLEAN;
BEGIN
RETURN TransformStep();
END FullTransform;
PROCEDURE InitReconstructedRange;
VAR
recMinDecLvl, c, ndec : LONGINT;
reslevel, offset, width, height, scanw, h : LONGINT;
subbInfo : J2KU.SubbandInfo;
dataInt : J2KU.LongIntArrayPtr;
dataReal : J2KU.RealArrayPtr;
BEGIN
IF reconstructedRange[curTile][3] < 0 THEN
recMinDecLvl := 0;
ELSE
recMinDecLvl := reconstructedRange[curTile][3];
END;
FOR c := 0 TO ncomp - 1 DO
ndec := decSpec.GetNumDecLevels(curTile, c);
reslevel := ndec - recMinDecLvl;
IF reslevel >= 0 THEN
subbInfo := deq.GetSubbandInfo(curTile, c, reslevel, J2KU.SUB_LL);
offset := reconstructedComps[curTile][c].offset;
scanw := reconstructedComps[curTile][c].scanw;
width := subbInfo.width;
height := subbInfo.height;
IF reconstructedComps[curTile][c] IS DataBlkInt THEN
dataInt := reconstructedComps[curTile][c](DataBlkInt).data;
FOR h := 0 TO subbInfo.height - 1 DO
Machine.Fill32(SYSTEM.ADR(dataInt[offset]), width*SYSTEM.SIZEOF(LONGINT), 0);
INC(offset, scanw);
END;
ELSIF reconstructedComps[curTile][c] IS DataBlkReal THEN
dataReal := reconstructedComps[curTile][c](DataBlkReal).data;
FOR h := 0 TO subbInfo.height - 1 DO
Machine.Fill32(SYSTEM.ADR(dataReal[offset]), width*SYSTEM.SIZEOF(REAL), 0);
INC(offset, scanw);
END;
END;
END;
END;
END InitReconstructedRange;
PROCEDURE GetData () : BOOLEAN;
VAR
ncblksRet, i, j, rowStartComp, rowStartCblk : LONGINT;
dataCblkArr : ARRAY CBLK_BUFSIZE OF DataBlk;
dataCblkInfoArr : ARRAY CBLK_BUFSIZE OF J2KU.CblkInfo;
dataCblk : DataBlk;
recComp : DataBlk;
dataInt : J2KU.LongIntArrayPtr;
dataReal : J2KU.RealArrayPtr;
comp : LONGINT;
BEGIN
ncblksRet := deq.GetCodeBlocks(dataCblkArr, dataCblkInfoArr, CBLK_BUFSIZE);
WHILE ncblksRet > 0 DO
FOR j := 0 TO ncblksRet - 1 DO
comp := dataCblkInfoArr[j].subbinfo.component;
recComp := reconstructedComps[curTile][comp];
rowStartComp := dataCblkInfoArr[j].ulsy * recComp.scanw + dataCblkInfoArr[j].ulsx + recComp.offset;
rowStartCblk := dataCblkArr[j].offset;
dataCblk := dataCblkArr[j];
IF dataCblk IS DataBlkInt THEN
WITH dataCblk : DataBlkInt DO
dataInt := recComp(DataBlkInt).data;
FOR i := 0 TO dataCblkInfoArr[j].height - 1 DO
SYSTEM.MOVE(SYSTEM.ADR(dataCblk.data[rowStartCblk]), SYSTEM.ADR(dataInt[rowStartComp]), dataCblkInfoArr[j].width * SYSTEM.SIZEOF(LONGINT));
INC(rowStartComp, recComp.scanw);
INC(rowStartCblk, dataCblk.scanw);
END;
END;
ELSIF dataCblk IS DataBlkReal THEN
WITH dataCblk : DataBlkReal DO
dataReal := recComp(DataBlkReal).data;
FOR i := 0 TO dataCblkInfoArr[j].height - 1 DO
SYSTEM.MOVE(SYSTEM.ADR(dataCblk.data[rowStartCblk]), SYSTEM.ADR(dataReal[rowStartComp]), dataCblkInfoArr[j].width * SYSTEM.SIZEOF(REAL));
INC(rowStartComp, recComp.scanw);
INC(rowStartCblk, dataCblk.scanw);
END;
END;
ELSE
KernelLog.String("ERROR (InverseDWT.TransformStep) : Dequantizer returned unknown data-block type");
KernelLog.Ln();
RETURN FALSE;
END;
END;
ncblksRet := deq.GetCodeBlocks(dataCblkArr, dataCblkInfoArr, CBLK_BUFSIZE);
END;
RETURN TRUE;
END GetData;
PROCEDURE TransformStep () : BOOLEAN;
VAR
i, origMaxDecLvl, origMinDecLvl : LONGINT;
BEGIN
origMaxDecLvl := maxDecLvl;
origMinDecLvl := minDecLvl;
IF (reconstructedRange[curTile][0] = minLayer)
& (reconstructedRange[curTile][1] = maxLayer)
THEN
IF (reconstructedRange[curTile][3] > origMinDecLvl)
& (reconstructedRange[curTile][2] = origMaxDecLvl)
THEN
SetDecLevelRange(reconstructedRange[curTile][3]-1, origMinDecLvl);
IF ~GetData() THEN
RETURN FALSE;
END;
SetDecLevelRange(reconstructedRange[curTile][3], origMinDecLvl);
ELSIF (reconstructedRange[curTile][3] # origMinDecLvl)
OR (reconstructedRange[curTile][2] # origMaxDecLvl)
THEN
InitReconstructedRange();
IF ~GetData() THEN
RETURN FALSE;
END;
END;
ELSE
InitReconstructedRange();
IF ~GetData() THEN
RETURN FALSE;
END;
END;
IF AllTilePartsRead() THEN
FOR i := 0 TO ncomp - 1 DO
IF ~Wavelet2DReconstruction(curTile, i) THEN
RETURN FALSE;
END;
END;
reconstructedRange[curTile][0] := minLayer;
reconstructedRange[curTile][1] := maxLayer;
reconstructedRange[curTile][2] := origMaxDecLvl;
reconstructedRange[curTile][3] := origMinDecLvl;
END;
SetDecLevelRange(origMaxDecLvl, origMinDecLvl);
RETURN TRUE;
END TransformStep;
PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
BEGIN
deq.SetMaxLayerRange(maxStartLayer, maxEndLayer);
END SetMaxLayerRange;
PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
BEGIN
SELF.minLayer := startLayer;
SELF.maxLayer := endLayer;
deq.SetLayerRange(startLayer, endLayer);
END SetLayerRange;
PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
BEGIN
startLayer := minLayer;
endLayer := maxLayer;
END GetLayerRange;
PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
BEGIN
overallMinDecLvl := maxEndDecLvl;
deq.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
END SetMaxDecLevelRange;
PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
BEGIN
SELF.minDecLvl := endDecLvl;
SELF.maxDecLvl := startDecLvl;
deq.SetDecLevelRange(startDecLvl, endDecLvl);
END SetDecLevelRange;
PROCEDURE GetDecLevelRange (VAR startDec, endDec : LONGINT);
BEGIN
startDec := maxDecLvl;
endDec := minDecLvl;
END GetDecLevelRange;
PROCEDURE GetComponent (component : LONGINT; VAR comp : DataBlk; VAR compInfo : J2KU.BlkInfo);
BEGIN
comp := reconstructedComps[curTile][component];
compInfo := reconstructedCompsInfo[curTile][component];
END GetComponent;
PROCEDURE CurrentTile () : LONGINT;
BEGIN
RETURN deq.CurrentTile();
END CurrentTile;
PROCEDURE CurrentTilePart () : LONGINT;
BEGIN
RETURN deq.CurrentTilePart();
END CurrentTilePart;
PROCEDURE NextTilePart () : BOOLEAN;
BEGIN
IF gotoReBuild THEN
SetReBuildMode();
gotoReBuild := FALSE;
END;
IF ~deq.NextTilePart() THEN
RETURN FALSE;
END;
RETURN InitTile();
END NextTilePart;
PROCEDURE AllTilePartsRead () : BOOLEAN;
BEGIN
RETURN deq.AllTilePartsRead();
END AllTilePartsRead;
PROCEDURE TilePartAvailable () : BOOLEAN;
BEGIN
RETURN deq.TilePartAvailable();
END TilePartAvailable;
PROCEDURE DataAvailable () : BOOLEAN;
BEGIN
RETURN deq.DataAvailable();
END DataAvailable;
PROCEDURE InitTile () : BOOLEAN;
VAR
transType, compSize, i, ndec : LONGINT;
subbInfo, subbInfoStart : J2KU.SubbandInfo;
compInt : DataBlkInt;
compReal : DataBlkReal;
recCompInfo : J2KU.BlkInfo;
minDecLvlTile : LONGINT;
BEGIN
curTile := deq.CurrentTile();
IF deq.CurrentTilePart() = 0 THEN
minDecLvlTile := decSpec.GetMinDecLevels(curTile);
IF minDecLvl > minDecLvlTile THEN
IF overallMinDecLvl > minDecLvlTile THEN
KernelLog.String("ERROR (InverseDWT.InitTile): Can't build image at requested resolution level: ");
KernelLog.String(" Minimum resolution level of tile ");
KernelLog.Int(curTile, 0);
KernelLog.String(" is higher than the requested resolution level");
RETURN FALSE;
ELSE
gotoReBuild := TRUE;
SetDecLevelRange(maxDecLvl, minDecLvlTile);
END;
END;
FOR i := 0 TO ncomp - 1 DO
ndec := decSpec.GetNumDecLevels(curTile, i);
IF maxDecLvl >= ndec THEN
subbInfoStart := deq.GetSubbandInfo(curTile, i, 0, J2KU.SUB_LL);
ELSE
subbInfoStart := deq.GetSubbandInfo(curTile, i, ndec - maxDecLvl, J2KU.SUB_LL);
END;
subbInfo := deq.GetSubbandInfo(curTile, i, ndec - overallMinDecLvl, J2KU.SUB_LL);
compSize := subbInfo.width * subbInfo.height;
transType := decSpec.GetWavTransType(curTile, i);
NEW(recCompInfo);
recCompInfo.ulx := subbInfoStart.ulcx;
recCompInfo.uly := subbInfoStart.ulcy;
recCompInfo.width := subbInfoStart.width;
recCompInfo.height := subbInfoStart.height;
reconstructedCompsInfo[curTile][i] := recCompInfo;
IF transType = J2KCS.TRANS_5X3_REV THEN
NEW(compInt);
NEW(compInt.data, compSize);
deq.SetDataType(curTile, i, DATA_LONGINT);
reconstructedComps[curTile][i] := compInt;
ELSIF transType = J2KCS.TRANS_9X7_IRREV THEN
NEW(compReal);
NEW(compReal.data, compSize);
deq.SetDataType(curTile, i, DATA_REAL);
reconstructedComps[curTile][i] := compReal;
END;
reconstructedComps[curTile][i].offset := 0;
reconstructedComps[curTile][i].scanw := subbInfo.width;
END;
reconstructedRange[curTile][0] := -1;
reconstructedRange[curTile][1] := -1;
reconstructedRange[curTile][2] := MIN(LONGINT);
reconstructedRange[curTile][3] := MAX(LONGINT);
END;
RETURN TRUE;
END InitTile;
PROCEDURE Wavelet2DReconstruction (tile, component : LONGINT) : BOOLEAN;
VAR
recComp : DataBlk;
recCompInfo : J2KU.BlkInfo;
ndec, curRes, curDec, ulcx, ulcy, ulx, uly, width, height, i, k, j : LONGINT;
subbInfo : J2KU.SubbandInfo;
bufInt, dataInt : J2KU.LongIntArrayPtr;
bufReal, dataReal : J2KU.RealArrayPtr;
dataOffset, tmpOffset : LONGINT;
transType : LONGINT;
BEGIN
recComp := reconstructedComps[tile][component];
recCompInfo := reconstructedCompsInfo[tile][component];
transType := decSpec.GetWavTransType(tile, component);
IF transType = J2KCS.TRANS_5X3_REV THEN
dataInt := recComp(DataBlkInt).data;
ELSIF transType = J2KCS.TRANS_9X7_IRREV THEN
dataReal := recComp(DataBlkReal).data;
ELSE
KernelLog.String("ERROR (InverseDWT.Wavelet2DReconstruction): Invalid/Unknown wavelet tranformation type specified");
KernelLog.Ln();
RETURN FALSE;
END;
ndec := decSpec.GetNumDecLevels(tile, component);
IF maxDecLvl > ndec THEN
curDec := ndec;
ELSE
curDec := maxDecLvl;
END;
ulcx := recCompInfo.ulx;
ulcy := recCompInfo.uly;
width := recCompInfo.width;
height := recCompInfo.height;
WHILE (curDec > minDecLvl) DO
DEC(curDec);
curRes := ndec - curDec;
subbInfo := deq.GetSubbandInfo(tile, component, curRes, J2KU.SUB_LL);
ulcx := subbInfo.ulcx;
ulcy := subbInfo.ulcy;
ulx := subbInfo.ulsx;
uly := subbInfo.ulsy;
width := subbInfo.width;
height := subbInfo.height;
IF (width # 0) & (height # 0) THEN
dataOffset := uly*recComp.scanw + ulx + recComp.offset;
IF transType = J2KCS.TRANS_5X3_REV THEN
tmpOffset := dataOffset;
IF width > height THEN
NEW(bufInt, width);
ELSE
NEW(bufInt, height);
END;
IF ~ODD(ulcx) THEN
FOR i := 0 TO height - 1 DO
SYSTEM.MOVE(SYSTEM.ADR(dataInt[tmpOffset]), SYSTEM.ADR(bufInt[0]), width*SYSTEM.SIZEOF(LONGINT));
filterRev.SynthesizeLPF(bufInt, 0, 1, bufInt, (width+1) DIV 2, 1, dataInt, tmpOffset, 1, width);
INC(tmpOffset, recComp.scanw);
END;
ELSE
FOR i := 0 TO height - 1 DO
SYSTEM.MOVE(SYSTEM.ADR(dataInt[tmpOffset]), SYSTEM.ADR(bufInt[0]), width*SYSTEM.SIZEOF(LONGINT));
filterRev.SynthesizeHPF(bufInt, 0, 1, bufInt, width DIV 2, 1, dataInt, tmpOffset, 1, width);
INC(tmpOffset, recComp.scanw);
END;
END;
tmpOffset := dataOffset;
IF ~ODD(ulcy) THEN
FOR i := 0 TO width - 1 DO
k := tmpOffset;
FOR j := 0 TO height - 1 DO
bufInt[j] := dataInt[k];
INC(k, recComp.scanw);
END;
filterRev.SynthesizeLPF(bufInt, 0, 1, bufInt, (height+1) DIV 2, 1, dataInt, tmpOffset, recComp.scanw, height);
INC(tmpOffset);
END;
ELSE
FOR i := 0 TO width - 1 DO
k := tmpOffset;
FOR j := 0 TO height - 1 DO
bufInt[j] := dataInt[k];
INC(k, recComp.scanw);
END;
filterRev.SynthesizeHPF(bufInt, 0, 1, bufInt, height DIV 2, 1, dataInt, tmpOffset, recComp.scanw, height);
INC(tmpOffset);
END;
END;
ELSIF transType = J2KCS.TRANS_9X7_IRREV THEN
tmpOffset := dataOffset;
IF width > height THEN
NEW(bufReal, width);
ELSE
NEW(bufReal, height);
END;
IF ~ODD(ulcx) THEN
FOR i := 0 TO height - 1 DO
SYSTEM.MOVE(SYSTEM.ADR(dataReal[tmpOffset]), SYSTEM.ADR(bufReal[0]), width*SYSTEM.SIZEOF(REAL));
filterIrrev.SynthesizeLPF(bufReal, 0, 1, bufReal, (width+1) DIV 2, 1, dataReal, tmpOffset, 1, width);
INC(tmpOffset, recComp.scanw);
END;
ELSE
FOR i := 0 TO height - 1 DO
SYSTEM.MOVE(SYSTEM.ADR(dataReal[tmpOffset]), SYSTEM.ADR(bufReal[0]), width*SYSTEM.SIZEOF(REAL));
filterIrrev.SynthesizeHPF(bufReal, 0, 1, bufReal, width DIV 2, 1, dataReal, tmpOffset, 1, width);
INC(tmpOffset, recComp.scanw);
END;
END;
tmpOffset := dataOffset;
IF ~ODD(ulcy) THEN
FOR i := 0 TO width - 1 DO
k := tmpOffset;
FOR j := 0 TO height - 1 DO
bufReal[j] := dataReal[k];
INC(k, recComp.scanw);
END;
filterIrrev.SynthesizeLPF(bufReal, 0, 1, bufReal, (height+1) DIV 2, 1, dataReal, tmpOffset, recComp.scanw, height);
INC(tmpOffset);
END;
ELSE
FOR i := 0 TO width - 1 DO
k := tmpOffset;
FOR j := 0 TO height - 1 DO
bufReal[j] := dataReal[k];
INC(k, recComp.scanw);
END;
filterIrrev.SynthesizeHPF(bufReal, 0, 1, bufReal, height DIV 2, 1, dataReal, tmpOffset, recComp.scanw, height);
INC(tmpOffset);
END;
END;
END;
END;
END;
recCompInfo.ulx := ulcx;
recCompInfo.uly := ulcy;
recCompInfo.width := width;
recCompInfo.height := height;
RETURN TRUE;
END Wavelet2DReconstruction;
PROCEDURE SetReBuildMode;
BEGIN
deq.SetReBuildMode();
END SetReBuildMode;
PROCEDURE FreeNonRebuildResources;
BEGIN
deq.FreeNonRebuildResources();
END FreeNonRebuildResources;
PROCEDURE FreeResources;
BEGIN
reconstructedComps := NIL;
reconstructedCompsInfo := NIL;
reconstructedRange := NIL;
deq.FreeResources();
END FreeResources;
END InverseDWT;
InverseMCT = OBJECT
VAR
mct : LONGINT;
invDWT : InverseDWT;
curTile : LONGINT;
comp012 : POINTER TO ARRAY OF ARRAY OF DataBlkInt;
comp012Info : POINTER TO ARRAY OF ARRAY OF J2KU.BlkInfo;
decSpec : J2KCS.DecoderSpecs;
nonRebuildBuffer : BOOLEAN;
transformRequired : POINTER TO ARRAY OF BOOLEAN;
startLayer, endLayer, startDecLvl, endDecLvl : LONGINT;
PROCEDURE &InitNew *(invMCTOpt : J2KU.InverseMCTOptions;
invDWT : InverseDWT;
decSpec : J2KCS.DecoderSpecs);
BEGIN
ReInit(invMCTOpt, invDWT, decSpec);
END InitNew;
PROCEDURE ReInit ( invMCTOpt : J2KU.InverseMCTOptions;
invDWT : InverseDWT;
decSpec : J2KCS.DecoderSpecs);
VAR
i, ntiles: LONGINT;
imgInfo : J2KCS.ImageInfo;
BEGIN
SELF.invDWT := invDWT;
SELF.decSpec := decSpec;
imgInfo := decSpec.GetImageInfo();
ntiles := imgInfo.GetNumTiles();
NEW(comp012, ntiles, 3);
NEW(comp012Info, ntiles, 3);
nonRebuildBuffer := invMCTOpt.nonRebuildBuffer;
startLayer := 0;
endLayer := MAX(LONGINT);
startDecLvl := MAX(LONGINT);
endDecLvl := 0;
NEW(transformRequired, ntiles);
FOR i := 0 TO ntiles - 1 DO
transformRequired[i] := TRUE;
END;
END ReInit;
PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
BEGIN
invDWT.SetMaxLayerRange(maxStartLayer, maxEndLayer);
END SetMaxLayerRange;
PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
VAR
i : LONGINT;
BEGIN
IF (startLayer # SELF.startLayer) OR (endLayer # SELF.endLayer) THEN
FOR i := 0 TO LEN(transformRequired^) - 1 DO
transformRequired[i] := TRUE;
END;
END;
SELF.startLayer := startLayer;
SELF.endLayer := endLayer;
invDWT.SetLayerRange(startLayer, endLayer);
END SetLayerRange;
PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
BEGIN
invDWT.GetLayerRange(startLayer, endLayer);
END GetLayerRange;
PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
BEGIN
invDWT.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
END SetMaxDecLevelRange;
PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
VAR
i : LONGINT;
BEGIN
IF (startDecLvl # SELF.startDecLvl) OR (endDecLvl # SELF.endDecLvl) THEN
FOR i := 0 TO LEN(transformRequired^) - 1 DO
transformRequired[i] := TRUE;
END;
END;
SELF.startDecLvl := startDecLvl;
SELF.endDecLvl := endDecLvl;
invDWT.SetDecLevelRange(startDecLvl, endDecLvl);
END SetDecLevelRange;
PROCEDURE GetDecLevelRange (VAR startDecLvl, endDecLvl : LONGINT);
BEGIN
startDecLvl := SELF.startDecLvl;
endDecLvl := SELF.endDecLvl;
END GetDecLevelRange;
PROCEDURE GetAdaptedComponent (component : LONGINT; VAR comp : DataBlk; VAR compInfo : J2KU.BlkInfo);
VAR
tmpComp : DataBlk;
dataBlkInt : DataBlkInt;
dataInt : J2KU.LongIntArrayPtr;
dataReal : J2KU.RealArrayPtr;
i, j, width, height, dataIdxReal, dataIdxInt, scanwReal, scanwInt : LONGINT;
BEGIN
invDWT.GetComponent(component, tmpComp, compInfo);
IF tmpComp IS DataBlkInt THEN
comp := tmpComp;
ELSIF tmpComp IS DataBlkReal THEN
width := compInfo.width;
height := compInfo.height;
NEW(dataBlkInt);
NEW(dataInt, width*height);
dataBlkInt.offset := 0;
dataBlkInt.scanw := width;
dataBlkInt.data := dataInt;
dataReal := tmpComp(DataBlkReal).data;
dataIdxReal := tmpComp.offset;
scanwReal := tmpComp.scanw;
dataIdxInt := dataBlkInt.offset;
scanwInt := dataBlkInt.scanw;
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
dataInt[dataIdxInt] := ENTIER(dataReal[dataIdxReal] + 0.5);
INC(dataIdxReal);
INC(dataIdxInt);
END;
dataIdxReal := dataIdxReal - width + scanwReal;
dataIdxInt := dataIdxInt - width + scanwInt;
END;
comp := dataBlkInt;
ELSE
KernelLog.String("ERROR (InverseMCT.GetAdaptedComponent): Returned data block type not unsupported");
KernelLog.Ln();
END;
END GetAdaptedComponent;
PROCEDURE GetComponent (component : LONGINT; VAR comp : DataBlk; VAR compInfo : J2KU.BlkInfo);
BEGIN
IF (component >= 3) OR (mct = MCT_NONE) THEN
GetAdaptedComponent(component, comp, compInfo);
ELSE
comp := comp012[curTile][component];
compInfo := comp012Info[curTile][component];
END;
END GetComponent;
PROCEDURE FullTransform () : BOOLEAN;
BEGIN
RETURN TransformStep();
END FullTransform;
PROCEDURE TransformStep () : BOOLEAN;
BEGIN
IF ~invDWT.FullTransform() THEN
RETURN FALSE;
END;
IF transformRequired[curTile] OR nonRebuildBuffer THEN
IF AllTilePartsRead() THEN
transformRequired[curTile] := FALSE;
END;
CASE mct OF
MCT_NONE :
RETURN TRUE;
| MCT_RCT :
RETURN InverseRCT();
| MCT_ICT :
RETURN InverseICT();
ELSE
KernelLog.String("ERROR (InverseMCT.TransformStep) : Invalid component transformation specified");
KernelLog.Ln();
RETURN FALSE;
END;
END;
RETURN TRUE;
END TransformStep;
PROCEDURE InitTile () : BOOLEAN;
VAR
ncomp, rev, i : LONGINT;
imgInfo : J2KCS.ImageInfo;
BEGIN
imgInfo := decSpec.GetImageInfo();
curTile := invDWT.CurrentTile();
ncomp := imgInfo.GetNumComponents();
IF (ncomp < 3) OR ~decSpec.CompTransUsed(curTile) THEN
mct := MCT_NONE;
RETURN TRUE;
ELSE
rev := 0;
FOR i := 0 TO 2 DO
IF decSpec.IsReversibleWavTrans(curTile, i) THEN
INC(rev);
END;
END;
IF rev = 3 THEN
mct := MCT_RCT;
ELSIF rev = 0 THEN
mct := MCT_ICT;
ELSE
KernelLog.String("ERROR (InverseMCT.InitTile): First three components of tile ");
KernelLog.Int(curTile, 0);
KernelLog.String(" differ in reversibility -> can't perform inverse component transformation");
KernelLog.Ln();
mct := -1;
RETURN FALSE;
END;
IF invDWT.CurrentTilePart() = 0 THEN
FOR i := 0 TO 2 DO
NEW(comp012[curTile][i]);
comp012[curTile][i].data := NIL;
NEW(comp012Info[curTile][i]);
END;
END;
RETURN TRUE;
END;
END InitTile;
PROCEDURE CurrentTile () : LONGINT;
BEGIN
RETURN invDWT.CurrentTile();
END CurrentTile;
PROCEDURE CurrentTilePart () : LONGINT;
BEGIN
RETURN invDWT.CurrentTilePart();
END CurrentTilePart;
PROCEDURE NextTilePart () : BOOLEAN;
BEGIN
IF ~invDWT.NextTilePart() THEN
RETURN FALSE;
END;
RETURN InitTile();
END NextTilePart;
PROCEDURE AllTilePartsRead () : BOOLEAN;
BEGIN
RETURN invDWT.AllTilePartsRead();
END AllTilePartsRead;
PROCEDURE TilePartAvailable () : BOOLEAN;
BEGIN
RETURN invDWT.TilePartAvailable();
END TilePartAvailable;
PROCEDURE DataAvailable () : BOOLEAN;
BEGIN
RETURN invDWT.DataAvailable();
END DataAvailable;
PROCEDURE InverseRCT () : BOOLEAN;
VAR
tmpComp : ARRAY 3 OF DataBlk;
data0, data1, data2, outData0, outData1, outData2 : J2KU.LongIntArrayPtr;
dataLen, i, j, dataIdxOut, dataIdxIn : LONGINT;
width, height, scanwOut, scanwIn : LONGINT;
BEGIN
invDWT.GetComponent(0, tmpComp[0], comp012Info[curTile][0]);
invDWT.GetComponent(1, tmpComp[1], comp012Info[curTile][1]);
invDWT.GetComponent(2, tmpComp[2], comp012Info[curTile][2]);
width := comp012Info[curTile][0].width;
height := comp012Info[curTile][0].height;
dataLen := width * height;
IF (dataLen # (comp012Info[curTile][1].width*comp012Info[curTile][1].height)) OR (dataLen # (comp012Info[curTile][2].width*comp012Info[curTile][2].height)) THEN
KernelLog.String("ERROR (InverseMCT.InverseRCT) : Transformation of components with different number of samples is not supported");
KernelLog.Ln();
RETURN FALSE;
END;
data0 := tmpComp[0](DataBlkInt).data;
data1 := tmpComp[1](DataBlkInt).data;
data2 := tmpComp[2](DataBlkInt).data;
outData0 := comp012[curTile][0].data;
outData1 := comp012[curTile][1].data;
outData2 := comp012[curTile][2].data;
IF (outData0 = NIL) OR (LEN(outData0^) < dataLen) THEN
NEW(outData0, dataLen);
NEW(outData1, dataLen);
NEW(outData2, dataLen);
comp012[curTile][0].data := outData0;
comp012[curTile][1].data := outData1;
comp012[curTile][2].data := outData2;
comp012[curTile][0].scanw := comp012Info[curTile][0].width;
comp012[curTile][1].scanw := comp012Info[curTile][1].width;
comp012[curTile][2].scanw := comp012Info[curTile][2].width;
comp012[curTile][0].offset := 0;
comp012[curTile][1].offset := 0;
comp012[curTile][2].offset := 0;
END;
dataIdxOut := comp012[curTile][0].offset;
dataIdxIn := tmpComp[0].offset;
scanwOut := comp012[curTile][0].scanw;
scanwIn := tmpComp[0].scanw;
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
outData1[dataIdxOut] := data0[dataIdxIn] - ASH(data2[dataIdxIn] + data1[dataIdxIn], -2);
outData0[dataIdxOut] := data2[dataIdxIn] + outData1[dataIdxOut];
outData2[dataIdxOut] := data1[dataIdxIn] + outData1[dataIdxOut];
INC(dataIdxOut);
INC(dataIdxIn);
END;
dataIdxOut := dataIdxOut - width + scanwOut;
dataIdxIn := dataIdxIn - width + scanwIn;
END;
RETURN TRUE;
END InverseRCT;
PROCEDURE InverseICT () : BOOLEAN;
VAR
tmpComp : ARRAY 3 OF DataBlk;
data0, data1, data2 : J2KU.RealArrayPtr;
outData0, outData1, outData2 : J2KU.LongIntArrayPtr;
dataLen, i, j, dataIdxOut, dataIdxIn : LONGINT;
width, height, scanwOut, scanwIn : LONGINT;
BEGIN
invDWT.GetComponent(0, tmpComp[0], comp012Info[curTile][0]);
invDWT.GetComponent(1, tmpComp[1], comp012Info[curTile][1]);
invDWT.GetComponent(2, tmpComp[2], comp012Info[curTile][2]);
width := comp012Info[curTile][0].width;
height := comp012Info[curTile][0].height;
dataLen := width * height;
IF (dataLen # (comp012Info[curTile][1].width*comp012Info[curTile][1].height)) OR (dataLen # (comp012Info[curTile][2].width*comp012Info[curTile][2].height)) THEN
KernelLog.String("ERROR (InverseMCT.InverseRCT) : Transformation of components with different number of samples is not supported");
KernelLog.Ln();
RETURN FALSE;
END;
data0 := tmpComp[0](DataBlkReal).data;
data1 := tmpComp[1](DataBlkReal).data;
data2 := tmpComp[2](DataBlkReal).data;
outData0 := comp012[curTile][0].data;
outData1 := comp012[curTile][1].data;
outData2 := comp012[curTile][2].data;
IF (outData0 = NIL) OR (LEN(outData0^) < dataLen) THEN
NEW(outData0, dataLen);
NEW(outData1, dataLen);
NEW(outData2, dataLen);
comp012[curTile][0].data := outData0;
comp012[curTile][1].data := outData1;
comp012[curTile][2].data := outData2;
comp012[curTile][0].scanw := comp012Info[curTile][0].width;
comp012[curTile][1].scanw := comp012Info[curTile][1].width;
comp012[curTile][2].scanw := comp012Info[curTile][2].width;
comp012[curTile][0].offset := 0;
comp012[curTile][1].offset := 0;
comp012[curTile][2].offset := 0;
END;
dataIdxOut := comp012[curTile][0].offset;
dataIdxIn := tmpComp[0].offset;
scanwOut := comp012[curTile][0].scanw;
scanwIn := tmpComp[0].scanw;
FOR j := 0 TO height - 1 DO
FOR i := 0 TO width - 1 DO
outData0[dataIdxOut] := ENTIER(data0[dataIdxIn] + 1.402*data2[dataIdxIn] + 0.5);
outData1[dataIdxOut] := ENTIER(data0[dataIdxIn] - 0.34413*data1[dataIdxIn] - 0.71414*data2[dataIdxIn] + 0.5);
outData2[dataIdxOut] := ENTIER(data0[dataIdxIn] + 1.772*data1[dataIdxIn] + 0.5);
INC(dataIdxOut);
INC(dataIdxIn);
END;
dataIdxOut := dataIdxOut - width + scanwOut;
dataIdxIn := dataIdxIn - width + scanwIn;
END;
RETURN TRUE;
END InverseICT;
PROCEDURE SetReBuildMode;
BEGIN
invDWT.SetReBuildMode();
END SetReBuildMode;
PROCEDURE FreeNonRebuildResources;
VAR
imgInfo : J2KCS.ImageInfo;
ntiles, i : LONGINT;
BEGIN
imgInfo := decSpec.GetImageInfo();
ntiles := imgInfo.GetNumTiles();
IF nonRebuildBuffer THEN
FOR i := 0 TO ntiles - 1 DO
IF comp012[i][0] # NIL THEN
comp012[i][0].data := NIL;
comp012[i][1].data := NIL;
comp012[i][2].data := NIL;
comp012Info[i][0] := NIL;
comp012Info[i][1] := NIL;
comp012Info[i][2] := NIL;
END;
END;
END;
invDWT.FreeNonRebuildResources();
END FreeNonRebuildResources;
PROCEDURE FreeResources;
BEGIN
comp012 := NIL;
comp012Info := NIL;
transformRequired := NIL;
invDWT.FreeResources();
END FreeResources;
END InverseMCT;
JP2Box = OBJECT
VAR
type : LONGINT;
END JP2Box;
CodestreamBox = OBJECT(JP2Box)
VAR
s : Streams.Reader;
PROCEDURE &InitNew*;
BEGIN
type := JP2CCST;
END InitNew;
END CodestreamBox;
TYPE
JP2FileFormatReader = OBJECT
VAR
s : Streams.Reader;
isJP2 : BOOLEAN;
initError : BOOLEAN;
lastBoxFound, jp2HeaderBoxFound : BOOLEAN;
curBoxType : LONGINT;
curBoxLen, curBoxContLen : HUGEINT;
PROCEDURE & InitNew *(s : Streams.Reader);
BEGIN
ReInit(s);
END InitNew;
PROCEDURE ReInit (s : Streams.Reader);
VAR
signature : LONGINT;
BEGIN
SELF.s := s;
IF ORD(s.Peek()) # 00H THEN
isJP2 := FALSE;
lastBoxFound := TRUE;
initError := FALSE;
RETURN;
END;
ReadBoxInfo();
signature := s.Net32();
IF (curBoxLen # 12)
OR (curBoxType # JP2SIGN)
OR (signature # 0D0A870AH)
THEN
isJP2 := FALSE;
lastBoxFound := TRUE;
KernelLog.String("ERROR: Not a valid JPEG 2000 - Part 1 file/stream");
KernelLog.Ln();
initError := TRUE;
RETURN;
END;
isJP2 := TRUE;
lastBoxFound := FALSE;
jp2HeaderBoxFound := FALSE;
ReadBoxInfo();
IF curBoxType # JP2FTYP THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReInit): Invalid box type (read: '");
KernelLog.Hex(curBoxType, 0);
KernelLog.String("'; required: '");
KernelLog.Hex(JP2FTYP, 0);
KernelLog.String("', i.e. File Type box)");
KernelLog.Ln();
initError := TRUE;
RETURN;
END;
initError := ~ReadFileTypeBox();
END ReInit;
PROCEDURE InitError () : BOOLEAN;
BEGIN
RETURN initError;
END InitError;
PROCEDURE IsJP2File () : BOOLEAN;
BEGIN
RETURN isJP2;
END IsJP2File;
PROCEDURE ReadBoxInfo;
VAR
tmp : LONGINT;
BEGIN
curBoxLen := s.Net32();
curBoxType := s.Net32();
IF curBoxLen = 0 THEN
curBoxLen := s.Available() + 8;
curBoxContLen := s.Available();
lastBoxFound := TRUE;
ELSIF curBoxLen = 1 THEN
tmp := SYSTEM.LSH(s.Net32(), 32);
curBoxLen := tmp + s.Net32();
curBoxContLen := curBoxLen - 16;
ELSE
curBoxContLen := curBoxLen - 8;
END;
END ReadBoxInfo;
PROCEDURE ReadFileTypeBox () : BOOLEAN;
VAR
br, minV : LONGINT;
clLength : HUGEINT;
jp2Comp : BOOLEAN;
BEGIN
IF ~HasNextBox() THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReadFileTypeBox): File Type box is last in file");
KernelLog.Ln();
RETURN FALSE;
END;
br := s.Net32();
minV := s.Net32();
clLength := SYSTEM.LSH(curBoxContLen - 8, -2);
IF clLength <= 0 THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReadFileTypeBox): Empty compatibility list");
KernelLog.Ln();
RETURN FALSE;
END;
jp2Comp := FALSE;
WHILE clLength > 0 DO
IF s.Net32() = JP2_FTBRAND THEN
jp2Comp := TRUE;
END;
DEC(clLength);
END;
IF ~jp2Comp THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReadFileTypeBox): Compatibility list does not contain JPEG 2000 - Part 1");
KernelLog.Ln();
END;
RETURN jp2Comp;
END ReadFileTypeBox;
PROCEDURE ReadJP2HeaderBox (VAR box : JP2Box) : BOOLEAN;
VAR
headerBoxLen, nColSpecBox : HUGEINT;
ok : BOOLEAN;
BEGIN
box := NIL;
IF ~HasNextBox() THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReadJP2HeaderBox): JP2 Header box is last box in file");
KernelLog.Ln();
RETURN FALSE;
END;
headerBoxLen := curBoxContLen;
ReadBoxInfo();
IF curBoxType # JP2IHDR THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReadJP2HeaderBox): Image Header box not first box in JP2 Header box");
KernelLog.Ln();
RETURN FALSE;
END;
ok := SkipBox();
DEC(headerBoxLen, curBoxLen);
nColSpecBox := 0;
WHILE ok & (headerBoxLen > 0) DO
ReadBoxInfo();
IF curBoxType = JP2BPCC THEN
ELSIF curBoxType = JP2COLR THEN
INC(nColSpecBox);
ELSIF curBoxType = JP2PCLR THEN
ELSIF curBoxType = JP2CMAP THEN
ELSIF curBoxType = JP2CDEF THEN
ELSIF curBoxType = JP2RESL THEN
ELSE
KernelLog.String("NOTICE: Unknown/unexpected JP2 box type found within JP2 Header box: ");
KernelLog.Hex(curBoxType, 0);
KernelLog.Ln();
END;
ok := SkipBox();
DEC(headerBoxLen, curBoxLen);
END;
IF ok & (nColSpecBox <= 0) THEN
KernelLog.String("ERROR (JP2FileFormatReader.ReadJP2HeaderBox): No Colour Specification box found");
KernelLog.Ln();
ok := FALSE;
END;
RETURN ok;
END ReadJP2HeaderBox;
PROCEDURE ReadContiguousCodestreamBox (VAR box : JP2Box) : BOOLEAN;
VAR
ccBox : CodestreamBox;
BEGIN
NEW(ccBox);
ccBox.s := SELF.s;
box := ccBox;
RETURN TRUE;
END ReadContiguousCodestreamBox;
PROCEDURE ReadIPRBox (VAR box : JP2Box) : BOOLEAN;
BEGIN
box := NIL;
RETURN SkipBox();
END ReadIPRBox;
PROCEDURE ReadXMLBox (VAR box : JP2Box) : BOOLEAN;
BEGIN
box := NIL;
RETURN SkipBox();
END ReadXMLBox;
PROCEDURE ReadUUIDBox (VAR box : JP2Box) : BOOLEAN;
BEGIN
box := NIL;
RETURN SkipBox();
END ReadUUIDBox;
PROCEDURE ReadUUIDInfoBox (VAR box : JP2Box) : BOOLEAN;
BEGIN
box := NIL;
RETURN SkipBox();
END ReadUUIDInfoBox;
PROCEDURE HasNextBox () : BOOLEAN;
BEGIN
RETURN ~initError & ~lastBoxFound & (s.Available() >= 8);
END HasNextBox;
PROCEDURE NextBox (VAR boxtype : LONGINT; VAR length : HUGEINT) : BOOLEAN;
BEGIN
IF ~HasNextBox() THEN
KernelLog.String("ERROR (JP2FileFormatReader.NextBox): No (more) JP2 boxes available");
KernelLog.Ln();
RETURN FALSE;
END;
ReadBoxInfo();
IF curBoxType = JP2HEAD THEN
IF jp2HeaderBoxFound THEN
KernelLog.String("ERROR (JP2FileFormatReader.NextBox): Multiple JP2 Header boxes found");
KernelLog.Ln();
RETURN FALSE;
ELSE
jp2HeaderBoxFound := TRUE;
END;
ELSIF curBoxType = JP2CCST THEN
IF ~jp2HeaderBoxFound THEN
KernelLog.String("ERROR (JP2FileFormatReader.NextBox): JP2 Header box not found before Contiguous codestream box");
KernelLog.Ln();
RETURN FALSE;
END;
ELSIF curBoxType = JP2INPR THEN
ELSIF curBoxType = JP2XMLD THEN
ELSIF curBoxType = JP2UUID THEN
ELSIF curBoxType = JP2UINF THEN
ELSE
KernelLog.String("NOTICE: Unknown/unexpected JP2 box type found in file: ");
KernelLog.Hex(curBoxType, 0);
KernelLog.Ln();
END;
boxtype := curBoxType;
length := curBoxContLen;
RETURN TRUE;
END NextBox;
PROCEDURE GetBoxContent (VAR box : JP2Box) : BOOLEAN;
BEGIN
IF curBoxType = JP2HEAD THEN
RETURN ReadJP2HeaderBox(box);
ELSIF curBoxType = JP2CCST THEN
RETURN ReadContiguousCodestreamBox(box);
ELSIF curBoxType = JP2INPR THEN
RETURN ReadIPRBox(box);
ELSIF curBoxType = JP2XMLD THEN
RETURN ReadXMLBox(box);
ELSIF curBoxType = JP2UUID THEN
RETURN ReadUUIDBox(box);
ELSIF curBoxType = JP2UINF THEN
RETURN ReadUUIDInfoBox(box);
ELSE
box := NIL;
RETURN SkipBox();
END;
END GetBoxContent;
PROCEDURE SkipBox () : BOOLEAN;
BEGIN
WHILE curBoxContLen > MAX(LONGINT) DO
s.SkipBytes(MAX(LONGINT));
DEC(curBoxContLen, MAX(LONGINT));
END;
s.SkipBytes(SHORT(curBoxContLen));
RETURN TRUE;
END SkipBox;
PROCEDURE GetCodestream () : Streams.Reader;
VAR
s : Streams.Reader;
noCodestream : BOOLEAN;
box : JP2Box;
boxType : LONGINT;
boxLen : HUGEINT;
BEGIN
s := NIL;
noCodestream := TRUE;
WHILE noCodestream & HasNextBox() DO
IF ~NextBox(boxType, boxLen) THEN
RETURN NIL;
END;
IF boxType = JP2CCST THEN
noCodestream := FALSE;
IF GetBoxContent(box) THEN
ASSERT(box.type = boxType);
s := box(CodestreamBox).s;
END;
ELSE
IF ~SkipBox() THEN
RETURN NIL;
END;
END;
END;
IF noCodestream THEN
KernelLog.String("ERROR (JP2FileFormatReader.GetCodestream): No codestream found");
KernelLog.Ln();
END;
RETURN s;
END GetCodestream;
PROCEDURE FreeResources;
BEGIN
s := NIL;
END FreeResources;
END JP2FileFormatReader;
CONST
PROD_FAILED* = -1;
PROD_DONE* = 1;
TYPE
ImageConsumer* = OBJECT
PROCEDURE SetPixels*(pixelData : J2KU.LongIntArrayPtr; xOffset, yOffset, width, height : LONGINT);
END SetPixels;
PROCEDURE SetProductionStatus* (status : LONGINT);
END SetProductionStatus;
END ImageConsumer;
ImageProducer = OBJECT
VAR
imgFmt : LONGINT;
src : InverseMCT;
producedOnce : BOOLEAN;
imgInfo : J2KCS.ImageInfo;
PROCEDURE &InitNew*;
BEGIN
src := NIL;
imgFmt := -1;
END InitNew;
PROCEDURE InitProduction (src : InverseMCT; imgInfo : J2KCS.ImageInfo) : BOOLEAN;
VAR
ncomp : LONGINT;
imgWidth, imgHeight, i : LONGINT;
compWidth, compHeight : LONGINT;
BEGIN
producedOnce := FALSE;
SELF.src := src;
SELF.imgInfo := imgInfo;
ncomp := imgInfo.GetNumComponents();
CASE ncomp OF
1 :
imgFmt := Codecs.ImgFmtGrey;
| 3:
imgFmt := Codecs.ImgFmtRGB;
|
4:
imgFmt := Codecs.ImgFmtRGBA;
ELSE
imgFmt := -1;
KernelLog.String("ERROR (ImageProducer.InitProduction) : Only 1, 3 and 4 components supported currently");
KernelLog.Ln();
RETURN FALSE;
END;
imgWidth := imgInfo.GetImgWidth(0);
imgHeight := imgInfo.GetImgHeight(0);
FOR i := 0 TO ncomp - 1 DO
compWidth := imgInfo.GetCompImgWidth(i, 0);
compHeight := imgInfo.GetCompImgHeight(i, 0);
IF (compWidth # imgWidth) OR (compHeight # imgHeight) THEN
KernelLog.String("ERROR (ImageProducer.InitProduction) : Component subsampling not supported (yet)");
KernelLog.Ln();
RETURN FALSE;
ELSIF imgInfo.GetBitDepth(i) > 8 THEN
KernelLog.String("ERROR (ImageProducer.InitProduction) : Component bit-depths greater than 8 bits not supported (yet)");
KernelLog.Ln();
RETURN FALSE;
END;
END;
RETURN TRUE;
END InitProduction;
PROCEDURE ProduceImage (VAR consumers : ARRAY OF ImageConsumer; offset, nconsumer : LONGINT);
VAR
ok : BOOLEAN;
comp : ARRAY 4 OF DataBlkInt;
compInfo : ARRAY 4 OF J2KU.BlkInfo;
data : ARRAY 4 OF J2KU.LongIntArrayPtr;
maxVal0, maxVal1, maxVal2, maxVal3 : LONGINT;
levShift0, levShift1, levShift2, levShift3 : LONGINT;
tmp, tmp0, tmp1, tmp2, tmp3 : LONGINT;
tileOffX, tileOffY : LONGINT;
width, height : LONGINT;
lineBuf : J2KU.LongIntArrayPtr;
ncomp : LONGINT;
t, c, i, w, h : LONGINT;
pos, scanw, rowWrap : LONGINT;
tmpBlk : DataBlk;
dummy, curDecLvl : LONGINT;
status : LONGINT;
BEGIN
status := PROD_FAILED;
ncomp := 0;
CASE imgFmt OF
Codecs.ImgFmtGrey :
tmp := imgInfo.GetBitDepth(0);
maxVal0 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift0 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
ncomp := 1;
| Codecs.ImgFmtRGB :
tmp := imgInfo.GetBitDepth(0);
maxVal0 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift0 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
tmp := imgInfo.GetBitDepth(1);
maxVal1 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift1 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
tmp := imgInfo.GetBitDepth(2);
maxVal2 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift2 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
ncomp := 3;
| Codecs.ImgFmtRGBA :
tmp := imgInfo.GetBitDepth(0);
maxVal0 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift0 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
tmp := imgInfo.GetBitDepth(1);
maxVal1 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift1 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
tmp := imgInfo.GetBitDepth(2);
maxVal2 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift2 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
tmp := imgInfo.GetBitDepth(3);
maxVal3 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
levShift3 := SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
ncomp := 4;
ELSE
KernelLog.String("ERROR (ImageProducer.ProduceImage) : Invalid image format encounterd");
KernelLog.Ln();
FOR i := offset TO (offset + nconsumer - 1) DO
consumers[i].SetProductionStatus(status);
END;
RETURN;
END;
IF producedOnce THEN
src.SetReBuildMode();
END;
LOOP
ok := src.NextTilePart();
IF ~ok THEN
IF ~src.DataAvailable() THEN
status := PROD_DONE;
END;
EXIT;
END;
ok := src.FullTransform();
IF ok THEN
t := src.CurrentTile();
FOR c := 0 TO ncomp - 1 DO
src.GetComponent(c, tmpBlk, compInfo[c]);
comp[c] := tmpBlk(DataBlkInt);
data[c] := comp[c].data;
END;
src.GetDecLevelRange(dummy, curDecLvl);
width := compInfo[0].width;
height := compInfo[0].height;
tileOffX := compInfo[0].ulx - imgInfo.GetImgULX(curDecLvl);
tileOffY := compInfo[0].uly - imgInfo.GetImgULY(curDecLvl);
NEW(lineBuf, width);
scanw := comp[0].scanw;
pos := comp[0].offset;
rowWrap := scanw - width;
FOR h := 0 TO height - 1 DO
CASE imgFmt OF
| Codecs.ImgFmtGrey :
FOR w := 0 TO width - 1 DO
tmp0 := data[0][pos] + levShift0;
IF tmp0 > maxVal0 THEN
tmp0 := maxVal0;
ELSIF tmp0 < 0 THEN
tmp0 := 0;
END;
lineBuf[w] := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 000000FFH), 24))
+ SYSTEM.VAL(SET, SYSTEM.LSH(tmp0, 16))
+ SYSTEM.VAL(SET, SYSTEM.LSH(tmp0, 8))
+ SYSTEM.VAL(SET, tmp0));
INC(pos);
END;
INC(pos, rowWrap);
| Codecs.ImgFmtRGB :
FOR w := 0 TO width - 1 DO
tmp0 := data[0][pos] + levShift0;
tmp1 := data[1][pos] + levShift1;
tmp2 := data[2][pos] + levShift2;
IF tmp0 > maxVal0 THEN
tmp0 := maxVal0;
ELSIF tmp0 < 0 THEN
tmp0 := 0;
END;
IF tmp1 > maxVal1 THEN
tmp1 := maxVal1;
ELSIF tmp1 < 0 THEN
tmp1 := 0;
END;
IF tmp2 > maxVal2 THEN
tmp2 := maxVal2;
ELSIF tmp2 < 0 THEN
tmp2 := 0;
END;
lineBuf[w] := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 000000FFH), 24))
+ SYSTEM.VAL(SET, SYSTEM.LSH(tmp0, 16))
+ SYSTEM.VAL(SET, SYSTEM.LSH(tmp1, 8))
+ SYSTEM.VAL(SET, tmp2));
INC(pos);
END;
INC(pos, rowWrap);
| Codecs.ImgFmtRGBA :
FOR w := 0 TO width - 1 DO
tmp0 := data[0][pos] + levShift0;
tmp1 := data[1][pos] + levShift1;
tmp2 := data[2][pos] + levShift2;
tmp3 := data[3][pos] + levShift3;
IF tmp0 > maxVal0 THEN
tmp0 := maxVal0;
ELSIF tmp0 < 0 THEN
tmp0 := 0;
END;
IF tmp1 > maxVal1 THEN
tmp1 := maxVal1;
ELSIF tmp1 < 0 THEN
tmp1 := 0;
END;
IF tmp2 > maxVal2 THEN
tmp2 := maxVal2;
ELSIF tmp2 < 0 THEN
tmp2 := 0;
END;
IF tmp3 > maxVal3 THEN
tmp3 := maxVal3;
ELSIF tmp3 < 0 THEN
tmp3 := 0;
END;
lineBuf[w] := SYSTEM.VAL(LONGINT,
SYSTEM.VAL(SET, SYSTEM.LSH(tmp0, 24))
+ SYSTEM.VAL(SET, SYSTEM.LSH(tmp1, 16))
+ SYSTEM.VAL(SET, SYSTEM.LSH(tmp2, 8))
+ SYSTEM.VAL(SET, tmp3));
INC(pos);
END;
INC(pos, rowWrap);
END;
FOR i := offset TO (offset + nconsumer - 1) DO
consumers[i].SetPixels(lineBuf, tileOffX, tileOffY + h, width, 1);
END;
END;
ELSE
status := PROD_FAILED;
EXIT;
END;
END;
IF ~producedOnce THEN
producedOnce := TRUE;
src.FreeNonRebuildResources();
END;
FOR i := offset TO (offset + nconsumer - 1) DO
consumers[i].SetProductionStatus(status);
END;
END ProduceImage;
PROCEDURE GetImgFormat () : LONGINT;
BEGIN
RETURN imgFmt;
END GetImgFormat;
END ImageProducer;
InternalToRaster = PROCEDURE {DELEGATE} (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
RasterImageAdapter* = OBJECT(ImageConsumer)
VAR
img : Raster.Image;
imgFmt : LONGINT;
transform : InternalToRaster;
PROCEDURE &InitNew* (img : Raster.Image);
BEGIN
SELF.img := img;
CASE img.fmt.code OF
| Raster.bgr565 :
transform := SetPixelsRGB565;
| Raster.bgr888 :
transform := SetPixelsRGB888;
| Raster.bgra8888 :
transform := SetPixelsRGBA8888;
ELSE
KernelLog.String("ERROR: Raster image type ");
KernelLog.Int(img.fmt.code, 0);
KernelLog.String(" not supported (yet)");
KernelLog.Ln();
transform := SetPixelsNIL;
END;
END InitNew;
PROCEDURE SetFormat* (fmt : LONGINT);
BEGIN
imgFmt := fmt;
END SetFormat;
PROCEDURE SetPixels*(pixelData : J2KU.LongIntArrayPtr; xOffset, yOffset, width, height : LONGINT);
VAR
len : LONGINT;
BEGIN
len := width * height;
transform(pixelData, xOffset, yOffset, len);
END SetPixels;
PROCEDURE SetPixelsRGB565 (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
VAR
adr: SYSTEM.ADDRESS; int, i : LONGINT;
r, g, b : LONGINT;
BEGIN
adr := img.adr + (img.width*yOffset + xOffset)*2;
FOR i := 0 TO length - 1 DO
IF (SYSTEM.VAL(SET, SYSTEM.LSH(pixelBuf[i], -24)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH) ))# {} THEN
r := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET,SYSTEM.LSH(pixelBuf[i], -16)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH)));
g := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET,SYSTEM.LSH(pixelBuf[i], -8)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH)));
b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, pixelBuf[i]) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH)));
int := SYSTEM.LSH(b, -3) + SYSTEM.LSH(SYSTEM.LSH(g, -2), 5) + SYSTEM.LSH(SYSTEM.LSH(r, -3), 11);
SYSTEM.PUT(adr, CHR(int)); SYSTEM.PUT(adr+1, CHR(SYSTEM.LSH(int, -8)));
END;
INC(adr, 2);
END;
END SetPixelsRGB565;
PROCEDURE SetPixelsRGB888 (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
VAR
adr: SYSTEM.ADDRESS; i : LONGINT;
BEGIN
adr := img.adr + (img.width*yOffset + xOffset)*3;
FOR i := 0 TO length - 1 DO
IF (SYSTEM.VAL(SET, pixelBuf[i]) * {23..31}) # {} THEN
SYSTEM.PUT(adr, CHR(pixelBuf[i]));
SYSTEM.PUT(adr + 1, CHR(SYSTEM.LSH(pixelBuf[i], -8)));
SYSTEM.PUT(adr + 2, CHR(SYSTEM.LSH(pixelBuf[i], -16)));
END;
INC(adr, 3);
END;
END SetPixelsRGB888;
PROCEDURE SetPixelsRGBA8888 (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
VAR
adr: SYSTEM.ADDRESS; i : LONGINT;
BEGIN
adr := img.adr + (img.width*yOffset + xOffset)*4;
FOR i := 0 TO length - 1 DO
SYSTEM.PUT(adr, CHR(pixelBuf[i]));
SYSTEM.PUT(adr + 1, CHR(SYSTEM.LSH(pixelBuf[i], -8)));
SYSTEM.PUT(adr + 2, CHR(SYSTEM.LSH(pixelBuf[i], -16)));
SYSTEM.PUT(adr + 3, CHR(SYSTEM.LSH(pixelBuf[i], -24)));
INC(adr, 4);
END;
END SetPixelsRGBA8888;
PROCEDURE SetPixelsNIL (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
END SetPixelsNIL;
END RasterImageAdapter;
Decoder* = OBJECT(Codecs.ImageDecoder);
VAR
decOpt : J2KU.DecoderOptions;
decSpec : J2KCS.DecoderSpecs;
fr : JP2FileFormatReader;
cr : J2KCS.CodestreamReader;
ed : EntropyDecoder;
roi : ROIDescaler;
deq : Dequantizer;
invDWT : InverseDWT;
invMCT : InverseMCT;
imgProd : ImageProducer;
ready : BOOLEAN;
deliveredOnce : BOOLEAN;
minResDec, minLayDec : LONGINT;
PROCEDURE &InitNew* (decOpt : J2KU.DecoderOptions);
BEGIN
SELF.decOpt := decOpt;
ready := FALSE;
END InitNew;
PROCEDURE Open*(s : Streams.Reader; VAR res : LONGINT);
VAR
imgInfo : J2KCS.ImageInfo;
buffCr : J2KCS.BufferedCodestreamReader;
BEGIN
IF fr = NIL THEN
NEW(fr, s);
IF ~fr.InitError() THEN
IF fr.IsJP2File() THEN
s := fr.GetCodestream();
END;
IF s # NIL THEN
IF decOpt.crOpt.component = J2KCS.BUF_CODESTREAM_READER THEN
NEW(buffCr, decOpt.crOpt, s);
cr := buffCr;
ELSE
NEW(cr, decOpt.crOpt, s);
END;
IF ~cr.InitError() THEN
decSpec := cr.GetDecoderSpecs();
imgInfo := decSpec.GetImageInfo();
NEW(ed, decOpt.edOpt, cr, decSpec);
NEW(roi, decOpt.roiOpt, ed, decSpec);
NEW(deq, decOpt.deqOpt, roi, decSpec);
NEW(invDWT, decOpt.invDWTOpt, deq, decSpec);
NEW(invMCT, decOpt.invMCTOpt, invDWT, decSpec);
NEW(imgProd);
ready := imgProd.InitProduction(invMCT, imgInfo);
END;
END;
END;
ELSE
fr.ReInit(s);
IF ~fr.InitError() THEN
IF fr.IsJP2File() THEN
s := fr.GetCodestream();
END;
IF s # NIL THEN
cr.ReInit(decOpt.crOpt, s);
IF ~cr.InitError() THEN
decSpec := cr.GetDecoderSpecs();
imgInfo := decSpec.GetImageInfo();
ed.ReInit(decOpt.edOpt, cr, decSpec);
roi.ReInit(decOpt.roiOpt, ed, decSpec);
deq.ReInit(decOpt.deqOpt, roi, decSpec);
invDWT.ReInit(decOpt.invDWTOpt, deq, decSpec);
invMCT.ReInit(decOpt.invMCTOpt, invDWT, decSpec);
ready := imgProd.InitProduction(invMCT, imgInfo);
END;
END;
END;
END;
minResDec := 0;
minLayDec := 0;
deliveredOnce := FALSE;
IF ready THEN
res := Codecs.ResOk;
ELSE
res := Codecs.ResFailed;
END;
END Open;
PROCEDURE GetImageInfo*(VAR width, height, format, maxProgressionLevel : LONGINT);
VAR
imgInfo : J2KCS.ImageInfo;
BEGIN
IF ready THEN
imgInfo := decSpec.GetImageInfo();
width := imgInfo.GetImgWidth(0);
height := imgInfo.GetImgHeight(0);
format := imgProd.GetImgFormat();
maxProgressionLevel := decSpec.GetMinNumLayers() - 1;
END;
END GetImageInfo;
PROCEDURE SetProgressionLevel*(progressionLevel: LONGINT);
VAR
dec : LONGINT;
BEGIN
IF ready THEN
dec := decSpec.GetMinNumLayers() - progressionLevel - 1;
DecreaseNumLayers(dec);
END;
END SetProgressionLevel;
PROCEDURE Render*(img : Raster.Image);
VAR
imgConsumerArr : ARRAY 1 OF ImageConsumer;
imgAdapt : RasterImageAdapter;
BEGIN
IF ready THEN
NEW(imgAdapt, img);
imgConsumerArr[0] := imgAdapt;
imgProd.ProduceImage(imgConsumerArr, 0, 1);
deliveredOnce := TRUE;
ELSE
KernelLog.String("ERROR (Decoder.Render) : Cannot render image because initializing image production failed");
KernelLog.Ln();
END;
END Render;
PROCEDURE DeliverImage* (VAR consumers : ARRAY OF ImageConsumer; offset, nconsumer : LONGINT);
BEGIN
IF ready THEN
imgProd.ProduceImage(consumers, offset, nconsumer);
deliveredOnce := TRUE;
ELSE
KernelLog.String("ERROR (Decoder.DeliverImage) : Cannot deliver image because initializing image production failed");
KernelLog.Ln();
END;
END DeliverImage;
PROCEDURE CloseStream*;
BEGIN
decSpec := NIL;
fr.FreeResources();
cr.FreeResources();
ed.FreeResources();
roi.FreeResources();
deq.FreeResources();
invDWT.FreeResources();
invMCT.FreeResources();
ready := FALSE;
END CloseStream;
PROCEDURE GetNumResolutionLevels* () : LONGINT;
BEGIN
IF ready THEN
RETURN decSpec.GetImgMinDecLevels() + 1;
ELSE
RETURN 0;
END;
END GetNumResolutionLevels;
PROCEDURE MinDecreaseResolutionLevel* (minResDec : LONGINT);
VAR
ndec, curStartLvl, curEndLvl : LONGINT;
BEGIN
IF ready THEN
IF ~deliveredOnce THEN
ndec := decSpec.GetImgMinDecLevels();
IF minResDec < 0 THEN
SELF.minResDec := 0;
ELSIF minResDec <= ndec THEN
SELF.minResDec := minResDec;
ELSE
KernelLog.String("WARNING (Decoder.MinDecreaseResolutionLevel): ");
KernelLog.String("Cannot decrease resolution level by ");
KernelLog.Int(minResDec, 0);
KernelLog.String(". Image has only ");
KernelLog.Int(ndec + 1, 0);
KernelLog.String(" resolution levels.");
KernelLog.Ln();
SELF.minResDec := ndec;
END;
invMCT.SetMaxDecLevelRange(MAX(LONGINT), SELF.minResDec);
invMCT.GetDecLevelRange(curStartLvl, curEndLvl);
IF curEndLvl < SELF.minResDec THEN
invMCT.SetDecLevelRange(curStartLvl, SELF.minResDec);
END;
ELSE
KernelLog.String("WARNING (Decoder.MinDecreaseResolutionLevel): ");
KernelLog.String("Procedure called after first image reconstruction -> won't change current value");
KernelLog.Ln();
END;
END;
END MinDecreaseResolutionLevel;
PROCEDURE DecreaseResolutionLevel* (resDec : LONGINT);
VAR
ndec, dec : LONGINT;
BEGIN
IF ready THEN
ndec := decSpec.GetImgMinDecLevels();
IF resDec < minResDec THEN
KernelLog.String("WARNING (Decoder.DecreaseResolutionLevel): ");
KernelLog.String("Cannot decrease resolution level only by ");
KernelLog.Int(resDec, 0);
KernelLog.String(". Res. level has to be decreased by at least ");
KernelLog.Int(minResDec, 0);
KernelLog.String(".");
KernelLog.Ln();
dec := minResDec;
ELSIF resDec <= ndec THEN
dec := resDec;
ELSE
KernelLog.String("WARNING (Decoder.DecreaseResolutionLevel): ");
KernelLog.String("Cannot decrease resolution level by ");
KernelLog.Int(resDec, 0);
KernelLog.String(". Image has only ");
KernelLog.Int(ndec + 1, 0);
KernelLog.String(" resolution levels.");
KernelLog.Ln();
dec := ndec;
END;
invMCT.SetDecLevelRange(MAX(LONGINT), dec);
END;
END DecreaseResolutionLevel;
PROCEDURE GetCurrentDecompositionLevel* () : LONGINT;
VAR
decLvl, minNumDecLvls, dummy : LONGINT;
BEGIN
IF ready THEN
invMCT.GetDecLevelRange(dummy, decLvl);
minNumDecLvls := decSpec.GetImgMinDecLevels();
IF decLvl > minNumDecLvls THEN
RETURN minNumDecLvls;
ELSE
RETURN decLvl;
END;
ELSE
RETURN -1;
END;
END GetCurrentDecompositionLevel;
PROCEDURE GetNumLayers* () : LONGINT;
BEGIN
IF ready THEN
RETURN decSpec.GetMinNumLayers();
ELSE
RETURN 0;
END;
END GetNumLayers;
PROCEDURE MinDecreaseNumLayers* (minLayers : LONGINT);
VAR
maxlayer, maxEndLayer, curStartLayer, curEndLayer : LONGINT;
BEGIN
IF ready THEN
IF ~deliveredOnce THEN
maxlayer := decSpec.GetMinNumLayers() - 1;
IF minLayers < 0 THEN
SELF.minLayDec := 0;
ELSIF minLayers <= maxlayer THEN
SELF.minLayDec := minLayers;
ELSE
KernelLog.String("WARNING (Decoder.MinDecreaseNumLayers): ");
KernelLog.String("Cannot decrease number of layers by ");
KernelLog.Int(minLayers, 0);
KernelLog.String(". Image has only ");
KernelLog.Int(maxlayer + 1, 0);
KernelLog.String(" layers.");
KernelLog.Ln();
SELF.minLayDec := maxlayer;
END;
maxEndLayer := maxlayer - SELF.minLayDec;
invMCT.SetMaxLayerRange(0, maxEndLayer);
invMCT.GetLayerRange(curStartLayer, curEndLayer);
IF curEndLayer > maxEndLayer THEN
invMCT.SetLayerRange(curStartLayer, maxEndLayer);
END;
ELSE
KernelLog.String("WARNING (Decoder.MinDecreaseNumLayers): ");
KernelLog.String("Procedure called after first image reconstruction -> won't change current value");
KernelLog.Ln();
END;
END;
END MinDecreaseNumLayers;
PROCEDURE DecreaseNumLayers* (layers : LONGINT);
VAR
maxlayer, dec : LONGINT;
BEGIN
IF ready THEN
maxlayer := decSpec.GetMinNumLayers() - 1;
IF layers < minLayDec THEN
KernelLog.String("WARNING (Decoder.DecreaseNumLayers): ");
KernelLog.String("Cannot decrease number of layers only by ");
KernelLog.Int(layers, 0);
KernelLog.String(". Num. of layers has to be decreased by at least ");
KernelLog.Int(minLayDec, 0);
KernelLog.String(".");
KernelLog.Ln();
dec := minLayDec;
ELSIF layers <= maxlayer THEN
dec := layers;
ELSE
KernelLog.String("WARNING (Decoder.DecreaseNumLayers): ");
KernelLog.String("Cannot decrease number of layers by ");
KernelLog.Int(layers, 0);
KernelLog.String(". Image has only ");
KernelLog.Int(maxlayer + 1, 0);
KernelLog.String(" layers.");
KernelLog.Ln();
dec := maxlayer;
END;
invMCT.SetLayerRange(0, maxlayer - dec);
END;
END DecreaseNumLayers;
PROCEDURE GetCurrentNumLayers* () : LONGINT;
VAR
minNumLayers, curNumLayers, maxLayer, dummy : LONGINT;
BEGIN
IF ready THEN
invMCT.GetLayerRange(dummy, maxLayer);
curNumLayers := maxLayer + 1;
minNumLayers := decSpec.GetMinNumLayers();
IF curNumLayers > minNumLayers THEN
RETURN minNumLayers;
ELSE
RETURN curNumLayers;
END;
ELSE
RETURN -1;
END;
END GetCurrentNumLayers;
PROCEDURE GetNumTiles* () : LONGINT;
VAR
imgInfo : J2KCS.ImageInfo;
BEGIN
IF ready THEN
imgInfo := decSpec.GetImageInfo();
RETURN imgInfo.GetNumTiles();
ELSE
RETURN 0;
END;
END GetNumTiles;
PROCEDURE GetNumComponents* () : LONGINT;
VAR
imgInfo : J2KCS.ImageInfo;
BEGIN
IF ready THEN
imgInfo := decSpec.GetImageInfo();
RETURN imgInfo.GetNumComponents();
ELSE
RETURN 0;
END;
END GetNumComponents;
PROCEDURE GetImageSize* (declevel : LONGINT; VAR width, height : LONGINT);
VAR
imgInfo : J2KCS.ImageInfo;
minDec : LONGINT;
BEGIN
IF ready THEN
imgInfo := decSpec.GetImageInfo();
minDec := decSpec.GetImgMinDecLevels();
IF declevel <= minDec THEN
width := imgInfo.GetImgWidth(declevel);
height := imgInfo.GetImgHeight(declevel);
END;
ELSE
width := -1;
height := -1;
END;
END GetImageSize;
PROCEDURE GetImageFormat* () : LONGINT;
BEGIN
IF ready THEN
RETURN imgProd.GetImgFormat();
ELSE
RETURN -1;
END;
END GetImageFormat;
PROCEDURE GetTileSize* (tile, declevel : LONGINT; VAR toffx, toffy, twidth, theight : LONGINT);
VAR
imgInfo : J2KCS.ImageInfo;
BEGIN
IF ready THEN
imgInfo := decSpec.GetImageInfo();
IF (tile < imgInfo.GetNumTiles()) & (declevel <= decSpec.GetMinDecLevels(tile)) THEN
toffx := imgInfo.GetTileULX(tile, declevel) - imgInfo.GetImgULX(declevel);
toffy := imgInfo.GetTileULY(tile, declevel) - imgInfo.GetImgULX(declevel);
twidth := imgInfo.GetTileWidth(tile, declevel);
theight := imgInfo.GetTileHeight(tile, declevel);
END;
ELSE
toffx := -1;
toffy := -1;
twidth := -1;
theight := -1;
END;
END GetTileSize;
END Decoder;
VAR
filter5x3Lift : FilterSyn5x3Lifting;
filter9x7Lift : FilterSyn9x7Lifting;
ENTROPY_ZEROLL_LUT, ENTROPY_ZEROHL_LUT, ENTROPY_ZEROHH_LUT : J2KU.LongIntArrayPtr;
ENTROPY_SIGN_LUT : ARRAY SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_SIGN_BITS) OF LONGINT;
MQ_INITSTATES, MQ_INITMPS : J2KU.LongIntArrayPtr;
MQPROB, MQNMPS, MQNLPS, MQSWITCH : ARRAY MQTABSIZ OF LONGINT;
PROCEDURE InitEntropyTables;
VAR
i, j : LONGINT;
twoAtLeast : ARRAY 11 OF LONGINT;
threeAtLeast : ARRAY 5 OF LONGINT;
twoBits : ARRAY 6 OF LONGINT;
oneBit : ARRAY 4 OF LONGINT;
h, v, hl, hr, vu, vd, hlsig, hrsig, vusig, vdsig : LONGINT;
tmpSignLut : ARRAY 16 OF LONGINT;
BEGIN
twoAtLeast[0] := 3;
twoAtLeast[1] := 5;
twoAtLeast[2] := 6;
twoAtLeast[3] := 7;
twoAtLeast[4] := 9;
twoAtLeast[5] := 10;
twoAtLeast[6] := 11;
twoAtLeast[7] := 12;
twoAtLeast[8] := 13;
twoAtLeast[9] := 14;
twoAtLeast[10] := 15;
threeAtLeast[0] := 7;
threeAtLeast[1] := 11;
threeAtLeast[2] := 13;
threeAtLeast[3] := 14;
threeAtLeast[4] := 15;
twoBits[0] := 3;
twoBits[1] := 5;
twoBits[2] := 6;
twoBits[3] := 9;
twoBits[4] := 10;
twoBits[5] := 12;
oneBit[0] := 1;
oneBit[1] := 2;
oneBit[2] := 4;
oneBit[3] := 8;
NEW(ENTROPY_ZEROLL_LUT, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS));
NEW(ENTROPY_ZEROHL_LUT, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS));
NEW(ENTROPY_ZEROHH_LUT, SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS));
FOR i := 0 TO 63 DO
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, ENTROPY_SIGHR)) + SYSTEM.VAL(SET, i))] := 8;
END;
FOR i := 1 TO 3 DO
FOR j := 0 TO 15 DO
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, SYSTEM.LSH(i, 4))) + SYSTEM.VAL(SET, j))] := 7;
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHR) + SYSTEM.VAL(SET, SYSTEM.LSH(i, 4))) + SYSTEM.VAL(SET, j))] := 7
END;
END;
FOR i := 1 TO 15 DO
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, i))] := 6;
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHR) + SYSTEM.VAL(SET, i))] := 6;
END;
ENTROPY_ZEROLL_LUT[ENTROPY_SIGHL] := 5;
ENTROPY_ZEROLL_LUT[ENTROPY_SIGHR] := 5;
FOR i := 0 TO 15 DO
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, ENTROPY_SIGVD)) + SYSTEM.VAL(SET, i))] := 4;
END;
FOR i := 0 TO 15 DO
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, i))] := 3;
ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVD) + SYSTEM.VAL(SET, i))] := 3;
END;
FOR i := 0 TO LEN(twoAtLeast) - 1 DO
ENTROPY_ZEROLL_LUT[twoAtLeast[i]] := 2;
END;
FOR i := 0 TO LEN(oneBit) - 1 DO
ENTROPY_ZEROLL_LUT[oneBit[i]] := 1;
END;
ENTROPY_ZEROLL_LUT[0] := 0;
FOR i := 0 TO 3 DO
FOR j := 0 TO 15 DO
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, ENTROPY_SIGVD)) + SYSTEM.VAL(SET, SYSTEM.LSH(i, 6) ) + SYSTEM.VAL(SET, j))] := 8;
END;
END;
FOR i := 1 TO 3 DO
FOR j := 0 TO 15 DO
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, SYSTEM.LSH(i, 6))) + SYSTEM.VAL(SET, j))] := 7;
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVD) + SYSTEM.VAL(SET, SYSTEM.LSH(i, 6))) + SYSTEM.VAL(SET, j))] := 7
END;
END;
FOR i := 1 TO 15 DO
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, i))] := 6;
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVD) + SYSTEM.VAL(SET, i))] := 6;
END;
ENTROPY_ZEROHL_LUT[ENTROPY_SIGVU] := 5;
ENTROPY_ZEROHL_LUT[ENTROPY_SIGVD] := 5;
FOR i := 0 TO 15 DO
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, ENTROPY_SIGHR)) + SYSTEM.VAL(SET, i))] := 4;
END;
FOR i := 0 TO 15 DO
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, i))] := 3;
ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHR) + SYSTEM.VAL(SET, i))] := 3;
END;
FOR i := 0 TO LEN(twoAtLeast) - 1 DO
ENTROPY_ZEROHL_LUT[twoAtLeast[i]] := 2;
END;
FOR i := 0 TO LEN(oneBit) - 1 DO
ENTROPY_ZEROHL_LUT[oneBit[i]] := 1;
END;
ENTROPY_ZEROHL_LUT[0] := 0;
FOR i := 0 TO 15 DO
FOR j := 0 TO LEN(threeAtLeast) - 1 DO
ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, 4)) + SYSTEM.VAL(SET, threeAtLeast[j]))] := 8;
END;
END;
FOR i := 1 TO 15 DO
FOR j := 0 TO LEN(twoBits) - 1 DO
ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, 4)) + SYSTEM.VAL(SET, twoBits[j]))] := 7;
END;
END;
FOR i := 0 TO LEN(twoBits) - 1 DO
ENTROPY_ZEROHH_LUT[twoBits[i]] := 6;
END;
FOR i := 0 TO LEN(twoAtLeast) - 1 DO
FOR j := 0 TO LEN(oneBit) - 1 DO
ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(twoAtLeast[i], 4)) + SYSTEM.VAL(SET, oneBit[j]))] := 5;
END;
END;
FOR i := 0 TO LEN(oneBit) - 1 DO
FOR j := 0 TO LEN(oneBit) - 1 DO
ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(oneBit[i], 4)) + SYSTEM.VAL(SET, oneBit[j]))] := 4;
END;
END;
FOR i := 0 TO LEN(oneBit) - 1 DO
ENTROPY_ZEROHH_LUT[oneBit[i]] := 3;
END;
FOR i := 0 TO LEN(twoAtLeast) - 1 DO
ENTROPY_ZEROHH_LUT[SYSTEM.LSH(twoAtLeast[i], 4)] := 2;
END;
FOR i := 0 TO LEN(oneBit) - 1 DO
ENTROPY_ZEROHH_LUT[SYSTEM.LSH(oneBit[i], 4)] := 1;
END;
ENTROPY_ZEROHH_LUT[0] := 0;
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(2, 2)) + SYSTEM.VAL(SET, 2))] := 13;
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(2, 2)) + SYSTEM.VAL(SET, 1))] := 12;
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(2, 2)) + SYSTEM.VAL(SET, 0))] := 11;
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(1, 2)) + SYSTEM.VAL(SET, 2))] := 10;
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(1, 2)) + SYSTEM.VAL(SET, 1))] := 9;
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(1, 2)) + SYSTEM.VAL(SET, 0))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 10)) + J2KU.LONGINT_SIGN_BIT);
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(0, 2)) + SYSTEM.VAL(SET, 2))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 11)) + J2KU.LONGINT_SIGN_BIT);
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(0, 2)) + SYSTEM.VAL(SET, 1))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 12)) + J2KU.LONGINT_SIGN_BIT);
tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(0, 2)) + SYSTEM.VAL(SET, 0))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 13)) + J2KU.LONGINT_SIGN_BIT);
FOR i := 0 TO SYSTEM.LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_SIGN_BITS) - 1 DO
hlsig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -7)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
hrsig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -6)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
vusig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -5)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
vdsig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -4)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
hl := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -3)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
hr := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -2)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
vu := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(i, -1)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
vd := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, i) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
h := hl * (1 - 2 * hlsig) + hr * (1 - 2 * hrsig);
v := vu * (1 - 2 * vusig) + vd * (1 - 2 * vdsig);
IF h > 1 THEN h := 1; END;
IF h < -1 THEN h := -1; END;
IF v > 1 THEN v := 1; END;
IF v < -1 THEN v := -1 END;
ENTROPY_SIGN_LUT[i] := tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.LSH(h+1, 2)) + SYSTEM.VAL(SET, v+1))]
END;
NEW(MQ_INITSTATES, 19);
NEW(MQ_INITMPS, 19);
MQ_INITSTATES[0] := 4;
MQ_INITMPS[0] := 0;
MQ_INITSTATES[ENTROPY_UNICTX] := 46;
MQ_INITMPS[ENTROPY_UNICTX] := 0;
MQ_INITSTATES[ENTROPY_RUNCTX] := 3;
MQ_INITMPS[ENTROPY_RUNCTX] := 0;
FOR i := 1 TO 16 DO
MQ_INITSTATES[i] := 0;
MQ_INITMPS[i] := 0;
END;
END InitEntropyTables;
PROCEDURE InitMQTables;
BEGIN
MQPROB[0] := 00005601H; MQNMPS[0] := 1; MQNLPS[0] := 1; MQSWITCH[0] := 1;
MQPROB[1] := 00003401H; MQNMPS[1] := 2; MQNLPS[1] := 6; MQSWITCH[1] := 0;
MQPROB[2] := 00001801H; MQNMPS[2] := 3; MQNLPS[2] := 9; MQSWITCH[2] := 0;
MQPROB[3] := 00000AC1H; MQNMPS[3] := 4; MQNLPS[3] := 12; MQSWITCH[3] := 0;
MQPROB[4] := 00000521H; MQNMPS[4] := 5; MQNLPS[4] := 29; MQSWITCH[4] := 0;
MQPROB[5] := 00000221H; MQNMPS[5] := 38; MQNLPS[5] := 33; MQSWITCH[5] := 0;
MQPROB[6] := 00005601H; MQNMPS[6] := 7; MQNLPS[6] := 6; MQSWITCH[6] := 1;
MQPROB[7] := 00005401H; MQNMPS[7] := 8; MQNLPS[7] := 14; MQSWITCH[7] := 0;
MQPROB[8] := 00004801H; MQNMPS[8] := 9; MQNLPS[8] := 14; MQSWITCH[8] := 0;
MQPROB[9] := 00003801H; MQNMPS[9] := 10; MQNLPS[9] := 14; MQSWITCH[9] := 0;
MQPROB[10] := 00003001H; MQNMPS[10] := 11; MQNLPS[10] := 17; MQSWITCH[10] := 0;
MQPROB[11] := 00002401H; MQNMPS[11] := 12; MQNLPS[11] := 18; MQSWITCH[11] := 0;
MQPROB[12] := 00001C01H; MQNMPS[12] := 13; MQNLPS[12] := 20; MQSWITCH[12] := 0;
MQPROB[13] := 00001601H; MQNMPS[13] := 29; MQNLPS[13] := 21; MQSWITCH[13] := 0;
MQPROB[14] := 00005601H; MQNMPS[14] := 15; MQNLPS[14] := 14; MQSWITCH[14] := 1;
MQPROB[15] := 00005401H; MQNMPS[15] := 16; MQNLPS[15] := 14; MQSWITCH[15] := 0;
MQPROB[16] := 00005101H; MQNMPS[16] := 17; MQNLPS[16] := 15; MQSWITCH[16] := 0;
MQPROB[17] := 00004801H; MQNMPS[17] := 18; MQNLPS[17] := 16; MQSWITCH[17] := 0;
MQPROB[18] := 00003801H; MQNMPS[18] := 19; MQNLPS[18] := 17; MQSWITCH[18] := 0;
MQPROB[19] := 00003401H; MQNMPS[19] := 20; MQNLPS[19] := 18; MQSWITCH[19] := 0;
MQPROB[20] := 00003001H; MQNMPS[20] := 21; MQNLPS[20] := 19; MQSWITCH[20] := 0;
MQPROB[21] := 00002801H; MQNMPS[21] := 22; MQNLPS[21] := 19; MQSWITCH[21] := 0;
MQPROB[22] := 00002401H; MQNMPS[22] := 23; MQNLPS[22] := 20; MQSWITCH[22] := 0;
MQPROB[23] := 00002201H; MQNMPS[23] := 24; MQNLPS[23] := 21; MQSWITCH[23] := 0;
MQPROB[24] := 00001C01H; MQNMPS[24] := 25; MQNLPS[24] := 22; MQSWITCH[24] := 0;
MQPROB[25] := 00001801H; MQNMPS[25] := 26; MQNLPS[25] := 23; MQSWITCH[25] := 0;
MQPROB[26] := 00001601H; MQNMPS[26] := 27; MQNLPS[26] := 24; MQSWITCH[26] := 0;
MQPROB[27] := 00001401H; MQNMPS[27] := 28; MQNLPS[27] := 25; MQSWITCH[27] := 0;
MQPROB[28] := 00001201H; MQNMPS[28] := 29; MQNLPS[28] := 26; MQSWITCH[28] := 0;
MQPROB[29] := 00001101H; MQNMPS[29] := 30; MQNLPS[29] := 27; MQSWITCH[29] := 0;
MQPROB[30] := 00000AC1H; MQNMPS[30] := 31; MQNLPS[30] := 28; MQSWITCH[30] := 0;
MQPROB[31] := 000009C1H; MQNMPS[31] := 32; MQNLPS[31] := 29; MQSWITCH[31] := 0;
MQPROB[32] := 000008A1H; MQNMPS[32] := 33; MQNLPS[32] := 30; MQSWITCH[32] := 0;
MQPROB[33] := 00000521H; MQNMPS[33] := 34; MQNLPS[33] := 31; MQSWITCH[33] := 0;
MQPROB[34] := 00000441H; MQNMPS[34] := 35; MQNLPS[34] := 32; MQSWITCH[34] := 0;
MQPROB[35] := 000002A1H; MQNMPS[35] := 36; MQNLPS[35] := 33; MQSWITCH[35] := 0;
MQPROB[36] := 00000221H; MQNMPS[36] := 37; MQNLPS[36] := 34; MQSWITCH[36] := 0;
MQPROB[37] := 00000141H; MQNMPS[37] := 38; MQNLPS[37] := 35; MQSWITCH[37] := 0;
MQPROB[38] := 00000111H; MQNMPS[38] := 39; MQNLPS[38] := 36; MQSWITCH[38] := 0;
MQPROB[39] := 00000085H; MQNMPS[39] := 40; MQNLPS[39] := 37; MQSWITCH[39] := 0;
MQPROB[40] := 00000049H; MQNMPS[40] := 41; MQNLPS[40] := 38; MQSWITCH[40] := 0;
MQPROB[41] := 00000025H; MQNMPS[41] := 42; MQNLPS[41] := 39; MQSWITCH[41] := 0;
MQPROB[42] := 00000015H; MQNMPS[42] := 43; MQNLPS[42] := 40; MQSWITCH[42] := 0;
MQPROB[43] := 00000009H; MQNMPS[43] := 44; MQNLPS[43] := 41; MQSWITCH[43] := 0;
MQPROB[44] := 00000005H; MQNMPS[44] := 45; MQNLPS[44] := 42; MQSWITCH[44] := 0;
MQPROB[45] := 00000001H; MQNMPS[45] := 45; MQNLPS[45] := 43; MQSWITCH[45] := 0;
MQPROB[46] := 00005601H; MQNMPS[46] := 46; MQNLPS[46] := 46; MQSWITCH[46] := 0;
END InitMQTables;
PROCEDURE GetDefaultDecoderOptions* () : J2KU.DecoderOptions;
VAR
decOpt : J2KU.DecoderOptions;
crOpt : J2KU.CodestreamReaderOptions;
edOpt : J2KU.EntropyDecoderOptions;
roiOpt : J2KU.ROIDescalerOptions;
deqOpt : J2KU.DequantizerOptions;
invDWTOpt : J2KU.InverseDWTOptions;
invMCTOpt : J2KU.InverseMCTOptions;
BEGIN
NEW(decOpt);
NEW(crOpt);
crOpt.component := J2KCS.BUF_CODESTREAM_READER;
crOpt.printComments := FALSE;
decOpt.crOpt := crOpt;
NEW(edOpt);
edOpt.component := ENTROPY_DECODER;
edOpt.concealError := FALSE;
decOpt.edOpt := edOpt;
NEW(roiOpt);
roiOpt.component := ROI_DESCALER;
roiOpt.noROI := FALSE;
decOpt.roiOpt := roiOpt;
NEW(deqOpt);
deqOpt.component := DEQUANTIZER;
decOpt.deqOpt := deqOpt;
NEW(invDWTOpt);
invDWTOpt.component := INVERSE_DWT;
invDWTOpt.filterRev := FILTER_5X3_LIFTING;
invDWTOpt.filterIrrev := FILTER_9X7_LIFTING;
decOpt.invDWTOpt := invDWTOpt;
NEW(invMCTOpt);
invMCTOpt.component := INVERSE_MCT;
invMCTOpt.nonRebuildBuffer := TRUE;
decOpt.invMCTOpt := invMCTOpt;
RETURN decOpt;
END GetDefaultDecoderOptions;
PROCEDURE Factory*() : Codecs.ImageDecoder;
VAR
decOpt : J2KU.DecoderOptions;
dec : Decoder;
BEGIN
decOpt := GetDefaultDecoderOptions();
NEW(dec, decOpt);
RETURN dec;
END Factory;
BEGIN
InitEntropyTables();
InitMQTables();
NEW(filter5x3Lift);
NEW(filter9x7Lift);
END JPEG2000Decoder.
SystemTools.Free JPEG2000Decoder~
SystemTools.Free JPEG2000DecoderCS~
SystemTools.Free JPEG2000Util~