I have made the following code and when I try to compile it I skip the error "hide.cpp :(. text + 0x5f): reference to 'operator delete' without defining" I would like to know how to solve it.
Code (C ++):
#pragma warning(disable: 4996)
#include <cstdio>
#include <cstring>
class BMP
{
char * data; // los pixeles del fichero
public:
BMP();
~BMP();
bool load(const char * fname); // carga un fichero bmp
void save(const char * fname); // almacena el bmp en un fichero bmp
int ancho;
int alto;
int planosDeColor;
int bitsPorPixel;
char * pixels;
int nPixels;
long fsize;
};
// obtener un entero a partir de un desplazamiento (offset) en un arreglo de caracteres
inline int getInt(char * data, int offset)
{
return 0xff00000000&(int)(data[offset + 3] << 24) | 0xff0000&(int)(data[offset + 2] << 16) | 0xff00&(int)(data[offset + 1] << 8) | 0xff&(int)(data[offset + 0]);
}
// obtener un short (2 bytes) a partir de un desplazamiento (offset) en un arreglo de caracteres
inline int getShort(char * data, int offset)
{
return 0xff00 & (int) (data[offset + 1] << 8) | 0xff & (int)(data[offset + 0]);
}
// metodo constructor de la clase
BMP::BMP()
{
data = NULL;
ancho = alto = 0;
}
// metodo destructor... liberar la memoria
BMP::~BMP()
{
if (data)
delete[] data;
}
// metodo para cargar un archivo
bool BMP::load(const char * fname)
{
// primero abrimos el fichero para conocer su longitud
FILE * f = fopen(fname, "rb");
if (f == NULL) // el archivo no existe
return false;
fseek(f, 0, SEEK_END); // ir al final del archivo
fsize = ftell(f); // en que posicion estamos?
fclose(f);
data = new char[fsize]; // reservar memoria para almacenar todo el contenido del fichero
f = fopen(fname, "rb");
fread(data, sizeof(char), fsize, f);
fclose(f);
int pixelsOffset = getInt(data, 10);
int headerSize = getInt(data, 14);
if (headerSize == 40) // BITMAPINFOHEADER
{
ancho = getInt(data, 18);
alto = getInt(data, 22);
planosDeColor = getShort(data, 26);
bitsPorPixel = getShort(data, 28);
pixels = data + pixelsOffset;
}
nPixels = ancho * alto;
return true;
}
// guarda el bitmap en un fichero
void BMP::save(const char * fname)
{
if (data)
{
FILE * f = fopen(fname, "wb");
fwrite(data, sizeof(char), fsize, f);
fclose(f);
}
}
// oculta el texto (str) en el mapa de bits
void ocultar(BMP & bmp, char * str)
{
int pixelsRequeridos = (1 + strlen(str)) * 8; // calcula el numero de pixels requeridos para almacenar el string
if (pixelsRequeridos <= bmp.nPixels) // el string cabe en los pixels del bmp
{
char * pixel;
for (pixel = bmp.pixels; *str; str++)
{
// descomponer el siguiente caracter en sus bits
for (int i = 0; i < 8; i++, *pixel++)
{
char bit = ((*str) >> i) & 1; // obtiene el siguiente bit
if(bit)
*pixel |= 1; // el bit es 1... ponerlo en el pixel actual
else
*pixel &= 0xfe; // el bit es 0... ponerlo en el pixel actual
}
}
for (int i = 0; i < 8; i++, *pixel++) // caracter de fin de string (#pragma warning(disable: 4996)
#include <cstdio>
#include <cstring>
class BMP
{
char * data; // los pixeles del fichero
public:
BMP();
~BMP();
bool load(const char * fname); // carga un fichero bmp
void save(const char * fname); // almacena el bmp en un fichero bmp
int ancho;
int alto;
int planosDeColor;
int bitsPorPixel;
char * pixels;
int nPixels;
long fsize;
};
// obtener un entero a partir de un desplazamiento (offset) en un arreglo de caracteres
inline int getInt(char * data, int offset)
{
return 0xff00000000&(int)(data[offset + 3] << 24) | 0xff0000&(int)(data[offset + 2] << 16) | 0xff00&(int)(data[offset + 1] << 8) | 0xff&(int)(data[offset + 0]);
}
// obtener un short (2 bytes) a partir de un desplazamiento (offset) en un arreglo de caracteres
inline int getShort(char * data, int offset)
{
return 0xff00 & (int) (data[offset + 1] << 8) | 0xff & (int)(data[offset + 0]);
}
// metodo constructor de la clase
BMP::BMP()
{
data = NULL;
ancho = alto = 0;
}
// metodo destructor... liberar la memoria
BMP::~BMP()
{
if (data)
delete[] data;
}
// metodo para cargar un archivo
bool BMP::load(const char * fname)
{
// primero abrimos el fichero para conocer su longitud
FILE * f = fopen(fname, "rb");
if (f == NULL) // el archivo no existe
return false;
fseek(f, 0, SEEK_END); // ir al final del archivo
fsize = ftell(f); // en que posicion estamos?
fclose(f);
data = new char[fsize]; // reservar memoria para almacenar todo el contenido del fichero
f = fopen(fname, "rb");
fread(data, sizeof(char), fsize, f);
fclose(f);
int pixelsOffset = getInt(data, 10);
int headerSize = getInt(data, 14);
if (headerSize == 40) // BITMAPINFOHEADER
{
ancho = getInt(data, 18);
alto = getInt(data, 22);
planosDeColor = getShort(data, 26);
bitsPorPixel = getShort(data, 28);
pixels = data + pixelsOffset;
}
nPixels = ancho * alto;
return true;
}
// guarda el bitmap en un fichero
void BMP::save(const char * fname)
{
if (data)
{
FILE * f = fopen(fname, "wb");
fwrite(data, sizeof(char), fsize, f);
fclose(f);
}
}
// oculta el texto (str) en el mapa de bits
void ocultar(BMP & bmp, char * str)
{
int pixelsRequeridos = (1 + strlen(str)) * 8; // calcula el numero de pixels requeridos para almacenar el string
if (pixelsRequeridos <= bmp.nPixels) // el string cabe en los pixels del bmp
{
char * pixel;
for (pixel = bmp.pixels; *str; str++)
{
// descomponer el siguiente caracter en sus bits
for (int i = 0; i < 8; i++, *pixel++)
{
char bit = ((*str) >> i) & 1; // obtiene el siguiente bit
if(bit)
*pixel |= 1; // el bit es 1... ponerlo en el pixel actual
else
*pixel &= 0xfe; // el bit es 0... ponerlo en el pixel actual
}
}
for (int i = 0; i < 8; i++, *pixel++) // caracter de fin de string (%pre%) al final
*pixel &= 0xfe;
}
}
// obtiene un string escondido en un bmp y lo retorna en str
void mostrar(BMP & bmp, char * & str)
{
char * pixel = bmp.pixels;
// primero contamos cuantos caracteres hay en la imagen
int n = 0;
while (true)
{
char c = '%pre%';
for (int i = 0; i < 8; i++) // obtener cada bit del caracter
{
char bit = ((*pixel) & 1) << i;
c |= bit; // concatenar el bit al caracter
*pixel++; // siguiente pixel
}
n++; // contar un caracter mas
if (c == '%pre%') break; // cuando lleguemos a %pre% ya termino el string
}
// ahora repetimos el procedimiento anterior, pero esta vez construyendo el string (str)
pixel = bmp.pixels;
str = new char[n];
for (int i = 0; i < n; i++)
{
str[i] = '%pre%';
for (int j = 0; j < 8; j++)
{
char bit = ((*pixel) & 1) << j;
str[i] |= bit;
*pixel++;
}
}
}
bool modoOcultar = false;
char * archivo1;
char * archivo2;
void imprimirUso(const char * programa)
{
printf("Uso:\n%s archivo.bmp -ocultar archivo_oculto.bmp\n%s archivo.bmp -mostrar\n", programa, programa);
}
int main(int argc, char ** argv)
{
// primero debemos obtener los parametros de la linea de comandos
if (argc == 4) // 3 parametros
{
archivo1 = argv[1]; // el primer parametro es el nombre del bmp
if (strcmp(argv[2], "-ocultar") == 0) // el segundo parametro debe ser -ocultar
{
modoOcultar = true;
archivo2 = argv[3]; // el tercer parametro es el nombre del bmp resultado
}
else
{
imprimirUso(argv[0]);
return 1;
}
}
else if (argc == 3) // 2 parametros
{
archivo1 = argv[1]; // el primer parametro es el nombre del bmp
if (strcmp(argv[2], "-mostrar") == 0) // el segundo parametro debe ser -mostrar
{
modoOcultar = false;
}
else
{
imprimirUso(argv[0]);
return 1;
}
}
else
{
imprimirUso(argv[0]);
return 1;
}
BMP bmp;
if (!bmp.load(archivo1)) // intentar cargar el archivo
{
printf("Imposible abrir %s\n", archivo1);
return 2;
}
if(modoOcultar)
{
// leer texto a ocultar:
char texto[256];
printf("Escriba el texto a ocultar: ");
fgets(texto, 255, stdin);
texto[strlen(texto) - 1] = '%pre%'; // quitar el caracter \n al final del string
ocultar(bmp, texto); // ocultar el texto en el mapa de bits
bmp.save(archivo2); // guardar el archivo resultante
}
else
{
char * buffer;
mostrar(bmp, buffer); // obtener el texto almacenado en el bmp
printf("%s\n", buffer); // e imprimirlo
delete[] buffer;
}
return 0;
}
) al final
*pixel &= 0xfe;
}
}
// obtiene un string escondido en un bmp y lo retorna en str
void mostrar(BMP & bmp, char * & str)
{
char * pixel = bmp.pixels;
// primero contamos cuantos caracteres hay en la imagen
int n = 0;
while (true)
{
char c = '%pre%';
for (int i = 0; i < 8; i++) // obtener cada bit del caracter
{
char bit = ((*pixel) & 1) << i;
c |= bit; // concatenar el bit al caracter
*pixel++; // siguiente pixel
}
n++; // contar un caracter mas
if (c == '%pre%') break; // cuando lleguemos a %pre% ya termino el string
}
// ahora repetimos el procedimiento anterior, pero esta vez construyendo el string (str)
pixel = bmp.pixels;
str = new char[n];
for (int i = 0; i < n; i++)
{
str[i] = '%pre%';
for (int j = 0; j < 8; j++)
{
char bit = ((*pixel) & 1) << j;
str[i] |= bit;
*pixel++;
}
}
}
bool modoOcultar = false;
char * archivo1;
char * archivo2;
void imprimirUso(const char * programa)
{
printf("Uso:\n%s archivo.bmp -ocultar archivo_oculto.bmp\n%s archivo.bmp -mostrar\n", programa, programa);
}
int main(int argc, char ** argv)
{
// primero debemos obtener los parametros de la linea de comandos
if (argc == 4) // 3 parametros
{
archivo1 = argv[1]; // el primer parametro es el nombre del bmp
if (strcmp(argv[2], "-ocultar") == 0) // el segundo parametro debe ser -ocultar
{
modoOcultar = true;
archivo2 = argv[3]; // el tercer parametro es el nombre del bmp resultado
}
else
{
imprimirUso(argv[0]);
return 1;
}
}
else if (argc == 3) // 2 parametros
{
archivo1 = argv[1]; // el primer parametro es el nombre del bmp
if (strcmp(argv[2], "-mostrar") == 0) // el segundo parametro debe ser -mostrar
{
modoOcultar = false;
}
else
{
imprimirUso(argv[0]);
return 1;
}
}
else
{
imprimirUso(argv[0]);
return 1;
}
BMP bmp;
if (!bmp.load(archivo1)) // intentar cargar el archivo
{
printf("Imposible abrir %s\n", archivo1);
return 2;
}
if(modoOcultar)
{
// leer texto a ocultar:
char texto[256];
printf("Escriba el texto a ocultar: ");
fgets(texto, 255, stdin);
texto[strlen(texto) - 1] = '%pre%'; // quitar el caracter \n al final del string
ocultar(bmp, texto); // ocultar el texto en el mapa de bits
bmp.save(archivo2); // guardar el archivo resultante
}
else
{
char * buffer;
mostrar(bmp, buffer); // obtener el texto almacenado en el bmp
printf("%s\n", buffer); // e imprimirlo
delete[] buffer;
}
return 0;
}