OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [util/] [zip/] [Inflater.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* Inflater.java - Decompress a data stream
2
   Copyright (C) 1999, 2000, 2001, 2003, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package java.util.zip;
39
 
40
/* Written using on-line Java Platform 1.2 API Specification
41
 * and JCL book.
42
 * Believed complete and correct.
43
 */
44
 
45
/**
46
 * Inflater is used to decompress data that has been compressed according
47
 * to the "deflate" standard described in rfc1950.
48
 *
49
 * The usage is as following.  First you have to set some input with
50
 * <code>setInput()</code>, then inflate() it.  If inflate doesn't
51
 * inflate any bytes there may be three reasons:
52
 * <ul>
53
 * <li>needsInput() returns true because the input buffer is empty.
54
 * You have to provide more input with <code>setInput()</code>.
55
 * NOTE: needsInput() also returns true when, the stream is finished.
56
 * </li>
57
 * <li>needsDictionary() returns true, you have to provide a preset
58
 *     dictionary with <code>setDictionary()</code>.</li>
59
 * <li>finished() returns true, the inflater has finished.</li>
60
 * </ul>
61
 * Once the first output byte is produced, a dictionary will not be
62
 * needed at a later stage.
63
 *
64
 * @author John Leuner, Jochen Hoenicke
65
 * @author Tom Tromey
66
 * @date May 17, 1999
67
 * @since JDK 1.1
68
 */
69
public class Inflater
70
{
71
  /* Copy lengths for literal codes 257..285 */
72
  private static final int CPLENS[] =
73
  {
74
    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
75
    35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
76
  };
77
 
78
  /* Extra bits for literal codes 257..285 */
79
  private static final int CPLEXT[] =
80
  {
81
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
82
    3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
83
  };
84
 
85
  /* Copy offsets for distance codes 0..29 */
86
  private static final int CPDIST[] = {
87
    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
88
    257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
89
    8193, 12289, 16385, 24577
90
  };
91
 
92
  /* Extra bits for distance codes */
93
  private static final int CPDEXT[] = {
94
    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
95
    7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
96
    12, 12, 13, 13
97
  };
98
 
99
  /* This are the state in which the inflater can be.  */
100
  private static final int DECODE_HEADER           = 0;
101
  private static final int DECODE_DICT             = 1;
102
  private static final int DECODE_BLOCKS           = 2;
103
  private static final int DECODE_STORED_LEN1      = 3;
104
  private static final int DECODE_STORED_LEN2      = 4;
105
  private static final int DECODE_STORED           = 5;
106
  private static final int DECODE_DYN_HEADER       = 6;
107
  private static final int DECODE_HUFFMAN          = 7;
108
  private static final int DECODE_HUFFMAN_LENBITS  = 8;
109
  private static final int DECODE_HUFFMAN_DIST     = 9;
110
  private static final int DECODE_HUFFMAN_DISTBITS = 10;
111
  private static final int DECODE_CHKSUM           = 11;
112
  private static final int FINISHED                = 12;
113
 
114
  /** This variable contains the current state. */
115
  private int mode;
116
 
117
  /**
118
   * The adler checksum of the dictionary or of the decompressed
119
   * stream, as it is written in the header resp. footer of the
120
   * compressed stream.  <br>
121
   *
122
   * Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
123
   */
124
  private int readAdler;
125
  /**
126
   * The number of bits needed to complete the current state.  This
127
   * is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
128
   * DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.
129
   */
130
  private int neededBits;
131
  private int repLength, repDist;
132
  private int uncomprLen;
133
  /**
134
   * True, if the last block flag was set in the last block of the
135
   * inflated stream.  This means that the stream ends after the
136
   * current block.
137
   */
138
  private boolean isLastBlock;
139
 
140
  /**
141
   * The total number of inflated bytes.
142
   */
143
  private long totalOut;
144
  /**
145
   * The total number of bytes set with setInput().  This is not the
146
   * value returned by getTotalIn(), since this also includes the
147
   * unprocessed input.
148
   */
149
  private long totalIn;
150
  /**
151
   * This variable stores the nowrap flag that was given to the constructor.
152
   * True means, that the inflated stream doesn't contain a header nor the
153
   * checksum in the footer.
154
   */
155
  private boolean nowrap;
156
 
157
  private StreamManipulator input;
158
  private OutputWindow outputWindow;
159
  private InflaterDynHeader dynHeader;
160
  private InflaterHuffmanTree litlenTree, distTree;
161
  private Adler32 adler;
162
 
163
  /**
164
   * Creates a new inflater.
165
   */
166
  public Inflater ()
167
  {
168
    this (false);
169
  }
170
 
171
  /**
172
   * Creates a new inflater.
173
   * @param nowrap true if no header and checksum field appears in the
174
   * stream.  This is used for GZIPed input.  For compatibility with
175
   * Sun JDK you should provide one byte of input more than needed in
176
   * this case.
177
   */
178
  public Inflater (boolean nowrap)
179
  {
180
    this.nowrap = nowrap;
181
    this.adler = new Adler32();
182
    input = new StreamManipulator();
183
    outputWindow = new OutputWindow();
184
    mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
185
  }
186
 
187
  /**
188
   * Finalizes this object.
189
   */
190
  protected void finalize ()
191
  {
192
    /* Exists only for compatibility */
193
  }
194
 
195
  /**
196
   * Frees all objects allocated by the inflater.  There's no reason
197
   * to call this, since you can just rely on garbage collection (even
198
   * for the Sun implementation).  Exists only for compatibility
199
   * with Sun's JDK, where the compressor allocates native memory.
200
   * If you call any method (even reset) afterwards the behaviour is
201
   * <i>undefined</i>.
202
   */
203
  public void end ()
204
  {
205
    outputWindow = null;
206
    input = null;
207
    dynHeader = null;
208
    litlenTree = null;
209
    distTree = null;
210
    adler = null;
211
  }
212
 
213
  /**
214
   * Returns true, if the inflater has finished.  This means, that no
215
   * input is needed and no output can be produced.
216
   */
217
  public boolean finished()
218
  {
219
    return mode == FINISHED && outputWindow.getAvailable() == 0;
220
  }
221
 
222
  /**
223
   * Gets the adler checksum.  This is either the checksum of all
224
   * uncompressed bytes returned by inflate(), or if needsDictionary()
225
   * returns true (and thus no output was yet produced) this is the
226
   * adler checksum of the expected dictionary.
227
   * @returns the adler checksum.
228
   */
229
  public int getAdler()
230
  {
231
    return needsDictionary() ? readAdler : (int) adler.getValue();
232
  }
233
 
234
  /**
235
   * Gets the number of unprocessed input.  Useful, if the end of the
236
   * stream is reached and you want to further process the bytes after
237
   * the deflate stream.
238
   * @return the number of bytes of the input which were not processed.
239
   */
240
  public int getRemaining()
241
  {
242
    return input.getAvailableBytes();
243
  }
244
 
245
  /**
246
   * Gets the total number of processed compressed input bytes.
247
   * @return the total number of bytes of processed input bytes.
248
   */
249
  public int getTotalIn()
250
  {
251
    return (int) (totalIn - getRemaining());
252
  }
253
 
254
  /**
255
   * Gets the total number of processed compressed input bytes.
256
   * @return the total number of bytes of processed input bytes.
257
   * @since 1.5
258
   */
259
  public long getBytesRead()
260
  {
261
    return totalIn - getRemaining();
262
  }
263
 
264
  /**
265
   * Gets the total number of output bytes returned by inflate().
266
   * @return the total number of output bytes.
267
   */
268
  public int getTotalOut()
269
  {
270
    return (int) totalOut;
271
  }
272
 
273
  /**
274
   * Gets the total number of output bytes returned by inflate().
275
   * @return the total number of output bytes.
276
   * @since 1.5
277
   */
278
  public long getBytesWritten()
279
  {
280
    return totalOut;
281
  }
282
 
283
  /**
284
   * Inflates the compressed stream to the output buffer.  If this
285
   * returns 0, you should check, whether needsDictionary(),
286
   * needsInput() or finished() returns true, to determine why no
287
   * further output is produced.
288
   * @param buf the output buffer.
289
   * @return the number of bytes written to the buffer, 0 if no further
290
   * output can be produced.
291
   * @exception DataFormatException if deflated stream is invalid.
292
   * @exception IllegalArgumentException if buf has length 0.
293
   */
294
  public int inflate (byte[] buf) throws DataFormatException
295
  {
296
    return inflate (buf, 0, buf.length);
297
  }
298
 
299
  /**
300
   * Inflates the compressed stream to the output buffer.  If this
301
   * returns 0, you should check, whether needsDictionary(),
302
   * needsInput() or finished() returns true, to determine why no
303
   * further output is produced.
304
   * @param buf the output buffer.
305
   * @param off the offset into buffer where the output should start.
306
   * @param len the maximum length of the output.
307
   * @return the number of bytes written to the buffer, 0 if no further
308
   * output can be produced.
309
   * @exception DataFormatException if deflated stream is invalid.
310
   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
311
   */
312
  public int inflate (byte[] buf, int off, int len) throws DataFormatException
313
  {
314
    /* Check for correct buff, off, len triple */
315
    if (0 > off || off > off + len || off + len > buf.length)
316
      throw new ArrayIndexOutOfBoundsException();
317
    int count = 0;
318
    for (;;)
319
      {
320
        if (outputWindow.getAvailable() == 0)
321
          {
322
            if (!decode())
323
              break;
324
          }
325
        else if (len > 0)
326
          {
327
            int more = outputWindow.copyOutput(buf, off, len);
328
            adler.update(buf, off, more);
329
            off += more;
330
            count += more;
331
            totalOut += more;
332
            len -= more;
333
          }
334
        else
335
          break;
336
      }
337
    return count;
338
  }
339
 
340
  /**
341
   * Returns true, if a preset dictionary is needed to inflate the input.
342
   */
343
  public boolean needsDictionary ()
344
  {
345
    return mode == DECODE_DICT && neededBits == 0;
346
  }
347
 
348
  /**
349
   * Returns true, if the input buffer is empty.
350
   * You should then call setInput(). <br>
351
   *
352
   * <em>NOTE</em>: This method also returns true when the stream is finished.
353
   */
354
  public boolean needsInput ()
355
  {
356
    return input.needsInput ();
357
  }
358
 
359
  /**
360
   * Resets the inflater so that a new stream can be decompressed.  All
361
   * pending input and output will be discarded.
362
   */
363
  public void reset ()
364
  {
365
    mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
366
    totalIn = totalOut = 0;
367
    input.reset();
368
    outputWindow.reset();
369
    dynHeader = null;
370
    litlenTree = null;
371
    distTree = null;
372
    isLastBlock = false;
373
    adler.reset();
374
  }
375
 
376
  /**
377
   * Sets the preset dictionary.  This should only be called, if
378
   * needsDictionary() returns true and it should set the same
379
   * dictionary, that was used for deflating.  The getAdler()
380
   * function returns the checksum of the dictionary needed.
381
   * @param buffer the dictionary.
382
   * @exception IllegalStateException if no dictionary is needed.
383
   * @exception IllegalArgumentException if the dictionary checksum is
384
   * wrong.
385
   */
386
  public void setDictionary (byte[] buffer)
387
  {
388
    setDictionary(buffer, 0, buffer.length);
389
  }
390
 
391
  /**
392
   * Sets the preset dictionary.  This should only be called, if
393
   * needsDictionary() returns true and it should set the same
394
   * dictionary, that was used for deflating.  The getAdler()
395
   * function returns the checksum of the dictionary needed.
396
   * @param buffer the dictionary.
397
   * @param off the offset into buffer where the dictionary starts.
398
   * @param len the length of the dictionary.
399
   * @exception IllegalStateException if no dictionary is needed.
400
   * @exception IllegalArgumentException if the dictionary checksum is
401
   * wrong.
402
   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
403
   */
404
  public void setDictionary (byte[] buffer, int off, int len)
405
  {
406
    if (!needsDictionary())
407
      throw new IllegalStateException();
408
 
409
    adler.update(buffer, off, len);
410
    if ((int) adler.getValue() != readAdler)
411
      throw new IllegalArgumentException("Wrong adler checksum");
412
    adler.reset();
413
    outputWindow.copyDict(buffer, off, len);
414
    mode = DECODE_BLOCKS;
415
  }
416
 
417
  /**
418
   * Sets the input.  This should only be called, if needsInput()
419
   * returns true.
420
   * @param buf the input.
421
   * @exception IllegalStateException if no input is needed.
422
   */
423
  public void setInput (byte[] buf)
424
  {
425
    setInput (buf, 0, buf.length);
426
  }
427
 
428
  /**
429
   * Sets the input.  This should only be called, if needsInput()
430
   * returns true.
431
   * @param buf the input.
432
   * @param off the offset into buffer where the input starts.
433
   * @param len the length of the input.
434
   * @exception IllegalStateException if no input is needed.
435
   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
436
   */
437
  public void setInput (byte[] buf, int off, int len)
438
  {
439
    input.setInput (buf, off, len);
440
    totalIn += len;
441
  }
442
 
443
  /**
444
   * Decodes the deflate header.
445
   * @return false if more input is needed.
446
   * @exception DataFormatException if header is invalid.
447
   */
448
  private boolean decodeHeader () throws DataFormatException
449
  {
450
    int header = input.peekBits(16);
451
    if (header < 0)
452
      return false;
453
    input.dropBits(16);
454
 
455
    /* The header is written in "wrong" byte order */
456
    header = ((header << 8) | (header >> 8)) & 0xffff;
457
    if (header % 31 != 0)
458
      throw new DataFormatException("Header checksum illegal");
459
 
460
    if ((header & 0x0f00) != (Deflater.DEFLATED << 8))
461
      throw new DataFormatException("Compression Method unknown");
462
 
463
    /* Maximum size of the backwards window in bits.
464
     * We currently ignore this, but we could use it to make the
465
     * inflater window more space efficient. On the other hand the
466
     * full window (15 bits) is needed most times, anyway.
467
     int max_wbits = ((header & 0x7000) >> 12) + 8;
468
     */
469
 
470
    if ((header & 0x0020) == 0) // Dictionary flag?
471
      {
472
        mode = DECODE_BLOCKS;
473
      }
474
    else
475
      {
476
        mode = DECODE_DICT;
477
        neededBits = 32;
478
      }
479
    return true;
480
  }
481
 
482
  /**
483
   * Decodes the dictionary checksum after the deflate header.
484
   * @return false if more input is needed.
485
   */
486
  private boolean decodeDict ()
487
  {
488
    while (neededBits > 0)
489
      {
490
        int dictByte = input.peekBits(8);
491
        if (dictByte < 0)
492
          return false;
493
        input.dropBits(8);
494
        readAdler = (readAdler << 8) | dictByte;
495
        neededBits -= 8;
496
      }
497
    return false;
498
  }
499
 
500
  /**
501
   * Decodes the huffman encoded symbols in the input stream.
502
   * @return false if more input is needed, true if output window is
503
   * full or the current block ends.
504
   * @exception DataFormatException if deflated stream is invalid.
505
   */
506
  private boolean decodeHuffman () throws DataFormatException
507
  {
508
    int free = outputWindow.getFreeSpace();
509
    while (free >= 258)
510
      {
511
        int symbol;
512
        switch (mode)
513
          {
514
          case DECODE_HUFFMAN:
515
            /* This is the inner loop so it is optimized a bit */
516
            while (((symbol = litlenTree.getSymbol(input)) & ~0xff) == 0)
517
              {
518
                outputWindow.write(symbol);
519
                if (--free < 258)
520
                  return true;
521
              }
522
            if (symbol < 257)
523
              {
524
                if (symbol < 0)
525
                  return false;
526
                else
527
                  {
528
                    /* symbol == 256: end of block */
529
                    distTree = null;
530
                    litlenTree = null;
531
                    mode = DECODE_BLOCKS;
532
                    return true;
533
                  }
534
              }
535
 
536
            try
537
              {
538
                repLength = CPLENS[symbol - 257];
539
                neededBits = CPLEXT[symbol - 257];
540
              }
541
            catch (ArrayIndexOutOfBoundsException ex)
542
              {
543
                throw new DataFormatException("Illegal rep length code");
544
              }
545
            /* fall through */
546
          case DECODE_HUFFMAN_LENBITS:
547
            if (neededBits > 0)
548
              {
549
                mode = DECODE_HUFFMAN_LENBITS;
550
                int i = input.peekBits(neededBits);
551
                if (i < 0)
552
                  return false;
553
                input.dropBits(neededBits);
554
                repLength += i;
555
              }
556
            mode = DECODE_HUFFMAN_DIST;
557
            /* fall through */
558
          case DECODE_HUFFMAN_DIST:
559
            symbol = distTree.getSymbol(input);
560
            if (symbol < 0)
561
              return false;
562
            try
563
              {
564
                repDist = CPDIST[symbol];
565
                neededBits = CPDEXT[symbol];
566
              }
567
            catch (ArrayIndexOutOfBoundsException ex)
568
              {
569
                throw new DataFormatException("Illegal rep dist code");
570
              }
571
            /* fall through */
572
          case DECODE_HUFFMAN_DISTBITS:
573
            if (neededBits > 0)
574
              {
575
                mode = DECODE_HUFFMAN_DISTBITS;
576
                int i = input.peekBits(neededBits);
577
                if (i < 0)
578
                  return false;
579
                input.dropBits(neededBits);
580
                repDist += i;
581
              }
582
            outputWindow.repeat(repLength, repDist);
583
            free -= repLength;
584
            mode = DECODE_HUFFMAN;
585
            break;
586
          default:
587
            throw new IllegalStateException();
588
          }
589
      }
590
    return true;
591
  }
592
 
593
  /**
594
   * Decodes the adler checksum after the deflate stream.
595
   * @return false if more input is needed.
596
   * @exception DataFormatException if checksum doesn't match.
597
   */
598
  private boolean decodeChksum () throws DataFormatException
599
  {
600
    while (neededBits > 0)
601
      {
602
        int chkByte = input.peekBits(8);
603
        if (chkByte < 0)
604
          return false;
605
        input.dropBits(8);
606
        readAdler = (readAdler << 8) | chkByte;
607
        neededBits -= 8;
608
      }
609
    if ((int) adler.getValue() != readAdler)
610
      throw new DataFormatException("Adler chksum doesn't match: "
611
                                    +Integer.toHexString((int)adler.getValue())
612
                                    +" vs. "+Integer.toHexString(readAdler));
613
    mode = FINISHED;
614
    return false;
615
  }
616
 
617
  /**
618
   * Decodes the deflated stream.
619
   * @return false if more input is needed, or if finished.
620
   * @exception DataFormatException if deflated stream is invalid.
621
   */
622
  private boolean decode () throws DataFormatException
623
  {
624
    switch (mode)
625
      {
626
      case DECODE_HEADER:
627
        return decodeHeader();
628
      case DECODE_DICT:
629
        return decodeDict();
630
      case DECODE_CHKSUM:
631
        return decodeChksum();
632
 
633
      case DECODE_BLOCKS:
634
        if (isLastBlock)
635
          {
636
            if (nowrap)
637
              {
638
                mode = FINISHED;
639
                return false;
640
              }
641
            else
642
              {
643
                input.skipToByteBoundary();
644
                neededBits = 32;
645
                mode = DECODE_CHKSUM;
646
                return true;
647
              }
648
          }
649
 
650
        int type = input.peekBits(3);
651
        if (type < 0)
652
          return false;
653
        input.dropBits(3);
654
 
655
        if ((type & 1) != 0)
656
          isLastBlock = true;
657
        switch (type >> 1)
658
          {
659
          case DeflaterConstants.STORED_BLOCK:
660
            input.skipToByteBoundary();
661
            mode = DECODE_STORED_LEN1;
662
            break;
663
          case DeflaterConstants.STATIC_TREES:
664
            litlenTree = InflaterHuffmanTree.defLitLenTree;
665
            distTree = InflaterHuffmanTree.defDistTree;
666
            mode = DECODE_HUFFMAN;
667
            break;
668
          case DeflaterConstants.DYN_TREES:
669
            dynHeader = new InflaterDynHeader();
670
            mode = DECODE_DYN_HEADER;
671
            break;
672
          default:
673
            throw new DataFormatException("Unknown block type "+type);
674
          }
675
        return true;
676
 
677
      case DECODE_STORED_LEN1:
678
        {
679
          if ((uncomprLen = input.peekBits(16)) < 0)
680
            return false;
681
          input.dropBits(16);
682
          mode = DECODE_STORED_LEN2;
683
        }
684
        /* fall through */
685
      case DECODE_STORED_LEN2:
686
        {
687
          int nlen = input.peekBits(16);
688
          if (nlen < 0)
689
            return false;
690
          input.dropBits(16);
691
          if (nlen != (uncomprLen ^ 0xffff))
692
            throw new DataFormatException("broken uncompressed block");
693
          mode = DECODE_STORED;
694
        }
695
        /* fall through */
696
      case DECODE_STORED:
697
        {
698
          int more = outputWindow.copyStored(input, uncomprLen);
699
          uncomprLen -= more;
700
          if (uncomprLen == 0)
701
            {
702
              mode = DECODE_BLOCKS;
703
              return true;
704
            }
705
          return !input.needsInput();
706
        }
707
 
708
      case DECODE_DYN_HEADER:
709
        if (!dynHeader.decode(input))
710
          return false;
711
        litlenTree = dynHeader.buildLitLenTree();
712
        distTree = dynHeader.buildDistTree();
713
        mode = DECODE_HUFFMAN;
714
        /* fall through */
715
      case DECODE_HUFFMAN:
716
      case DECODE_HUFFMAN_LENBITS:
717
      case DECODE_HUFFMAN_DIST:
718
      case DECODE_HUFFMAN_DISTBITS:
719
        return decodeHuffman();
720
      case FINISHED:
721
        return false;
722
      default:
723
        throw new IllegalStateException();
724
      }
725
  }
726
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.