From 36c824864c02f0a3f62c8a1d365d1670835c8c96 Mon Sep 17 00:00:00 2001 From: "Christian A. Weber" Date: Tue, 12 May 1992 22:26:12 +0000 Subject: Initial revision --- Source/DecodePic.S | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 Source/DecodePic.S (limited to 'Source/DecodePic.S') 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 -- cgit v1.2.3