1 51 package org.apache.fop.render.ps; 52 53 import java.io.FilterOutputStream ; 54 import java.io.OutputStream ; 55 import java.io.IOException ; 56 57 63 64 public class RunLengthEncodeOutputStream extends FilterOutputStream 65 implements Finalizable { 66 67 private static final int MAX_SEQUENCE_COUNT = 127; 68 private static final int END_OF_DATA = 128; 69 private static final int BYTE_MAX = 256; 70 71 private static final int NOT_IDENTIFY_SEQUENCE = 0; 72 private static final int START_SEQUENCE = 1; 73 private static final int IN_SEQUENCE = 2; 74 private static final int NOT_IN_SEQUENCE = 3; 75 76 private int runCount = 0; 77 private int isSequence = NOT_IDENTIFY_SEQUENCE; 78 private byte[] runBuffer = new byte[MAX_SEQUENCE_COUNT + 1]; 79 80 81 86 public RunLengthEncodeOutputStream(OutputStream out) { 87 super(out); 88 } 89 90 91 98 public void write(byte b) 99 throws java.io.IOException { 100 runBuffer[runCount] = b; 101 102 switch (runCount) { 103 case 0: 104 runCount = 0; 105 isSequence = NOT_IDENTIFY_SEQUENCE; 106 runCount++; 107 break; 108 case 1: 109 if (runBuffer[runCount] != runBuffer[runCount - 1]) { 110 isSequence = NOT_IN_SEQUENCE; 111 } 112 runCount++; 113 break; 114 case 2: 115 if (runBuffer[runCount] != runBuffer[runCount - 1]) { 116 isSequence = NOT_IN_SEQUENCE; 117 } else { 118 if (isSequence == NOT_IN_SEQUENCE) { 119 isSequence = START_SEQUENCE; 120 } else { 121 isSequence = IN_SEQUENCE; 122 } 123 } 124 runCount++; 125 break; 126 case MAX_SEQUENCE_COUNT: 127 if (isSequence == IN_SEQUENCE) { 128 out.write(BYTE_MAX - (MAX_SEQUENCE_COUNT - 1)); 129 out.write(runBuffer[runCount - 1]); 130 runBuffer[0] = runBuffer[runCount]; 131 runCount = 1; 132 } else { 133 out.write(MAX_SEQUENCE_COUNT); 134 out.write(runBuffer, 0, runCount + 1); 135 runCount = 0; 136 } 137 isSequence = NOT_IDENTIFY_SEQUENCE; 138 break; 139 default: 140 switch (isSequence) { 141 case IN_SEQUENCE: 142 if (runBuffer[runCount] != runBuffer[runCount - 1]) { 143 out.write(BYTE_MAX - (runCount - 1)); 144 out.write(runBuffer[runCount - 1]); 145 runBuffer[0] = runBuffer[runCount]; 146 runCount = 1; 147 isSequence = NOT_IDENTIFY_SEQUENCE; 148 break; 149 } 150 runCount++; 151 break; 152 case NOT_IN_SEQUENCE: 153 if (runBuffer[runCount] == runBuffer[runCount - 1]) { 154 isSequence = START_SEQUENCE; 155 } 156 runCount++; 157 break; 158 case START_SEQUENCE: 159 if (runBuffer[runCount] == runBuffer[runCount - 1]) { 160 out.write(runCount - 3); 161 out.write(runBuffer, 0, runCount - 2); 162 runBuffer[0] = runBuffer[runCount]; 163 runBuffer[1] = runBuffer[runCount]; 164 runBuffer[2] = runBuffer[runCount]; 165 runCount = 3; 166 isSequence = IN_SEQUENCE; 167 break; 168 } else { 169 isSequence = NOT_IN_SEQUENCE; 170 runCount++; 171 break; 172 } 173 } 174 } 175 } 176 177 178 183 public void write(byte[] b) 184 throws IOException { 185 186 for (int i = 0; i < b.length; i++) { 187 this.write(b[i]); 188 } 189 } 190 191 192 201 public void write(byte[] b, int off, int len) 202 throws IOException { 203 204 for (int i = 0; i < len; i++) { 205 this.write(b[off + i]); 206 } 207 } 208 209 210 216 public void finalizeStream() 217 throws IOException { 218 switch (isSequence) { 219 case IN_SEQUENCE: 220 out.write(BYTE_MAX - (runCount - 1)); 221 out.write(runBuffer[runCount - 1]); 222 break; 223 default: 224 out.write(runCount - 1); 225 out.write(runBuffer, 0, runCount); 226 } 227 228 out.write(END_OF_DATA); 229 230 flush(); 231 if (out instanceof Finalizable) { 232 ((Finalizable) out).finalizeStream(); 233 } 234 } 235 236 237 242 public void close() 243 throws IOException { 244 finalizeStream(); 245 super.close(); 246 } 247 248 } 249 250 | Popular Tags |