1447 ! ! |
1447 ! ! |
1448 |
1448 |
1449 !ByteArray methodsFor:'image manipulation support'! |
1449 !ByteArray methodsFor:'image manipulation support'! |
1450 |
1450 |
1451 compressPixels:nBitsPerPixel width:width height:height into:aByteArray |
1451 compressPixels:nBitsPerPixel width:width height:height into:aByteArray |
1452 mapping:aMapByteArray |
1452 mapping:aMapByteArray |
1453 |
1453 |
1454 "given the receiver with 8-bit pixels, compress them into aByteArray |
1454 "given the receiver with 8-bit pixels, compress them into aByteArray |
1455 with nBitsPerPixel-depth pixels. The width/height-arguments are needed |
1455 with nBitsPerPixel-depth pixels. The width/height-arguments are needed |
1456 to allow for any padding. On the fly, the source bytes are translated |
1456 to allow for any padding. On the fly, the source bytes are translated |
1457 using aMapByteArray (if non-nil). |
1457 using aMapByteArray (if non-nil). |
1478 |
1479 |
1479 if ((__qClass(self) == @global(ByteArray)) |
1480 if ((__qClass(self) == @global(ByteArray)) |
1480 && (__qClass(aByteArray) == @global(ByteArray)) |
1481 && (__qClass(aByteArray) == @global(ByteArray)) |
1481 && __isSmallInteger(nBitsPerPixel) |
1482 && __isSmallInteger(nBitsPerPixel) |
1482 && __bothSmallInteger(height, width)) { |
1483 && __bothSmallInteger(height, width)) { |
1483 if ((aMapByteArray != nil) |
1484 if ((aMapByteArray != nil) |
1484 && (__Class(aMapByteArray) == @global(ByteArray))) { |
1485 && (__Class(aMapByteArray) == @global(ByteArray))) { |
1485 map = __ByteArrayInstPtr(aMapByteArray)->ba_element; |
1486 map = __ByteArrayInstPtr(aMapByteArray)->ba_element; |
1486 } else { |
1487 } else { |
1487 map = (unsigned char *)0; |
1488 map = (unsigned char *)0; |
1488 } |
1489 } |
1489 |
1490 |
1490 bitsPerPixel = __intVal(nBitsPerPixel); |
1491 bitsPerPixel = __intVal(nBitsPerPixel); |
1491 w = __intVal(width); |
1492 w = __intVal(width); |
1492 h = __intVal(height); |
1493 h = __intVal(height); |
1493 src = __ByteArrayInstPtr(self)->ba_element; |
1494 src = __ByteArrayInstPtr(self)->ba_element; |
1494 dst = __ByteArrayInstPtr(aByteArray)->ba_element; |
1495 dst = __ByteArrayInstPtr(aByteArray)->ba_element; |
1495 switch (bitsPerPixel) { |
1496 dstEnd = dst + __byteArraySize(aByteArray); |
1496 case 1: |
1497 switch (bitsPerPixel) { |
1497 mask = 0x01; |
1498 case 1: |
1498 break; |
1499 mask = 0x01; |
1499 case 2: |
1500 break; |
1500 mask = 0x03; |
1501 case 2: |
1501 break; |
1502 mask = 0x03; |
1502 case 4: |
1503 break; |
1503 mask = 0x0F; |
1504 case 4: |
1504 break; |
1505 mask = 0x0F; |
1505 case 8: |
1506 break; |
1506 mask = 0xFF; |
1507 case 8: |
1507 break; |
1508 mask = 0xFF; |
1508 default: |
1509 break; |
1509 goto fail; |
1510 default: |
1510 } |
1511 goto fail; |
1511 if (map) { |
1512 } |
1512 /* |
1513 if (map) { |
1513 * if a map is present, it must have entries for |
1514 /* |
1514 * all possible byte-values (i.e. its size must be >= 256) |
1515 * if a map is present, it must have entries for |
1515 */ |
1516 * all possible byte-values (i.e. its size must be >= 256) |
1516 if ((__qSize(aMapByteArray) - OHDR_SIZE) < 256) |
1517 */ |
1517 goto fail; |
1518 if ((__qSize(aMapByteArray) - OHDR_SIZE) < 256) |
1518 } |
1519 goto fail; |
1519 |
1520 } |
1520 bytesPerRow = (w * bitsPerPixel + 7) / 8; |
1521 |
1521 dstBytes = bytesPerRow * h; |
1522 bytesPerRow = (w * bitsPerPixel + 7) / 8; |
1522 srcBytes = w * h; |
1523 dstBytes = bytesPerRow * h; |
1523 |
1524 srcBytes = w * h; |
1524 if ((__byteArraySize(self) >= srcBytes) |
1525 |
1525 && (__byteArraySize(aByteArray) >= dstBytes)) { |
1526 if ((__byteArraySize(self) >= srcBytes) |
1526 for (hrun=h; hrun; hrun--) { |
1527 && (__byteArraySize(aByteArray) >= dstBytes)) { |
1527 dstNext = dst + bytesPerRow; |
1528 for (hrun=h; hrun; hrun--) { |
1528 bits = 0; shift = 8; |
1529 dstNext = dst + bytesPerRow; |
1529 if (map) { |
1530 bits = 0; shift = 8; |
1530 for (wrun=w; wrun; wrun--) { |
1531 if (map) { |
1531 bits = (bits << bitsPerPixel) | (map[*src++] & mask); |
1532 for (wrun=w; wrun; wrun--) { |
1532 shift -= bitsPerPixel; |
1533 bits = (bits << bitsPerPixel) | (map[*src++] & mask); |
1533 if (shift == 0) { |
1534 shift -= bitsPerPixel; |
1534 *dst++ = bits; |
1535 if (shift == 0) { |
1535 bits = 0; shift = 8; |
1536 if (dst == dstEnd) goto fail; |
1536 } |
1537 *dst++ = bits; |
1537 } |
1538 bits = 0; shift = 8; |
1538 } else { |
1539 } |
1539 for (wrun=w; wrun; wrun--) { |
1540 } |
1540 bits = (bits << bitsPerPixel) | (*src++ & mask); |
1541 } else { |
1541 shift -= bitsPerPixel; |
1542 for (wrun=w; wrun; wrun--) { |
1542 if (shift == 0) { |
1543 bits = (bits << bitsPerPixel) | (*src++ & mask); |
1543 *dst++ = bits; |
1544 shift -= bitsPerPixel; |
1544 bits = 0; shift = 8; |
1545 if (shift == 0) { |
1545 } |
1546 if (dst == dstEnd) goto fail; |
1546 } |
1547 *dst++ = bits; |
1547 } |
1548 bits = 0; shift = 8; |
1548 if (shift != 8) { |
1549 } |
1549 *dst = bits; |
1550 } |
1550 } |
1551 } |
1551 dst = dstNext; |
1552 if (shift != 8) { |
1552 } |
1553 if (dst == dstEnd) goto fail; |
1553 RETURN ( self ); |
1554 *dst = bits; |
1554 } |
1555 } |
|
1556 dst = dstNext; |
|
1557 } |
|
1558 RETURN ( self ); |
|
1559 } |
1555 } |
1560 } |
1556 fail: ; |
1561 fail: ; |
1557 %} |
1562 %} |
1558 . |
1563 . |
1559 self primitiveFailed |
1564 self primitiveFailed |