Skip to content

Package: Decoder$State

Decoder$State

nameinstructionbranchcomplexitylinemethod
static {...}
M: 44 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.glassfish.grizzly.compression.lzma.impl;
18:
19: import java.io.IOException;
20:
21: import org.glassfish.grizzly.Buffer;
22: import org.glassfish.grizzly.compression.lzma.LZMADecoder;
23: import org.glassfish.grizzly.compression.lzma.LZMADecoder.LZMAInputState;
24: import org.glassfish.grizzly.compression.lzma.impl.lz.OutWindow;
25: import org.glassfish.grizzly.compression.lzma.impl.rangecoder.BitTreeDecoder;
26: import org.glassfish.grizzly.compression.lzma.impl.rangecoder.RangeDecoder;
27:
28: /**
29: * RangeDecoder
30: *
31: * @author Igor Pavlov
32: */
33: public class Decoder {
34:
35: public enum State {
36: ERR, NEED_MORE_DATA, DONE, CONTINUE // internal only
37: }
38:
39: static class LenDecoder {
40:
41: final short[] m_Choice = new short[2];
42: final BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
43: final BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
44: final BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
45: int m_NumPosStates = 0;
46:
47: public void create(int numPosStates) {
48: for (; m_NumPosStates < numPosStates; m_NumPosStates++) {
49: m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
50: m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
51: }
52: }
53:
54: public void init() {
55: decodeMethodState = 0;
56:
57: RangeDecoder.initBitModels(m_Choice);
58: for (int posState = 0; posState < m_NumPosStates; posState++) {
59: m_LowCoder[posState].init();
60: m_MidCoder[posState].init();
61: }
62: m_HighCoder.init();
63: }
64:
65: private int decodeMethodState;
66:
67: public boolean decode(LZMADecoder.LZMAInputState decoderState, RangeDecoder rangeDecoder, int posState) throws IOException {
68: do {
69: switch (decodeMethodState) {
70: case 0: {
71: if (!rangeDecoder.decodeBit(decoderState, m_Choice, 0)) {
72: return false;
73: }
74:
75: decodeMethodState = decoderState.lastMethodResult == 0 ? 1 : 2;
76: continue;
77: }
78: case 1: {
79: if (!m_LowCoder[posState].decode(decoderState, rangeDecoder)) {
80: return false;
81: }
82:
83: // using last result from m_LowCoder[posState].decode(...)
84: decodeMethodState = 5;
85: continue;
86: }
87: case 2: {
88: if (!rangeDecoder.decodeBit(decoderState, m_Choice, 1)) {
89: return false;
90: }
91: decodeMethodState = decoderState.lastMethodResult == 0 ? 3 : 4;
92: continue;
93: }
94: case 3: {
95: if (!m_MidCoder[posState].decode(decoderState, rangeDecoder)) {
96: return false;
97: }
98:
99: decoderState.lastMethodResult += Base.kNumLowLenSymbols;
100:
101: decodeMethodState = 5;
102: continue;
103: }
104: case 4: {
105: if (!m_HighCoder.decode(decoderState, rangeDecoder)) {
106: return false;
107: }
108:
109: decoderState.lastMethodResult += Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
110: decodeMethodState = 5;
111: continue;
112: }
113: case 5: {
114: decodeMethodState = 0;
115: return true;
116: }
117: }
118: } while (true);
119: }
120: }
121:
122: public static class LiteralDecoder {
123:
124: public static class Decoder2 {
125:
126: final short[] m_Decoders = new short[0x300];
127: int decodeNormalMethodState;
128: int decodeWithMatchByteMethodState;
129: int symbol;
130: int matchBit;
131: byte matchByte;
132:
133: public void init() {
134: decodeNormalMethodState = 0;
135: decodeWithMatchByteMethodState = 0;
136: RangeDecoder.initBitModels(m_Decoders);
137: }
138:
139: public boolean decodeNormal(LZMADecoder.LZMAInputState decoderState, RangeDecoder rangeDecoder) throws IOException {
140:
141: do {
142: switch (decodeNormalMethodState) {
143: case 0: {
144: symbol = 1;
145: decodeNormalMethodState = 1;
146: }
147: case 1: {
148: if (!rangeDecoder.decodeBit(decoderState, m_Decoders, symbol)) {
149: return false;
150: }
151:
152: symbol = symbol << 1 | decoderState.lastMethodResult;
153:
154: if (symbol >= 0x100) {
155: decodeNormalMethodState = 0;
156: decoderState.lastMethodResult = symbol;
157: return true;
158: }
159: }
160: }
161: } while (true);
162: }
163:
164: public boolean decodeWithMatchByte(LZMADecoder.LZMAInputState decoderState, RangeDecoder rangeDecoder, byte matchByteParam) throws IOException {
165:
166: do {
167: switch (decodeWithMatchByteMethodState) {
168: case 0: {
169: symbol = 1;
170: this.matchByte = matchByteParam;
171: // decodeWithMatchByteMethodState = 1;
172: }
173: case 1: {
174: matchBit = matchByte >> 7 & 1;
175: matchByte <<= 1;
176: decodeWithMatchByteMethodState = 2;
177: }
178: case 2: {
179: if (!rangeDecoder.decodeBit(decoderState, m_Decoders, (1 + matchBit << 8) + symbol)) {
180: return false;
181: }
182:
183: final int bit = decoderState.lastMethodResult;
184: symbol = symbol << 1 | bit;
185: if (matchBit == bit) {
186: if (symbol >= 0x100) { // outter while(symbol < 0x100)
187: decodeWithMatchByteMethodState = 4; // break
188: continue;
189: }
190:
191: // loop
192: decodeWithMatchByteMethodState = 1;
193: continue;
194: }
195:
196: decodeWithMatchByteMethodState = 3;
197: }
198: case 3: {
199: if (symbol >= 0x100) { // inner while(symbol < 0x100)
200: decodeWithMatchByteMethodState = 4; // break
201: continue;
202: }
203:
204: if (!rangeDecoder.decodeBit(decoderState, m_Decoders, symbol)) {
205: return false;
206: }
207:
208: symbol = symbol << 1 | decoderState.lastMethodResult;
209: continue;
210: }
211:
212: case 4: {
213: decodeWithMatchByteMethodState = 0;
214: decoderState.lastMethodResult = symbol;
215: return true;
216: }
217: }
218: } while (true);
219: }
220: }
221:
222: Decoder2[] m_Coders;
223: int m_NumPrevBits;
224: int m_NumPosBits;
225: int m_PosMask;
226:
227: public void create(int numPosBits, int numPrevBits) {
228: if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) {
229: return;
230: }
231: m_NumPosBits = numPosBits;
232: m_PosMask = (1 << numPosBits) - 1;
233: m_NumPrevBits = numPrevBits;
234: int numStates = 1 << m_NumPrevBits + m_NumPosBits;
235: m_Coders = new Decoder2[numStates];
236: for (int i = 0; i < numStates; i++) {
237: m_Coders[i] = new Decoder2();
238: }
239: }
240:
241: public void init() {
242: int numStates = 1 << m_NumPrevBits + m_NumPosBits;
243: for (int i = 0; i < numStates; i++) {
244: m_Coders[i].init();
245: }
246: }
247:
248: Decoder2 getDecoder(int pos, byte prevByte) {
249: return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> 8 - m_NumPrevBits)];
250: }
251: }
252:
253: final OutWindow m_OutWindow = new OutWindow();
254: final RangeDecoder m_RangeDecoder = new RangeDecoder();
255: final short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
256: final short[] m_IsRepDecoders = new short[Base.kNumStates];
257: final short[] m_IsRepG0Decoders = new short[Base.kNumStates];
258: final short[] m_IsRepG1Decoders = new short[Base.kNumStates];
259: final short[] m_IsRepG2Decoders = new short[Base.kNumStates];
260: final short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
261: final BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
262: final short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
263: final BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
264: final LenDecoder m_LenDecoder = new LenDecoder();
265: final LenDecoder m_RepLenDecoder = new LenDecoder();
266: final LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
267: int m_DictionarySize = -1;
268: int m_DictionarySizeCheck = -1;
269: int m_PosStateMask;
270:
271: public Decoder() {
272: for (int i = 0; i < Base.kNumLenToPosStates; i++) {
273: m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
274: }
275: }
276:
277: public boolean setDecoderProperties(byte[] properties) {
278: if (properties.length < 5) {
279: return false;
280: }
281: int val = properties[0] & 0xFF;
282: int lc = val % 9;
283: int remainder = val / 9;
284: int lp = remainder % 5;
285: int pb = remainder / 5;
286: int dictionarySize = 0;
287: for (int i = 0; i < 4; i++) {
288: dictionarySize += (properties[1 + i] & 0xFF) << i * 8;
289: }
290: return setLcLpPb(lc, lp, pb) && setDictionarySize(dictionarySize);
291: }
292:
293: boolean setDictionarySize(int dictionarySize) {
294: if (dictionarySize < 0) {
295: return false;
296: }
297: if (m_DictionarySize != dictionarySize) {
298: m_DictionarySize = dictionarySize;
299: m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);
300: m_OutWindow.create(Math.max(m_DictionarySizeCheck, 1 << 12));
301: }
302: return true;
303: }
304:
305: boolean setLcLpPb(int lc, int lp, int pb) {
306: if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax) {
307: return false;
308: }
309: m_LiteralDecoder.create(lp, lc);
310: int numPosStates = 1 << pb;
311: m_LenDecoder.create(numPosStates);
312: m_RepLenDecoder.create(numPosStates);
313: m_PosStateMask = numPosStates - 1;
314: return true;
315: }
316:
317: void init() throws IOException {
318: m_OutWindow.init(false);
319:
320: RangeDecoder.initBitModels(m_IsMatchDecoders);
321: RangeDecoder.initBitModels(m_IsRep0LongDecoders);
322: RangeDecoder.initBitModels(m_IsRepDecoders);
323: RangeDecoder.initBitModels(m_IsRepG0Decoders);
324: RangeDecoder.initBitModels(m_IsRepG1Decoders);
325: RangeDecoder.initBitModels(m_IsRepG2Decoders);
326: RangeDecoder.initBitModels(m_PosDecoders);
327:
328: m_LiteralDecoder.init();
329: int i;
330: for (i = 0; i < Base.kNumLenToPosStates; i++) {
331: m_PosSlotDecoder[i].init();
332: }
333: m_LenDecoder.init();
334: m_RepLenDecoder.init();
335: m_PosAlignDecoder.init();
336: m_RangeDecoder.init();
337: }
338:
339: public State code(LZMADecoder.LZMAInputState decoderState, long outSize) throws IOException {
340: // Init();
341: final Buffer inputBuffer = decoderState.getSrc();
342: m_RangeDecoder.initFromState(decoderState);
343: m_OutWindow.initFromState(decoderState);
344: if (!decoderState.isInitialized()) {
345: if (inputBuffer.remaining() < 13) {
346: return State.NEED_MORE_DATA;
347: }
348:
349: decoderState.initialize(inputBuffer);
350: init();
351: }
352:
353: // final RangeDecoder m_RangeDecoder = decoderState.m_RangeDecoder;
354: // final OutWindow m_OutWindow = decoderState.m_OutWindow;
355: //
356:
357: // int state = Base.StateInit();
358: // int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
359: //
360: // long nowPos64 = 0;
361: // byte prevByte = 0;
362: _outter: while (true) {
363: switch (decoderState.inner1State) {
364: case 0: {
365: if (outSize >= 0 && decoderState.nowPos64 >= outSize) {
366: break _outter;
367: }
368: decoderState.inner1State = 1;
369: }
370:
371: case 1: {
372: decoderState.posState = (int) decoderState.nowPos64 & m_PosStateMask;
373: if (!m_RangeDecoder.decodeBit(decoderState, m_IsMatchDecoders, (decoderState.state << Base.kNumPosStatesBitsMax) + decoderState.posState)) {
374: return State.NEED_MORE_DATA;
375:
376: }
377:
378: final int result = decoderState.lastMethodResult;
379: decoderState.inner1State = result == 0 ? 2 : 3;
380: break;
381: }
382:
383: case 2: {
384: if (!processState2(decoderState)) {
385: return State.NEED_MORE_DATA;
386: }
387: decoderState.inner1State = 0;
388: break;
389: }
390:
391: case 3: {
392: final State internalState = processState3(decoderState);
393: if (internalState == State.NEED_MORE_DATA || internalState == State.ERR) {
394: return internalState;
395: }
396:
397: decoderState.inner1State = 0;
398:
399: if (internalState == State.DONE) {
400: break _outter;
401: }
402: }
403: }
404: }
405:
406: m_OutWindow.flush();
407: m_OutWindow.releaseBuffer();
408: m_RangeDecoder.releaseBuffer();
409: return State.DONE;
410: }
411:
412: private boolean processState2(final LZMADecoder.LZMAInputState decoderState) throws IOException {
413: do {
414: switch (decoderState.inner2State) {
415: case 0: {
416: decoderState.decoder2 = m_LiteralDecoder.getDecoder((int) decoderState.nowPos64, decoderState.prevByte);
417: decoderState.inner2State = !Base.stateIsCharState(decoderState.state) ? 1 : 2;
418: continue;
419: }
420:
421: case 1: {
422: if (!decoderState.decoder2.decodeWithMatchByte(decoderState, m_RangeDecoder, m_OutWindow.getByte(decoderState.rep0))) {
423: return false;
424: }
425: decoderState.prevByte = (byte) decoderState.lastMethodResult;
426: decoderState.inner2State = 3;
427: continue;
428: }
429: case 2: {
430: if (!decoderState.decoder2.decodeNormal(decoderState, m_RangeDecoder)) {
431: return false;
432: }
433:
434: decoderState.prevByte = (byte) decoderState.lastMethodResult;
435: decoderState.inner2State = 3;
436: }
437: case 3: {
438: // if (!decoderState.decoder2.decodeNormal(
439: // decoderState, m_RangeDecoder)) {
440: // return false;
441: // }
442: // decoderState.prevByte = (byte) decoderState.lastMethodResult;
443: m_OutWindow.putByte(decoderState.prevByte);
444: decoderState.state = Base.stateUpdateChar(decoderState.state);
445: decoderState.nowPos64++;
446:
447: decoderState.inner2State = 0;
448:
449: return true;
450: }
451: }
452: } while (true);
453: }
454:
455: private State processState3(final LZMADecoder.LZMAInputState decoderState) throws IOException {
456: // int len;
457:
458: do {
459: switch (decoderState.inner2State) {
460: case 0: {
461: if (!m_RangeDecoder.decodeBit(decoderState, m_IsRepDecoders, decoderState.state)) {
462: return State.NEED_MORE_DATA;
463: }
464: decoderState.inner2State = decoderState.lastMethodResult == 1 ? 1 : 2;
465: continue;
466: }
467:
468: case 1: {
469: if (!processState31(decoderState)) {
470: return State.NEED_MORE_DATA;
471: }
472:
473: decoderState.inner2State = 3;
474: continue;
475: }
476: case 2: {
477: final State internalResult = processState32(decoderState);
478: if (internalResult != State.CONTINUE) {
479: return internalResult;
480: }
481:
482: decoderState.inner2State = 3;
483: }
484: case 3: {
485: if (decoderState.rep0 >= decoderState.nowPos64 || decoderState.rep0 >= m_DictionarySizeCheck) {
486: // m_OutWindow.Flush();
487: return State.ERR;
488: }
489: m_OutWindow.copyBlock(decoderState.rep0, decoderState.state3Len);
490: decoderState.nowPos64 += decoderState.state3Len;
491: decoderState.prevByte = m_OutWindow.getByte(0);
492:
493: decoderState.inner2State = 0;
494: return State.CONTINUE;
495: }
496:
497: }
498: } while (true);
499: }
500:
501: private boolean processState31(final LZMAInputState decoderState) throws IOException {
502: do {
503: switch (decoderState.state31) {
504: case 0: {
505: decoderState.state3Len = 0;
506:
507: if (!m_RangeDecoder.decodeBit(decoderState, m_IsRepG0Decoders, decoderState.state)) {
508: return false;
509: }
510:
511: decoderState.state31 = decoderState.lastMethodResult == 0 ? 1 : 2;
512: continue;
513: }
514:
515: case 1: {
516: if (!m_RangeDecoder.decodeBit(decoderState, m_IsRep0LongDecoders, (decoderState.state << Base.kNumPosStatesBitsMax) + decoderState.posState)) {
517: return false;
518: }
519:
520: if (decoderState.lastMethodResult == 0) {
521: decoderState.state = Base.stateUpdateShortRep(decoderState.state);
522: decoderState.state3Len = 1;
523: }
524:
525: decoderState.state31 = 3;
526: continue;
527: }
528:
529: case 2: {
530: if (!processState311(decoderState)) {
531: return false;
532: }
533:
534: decoderState.state31 = 3;
535: }
536:
537: case 3: {
538: if (decoderState.state3Len != 0) {
539: decoderState.state31 = 0;
540: return true;
541: }
542: decoderState.state31 = 4;
543: }
544: case 4: {
545: if (!m_RepLenDecoder.decode(decoderState, m_RangeDecoder, decoderState.posState)) {
546: return false;
547: }
548:
549: decoderState.state3Len = decoderState.lastMethodResult + Base.kMatchMinLen;
550: decoderState.state = Base.stateUpdateRep(decoderState.state);
551:
552: decoderState.state31 = 0;
553: return true;
554: }
555: }
556: } while (true);
557: }
558:
559: private boolean processState311(final LZMAInputState decoderState) throws IOException {
560: do {
561: switch (decoderState.state311) {
562: case 0: {
563: if (!m_RangeDecoder.decodeBit(decoderState, m_IsRepG1Decoders, decoderState.state)) {
564: return false;
565: }
566:
567: decoderState.state311 = decoderState.lastMethodResult == 0 ? 1 : 2;
568: continue;
569: }
570:
571: case 1: {
572: decoderState.state311Distance = decoderState.rep1;
573: decoderState.state311 = 3;
574: continue;
575: }
576:
577: case 2: {
578: if (!m_RangeDecoder.decodeBit(decoderState, m_IsRepG2Decoders, decoderState.state)) {
579: return false;
580: }
581:
582: if (decoderState.lastMethodResult == 0) {
583: decoderState.state311Distance = decoderState.rep2;
584: } else {
585: decoderState.state311Distance = decoderState.rep3;
586: decoderState.rep3 = decoderState.rep2;
587: }
588:
589: decoderState.rep2 = decoderState.rep1;
590: }
591:
592: case 3: {
593: decoderState.rep1 = decoderState.rep0;
594: decoderState.rep0 = decoderState.state311Distance;
595: decoderState.state311 = 0;
596: return true;
597: }
598: }
599: } while (true);
600: }
601:
602: private State processState32(final LZMAInputState decoderState) throws IOException {
603: do {
604: switch (decoderState.state32) {
605: case 0: {
606: decoderState.rep3 = decoderState.rep2;
607: decoderState.rep2 = decoderState.rep1;
608: decoderState.rep1 = decoderState.rep0;
609: decoderState.state32 = 1;
610: }
611: case 1: {
612: if (!m_LenDecoder.decode(decoderState, m_RangeDecoder, decoderState.posState)) {
613: return State.NEED_MORE_DATA;
614: }
615:
616: decoderState.state3Len = Base.kMatchMinLen + decoderState.lastMethodResult;
617: decoderState.state = Base.stateUpdateMatch(decoderState.state);
618:
619: decoderState.state32 = 2;
620: }
621: case 2: {
622: if (!m_PosSlotDecoder[Base.getLenToPosState(decoderState.state3Len)].decode(decoderState, m_RangeDecoder)) {
623: return State.NEED_MORE_DATA;
624: }
625:
626: decoderState.state32PosSlot = decoderState.lastMethodResult;
627: decoderState.state32 = decoderState.state32PosSlot >= Base.kStartPosModelIndex ? 3 : 4;
628: continue;
629: }
630: case 3: {
631: final State localState = processState321(decoderState);
632: if (localState == State.CONTINUE) {
633: decoderState.state32 = 0;
634: }
635:
636: return localState;
637: }
638: case 4: {
639: decoderState.rep0 = decoderState.state32PosSlot;
640: decoderState.state32 = 0;
641: return State.CONTINUE;
642: }
643: }
644: } while (true);
645: }
646:
647: private State processState321(final LZMAInputState decoderState) throws IOException {
648: do {
649: switch (decoderState.state321) {
650: case 0: {
651: decoderState.state321NumDirectBits = (decoderState.state32PosSlot >> 1) - 1;
652: decoderState.rep0 = (2 | decoderState.state32PosSlot & 1) << decoderState.state321NumDirectBits;
653: decoderState.state321 = decoderState.state32PosSlot < Base.kEndPosModelIndex ? 1 : 2;
654: continue;
655: }
656: case 1: {
657: if (!BitTreeDecoder.reverseDecode(decoderState, m_PosDecoders, decoderState.rep0 - decoderState.state32PosSlot - 1, m_RangeDecoder,
658: decoderState.state321NumDirectBits)) {
659: return State.NEED_MORE_DATA;
660: }
661:
662: decoderState.rep0 += decoderState.lastMethodResult;
663: decoderState.state321 = 0;
664: return State.CONTINUE;
665: }
666:
667: case 2: {
668: if (!m_RangeDecoder.decodeDirectBits(decoderState, decoderState.state321NumDirectBits - Base.kNumAlignBits)) {
669: return State.NEED_MORE_DATA;
670: }
671:
672: decoderState.rep0 += decoderState.lastMethodResult << Base.kNumAlignBits;
673: decoderState.state321 = 3;
674: continue;
675: }
676: case 3: {
677: if (!m_PosAlignDecoder.reverseDecode(decoderState, m_RangeDecoder)) {
678: return State.NEED_MORE_DATA;
679: }
680:
681: decoderState.rep0 += decoderState.lastMethodResult;
682:
683: decoderState.state321 = 0;
684:
685: if (decoderState.rep0 < 0) {
686: if (decoderState.rep0 == -1) {
687: return State.DONE;
688: }
689:
690: return State.ERR;
691: }
692: return State.CONTINUE;
693: }
694: }
695: } while (true);
696: }
697: }