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