1 50 51 package org.openlaszlo.iv.flash.util; 52 53 import java.awt.geom.AffineTransform ; 54 import java.awt.geom.Rectangle2D ; 55 import java.io.*; 56 import org.openlaszlo.iv.flash.api.*; 57 58 66 public class FlashBuffer { 67 68 private int bitBuf; 70 private int bitPos; 71 72 private byte buf[]; 74 75 public int pos; 77 78 private int size; 80 81 public FlashBuffer() { 82 } 83 84 90 public FlashBuffer( int capacity ) { 91 this( new byte[capacity], 0, 0 ); 92 } 93 94 100 public FlashBuffer( byte[] buf ) { 101 this( buf, 0, buf.length ); 102 } 103 104 111 public FlashBuffer( byte[] buf, int size ) { 112 this( buf, 0, size ); 113 } 114 115 122 public FlashBuffer( byte[] buf, int pos, int size ) { 123 init( buf, pos, size ); 124 } 125 126 136 public FlashBuffer( InputStream is ) throws IOException { 137 size = 0; 138 try { 139 int count = is.available(); 140 if( count <= 0 ) count = 4096; 141 buf = new byte[count+8]; for(;;) { 143 count = is.read(buf, size, buf.length - size); 144 if( count == -1 ) break; 145 size += count; 146 if( size == buf.length ) 147 ensureCapacity(buf.length + 4096 * 4); 148 } 149 } finally { 150 is.close(); 151 } 152 pos = 0; 153 bitBuf = 0; 154 bitPos = 0; 155 } 156 157 public void init( byte[] buf, int pos, int size ) { 158 this.buf = buf; 159 this.pos = pos; 160 this.size = size; 161 this.bitBuf = 0; 162 this.bitPos = 0; 163 } 164 165 170 public final void ensureCapacity( int cap ) { 171 if( cap > buf.length ) { 172 int max = buf.length*2; 173 if( cap > max ) max = cap+16; 174 if( max < 4096 ) max = 4096; 175 byte[] newBuf = new byte[max]; 176 System.arraycopy(buf, 0, newBuf, 0, buf.length); 177 buf = newBuf; 178 } 179 } 180 181 186 public FlashBuffer getCopy() { 187 byte[] myBuf = new byte[buf.length]; 188 System.arraycopy(buf, 0, myBuf, 0, buf.length); 189 return new FlashBuffer( myBuf, pos, size ); 190 } 191 192 197 public final int getPos() { 198 return pos; 199 } 200 201 206 public final int getSize() { 207 return size; 208 } 209 210 218 public final void setPos( int pos ) { 219 this.pos = pos; 220 if( pos > size ) size = pos; 221 } 222 223 231 public final void incPos() { 232 if( ++pos > size ) size = pos; 233 } 234 235 242 public final void setSize( int size ) { 243 this.size = size; 244 } 245 246 253 public final void skip( int inc ) { 254 setPos( pos + inc ); 255 } 256 257 262 public final byte[] getBuf() { 263 return buf; 264 } 265 266 269 270 277 public final void writeByteAt( int b, int pos ) { 278 buf[pos] = (byte) b; 279 } 280 281 288 public final void writeWordAt( int b, int pos ) { 289 buf[pos] = (byte) b; 290 buf[pos+1] = (byte) (b>>8); 291 } 292 293 300 public final void writeDWordAt( int b, int pos ) { 301 buf[pos] = (byte) b; 302 buf[pos+1] = (byte) (b>>8); 303 buf[pos+2] = (byte) (b>>16); 304 buf[pos+3] = (byte) (b>>24); 305 } 306 307 312 public final void writeByte( int b ) { 313 ensureCapacity( pos+1 ); 314 buf[pos] = (byte) b; 315 incPos(); 316 } 317 318 323 public final void writeWord( int b ) { 324 ensureCapacity( pos+2 ); 325 buf[pos] = (byte) b; 326 buf[pos+1] = (byte) (b>>8); 327 setPos( pos+2 ); 328 } 329 330 335 public final void writeDWord( int b ) { 336 ensureCapacity( pos+4 ); 337 buf[pos] = (byte) b; 338 buf[pos+1] = (byte) (b>>8); 339 buf[pos+2] = (byte) (b>>16); 340 buf[pos+3] = (byte) (b>>24); 341 setPos( pos+4 ); 342 } 343 344 345 348 349 354 public final void _writeByte( int b ) { 355 buf[pos++] = (byte) b; 356 } 357 358 363 public final void _writeWord( int b ) { 364 buf[pos++] = (byte) b; 365 buf[pos++] = (byte) (b>>8); 366 } 367 368 373 public final void _writeDWord( int b ) { 374 buf[pos++] = (byte) b; 375 buf[pos++] = (byte) (b>>8); 376 buf[pos++] = (byte) (b>>16); 377 buf[pos++] = (byte) (b>>24); 378 } 379 380 381 386 public final byte[] _writeStringZ( String s ) { 387 return _writeStringZ(s, "Cp1252"); 388 } 389 390 391 397 public final byte[] _writeStringZ( String s, String encoding ) { 398 byte chars[]; 399 try { 400 chars = s.getBytes(encoding); 401 } catch (UnsupportedEncodingException e) { 402 throw new RuntimeException ("could not convert string to "+encoding); 403 } 404 System.arraycopy(chars, 0, buf, pos, chars.length); 405 setPos( pos+chars.length ); 406 buf[pos++] = 0; return chars; 408 } 409 410 411 412 419 public final void _writeArray( byte b[], int off, int len ) { 420 System.arraycopy(b, off, buf, pos, len); 421 setPos( pos+len ); 422 } 423 424 425 426 427 428 429 434 public final void writeFOB( FlashBuffer fob ) { 435 int len = fob.getSize(); 436 ensureCapacity( pos+len ); 437 System.arraycopy(fob.getBuf(), 0, buf, pos, len); 438 setPos( pos+len ); 439 } 440 441 448 public final void writeArray( byte b[], int off, int len ) { 449 ensureCapacity( pos+len ); 450 System.arraycopy(b, off, buf, pos, len); 451 setPos( pos+len ); 452 } 453 454 462 463 public final byte[] writeStringZ( String s ) { 464 return writeStringZ(s, "Cp1252"); 465 } 466 467 468 475 476 public final byte[] writeStringZ( String s, String encoding ) { 477 byte chars[]; 478 try { 479 chars = s.getBytes(encoding); 481 } catch (UnsupportedEncodingException e) { 482 throw new RuntimeException ("could not convert string to "+encoding); 483 } 484 ensureCapacity( pos+chars.length+1 ); 485 for( int i=0; i<chars.length; i++ ) { 486 buf[pos++] = chars[i]; 487 } 488 buf[pos] = 0; 489 incPos(); 490 return chars; 491 } 492 493 498 public final void writeStringL( String s ) { 499 writeStringL(s, "Cp1252"); 500 } 501 502 508 public final void writeStringL( String s, String encoding ) { 509 510 byte chars[]; 511 try { 512 chars = s.getBytes(encoding); 513 } catch (UnsupportedEncodingException e) { 514 throw new RuntimeException ("could not convert string to "+encoding); 515 } 516 ensureCapacity( pos+chars.length+1 ); 517 buf[pos++] = (byte) chars.length; 518 for( int i=0; i<chars.length; i++ ) { 519 buf[pos++] = chars[i]; 520 } 521 setPos( pos ); } 523 524 535 public final void writeTag( int tagCode, int tagSize ) { 536 if( tagSize >= 0x3f ) { 537 writeLongTag( tagCode, tagSize ); 538 } else { 539 writeWord( (tagCode<<6) | tagSize ); 540 } 541 } 542 543 553 public final void writeLongTag( int tagCode, int tagSize ) { 554 writeWord( (tagCode<<6) | 0x3f ); 555 writeDWord( tagSize ); 556 } 557 558 569 public final void writeShortTagAt( int tagCode, int tagSize, int pos ) { 570 writeWordAt( (tagCode<<6) | tagSize, pos ); 571 } 572 573 584 public final void writeLongTagAt( int tagCode, int tagSize, int pos ) { 585 writeWordAt( (tagCode<<6) | 0x3f, pos ); 586 writeDWordAt( tagSize, pos+2 ); 587 } 588 589 597 public final void writeBit( int b ) { 598 writeBits( b, 1 ); 599 } 600 601 608 public final void writeBool( boolean b ) { 609 writeBits( b?1:0, 1 ); 610 } 611 612 622 public final void writeBits( int v, int len ) { 623 ensureCapacity( pos+4 ); 624 for(;;) { 625 v = v & ((1<<len)-1); 626 int l = 8-bitPos; 627 int s = l-len; 628 if( s >= 0 ) { 629 bitBuf = (bitBuf<<len) | v; 630 bitPos += len; 631 return; 632 } else { 633 s = -s; 634 int bb = (bitBuf<<l) | (v>>>s); 635 buf[pos] = (byte)bb; 636 incPos(); 637 len = s; 638 bitBuf = 0; 639 bitPos = 0; 640 } 641 } 642 } 643 644 651 public final void flushBits() { 652 if( bitPos != 0 ) { 653 int bb = bitBuf << (8-bitPos); 654 writeByte( bb ); 655 } 656 bitBuf = 0; 657 bitPos = 0; 658 } 659 660 670 public final void initBits() { 671 bitBuf = 0; 672 bitPos = 0; 673 } 674 675 680 public final void write( InputStream is ) throws IOException { 681 try { 682 int count = is.available(); 683 if( count <= 0 ) count = 4096; 684 ensureCapacity(pos+count+8); 685 for(;;) { 686 count = is.read(buf, pos, buf.length - pos); 687 if( count == -1 ) break; 688 pos += count; 689 if( pos == buf.length ) 690 ensureCapacity(buf.length + 4096 * 4); 691 } 692 setPos(pos); 693 } finally { 694 is.close(); 695 } 696 } 697 698 701 702 708 public final void skipBits( int n ) { 709 for (;;) { 710 int s = n - bitPos; 711 if( s > 0 ) { 712 n -= bitPos; 713 bitBuf = getUByte(); 715 bitPos = 8; 716 } else { 717 s = -s; 719 bitPos = s; 720 bitBuf &= (1<<s)-1; break; 722 } 723 } 724 } 725 726 738 public final int getBits( int n ) { 739 int v = 0; 741 742 for (;;) { 743 int s = n - bitPos; 744 if( s > 0 ) { 745 v |= bitBuf << s; 747 n -= bitPos; 748 749 bitBuf = getUByte(); 751 bitPos = 8; 752 } else { 753 s = -s; 755 v |= bitBuf >> s; 756 bitPos = s; 757 bitBuf &= (1<<s)-1; return v; 759 } 760 } 761 } 762 763 public final int new_getBits( int n ) { 765 767 int s = n-bitPos; 768 if( s > 0 ) { 769 int v = bitBuf << s; 771 n -= bitPos; 772 773 if( n <= 8 ) { 775 bitBuf = getUByte(); 776 bitPos = 8; 777 } else if( n <= 16 ) { 778 bitBuf = (getUByte()<<8) | getUByte(); 779 bitPos = 16; 780 } else if( n <= 24 ) { 781 bitBuf = (getUByte()<<16) | (getUByte()<<8) | getUByte(); 782 bitPos = 24; 783 } else { 784 bitBuf = (getUByte()<<24) | (getUByte()<<16) | (getUByte()<<8) | getUByte(); 785 bitPos = 32; 786 } 787 bitPos -= n; 788 v |= bitBuf >> bitPos; 789 bitBuf &= (1<<bitPos)-1; 790 return v; 791 } 792 793 s = -s; 795 int v = bitBuf >> s; 796 bitPos = s; 797 bitBuf &= (1<<s)-1; return v; 799 } 800 801 809 public final int getSBits( int n ) { 810 int v = getBits(n); 813 814 if( (v & (1<<(n-1))) != 0 ) { 816 v |= -1 << n; 818 } 819 820 return v; 821 } 822 823 828 public boolean getBool() { 829 return getBits(1) == 1; 830 } 831 832 838 public final void getTo( FlashBuffer fob, int length ) { 839 fob.writeArray(buf, pos, length); 840 pos += length; 841 } 842 843 848 public final String getString() { 849 int sp = pos; 850 while( buf[pos++] != 0 ); 851 return new String ( buf, sp, pos-sp-1 ); 852 } 853 854 860 public final String getString( int length ) { 861 int sp = pos; 862 pos += length; 863 return new String (buf, sp, length); 864 } 865 866 872 public final byte[] getBytes( int length ) { 873 byte[] ba = new byte[length]; 874 System.arraycopy(buf, pos, ba, 0, length); 875 pos += length; 876 return ba; 877 } 878 879 884 public final int getByte() { 885 return buf[pos++]; 886 } 887 888 893 public final int getUByte() { 894 return buf[pos++] & 0xff; 895 } 896 897 public final int getByteAt( int p ) { 898 return buf[p]; 899 } 900 901 public final int getUByteAt( int p ) { 902 return buf[p] & 0xff; 903 } 904 905 910 public final int getWord() { 911 int r = Util.getWord(buf[pos], buf[pos+1]); 912 pos += 2; 913 return r; 914 } 915 916 public final int getWordAt( int p ) { 917 return Util.getWord(buf[p], buf[p+1]); 918 } 919 920 925 public final int getUWord() { 926 int r = Util.getUWord(buf[pos], buf[pos+1]); 927 pos += 2; 928 return r; 929 } 930 931 public final int getUWordAt( int p ) { 932 return Util.getUWord(buf[p], buf[p+1]); 933 } 934 935 940 public int getDWord() { 941 int r = Util.getDWord(buf[pos], buf[pos+1], buf[pos+2], buf[pos+3]); 942 pos += 4; 943 return r; 944 } 945 946 public int getDWordAt( int p ) { 947 return Util.getDWord(buf[p], buf[p+1], buf[p+2], buf[p+3]); 948 } 949 950 955 public int getUDWord() { 956 int r = Util.getUDWord(buf[pos], buf[pos+1], buf[pos+2], buf[pos+3]); 957 pos += 4; 958 return r; 959 } 960 961 public int getUDWordAt( int p ) { 962 return Util.getUDWord(buf[p], buf[p+1], buf[p+2], buf[p+3]); 963 } 964 965 968 969 975 public InputStream getInputStream() { 976 return new FlashBufferInputStream(); 977 } 978 979 986 public InputStream getInputStream( int pos ) { 987 return new FlashBufferInputStream(pos); 988 } 989 990 public class FlashBufferInputStream extends InputStream { 991 992 private int curPos = 0; 993 994 public FlashBufferInputStream() { 995 } 996 997 public FlashBufferInputStream( int curPos ) { 998 this.curPos = curPos; 999 } 1000 1001 public int read() throws IOException { 1002 if( curPos >= size ) return -1; 1003 return buf[curPos++] & 0xff; 1004 } 1005 1006 public int read( byte b[], int off, int len ) throws IOException { 1007 if( len == 0 ) return 0; 1008 int sz = Math.min(len, size-curPos); 1009 if( sz <= 0 ) return -1; 1010 System.arraycopy(buf, curPos, b, off, sz); 1011 curPos += sz; 1012 return sz; 1013 } 1014 1015 public int available() throws IOException { 1016 return size-curPos; 1017 } 1018 } 1019 1020 1023 1024 1030 public OutputStream getOutputStream() { 1031 return new FlashBufferOutputStream(); 1032 } 1033 1034 public class FlashBufferOutputStream extends OutputStream { 1035 1036 public FlashBufferOutputStream() { 1037 } 1038 1039 public void write(int b) { 1040 writeByte(b); 1041 } 1042 1043 public void write(byte b[], int off, int len) { 1044 writeArray(b,off,len); 1045 } 1046 } 1047 1048 1051 1052 public AffineTransform getMatrix() { 1053 initBits(); 1054 1055 double m00; double m10; double m01; double m11; double m02; double m12; 1062 if( getBool() ) { 1064 int nBits = getBits(5); 1065 m00 = Util.fixed2double(getSBits(nBits)); 1066 m11 = Util.fixed2double(getSBits(nBits)); 1067 } else { 1068 m00 = 1.0; 1069 m11 = 1.0; 1070 } 1071 1072 if( getBool() ) { 1074 int nBits = getBits(5); 1075 m10 = Util.fixed2double(getSBits(nBits)); 1076 m01 = Util.fixed2double(getSBits(nBits)); 1077 } else { 1078 m10 = 0.0; 1079 m01 = 0.0; 1080 } 1081 1082 int nBits = getBits(5); 1084 m02 = getSBits(nBits); 1085 m12 = getSBits(nBits); 1086 1087 AffineTransform m = new AffineTransform ( m00, m10, m01, m11, m02, m12 ); 1088 return m; 1089 } 1090 1091 1094 public void skipMatrix() { 1095 initBits(); 1096 if( getBool() ) { 1098 int nBits = getBits(5); 1099 skipBits(nBits+nBits); 1100 } 1101 if( getBool() ) { 1103 int nBits = getBits(5); 1104 skipBits(nBits+nBits); 1105 } 1106 int nBits = getBits(5); 1108 skipBits(nBits+nBits); 1109 } 1110 1111 public void write( AffineTransform m ) { 1112 initBits(); 1113 1114 double m00 = m.getScaleX(); 1115 double m10 = m.getShearY(); 1116 double m01 = m.getShearX(); 1117 double m11 = m.getScaleY(); 1118 double m02 = m.getTranslateX(); 1119 double m12 = m.getTranslateY(); 1120 1121 if( m00 != 1.0 || m11 != 1.0 ) { 1122 writeBit(1); 1123 int i_scaleX = Util.double2fixed(m00); 1124 int i_scaleY = Util.double2fixed(m11); 1125 int nBits = Util.getMinBitsS( Util.getMax(i_scaleX,i_scaleY) ); 1126 writeBits(nBits, 5); 1127 writeBits(i_scaleX, nBits); 1128 writeBits(i_scaleY, nBits); 1129 } else { 1130 writeBit(0); 1131 } 1132 1133 if( m10 != 0.0 || m01 != 0.0 ) { 1134 writeBit(1); 1135 int i_rotateSkew0 = Util.double2fixed(m10); 1136 int i_rotateSkew1 = Util.double2fixed(m01); 1137 int nBits = Util.getMinBitsS( Util.getMax(i_rotateSkew0,i_rotateSkew1) ); 1138 writeBits(nBits, 5); 1139 writeBits(i_rotateSkew0, nBits); 1140 writeBits(i_rotateSkew1, nBits); 1141 } else { 1142 writeBit(0); 1143 } 1144 1145 int i_translateX = (int) m02; 1146 int i_translateY = (int) m12; 1147 int nBits = Util.getMinBitsS( Util.getMax(i_translateX,i_translateY) ); 1148 writeBits(nBits, 5); 1149 writeBits(i_translateX, nBits); 1150 writeBits(i_translateY, nBits); 1151 flushBits(); 1152 } 1153 1154 1157 1158 public Rectangle2D getRect() { 1159 initBits(); 1160 int nBits = getBits(5); 1161 int xmin = getSBits(nBits); 1162 int xmax = getSBits(nBits); 1163 int ymin = getSBits(nBits); 1164 int ymax = getSBits(nBits); 1165 1166 Rectangle2D r = GeomHelper.newRectangle( xmin, ymin, xmax-xmin, ymax-ymin ); 1167 return r; 1168 } 1169 1170 1173 public void skipRect() { 1174 initBits(); 1175 int nBits = getBits(5); 1176 skip( ((5+(nBits*4))+7)/8 - 1 ); 1177 } 1178 1179 public void write( Rectangle2D r ) { 1180 initBits(); 1181 1182 int xmin = (int) r.getMinX(); 1183 int xmax = (int) r.getMaxX(); 1184 int ymin = (int) r.getMinY(); 1185 int ymax = (int) r.getMaxY(); 1186 1187 int nBits = Util.getMinBitsS( Util.getMax(xmin,xmax,ymin,ymax) ); 1188 writeBits( nBits, 5 ); 1189 writeBits( xmin, nBits ); 1190 writeBits( xmax, nBits ); 1191 writeBits( ymin, nBits ); 1192 writeBits( ymax, nBits ); 1193 flushBits(); 1194 } 1195 1196 public String toString() { 1197 return new String (buf, 0, pos); 1198 } 1199 1200 public String toString( String encoding ) throws java.io.UnsupportedEncodingException { 1201 return new String (buf, 0, pos, encoding); 1202 } 1203} 1204 | Popular Tags |