rendered paste body//estos ficheros de cabecera deben estar en el mismo directorio que los de codigo (o si no, indicarle al compilador donde buscar los include)
#include "FicherosBMP_ansi.h"
#include "Contadorciclos_ansi.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
struct t_imgrgb {
// el orden RGB es el contrario porque los píxeles se almacenan al reves:
// desde el final del fichero hasta el ppio
unsigned char B;
unsigned char G;
unsigned char R;
unsigned char ALFA;
};
///////////////////////////////////////////////////////////////////////////////
struct t_imgrgb *buf_imgrgb ;
FILE * pf;
///////////////////////////////////////////////////////////////////////////////
//funcion para terminar el programa, cerrando ficheros, liberando memoria, etc
void fin_prog (int);
///////////////////////////////////////////////////////////////////////////////
int main(void)
{
unsigned int i, ind_max, ind_permutado ;
unsigned char kk[54], colores[4], color_max ;
long int tamaño ;
_Win4xBitmapHeader header;
short int bytes_por_pixel ;
char nomfh[256];
unsigned char alfaVal;
printf ("- Dame fichero entrada (con extension): ");
gets (nomfh);
if ( (pf=fopen(nomfh, "rb")) == NULL) fin_prog (-1);
//fseek (pf, 14, SEEK_CUR );
fread (kk, 1, 14, pf) ; //leo los 14 bytes de la primera cabecera, solo para copiarlos en fichero de salida
fread (&header.Size, 1, sizeof(header.Size), pf) ;//leo el primer campo
//que contiene el tamaño de la segunda cabecera (es la importante)
fread (&header.Size + 1, 1, (header.Size)-sizeof(header.Size), pf) ;//leo el resto de campos
//de la segunda cabecera
printf ("- Caraceristicas fichero original:\n");
printf (" - Header Size=%ld, Width=%ld, Height =%ld\n",
header.Size ,header.Width, header.Height);
printf (" - BitsPerPixel=%d, SizeOfBitmap=%ld\n",
header.BitsPerPixel, header.SizeOfBitmap);
if ( header.BitsPerPixel != 32) fin_prog (-2);//tamaño de imagen en pixeles
bytes_por_pixel = (header.BitsPerPixel / 8) ; //debe ser 3 evidentemente !!!!!!!! (4)
tamaño = header.Width * header.Height; //en pixeles
printf ("- Numero de bytes reales Width * Height * BitsPerPixel / 8 =%ld\n",
tamaño * bytes_por_pixel );
if ( header.SizeOfBitmap != tamaño * bytes_por_pixel )
{
printf (" *** La cabecera del bmp original no es estandar; \n");
}
buf_imgrgb = (t_imgrgb *) calloc (header.SizeOfBitmap, 1);
i = fread (buf_imgrgb , 1, (header.SizeOfBitmap), pf) ;
if ( header.SizeOfBitmap != i ) fin_prog (-3);
printf ("\n\n");
srand( (unsigned)time( NULL ) );
for(int z =0;z<5;z++)
{
////////////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
unsigned int toverhead_alto, toverhead_bajo;
unsigned int toverhead_alto_prov, toverhead_bajo_prov;
unsigned int t1_alto, t1_bajo;
unsigned int t0_alto, t0_bajo;
unsigned int j;
double nanoseg ;
LeerCiclosAnsi (&t0_alto,&t0_bajo);
LeerCiclosAnsi (&t1_alto,&t1_bajo);
RestarCiclosAnsi (&toverhead_alto, &toverhead_bajo, &t1_alto,&t1_bajo,&t0_alto,&t0_bajo);
//repito 5 veces para hallar overhead mas bajo:
for(j=0;j<5;j++)
{
LeerCiclosAnsi (&t0_alto,&t0_bajo);
LeerCiclosAnsi (&t1_alto,&t1_bajo);
RestarCiclosAnsi (&toverhead_alto_prov, &toverhead_bajo_prov, &t1_alto,&t1_bajo,&t0_alto,&t0_bajo);
if(toverhead_bajo_prov < toverhead_bajo)//se supone que toverhead_alto siempre será cero
toverhead_bajo = toverhead_bajo_prov ;
}
ImprimirCiclosAnsi (" Ciclos de overhead (minimo) = ", &toverhead_alto, &toverhead_bajo);
LeerCiclosAnsi (&t0_alto,&t0_bajo);
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////////////
for (alfaVal=255 ; alfaVal>0 ; alfaVal--)
{
unsigned int cond_fin = (int)(buf_imgrgb+header.SizeOfBitmap);
__asm {
lea eax,buf_imgrgb // r1 = &buf_imgrgb
bucle:
ldps XMM0, [eax] // carga un pixel con su B G R ALPHA
ldss XMM1, alfaVal // cargamos alfaVal en la parte baja de MM1
shufps XMM1,XMM1,0 // replicamos alfaVal
cmpgtps XMM2,XMM0,XMM1 // creamos la máscara del condicional cierta
cmpleps XMM3,XMM0,XMM1 // creamos la máscara del condicional falsa
andps XMM2,XMM2,XMM1 // res con cond cierta
andps XMM3,XMM3,XMM0 // res con cond falsa
orps XMM2,XMM2,XMM3 // resultado
stps [eax], XMM2 // lo almacenamos
addi eax,eax,16
slti ebx,eax,cond_fin
bnez ebx,bucle
}
// for (i=0;i <(header.SizeOfBitmap)/4 ; i++)
// /* le sumo 2 y redondeo a multiplo de 3
// porque no estan bien hechas las cuentas en algunos bmp. NO coincide
// header.Width * header.Height con el numero de pixeles reales
// */
// {
// colores[0] = (buf_imgrgb + i)->B;
// colores[1] = (buf_imgrgb + i)->G;
// colores[2] = (buf_imgrgb + i)->R;
// colores[3] = (buf_imgrgb + i)->ALFA;
//
// if (colores[3] > alfaVal) colores[3] = alfaVal;
// if (colores[2] > alfaVal) colores[2] = alfaVal;
// if (colores[1] > alfaVal) colores[1] = alfaVal;
// if (colores[0] > alfaVal) colores[0] = alfaVal;
//
// (buf_imgrgb + i)->B = colores[0];
// (buf_imgrgb + i)->G = colores[1];
// (buf_imgrgb + i)->R = colores[2];
// (buf_imgrgb + i)->ALFA = colores[3];
// }
}
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
LeerCiclosAnsi (&t1_alto,&t1_bajo);
RestarCiclosAnsi (&t1_alto,&t1_bajo, &t1_alto,&t1_bajo,&t0_alto,&t0_bajo);
//finalmente, resto el overhead:
RestarCiclosAnsi (&t1_alto,&t1_bajo, &t1_alto,&t1_bajo,&toverhead_alto, &toverhead_bajo);
ImprimirCiclosAnsi (" - Duracion total en Ciclos = ", &t1_alto,&t1_bajo);
printf (" - Duracion total en seg = %le \n", ConvertirATiempoAnsi(&t1_alto,&t1_bajo) );
nanoseg = ConvertirATiempoAnsi(&t1_alto,&t1_bajo)*1.0e9;
printf( " - Duracion por pixel: %.2lf ciclos; %.2lf ns ; \n",
ConvertirACiclosAnsi(&t1_alto,&t1_bajo) /(double)tamaño , nanoseg /(double)tamaño );
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
////////////////////////////////////
}
fin_prog (0);
return 0;
}
//***********************************************************************
// FUNCIONES
//***********************************************************************
//////////////////////////////////////////////////////////////////////
//Funcion para imprimir mensajes tras finalizar el programa
void fin_prog (int codigo_salida)
{
free(buf_imgrgb);
fclose (pf);
if (codigo_salida == 0)
printf("\n- Programa termino bien\n");
else
printf("\n- Error %d. La imagen no es ARGB\n", codigo_salida);
//Dejar siempre lo siguiente para que no se cierre la ventana.
printf( "\n- Pulse Intro para cerrar ventana \n");
fflush(stdin);
getchar();
exit (codigo_salida);
}
//////////////////////////////////////////////////////////////////////