Author: wmb
Date: Mon Jan 17 22:58:06 2011
New Revision: 2111
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2111
Log:
Initial revision of color space converstion code.
Added:
dev/olpc/viacamera/ycrcbtorgb.fth
Added: dev/olpc/viacamera/ycrcbtorgb.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dev/olpc/viacamera/ycrcbtorgb.fth Mon Jan 17 22:58:06 2011 (r2111)
@@ -0,0 +1,141 @@
+\ See license at end of file
+purpose: Color space conversion from YCbCr to RGB
+
+\ R = clip (Y + 1.402 * Cr)
+\ G = clip (Y - 0.344 * Cb - 0.714 * Cr)
+\ B = clip (Y + 1.772 * Cb)
+
+\ This is for full-range YCbCr, where the Y anc Cb/Cr values ranges from 0-255.
+\ For restricted-range YCbCr (16 <= Y <= 235, 16 <= Cr,Cb <= 240), the Y value
+\ would need to be adjusted to Ysc = (Y - 16) * 1.164 (1.164 = 298 / 256 = 149 / 128)
+\ and the multipliers change from (1.402, -0.343, -0.711, 1.765) to (1.596, -0.392, -0.813, 2.017)
+
+code ycrcb444>rgb888 ( y cr cb -- r g b )
+ \ y: 8 [sp]
+ \ u: 4 [sp] = Cr
+ \ v: 0 [sp] = Cb
+
+ d# 128 # 0 [sp] sub \ convert Cb to signed
+ d# 128 # 4 [sp] sub \ convert Cr to signed
+ 8 [sp] bx mov \ Get Y into register
+
+ d# 90 # 4 [sp] ax imul-imm \ Multiply Cr by 1.402 * 64 (actually 1.406)
+ d# 6 # ax sar \ Scale down by 64
+ bx ax add \ Add to Y
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ ax 8 [sp] mov \ Put R in place on stack
+
+ d# -46 # 4 [sp] ax imul-imm \ Multiply Cr by -0.714 * 64 (actually -0.719)
+ d# 6 # ax sar \ Scale down by 64
+ ax cx mov
+ d# -22 # 0 [sp] ax imul-imm \ Multiply Cr by -0.344 * 64 (actually -0.344)
+ d# 6 # ax sar \ Scale down by 64
+ ax cx add
+ bx cx add \ Now we have G
+ 0< if cx cx xor then \ Clip to 0
+ d# 255 # cx cmp > if d# 255 # cx mov then \ Clip to 255
+
+ d# 113 # 0 [sp] ax imul-imm \ Multiply Cr by 1.772 * 64 (actually 1.766)
+ d# 6 # ax sar \ Scale down by 64
+ bx ax add \ Add to Y
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+ ax 0 [sp] mov \ Put B in place on stack
+
+ cx 4 [sp] mov \ Put G in place on stack
+c;
+
+
+\ This version operates on pixel values in memory
+\ Src bytes are Cb Y1 Cr Y2 (2 pixels)
+\ Dst bytes are R G B A R G B A (2 pixels)
+
+code ycbcr422>rgba8888 ( src dst count -- )
+ 4 [sp] di xchg \ di: dst
+ 8 [sp] si xchg \ si: src
+
+ ax push ax push \ Space on stack for Cr and Cb values
+
+ begin
+ \ src: Cb Y1 Cr Y2 dst: R1 G1 B1 A1 R2 G2 B2 A2
+ ax ax xor al lods d# 128 # ax sub ax 0 [sp] mov \ Get Cb, make signed, save on stack
+ ax ax xor al lods ax bx mov \ Get Y1, save in BX
+ ax ax xor al lods d# 128 # ax sub ax 4 [sp] mov \ Get Cr, make signed, save on stack
+
+ d# 90 # 4 [sp] ax imul-imm \ Multiply Cr by 1.402 * 64 (actually 1.406)
+ d# 6 # ax sar \ Scale down by 64
+ bx ax add \ Add to Y
+
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ al stos \ Output R
+
+ d# -46 # 4 [sp] ax imul-imm \ Multiply Cr by -0.714 * 64 (actually -0.719)
+ d# 6 # ax sar \ Scale down by 64
+ ax dx mov
+ d# -22 # 0 [sp] ax imul-imm \ Multiply Cr by -0.344 * 64 (actually -0.344)
+ d# 6 # ax sar \ Scale down by 64
+ dx ax add
+ bx ax add \ Now we have G
+
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ al stos \ Output G
+
+ d# 113 # 0 [sp] ax imul-imm \ Multiply Cr by 1.772 * 64 (actually 1.766)
+ d# 6 # ax sar \ Scale down by 64
+ bx ax add \ Add to Y
+
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ al stos \ Output B
+ d# 255 # al mov
+ al stos \ Output A
+
+ ax ax xor al lods ax bx mov \ Get Y2 into BX
+
+ d# 90 # 4 [sp] ax imul-imm \ Multiply Cr by 1.402 * 64 (actually 1.406)
+ d# 6 # ax sar \ Scale down by 64
+ bx ax add \ Add to Y
+
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ al stos \ Output R
+
+ d# -46 # 4 [sp] ax imul-imm \ Multiply Cr by -0.714 * 64 (actually -0.719)
+ d# 6 # ax sar \ Scale down by 64
+ ax dx mov
+ d# -22 # 0 [sp] ax imul-imm \ Multiply Cr by -0.344 * 64 (actually -0.344)
+ d# 6 # ax sar \ Scale down by 64
+ dx ax add
+ bx ax add \ Now we have G
+
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ al stos \ Output G
+
+ d# 113 # 0 [sp] ax imul-imm \ Multiply Cr by 1.772 * 64 (actually 1.766)
+ d# 6 # ax sar \ Scale down by 64
+ bx ax add \ Add to Y
+
+ 0< if ax ax xor then \ Clip to 0
+ d# 255 # ax cmp > if d# 255 # ax mov then \ Clip to 255
+
+ al stos \ Output B
+ d# 255 # al mov
+ al stos \ Output A
+
+ 8 [sp] dec
+ 0= until
+
+ d# 12 [sp] sp lea \ Clean stack
+ 0 [sp] di xchg \ Restore EDI
+ 4 [sp] si xchg \ Restore ESI
+c;