Is there any algorism that converts YCbCr to RGB??? (Integer based!!!)
I got a C source. But, it uses floating point operation. :(
I prefer speed than precision. :)

Have a nice day!
Posted on 2002-08-09 01:32:19 by nyam
Use fixed point?
Posted on 2002-08-09 02:26:58 by comrade
Hi,

that depends on the source format. Is it a 4:2:0 (like most MPEG)
or 4:2:2 (seens in some JPEGs) or 4:4:4 (some MPEG2)

Generally you can use this formula:

B = 1.164(Y - 16) + 2.018(Cb - 128)
G = 1.164(Y - 16) - 0.813(Cr - 128) - 0.391(Cb - 128)
R = 1.164(Y - 16) + 1.596(Cr - 128)
That way you can work with a lookup table which is even faster
than using real calculations via MMX.

building lookup table(s)

``````
push	1024
push	GMEM_FIXED
call	GlobalAlloc
mov	[edi.ve_lpCrRed], eax
test	eax, eax
je	iveError

push	1024
push	GMEM_FIXED
call	GlobalAlloc
mov	[edi.ve_lpCrGreen], eax
test	eax, eax
je	iveError

push	1024
push	GMEM_FIXED
call	GlobalAlloc
mov	[edi.ve_lpCbGreen], eax
test	eax, eax
je	iveError

push	1024
push	GMEM_FIXED
call	GlobalAlloc
mov	[edi.ve_lpCbBlue], eax
test	eax, eax
je	iveError

push	1024
push	GMEM_FIXED
call	GlobalAlloc
mov	[edi.ve_lpLum], eax
test	eax, eax
je	iveError

; -- build color tables --

xor	ecx, ecx
iveLoop:	mov	esi, ecx
sub	esi, 128

mov	eax, esi
imul	eax, 359
mov	ebx, [edi.ve_lpCrRed]
mov	[ebx + ecx * 4], eax

mov	eax, esi
imul	eax, 88
neg	eax
mov	ebx, [edi.ve_lpCbGreen]
mov	[ebx + ecx * 4], eax

mov	eax, esi
imul	eax, 183
neg	eax
mov	ebx, [edi.ve_lpCrGreen]
mov	[ebx + ecx * 4], eax

mov	eax, esi
imul	eax, 454
mov	ebx, [edi.ve_lpCbBlue]
mov	[ebx + ecx * 4], eax

mov	eax, ecx
imul	eax, 298
mov	ebx, [edi.ve_lpLum]
mov	[ebx + ecx * 4], eax

inc	ecx
cmp	ecx, 256
jl	iveLoop
``````

now you can get get the chrominance value and put the RGB
by using the luminance values according to these macros:

``````

; lpCb points to the current Cb value
; lpCr points to the current Cr value
; dwCrRed .. dwCbBlue are local temporary variables

getchrom	MACRO

xor	ebx, ebx
xor	ecx, ecx

mov	eax, lpCb
mov	bl, [eax]
mov	eax, lpCr
mov	cl, [eax]

mov	eax, xVideoEngine.ve_lpCrRed
mov	eax, [eax + ecx * 4]
mov	dwCrRed, eax

mov	eax, xVideoEngine.ve_lpCrGreen
mov	eax, [eax + ecx * 4]
mov	dwCrGreen, eax

mov	eax, xVideoEngine.ve_lpCbGreen
mov	eax, [eax + ebx * 4]
mov	dwCbGreen, eax

mov	eax, xVideoEngine.ve_lpCbBlue
mov	eax, [eax + ebx * 4]
mov	dwCbBlue, eax

ENDM

; writes the blue value to the RGB plane pointed by ecx
; esi ist the current luminance (Y) value
; edi is a clipping table to keep the values in byte size
; instead of edi you might do a clip of eax against 0 and 255

setblue	MACRO

mov	eax, esi

sar	eax, 8
and	eax, 03FFh

mov	al, [edi + eax]
mov	[ecx], al

ENDM

setgreen	MACRO

mov	eax, esi

sar	eax, 8
and	eax, 03FFh

mov	al, [edi + eax]
mov	[ecx + 1], al

ENDM

setred	MACRO

mov	eax, esi

sar	eax, 8
and	eax, 03FFh

mov	al, [edi + eax]
mov	[ecx + 2], al

ENDM

``````

Hope this helps

:)

Bye Miracle
Posted on 2002-08-09 02:27:50 by miracle
Fixed point 8 (sar eax,8) ?

ve_lpCrRed 1,596*256=409 ?359
ve_lpCbGreen 0,391*256=100 ?88
ve_lpCrGreen 0,813*256=208 ?183
ve_lpCbBlue 2,018*256=517 ?454
ve_lpLum 1,164*256=298 =298, but where -16

Where table ve_lpLum is used?
("esi ist the current luminance (Y) value"???)

``````
and	eax, 03FFh
mov	al, [edi + eax]
``````

This code clipping signed values? I do not believe :)
Posted on 2002-08-09 12:02:41 by Nexo