summaryrefslogtreecommitdiff
path: root/Source/DecodePic.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/DecodePic.S
downloadiff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.tar.gz
iff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.tar.bz2
iff-library-36c824864c02f0a3f62c8a1d365d1670835c8c96.zip
Initial revision
Diffstat (limited to 'Source/DecodePic.S')
-rw-r--r--Source/DecodePic.S232
1 files changed, 232 insertions, 0 deletions
diff --git a/Source/DecodePic.S b/Source/DecodePic.S
new file mode 100644
index 0000000..e8877a5
--- /dev/null
+++ b/Source/DecodePic.S
@@ -0,0 +1,232 @@
+**
+** $Id: $
+** $Revision: $
+**
+** $Filename: DecodePic.S $
+** $Author: Christian A. Weber $
+** $Release: 19.1 $
+** $Date: 92/05/11 21:11:27 $
+**
+** iff.library/IFFLib_DecodePic
+**
+** 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_DecodePic
+ SECTION text,CODE
+
+ INCLUDE "IFFLib.i"
+
+ XREF ClearError,SetError,GetBMHDFunc,FindChunkFunc
+ XDEF DecodePicFunc
+
+
+******* iff.library/IFFLib_DecodePic ****************************************
+*
+* NAME
+* IFFLib_DecodePic -- decode the BODY of an ILBM file into a BitMap
+*
+* SYNOPSIS
+* success = IFFLib_DecodePic( ifffile, bitmap )
+* D0 A1 A0
+*
+* BOOL IFFLib_DecodePic( IFFFILE, struct BitMap * )
+*
+* FUNCTION
+* Decodes and decompresses a picture into the user supplied BitMap.
+* If the picture is larger than your BitMap's planes, it will be
+* truncated. If your BitMap is larger than the picture, the picture
+* will be drawn into the top left corner of your BitMap.
+* If the picture has less planes than the BitMap, the unused planes
+* are NOT touched by this routine, so you may wish to clear them
+* before calling IFFLib_DecodePic(). If the picture has more planes
+* than your BitMap, the surplus planes of the picture are ignored.
+*
+* INPUTS
+* ifffile - IFF file pointer, from IFFLib_OpenIFF()
+* bitmap - Pointer to a properly initialized BitMap structure:
+* bm_Planes[] must point to valid BitPlanes,
+* bm_Depth contains the number of planes.
+* bm_Width and bm_Height must be set according to the
+* size of your bit planes.
+*
+* RESULTS
+* Non-zero if OK, 0 if error, Call IFFError() to know the reason
+* of the failure
+*
+* NOTE
+* This routine needs at least 620 bytes of stack space
+*
+* SEE ALSO
+*
+*****************************************************************************
+
+ STRUCTURE DecodePicStackFrame,0
+ STRUCT WorkPlanes,24*4 ; muß am Anfang sein
+ STRUCT LineBuffer,400 ; max 3200 pixel bei stencil
+ LABEL LINKSIZE
+
+DecodePicFunc: movem.l d2-d7/a2-a6,-(SP)
+ lea -LINKSIZE(SP),SP ; Lokalen Datenraum schaffen
+ movea.l a6,a5 ; A5: IFFBase für SetError()
+ movea.l a0,a3 ; A3: BitMap
+ movea.l a1,a4 ; A4: IFFFile
+
+ *** Testen ob ILBM-File
+
+ cmpi.l #'ILBM',8(a4) ; ist's überhaupt ein ILBM-File ?
+ beq.s 1$ ; ja --->
+ moveq #IFF_NOILBM,d0 ; Fehlernummer
+ bra .Error
+1$:
+ *** BitMapHeader suchen und nach A2
+
+ bsr GetBMHDFunc ; BitMapHeader suchen
+ ;; tst.l d0
+ bne.s 2$ ; gefunden --->
+ moveq #IFF_NOBMHD,d0 ; Fehlernummer
+ bra .Error
+2$: movea.l d0,a2 ; A2: BitMapHeader
+
+ *** Testen ob Bild-Depth <= BitMap Depth
+
+ move.b bmh_nPlanes(a2),d2 ; D2: Depth (Minimum)
+ beq .Okay ; Bild hat 0 planes --->
+3$:
+ *** Planes in Arbeitsbereich kopieren
+
+ moveq.l #23,d0 ; Max. 24 Bitplanes
+ lea bm_Planes(a3),a0 ; Source
+ lea WorkPlanes(SP),a1 ; Destination
+.CopyLoop: move.l (a0)+,(a1)+
+ dbf d0,.CopyLoop
+
+ *** BODY-Chunk suchen und nach A0, BODY-Ende nach A4
+
+ move.l #'BODY',d0
+ movea.l a4,a1 ; IFF-File
+ bsr FindChunkFunc
+ ;; tst.l d0
+ bne.s 4$ ; gefunden --->
+ moveq #IFF_NOBODY,d0 ; Fehlernummer
+ bra .Error
+4$:
+ movea.l d0,a0 ; A0 : Body-Adresse
+ addq.l #4,a0 ; 'BODY' überspringen
+ movea.l (a0)+,a4 ; Chunk-size
+ adda.l a0,a4 ; A4 : Body-Endadresse
+
+ *** Compression testen und entsprechende Routine nach A6
+
+ move.b bmh_Compression(a2),d0
+ bne.s 5$
+ lea CopyRow(PC),a6 ; Not crunched
+ bra.s 7$ ; --->
+5$:
+ cmpi.b #1,d0 ; CmpByteRun1 ?
+ bne.s 6$ ; ja --->
+ lea DecrunchRow(PC),a6 ; CmpByteRun1
+ bra.s 7$ ; --->
+6$:
+ moveq #IFF_UNKNOWNCOMPRESSION,d0
+ bra.s .Error
+7$:
+ *** Masking testen und wenn 'hasmask' (Stencil) D7.B:=$FF, sonst $00
+
+ cmpi.b #1,bmh_Masking(a2) ; 'mskHasMask' ?
+ seq d7 ; wenn ja: D7 := $FF
+
+ *** Modulos setzen etc.
+
+.doit: moveq.l #0,d4 ; D4 : Source-Modulo
+ move.w bmh_Width(a2),d4
+ add.w #15,d4 ; auf WORD aufrunden
+ lsr.l #3,d4
+ bclr #0,d4 ; auf WORD aufrunden
+
+ moveq.l #0,d5
+ move.w bm_BytesPerRow(a3),d5 ; D5 : Destination-Modulo
+
+ moveq.l #0,d6
+ move.w bm_Rows(a3),d6 ; D6 : Max. Anzahl Zeilen
+ cmp.w bmh_Height(a2),d6 ; BitMap zu groß ?
+ ble.s 8$ ; nein --->
+ move.w bmh_Height(a2),d6 ; Sonst Höhe aus bmh nehmen
+8$:
+ bra.s .CheckCond ; ---> für dbf
+
+ *** Hauptschleife
+
+.body1: moveq #0,d3 ; Init plane-counter
+ lea WorkPlanes(SP),a2 ; A2 : Arbeitskopie der Planes
+
+.body2: move.l d4,d0 ; Source bytes per row
+ cmp.b bm_Depth(a3),d3 ; Is there a dest-plane ?
+ bhs.s .NoDest ; nope ---> skip it
+ movea.l (a2),a1 ; Adrese der aktuellen Plane
+ add.l d5,(a2)+ ; Plane auf nächste Linie
+ bra.s 9$
+.NoDest: lea LineBuffer(SP),a1 ; Plane ins NIL kopieren
+9$: jsr (a6) ; Linie copyren / decrunchen
+ addq.b #1,d3 ; INC planecounter
+ cmp.b d2,d3
+ blt.s .body2 ; ---> Nächste Plane
+
+ tst.b d7 ; Maske zu überhüpfen ?
+ beq.s .NoMask ; nein --->
+ move.l d4,d0 ; Source bytes per row
+ lea LineBuffer(SP),a1 ; Maske zur Hölle schicken
+ jsr (a6) ; Linie copyren / decrunchen
+.NoMask:
+.CheckCond: cmpa.l a4,a0 ; fertig ?
+ dbhs d6,.body1 ; wenn nicht: nächste Linie
+
+.Okay: bsr ClearError ; IFFError rücksetzen, D0 := 1
+ bra.s .Ende
+
+.Error: bsr SetError ; IFFError setzen, clr.l d0
+
+.Ende: lea LINKSIZE(SP),SP
+ movem.l (SP)+,d2-d7/a2-a6
+ rts
+
+
+*************** 1 Linie kopieren *****************************************
+
+copyloop: move.b (a0)+,(a1)+
+CopyRow: dbf d0,copyloop
+ rts
+
+
+*************** 1 Linie decrunchen ***************************************
+
+DecrunchRow: move.l d2,-(SP)
+
+1$: moveq.l #0,d1
+ move.b (a0)+,d1 ; D1 : nächstes Kommando-Byte
+ bmi.s 2$ ; crunched --->
+
+.CopyLoop: move.b (a0)+,(a1)+ ; D1+1 Bytes normal kopieren
+ subq.w #1,d0 ; DEC ColumnCounter
+ dble d1,.CopyLoop
+ bra.s 3$ ; --->
+2$:
+ neg.b d1
+ bmi.s 3$ ; ~$80 (== $80) ist 'NOP'
+ move.b (a0)+,d2 ; Zu repetierender Wert
+.RepLoop: move.b d2,(a1)+
+ subq.w #1,d0 ; DEC ColumnCounter
+ dble d1,.RepLoop
+3$:
+ tst.w d0 ; Linie fertig ?
+ bgt.s 1$ ; noch nicht ---> Loop
+
+ move.l (SP)+,d2
+ rts
+
+ END