soy nuevo por aquí, lo que pasa es que tengo que leer un archivo (una imagen) PPM mediante un programa de C++, estoy usando QT Creator y el programa lo creé usando CMAKE a partir de un archivo CMakeLists.txt. En el CMakeLists coloqué todas las carpetas que necesito al igual que los .h y.c que voy a utilizar, sin embargo, cuando intento leer desde el main la imagen, me saltan dos errores. Si estoy incluyendo el archivo de cabecera en el main.
Este es el archivo CMakeLists.txt
project(testc LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(testc_src
"test/main.cpp"
"include/ppm.h"
"source/ppm.c"
)
add_executable(testc ${testc_src})
include_directories ( ./include)
El archivo de cabecera .h
*
* ppm.h
*
* Read and write PPM files. Only works for "raw" format.
*
* AF970205
*
****************************************************************/
#ifndef PPM_H
#define PPM_H
#include <sys/types.h>
#define u_char unsigned char
typedef struct Image //crea un nuevo tipo Image de tipo struct
{
int width;
int height;
u_char *data;
} Image;//crea una variable imagen
Image *ImageCreate(int width, int height);
Image *ImageRead(const char *filename);
void ImageWrite(Image *image, const char *filename);
int ImageWidth(Image *image);
int ImageHeight(Image *image);
void ImageClear(Image *image, u_char red, u_char green, u_char blue);
void ImageSetPixel(Image *image, int x, int y, int chan, u_char val);
u_char ImageGetPixel(Image *image, int x, int y, int chan);
#endif /* PPM_H */
El archivo .c
*
* ppm.c
*
* Read and write PPM files. Only works for "raw" format.
*
* AF970205
*
****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "ppm.h"
#include <sys/types.h>
#define u_char unsigned char
/************************ private functions ****************************/
/* die gracelessly */
static void
die(char *message)
{
fprintf(stderr, "ppm: %s\n", message);
exit(1);
}
/* check a dimension (width or height) from the image file for reasonability */
static void
checkDimension(int dim)
{
if (dim < 1 || dim > 4000) //si es muy grande o tiene valores negativos el archivo no abre
die("file contained unreasonable width or height");
}
/* read a header: verify format and get width and height */
static void
readPPMHeader(FILE *fp, int *width, int *height)
{
char ch;
int maxval;
if (fscanf(fp, "P%c\n", &ch) != 1 || ch != '6') //si fscanf retorna un numero diferente de 1 entonces falla la función. Si el numero que acompaña a la P no es el 6 no es PPM
die("file is not in ppm raw format; cannot read");
/* skip comments */
ch = getc(fp);
while (ch == '#')
{
do {
ch = getc(fp);
} while (ch != '\n'); /* read to the end of the line Lee hasta que el dato sea \n*/
ch = getc(fp); /* Continua leyendo en la siguiente linea*/
}
if (!isdigit(ch)) die("cannot read header information from ppm file"); //Si lo que se lee no es un numero, entonces se generar un error
ungetc(ch, fp); /* put that digit back Se devuelve una posición para leer de nuevo el número*/
/* read the width, height, and maximum value for a pixel */
fscanf(fp, "%d%d%d\n", width, height, &maxval);
if (maxval != 255) die("image is not true-color (24 bit); read failed");
checkDimension(*width);
checkDimension(*height);
}
/************************ exported functions ****************************/ //Funciones que vienen del .h
Image *
ImageCreate(int width, int height) //Crea la imagen, asigna o reserva espacios de memoria para crear la imagen
{
Image *image = (Image *) malloc(sizeof(Image));
if (!image) die("cannot allocate memory for new image");
image->width = width;
image->height = height;
image->data = (u_char *) malloc(width * height * 3);
if (!image->data) die("cannot allocate memory for new image");
return image;
}
Image *
ImageRead(const char *filename)
{
int width, height, num, size;
u_char *p;
Image *image = (Image *) malloc(sizeof(Image));
FILE *fp = fopen(filename, "r");
if (!image) die("cannot allocate memory for new image");
if (!fp) die("cannot open file for reading");
readPPMHeader(fp, &width, &height);
size = width * height * 3;
image->data = (u_char *) malloc(size);
image->width = width;
image->height = height;
if (!image->data) die("cannot allocate memory for new image");
num = fread((void *) image->data, 1, (size_t) size, fp);
if (num != size) die("cannot read image data from file");
fclose(fp);
return image;
}
void ImageWrite(Image *image, const char *filename)
{
int num;
int size = image->width * image->height * 3;
FILE *fp = fopen(filename, "w");
if (!fp) die("cannot open file for writing");
fprintf(fp, "P6\n%d %d\n%d\n", image->width, image->height, 255);
num = fwrite((void *) image->data, 1, (size_t) size, fp);
if (num != size) die("cannot write image data to file");
fclose(fp);
}
int
ImageWidth(Image *image)
{
return image->width;
}
int
ImageHeight(Image *image)
{
return image->height;
}
void
ImageClear(Image *image, u_char red, u_char green, u_char blue)
{
int i;
int pix = image->width * image->height;
u_char *data = image->data;
for (i = 0; i < pix; i++)
{
*data++ = red;
*data++ = green;
*data++ = blue;
}
}
void
ImageSetPixel(Image *image, int x, int y, int chan, u_char val)
{
int offset = (y * image->width + x) * 3 + chan;
image->data[offset] = val;
}
u_char
ImageGetPixel(Image *image, int x, int y, int chan)
{
int offset = (y * image->width + x) * 3 + chan;
return image->data[offset];
}
El programa principal main.cpp
#include "ppm.h"
using namespace std;
int main()
{
Image *image;
const char *filename="Data/uno.ppm";
image = ImageRead(filename);
cout << "Hello World!" << endl;
system("pause");
return 0;
}
Todos los archivos están en sus carpetas correspondientes pero cuando intento leer la imagen los errores que me aparecen son: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] char *filename="Data/uno.ppm"; //const
Y luego que "ImageRead" no está definida pero sí está definida:
error: undefined reference to `ImageRead(char*)'
¿Qué puedo hacer para leer la imagen? Gracias por su ayuda!!!
PD: El código nos lo entregaron de una página web y debemos arreglarlo, pero no encuentro por qué no funciona. Gracias de nuevo.
Edit 1: El código actual se encuentra actualizado según el comentario que colocó braver anteriormente. Se cambiaron todas las funciones que tenían char por const char sin embargo aún aparece el siguiente error: error: undefined reference to `ImageRead(char const*)'