Skip to content

Instantly share code, notes, and snippets.

@andfoy
Created May 14, 2015 00:30
Show Gist options
  • Select an option

  • Save andfoy/83468725819be30fd071 to your computer and use it in GitHub Desktop.

Select an option

Save andfoy/83468725819be30fd071 to your computer and use it in GitHub Desktop.
// isis1304-111-proyecto2.cpp: define el punto de entrada de la aplicación de consola.
//
// DESARROLLADO POR:
// Nombre, carnet
// Nombre, carnet
// Nombre, carnet
#define _CRT_SECURE_NO_WARNINGS
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
// La representacion de la imagen
typedef struct img
{
int ancho;
int alto;
unsigned char *informacion;
} Imagen;
unsigned char c = 0;
// Función que carga el bmp en la estructura Imagen
void cargarBMP24 ( Imagen * imagen, char * nomArchivoEntrada );
// Funcion que guarda el contenido de la estructura imagen en un archivo binario
void guardarBMP24 ( Imagen * imagen, char * nomArchivoSalida );
//Funcion que inserta un mensaje en la imagen usando n bits por Byte
void insertarMensaje( Imagen * img , unsigned char mensaje[], int n );
//Funcion que lee un mensaje de una imagen dando la longitud del mensaje y el numero de bits por byte usados
void leerMensaje( Imagen * img,unsigned char msg[], int l, int n );
//Extrae de mensaje n bits a partir del bit que se encuentra en la posición bitpos
unsigned char sacarNbits( unsigned char mensaje[],int bitPos, int n );
//Traduce un carácter (dígito) a su equivalente como entero
int charToInt( char * s );
// Programa principal
// NO MODIFICAR
int main( int argc, char* argv[] )
{
Imagen *img = (Imagen *) malloc (sizeof (Imagen));
char msg[10000];
char op;
int num;
int l;
int i;
int n;
char nomArch1 [256] = "";
if (argc != 3)
{
printf ("Faltan argumentos - Debe ser un archivo\n");
return -1;
}
strcat (nomArch1, argv[1]);
// Cargar los datos
cargarBMP24 (img, nomArch1);
printf("Indique la accion\n\t1) insertar mensaje\n\t2) leer mensaje\n\n");
op = fgetc(stdin);
int c;
while((c = getchar()) != '\n' && c != EOF);
if(op == '1')
{
printf("ingrese el mensaje a insertar\n");
gets(msg);
printf("longitud mensaje: %d\n",strlen(msg));
num = charToInt(argv[2]);
insertarMensaje(img,msg,num);
guardarBMP24 (img, nomArch1);
printf("mensaje insertado\n");
}
else if(op =='2')
{
printf("ingrese la longitud del mensaje insertado\n");
scanf("%d",&l);
n = charToInt(argv[2]);
for(i=0;i<l;i++)
{
msg[i]=0;
}
leerMensaje(img,msg, l, n);
msg[l]=0;
printf("el mensaje es: %s\n",msg);
}
else
{
printf("%s","Hubo un error al cargar el archivo\n");
}
return 0;
}
/**
* Traduce un carácter (dígito) a su equivalente como entero
* parametro s Apuntador a la cadena de caracteres.
*/
int charToInt( char * s )
{
//TODO: IMPLEMENTAR EN ENSAMBLADOR USANDO NOMBRES SIMBÓLICOS
__asm
{
push ebx
mov eax, 0
mov ebx, s
mov al, [ebx]
sub eax, 48
mov byte ptr[c], al
pop ebx
}
}
/**
* Inserta un mensaje, de a n bits por componente de color, en la imagen apuntada por img
* parametro img Apuntador a una imagen en cuyos pixeles se almacenará el mensaje.
* parametro mensaje Apuntador a una cadena de caracteres con el mensaje.
* parametro n Cantidad de bits del mensaje que se almacenarán en cada componente de color de cada pixel. 0 < n <= 8.
*/
void insertarMensaje( Imagen * img , unsigned char mensaje[], int n )
{
//TODO: IMPLEMENTAR EN ENSAMBLADOR USANDO NOMBRES SIMBÓLICOS
}
/**
* Extrae un mensaje de tamaño l, guardado de a n bits por componente de color, de la imagen apuntada por img
* parametro img Apuntador a una imagen que tiene almacenado el mensaje en sus pixeles.
* parametro msg Apuntador a una cadena de caracteres donde se depositará el mensaje.
* parametro l Tamaño en bytes del mensaje almacenado en la imagen.
* parametro n Cantidad de bits del mensaje que se almacenan en cada componente de color de cada pixel. 0 < n <= 8.
*/
void leerMensaje( Imagen * img, unsigned char msg[], int l, int n )
{
//TODO: IMPLEMENTAR EN ENSAMBLADOR USANDO NOMBRES SIMBÓLICOS
unsigned char* bitmap = img->informacion; //Se solicita el apuntador a los componentes de la imagen.
int word_size = 8; //Tamaño inicial de palabra
int cant_char = 0; //Cantidad de caracteres extraídos
int bitmap_pos = 0; //Índice del componente actual de la imagen
int extracted_chunks = 0; //Paquetes recuperados por componente
int num_chunks = 8 / n; //Número de paquetes que se pueden extraer de acuerdo al tamaño n solicitado
int residuo = 8 % n; //Sobrante sujeto al número de paquetes por n.
__asm
{
push eax
push ebx
push ecx
push edx
push edi
push esi
mov esi, [bitmap]// Char*
mov edi, msg
mov ebx, 0//mascara de ceros en bl
// cl es Caracter actual
procesar_imagen :
mov esi, [bitmap]// Char*
mov edi, msg
mov ecx, [l]
cmp[cant_char], ecx
jge fin_procesar
mov[extracted_chunks], 0
mov eax, [word_size]
mov ecx, [n]
mov edx, 0
div ecx
mov[num_chunks], eax
mov[residuo], edx
extract_chunks :
cmp[extracted_chunks], eax
jge fin_extract
mov ecx, [bitmap_pos]
mov esi, [bitmap]
mov dl, [esi + ecx]
mov ecx, 0
mov ecx, 8
sub ecx, [n]
shl dl, cl
shr dl, cl
or bl, dl
inc[bitmap_pos]
mov ecx, [num_chunks]
sub ecx, 1
cmp[extracted_chunks], ecx
je fin_extract
mov ecx, [n]
shl bl, cl
inc[extracted_chunks]
jmp extract_chunks
fin_extract :
cmp[residuo], 0
je no_residuo
mov ecx, [bitmap_pos]
mov esi, [bitmap]
mov dl, [esi + ecx]
mov ecx, 0
mov ecx, 8
sub ecx, [n]
shl dl, cl
shr dl, cl
mov ecx, [residuo]
shl bl, cl
push edx
mov ecx, [n]
sub ecx, [residuo]
shr dl, cl
or bl, dl
pop edx
mov ecx, [cant_char]
mov byte ptr[edi + ecx], bl
mov ebx, 0
mov ecx, 8
add ecx, [residuo]
sub ecx, [n]
mov[word_size], ecx
mov eax, [word_size]
push edx
mov edx, 0
mov ecx, [n]
div ecx
mov[residuo], edx
inc[bitmap_pos]
pop edx
mov ecx, 8
sub ecx, [residuo]
cmp ecx, [n]
jge cond_2
or bl, dl
jmp pre_proc
cond_2 :
mov cl, dl
push ecx
mov cl, byte ptr[n]
shl dl, cl
or bl, dl
pop ecx
jmp pre_proc
no_residuo :
mov ecx, [cant_char]
mov byte ptr[edi + ecx], bl
mov [c], bl
mov ebx, 0
push edx
mov ecx, [n]
mov edx, 0
mov eax, 8
div ecx
mov[residuo], edx
mov[word_size], 8
pop edx
pre_proc :
inc[cant_char]
mov[extracted_chunks], 0
jmp procesar_imagen
fin_procesar :
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
}
}
/**
* Extrae n bits a partir del bit que se encuentra en la posición bitpos en la secuencia de bytes que
* se pasan como parámetro
* parametro secuencia Apuntador a una secuencia de bytes.
* parametro n Cantidad de bits que se desea extraer. 0 < n <= 8.
* parametro bitpos Posición del bit desde donde se extraerán los bits. 0 <= n < 8*longitud de la secuencia
* retorno Los n bits solicitados almacenados en los bits menos significativos de un unsigned char
*/
unsigned char sacarNbits( unsigned char secuencia[], int bitpos, int n )
{
//TODO: IMPLEMENTAR EN ENSAMBLADOR SIN UTILIZAR NOMBRES SIMBÓLICOS
}
// Lee un archivo en formato BMP y lo almacena en la estructura img
// NO MODIFICAR
void cargarBMP24 (Imagen * imagen, char * nomArchivoEntrada)
{
// bmpDataresiduo almacena la posición inicial de los datos de la imagen. Las otras almacenan el alto y el ancho
// en pixeles respectivamente
int bmpDataresiduo, bmpHeight, bmpWidth;
int y;
int x;
int residuo;
FILE *bitmapFile;
bitmapFile = fopen (nomArchivoEntrada, "rb");
if (bitmapFile == NULL)
{
printf ("No ha sido posible cargar el archivo: %s\n", nomArchivoEntrada);
exit (-1);
}
fseek (bitmapFile, 10, SEEK_SET); // 10 es la posición del campo "Bitmap Data residuo" del bmp
fread (&bmpDataresiduo, sizeof (int), 1, bitmapFile);
fseek (bitmapFile, 18, SEEK_SET); // 18 es la posición del campo "height" del bmp
fread (&bmpWidth, sizeof (int), 1, bitmapFile);
bmpWidth = bmpWidth*3;
fseek (bitmapFile, 22, SEEK_SET); // 22 es la posición del campo "width" del bmp
fread (&bmpHeight, sizeof (int), 1, bitmapFile);
residuo = (4 - (bmpWidth) % 4)&3; // Se debe calcular los bits residuales del bmp, que surjen al almacenar en palabras de 32 bits
imagen -> ancho = bmpWidth;
imagen -> alto = bmpHeight;
imagen -> informacion = (unsigned char *) calloc (bmpWidth * bmpHeight, sizeof (unsigned char));
fseek (bitmapFile, bmpDataresiduo, SEEK_SET); // Se ubica el puntero del archivo al comienzo de los datos
for (y = 0; y < bmpHeight; y++)
{
for ( x= 0; x < bmpWidth; x++)
{
int pos = y * bmpWidth + x;
fread (&imagen -> informacion [pos], sizeof(unsigned char ), 1, bitmapFile);
}
fseek(bitmapFile, residuo, SEEK_CUR); // Se omite el residuo en los datos
}
fclose (bitmapFile);
}
// Esta funcion se encarga de guardar una estructura de Imagen con formato de 24 bits (formato destino) en un archivo binario
// con formato BMP de Windows.
// NO MODIFICAR
void guardarBMP24 (Imagen * imagen, char * nomArchivoSalida)
{
unsigned char bfType[2];
unsigned int bfSize, bfReserved, bfOffBits, biSize, biWidth, biHeight, biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant;
unsigned short biPlanes, biBitCount;
FILE * archivoSalida;
int y, x;
int relleno = 0;
int residuo = (4 - (imagen->ancho) % 4)&3; // Se debe calcular los bits residuales del bmp, que quedan al forzar en palabras de 32 bits
bfType[2]; // Tipo de Bitmap
bfType[0] = 'B';
bfType[1] = 'M';
bfSize = 54 + imagen -> alto * ((imagen -> ancho)/3) * sizeof (unsigned char); // Tamanio total del archivo en bytes
bfReserved = 0; // Reservado para uso no especificados
bfOffBits = 54; // Tamanio total del encabezado
biSize = 40; // Tamanio del encabezado de informacion del bitmap
biWidth = (imagen -> ancho)/3; // Ancho en pixeles del bitmap
biHeight = imagen -> alto; // Alto en pixeles del bitmap
biPlanes = 1; // Numero de planos
biBitCount = 24; // Bits por pixel (1,4,8,16,24 or 32)
biCompression = 0; // Tipo de compresion
biSizeImage = imagen -> alto * imagen -> ancho; // Tamanio de la imagen (sin ecabezado) en bits
biXPelsPerMeter = 2835; // Resolucion del display objetivo en coordenada x
biYPelsPerMeter = 2835; // Resolucion del display objetivo en coordenada y
biClrUsed = 0; // Numero de colores usados (solo para bitmaps con paleta)
biClrImportant = 0; // Numero de colores importantes (solo para bitmaps con paleta)
archivoSalida = fopen (nomArchivoSalida, "w+b"); // Archivo donde se va a escribir el bitmap
if (archivoSalida == 0)
{
printf ("No ha sido posible crear el archivo: %s\n", nomArchivoSalida);
exit (-1);
}
fwrite (bfType, sizeof(char), 2, archivoSalida); // Se debe escribir todo el encabezado en el archivo. En total 54 bytes.
fwrite (&bfSize, sizeof(int), 1, archivoSalida);
fwrite (&bfReserved, sizeof(int), 1, archivoSalida);
fwrite (&bfOffBits, sizeof(int), 1, archivoSalida);
fwrite (&biSize, sizeof(int), 1, archivoSalida);
fwrite (&biWidth, sizeof(int), 1, archivoSalida);
fwrite (&biHeight, sizeof(int), 1, archivoSalida);
fwrite (&biPlanes, sizeof(short), 1, archivoSalida);
fwrite (&biBitCount, sizeof(short), 1, archivoSalida);
fwrite (&biCompression, sizeof(int), 1, archivoSalida);
fwrite (&biSizeImage, sizeof(int), 1, archivoSalida);
fwrite (&biXPelsPerMeter, sizeof(int), 1, archivoSalida);
fwrite (&biYPelsPerMeter, sizeof(int), 1, archivoSalida);
fwrite (&biClrUsed, sizeof(int), 1, archivoSalida);
fwrite (&biClrImportant, sizeof(int), 1, archivoSalida);
// Se escriben en el archivo los datos RGB de la imagen.
for (y = 0; y < imagen -> alto; y++)
{
for (x = 0; x < imagen -> ancho; x++)
{
int pos = y * imagen -> ancho + x;
fwrite (&imagen -> informacion[pos], sizeof(unsigned char), 1, archivoSalida);
}
fwrite(&relleno, sizeof(unsigned char), residuo, archivoSalida);
}
fclose(archivoSalida);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment