summaryrefslogtreecommitdiff
path: root/Source/CompressBlock.S
diff options
context:
space:
mode:
authorChristian A. Weber <chris@gna.ch>1992-05-12 22:26:12 +0000
committerChristian A. Weber <chris@gna.ch>1992-05-12 22:26:12 +0000
commit36c824864c02f0a3f62c8a1d365d1670835c8c96 (patch)
treef3f433e4af522925d4c91f56865d38efaf83a456 /Source/CompressBlock.S
downloadiff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.tar.gz
iff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.tar.bz2
iff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.zip
Initial revision
Diffstat (limited to 'Source/CompressBlock.S')
-rw-r--r--Source/CompressBlock.S144
1 files changed, 144 insertions, 0 deletions
diff --git a/Source/CompressBlock.S b/Source/CompressBlock.S
new file mode 100644
index 0000000..14984ec
--- /dev/null
+++ b/Source/CompressBlock.S
@@ -0,0 +1,144 @@
+**
+** $Id: $
+** $Revision: $
+**
+** $Filename: CompressBlock.S $
+** $Author: Christian A. Weber $
+** $Release: $
+** $Date: 92/05/12 22:26:30 $
+**
+** iff.library/IFFLib_CompressBlock
+**
+** COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2,
+** CH-8037 ZUERICH, SWITZERLAND. ALL RIGHTS RESERVED. NO PART
+** OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED
+** IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PER-
+** MISSION OF THE AUTHOR. USE AT YOUR OWN RISK.
+**
+
+
+ IDNT IFFLib_CompressBlock
+ SECTION text,CODE
+
+ INCLUDE "IffLib.i"
+
+ XREF ClearError
+ XDEF CompressBlockFunc
+
+
+******* iff.library/IFFLib_CompressBlock ************************************
+*
+* NAME
+* IFFLib_CompressBlock -- Compress a memory block
+*
+* SYNOPSIS
+* result = IFFLib_CompressBlock( source, destination, size, mode )
+* A0 A1 D0 D1
+*
+* ULONG IFFLib_CompressBlock( APTR, APTR, ULONG, ULONG )
+*
+* FUNCTION
+* Compress the memory block using the appropriate compression mode.
+* If the compressed data would become longer than the uncompressed,
+* an error is returned.
+*
+* INPUTS
+* source - Pointer to data to compress
+* destination - Target address for compression
+* size - Number of data bytes to compress
+* mode - Compression mode. Currently, the following modes
+* are supported:
+* $$$
+*
+* RESULTS
+* Length of compressed data or 0 if an error occurred.
+*
+* SEE ALSO
+* IFFLib_DecompressBlock()
+*
+*****************************************************************************
+
+CompressBlockFunc:
+ tst.l d1 ; Modus == 0 ?
+ beq.b Mode_Copy
+ subq.l #1,d1 ; Modus == 1 ?
+ beq.b Mode_CmpByteRun1
+ moveq.l #0,d0
+ rts
+
+*****************************************************************************
+** Kopiermodus
+
+Mode_Copy: movem.l d0/a6,-(SP)
+ movea.l ib_SysBase(a6),a6
+ JSRLIB CopyMem
+ movem.l (SP)+,d0/a6
+ rts
+
+*****************************************************************************
+** CmpByteRun1 komprimieren
+
+Mode_CmpByteRun1:
+ movem.l d2-d3/a2-a3,-(SP)
+ lea (a0,d0.l),a2 ; A2 : Source-Endadresse
+ moveq #0,d3 ; Byte-Zähler
+
+crunchloop: bsr.b CountEq ; wieviele gleiche Bytes folgen ?
+ cmp.w #3,d0 ; genug gleiche Bytes zum runnen ?
+ blt.b countdump ; nee, lohnt sich nicht -> Dumpen
+
+ addq.l #2,d3 ; Markierbyte & Anzahl
+ move.b (a0),d1 ; Wert
+ adda.w d0,a0 ; Source anpassen
+ subq.w #1,d0 ; muss .w sein und nicht .b !!!!!!!
+ neg.b d0 ; negieren (= "Run"-Code)
+ move.b d0,(a1)+ ; und eintragen
+ move.b d1,(a1)+ ; Wert eintragen
+ bra.b crunchcont ; weitermachen
+
+countdump: movea.l a0,a3 ; Source-Pointer retten
+ moveq #0,d2 ; D2 : Länge des Dump-Blocks
+1$: addq.b #1,d2
+ bmi.b 2$ ; höchstens 127 Bytes pro Block
+ addq.l #1,a0
+ cmpa.l a2,a0 ; Ende der Linie erreicht ?
+ bge.b 3$ ; ja -> abbrechen
+ bsr.b CountEq
+ cmp.w #3,d0 ; Ende des Dump-Blocks ?
+ blt.b 1$ ; noch nicht
+ bra.b 3$ ; Ende
+2$: moveq #127,d2
+3$: movea.l a3,a0 ; Source-Pointer restaurieren
+
+ add.l d2,d3 ; zur Gesamtanzahl dazuzählen
+ addq.l #1,d3 ; Markierbyte nicht vergessen
+ subq.w #1,d2 ; aus 1..128 mach 0..127
+ move.b d2,(a1)+ ; Markierbyte eintragen
+4$: move.b (a0)+,(a1)+ ; Datenbytes eintragen
+ dbf d2,4$
+
+
+crunchcont: cmpa.l a2,a0 ; Ende der Linie erreicht ?
+ blt.b crunchloop ; noch nicht!
+
+ move.l d3,d0 ; Return: Anzahl Destination-Bytes
+ movem.l (SP)+,d2-d3/a2-a3
+ rts
+
+ *** Anzahl gleicher Zeichen ab (a0) zählen und nach D0
+
+CountEq: move.l a0,-(SP)
+ moveq #1,d0 ; D0 : Anzahl gleiche Bytes
+1$: move.b (a0)+,d1 ; erstes Byte
+2$: cmp.b (a0)+,d1 ; Byte gleich wie letztes Byte ?
+ bne.b 3$ ; nein -> abbrechen
+ cmp.w #128,d0
+ bge.b 3$ ; höchstens 128 gleiche
+ addq.w #1,d0 ; Anzahl erhöhen
+ cmpa.l a2,a0 ; Ende der Linie erreicht ?
+ blt.b 2$ ; noch nicht -> weiterzählen
+3$: move.l (SP)+,a0
+ rts
+
+ END
+