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 |
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 |
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 %} |
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 |