home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / graphics / crack136 / crackart / compress / ca_pack.s < prev    next >
Text File  |  1991-10-19  |  10KB  |  258 lines

  1.  
  2. ; CRACK ART Kompressionsroutine für Bilddaten (CA?)
  3. ; Copyright © Detlef Röttger 04.03.1990
  4.  
  5. ; GFA-Aufruf: Länge%=C:CA_COMPRESS%( l:Quelle, l:Ziel )
  6.  
  7. ; Kompressions-Codes:
  8. ; Byte                   = unkomprimiertes Byte
  9. ; ESC ESC                = ein ESC Byte
  10. ; ESC Anzahl-1 Byte      = Anzahl gleiche Bytes
  11. ; ESC 0 Anzahl-1 Byte    = Anzahl gleiche Bytes (nötig, falls Anzahl-1=ESC)
  12. ; ESC 1 Mult Rest-1 Byte = 256 * Mult + Rest gleiche Bytes
  13. ; ESC 2 Mult Rest-1      = 256 * Mult + Rest DELTA Bytes
  14. ; ESC 2 0                = Bildende
  15.  
  16. ; Komprimiertes Image:
  17. ; ESC.b DELTA.b OFFSET.w Komprimierte_Bilddaten... ESC 2 0
  18.  
  19.                 TEXT
  20.  
  21.                 movem.l d1-a6,-(sp)
  22.  
  23.                 movem.l 60(sp),a0-a1    ; Quelle/Ziel
  24.                 movea.l 64(sp),a1       ; Zieladresse
  25.  
  26.                 movea.l a1,a2           ; Platz für die Bytehäufigkeit vorbereiten
  27.                 move.w  #255,d0
  28. init:           clr.w   (a2)+
  29.                 dbra    d0,init
  30.  
  31.                 movea.l a0,a2           ; Bytehäufigkeit zählen
  32.                 move.w  #31999,d0       ; 32000 Bytes pro Bildschirm
  33. zaehl:          clr.w   d1
  34.                 move.b  (a2)+,d1        ; Byte vom Quellbildschirm
  35.                 add.w   d1,d1
  36.                 addq.w  #1,0(a1,d1.w)   ; wortweise reicht
  37.                 dbra    d0,zaehl
  38.  
  39. ; Das seltenste Byte finden, von hinten suchen, damit die Wahrscheinlichkeit,
  40. ; daß das ESC Byte mit dem Anzahl-Zähler übereinstimmt, geringer wird
  41. ; (ESC 0 Anzahl-1 Byte) soll so selten wie möglich auftreten
  42.  
  43.                 movea.l a1,a2           ; Minimum finden
  44.                 lea     512(a2),a2      ; an das Ende der Zähler
  45.                 move.w  #32500,d1       ; Minimum vorbelegen
  46.                 move.w  #252,d0         ; Bytes 0,1,2 sind reservierte Codes
  47. minimum:        move.w  -(a2),d2
  48.                 cmp.w   d1,d2           ; mit bisherigem Minimum vergleichen
  49.                 bge.s   nextmin         ; das erste Minimum behalten
  50.                 move.w  d0,d3           ; Zähler merken
  51.                 move.w  d2,d1           ; neues Minimum merken
  52.                 beq.s   minend          ; d1=0 kein kleinerer Wert moeglich
  53. nextmin:        dbra    d0,minimum
  54. minend:         addq.w  #3,d3           ; das ist das Esc Byte
  55.                 move.w  d3,d7           ; ESC Byte merken
  56.  
  57.                 movea.l a1,a2           ; Maximum finden
  58.                 move.w  #-1,d1          ; Maximum vorbelegen
  59.                 move.w  #255,d0
  60. maximum:        move.w  (a2)+,d2
  61.                 cmp.w   d1,d2           ; mit bisherigem Maximum vergleichen
  62.                 ble.s   nextmax         ; bei gleichhäufigen Bytes das erste nehmen
  63. ;                                         damit ESC und DELTA niemals gleich sein koennen
  64.                 move.w  d0,d3           ; Zähler merken
  65.                 move.w  d2,d1           ; neues Maximum merken
  66. nextmax:        dbra    d0,maximum
  67.                 neg.w   d3
  68.                 addi.w  #255,d3         ; das ist das DELTA Byte
  69.                 move.w  d3,d6           ; DELTA Byte merken
  70.  
  71.  
  72. ; =================================== Hier beginnt der Kompressionsalgorithmus
  73.  
  74.                 movea.l 60(sp),a0       ; Quelladresse
  75.                 lea     32000(a0),a2    ; Endadresse
  76.  
  77.                 move.w  #32000,d4       ; Vergleichslänge
  78.                 lea     offset(pc),a6   ; Offsetliste
  79.  
  80. while:          movea.l (a6)+,a5        ; Offset holen
  81.                 cmpa.l  #0,a5
  82.                 beq.s   endwhile        ; Offset=0 ist Abbruchkriterium
  83.                 cmpa.l  #-1,a5
  84.                 beq.s   endprg          ; -1 ist Programmende
  85.  
  86.                 movem.l 60(sp),a0/a3    ; Quelle/Ziel
  87.                 movea.l a0,a1           ; Workadresse
  88.                 move.b  d7,(a3)+        ; ESC auf Zielbildschirm merken
  89.                 move.b  d6,(a3)+        ; DELTA uebertragen
  90.                 move.w  a5,(a3)+        ; Offset
  91.                 move.w  #4,d3           ; Länge des komprimierten Bildes
  92. ;                                         ESC.b + DELTA.b + Offset.w
  93.                 move.l  a5,d0           ; Offset als
  94.                 subq.w  #1,d0           ; Durchlaufzähler
  95.  
  96. mainloop:       tst.w   d0
  97.                 bmi.s   endcode         ; neuer Offset
  98.                 move.b  (a1),d1         ; erstes Byte holen
  99.                 clr.w   d2              ; gleiche Bytes zählen
  100. testloop:                               ; Nächste Adresse errechnen
  101.                 adda.l  a5,a1           ; Offset addieren
  102.                 cmpa.l  a2,a1           ; Hinter dem Bildschirmende ?
  103.                 blt.s   nextok          ; wenn nicht, dann weiter
  104.                 addq.l  #1,a0           ; sonst Quelladresse einen weiter
  105.                 movea.l a0,a1           ; und neue Workadresse
  106.                 subq.w  #1,d0           ; ein Überschlag
  107.                 bmi.s   compress        ; Ende der Kompression anzeigen
  108. nextok:
  109.                 cmp.b   (a1),d1
  110.                 bne.s   compress        ; Reihe abgebrochen
  111.                 addq.w  #1,d2
  112.                 bra.s   testloop
  113.  
  114. endcode:        addq.w  #1,d3           ; Code: ESC 2 0  (Endekennung)
  115.                 cmp.w   d4,d3
  116.                 bge.s   while
  117.                 move.b  d7,(a3)+        ; ESC
  118.                 addq.w  #1,d3
  119.                 cmp.w   d4,d3
  120.                 bge.s   while
  121.                 move.b  #2,(a3)+        ; 2
  122.                 addq.w  #1,d3
  123.                 cmp.w   d4,d3
  124.                 bge.s   while
  125.                 clr.b   (a3)+           ; 0
  126.  
  127.                 move.w  d3,d4           ; neue Länge
  128.                 move.l  a5,d5           ; Offset merken
  129.                 bra.s   while           ; und weiter
  130.  
  131. endwhile:
  132.                 cmp.w   #32000,d4
  133.                 bge.s   endprg
  134.                 move.w  #32000,d4
  135.                 lea     shortest(pc),a6
  136.                 move.l  d5,(a6)
  137.                 move.l  #-1,4(a6)
  138.                 bra.s   while
  139.  
  140. endprg:         moveq   #0,d0
  141.                 move.w  d4,d0           ; Länge des komprimierten Bildes
  142.  
  143.                 movem.l (sp)+,d1-a6
  144.                 rts
  145.  
  146.  
  147. ; ========================================================= compress
  148. ; In d1.b ist das Byte, in d2.w die Anzahl
  149. compress:
  150.                 tst.w   d0
  151.                 bpl.s   intern
  152.                 cmp.b   d6,d1           ; DELTA
  153.                 beq.s   endcode
  154.  
  155. intern:         cmp.b   d7,d1
  156.                 bne.s   noesc
  157.  
  158. compesc:        addq.w  #1,d3           ; Code: ESC ESC
  159.                 cmp.w   d4,d3
  160.                 bge     while           ; nächste Kompression
  161.                 move.b  d7,(a3)+
  162.                 addq.w  #1,d3
  163.                 cmp.w   d4,d3
  164.                 bge     while
  165.                 move.b  d7,(a3)+
  166.                 dbra    d2,compesc      ; Länge erhöhen
  167.                 bra     mainloop        ; und weiter
  168.  
  169. noesc:          cmp.w   #2,d2
  170.                 bgt.s   more            ; mehr als 3 Bytes gleich
  171. uncomp:         addq.w  #1,d3           ; Code: Byte
  172.                 cmp.w   d4,d3
  173.                 bge     while
  174.                 move.b  d1,(a3)+        ; Byte
  175.                 dbra    d2,uncomp
  176.                 bra     mainloop
  177.  
  178. more:           cmp.w   #255,d2
  179.                 bgt.s   evenmore
  180.                 addq.w  #1,d3           ; Code: ESC Anzahl-1 Byte
  181.                 cmp.w   d4,d3           ; oder: ESC 0 Anzahl-1 Byte
  182.                 bge     while
  183.                 move.b  d7,(a3)+        ; ESC
  184.                 cmp.b   d7,d2           ; zufällig Anzahl-1 = ESC ?
  185.                 bne.s   morenorm
  186.                 addq.w  #1,d3
  187.                 cmp.w   d4,d3
  188.                 bge     while
  189.                 clr.b   (a3)+           ; 00
  190. morenorm:       addq.w  #1,d3
  191.                 cmp.w   d4,d3
  192.                 bge     while
  193.                 move.b  d2,(a3)+        ; Anzahl-1
  194.                 addq.w  #1,d3
  195.                 cmp.w   d4,d3
  196.                 bge     while
  197.                 move.b  d1,(a3)+        ; Byte
  198.                 bra     mainloop
  199.  
  200. evenmore:       cmp.b   d6,d1           ; DELTA ?
  201.                 beq.s   moredelta
  202.                 addq.w  #1,d3           ; Code: ESC 1 Mult Rest-1 Byte
  203.                 cmp.w   d4,d3
  204.                 bge     while
  205.                 move.b  d7,(a3)+        ; ESC
  206.                 addq.w  #1,d3
  207.                 cmp.w   d4,d3
  208.                 bge     while
  209.                 move.b  #1,(a3)+        ; 1
  210.                 addq.w  #1,d3
  211.                 cmp.w   d4,d3
  212.                 bge     while
  213.                 movea.w d2,a4           ; sichern
  214.                 lsr.w   #8,d2           ; div 256
  215.                 move.b  d2,(a3)+        ; Mult
  216.                 addq.w  #1,d3
  217.                 cmp.w   d4,d3
  218.                 bge     while
  219.                 move.w  a4,d2
  220.                 and.w   #255,d2
  221.                 move.b  d2,(a3)+        ; Rest-1
  222.                 addq.w  #1,d3
  223.                 cmp.w   d4,d3
  224.                 bge     while
  225.                 move.b  d1,(a3)+        ; Byte
  226.                 bra     mainloop
  227.  
  228. moredelta:      addq.w  #1,d3           ; Code: ESC 2 Mult Rest-1
  229.                 cmp.w   d4,d3
  230.                 bge     while
  231.                 move.b  d7,(a3)+
  232.                 addq.w  #1,d3
  233.                 cmp.w   d4,d3
  234.                 bge     while
  235.                 move.b  #2,(a3)+
  236.                 addq.w  #1,d3
  237.                 cmp.w   d4,d3
  238.                 bge     while
  239.                 movea.w d2,a4           ; sichern
  240.                 lsr.w   #8,d2           ; div 256
  241.                 move.b  d2,(a3)+
  242.                 addq.w  #1,d3
  243.                 cmp.w   d4,d3
  244.                 bge     while
  245.                 move.w  a4,d2
  246.                 and.w   #255,d2
  247.                 move.b  d2,(a3)+
  248.                 bra     mainloop
  249.  
  250.                 DATA
  251.                 EVEN
  252.  
  253. offset:         DC.L 160,8,80,1,2,4,320,640,480,0
  254.  
  255. shortest:       DC.L 0,-1
  256.  
  257.                 END
  258.