Last active
August 29, 2015 14:19
-
-
Save andfoy/ba064e7c488544d015b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // isis1304-111-proyecto2.cpp: define el punto de entrada de la aplicación de consola. | |
| // | |
| // DESARROLLADO POR: | |
| // Camila García, carnet | |
| // Daniel Ordoñez, carnet | |
| // Edgar A. Margffoy, 201412566 | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <stdbool.h> | |
| #define CHAR_SIZE sizeof(char)*8 | |
| // La representacion de la imagen | |
| typedef struct img | |
| { | |
| int ancho; | |
| int alto; | |
| unsigned char *informacion; | |
| } Imagen; | |
| // 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,char msg[], int l, int n); | |
| //unsigned char sacarNbits(char mensaje[],int bitPos,int n); | |
| const char* byte_to_binary(int x) | |
| { | |
| static char b[9]; | |
| b[0] = '\0'; | |
| int z; | |
| for (z = 128; z > 0; z >>= 1) | |
| { | |
| strcat(b, ((x & z) == z) ? "1" : "0"); | |
| } | |
| return b; | |
| } | |
| void message_insertion(char* bitmap, char* msg, int pos, int len, int n) | |
| { | |
| int i; | |
| int num_chunks = CHAR_SIZE / n; | |
| int offset = CHAR_SIZE % n; | |
| int old_offset = 0; | |
| int word_size = CHAR_SIZE; | |
| unsigned char zero_mask = 0; | |
| unsigned char positive_mask = 0xff << n; //<< (CHAR_SIZE - n-1); | |
| int bitmap_pos = 0; | |
| bool skip = false; | |
| unsigned char act; | |
| for(i = 0; i < len; i++) | |
| { | |
| int extracted_chunks = 0; | |
| num_chunks = word_size/n; | |
| if(!skip) | |
| { | |
| act = msg[i]; | |
| } | |
| else | |
| { | |
| skip = false; | |
| } | |
| while(extracted_chunks < num_chunks) | |
| { | |
| printf("Current char: %s\n", byte_to_binary(act)); | |
| printf("Current bitmap: %s\n", byte_to_binary(bitmap[pos+bitmap_pos])); | |
| zero_mask |= act >> CHAR_SIZE-n; | |
| printf("Replacement: %s\n\n", byte_to_binary(zero_mask)); | |
| act <<= n; | |
| positive_mask |= zero_mask; | |
| bitmap[pos+bitmap_pos] &= positive_mask; | |
| bitmap[pos+bitmap_pos] |= zero_mask; | |
| printf("Result: %s\n\n", byte_to_binary(bitmap[pos+bitmap_pos])); | |
| zero_mask = 0; | |
| positive_mask = 0xff << n; | |
| bitmap_pos++; | |
| extracted_chunks++; | |
| } | |
| if(offset != 0) | |
| { | |
| printf("Offset! %d\n", offset); | |
| printf("Current char: %s\n", byte_to_binary(act)); | |
| printf("Current bitmap: %s\n", byte_to_binary(bitmap[pos+bitmap_pos])); | |
| act >>= CHAR_SIZE-n; | |
| zero_mask |= act; | |
| printf("Positive mask: %s\n", byte_to_binary(zero_mask)); | |
| if(i+1 < len) | |
| { | |
| act = msg[i+1]; | |
| printf("Next char: %s\n", byte_to_binary(act)); | |
| zero_mask |= act >> (CHAR_SIZE-n+(offset)); | |
| act <<= n-offset; | |
| positive_mask |= zero_mask; | |
| printf("Ar yu a mask: %s\n\n", byte_to_binary(zero_mask)); | |
| bitmap[pos+bitmap_pos] &= positive_mask; | |
| bitmap[pos+bitmap_pos] |= zero_mask; | |
| printf("Result: %s\n\n", byte_to_binary(bitmap[pos+bitmap_pos])); | |
| zero_mask = 0; | |
| positive_mask = 0xff << n; | |
| word_size = CHAR_SIZE - (n - offset); | |
| offset = word_size % n; | |
| skip = true; | |
| bitmap_pos++; | |
| } | |
| else | |
| { | |
| positive_mask |= zero_mask; | |
| bitmap[pos+bitmap_pos] &= positive_mask; | |
| bitmap[pos+bitmap_pos] |= zero_mask; | |
| } | |
| } | |
| else | |
| { | |
| word_size = CHAR_SIZE; | |
| offset = word_size % n; | |
| old_offset = word_size % n; | |
| } | |
| } | |
| } | |
| /** | |
| * 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 ) | |
| { | |
| unsigned char* bitmap = img -> informacion; | |
| message_insertion(bitmap, mensaje, 0, (int) strlen(mensaje), n); | |
| } | |
| /** | |
| * 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 ) | |
| { | |
| /* int paquetes = l/n;*/ | |
| /* int acarreo= l%n;*/ | |
| unsigned char* bitmap = img -> informacion; | |
| /* int paquetesleidos = 0 ;*/ | |
| /* int bitmapPos =0;*/ | |
| /* unsigned char cadenaBinaria[];*/ | |
| /* while(paquetesleidos<paquetes)*/ | |
| /* {*/ | |
| /* for(int i=0;i<n;i++)*/ | |
| /* {*/ | |
| /* strcat(cadenaBinaria, bitmap[bitmapPos+CHAR_SIZE-n+i]);*/ | |
| /* }*/ | |
| /* */ | |
| /* bitmapPos += 8;*/ | |
| /* paquetesleidos++;*/ | |
| /* */ | |
| /* }*/ | |
| /* if(acarreo!=0)*/ | |
| /* {*/ | |
| /* for(int i=0;i<acarreo:i++)*/ | |
| /* {*/ | |
| /* strcat(cadenaBinaria, bitmap[bitmapPos+CHAR_SIZE-n+i]);*/ | |
| /* }*/ | |
| /* }*/ | |
| unsigned char zero_mask = 0; | |
| int word_size = CHAR_SIZE; | |
| int cant_char = 0; | |
| int bitmap_pos = 0; | |
| int extracted_chunks = 0; | |
| int num_chunks = CHAR_SIZE / n; | |
| int offset = CHAR_SIZE % n; | |
| unsigned char component; | |
| while(cant_char < l) | |
| { | |
| int extracted_chunks = 0; | |
| num_chunks = word_size/n; | |
| while(extracted_chunks < num_chunks) | |
| { | |
| printf("Word Size: %d\n", word_size); | |
| component = bitmap[bitmap_pos]; | |
| printf("Current bitmap: %s\n", byte_to_binary(bitmap[bitmap_pos])); | |
| component <<= CHAR_SIZE-n; | |
| printf("Left Shift: %s\n", byte_to_binary(component)); | |
| component >>= CHAR_SIZE-n; | |
| printf("Right Shift: %s\n", byte_to_binary(component)); | |
| zero_mask |= component; | |
| printf("Mask: %s\n", byte_to_binary(zero_mask)); | |
| bitmap_pos++; | |
| if(extracted_chunks == num_chunks-1) | |
| { | |
| break; | |
| } | |
| zero_mask <<= n; | |
| printf("Ready for next: %s\n\n", byte_to_binary(zero_mask)); | |
| extracted_chunks++; | |
| } | |
| if(offset != 0) | |
| { | |
| printf("Offset! %d\n", offset); | |
| component = bitmap[bitmap_pos]; | |
| printf("Current bitmap: %s\n", byte_to_binary(bitmap[bitmap_pos])); | |
| component <<= CHAR_SIZE-n; | |
| printf("Left Shift: %s\n", byte_to_binary(component)); | |
| component >>= CHAR_SIZE-n; | |
| printf("Right Shift: %s\n", byte_to_binary(component)); | |
| zero_mask <<= offset; | |
| zero_mask |= component >> n-offset; | |
| printf("Mask: %s\n", byte_to_binary(zero_mask)); | |
| msg[cant_char] = zero_mask; | |
| zero_mask = 0; | |
| word_size = CHAR_SIZE - (n-offset); | |
| offset = word_size % n; | |
| if(CHAR_SIZE-offset<n) | |
| { | |
| zero_mask |= component; //<< offset; | |
| } | |
| else | |
| { | |
| zero_mask |= component << n; | |
| } | |
| printf("Mask After: %s\n", byte_to_binary(zero_mask)); | |
| bitmap_pos++; | |
| } | |
| else | |
| { | |
| msg[cant_char] = zero_mask; | |
| zero_mask = 0; | |
| offset = CHAR_SIZE % n; | |
| word_size = CHAR_SIZE; //0 si es perfecto! Yei! | |
| } | |
| printf("Extracted: %s\n\n", byte_to_binary(msg[cant_char])); | |
| cant_char++; | |
| extracted_chunks = 0; | |
| } | |
| } | |
| /** | |
| * 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 Desarrollar completo en C | |
| } | |
| // Lee un archivo en formato BMP y lo almacena en la estructura img | |
| // NO MODIFICAR | |
| void cargarBMP24 (Imagen * imagen, char * nomArchivoEntrada) | |
| { | |
| // bmpDataOffset almacena la posición inicial de los datos de la imagen. Las otras almacenan el alto y el ancho | |
| // en pixeles respectivamente | |
| int bmpDataOffset, 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 Offset" del bmp | |
| fread (&bmpDataOffset, 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, bmpDataOffset, 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); | |
| } | |
| // 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 != 2) | |
| { | |
| printf ("Faltan argumentos - Debe ser un archivo\n"); | |
| system("pause"); | |
| 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"); | |
| fgets(msg, 10000, stdin); | |
| printf("longitud mensaje: %d\n",strlen(msg)); | |
| num=0; | |
| printf("ingrese el numero de bits por Byte\n"); | |
| scanf("%d",&num); | |
| 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); | |
| printf("ingrese el numero de bits por Byte\n"); | |
| scanf("%d",&n); | |
| 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"); | |
| } | |
| system ("pause"); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment