Skip to content

Instantly share code, notes, and snippets.

@andfoy
Last active August 29, 2015 14:19
Show Gist options
  • Select an option

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

Select an option

Save andfoy/ba064e7c488544d015b6 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:
// 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