home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 106
/
EnigmaAmiga106CD.iso
/
indispensabili
/
grafica
/
amipeg_1.1
/
src
/
s24bit.s
< prev
next >
Wrap
Text File
|
1997-12-02
|
13KB
|
751 lines
;
; This source handles conversion from yuv to rgb space, which includes
; initialization of the conversion & clamp tables.
;
; Original routines are in 24bit.c, which mainly contained those lovely
; just-perfectly-fit-for-assembler-kick-ass constructions.
;
; Michael Rausch 14-4-94 1:12:57
;
SECTION text,CODE
;************************************************************************************
; We'll define the "ConvertColor" macro here to do fixed point arithmetic
; that'll convert from YCrCb to RGB using:
; R = L + 1.40200*Cr
; G = L - 0.34414*Cb - 0.71414*Cr
; B = L + 1.77200*Cb
;
; void InitColorDither(void)
XDEF @InitColorDither
@InitColorDither:
lea Cb_r_tab,a0
Cr_gb_off EQU 256*4
lea Cb_r_tab+Cr_gb_off,a1
move.w #255,d0
moveq #-128,d1
crgbtabs:
move.w d1,d2
muls.w #179,d2 ; 1.40200
asr.w #7,d2
add.w d2,d2
move.w d2,(a0)+ ;br
move.w d1,d2
muls.w #-91,d2 ; -0.71414
asr.w #7,d2
add.w d2,d2
move.w d2,(a1)+ ;bg
move.w d1,d2
muls.w #-44,d2 ; -0.34414
asr.w #7,d2
add.w d2,d2
move.w d2,(a0)+ ;rg
move.w d1,d2
muls.w #226,d2 ; 1.77200
asr.w #7,d2
add.w d2,d2
move.w d2,(a1)+ ;rb
addq.l #1,d1
dbra d0,crgbtabs
;
; create the clamp tables, including the shifted one
;
; IMPORTANT: The first versions had a MUCH too low clampsize, resulting in really
; annoying purple artifacts !!!
;
clampsize EQU 192
moveq #0,d1
lea _clamp-clampsize*2,a0 ; clear lower and upper 64 bytes
move.w #clampsize-1,d0
fill_ct1:move.w #$ff00,((clampsize+256)*2,a0)
move.w d1,(a0)+
dbra d0,fill_ct1
move.w #255,d0
fill_ct2:move.w d1,(a0)+
add.w #$100,d1
dbra d0,fill_ct2
rts
;************************************************************************************
;void ColorDitherImage(unsigned char *lum, unsigned char *cr, unsigned char *cb,
; unsigned char *out, int rows, int cols)
XDEF @ColorDitherImage_lores
@ColorDitherImage_lores:
; a0 unsigned char *lum
; a1 unsigned char *cr
; 4(sp) unsigned char *cb
; 8(sp) unsigned char *out
; d0 int rows
; d1 int cols
cdi_regs REG d2-d7/a2-a6 ; 6+5=11
movem.l cdi_regs,-(sp)
;saved7 EQU 0
saverows EQU 4
savecols EQU 8
localvars EQU savecols+4
cb_offset EQU localvars+11*4+4
out_offset EQU cb_offset+4
sub.w #localvars,sp
move.l d1,(savecols,sp)
lsr.l #1,d0
subq.l #1,d0
move.l d0,d7
move.l a0,a2 ; lum1
move.l a2,a3
add.l d1,a3 ; lum2 = lum1+cols
move.l a1,a4 ; cr channel
move.l cb_offset(sp),d5
sub.l a4,d5 ; cb channel is addressed via its offset to the cr channel
lea Cb_r_tab,a5 ; conversion tab(s)
move.l (out_offset,sp),a0 ; row1
move.l a0,a1
add.l d1,d1
add.l d1,a1 ; row2=row1+cols*2
all_rows_lores:
move.l (savecols,sp),d6
lsr.l #1,d6
subq.l #1,d6
all_cols_lores:
; free: d4
moveq #0,d1
moveq #0,d2
move.b (a4,d5.l),d1 ; CB channel
move.b (a4)+,d2 ; CR channel
move.l (a5,d1.w*4),d0 ; cb_r cb_g
move.l (Cr_gb_off,a5,d2.w*4),d1 ; cr_g cr_b
move.w d1,d2
swap d1
add.w d0,d1
swap d0
sub.w d1,d0
sub.w d1,d2
ext.l d1
add.l #_clamp,d1
; d0 cb_r *2
; d1 (cr_g+cb_g) *2
; d2 cr_b *2
moveq #0,d3 ; *lum++
move.b (a2)+,d3
move.l d1,a6 ; clamp table includes on L
add.l d3,d3
add.l d3,a6
move.w (a6,d0.w),d3 ; r
or.b (a6),d3 ; g
swap d3
move.b (a2)+,d3 ; *lum++
move.l d1,a6 ; clamp table includes on L
add.w d3,d3
add.w d3,a6
move.w (a6,d2.w),d3 ; b
or.b (a6),d3 ; g
move.l d3,(a0)+ ; *row1++
moveq #0,d3 ; *lum++
move.b (a3)+,d3
move.l d1,a6 ; clamp table includes on L
add.l d3,d3
add.l d3,a6
move.w (a6,d0.w),d3 ; r
move.b (a6),d3 ; g
swap d3
move.b (a3)+,d3 ; *lum++
move.l d1,a6 ; clamp table includes on L
add.w d3,d3
add.w d3,a6
move.w (a6,d2.w),d3 ; b
move.b (a6),d3 ; g
move.l d3,(a1)+ ; *row1++
dbra d6,all_cols_lores
move.l savecols(sp),d0 ; next line in the luminance channel
add.l d0,a2
add.l d0,a3
add.l d0,d0 ; 2 bytes per pixel
add.l d0,a0 ; next line in the output row
add.l d0,a1
dbra d7,all_rows_lores
add.w #localvars,sp
movem.l (sp)+,cdi_regs
rts
;************************************************************************************
XDEF @ColorDitherImage_VideoLayerYCbCr
; a0 unsigned char *lum
; a1 unsigned char *cr
; 4(sp) unsigned char *cb
; 8(sp) unsigned char *out
; d0 int rows
; d1 int cols
cb_off2 EQU 11*4+4
out_off2 EQU cb_off2+4
@ColorDitherImage_VideoLayerYCbCr:
movem.l cdi_regs,-(sp)
move.l cb_off2(sp),a2
move.l out_off2(sp),a3
lea (a0,d1.w),a5
lea (a3,d1.w*2),a4
move.l d1,d4
lsl.l #1,d4
lsr.w #1,d0
sub.w #1,d0
all_rows_VL
move.l d1,d5
lsr.w #1,d5
sub.w #1,d5
column_VL
move.b (a1)+,d2
move.b (a0)+,d3
lsl.w #8,d3
move.b d2,d3
move.w d3,(a3)+
move.b (a5)+,d3
lsl.w #8,d3
move.b d2,d3
move.w d3,(a4)+
move.b (a2)+,d2
move.b (a0)+,d3
lsl.w #8,d3
move.b d2,d3
move.w d3,(a3)+
move.b (a5)+,d3
lsl.w #8,d3
move.b d2,d3
move.w d3,(a4)+
dbf d5,column_VL
add.l d1,a0
add.l d1,a5
add.l d4,a3
add.l d4,a4
dbf d0,all_rows_VL
movem.l (sp)+,cdi_regs
rts
;************************************************************************************
XDEF @ColorDitherImage_VideoLayerGray
; a0 unsigned char *lum
; a1 unsigned char *cr
; 4(sp) unsigned char *cb
; 8(sp) unsigned char *out
; d0 int rows
; d1 int cols
@ColorDitherImage_VideoLayerGray:
movem.l cdi_regs,-(sp)
move.l out_off2(sp),a3
lea (a0,d1.w),a5
lea (a3,d1.w*2),a4
move.l d1,d4
lsl.l #1,d4
lsr.w #1,d0
sub.w #1,d0
move.b #$80,d2
all_rows_VLG
move.l d1,d5
lsr.w #1,d5
sub.w #1,d5
column_VLG
move.b (a0)+,d3
lsl.w #8,d3
move.b d2,d3
lsl.l #8,d3
move.b (a0)+,d3
lsl.l #8,d3
move.b d2,d3
move.l d3,(a3)+
move.b (a5)+,d3
lsl.w #8,d3
move.b d2,d3
lsl.l #8,d3
move.b (a5)+,d3
lsl.l #8,d3
move.b d2,d3
move.l d3,(a4)+
dbf d5,column_VLG
add.l d1,a0
add.l d1,a5
add.l d4,a3
add.l d4,a4
dbf d0,all_rows_VLG
movem.l (sp)+,cdi_regs
rts
;************************************************************************************
XDEF @ColorDitherImage_RGB
; a0 unsigned char *lum
; a1 unsigned char *cr
; 4(sp) unsigned char *cb
; 8(sp) unsigned char *out
; d0 int rows
; d1 int cols
@ColorDitherImage_RGB:
movem.l cdi_regs,-(sp)
sub.w #localvars,sp
move.l d1,(savecols,sp)
lsr.l #1,d0
subq.l #1,d0
move.l d0,d7
move.l a0,a2 ; lum1
move.l a2,a3
add.l d1,a3 ; lum2 = lum1+cols
move.l a1,a4 ; cr channel
move.l cb_offset(sp),d5
sub.l a4,d5 ; cb channel is addressed via its offset to the cr channel
lea Cb_r_tab,a5 ; conversion tab(s)
move.l (out_offset,sp),a0 ; row1
move.l a0,a1
lsl.l #2,d1
add.l d1,a1 ; row2=row1+cols*4
move.l (savecols,sp),d4
all_rows_rgb:
move.w d4,d6
lsr.w #1,d6
subq.w #1,d6
all_cols_rgb:
; still free: d4
moveq #0,d1
moveq #0,d2
move.b (a4,d5.l),d1 ; CB channel
move.b (a4)+,d2 ; CR channel
move.l (a5,d1.w*4),d0 ; cb_r cb_g
move.l (Cr_gb_off,a5,d2.w*4),d1 ; cr_g cr_b
move.w d1,d2
swap d1
add.w d0,d1
swap d0
sub.w d2,d0
sub.w d2,d1
ext.l d2
add.l #_clamp,d2
exg a4,d2
; d0 cb_r *2
; d1 (cr_g+cb_g) *2
; d2 cr_b *2
; moveq #0,d3 ; *lum++
clr.w d3
move.b (a2)+,d3
lea (a4,d3.w*2),a6
; move.b (a6,d0.w),d3
; swap d3
move.l -1(a6,d0.w),d3
move.w (a6,d1.w),d3
move.b (a6),d3
move.l d3,(a0)+
; moveq #0,d3 ; *lum++
clr.w d3
move.b (a2)+,d3
lea (a4,d3.w*2),a6
; move.b (a6,d0.w),d3
; swap d3
move.l -1(a6,d0.w),d3
move.w (a6,d1.w),d3
move.b (a6),d3
move.l d3,(a0)+
; moveq #0,d3 ; *lum2++
clr.w d3
move.b (a3)+,d3
lea (a4,d3.w*2),a6
; move.b (a6,d0.w),d3
; swap d3
move.l -1(a6,d0.w),d3
move.w (a6,d1.w),d3
move.b (a6),d3
move.l d3,(a1)+
; moveq #0,d3 ; *lum2++
clr.w d3
move.b (a3)+,d3
lea (a4,d3.w*2),a6
; move.b (a6,d0.w),d3
; swap d3
move.l -1(a6,d0.w),d3
move.w (a6,d1.w),d3
move.b (a6),d3
move.l d3,(a1)+
move.l d2,a4
dbra d6,all_cols_rgb
move.l d4,d0 ; next line in the luminance channel
add.l d0,a2
add.l d0,a3
lsl.l #2,d0 ; 4 bytes per pixel
add.l d0,a0 ; next line in the output row
add.l d0,a1
dbra d7,all_rows_rgb
add.w #localvars,sp
movem.l (sp)+,cdi_regs
rts
;************************************************************************************
XDEF @ColorDitherImage
@ColorDitherImage:
movem.l cdi_regs,-(sp)
sub.w #localvars,sp
move.l d1,(savecols,sp)
lsr.l #1,d0
subq.l #1,d0
move.l d0,d7
move.l a0,a2 ; lum1
move.l a2,a3
add.l d1,a3 ; lum2 = lum1+cols
move.l a1,a4 ; cr channel
move.l cb_offset(sp),d5
sub.l a4,d5 ; cb channel is addressed via its offset to the cr channel
lea Cb_r_tab,a5 ; conversion tab(s)
move.l (out_offset,sp),a0 ; row1
move.l a0,a1
lsl.l #2,d1
add.l d1,a1 ; row2=row1+cols*4
all_rows:
move.l (savecols,sp),d6
lsr.l #1,d6
subq.l #1,d6
all_cols:
; still free: d4
moveq #0,d1
moveq #0,d2
move.b (a4,d5.l),d1 ; CB channel
move.b (a4)+,d2 ; CR channel
move.l (a5,d1.w*4),d0 ; cb_r cb_g
move.l (Cr_gb_off,a5,d2.w*4),d1 ; cr_g cr_b
move.w d1,d2
swap d1
add.w d0,d1
swap d0
sub.w d2,d0
sub.w d2,d1
ext.l d2
add.l #_clamp,d2
exg a4,d2
; d0 cb_r *2
; d1 (cr_g+cb_g) *2
; d2 cr_b *2
moveq #0,d3 ; *lum++
move.b (a2)+,d3
lea (a4,d3.w*2),a6
move.w (a6),d3 ; b BRG0
move.b (a6,d0.w),d3 ; r
swap d3
move.w (a6,d1.w),d3 ; g
move.l d3,(a0)+ ; *row1++
moveq #0,d3 ; *lum++
move.b (a2)+,d3
lea (a4,d3.w*2),a6
move.w (a6),d3 ; b BRG0
move.b (a6,d0.w),d3 ; r
swap d3
move.w (a6,d1.w),d3 ; g
move.l d3,(a0)+ ; *row1++
moveq #0,d3 ; *lum2++
move.b (a3)+,d3
lea (a4,d3.w*2),a6
move.w (a6),d3 ; b BRG0
move.b (a6,d0.w),d3 ; r
swap d3
move.w (a6,d1.w),d3 ; g
move.l d3,(a1)+ ; *row2++
moveq #0,d3 ; *lum2++
move.b (a3)+,d3
lea (a4,d3.w*2),a6
move.w (a6),d3 ; b BRG0
move.b (a6,d0.w),d3 ; r
swap d3
move.w (a6,d1.w),d3 ; g
move.l d3,(a1)+ ; *row2++
move.l d2,a4
dbra d6,all_cols
move.l savecols(sp),d0 ; next line in the luminance channel
add.l d0,a2
add.l d0,a3
lsl.l #2,d0 ; 4 bytes per pixel
add.l d0,a0 ; next line in the output row
add.l d0,a1
dbra d7,all_rows
add.w #localvars,sp
movem.l (sp)+,cdi_regs
rts
;************************************************************************************
XDEF @ColorDitherImage_12bit
@ColorDitherImage_12bit:
movem.l cdi_regs,-(sp)
sub.w #localvars,sp
move.l d1,(savecols,sp)
lsr.l #1,d0
subq.l #1,d0
move.l d0,d7
move.l a0,a2 ; lum1
move.l a2,a3
add.l d1,a3 ; lum2 = lum1+cols
move.l a1,a4 ; cr channel
move.l cb_offset(sp),d5
sub.l a4,d5 ; cb channel is addressed via its offset to the cr channel
lea Cb_r_tab,a5 ; conversion tab(s)
move.l (out_offset,sp),a0 ; row1
move.l a0,a1
add.l d1,a1 ; row2=row1+cols
all_rows_12bit:
move.l (savecols,sp),d6
lsr.l #1,d6
subq.l #1,d6
all_cols_12bit:
moveq #0,d1
moveq #0,d2
move.b (a4,d5.l),d1 ; CB channel
move.b (a4)+,d2 ; CR channel
move.l (a5,d1.w*4),d0 ; cb_r cb_g
move.l (Cr_gb_off,a5,d2.w*4),d1 ; cr_g cr_b
move.w d1,d2
swap d1
add.w d0,d1
swap d0
sub.w d1,d0
sub.w d1,d2
ext.l d1
add.l #_clamp,d1
; d0 cb_r *2
; d1 (cr_g+cb_g) *2
; d2 cr_b *2
moveq #0,d3 ; *lum++
moveq #0,d4
move.b (a2)+,d3
move.l d1,a6 ; clamp table includes on L
add.l d3,d3
add.l d3,a6
move.w (a6,d0.w),d3 ; r
lsl.l #4,d3
move.w (a6),d3 ; g
lsl.l #4,d3
move.b (a2)+,d4 ; *lum++
move.l d1,a6 ; clamp table includes on L
add.w d4,d4
add.l d4,a6
move.w (a6,d2.w),d3 ; b
lsr.l #4,d3
move.b (a6),d3 ; g
lsr.l #4,d3
move.w d3,(a0)+ ; *row1++
moveq #0,d3 ; *lum++
moveq #0,d4
move.b (a3)+,d3
move.l d1,a6 ; clamp table includes on L
add.l d3,d3
add.l d3,a6
move.w (a6,d0.w),d3 ; r
lsl.l #4,d3
move.w (a6),d3 ; g
lsl.l #4,d3
move.b (a3)+,d4 ; *lum++
move.l d1,a6 ; clamp table includes on L
add.w d4,d4
add.l d4,a6
move.w (a6,d2.w),d3 ; b
lsr.l #4,d3
move.b (a6),d3 ; g
lsr.l #4,d3
move.w d3,(a1)+ ; *row1++
dbra d6,all_cols_12bit
move.l savecols(sp),d0 ; next line in the luminance channel
add.l d0,a2
add.l d0,a3
add.l d0,a0 ; next line in the output row
add.l d0,a1
dbra d7,all_rows_12bit
add.w #localvars,sp
movem.l (sp)+,cdi_regs
rts
;************************************************************************************
SECTION __MERGED,BSS
;
; uv conversion table; contains 4 sets describing the relation between the two
; chrominance channels and the four-times bigger luminance channel.
;
Cb_r_tab: ds.l 2*256
; clamp table
;
; clamp[x] = 0xff00
; *(&clamp[x]-1) = 0x00ff
;
; an offset into this clamp table could very easily implement overall brightness control!
;
; we can reuse this special construct in video.c/sutils.s
;
XDEF _clamp
ds.w clampsize
_clamp: ds.w 256+clampsize
END