PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/kreative/rsrc/pict/PICTUtilities.java

http://ksfl.googlecode.com/
Java | 787 lines | 738 code | 17 blank | 32 comment | 300 complexity | ff7ad825bf36f8bb6204e35fda012375 MD5 | raw file
Possible License(s): LGPL-3.0
  1. /*
  2. * Copyright © 2009-2011 Rebecca G. Bettencourt / Kreative Software
  3. * <p>
  4. * The contents of this file are subject to the Mozilla Public License
  5. * Version 1.1 (the "License"); you may not use this file except in
  6. * compliance with the License. You may obtain a copy of the License at
  7. * <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
  8. * <p>
  9. * Software distributed under the License is distributed on an "AS IS"
  10. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  11. * License for the specific language governing rights and limitations
  12. * under the License.
  13. * <p>
  14. * Alternatively, the contents of this file may be used under the terms
  15. * of the GNU Lesser General Public License (the "LGPL License"), in which
  16. * case the provisions of LGPL License are applicable instead of those
  17. * above. If you wish to allow use of your version of this file only
  18. * under the terms of the LGPL License and not to allow others to use
  19. * your version of this file under the MPL, indicate your decision by
  20. * deleting the provisions above and replace them with the notice and
  21. * other provisions required by the LGPL License. If you do not delete
  22. * the provisions above, a recipient may use your version of this file
  23. * under either the MPL or the LGPL License.
  24. * @since KSFL 1.0
  25. * @author Rebecca G. Bettencourt, Kreative Software
  26. */
  27. package com.kreative.rsrc.pict;
  28. import java.awt.image.*;
  29. import java.io.*;
  30. import java.util.*;
  31. public class PICTUtilities {
  32. private PICTUtilities() {}
  33. public static byte[] makeByteArray(Object... objs) throws IOException {
  34. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  35. DataOutputStream dos = new DataOutputStream(bos);
  36. for (Object o : objs) {
  37. if (o instanceof Byte) dos.writeByte((Byte)o);
  38. else if (o instanceof Short) dos.writeShort((Short)o);
  39. else if (o instanceof Integer) dos.writeInt((Integer)o);
  40. else if (o instanceof Long) dos.writeLong((Long)o);
  41. else if (o instanceof Float) dos.writeFloat((Float)o);
  42. else if (o instanceof Double) dos.writeDouble((Double)o);
  43. else if (o instanceof Boolean) dos.writeBoolean((Boolean)o);
  44. else if (o instanceof Character) dos.writeChar((Character)o);
  45. else if (o instanceof String) {
  46. dos.writeInt(((String)o).length());
  47. dos.writeChars((String)o);
  48. }
  49. else if (o instanceof StringBuffer) {
  50. dos.writeInt((o.toString()).length());
  51. dos.writeChars(o.toString());
  52. }
  53. else if (o instanceof byte[]) {
  54. dos.writeInt(((byte[])o).length);
  55. dos.write((byte[])o);
  56. }
  57. else if (o instanceof ColorSpec) ((ColorSpec)o).write(dos);
  58. else if (o instanceof ColorTable) ((ColorTable)o).write(dos);
  59. else if (o instanceof PixMap) ((PixMap)o).write(dos, true);
  60. else if (o instanceof Point) ((Point)o).write(dos);
  61. else if (o instanceof Polygon) ((Polygon)o).write(dos);
  62. else if (o instanceof Rect) ((Rect)o).write(dos);
  63. else if (o instanceof Region) ((Region)o).write(dos);
  64. else if (o instanceof RGBColor) ((RGBColor)o).write(dos);
  65. }
  66. dos.close();
  67. bos.close();
  68. return bos.toByteArray();
  69. }
  70. public static Object[] unmakeByteArray(byte[] data, Class<?>... classes) throws IOException {
  71. ByteArrayInputStream bis = new ByteArrayInputStream(data);
  72. DataInputStream dis = new DataInputStream(bis);
  73. List<Object> objs = new Vector<Object>();
  74. for (Class<?> c : classes) {
  75. if (c == byte.class || c == Byte.class) objs.add(dis.readByte());
  76. else if (c == short.class || c == Short.class) objs.add(dis.readShort());
  77. else if (c == int.class || c == Integer.class) objs.add(dis.readInt());
  78. else if (c == long.class || c == Long.class) objs.add(dis.readLong());
  79. else if (c == float.class || c == Float.class) objs.add(dis.readFloat());
  80. else if (c == double.class || c == Double.class) objs.add(dis.readDouble());
  81. else if (c == boolean.class || c == Boolean.class) objs.add(dis.readBoolean());
  82. else if (c == char.class || c == Character.class) objs.add(dis.readChar());
  83. else if (c == String.class) {
  84. int len = dis.readInt();
  85. StringBuffer sb = new StringBuffer(len);
  86. while (len-->0) sb.append(dis.readChar());
  87. objs.add(sb.toString());
  88. }
  89. else if (c == StringBuffer.class) {
  90. int len = dis.readInt();
  91. StringBuffer sb = new StringBuffer(len);
  92. while (len-->0) sb.append(dis.readChar());
  93. objs.add(sb);
  94. }
  95. else if (c == byte[].class) {
  96. byte[] d = new byte[dis.readInt()];
  97. dis.readFully(d);
  98. objs.add(d);
  99. }
  100. else if (c == ColorSpec.class) objs.add(ColorSpec.read(dis));
  101. else if (c == ColorTable.class) objs.add(ColorTable.read(dis));
  102. else if (c == PixMap.class) objs.add(PixMap.read(dis, true));
  103. else if (c == Point.class) objs.add(Point.read(dis));
  104. else if (c == Polygon.class) objs.add(Polygon.read(dis));
  105. else if (c == Rect.class) objs.add(Rect.read(dis));
  106. else if (c == Region.class) objs.add(Region.read(dis));
  107. else if (c == RGBColor.class) objs.add(RGBColor.read(dis));
  108. }
  109. dis.close();
  110. bis.close();
  111. return objs.toArray(new Object[0]);
  112. }
  113. public static byte[] packBits(byte[] data) {
  114. byte[] runs = new byte[data.length*2];
  115. int runsPtr = 0;
  116. for (byte b : data) {
  117. if (runsPtr >= 2 && runs[runsPtr-1] == b && runs[runsPtr-2] < 127) {
  118. runs[runsPtr-2]++;
  119. } else {
  120. runs[runsPtr++] = 1;
  121. runs[runsPtr++] = b;
  122. }
  123. }
  124. byte[] comp = new byte[data.length*2];
  125. int compPtr = 0;
  126. int compCntPtr = 0;
  127. for (int i = 0; i < runsPtr; i += 2) {
  128. int cnt = runs[i];
  129. byte b = runs[i+1];
  130. if (cnt > 1) {
  131. comp[compPtr++] = (byte)(-cnt+1);
  132. comp[compPtr++] = b;
  133. compCntPtr = compPtr;
  134. } else {
  135. if (compCntPtr == compPtr || comp[compCntPtr] >= 127) {
  136. comp[compPtr++] = 0;
  137. comp[compPtr++] = b;
  138. } else {
  139. comp[compCntPtr]++;
  140. comp[compPtr++] = b;
  141. }
  142. }
  143. }
  144. byte[] fin = new byte[compPtr];
  145. for (int i = 0; i < compPtr; i++) fin[i] = comp[i];
  146. return fin;
  147. }
  148. public static byte[] unpackBits(byte[] data) {
  149. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  150. int dataPtr = 0;
  151. while (dataPtr < data.length) {
  152. int v = data[dataPtr++];
  153. if (v < 0) {
  154. int count = -v+1;
  155. byte d = data[dataPtr++];
  156. while (count-->0) bos.write(d);
  157. } else {
  158. int count = v+1;
  159. while (count-->0) bos.write(data[dataPtr++]);
  160. }
  161. }
  162. return bos.toByteArray();
  163. }
  164. public static PICTInstruction makeBitsRect(int x, int y, BufferedImage img, int matte, float hRes, float vRes) {
  165. int w = img.getWidth();
  166. int h = img.getHeight();
  167. int[] pixels = new int[w*h];
  168. img.getRGB(0, 0, w, h, pixels, 0, w);
  169. Set<Integer> colors = new HashSet<Integer>();
  170. for (int i = 0; i < pixels.length; i++) {
  171. if (pixels[i] >= 0) {
  172. pixels[i] = matte | 0xFF000000;
  173. } else {
  174. pixels[i] |= 0xFF000000;
  175. }
  176. colors.add(pixels[i] | 0xFF000000);
  177. }
  178. if (colors.size() <= 256) {
  179. // indexed
  180. PixMap pm = new PixMap();
  181. pm.baseAddr = 0;
  182. pm.rowBytes = w | 0x8000; while ((pm.rowBytes & 3) != 0) pm.rowBytes++;
  183. pm.bounds = new Rect(x, y, w, h);
  184. pm.pmVersion = 0;
  185. pm.packType = PixMap.PACK_TYPE_PACKBITS;
  186. pm.packSize = 0;
  187. pm.hRes = hRes;
  188. pm.vRes = vRes;
  189. pm.pixelType = PixMap.PIXEL_TYPE_INDEXED;
  190. pm.pixelSize = PixMap.PIXEL_SIZE_8BIT;
  191. pm.cmpCount = PixMap.COMPONENT_COUNT_INDEXED;
  192. pm.cmpSize = PixMap.COMPONENT_SIZE_8BIT;
  193. pm.planeBytes = 0;
  194. pm.pmTable = 0;
  195. pm.pmReserved = 0;
  196. ColorTable ct = new ColorTable();
  197. ct.ctSeed = 0;
  198. ct.ctFlags = 0;
  199. ct.ctSize = colors.size()-1;
  200. Integer[] ca = colors.toArray(new Integer[0]);
  201. Arrays.sort(ca, new Comparator<Integer>() {
  202. public int compare(Integer o1, Integer o2) {
  203. return o2.compareTo(o1);
  204. }
  205. });
  206. for (int c : ca) {
  207. ct.ctTable.add(new ColorSpec(c));
  208. }
  209. BufferedImage pdi = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, ct.toIndexColorModel(8));
  210. pdi.setRGB(0, 0, w, h, pixels, 0, w);
  211. byte[] pddata = ((DataBufferByte)pdi.getData().getDataBuffer()).getData();
  212. ByteArrayOutputStream pdb = new ByteArrayOutputStream();
  213. DataOutputStream pdd = new DataOutputStream(pdb);
  214. try {
  215. byte[] pdscanline = new byte[(pm.rowBytes & 0x7FFF)];
  216. if ((pm.rowBytes & 0x7FFF) < 8) {
  217. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  218. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  219. pdscanline[lx] = pddata[pddx];
  220. }
  221. pdd.write(pdscanline);
  222. }
  223. } else if ((pm.rowBytes & 0x7FFF) > 250) {
  224. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  225. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  226. pdscanline[lx] = pddata[pddx];
  227. }
  228. byte[] csl = packBits(pdscanline);
  229. pdd.writeShort(csl.length);
  230. pdd.write(csl);
  231. }
  232. } else {
  233. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  234. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  235. pdscanline[lx] = pddata[pddx];
  236. }
  237. byte[] csl = packBits(pdscanline);
  238. pdd.writeByte(csl.length);
  239. pdd.write(csl);
  240. }
  241. }
  242. pdd.close();
  243. pdb.close();
  244. } catch (IOException ex) {}
  245. byte[] pd = pdb.toByteArray();
  246. return new PICTInstruction.PackBitsRect(pm, ct, pm.bounds, pm.bounds, PICTInstruction.ModeConstants.SRC_COPY, pd);
  247. } else {
  248. // rgb
  249. PixMap pm = new PixMap();
  250. pm.baseAddr = 0;
  251. pm.rowBytes = (w*4) | 0x8000;
  252. pm.bounds = new Rect(x, y, w, h);
  253. pm.pmVersion = 0;
  254. pm.packType = PixMap.PACK_TYPE_BY_COMPONENT;
  255. pm.packSize = 0;
  256. pm.hRes = hRes;
  257. pm.vRes = vRes;
  258. pm.pixelType = PixMap.PIXEL_TYPE_RGBDIRECT;
  259. pm.pixelSize = PixMap.PIXEL_SIZE_32BIT;
  260. pm.cmpCount = PixMap.COMPONENT_COUNT_RGB;
  261. pm.cmpSize = PixMap.COMPONENT_SIZE_32BIT;
  262. pm.planeBytes = 0;
  263. pm.pmTable = 0;
  264. pm.pmReserved = 0;
  265. ByteArrayOutputStream pdb = new ByteArrayOutputStream();
  266. DataOutputStream pdd = new DataOutputStream(pdb);
  267. try {
  268. byte[] pdscanline = new byte[w*3];
  269. if ((pm.rowBytes & 0x7FFF) < 8) {
  270. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  271. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  272. pdscanline[lx] = (byte)((pixels[pddx] >>> 16) & 0xFF);
  273. }
  274. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  275. pdscanline[lx+w] = (byte)((pixels[pddx] >>> 8) & 0xFF);
  276. }
  277. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  278. pdscanline[lx+w+w] = (byte)((pixels[pddx] >>> 0) & 0xFF);
  279. }
  280. pdd.write(pdscanline);
  281. }
  282. } else if ((pm.rowBytes & 0x7FFF) > 250) {
  283. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  284. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  285. pdscanline[lx] = (byte)((pixels[pddx] >>> 16) & 0xFF);
  286. }
  287. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  288. pdscanline[lx+w] = (byte)((pixels[pddx] >>> 8) & 0xFF);
  289. }
  290. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  291. pdscanline[lx+w+w] = (byte)((pixels[pddx] >>> 0) & 0xFF);
  292. }
  293. byte[] csl = packBits(pdscanline);
  294. pdd.writeShort(csl.length);
  295. pdd.write(csl);
  296. }
  297. } else {
  298. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  299. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  300. pdscanline[lx] = (byte)((pixels[pddx] >>> 16) & 0xFF);
  301. }
  302. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  303. pdscanline[lx+w] = (byte)((pixels[pddx] >>> 8) & 0xFF);
  304. }
  305. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  306. pdscanline[lx+w+w] = (byte)((pixels[pddx] >>> 0) & 0xFF);
  307. }
  308. byte[] csl = packBits(pdscanline);
  309. pdd.writeByte(csl.length);
  310. pdd.write(csl);
  311. }
  312. }
  313. pdd.close();
  314. pdb.close();
  315. } catch (IOException ex) {}
  316. byte[] pd = pdb.toByteArray();
  317. pm.packSize = pd.length;
  318. return new PICTInstruction.DirectBitsRect(pm, pm.bounds, pm.bounds, PICTInstruction.ModeConstants.SRC_COPY, pd);
  319. }
  320. }
  321. public static PICTInstruction makeBitsRgn(int x, int y, BufferedImage img, int matte, float hRes, float vRes) {
  322. int w = img.getWidth();
  323. int h = img.getHeight();
  324. int[] pixels = new int[w*h];
  325. img.getRGB(0, 0, w, h, pixels, 0, w);
  326. Region rgn = Region.fromAlpha(x, y, w, h, pixels, 0, w);
  327. for (int i = 0; i < pixels.length; i++) {
  328. if (pixels[i] >= 0) {
  329. pixels[i] = matte | 0xFF000000;
  330. } else {
  331. pixels[i] |= 0xFF000000;
  332. }
  333. }
  334. PixMap pm = new PixMap();
  335. pm.baseAddr = 0;
  336. pm.rowBytes = (w*4) | 0x8000;
  337. pm.bounds = new Rect(x, y, w, h);
  338. pm.pmVersion = 0;
  339. pm.packType = PixMap.PACK_TYPE_BY_COMPONENT;
  340. pm.packSize = 0;
  341. pm.hRes = hRes;
  342. pm.vRes = vRes;
  343. pm.pixelType = PixMap.PIXEL_TYPE_RGBDIRECT;
  344. pm.pixelSize = PixMap.PIXEL_SIZE_32BIT;
  345. pm.cmpCount = PixMap.COMPONENT_COUNT_RGB;
  346. pm.cmpSize = PixMap.COMPONENT_SIZE_32BIT;
  347. pm.planeBytes = 0;
  348. pm.pmTable = 0;
  349. pm.pmReserved = 0;
  350. ByteArrayOutputStream pdb = new ByteArrayOutputStream();
  351. DataOutputStream pdd = new DataOutputStream(pdb);
  352. try {
  353. byte[] pdscanline = new byte[w*3];
  354. if ((pm.rowBytes & 0x7FFF) < 8) {
  355. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  356. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  357. pdscanline[lx] = (byte)((pixels[pddx] >>> 16) & 0xFF);
  358. }
  359. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  360. pdscanline[lx+w] = (byte)((pixels[pddx] >>> 8) & 0xFF);
  361. }
  362. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  363. pdscanline[lx+w+w] = (byte)((pixels[pddx] >>> 0) & 0xFF);
  364. }
  365. pdd.write(pdscanline);
  366. }
  367. } else if ((pm.rowBytes & 0x7FFF) > 250) {
  368. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  369. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  370. pdscanline[lx] = (byte)((pixels[pddx] >>> 16) & 0xFF);
  371. }
  372. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  373. pdscanline[lx+w] = (byte)((pixels[pddx] >>> 8) & 0xFF);
  374. }
  375. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  376. pdscanline[lx+w+w] = (byte)((pixels[pddx] >>> 0) & 0xFF);
  377. }
  378. byte[] csl = packBits(pdscanline);
  379. pdd.writeShort(csl.length);
  380. pdd.write(csl);
  381. }
  382. } else {
  383. for (int ly = 0, pddy = 0; ly < h; ly++, pddy += w) {
  384. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  385. pdscanline[lx] = (byte)((pixels[pddx] >>> 16) & 0xFF);
  386. }
  387. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  388. pdscanline[lx+w] = (byte)((pixels[pddx] >>> 8) & 0xFF);
  389. }
  390. for (int lx = 0, pddx = pddy; lx < w; lx++, pddx++) {
  391. pdscanline[lx+w+w] = (byte)((pixels[pddx] >>> 0) & 0xFF);
  392. }
  393. byte[] csl = packBits(pdscanline);
  394. pdd.writeByte(csl.length);
  395. pdd.write(csl);
  396. }
  397. }
  398. pdd.close();
  399. pdb.close();
  400. } catch (IOException ex) {}
  401. byte[] pd = pdb.toByteArray();
  402. pm.packSize = pd.length;
  403. return new PICTInstruction.DirectBitsRgn(pm, pm.bounds, pm.bounds, PICTInstruction.ModeConstants.SRC_COPY, rgn, pd);
  404. }
  405. public static BufferedImage pixmapToImage(PixMap pm, ColorTable ct, byte[] data, int bg, int fg, boolean pixpat, boolean packed) {
  406. // DECOMPRESS THE DATA TO GET THE RAW PIXEL DATA
  407. if (((pm.packType == PixMap.PACK_TYPE_PACKBITS) && !packed) || (pm.packType == PixMap.PACK_TYPE_UNPACKED) || ((pm.rowBytes & 0x7FFF) < 8)) {
  408. // no decompression necessary
  409. } else if (pm.packType == PixMap.PACK_TYPE_UNPACKED_NO_PADDING) {
  410. byte[] ndata = new byte[data.length*4/3];
  411. for (int di = 0, ndi = 0; di < data.length && ndi < ndata.length; di += 3, ndi += 4) {
  412. ndata[ndi+0] = 0;
  413. ndata[ndi+1] = data[di+0];
  414. ndata[ndi+2] = data[di+1];
  415. ndata[ndi+3] = data[di+2];
  416. }
  417. data = ndata;
  418. } else if ((pm.rowBytes & 0x7FFF) > 250) {
  419. try {
  420. ByteArrayInputStream bin = new ByteArrayInputStream(data);
  421. DataInputStream din = new DataInputStream(bin);
  422. ByteArrayOutputStream bout = new ByteArrayOutputStream();
  423. DataOutputStream dout = new DataOutputStream(bout);
  424. for (int y = pm.bounds.top; y < pm.bounds.bottom; y++) {
  425. byte[] scanline = new byte[din.readUnsignedShort()];
  426. din.readFully(scanline);
  427. scanline = unpackBits(scanline);
  428. if (pm.packType == PixMap.PACK_TYPE_BY_COMPONENT) {
  429. if (pm.cmpCount == PixMap.COMPONENT_COUNT_ARGB) {
  430. byte[] nscanline = new byte[scanline.length];
  431. int sli = 0;
  432. for (int nsli = 0; nsli < nscanline.length; nsli += 4, sli++) {
  433. nscanline[nsli] = scanline[sli];
  434. }
  435. for (int nsli = 1; nsli < nscanline.length; nsli += 4, sli++) {
  436. nscanline[nsli] = scanline[sli];
  437. }
  438. for (int nsli = 2; nsli < nscanline.length; nsli += 4, sli++) {
  439. nscanline[nsli] = scanline[sli];
  440. }
  441. for (int nsli = 3; nsli < nscanline.length; nsli += 4, sli++) {
  442. nscanline[nsli] = scanline[sli];
  443. }
  444. scanline = nscanline;
  445. } else if (pm.cmpCount == PixMap.COMPONENT_COUNT_RGB) {
  446. byte[] nscanline = new byte[scanline.length*4/3];
  447. int sli = 0;
  448. for (int nsli = 0; nsli < nscanline.length; nsli += 4) {
  449. nscanline[nsli] = 0;
  450. }
  451. for (int nsli = 1; nsli < nscanline.length; nsli += 4, sli++) {
  452. nscanline[nsli] = scanline[sli];
  453. }
  454. for (int nsli = 2; nsli < nscanline.length; nsli += 4, sli++) {
  455. nscanline[nsli] = scanline[sli];
  456. }
  457. for (int nsli = 3; nsli < nscanline.length; nsli += 4, sli++) {
  458. nscanline[nsli] = scanline[sli];
  459. }
  460. scanline = nscanline;
  461. }
  462. }
  463. dout.write(scanline);
  464. }
  465. dout.close();
  466. bout.close();
  467. din.close();
  468. bin.close();
  469. data = bout.toByteArray();
  470. } catch (IOException ioe) {
  471. return null;
  472. }
  473. } else {
  474. try {
  475. ByteArrayInputStream bin = new ByteArrayInputStream(data);
  476. DataInputStream din = new DataInputStream(bin);
  477. ByteArrayOutputStream bout = new ByteArrayOutputStream();
  478. DataOutputStream dout = new DataOutputStream(bout);
  479. for (int y = pm.bounds.top; y < pm.bounds.bottom; y++) {
  480. byte[] scanline = new byte[din.readUnsignedByte()];
  481. din.readFully(scanline);
  482. scanline = unpackBits(scanline);
  483. if (pm.packType == PixMap.PACK_TYPE_BY_COMPONENT) {
  484. if (pm.cmpCount == PixMap.COMPONENT_COUNT_ARGB) {
  485. byte[] nscanline = new byte[scanline.length];
  486. int sli = 0;
  487. for (int nsli = 0; nsli < nscanline.length; nsli += 4, sli++) {
  488. nscanline[nsli] = scanline[sli];
  489. }
  490. for (int nsli = 1; nsli < nscanline.length; nsli += 4, sli++) {
  491. nscanline[nsli] = scanline[sli];
  492. }
  493. for (int nsli = 2; nsli < nscanline.length; nsli += 4, sli++) {
  494. nscanline[nsli] = scanline[sli];
  495. }
  496. for (int nsli = 3; nsli < nscanline.length; nsli += 4, sli++) {
  497. nscanline[nsli] = scanline[sli];
  498. }
  499. scanline = nscanline;
  500. } else if (pm.cmpCount == PixMap.COMPONENT_COUNT_RGB) {
  501. byte[] nscanline = new byte[scanline.length*4/3];
  502. int sli = 0;
  503. for (int nsli = 0; nsli < nscanline.length; nsli += 4) {
  504. nscanline[nsli] = 0;
  505. }
  506. for (int nsli = 1; nsli < nscanline.length; nsli += 4, sli++) {
  507. nscanline[nsli] = scanline[sli];
  508. }
  509. for (int nsli = 2; nsli < nscanline.length; nsli += 4, sli++) {
  510. nscanline[nsli] = scanline[sli];
  511. }
  512. for (int nsli = 3; nsli < nscanline.length; nsli += 4, sli++) {
  513. nscanline[nsli] = scanline[sli];
  514. }
  515. scanline = nscanline;
  516. }
  517. }
  518. dout.write(scanline);
  519. }
  520. dout.close();
  521. bout.close();
  522. din.close();
  523. bin.close();
  524. data = bout.toByteArray();
  525. } catch (IOException ioe) {
  526. return null;
  527. }
  528. }
  529. // CREATE THE COLOR TABLE
  530. int[] colors;
  531. if (ct != null) {
  532. colors = ct.toIntArray();
  533. if (colors.length < (1 << pm.pixelSize)) {
  534. int[] newcolors = new int[1 << pm.pixelSize];
  535. for (int i = 0; i < colors.length; i++) {
  536. newcolors[i] = colors[i];
  537. }
  538. int k = newcolors.length - colors.length - 1;
  539. if (k == 0) {
  540. for (int i = colors.length; i < newcolors.length; i++) {
  541. newcolors[i] = fg;
  542. }
  543. } else {
  544. int bga = (bg >>> 24) & 0xFF;
  545. int bgr = (bg >>> 16) & 0xFF;
  546. int bgg = (bg >>> 8) & 0xFF;
  547. int bgb = (bg >>> 0) & 0xFF;
  548. int fga = (fg >>> 24) & 0xFF;
  549. int fgr = (fg >>> 16) & 0xFF;
  550. int fgg = (fg >>> 8) & 0xFF;
  551. int fgb = (fg >>> 0) & 0xFF;
  552. for (int i = colors.length, j = 0; i < newcolors.length; i++, j++) {
  553. int a = bga + (fga-bga)*j/k;
  554. int r = bgr + (fgr-bgr)*j/k;
  555. int g = bgg + (fgg-bgg)*j/k;
  556. int b = bgb + (fgb-bgb)*j/k;
  557. newcolors[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
  558. }
  559. }
  560. colors = newcolors;
  561. }
  562. } else if (pixpat) {
  563. colors = new int[1 << pm.pixelSize];
  564. int k = colors.length-1;
  565. int bga = (bg >>> 24) & 0xFF;
  566. int bgr = (bg >>> 16) & 0xFF;
  567. int bgg = (bg >>> 8) & 0xFF;
  568. int bgb = (bg >>> 0) & 0xFF;
  569. int fga = (fg >>> 24) & 0xFF;
  570. int fgr = (fg >>> 16) & 0xFF;
  571. int fgg = (fg >>> 8) & 0xFF;
  572. int fgb = (fg >>> 0) & 0xFF;
  573. for (int i = 0; i < colors.length; i++) {
  574. int a = bga + (fga-bga)*i/k;
  575. int r = bgr + (fgr-bgr)*i/k;
  576. int g = bgg + (fgg-bgg)*i/k;
  577. int b = bgb + (fgb-bgb)*i/k;
  578. colors[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
  579. }
  580. } else {
  581. if (pm.pixelSize <= 1) colors = COLORS_1BIT;
  582. else if (pm.pixelSize <= 2) colors = COLORS_2BIT;
  583. else if (pm.pixelSize <= 4) colors = COLORS_4BIT;
  584. else colors = COLORS_8BIT;
  585. }
  586. // CREATE THE IMAGE
  587. int w = pm.bounds.right-pm.bounds.left;
  588. int h = pm.bounds.bottom-pm.bounds.top;
  589. int bw = (pm.rowBytes & 0x7FFF) * 8 / pm.pixelSize;
  590. int[] pixels = new int[bw*h];
  591. switch (pm.pixelSize) {
  592. case PixMap.PIXEL_SIZE_32BIT:
  593. for (int ly = 0, py = 0, dy = 0; ly < h && py < pixels.length && dy < data.length; ly++, py += bw, dy += (pm.rowBytes & 0x7FFF)) {
  594. for (int lx = 0, px = py, dx = dy; lx < w && px < pixels.length && dx < data.length; lx++, px++, dx += 4) {
  595. if (pm.cmpCount == PixMap.COMPONENT_COUNT_ARGB) {
  596. pixels[px] = ((data[dx+0] & 0xFF) << 24) | ((data[dx+1] & 0xFF) << 16) | ((data[dx+2] & 0xFF) << 8) | (data[dx+3] & 0xFF);
  597. } else {
  598. pixels[px] = 0xFF000000 | ((data[dx+1] & 0xFF) << 16) | ((data[dx+2] & 0xFF) << 8) | (data[dx+3] & 0xFF);
  599. }
  600. }
  601. }
  602. break;
  603. case PixMap.PIXEL_SIZE_16BIT:
  604. for (int ly = 0, py = 0, dy = 0; ly < h && py < pixels.length && dy < data.length; ly++, py += bw, dy += (pm.rowBytes & 0x7FFF)) {
  605. for (int lx = 0, px = py, dx = dy; lx < w && px < pixels.length && dx < data.length; lx++, px++, dx += 2) {
  606. int sh = ((data[dx+0] & 0xFF) << 8) | (data[dx+1] & 0xFF);
  607. int r = ((sh >>> 10) & 0x1F) * 255 / 31;
  608. int g = ((sh >>> 5) & 0x1F) * 255 / 31;
  609. int b = (sh & 0x1F) * 255 / 31;
  610. pixels[px] = 0xFF000000 | (r << 16) | (g << 8) | b;
  611. }
  612. }
  613. break;
  614. case PixMap.PIXEL_SIZE_8BIT:
  615. for (int ly = 0, py = 0, dy = 0; ly < h && py < pixels.length && dy < data.length; ly++, py += bw, dy += (pm.rowBytes & 0x7FFF)) {
  616. for (int lx = 0, px = py, dx = dy; lx < w && px < pixels.length && dx < data.length; lx++, px++, dx++) {
  617. pixels[px] = colors[data[dx] & 0xFF];
  618. }
  619. }
  620. break;
  621. case PixMap.PIXEL_SIZE_4BIT:
  622. for (int ly = 0, py = 0, dy = 0; ly < h && py < pixels.length && dy < data.length; ly++, py += bw, dy += (pm.rowBytes & 0x7FFF)) {
  623. for (int lx = 0, px = py, dx = dy; lx < w && px < pixels.length && dx < data.length; lx++, px += 2, dx++) {
  624. pixels[px] = colors[(data[dx] >>> 4) & 0xF];
  625. pixels[px+1] = colors[data[dx] & 0xF];
  626. }
  627. }
  628. break;
  629. case PixMap.PIXEL_SIZE_2BIT:
  630. for (int ly = 0, py = 0, dy = 0; ly < h && py < pixels.length && dy < data.length; ly++, py += bw, dy += (pm.rowBytes & 0x7FFF)) {
  631. for (int lx = 0, px = py, dx = dy; lx < w && px < pixels.length && dx < data.length; lx++, px += 4, dx++) {
  632. pixels[px] = colors[(data[dx] >>> 6) & 0x3];
  633. pixels[px+1] = colors[(data[dx] >>> 4) & 0x3];
  634. pixels[px+2] = colors[(data[dx] >>> 2) & 0x3];
  635. pixels[px+3] = colors[data[dx] & 0x3];
  636. }
  637. }
  638. break;
  639. case PixMap.PIXEL_SIZE_1BIT:
  640. for (int ly = 0, py = 0, dy = 0; ly < h && py < pixels.length && dy < data.length; ly++, py += bw, dy += (pm.rowBytes & 0x7FFF)) {
  641. for (int lx = 0, px = py, dx = dy; lx < w && px < pixels.length && dx < data.length; lx++, px += 8, dx++) {
  642. pixels[px] = colors[(data[dx] >>> 7) & 0x1];
  643. pixels[px+1] = colors[(data[dx] >>> 6) & 0x1];
  644. pixels[px+2] = colors[(data[dx] >>> 5) & 0x1];
  645. pixels[px+3] = colors[(data[dx] >>> 4) & 0x1];
  646. pixels[px+4] = colors[(data[dx] >>> 3) & 0x1];
  647. pixels[px+5] = colors[(data[dx] >>> 2) & 0x1];
  648. pixels[px+6] = colors[(data[dx] >>> 1) & 0x1];
  649. pixels[px+7] = colors[data[dx] & 0x1];
  650. }
  651. }
  652. break;
  653. }
  654. BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
  655. img.setRGB(0, 0, w, h, pixels, 0, bw);
  656. return img;
  657. }
  658. public static byte[] encodeString(String s) {
  659. try {
  660. return s.getBytes("MACROMAN");
  661. } catch (UnsupportedEncodingException uee) {
  662. ByteArrayOutputStream bs = new ByteArrayOutputStream(s.length());
  663. for (char ch : s.toCharArray()) {
  664. if (ch < 0x80) bs.write(ch);
  665. else {
  666. boolean found = false;
  667. for (int i = 0x80; i < 0x100; i++) {
  668. if (MACROMAN[i] == ch) {
  669. found = true;
  670. bs.write(i);
  671. break;
  672. }
  673. }
  674. if (!found) bs.write('?');
  675. }
  676. }
  677. return bs.toByteArray();
  678. }
  679. }
  680. public static String decodeString(byte[] data) {
  681. try {
  682. return new String(data, "MACROMAN");
  683. } catch (UnsupportedEncodingException uee) {
  684. StringBuffer sb = new StringBuffer(data.length);
  685. for (byte b : data) {
  686. if (b >= 0) sb.append((char)b);
  687. else sb.append(MACROMAN[b & 0xFF]);
  688. }
  689. return sb.toString();
  690. }
  691. }
  692. public static final int[] COLORS_8BIT = {
  693. 0xFFFFFFFF, 0xFFFFFFCC, 0xFFFFFF99, 0xFFFFFF66, 0xFFFFFF33, 0xFFFFFF00, 0xFFFFCCFF, 0xFFFFCCCC,
  694. 0xFFFFCC99, 0xFFFFCC66, 0xFFFFCC33, 0xFFFFCC00, 0xFFFF99FF, 0xFFFF99CC, 0xFFFF9999, 0xFFFF9966,
  695. 0xFFFF9933, 0xFFFF9900, 0xFFFF66FF, 0xFFFF66CC, 0xFFFF6699, 0xFFFF6666, 0xFFFF6633, 0xFFFF6600,
  696. 0xFFFF33FF, 0xFFFF33CC, 0xFFFF3399, 0xFFFF3366, 0xFFFF3333, 0xFFFF3300, 0xFFFF00FF, 0xFFFF00CC,
  697. 0xFFFF0099, 0xFFFF0066, 0xFFFF0033, 0xFFFF0000, 0xFFCCFFFF, 0xFFCCFFCC, 0xFFCCFF99, 0xFFCCFF66,
  698. 0xFFCCFF33, 0xFFCCFF00, 0xFFCCCCFF, 0xFFCCCCCC, 0xFFCCCC99, 0xFFCCCC66, 0xFFCCCC33, 0xFFCCCC00,
  699. 0xFFCC99FF, 0xFFCC99CC, 0xFFCC9999, 0xFFCC9966, 0xFFCC9933, 0xFFCC9900, 0xFFCC66FF, 0xFFCC66CC,
  700. 0xFFCC6699, 0xFFCC6666, 0xFFCC6633, 0xFFCC6600, 0xFFCC33FF, 0xFFCC33CC, 0xFFCC3399, 0xFFCC3366,
  701. 0xFFCC3333, 0xFFCC3300, 0xFFCC00FF, 0xFFCC00CC, 0xFFCC0099, 0xFFCC0066, 0xFFCC0033, 0xFFCC0000,
  702. 0xFF99FFFF, 0xFF99FFCC, 0xFF99FF99, 0xFF99FF66, 0xFF99FF33, 0xFF99FF00, 0xFF99CCFF, 0xFF99CCCC,
  703. 0xFF99CC99, 0xFF99CC66, 0xFF99CC33, 0xFF99CC00, 0xFF9999FF, 0xFF9999CC, 0xFF999999, 0xFF999966,
  704. 0xFF999933, 0xFF999900, 0xFF9966FF, 0xFF9966CC, 0xFF996699, 0xFF996666, 0xFF996633, 0xFF996600,
  705. 0xFF9933FF, 0xFF9933CC, 0xFF993399, 0xFF993366, 0xFF993333, 0xFF993300, 0xFF9900FF, 0xFF9900CC,
  706. 0xFF990099, 0xFF990066, 0xFF990033, 0xFF990000, 0xFF66FFFF, 0xFF66FFCC, 0xFF66FF99, 0xFF66FF66,
  707. 0xFF66FF33, 0xFF66FF00, 0xFF66CCFF, 0xFF66CCCC, 0xFF66CC99, 0xFF66CC66, 0xFF66CC33, 0xFF66CC00,
  708. 0xFF6699FF, 0xFF6699CC, 0xFF669999, 0xFF669966, 0xFF669933, 0xFF669900, 0xFF6666FF, 0xFF6666CC,
  709. 0xFF666699, 0xFF666666, 0xFF666633, 0xFF666600, 0xFF6633FF, 0xFF6633CC, 0xFF663399, 0xFF663366,
  710. 0xFF663333, 0xFF663300, 0xFF6600FF, 0xFF6600CC, 0xFF660099, 0xFF660066, 0xFF660033, 0xFF660000,
  711. 0xFF33FFFF, 0xFF33FFCC, 0xFF33FF99, 0xFF33FF66, 0xFF33FF33, 0xFF33FF00, 0xFF33CCFF, 0xFF33CCCC,
  712. 0xFF33CC99, 0xFF33CC66, 0xFF33CC33, 0xFF33CC00, 0xFF3399FF, 0xFF3399CC, 0xFF339999, 0xFF339966,
  713. 0xFF339933, 0xFF339900, 0xFF3366FF, 0xFF3366CC, 0xFF336699, 0xFF336666, 0xFF336633, 0xFF336600,
  714. 0xFF3333FF, 0xFF3333CC, 0xFF333399, 0xFF333366, 0xFF333333, 0xFF333300, 0xFF3300FF, 0xFF3300CC,
  715. 0xFF330099, 0xFF330066, 0xFF330033, 0xFF330000, 0xFF00FFFF, 0xFF00FFCC, 0xFF00FF99, 0xFF00FF66,
  716. 0xFF00FF33, 0xFF00FF00, 0xFF00CCFF, 0xFF00CCCC, 0xFF00CC99, 0xFF00CC66, 0xFF00CC33, 0xFF00CC00,
  717. 0xFF0099FF, 0xFF0099CC, 0xFF009999, 0xFF009966, 0xFF009933, 0xFF009900, 0xFF0066FF, 0xFF0066CC,
  718. 0xFF006699, 0xFF006666, 0xFF006633, 0xFF006600, 0xFF0033FF, 0xFF0033CC, 0xFF003399, 0xFF003366,
  719. 0xFF003333, 0xFF003300, 0xFF0000FF, 0xFF0000CC, 0xFF000099, 0xFF000066, 0xFF000033, 0xFFEE0000,
  720. 0xFFDD0000, 0xFFBB0000, 0xFFAA0000, 0xFF880000, 0xFF770000, 0xFF550000, 0xFF440000, 0xFF220000,
  721. 0xFF110000, 0xFF00EE00, 0xFF00DD00, 0xFF00BB00, 0xFF00AA00, 0xFF008800, 0xFF007700, 0xFF005500,
  722. 0xFF004400, 0xFF002200, 0xFF001100, 0xFF0000EE, 0xFF0000DD, 0xFF0000BB, 0xFF0000AA, 0xFF000088,
  723. 0xFF000077, 0xFF000055, 0xFF000044, 0xFF000022, 0xFF000011, 0xFFEEEEEE, 0xFFDDDDDD, 0xFFBBBBBB,
  724. 0xFFAAAAAA, 0xFF888888, 0xFF777777, 0xFF555555, 0xFF444444, 0xFF222222, 0xFF111111, 0xFF000000
  725. };
  726. public static final int[] COLORS_4BIT = {
  727. 0xFFFFFFFF, 0xFFFCF305, 0xFFFF6503, 0xFFDD0907, 0xFFF30885, 0xFF4700A5, 0xFF0000D4, 0xFF02ABEB,
  728. 0xFF1FB814, 0xFF006512, 0xFF562D05, 0xFF91713A, 0xFFC0C0C0, 0xFF808080, 0xFF404040, 0xFF000000
  729. };
  730. public static final int[] COLORS_2BIT = {
  731. 0xFFFFFFFF, 0xFF808080, 0xFFCCCCFF, 0xFF000000
  732. };
  733. public static final int[] COLORS_1BIT = {
  734. 0xFFFFFFFF, 0xFF000000
  735. };
  736. private static final char[] MACROMAN = {
  737. '\u0000','\u0001','\u0002','\u0003','\u0004','\u0005','\u0006','\u0007',
  738. '\u0008','\u0009','\n','\u000B','\u000C','\r','\u000E','\u000F',
  739. '\u0010','\u0011','\u0012','\u0013','\u0014','\u0015','\u0016','\u0017',
  740. '\u0018','\u0019','\u001A','\u001B','\u001C','\u001D','\u001E','\u001F',
  741. '\u0020','\u0021','\u0022','\u0023','\u0024','\u0025','\u0026','\'',
  742. '\u0028','\u0029','\u002A','\u002B','\u002C','\u002D','\u002E','\u002F',
  743. '\u0030','\u0031','\u0032','\u0033','\u0034','\u0035','\u0036','\u0037',
  744. '\u0038','\u0039','\u003A','\u003B','\u003C','\u003D','\u003E','\u003F',
  745. '\u0040','\u0041','\u0042','\u0043','\u0044','\u0045','\u0046','\u0047',
  746. '\u0048','\u0049','\u004A','\u004B','\u004C','\u004D','\u004E','\u004F',
  747. '\u0050','\u0051','\u0052','\u0053','\u0054','\u0055','\u0056','\u0057',
  748. '\u0058','\u0059','\u005A','\u005B','\\','\u005D','\u005E','\u005F',
  749. '\u0060','\u0061','\u0062','\u0063','\u0064','\u0065','\u0066','\u0067',
  750. '\u0068','\u0069','\u006A','\u006B','\u006C','\u006D','\u006E','\u006F',
  751. '\u0070','\u0071','\u0072','\u0073','\u0074','\u0075','\u0076','\u0077',
  752. '\u0078','\u0079','\u007A','\u007B','\u007C','\u007D','\u007E','\u007F',
  753. '\u00C4','\u00C5','\u00C7','\u00C9','\u00D1','\u00D6','\u00DC','\u00E1',
  754. '\u00E0','\u00E2','\u00E4','\u00E3','\u00E5','\u00E7','\u00E9','\u00E8',
  755. '\u00EA','\u00EB','\u00ED','\u00EC','\u00EE','\u00EF','\u00F1','\u00F3',
  756. '\u00F2','\u00F4','\u00F6','\u00F5','\u00FA','\u00F9','\u00FB','\u00FC',
  757. '\u2020','\u00B0','\u00A2','\u00A3','\u00A7','\u2022','\u00B6','\u00DF',
  758. '\u00AE','\u00A9','\u2122','\u00B4','\u00A8','\u2260','\u00C6','\u00D8',
  759. '\u221E','\u00B1','\u2264','\u2265','\u00A5','\u00B5','\u2202','\u2211',
  760. '\u220F','\u03C0','\u222B','\u00AA','\u00BA','\u03A9','\u00E6','\u00F8',
  761. '\u00BF','\u00A1','\u00AC','\u221A','\u0192','\u2248','\u2206','\u00AB',
  762. '\u00BB','\u2026','\u00A0','\u00C0','\u00C3','\u00D5','\u0152','\u0153',
  763. '\u2013','\u2014','\u201C','\u201D','\u2018','\u2019','\u00F7','\u25CA',
  764. '\u00FF','\u0178','\u2044','\u20AC','\u2039','\u203A','\uFB01','\uFB02',
  765. '\u2021','\u00B7','\u201A','\u201E','\u2030','\u00C2','\u00CA','\u00C1',
  766. '\u00CB','\u00C8','\u00CD','\u00CE','\u00CF','\u00CC','\u00D3','\u00D4',
  767. '\uF8FF','\u00D2','\u00DA','\u00DB','\u00D9','\u0131','\u02C6','\u02DC',
  768. '\u00AF','\u02D8','\u02D9','\u02DA','\u00B8','\u02DD','\u02DB','\u02C7',
  769. };
  770. }