JPEGView/Source/68020/DecodeDummyRow.a
Aaron Giles 92bdb55672 JPEGView 3.3 for Macintosh
These are the sources for the final official release of JPEGView for the
Mac, back in 1994.
2015-02-05 00:18:10 -08:00

1 line
7.4 KiB
Plaintext

;*********************************************************/
;* This source code copyright (c) 1991-2001, Aaron Giles */
;* See the Read Me file for licensing information. */
;* Contact email: mac@aarongiles.com */
;*********************************************************/
movem.l d3-d7/a2-a4/a6,-(sp) ;Save all registers
move.l 44(sp),a6 ;get the address of the CopyData structure in a6
;(based off stack: 9 registers + 1 a6 link + 1 return addr.
; = 12 * 4 bytes = 48 bytes)
movem.l store(a6),d1-d7/a0/a2-a4;Restore some important variables
movea.l dest(a6),a1 ;Point a1 to the destination
tst.l a1 ;Are we just initializing?
beq.w @InitTree ;If so, do it and get outta here
move.w width(a6),d1 ;Get the width in d1
subq.w #1,d1 ;Decrement for dbra instruction
@ILoop:
cmpa.l a4,a2 ;Is the stack empty?
beq.s @NewCode ;If so, get a new code
;***** move.b -(a2),(a1)+ ;Otherwise, copy to destination
subq.w #1,a2 ;Otherwise, pull a byte off the stack
@EndI:
dbra.w d1,@ILoop ;Decrement and loop until done
clr.b theReturn(a6) ;Store false
bra.w @Return ;Return and exit
;
; Get a new code of the appropriate length = (lo)d2
;
@NewCode:
swap d1 ;Low word of d1 = byte count
swap d4 ;Low word of d4 = bits in buffer
@NCLoop:
cmp.w d4,d2 ;Compare the code size to the buffer size
ble.s @GotCode ;If there's enough we're done
tst.w d1 ;Any more bytes available?
bne.s @NCAddByte ;If so, skip ahead
move.b (a0)+,d1 ;Get a new byte count
beq.w @ReturnT ;Return true if zero
@NCAddByte:
subq.w #1,d1 ;Decrement the byte count
clr.l d0 ;Clear the accumulator
move.b (a0)+,d0 ;Get the next byte
lsl.l d4,d0 ;Shift these new bits over
or.l d0,d3 ;Or them into the buffer
addq.w #8,d4 ;Adjust the buffer size
bra.s @NCLoop ;Loop until we have enough bits
@GotCode:
move.l d3,d0 ;Copy buffer into accumulator
swap d7 ;Low word of d7 = (1 << codeSize) - 1
and.w d7,d0 ;Keep only as many bits as we need
swap d7 ;Put it back in the high word
lsr.l d2,d3 ;Shift these bits out of the buffer
sub.w d2,d4 ;Adjust the bitcount of the buffer
swap d4 ;Low word of d4 = tree size
swap d1 ;Low word of d1 = column counter
;
; Process the code
;
cmp.w d5,d0 ;Clear code?
beq.w @ClrTree ;If so, reset the LZW tree
swap d5 ;Low word of d5 = endCode
cmp.w d5,d0 ;End code?
beq.w @ReturnT ;If so, return with a true
swap d5 ;Otherwise put d5 back
;
; Handle a normal code
;
swap d6 ;Low word of d6 = old
move.w d0,d6 ;Save a copy of the current code in d6
swap d6 ;In the high word
cmp.w d4,d0 ;Is it a valid code?
blt.s @DecLoop ;If so, continue
bne.w @SignalError ;//If not equal to tree size, then invalid
swap d2 ;Otherwise, low word of d2 = first
move.b d2,(a2)+ ;Push that on the stack
swap d2 ;Restore d2
move.w d6,d0 ;Current code = last code
@DecLoop:
cmp.w d5,d0 ;Is the code greater than clear code?
blt.s @DecDone ;Skip out if so
move.l (0,a3,d0.w*4),d0 ;Get the parent and code for this node
move.b d0,(a2)+ ;Push code on the stack
swap d0 ;Get the parent in the low word
bra.s @DecLoop ;Loop until we're done
@DecDone:
;***** move.b d0,(a1)+ ;Send this last guy to the output
swap d2 ;Low word of d2 = first
move.w d0,d2 ;Store this for later
swap d2 ;In the high word
;
; Add a new node, if there's room
;
cmpi.w #4096,d4 ;Is the tree max'ed out?
bge.s @EndI ;If so, just loop
swap d0 ;Swap the current node high
move.w d6,d0 ;Put last into d0
swap d0 ;Back to the correct order
swap d6 ;Set last = old
move.l d0,(0,a3,d4.w*4) ;Add this to the tree
addq.w #1,d4 ;Increment the tree size
cmp.w d7,d4 ;Should we increase the code size?
blt.w @EndI ;If not, just loop
cmpi.w #12,d2 ;*Can* we increase the code size?
beq.w @EndI ;If not, just loop
lsl.l #1,d7 ;Shift both words of d7 up one bit
ori.l #65536,d7 ;OR in a new mask bit (65536 == $00010000)
addq.w #1,d2 ;Increment the code size
bra.w @EndI ;Loop for some more
;
; Initialize the LZW tree
;
@InitTree:
movea.l src(a6),a0 ;Get the input address
movea.l tree(a6),a3 ;Get the tree address
clr.w d0 ;Clear d0
move.b (a0)+,d0 ;Get the char size in d0
move.w d0,charSize(a6) ;Store this elsewhere
movea.l stack(a6),a2 ;Point a2 to the stack
move.l a2,a4 ;Copy this into a4
clr.l d1 ;Erase d1
clr.l d3 ;Erase d3
moveq.l #1,d4 ;Set the tree size to 1
lsl.l d0,d4 ;Shift it left by char size
move.w d4,d5 ;Copy it to d5 for the end code
addq.w #1,d5 ;Increment by 1 = end code
swap d5 ;Put that into the high word
move.w d4,d5 ;Copy tree size into low word = clear
addq.w #2,d4 ;tree size += 2
addq.w #1,d0 ;Increment the char size = code size
move.w d0,d2 ;Store as the code size
move.l #65537,d7 ;Put 1's in high & low of d7 (65537 == $00010001)
lsl.l d0,d7 ;Shift left by code size
subi.l #65536,d7 ;Decrement the high word by 1 (65536 == $00010000)
bra.s @ReturnT ;Return a true
;
; Reset the LZW tree
;
@ClrTree:
move.w charSize(a6),d0 ;Get charSize
move.w #1,d4 ;Set the tree size to 1
lsl.w d0,d4 ;Shift it left by charSize
addq.w #2,d4 ;Tree size += 2
addq.w #1,d0 ;Increment the char size = code size
move.w d0,d2 ;Store as the code size
move.l #65537,d7 ;Put 1's in high & low of d7 (65537 == $00010001)
lsl.l d0,d7 ;Shift left by code size
subi.l #65536,d7 ;Decrement the high word by 1 (65536 == $00010000)
;
; Get a new code of the appropriate length = (lo)d2
;
swap d1 ;Low word of d1 = byte count
swap d4 ;Low word of d4 = bits in buffer
@CCLoop:
cmp.w d4,d2 ;Compare the code size to the buffer size
ble.s @CGtCode ;If there's enough we're done
tst.w d1 ;Any more bytes available?
bne.s @CCAddByte ;If so, skip ahead
move.b (a0)+,d1 ;Get a new byte count
beq.s @ReturnT ;Return true if zero
@CCAddByte:
subq.w #1,d1 ;Decrement the byte count
clr.l d0 ;Clear the accumulator
move.b (a0)+,d0 ;Get the next byte
lsl.l d4,d0 ;Shift these new bits over
or.l d0,d3 ;Or them into the buffer
addq.w #8,d4 ;Adjust the buffer size
bra.s @CCLoop ;Loop until we have enough bits
@CGtCode:
move.l d3,d0 ;Copy buffer into accumulator
swap d7 ;Low word of d7 = (1 << codeSize) - 1
and.w d7,d0 ;Keep only as many bits as we need
swap d7 ;Put it back in the high word
lsr.l d2,d3 ;Shift these bits out of the buffer
sub.w d2,d4 ;Adjust the bitcount of the buffer
cmp.w d5,d0 ;Is it another clear code?
beq.s @CCLoop ;If so, get another code
swap d4 ;Low word of d4 = tree size
swap d1 ;Low word of d1 = column counter
;***** move.b d0,(a1)+ ;Store this as the output
swap d2 ;Low word of d2 = first
move.w d0,d2 ;This code is also first
swap d2 ;But in the high word
move.w d0,d6 ;It's also the last
bra.w @EndI ;Continue on
;
; Return to the program
;
@ReturnT:
move.b #1,theReturn(a6) ;Store a one
@Return:
move.l theEnd(a6),a1 ;Get the end of data pointer
cmp.l a0,a1 ;Did we pass the end of data?
bgt.s @NoError ;If not, no error
@SignalError:
clr.l theEnd(a6)
@NoError:
movem.l d1-d7/a0/a2-a4,store(a6);Save some important variables
movem.l (sp)+,d3-d7/a2-a4/a6 ;Restore all registers