Funcion equivalente en C

Iniciado por Kougami, 23 Mayo 2017, 14:12 PM

0 Miembros y 1 Visitante están viendo este tema.

Kougami

Buenas, escribia porque no se como sacar una funcion equivalente en C del siguiente codigo escrito en asm:
Código (asm) [Seleccionar]

.global rgb2gray

.equ COEF1, 3483
.equ COEF2, 11718
.equ COEF3, 1183

.text

rgb2gray:
  ldr r3, =COEF1
  mul r0, r3, r0
  ldr r3, =COEF2
  mla r0, r3, r1, r0
  ldr r3, =COEF3
  mla r0, r3, r2, r0
  mov r0, r0, lsr #14

  mov pc, lr


Si me pudieseis ayudar estaria genial.
Muchas gracias de antemano

cpu2

No es el lugar indicado, si comprendes el codigo en ASM escribe un pseudocode y colocalo en el sub-foro de C/C++, hay si que pueden ayudarte.

Un saludo.

Serapis

#2
RGB To Gray es una función que convierte un byte (o un array de bytes procedente de una imagen), a gris...

el gris, como sabrás tiene un solo canal (8bits), pero si se amplía a 3 canales (24 bits), lo que se hace es repetir ese valor en los 3 canales.

Sea el color hexadecimal: FF54AB. Bueno, pués lo primero es decomponer el valor de 32 bits en los 3 canales sueltos, para tener los valores individuales de cada canal:

Valor = Valor and 16777215 // borramso un posible valor sobre el canal alfa.
Rojo= (Valor and 255)
Verde = ((Valor\256) and 255)
Azul = ((Valor\65536) )

Ya tenemos cada valor de canal suelto, ahora podemos recurrir a dos modos, el más rápido es sumar y dividir entre 3, es decir concedemos la misma importancia a cada canal (esto es más rápido pero puede no ser muy preciso)


Gris = ((rojo + verde + azul) \3)
//             azul                verde       rojo
Valor = ((Gris * 65536) or (Gris * 256) or Gris)


Puedes usar la fórmula más lenta de usar parcialmente cada valor en partes no iguales (LUMA):

Gris = ((Azul * 0.11) + (Verde * 0.59) + (Rojo * 0.3)) //  0'11+0'59+0'3=1'00
//             azul                verde       rojo
Valor = ((Gris * 65536) or (Gris * 256) or Gris)


Entonces la función pelada, queda así:
Funcion RGBaGrisLUMA(valor)
   Rojo= (Valor and 255)
   Verde = ((Valor\256) and 255)
   Azul = ((Valor\65536) and 255) // borramos un posible valor sobre el canal alfa.

   Gris = ((Azul * 0.11) + (Verde * 0.59) + (Rojo * 0.3))
   Valor = ((Gris * 65536) or (Gris * 256) or Gris)
Fin Funcion


// La versión rápida: Prueba ambas, a veces no se nota demasiada diferencia de calidad.
Funcion RGBaGris(valor)
    Rojo= (Valor and 255)
    Verde = ((Valor\256) and 255)
    Azul = ((Valor\65536) and 255) // borramos un posible valor sobre el canal alfa.

    Gris = ((Azul + Verde + Rojo) \ 3)
    Valor = ((Gris * 65536) or (Gris * 256) or Gris)
Fin Funcion


Se admiten ligeras variaciaciones sobre los coeficientes de LUMA, pero lo que no varía es que la suma de los 3 deber ser siempre igual a 1.

NOTA: Si se hacen desplazamientos, en vez de divisiones y multiplicaciones ( >>, <<), las operaciones serán mucho más rápido.