Para que me diga como hacer arrancar esto en Ubuntu 10.04:
#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#include <math.h>
#include <stdint.h>
/* Grafica el espectro de la imagen. Reinoso G. 15/06/2010
* Toma la línea central y devuelve el histograma en escala de grises.
* Basado en el ejemplo de la libjpeg en http://www.cim.mcgill.ca/~junaed/libjpeg.php
* Compilar con: gcc espectro.c -g -ljpeg -o espectro -Wall -lm
* */
typedef struct {
int colores;
int ancho;
int alto;
int leida;
double *buffer;
} t_linea;
t_linea read_jpeg_line(char *filename, unsigned int num_linea, unsigned int ancho)
{
t_linea central;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
unsigned char* filas[1];
double* media_filas[1];
FILE *infile = fopen( filename, "rb" );
if ( !infile )
{
printf("Error al abrir %s: %s.\n", filename, strerror(errno) );
exit(1);
}
/* JPEG */
cinfo.err = jpeg_std_error( &jerr );
jpeg_create_decompress( &cinfo );
jpeg_stdio_src( &cinfo, infile );
jpeg_read_header( &cinfo, TRUE );
/*
printf( "JPEG File Information: \n" );
printf( "Image width and height: %d pixels and %d pixels.\n", cinfo.image_width, cinfo.image_height );
printf( "Color components per pixel: %d.\n", cinfo.num_components );
printf( "Color space: %d.\n", cinfo.jpeg_color_space );
*/
if (num_linea > cinfo.image_height) {
printf("Imposible obtener la línea %d, el alto de la imagen es de sólo %d.\n",
num_linea,
cinfo.image_height);
exit(1);
}
else if (num_linea == 0) {
num_linea = cinfo.image_height/2;
}
/* reservamos espacio ahora que ya sabemos cuánto */
filas[0] = (unsigned char *)malloc( cinfo.image_width*cinfo.num_components );
media_filas[0] = (double *)malloc( cinfo.image_width*cinfo.num_components*sizeof(double) );
/* Comenzar la descompresión */
jpeg_start_decompress( &cinfo );
/* Leemos hasta la mitad del archivo */
while( cinfo.output_scanline <= num_linea+ancho && cinfo.output_scanline < cinfo.image_height)
{
jpeg_read_scanlines( &cinfo, filas, 1 );
//printf("Leída la línea %d de %d.\n", cinfo.output_scanline, cinfo.image_height);
if (cinfo.output_scanline >= num_linea-ancho && cinfo.output_scanline <= num_linea+ancho)
{
int i;
for (i=1; i <= cinfo.image_width*cinfo.num_components; i++) {
media_filas[0][i-1] = media_filas[0][i-1] + filas[0][i-1]*1.0/(1+2*ancho);
}
printf("Incorporada la línea %d de %d.\n", cinfo.output_scanline, cinfo.image_height);
}
}
central.colores = cinfo.num_components;
central.alto = cinfo.image_height;
central.ancho = cinfo.image_width;
central.leida = num_linea;
central.buffer = media_filas[0];
jpeg_destroy_decompress( &cinfo );
fclose(infile);
free(filas[0]);
return central;
}
/* Escribe un breve fichero AVS con los valores de la linea o lineas analizados */
/* Para eso transforma t_linea.buffer a unsiged char */
void writeimage (char *outfilename, t_linea linea) {
uint32_t width;
uint32_t height;
uint8_t *avsbuffer;
FILE *outfile;
/* Esto porque el formato AVS no le gusta el endian de los intel */
#define SWAP(x) ( ((x) << 24) | \
(((x) << 8) & 0x00ff0000) | \
(((x) >> 8) & 0x0000ff00) | \
((x) >> 24) )
#define FIX(x) (*(unsigned *)&(x) = \
SWAP(*(unsigned *)&(x)))
width = linea.ancho;
width = FIX(width);
height = 10;
height = FIX(height);
int i;
outfile = fopen(outfilename, "wb");
if ( !outfile ) {
printf("Error al abrir %s: %s.\n", outfilename, strerror(errno));
exit(1);
}
avsbuffer = (uint8_t*) malloc(linea.ancho * 4); /* Header + ancho x ARGB */
if (linea.colores == 1) {
int i,j;
for (i = 0, j=0; i < (linea.ancho); i++, j+=4) {
avsbuffer[j] = 0; /* Alpha */
avsbuffer[j+1] = linea.buffer[i]; /* Red */
avsbuffer[j+2] = linea.buffer[i]; /* Green */
avsbuffer[j+3] = linea.buffer[i]; /* Blue */
}
}
else {
int i,j;
for (i = 0, j=0; i < (linea.ancho*3); i+=3, j+=4) {
avsbuffer[j] = 255; /* Alpha */
avsbuffer[j+1] = linea.buffer[i]; /* Red */
avsbuffer[j+2] = linea.buffer[i+1]; /* Green */
avsbuffer[j+3] = linea.buffer[i+2]; /* Blue */
}
}
fwrite(&width, 4, 1, outfile);
fwrite(&height, 4, 1, outfile);
for (i=0; i < 10; i++) {
fwrite(avsbuffer, 1, linea.ancho * 4, outfile);
}
free(avsbuffer);
fclose(outfile);
}
/* Genera el archivo de órdenes para gnuplot y lanza el programa (debe estar en el path) */
void do_gnuplot (char *textfilename, char *graphfilename, t_linea linea) {
FILE *outfile;
outfile = fopen(textfilename, "w");
if ( !outfile ) {
printf("Error al abrir %s: %s.\n", textfilename, strerror(errno));
exit(1);
}
fprintf(outfile,
"set terminal pngcairo nocrop enhanced size 1000,300 truecolor font 'Arial,10'\n"
"#set terminal png nocrop enhanced size 1000,300 # para gnuplot <= 4.2\n"
"se output '%s'\n"
"se xrange [0:%d]\n"
"se yrange [0:1.05]\n"
"se grid front lc rgb '#999999'\n"
"unset key\n"
"plot 'resul_espectro.x' binary filetype=avs with rgbimage, \\\n"
" 'resul_espectro.dat' w l lw 4 lc rgb 'white', \\\n"
" 'resul_espectro.dat' w l lw 2 lc rgb 'red'\n"
, graphfilename, linea.ancho - 1
);
fclose(outfile);
system("gnuplot resul_espectro.plot"); /* sí, está mal, TODO usar textfilename */
}
int main(int argc, char **argv)
{
t_linea linea;
char *infilename;
char *outfilename = "resul_espectro.dat";
int num_linea = 0;
unsigned int ancho = 0;
setlocale (LC_MESSAGES, "");
if (argc < 2 || argc > 4) {
puts("Uso: espectro <fichero.jpg> [linea] [+-lineas]");
exit(1);
}
else if (argc == 3) {
num_linea = atoi(argv[2]);
}
else if (argc == 4) {
num_linea = atoi(argv[2]);
ancho = atoi(argv[3]);
}
infilename = argv[1];
linea = read_jpeg_line(infilename, num_linea, ancho);
if (linea.ancho < 2) {
puts("Imagen no válida.");
exit(1);
}
printf("\nSe ha leído la línea %d de %d (+-%d).\nEl ancho de la linea es %d.\n",
linea.leida,
linea.alto, /* de la imagen, no de la linea */
ancho,
linea.ancho); /* no confundir el ancho de la linea con el ancho vertical de la ponderación */
/* Dibujar la imagen en formato AVS. */
writeimage("resul_espectro.x", linea);
/* Calcular el archivo de salida */
if (linea.colores == 3) {
int i;
int lum = 0;
unsigned char x,y,z;
int max = 0;
FILE *outfile;
/* Evaluar el máximo */
for (i = 0; i < (linea.ancho*3); i+=3) {
long acc;
x = linea.buffer[i];
y = linea.buffer[i+1];
z = linea.buffer[i+2];
/* lum = x+3*y+z; */
acc = x*x;
acc += y*y;
acc += z*z;
lum = sqrt(acc);
if (max < lum) max = lum;
}
printf("Imagen en color, valor máximo %d.\n", max);
printf("Escribiendo el archivo %s...\n", outfilename);
outfile = fopen(outfilename, "w");
if ( !outfile ) {
printf("Error al abrir %s: %s.\n", outfilename, strerror(errno));
exit(1);
}
/* Escribir los valores normalizados */
for (i = 0; i < (linea.ancho*3); i+=3) {
long acc;
x = linea.buffer[i];
y = linea.buffer[i+1];
z = linea.buffer[i+2];
/* lum = x+3*y+z; */
acc = x*x;
acc += y*y;
acc += z*z;
lum = sqrt(acc);
fprintf(outfile, "%i\t%f\n", i/3, lum/(float)max);
//printf("%i\t%x %x %x %d\t%f\n", i/3, x,y,z,lum,lum/(float)max);
}
fclose(outfile);
}
else if (linea.colores == 1) {
int i;
int max = 0;
FILE *outfile;
/* Evaluar el máximo */
for (i = 0; i < linea.ancho; i++) {
if (max < linea.buffer[i]) max = linea.buffer[i];
}
printf("Imagen en escala de grises, valor máximo %d.\n", max);
printf("Escribiendo el archivo %s...\n", outfilename);
outfile = fopen(outfilename, "w");
if ( !outfile ) {
printf("Error al abrir %s: %s.\n", outfilename, strerror(errno));
exit(1);
}
/* Escribir los valores normalizados */
for (i = 0; i < linea.ancho; i++) {
fprintf(outfile, "%i\t%f\n", i, linea.buffer[i]/(float)max);
}
fclose(outfile);
}
else {
puts("Tipo de imagen no reconocida.");
exit(1);
}
/* Dibujar el gráfico con gnuplot */
puts("Llamando a Gnuplot...");
do_gnuplot("resul_espectro.plot", "resul_espectro.png", linea);
puts("Hecho.");
return 0;
}
Lo he intentado con gcc -o y con gcc espectro.c -g -ljpeg -o espectro -Wall -lm y me saltan como 20 errores de compilacion, el creador del codigo no deja direccion de contacto, y como no tengo ni puta idea de programacion pues pregunto a ver si algun valiente quiere hacer correr esto en ubuntu, me seria realmente util.
P.D.: Regalo sable laser al ganador!!1!