Se busca a alguien con un par de cojones

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!
coyote@Miyuki ~$ gcc espectro.c -g -ljpeg -o espectro -Wall -lm
coyote@Miyuki ~$ ls -lh espectro*
-rwxr-xr-x 1 coyote users  27K oct 12 18:01 espectro
-rw-r--r-- 1 coyote users 9,0K oct 12 18:00 espectro.c


En ArchLinux x86_64

Ni un solo warning hoyga... tienes instalado toda la paqueteria de desarrollo?

EDIT: donde esta mi sable laser? XD
sin errores

$ gcc main.c -g -ljpeg -o espectro -Wall -lm
$ ll
total 44K
-rwxr-xr-x 1 jose jose  29K 2010-10-12 18:09 espectro
-rw-r--r-- 1 jose jose 9,0K 2010-10-12 18:03 main.c
Obviamente, también tendrías que instalar el paquete -dev de jpeg (o libjpeg) XD
coyote escribió:Obviamente, también tendrías que instalar el paquete -dev de jpeg (o libjpeg) XD

listo, era lo que me faltaba [sonrisa]

sudo apt-get install libjpeg-dev


compilado, que curioso... a ti te deja el ejecutable con 27k a mi con 29k, por cierto compilado en Ubuntu 10.10 64Bits
AzagraMac escribió:compilado, que curioso... a ti te deja el ejecutable con 27k a mi con 29k, por cierto compilado en Ubuntu 10.10 64Bits


Sera por la optimización:

CFLAGS="-march=native -mtune=native -O2 -pipe"
CXXFLAGS="-march=native -mtune=native -O2 -pipe"
MAKEFLAGS="-j3"
AzagraMac escribió:
coyote escribió:Obviamente, también tendrías que instalar el paquete -dev de jpeg (o libjpeg) XD

listo, era lo que me faltaba [sonrisa]

sudo apt-get install libjpeg-dev


compilado, que curioso... a ti te deja el ejecutable con 27k a mi con 29k, por cierto compilado en Ubuntu 10.10 64Bits



Va a ser que tenias razon, pensaba que ya tenia lo que el programa necesitaba, lo comprobe con synaptic y creei que si, pero ahora hay otro problema: debo ser gilipollas pero no consigo lanzar el ejecutable, me escupe un ejecutable pero desde escritorio no se abre nada, y desde consola no se como ejecutarlo, ni ./ ni sh ni escribiendo el nombre a pelo.


Al sable laser esperad que lo vea corriendo :o
coyote@Miyuki ~$ ./espectro 2010-10-12-333547.jpeg
Incorporada la línea 312 de 624.

Se ha leído la línea 312 de 624 (+-0).
El ancho de la linea es 515.
Imagen en color, valor máximo 441.
Escribiendo el archivo resul_espectro.dat...
Llamando a Gnuplot...
sh: gnuplot: no se encontró la orden
Hecho.

Es una app de consola. Obviamente, no tengo instalado gnuplot.

PD: chmod +x nombre_programa
a mi si me lanza gnuplot, de echo me ha dejado varios archivos donde tengo el .jpeg
AzagraMac escribió:a mi si me lanza gnuplot, de echo me ha dejado varios archivos donde tengo el .jpeg



Es un programa que tu le metes una espectrografia cutre y te saca el solito las frecuencias, cosa que a mano es insufrible, el problema estoy viendo es que tendria que escupirte un png con la grafica y solo me escupe los datos, supongo que tendre que investigar un poco mas el programa, si quieres te paso de donde lo saque, el sitio esta interesante. SI me rayo mas con el programa os aviso.

Muchas gracias a ambos, por cierto coyote:


Imagen

Elije el color!
Storz escribió:Muchas gracias a ambos, por cierto coyote:


Imagen

Elije el color!

Me pillo el blanco (o azulao claro, según se mire) :D
coyote escribió:
Storz escribió:Muchas gracias a ambos, por cierto coyote:


Imagen

Elije el color!

Me pillo el blanco (o azulao claro, según se mire) :D



Ahora mismo voy a correos y te lo mando XD


Ma surgio una duda mas, ya lo he echo arrancar y me escupe esto:

try$ ./espectro test.jpg 1 2

Se ha le�do la l�nea 1 de 640 (+-2).
El ancho de la linea es 480.
Imagen en color, valor m�ximo 0.
Escribiendo el archivo resul_espectro.dat...
Llamando a Gnuplot...

set terminal pngcairo nocrop enhanced size 1000,300 truecolor font 'Arial,10'
             ^
"resul_espectro.plot", line 1: unknown or ambiguous terminal type; type just 'set terminal' for a list

Hecho.



Creo que la parte que no me rula de escupirme el png es la del pngcairo, dize que tiene que leer la historia de resul_espectro.plot, y abro el archivo y me sale esto:

set terminal pngcairo nocrop enhanced size 1000,300 truecolor font 'Arial,10'
#set terminal png nocrop enhanced size 1000,300 # para gnuplot <= 4.2
se output  'resul_espectro.png'
se xrange [0:479]
se yrange [0:1.05]
se grid front lc rgb '#999999'
unset key
plot 'resul_espectro.x' binary filetype=avs with rgbimage, \
    'resul_espectro.dat' w l lw 4 lc rgb 'white', \
    'resul_espectro.dat' w l lw 2 lc rgb 'red'




Vamos, que el plot ese es lo que me escupe mi amado png, pero el plot no funciona porque pngcairo no esta o suda de trabajar o lo que sea, el caso es que lo he buscado en el centro de software y no existe nada llamado pngcairo.

¿alguien sabe que es pngcairo y porque no me funciona? (esta vez tendreis que conformaros con un vivbrador luminoso o una vagina en lata como regalo, se me ha ido todo el presupuesto ya en sables laser)
Storz escribió:Muchas gracias a ambos, por cierto coyote:


Imagen

Elije el color!

Si queda algún otro.. me pillo el rojo xD


pd: si me deja un .png con una grafica
$ ll
total 364K
-rwxr-xr-x 1 jose jose  29K 2010-10-12 19:33 espectro
-rw-r--r-- 1 jose jose 9,0K 2010-10-12 18:03 main.c
-rw-r--r-- 1 jose jose 222K 2010-09-27 23:26 prueba.jpg
-rw-r--r-- 1 jose jose  11K 2010-10-12 19:33 resul_espectro.dat
-rw-r--r-- 1 jose jose  418 2010-10-12 19:33 resul_espectro.plot
-rw-r--r-- 1 jose jose  48K 2010-10-12 19:33 resul_espectro.png
-rw-r--r-- 1 jose jose  32K 2010-10-12 19:33 resul_espectro.x
o$ ./espectro prueba.jpg
Incorporada la línea 366 de 732.

Se ha leído la línea 366 de 732 (+-0).
El ancho de la linea es 800.
Imagen en color, valor máximo 418.
Escribiendo el archivo resul_espectro.dat...
Llamando a Gnuplot...
Hecho.

   G N U P L O T
   Version 4.4 patchlevel 0
   last modified March 2010
   System: Linux 2.6.35-22-generic

   Copyright (C) 1986-1993, 1998, 2004, 2007-2010
   Thomas Williams, Colin Kelley and many others

   gnuplot home:     http://www.gnuplot.info
   faq, bugs, etc:   type "help seeking-assistance"
   immediate help:   type "help"
   plot window:      hit 'h'

Terminal type set to 'wxt'
gnuplot>

resul_espectro.png
Imagen
DIIIIIIIIIIOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOSSSSSSSSSSSSSSSSSSSSs


Por fin, la ostia, por fiiiiiiiiiiiiiin


A ver, si no es por el codigo de Azagra ni me entero, mi gnuplot es 4.2, para sacar el png tengo que descomentar una linea del archivo .plot y comentar otra, y he tenido que rebuscar en el codigo fuente la funcion para ejecutarlo, hasta que no edite el codigo y lo recompile son esos dos pasos, y ya me escupe mi amado png:

Imagen

Mira, prueba con esta imagen:

Imagen























SABLES LASER PARA TODOOOOOOOOOOOOOOOOOOOOSSSSSS!!!1!1!!11 AMOOOOOS YAAAAAAAAA
Imagen
Imagen
Imagen
No es un poco diferente tu .png del mio?
Imagen

y el tuyo
Imagen
AzagraMac escribió:No es un poco diferente tu .png del mio?
Imagen

y el tuyo
Imagen



He estado mirado y creo que es porque estaba jugando con los valores del programa cuando saque la foto, el programa te deja meter una foto y 2 valores. Segun el autor, el primer valor determina la linea a seguir (ni idea de si la linea es del espectro o de la grafica o de donde), si no la indicas por defecto sigue la de en medio, y el segundo te extrae las lineas adyacentes que pidas (tampoco se exactamente que lineas habla).

Si quieres te subo mas espectogramas para que lo pruebes, a mi me ha estado funcionando de maravilla, el programa no es muy preciso (bastante mas que yo fijo) pero la fuente no es que lo sea tampoco, y un equipo profesional de los 1500€ no baja.
15 respuestas