ByteArray.st
changeset 2579 7e0783458c2f
parent 2464 e44ab57ff8ae
child 2585 6c25622320aa
equal deleted inserted replaced
2578:9fa5d20c0bf0 2579:7e0783458c2f
    51     programs/data-bases, see a companion class (Structure) in the goodies directory.
    51     programs/data-bases, see a companion class (Structure) in the goodies directory.
    52     It allows the definition of subclasses of ByteArray, which transparently fetch
    52     It allows the definition of subclasses of ByteArray, which transparently fetch
    53     and store C-structure fields.
    53     and store C-structure fields.
    54 
    54 
    55     [warning:]
    55     [warning:]
    56         read the warning about 'growing fixed size collection'
    56 	read the warning about 'growing fixed size collection'
    57         in ArrayedCollection's documentation
    57 	in ArrayedCollection's documentation
    58 
    58 
    59     [author:]
    59     [author:]
    60         Claus Gittinger
    60 	Claus Gittinger
    61 
    61 
    62     [See also:]
    62     [See also:]
    63         Array CharacterArray String
    63 	Array CharacterArray String
    64 "
    64 "
    65 ! !
    65 ! !
    66 
    66 
    67 !ByteArray class methodsFor:'instance creation'!
    67 !ByteArray class methodsFor:'instance creation'!
    68 
    68 
    88     "the size modulu 3 is encoded in the last character, if its in the
    88     "the size modulu 3 is encoded in the last character, if its in the
    89      range 97 .. otherwise, its exact."
    89      range 97 .. otherwise, its exact."
    90 
    90 
    91     lastCharacter := aString last.
    91     lastCharacter := aString last.
    92     lastCharacter asciiValue > 96 ifTrue:[
    92     lastCharacter asciiValue > 96 ifTrue:[
    93         stop := stop - 3 + lastCharacter asciiValue - 96
    93 	stop := stop - 3 + lastCharacter asciiValue - 96
    94     ].
    94     ].
    95     bytes := self new:stop.
    95     bytes := self new:stop.
    96 
    96 
    97     index := 1. dstIndex := 1.
    97     index := 1. dstIndex := 1.
    98     [dstIndex <= stop] whileTrue:[
    98     [dstIndex <= stop] whileTrue:[
    99         "take 4 characters ..."
    99 	"take 4 characters ..."
   100         sixBits := (aString at:index) asciiValue.
   100 	sixBits := (aString at:index) asciiValue.
   101         sixBits := sixBits bitAnd:16r3F.
   101 	sixBits := sixBits bitAnd:16r3F.
   102         n := sixBits.
   102 	n := sixBits.
   103         
   103         
   104         sixBits := (aString at:index+1) asciiValue.
   104 	sixBits := (aString at:index+1) asciiValue.
   105         sixBits := sixBits bitAnd:16r3F.
   105 	sixBits := sixBits bitAnd:16r3F.
   106         n := (n bitShift:6) + sixBits.
   106 	n := (n bitShift:6) + sixBits.
   107 
   107 
   108         sixBits := (aString at:index+2) asciiValue.
   108 	sixBits := (aString at:index+2) asciiValue.
   109         sixBits := sixBits bitAnd:16r3F.
   109 	sixBits := sixBits bitAnd:16r3F.
   110         n := (n bitShift:6) + sixBits.
   110 	n := (n bitShift:6) + sixBits.
   111 
   111 
   112         sixBits := (aString at:index+3) asciiValue.
   112 	sixBits := (aString at:index+3) asciiValue.
   113         sixBits := sixBits bitAnd:16r3F.
   113 	sixBits := sixBits bitAnd:16r3F.
   114         n := (n bitShift:6) + sixBits.
   114 	n := (n bitShift:6) + sixBits.
   115 
   115 
   116         index := index + 4.
   116 	index := index + 4.
   117 
   117 
   118         "/ now have 24 bits in n
   118 	"/ now have 24 bits in n
   119 
   119 
   120         bytes at:dstIndex put:(n bitShift:-16).
   120 	bytes at:dstIndex put:(n bitShift:-16).
   121 
   121 
   122         dstIndex < stop ifTrue:[
   122 	dstIndex < stop ifTrue:[
   123             bytes at:dstIndex+1 put:((n bitShift:-8) bitAnd:16rFF).
   123 	    bytes at:dstIndex+1 put:((n bitShift:-8) bitAnd:16rFF).
   124             dstIndex+2 <= stop ifTrue:[
   124 	    dstIndex+2 <= stop ifTrue:[
   125                 bytes at:dstIndex+2 put:(n bitAnd:16rFF).
   125 		bytes at:dstIndex+2 put:(n bitAnd:16rFF).
   126             ]
   126 	    ]
   127         ].
   127 	].
   128         dstIndex := dstIndex + 3.
   128 	dstIndex := dstIndex + 3.
   129     ].
   129     ].
   130     ^ bytes
   130     ^ bytes
   131 
   131 
   132     "
   132     "
   133      ByteArray fromPackedString:(#[1 1 1 1] asPackedString) 
   133      ByteArray fromPackedString:(#[1 1 1 1] asPackedString) 
   293     int val;
   293     int val;
   294     REGISTER OBJ slf;
   294     REGISTER OBJ slf;
   295     REGISTER OBJ cls;
   295     REGISTER OBJ cls;
   296 
   296 
   297     if (__bothSmallInteger(index, value)) {
   297     if (__bothSmallInteger(index, value)) {
   298         val = __intVal(value);
   298 	val = __intVal(value);
   299         if ((unsigned)(val) <= 0xFF /* i.e. (val >= 0) && (val <= 255) */) {
   299 	if ((unsigned)(val) <= 0xFF /* i.e. (val >= 0) && (val <= 255) */) {
   300             indx = __intVal(index) - 1;
   300 	    indx = __intVal(index) - 1;
   301             slf = self;
   301 	    slf = self;
   302             if ((cls = __qClass(slf)) != @global(ByteArray)) {
   302 	    if ((cls = __qClass(slf)) != @global(ByteArray)) {
   303                 if (((INT)__ClassInstPtr(cls)->c_flags & __MASKSMALLINT(ARRAYMASK))
   303 		if (((INT)__ClassInstPtr(cls)->c_flags & __MASKSMALLINT(ARRAYMASK))
   304                     != __MASKSMALLINT(BYTEARRAY)) {
   304 		    != __MASKSMALLINT(BYTEARRAY)) {
   305                     goto fail;
   305 		    goto fail;
   306                 }
   306 		}
   307                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   307 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   308             }
   308 	    }
   309             nIndex = __byteArraySize(slf);
   309 	    nIndex = __byteArraySize(slf);
   310             if ((unsigned)indx < (unsigned)nIndex) {
   310 	    if ((unsigned)indx < (unsigned)nIndex) {
   311                 __ByteArrayInstPtr(slf)->ba_element[indx] = val;
   311 		__ByteArrayInstPtr(slf)->ba_element[indx] = val;
   312                 RETURN ( value );
   312 		RETURN ( value );
   313             }
   313 	    }
   314         }
   314 	}
   315     }
   315     }
   316   fail: ;
   316   fail: ;
   317 %}.
   317 %}.
   318     ^ super basicAt:index put:value
   318     ^ super basicAt:index put:value
   319 
   319 
   729      bIdx  "{ Class: SmallInteger }"
   729      bIdx  "{ Class: SmallInteger }"
   730      delta "{ Class: SmallInteger }"|
   730      delta "{ Class: SmallInteger }"|
   731 
   731 
   732     l := LargeInteger basicNew numberOfDigits:8.
   732     l := LargeInteger basicNew numberOfDigits:8.
   733     msb ifTrue:[
   733     msb ifTrue:[
   734         bIdx := index + 7.
   734 	bIdx := index + 7.
   735         delta := -1
   735 	delta := -1
   736     ] ifFalse:[
   736     ] ifFalse:[
   737         bIdx := index.
   737 	bIdx := index.
   738         delta := 1
   738 	delta := 1
   739     ].
   739     ].
   740     1 to:8 do:[:i |
   740     1 to:8 do:[:i |
   741         l digitAt:i put:(self basicAt:bIdx).
   741 	l digitAt:i put:(self basicAt:bIdx).
   742         bIdx := bIdx + delta
   742 	bIdx := bIdx + delta
   743     ].
   743     ].
   744     ^ l compressed
   744     ^ l compressed
   745 
   745 
   746     "
   746     "
   747      |b|
   747      |b|
   813      This may be worth a primitive."
   813      This may be worth a primitive."
   814 
   814 
   815     |b "{ Class: SmallInteger }"|
   815     |b "{ Class: SmallInteger }"|
   816 
   816 
   817     aSignedByteValue >= 0 ifTrue:[
   817     aSignedByteValue >= 0 ifTrue:[
   818         b := aSignedByteValue
   818 	b := aSignedByteValue
   819     ] ifFalse:[
   819     ] ifFalse:[
   820         b := 16r100 + aSignedByteValue
   820 	b := 16r100 + aSignedByteValue
   821     ].
   821     ].
   822     self at:index put:b.
   822     self at:index put:b.
   823     ^ aSignedByteValue
   823     ^ aSignedByteValue
   824 
   824 
   825     "
   825     "
   839 
   839 
   840     |w|
   840     |w|
   841 
   841 
   842     w := self doubleWordAt:index.
   842     w := self doubleWordAt:index.
   843     (w > (16r7FFFFFFF)) ifTrue:[
   843     (w > (16r7FFFFFFF)) ifTrue:[
   844         ^ w - (16r100000000)
   844 	^ w - (16r100000000)
   845     ].
   845     ].
   846     ^ w
   846     ^ w
   847 
   847 
   848 "
   848 "
   849     w := self doubleWordAt:index.
   849     w := self doubleWordAt:index.
   850     (w > 16r7FFFFFFF) ifTrue:[
   850     (w > 16r7FFFFFFF) ifTrue:[
   851         ^ w - 16r100000000
   851 	^ w - 16r100000000
   852     ].
   852     ].
   853     ^ w
   853     ^ w
   854 "
   854 "
   855 
   855 
   856     "
   856     "
   870 
   870 
   871     |w|
   871     |w|
   872 
   872 
   873     w := self doubleWordAt:index MSB:msb.
   873     w := self doubleWordAt:index MSB:msb.
   874     (w > (16r7FFFFFFF)) ifTrue:[
   874     (w > (16r7FFFFFFF)) ifTrue:[
   875         ^ w - (16r100000000)
   875 	^ w - (16r100000000)
   876     ].
   876     ].
   877     ^ w
   877     ^ w
   878 "
   878 "
   879     w := self doubleWordAt:index.
   879     w := self doubleWordAt:index.
   880     (w > 16r7FFFFFFF) ifTrue:[
   880     (w > 16r7FFFFFFF) ifTrue:[
   881         ^ w - 16r100000000
   881 	^ w - 16r100000000
   882     ].
   882     ].
   883     ^ w
   883     ^ w
   884 "
   884 "
   885 
   885 
   886     "
   886     "
   899      This may be worth a primitive."
   899      This may be worth a primitive."
   900 
   900 
   901     |v|
   901     |v|
   902 
   902 
   903     value >= 0 ifTrue:[
   903     value >= 0 ifTrue:[
   904         v := value
   904 	v := value
   905     ] ifFalse:[
   905     ] ifFalse:[
   906         v := value + 16r100000000
   906 	v := value + 16r100000000
   907     ].
   907     ].
   908     self doubleWordAt:index put:v.
   908     self doubleWordAt:index put:v.
   909     ^ value
   909     ^ value
   910 
   910 
   911     "
   911     "
   924      This may be worth a primitive."
   924      This may be worth a primitive."
   925 
   925 
   926     |v|
   926     |v|
   927 
   927 
   928     value >= 0 ifTrue:[
   928     value >= 0 ifTrue:[
   929         v := value
   929 	v := value
   930     ] ifFalse:[
   930     ] ifFalse:[
   931         v := value + 16r100000000
   931 	v := value + 16r100000000
   932     ].
   932     ].
   933     self doubleWordAt:index put:v MSB:msb.
   933     self doubleWordAt:index put:v MSB:msb.
   934     ^ value
   934     ^ value
   935 
   935 
   936     "
   936     "
  1002      This may be worth a primitive."
  1002      This may be worth a primitive."
  1003 
  1003 
  1004     |v|
  1004     |v|
  1005 
  1005 
  1006     value >= 0 ifTrue:[
  1006     value >= 0 ifTrue:[
  1007         v := value
  1007 	v := value
  1008     ] ifFalse:[
  1008     ] ifFalse:[
  1009         v := 16r10000 + value
  1009 	v := 16r10000 + value
  1010     ].
  1010     ].
  1011     self wordAt:index put:v.
  1011     self wordAt:index put:v.
  1012     ^ value
  1012     ^ value
  1013 
  1013 
  1014     "
  1014     "
  1031      This may be worth a primitive."
  1031      This may be worth a primitive."
  1032 
  1032 
  1033     |v|
  1033     |v|
  1034 
  1034 
  1035     value >= 0 ifTrue:[
  1035     value >= 0 ifTrue:[
  1036         v := value
  1036 	v := value
  1037     ] ifFalse:[
  1037     ] ifFalse:[
  1038         v := 16r10000 + value
  1038 	v := 16r10000 + value
  1039     ].
  1039     ].
  1040     self wordAt:index put:v MSB:msb.
  1040     self wordAt:index put:v MSB:msb.
  1041     ^ value
  1041     ^ value
  1042 
  1042 
  1043     "
  1043     "
  1251 
  1251 
  1252     |myClass myBasicSize|
  1252     |myClass myBasicSize|
  1253 
  1253 
  1254     "not, if I have named instance variables"
  1254     "not, if I have named instance variables"
  1255     (myClass := self class) instSize ~~ 0 ifTrue:[
  1255     (myClass := self class) instSize ~~ 0 ifTrue:[
  1256         ^ super storeBinaryDefinitionOn:stream manager:manager
  1256 	^ super storeBinaryDefinitionOn:stream manager:manager
  1257     ].
  1257     ].
  1258     manager putIdOfClass:myClass on: stream.
  1258     manager putIdOfClass:myClass on: stream.
  1259     stream nextNumber:4 put:(myBasicSize := self basicSize).
  1259     stream nextNumber:4 put:(myBasicSize := self basicSize).
  1260     stream nextPutBytes:myBasicSize from:self startingAt:1.
  1260     stream nextPutBytes:myBasicSize from:self startingAt:1.
  1261 "/    stream nextPutAll:(self asByteArray)
  1261 "/    stream nextPutAll:(self asByteArray)
  1362 	    dstp += nInst;
  1362 	    dstp += nInst;
  1363 	    len -= nInst;
  1363 	    len -= nInst;
  1364 	}
  1364 	}
  1365 
  1365 
  1366 	value = __intVal(aNumber);
  1366 	value = __intVal(aNumber);
  1367 	if (((value & ~0xFF) == 0) /* i.e. (value >= 0) && (value <= 255) */
  1367 	if (((unsigned)value <= 0xFF) /* i.e. (value >= 0) && (value <= 255) */
  1368 	 && (index1 <= index2) 
  1368 	 && (index1 <= index2) 
  1369 	 && (index1 > 0)) {
  1369 	 && (index1 > 0)) {
  1370 	    if (index2 <= len) {
  1370 	    if (index2 <= len) {
  1371 		count = index2 - index1 + 1;
  1371 		count = index2 - index1 + 1;
       
  1372 
       
  1373 #ifdef memset4
       
  1374 		if (count > 20) {
       
  1375 		    while (((unsigned)dstp & 3) != 0) {
       
  1376 			*dstp++ = value;
       
  1377 			count--;
       
  1378 		    }
       
  1379 		    {
       
  1380 			int n4 = count & ~3;
       
  1381 			int v4, nW;
       
  1382 
       
  1383 			v4 = (value << 8) | value;
       
  1384 			v4 = (v4 << 16) | v4;
       
  1385 			nW = n4>>2;
       
  1386 			memset4(dstp, v4, nW);
       
  1387 			count -= n4;
       
  1388 			dstp += n4;
       
  1389 		    }
       
  1390 		    while (count--) {
       
  1391 			*dstp++ = value;
       
  1392 		    }
       
  1393 		    RETURN (self);
       
  1394 		}
       
  1395 #endif /* memset4 */
       
  1396 
  1372 #ifdef FAST_MEMSET
  1397 #ifdef FAST_MEMSET
  1373 		memset(dstp, count, value);
  1398 		memset(dstp, value, count);
  1374 #else
  1399 #else
  1375 # ifdef UNROLL_LOOPS
  1400 # ifdef UNROLL_LOOPS
  1376 		while (count >= 8) {
  1401 		while (count >= 8) {
  1377 		    dstp[0] = dstp[1] = dstp[2] = dstp[3] =
  1402 		    dstp[0] = dstp[1] = dstp[2] = dstp[3] =
  1378 		    dstp[4] = dstp[5] = dstp[6] = dstp[7] = value;
  1403 		    dstp[4] = dstp[5] = dstp[6] = dstp[7] = value;
  1379 		    dstp += 8;
  1404 		    dstp += 8;
  1380 		    count -= 8;
  1405 		    count -= 8;
  1381 		}
  1406 		}
  1382 # endif
  1407 # endif /* UNROLL_LOOPS */
  1383 		while (count--) {
  1408 		while (count--) {
  1384 		    *dstp++ = value;
  1409 		    *dstp++ = value;
  1385 		}
  1410 		}
  1386 #endif
  1411 #endif
  1387 		RETURN (self);
  1412 		RETURN (self);
  1454 			    *--dst = *--src;
  1479 			    *--dst = *--src;
  1455 			}
  1480 			}
  1456 			RETURN ( self );
  1481 			RETURN ( self );
  1457 		    }
  1482 		    }
  1458 		}
  1483 		}
  1459 #ifdef FAST_MEMCPY
  1484 
  1460 # ifdef bcopy4
  1485 #ifdef bcopy4
  1461 		if (((src & 3) == 0)
  1486 		if ((((unsigned)src & 3) == 0)
  1462 		 && ((dst & 3) == 0)) {
  1487 		 && (((unsigned)dst & 3) == 0)) {
  1463 		    /* copy aligned part */
  1488 		    /* copy aligned part */
  1464 		    bcopy4(src, dst, count//4);
  1489 		    int nW = count >> 2;
       
  1490 
       
  1491 		    bcopy4(src, dst, nW);
  1465 		    /* copy rest */
  1492 		    /* copy rest */
  1466 		    if (count & 3) {
  1493 		    if (count & 3) {
  1467 			src += (count & ~3);
  1494 			src += (count & ~3);
  1468 			dst += (count & ~3);
  1495 			dst += (count & ~3);
  1469 			count = count & 3;
  1496 			count = count & 3;
  1470 			while (count--) {
  1497 			while (count--) {
  1471 			    *dst++ = *src++;
  1498 			    *dst++ = *src++;
  1472 			}
  1499 			}
  1473 		    }
  1500 		    }
  1474 		} else
  1501 		    RETURN ( self );
  1475 # endif /* bcopy4 */
  1502 		}
  1476 		    bcopy(src, dst, count);
  1503 #endif /* bcopy4 */
       
  1504 
       
  1505 #ifdef FAST_MEMCPY
       
  1506 		bcopy(src, dst, count);
  1477 #else
  1507 #else
       
  1508 # ifdef UNROLL_LOOPS
       
  1509 		while (count >= 8) {
       
  1510 		    dst[0] = src[0]; dst[1] = src[1];
       
  1511 		    dst[2] = src[2]; dst[3] = src[3];
       
  1512 		    dst[4] = src[4]; dst[5] = src[5];
       
  1513 		    dst[6] = src[6]; dst[7] = src[7];
       
  1514 		    dst += 8; src += 8;
       
  1515 		    count -= 8;
       
  1516 		}
       
  1517 # endif /* UNROLL_LOOPS */
  1478 		while (count-- > 0) {
  1518 		while (count-- > 0) {
  1479 		    *dst++ = *src++;
  1519 		    *dst++ = *src++;
  1480 		}
  1520 		}
  1481 #endif
  1521 #endif
  1482 		RETURN ( self );
  1522 		RETURN ( self );
  1496 replaceFrom:start to:stop with:aCollection startingAt:repStart
  1536 replaceFrom:start to:stop with:aCollection startingAt:repStart
  1497     "replace elements in the receiver between index start and stop,
  1537     "replace elements in the receiver between index start and stop,
  1498      with elements  taken from replacementCollection starting at repStart."
  1538      with elements  taken from replacementCollection starting at repStart."
  1499 
  1539 
  1500     (aCollection class == self class) ifTrue:[
  1540     (aCollection class == self class) ifTrue:[
  1501         ^ self replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1541 	^ self replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1502     ].
  1542     ].
  1503     ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart
  1543     ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart
  1504 
  1544 
  1505     "Modified: 13.4.1996 / 12:16:46 / cg"
  1545     "Modified: 13.4.1996 / 12:16:46 / cg"
  1506 ! !
  1546 ! !
  1507 
  1547 
  1508 !ByteArray methodsFor:'image manipulation support'!
  1548 !ByteArray methodsFor:'image manipulation support'!
  1509 
  1549 
  1510 compressPixels:nBitsPerPixel width:width height:height into:aByteArray
  1550 compressPixels:nBitsPerPixel width:width height:height into:aByteArray
  1511                          mapping:aMapByteArray
  1551 			 mapping:aMapByteArray
  1512 
  1552 
  1513     "given the receiver with 8-bit pixels, compress them into aByteArray
  1553     "given the receiver with 8-bit pixels, compress them into aByteArray
  1514      with nBitsPerPixel-depth pixels. The width/height-arguments are needed
  1554      with nBitsPerPixel-depth pixels. The width/height-arguments are needed
  1515      to allow for any padding. On the fly, the source bytes are translated
  1555      to allow for any padding. On the fly, the source bytes are translated
  1516      using aMapByteArray (if non-nil).
  1556      using aMapByteArray (if non-nil).
  1538 
  1578 
  1539     if ((__qClass(self) == @global(ByteArray)) 
  1579     if ((__qClass(self) == @global(ByteArray)) 
  1540      && (__qClass(aByteArray) == @global(ByteArray))
  1580      && (__qClass(aByteArray) == @global(ByteArray))
  1541      && __isSmallInteger(nBitsPerPixel)
  1581      && __isSmallInteger(nBitsPerPixel)
  1542      && __bothSmallInteger(height, width)) {
  1582      && __bothSmallInteger(height, width)) {
  1543         if ((aMapByteArray != nil)
  1583 	if ((aMapByteArray != nil)
  1544          && (__Class(aMapByteArray) == @global(ByteArray))) {
  1584 	 && (__Class(aMapByteArray) == @global(ByteArray))) {
  1545             map = __ByteArrayInstPtr(aMapByteArray)->ba_element;
  1585 	    map = __ByteArrayInstPtr(aMapByteArray)->ba_element;
  1546         } else {
  1586 	} else {
  1547             map = (unsigned char *)0;
  1587 	    map = (unsigned char *)0;
  1548         }
  1588 	}
  1549 
  1589 
  1550         bitsPerPixel = __intVal(nBitsPerPixel);
  1590 	bitsPerPixel = __intVal(nBitsPerPixel);
  1551         w = __intVal(width);
  1591 	w = __intVal(width);
  1552         h = __intVal(height);
  1592 	h = __intVal(height);
  1553         src = __ByteArrayInstPtr(self)->ba_element;
  1593 	src = __ByteArrayInstPtr(self)->ba_element;
  1554         dst = __ByteArrayInstPtr(aByteArray)->ba_element;
  1594 	dst = __ByteArrayInstPtr(aByteArray)->ba_element;
  1555         dstEnd = dst + __byteArraySize(aByteArray);
  1595 	dstEnd = dst + __byteArraySize(aByteArray);
  1556         switch (bitsPerPixel) {
  1596 	switch (bitsPerPixel) {
  1557             case 1:
  1597 	    case 1:
  1558                 mask = 0x01;
  1598 		mask = 0x01;
  1559                 break;
  1599 		break;
  1560             case 2:
  1600 	    case 2:
  1561                 mask = 0x03;
  1601 		mask = 0x03;
  1562                 break;
  1602 		break;
  1563             case 4:
  1603 	    case 4:
  1564                 mask = 0x0F;
  1604 		mask = 0x0F;
  1565                 break;
  1605 		break;
  1566             case 8:
  1606 	    case 8:
  1567                 mask = 0xFF;
  1607 		mask = 0xFF;
  1568                 break;
  1608 		break;
  1569             default:
  1609 	    default:
  1570                 goto fail;
  1610 		goto fail;
  1571         }
  1611 	}
  1572         if (map) {
  1612 	if (map) {
  1573             /*
  1613 	    /*
  1574              * if a map is present, it must have entries for
  1614 	     * if a map is present, it must have entries for
  1575              * all possible byte-values (i.e. its size must be >= 256)
  1615 	     * all possible byte-values (i.e. its size must be >= 256)
  1576              */
  1616 	     */
  1577             if ((__qSize(aMapByteArray) - OHDR_SIZE) < 256)
  1617 	    if ((__qSize(aMapByteArray) - OHDR_SIZE) < 256)
  1578                 goto fail;
  1618 		goto fail;
  1579         }
  1619 	}
  1580 
  1620 
  1581         bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1621 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1582         dstBytes = bytesPerRow * h;
  1622 	dstBytes = bytesPerRow * h;
  1583         srcBytes = w * h;
  1623 	srcBytes = w * h;
  1584 
  1624 
  1585         if ((__byteArraySize(self) >= srcBytes)
  1625 	if ((__byteArraySize(self) >= srcBytes)
  1586          && (__byteArraySize(aByteArray) >= dstBytes)) {
  1626 	 && (__byteArraySize(aByteArray) >= dstBytes)) {
  1587             for (hrun=h; hrun; hrun--) {
  1627 	    for (hrun=h; hrun; hrun--) {
  1588                 dstNext = dst + bytesPerRow;
  1628 		dstNext = dst + bytesPerRow;
  1589                 bits = 0; shift = 8;
  1629 		bits = 0; shift = 8;
  1590                 if (map) {
  1630 		if (map) {
  1591                     for (wrun=w; wrun; wrun--) {
  1631 		    for (wrun=w; wrun; wrun--) {
  1592                         bits = (bits << bitsPerPixel) | (map[*src++] & mask);
  1632 			bits = (bits << bitsPerPixel) | (map[*src++] & mask);
  1593                         shift -= bitsPerPixel;
  1633 			shift -= bitsPerPixel;
  1594                         if (shift == 0) {
  1634 			if (shift == 0) {
  1595                             if (dst == dstEnd) goto fail;
  1635 			    if (dst == dstEnd) goto fail;
  1596                             *dst++ = bits;
  1636 			    *dst++ = bits;
  1597                             bits = 0; shift = 8;
  1637 			    bits = 0; shift = 8;
  1598                         }
  1638 			}
  1599                     }
  1639 		    }
  1600                 } else {
  1640 		} else {
  1601                     for (wrun=w; wrun; wrun--) {
  1641 		    for (wrun=w; wrun; wrun--) {
  1602                         bits = (bits << bitsPerPixel) | (*src++ & mask);
  1642 			bits = (bits << bitsPerPixel) | (*src++ & mask);
  1603                         shift -= bitsPerPixel;
  1643 			shift -= bitsPerPixel;
  1604                         if (shift == 0) {
  1644 			if (shift == 0) {
  1605                             if (dst == dstEnd) goto fail;
  1645 			    if (dst == dstEnd) goto fail;
  1606                             *dst++ = bits;
  1646 			    *dst++ = bits;
  1607                             bits = 0; shift = 8;
  1647 			    bits = 0; shift = 8;
  1608                         }
  1648 			}
  1609                     }
  1649 		    }
  1610                 }
  1650 		}
  1611                 if (shift != 8) {
  1651 		if (shift != 8) {
  1612                     if (dst == dstEnd) goto fail;
  1652 		    if (dst == dstEnd) goto fail;
  1613                     *dst = bits;
  1653 		    *dst = bits;
  1614                 }
  1654 		}
  1615                 dst = dstNext;
  1655 		dst = dstNext;
  1616             }
  1656 	    }
  1617             RETURN ( self );
  1657 	    RETURN ( self );
  1618         }
  1658 	}
  1619     }
  1659     }
  1620 fail: ;
  1660 fail: ;
  1621 %}
  1661 %}
  1622 .
  1662 .
  1623     self primitiveFailed
  1663     self primitiveFailed
  1627     "
  1667     "
  1628     "
  1668     "
  1629      |inBits outBits|
  1669      |inBits outBits|
  1630 
  1670 
  1631      inBits := #[0 0 0 0 1 1 1 1
  1671      inBits := #[0 0 0 0 1 1 1 1
  1632                  0 0 1 1 0 0 1 1
  1672 		 0 0 1 1 0 0 1 1
  1633                  0 1 0 1 0 1 0 1
  1673 		 0 1 0 1 0 1 0 1
  1634                  1 1 1 1 0 0 0 0].
  1674 		 1 1 1 1 0 0 0 0].
  1635      outBits := ByteArray new:4.
  1675      outBits := ByteArray new:4.
  1636      inBits compressPixels:1 width:8 height:4
  1676      inBits compressPixels:1 width:8 height:4
  1637                     into:outBits mapping:nil.
  1677 		    into:outBits mapping:nil.
  1638      outBits inspect
  1678      outBits inspect
  1639     "
  1679     "
  1640 
  1680 
  1641     "Example2:
  1681     "Example2:
  1642      compress byte-array into a bitArray, translating 99 to 0-bits,
  1682      compress byte-array into a bitArray, translating 99 to 0-bits,
  1649      map := ByteArray new:256.
  1689      map := ByteArray new:256.
  1650      map at:176+1 put:1.
  1690      map at:176+1 put:1.
  1651 
  1691 
  1652      outBits := ByteArray new:2.
  1692      outBits := ByteArray new:2.
  1653      inBits compressPixels:1 width:16 height:1 
  1693      inBits compressPixels:1 width:16 height:1 
  1654                     into:outBits mapping:map.
  1694 		    into:outBits mapping:map.
  1655      outBits inspect
  1695      outBits inspect
  1656     "
  1696     "
  1657 
  1697 
  1658     "Example3:
  1698     "Example3:
  1659      compress byte-array into a bitArray, translating everything below 128 to 0-bits,
  1699      compress byte-array into a bitArray, translating everything below 128 to 0-bits,
  1666      map := ByteArray new:256.
  1706      map := ByteArray new:256.
  1667      map atAll:(128+1 to:255+1) put:1.
  1707      map atAll:(128+1 to:255+1) put:1.
  1668 
  1708 
  1669      outBits := ByteArray new:2.
  1709      outBits := ByteArray new:2.
  1670      inBits compressPixels:1 width:16 height:1 
  1710      inBits compressPixels:1 width:16 height:1 
  1671                     into:outBits mapping:map.
  1711 		    into:outBits mapping:map.
  1672      outBits inspect
  1712      outBits inspect
  1673     "
  1713     "
  1674 !
  1714 !
  1675 
  1715 
  1676 expandPixels:nBitsPerPixel width:width height:height into:aByteArray
  1716 expandPixels:nBitsPerPixel width:width height:height into:aByteArray
  1677                          mapping:aMapByteArray
  1717 			 mapping:aMapByteArray
  1678 
  1718 
  1679     "given the receiver with nBitsPerPixel-depth pixels, expand them into
  1719     "given the receiver with nBitsPerPixel-depth pixels, expand them into
  1680      aByteArray with 8-bit pixels. The width/height-arguments are needed
  1720      aByteArray with 8-bit pixels. The width/height-arguments are needed
  1681      to skip any padded src-bits. On the fly, the destination pixels
  1721      to skip any padded src-bits. On the fly, the destination pixels
  1682      are translated using aMapByteArray (if non-nil).
  1722      are translated using aMapByteArray (if non-nil).
  1705 
  1745 
  1706     if ((__qClass(self) == @global(ByteArray)) 
  1746     if ((__qClass(self) == @global(ByteArray)) 
  1707      && (__qClass(aByteArray) == @global(ByteArray))
  1747      && (__qClass(aByteArray) == @global(ByteArray))
  1708      && __isSmallInteger(nBitsPerPixel)
  1748      && __isSmallInteger(nBitsPerPixel)
  1709      && __bothSmallInteger(height, width)) {
  1749      && __bothSmallInteger(height, width)) {
  1710         if ((aMapByteArray != nil)
  1750 	if ((aMapByteArray != nil)
  1711          && (__Class(aMapByteArray) == @global(ByteArray))) {
  1751 	 && (__Class(aMapByteArray) == @global(ByteArray))) {
  1712             map = __ByteArrayInstPtr(aMapByteArray)->ba_element;
  1752 	    map = __ByteArrayInstPtr(aMapByteArray)->ba_element;
  1713         } else {
  1753 	} else {
  1714             map = (unsigned char *)0;
  1754 	    map = (unsigned char *)0;
  1715         }
  1755 	}
  1716 
  1756 
  1717         bitsPerPixel = __intVal(nBitsPerPixel);
  1757 	bitsPerPixel = __intVal(nBitsPerPixel);
  1718         w = __intVal(width);
  1758 	w = __intVal(width);
  1719         h = __intVal(height);
  1759 	h = __intVal(height);
  1720         src = __ByteArrayInstPtr(self)->ba_element;
  1760 	src = __ByteArrayInstPtr(self)->ba_element;
  1721         dst = __ByteArrayInstPtr(aByteArray)->ba_element;
  1761 	dst = __ByteArrayInstPtr(aByteArray)->ba_element;
  1722         switch (bitsPerPixel) {
  1762 	switch (bitsPerPixel) {
  1723             case 1:
  1763 	    case 1:
  1724                 mask = 0x01;
  1764 		mask = 0x01;
  1725                 break;
  1765 		break;
  1726             case 2:
  1766 	    case 2:
  1727                 mask = 0x03;
  1767 		mask = 0x03;
  1728                 break;
  1768 		break;
  1729             case 4:
  1769 	    case 4:
  1730                 mask = 0x0F;
  1770 		mask = 0x0F;
  1731                 break;
  1771 		break;
  1732             case 8:
  1772 	    case 8:
  1733                 mask = 0xFF;
  1773 		mask = 0xFF;
  1734                 break;
  1774 		break;
  1735             default:
  1775 	    default:
  1736 printf("invalid depth\n");
  1776 printf("invalid depth\n");
  1737                 goto fail;
  1777 		goto fail;
  1738         }
  1778 	}
  1739         ncells = mask + 1;
  1779 	ncells = mask + 1;
  1740         if (map) {
  1780 	if (map) {
  1741             /*
  1781 	    /*
  1742              * if a map is present, it must have the correct size
  1782 	     * if a map is present, it must have the correct size
  1743              * (i.e. 2 raisedTo:nBitsPerPixel)
  1783 	     * (i.e. 2 raisedTo:nBitsPerPixel)
  1744              */
  1784 	     */
  1745             if ((__qSize(aMapByteArray) - OHDR_SIZE) < ncells) {
  1785 	    if ((__qSize(aMapByteArray) - OHDR_SIZE) < ncells) {
  1746 printf("invalid map\n");
  1786 printf("invalid map\n");
  1747                 goto fail;
  1787 		goto fail;
  1748             }
  1788 	    }
  1749         }
  1789 	}
  1750 
  1790 
  1751         bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1791 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  1752         shift0 = 8 - bitsPerPixel;
  1792 	shift0 = 8 - bitsPerPixel;
  1753         srcBytes = bytesPerRow * h;
  1793 	srcBytes = bytesPerRow * h;
  1754         dstBytes = w * h;
  1794 	dstBytes = w * h;
  1755 
  1795 
  1756         if ((__byteArraySize(self) >= srcBytes)
  1796 	if ((__byteArraySize(self) >= srcBytes)
  1757          && (__byteArraySize(aByteArray) >= dstBytes)) {
  1797 	 && (__byteArraySize(aByteArray) >= dstBytes)) {
  1758             for (hrun=h; hrun; hrun--) {
  1798 	    for (hrun=h; hrun; hrun--) {
  1759                 srcNext = src + bytesPerRow;
  1799 		srcNext = src + bytesPerRow;
  1760                 shift = shift0;
  1800 		shift = shift0;
  1761                 if (map) {
  1801 		if (map) {
  1762                     if (shift0 == 0) {
  1802 		    if (shift0 == 0) {
  1763                         /* translate only */
  1803 			/* translate only */
  1764                         for (wrun=w; wrun; wrun--) {
  1804 			for (wrun=w; wrun; wrun--) {
  1765                             bits = *src++;
  1805 			    bits = *src++;
  1766                             *dst++ = map[bits];
  1806 			    *dst++ = map[bits];
  1767                         }
  1807 			}
  1768                     } else {
  1808 		    } else {
  1769                         for (wrun=w; wrun; wrun--) {
  1809 			for (wrun=w; wrun; wrun--) {
  1770                             if (shift == shift0) {
  1810 			    if (shift == shift0) {
  1771                                 bits = *src++;
  1811 				bits = *src++;
  1772                             }
  1812 			    }
  1773                             *dst++ = map[(bits >> shift) & mask];
  1813 			    *dst++ = map[(bits >> shift) & mask];
  1774                             shift -= bitsPerPixel;
  1814 			    shift -= bitsPerPixel;
  1775                             if (shift < 0) {
  1815 			    if (shift < 0) {
  1776                                 shift = shift0;
  1816 				shift = shift0;
  1777                             }
  1817 			    }
  1778                         }
  1818 			}
  1779                     }
  1819 		    }
  1780                 } else {
  1820 		} else {
  1781                     for (wrun=w; wrun; wrun--) {
  1821 		    for (wrun=w; wrun; wrun--) {
  1782                         if (shift == shift0) {
  1822 			if (shift == shift0) {
  1783                             bits = *src++;
  1823 			    bits = *src++;
  1784                         }
  1824 			}
  1785                         *dst++ = (bits >> shift) & mask;
  1825 			*dst++ = (bits >> shift) & mask;
  1786                         shift -= bitsPerPixel;
  1826 			shift -= bitsPerPixel;
  1787                         if (shift < 0) {
  1827 			if (shift < 0) {
  1788                             shift = shift0;
  1828 			    shift = shift0;
  1789                         }
  1829 			}
  1790                     }
  1830 		    }
  1791                 }
  1831 		}
  1792                 src = srcNext;
  1832 		src = srcNext;
  1793             }
  1833 	    }
  1794             RETURN ( self );
  1834 	    RETURN ( self );
  1795         }
  1835 	}
  1796     }
  1836     }
  1797 printf("invalid args\n");
  1837 printf("invalid args\n");
  1798 
  1838 
  1799 fail: ;
  1839 fail: ;
  1800 %}
  1840 %}
  1806     "
  1846     "
  1807     "
  1847     "
  1808      |inBits outBits|
  1848      |inBits outBits|
  1809 
  1849 
  1810      inBits := #[2r11110000 
  1850      inBits := #[2r11110000 
  1811                  2r11001100 
  1851 		 2r11001100 
  1812                  2r01010101 
  1852 		 2r01010101 
  1813                  2r00001111].
  1853 		 2r00001111].
  1814      outBits := ByteArray new:(8*4).
  1854      outBits := ByteArray new:(8*4).
  1815      inBits expandPixels:1 width:8 height:4
  1855      inBits expandPixels:1 width:8 height:4
  1816                     into:outBits mapping:nil.
  1856 		    into:outBits mapping:nil.
  1817      outBits inspect
  1857      outBits inspect
  1818     "
  1858     "
  1819 
  1859 
  1820     "Example2:
  1860     "Example2:
  1821      expand bit-array into a byteArray, translating 0-bits to 99,
  1861      expand bit-array into a byteArray, translating 0-bits to 99,
  1825      |inBits outBits|
  1865      |inBits outBits|
  1826 
  1866 
  1827      inBits := #[2r11110000 2r11001100].
  1867      inBits := #[2r11110000 2r11001100].
  1828      outBits := ByteArray new:16.
  1868      outBits := ByteArray new:16.
  1829      inBits expandPixels:1 width:16 height:1 
  1869      inBits expandPixels:1 width:16 height:1 
  1830                     into:outBits mapping:#[99 176].
  1870 		    into:outBits mapping:#[99 176].
  1831      outBits inspect
  1871      outBits inspect
  1832     "
  1872     "
  1833 !
  1873 !
  1834 
  1874 
  1835 invert
  1875 invert
  1842     REGISTER unsigned char *dst;
  1882     REGISTER unsigned char *dst;
  1843     REGISTER unsigned long *ldst;
  1883     REGISTER unsigned long *ldst;
  1844     REGISTER int cnt;
  1884     REGISTER int cnt;
  1845 
  1885 
  1846     if (__qClass(self) == @global(ByteArray)) {
  1886     if (__qClass(self) == @global(ByteArray)) {
  1847         cnt = __byteArraySize(self);
  1887 	cnt = __byteArraySize(self);
  1848         dst = __ByteArrayInstPtr(self)->ba_element;
  1888 	dst = __ByteArrayInstPtr(self)->ba_element;
  1849         if (! ((int)dst & (sizeof(long)-1))) {
  1889 	if (! ((int)dst & (sizeof(long)-1))) {
  1850             ldst = (unsigned long *)dst;
  1890 	    ldst = (unsigned long *)dst;
  1851             while (cnt > 16) {
  1891 	    while (cnt > 16) {
  1852                 ldst[0] = ~(ldst[0]);
  1892 		ldst[0] = ~(ldst[0]);
  1853                 ldst[1] = ~(ldst[1]);
  1893 		ldst[1] = ~(ldst[1]);
  1854                 ldst[2] = ~(ldst[2]);
  1894 		ldst[2] = ~(ldst[2]);
  1855                 ldst[3] = ~(ldst[3]);
  1895 		ldst[3] = ~(ldst[3]);
  1856                 ldst += 4;
  1896 		ldst += 4;
  1857                 cnt -= 16;
  1897 		cnt -= 16;
  1858             }
  1898 	    }
  1859             while (cnt >= sizeof(long)) {
  1899 	    while (cnt >= sizeof(long)) {
  1860                 *ldst = ~(*ldst);
  1900 		*ldst = ~(*ldst);
  1861                 ldst++;
  1901 		ldst++;
  1862                 cnt -= sizeof(long);
  1902 		cnt -= sizeof(long);
  1863             }
  1903 	    }
  1864             dst = (unsigned char *)ldst;
  1904 	    dst = (unsigned char *)ldst;
  1865         }
  1905 	}
  1866         while (cnt--) {
  1906 	while (cnt--) {
  1867             *dst = ~(*dst);
  1907 	    *dst = ~(*dst);
  1868             dst++;
  1908 	    dst++;
  1869         }
  1909 	}
  1870         RETURN ( self );
  1910 	RETURN ( self );
  1871     }
  1911     }
  1872 %}
  1912 %}
  1873 .
  1913 .
  1874     self primitiveFailed
  1914     self primitiveFailed
  1875 !
  1915 !
  1991 
  2031 
  1992     outStream := WriteStream on:String new.
  2032     outStream := WriteStream on:String new.
  1993     index := 1. 
  2033     index := 1. 
  1994     stop := self size.
  2034     stop := self size.
  1995     [index <= stop] whileTrue:[
  2035     [index <= stop] whileTrue:[
  1996         "take 3 source bytes"
  2036 	"take 3 source bytes"
  1997         n := (self at:index) bitShift:16.
  2037 	n := (self at:index) bitShift:16.
  1998         (index < stop) ifTrue:[
  2038 	(index < stop) ifTrue:[
  1999             nextIndex := index + 1.
  2039 	    nextIndex := index + 1.
  2000             n := n bitOr:((self at:nextIndex) bitShift:8).
  2040 	    n := n bitOr:((self at:nextIndex) bitShift:8).
  2001             (nextIndex < stop) ifTrue:[
  2041 	    (nextIndex < stop) ifTrue:[
  2002                 n := n bitOr:(self at:(index + 2)).
  2042 		n := n bitOr:(self at:(index + 2)).
  2003             ].
  2043 	    ].
  2004         ].
  2044 	].
  2005 
  2045 
  2006         "took me a while to find that one out ..."
  2046 	"took me a while to find that one out ..."
  2007         n := n bitXor:16r820820.
  2047 	n := n bitXor:16r820820.
  2008 
  2048 
  2009         outStream nextPut:(Character value:(n bitShift:-18) + 32).
  2049 	outStream nextPut:(Character value:(n bitShift:-18) + 32).
  2010         outStream nextPut:(Character value:((n bitShift:-12) bitAnd:16r3F) + 32).
  2050 	outStream nextPut:(Character value:((n bitShift:-12) bitAnd:16r3F) + 32).
  2011         outStream nextPut:(Character value:((n bitShift:-6) bitAnd:16r3F) + 32).
  2051 	outStream nextPut:(Character value:((n bitShift:-6) bitAnd:16r3F) + 32).
  2012         outStream nextPut:(Character value:(n bitAnd:16r3F) + 32).
  2052 	outStream nextPut:(Character value:(n bitAnd:16r3F) + 32).
  2013         index := index + 3.
  2053 	index := index + 3.
  2014     ].
  2054     ].
  2015     (mod := stop \\ 3) ~~ 0 ifTrue:[
  2055     (mod := stop \\ 3) ~~ 0 ifTrue:[
  2016         outStream position:(outStream position - 1).
  2056 	outStream position:(outStream position - 1).
  2017         outStream nextPut:(Character value:(mod + 96)).
  2057 	outStream nextPut:(Character value:(mod + 96)).
  2018     ].
  2058     ].
  2019     ^ outStream contents
  2059     ^ outStream contents
  2020 
  2060 
  2021     "Modified: 12.11.1996 / 15:45:02 / cg"
  2061     "Modified: 12.11.1996 / 15:45:02 / cg"
  2022 !
  2062 !
  2035      reconstructed to aStream. (reimplemented to make it look better)"
  2075      reconstructed to aStream. (reimplemented to make it look better)"
  2036 
  2076 
  2037     |first|
  2077     |first|
  2038 
  2078 
  2039     self class == ByteArray ifTrue:[    "/ care for subclasses
  2079     self class == ByteArray ifTrue:[    "/ care for subclasses
  2040         aStream nextPutAll:'#['.
  2080 	aStream nextPutAll:'#['.
  2041         first := true.
  2081 	first := true.
  2042         self do:[:byte | 
  2082 	self do:[:byte | 
  2043             first ifFalse:[aStream space]
  2083 	    first ifFalse:[aStream space]
  2044                   ifTrue:[first := false].
  2084 		  ifTrue:[first := false].
  2045             byte storeOn:aStream.
  2085 	    byte storeOn:aStream.
  2046         ].
  2086 	].
  2047         aStream nextPutAll:']'.
  2087 	aStream nextPutAll:']'.
  2048         ^ self
  2088 	^ self
  2049     ].
  2089     ].
  2050     ^ super storeOn:aStream
  2090     ^ super storeOn:aStream
  2051 
  2091 
  2052     "
  2092     "
  2053      #[1 2 3 4 5] storeOn:Transcript   
  2093      #[1 2 3 4 5] storeOn:Transcript   
  2264 ! !
  2304 ! !
  2265 
  2305 
  2266 !ByteArray class methodsFor:'documentation'!
  2306 !ByteArray class methodsFor:'documentation'!
  2267 
  2307 
  2268 version
  2308 version
  2269     ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.77 1997-03-19 18:52:53 cg Exp $'
  2309     ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.78 1997-04-22 18:59:18 cg Exp $'
  2270 ! !
  2310 ! !