All pastes #986241 Raw Edit

Unnamed

public text v1 · immutable
·published 2008-04-15 17:24 UTC
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);
}
//////////////////////////////////////////////////////////////////////