1. /*
  2. * @(#)RLEUtilities.java 1.3 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * @(#)Utilities.java 1.1 98/07/31
  9. *
  10. * (C) Copyright IBM Corp. 1998 - All Rights Reserved
  11. */
  12. package javax.swing.text;
  13. /*
  14. * simple run-length-encoding of byte arrays
  15. * runs of same value up to 0x7f in length written as 0x80 | count, value
  16. * runs of mixed values up to 0x7f in length written as count, values[count]
  17. */
  18. import java.util.Random;
  19. class RLEUtilities {
  20. static final boolean debug = false;
  21. static byte[] writeRLE(byte[] src) {
  22. // break into runs of similar and dissimilar bytes at runs where three bytes are the same
  23. //
  24. byte[] result = new byte[src.length + (src.length / 0x7e) + 1];
  25. int w = 0;
  26. int p = 0;
  27. while (p < src.length) {
  28. int b0 = src[p];
  29. boolean match = false;
  30. int q = p + 1;
  31. int e = Math.min(src.length, p + 0x7e);
  32. while (q < e) {
  33. if (src[q] == b0) {
  34. ++q;
  35. if (q < e) {
  36. if (src[q] == b0) {
  37. q -= 2;
  38. break;
  39. }
  40. } else {
  41. break;
  42. }
  43. }
  44. b0 = src[q];
  45. ++q;
  46. }
  47. if (q > p) {
  48. int n = q - p;
  49. if (debug) {
  50. System.out.print(p + ": ");
  51. for (int x = p; x < q; ++x) {
  52. System.out.print(Integer.toHexString(src[x]) + " ");
  53. }
  54. System.out.println();
  55. System.out.println(n + " distinct values");
  56. }
  57. result[w++] = (byte)n; // different code
  58. try {
  59. System.arraycopy(src, p, result, w, n);
  60. }
  61. catch (ArrayIndexOutOfBoundsException ex) {
  62. System.out.println("src len: " + src.length + " p: " + p + " res len: " + result.length + " w: " + w + " n: " + n);
  63. throw ex;
  64. }
  65. w += n;
  66. }
  67. if (q >= src.length) break;
  68. p = q;
  69. q = p + 1;
  70. e = Math.min(src.length, p + 0x7e);
  71. int b = src[p];
  72. while (q < e && src[q] == b) ++q;
  73. if (q > p + 2) {
  74. int n = q - p;
  75. if (debug) {
  76. System.out.print(p + ": ");
  77. for (int x = p; x < q; ++x) {
  78. System.out.print(Integer.toHexString(src[x]) + " ");
  79. }
  80. System.out.println();
  81. System.out.println(n + " common values of " + Integer.toHexString(src[p]));
  82. }
  83. result[w++] = (byte)(0x80 | n);
  84. result[w++] = (byte)b;
  85. p = q;
  86. }
  87. }
  88. // System.out.println("rle in: " + src.length + " out: " + w);
  89. byte[] temp = new byte[w];
  90. System.arraycopy(result, 0, temp, 0, w);
  91. return temp;
  92. }
  93. static byte[] readRLE(byte[] src) {
  94. byte[] result = new byte[src.length * 4];
  95. int w = 0;
  96. int p = 0;
  97. while (p < src.length) {
  98. byte code = src[p++];
  99. int count = code & 0x7f;
  100. if (w + count > result.length) {
  101. byte[] temp = new byte[Math.max(w + count, result.length * 2)];
  102. System.arraycopy(result, 0, temp, 0, w);
  103. result = temp;
  104. }
  105. if ((code & 0x80) != 0) { // same
  106. byte val = src[p++];
  107. // System.out.println(w + ": reading " + count + " values of " + Integer.toHexString(val));
  108. while (--count >= 0) {
  109. result[w++] = val;
  110. }
  111. }
  112. else { // distinct
  113. if (debug) {
  114. System.out.print(w + ": reading " + count + " distinct values: ");
  115. for (int i = 0; i < count; i++) {
  116. byte val = src[p+i];
  117. System.out.print(Integer.toHexString(val) + " ");
  118. }
  119. System.out.println();
  120. }
  121. System.arraycopy(src, p, result, w, count);
  122. p += count;
  123. w += count;
  124. }
  125. }
  126. byte[] temp = new byte[w];
  127. System.arraycopy(result, 0, temp, 0, w);
  128. return temp;
  129. }
  130. /*
  131. private static void compareArrays(byte[] olda, byte[] newa) {
  132. if (newa.length != olda.length) {
  133. System.out.println("length mismatch, old: " + olda.length + ", new: " + newa.length);
  134. }
  135. for (int i = 0; i < olda.length; i++) {
  136. if (newa[i] != olda[i]) {
  137. System.out.println("mismatch at: " + i);
  138. break;
  139. }
  140. }
  141. }
  142. public static void main(String[] args) {
  143. Random r = new Random(23);
  144. int inlen = 0;
  145. int outlen = 0;
  146. for (int i = 1; i < 300; ++i) {
  147. System.out.print(".");
  148. byte[] b = new byte[i];
  149. for (int j = 0; j < i; ++j) {
  150. for (int k = 0; k < i;) {
  151. boolean run = (r.nextInt() & 0x1) == 0;
  152. int n = ((r.nextInt() % 0x3f) % (i-k)) + 1;
  153. if (run) {
  154. byte v = (byte)(r.nextInt() % 0xff);
  155. while (--n >= 0) {
  156. b[k++] = v;
  157. }
  158. } else {
  159. while (--n >= 0) {
  160. b[k++] = (byte)(r.nextInt() % 0xff);
  161. }
  162. }
  163. }
  164. byte[] b2 = writeRLE(b);
  165. inlen += b.length;
  166. outlen += b2.length;
  167. compareArrays(b, readRLE(b2));
  168. }
  169. }
  170. System.out.println("inlen: " + inlen + " outlen: " + outlen + " ratio: " + (float)((double)inlen / (double)outlen));
  171. }
  172. */
  173. }