Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

RunLengthEncodeOutputStream.java 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.util;
  18. import java.io.FilterOutputStream;
  19. import java.io.OutputStream;
  20. import java.io.IOException;
  21. /**
  22. * This class applies a RunLengthEncode filter to the stream.
  23. *
  24. * @author <a href="mailto:smwolke@geistig.com">Stephen Wolke</a>
  25. * @version $Id$
  26. */
  27. public class RunLengthEncodeOutputStream extends FilterOutputStream
  28. implements Finalizable {
  29. private static final int MAX_SEQUENCE_COUNT = 127;
  30. private static final int END_OF_DATA = 128;
  31. private static final int BYTE_MAX = 256;
  32. private static final int NOT_IDENTIFY_SEQUENCE = 0;
  33. private static final int START_SEQUENCE = 1;
  34. private static final int IN_SEQUENCE = 2;
  35. private static final int NOT_IN_SEQUENCE = 3;
  36. private int runCount = 0;
  37. private int isSequence = NOT_IDENTIFY_SEQUENCE;
  38. private byte[] runBuffer = new byte[MAX_SEQUENCE_COUNT + 1];
  39. /** @see java.io.FilterOutputStream **/
  40. public RunLengthEncodeOutputStream(OutputStream out) {
  41. super(out);
  42. }
  43. /** @see java.io.FilterOutputStream **/
  44. public void write(byte b)
  45. throws java.io.IOException {
  46. runBuffer[runCount] = b;
  47. switch (runCount) {
  48. case 0:
  49. runCount = 0;
  50. isSequence = NOT_IDENTIFY_SEQUENCE;
  51. runCount++;
  52. break;
  53. case 1:
  54. if (runBuffer[runCount] != runBuffer[runCount - 1]) {
  55. isSequence = NOT_IN_SEQUENCE;
  56. }
  57. runCount++;
  58. break;
  59. case 2:
  60. if (runBuffer[runCount] != runBuffer[runCount - 1]) {
  61. isSequence = NOT_IN_SEQUENCE;
  62. } else {
  63. if (isSequence == NOT_IN_SEQUENCE) {
  64. isSequence = START_SEQUENCE;
  65. } else {
  66. isSequence = IN_SEQUENCE;
  67. }
  68. }
  69. runCount++;
  70. break;
  71. case MAX_SEQUENCE_COUNT:
  72. if (isSequence == IN_SEQUENCE) {
  73. out.write(BYTE_MAX - (MAX_SEQUENCE_COUNT - 1));
  74. out.write(runBuffer[runCount - 1]);
  75. runBuffer[0] = runBuffer[runCount];
  76. runCount = 1;
  77. } else {
  78. out.write(MAX_SEQUENCE_COUNT);
  79. out.write(runBuffer, 0, runCount + 1);
  80. runCount = 0;
  81. }
  82. isSequence = NOT_IDENTIFY_SEQUENCE;
  83. break;
  84. default:
  85. switch (isSequence) {
  86. case IN_SEQUENCE:
  87. if (runBuffer[runCount] != runBuffer[runCount - 1]) {
  88. out.write(BYTE_MAX - (runCount - 1));
  89. out.write(runBuffer[runCount - 1]);
  90. runBuffer[0] = runBuffer[runCount];
  91. runCount = 1;
  92. isSequence = NOT_IDENTIFY_SEQUENCE;
  93. break;
  94. }
  95. runCount++;
  96. break;
  97. case NOT_IN_SEQUENCE:
  98. if (runBuffer[runCount] == runBuffer[runCount - 1]) {
  99. isSequence = START_SEQUENCE;
  100. }
  101. runCount++;
  102. break;
  103. case START_SEQUENCE:
  104. if (runBuffer[runCount] == runBuffer[runCount - 1]) {
  105. out.write(runCount - 3);
  106. out.write(runBuffer, 0, runCount - 2);
  107. runBuffer[0] = runBuffer[runCount];
  108. runBuffer[1] = runBuffer[runCount];
  109. runBuffer[2] = runBuffer[runCount];
  110. runCount = 3;
  111. isSequence = IN_SEQUENCE;
  112. break;
  113. } else {
  114. isSequence = NOT_IN_SEQUENCE;
  115. runCount++;
  116. break;
  117. }
  118. }
  119. }
  120. }
  121. /** @see java.io.FilterOutputStream **/
  122. public void write(byte[] b)
  123. throws IOException {
  124. for (int i = 0; i < b.length; i++) {
  125. this.write(b[i]);
  126. }
  127. }
  128. /** @see java.io.FilterOutputStream **/
  129. public void write(byte[] b, int off, int len)
  130. throws IOException {
  131. for (int i = 0; i < len; i++) {
  132. this.write(b[off + i]);
  133. }
  134. }
  135. /** @see Finalizable **/
  136. public void finalizeStream()
  137. throws IOException {
  138. switch (isSequence) {
  139. case IN_SEQUENCE:
  140. out.write(BYTE_MAX - (runCount - 1));
  141. out.write(runBuffer[runCount - 1]);
  142. break;
  143. default:
  144. out.write(runCount - 1);
  145. out.write(runBuffer, 0, runCount);
  146. }
  147. out.write(END_OF_DATA);
  148. flush();
  149. if (out instanceof Finalizable) {
  150. ((Finalizable) out).finalizeStream();
  151. }
  152. }
  153. /** @see java.io.FilterOutputStream **/
  154. public void close()
  155. throws IOException {
  156. finalizeStream();
  157. super.close();
  158. }
  159. }