Lectura BMP

Todo lo relacionado con los gráficos en ADA.

Moderadores: gneuromante, Andres_age, Yzumi

Lectura BMP

Notapor Yzumi » Mar Abr 07, 2009 23:14

Haver si podrias mirar este programa para la lectura de imagenes de mapas de bits de 24 bits/pixel, ya se que lleva trabajo pero hace un tiempo que quiero realizar este programa, en concreto me da
STORAGE ERROR : EXCEPTION_STACK_OVERFLOW. Ayudadme por favor:

Código: Seleccionar todo
PACKAGE Mapa_Bits IS
   --
   TYPE Byte IS ARRAY (0..7) OF Boolean;
   PRAGMA Pack (Byte);
   --
   TYPE Color IS RECORD
      R,G,B:Integer;
   END RECORD;
   --
   TYPE Matriu IS ARRAY(0..1000,0..1000) OF Color;
   --
   TYPE Mapa_Bit IS RECORD
      X,Y:Integer;
      M:Matriu;
   END RECORD;
   --
   --declaracio d'excepcions:
   --
   Mapa_Bits_Incorrecte,Mapa_De_Bits_Impossible_Lectura:EXCEPTION;
   --
   --declaracio de funcions:
   --
   FUNCTION Lectura_Mapa_Bits(S:IN String) RETURN Mapa_Bit;
END Mapa_Bits;



Código: Seleccionar todo
WITH Ada.Direct_Io;
PACKAGE BODY Mapa_Bits IS
   -------------------------------------------------------------------------------
   -------------------------------------------------------------------------------
   --                                                                           --
   --Estructures usades:                                                        --
   --                                                                           --
   --   TYPE Color IS RECORD                                                    --
   --      R,G,B:Integer;                                                       --
   --   END RECORD;                                                             --
   --   --                                                                      --
   --   TYPE Matriu IS ARRAY(0..1000,0..1000) OF Color;                         --
   --   --                                                                      --
   --   TYPE Mapa_Bit IS RECORD                                                 --
   --      X,Y:Integer;                                                         --
   --      M:Matriu;                                                            --
   --   END RECORD;                                                             --
   --                                                                           --
   --Enllaç d'on s'ha extret l'informacio:                                      --
   --                                                                           --
   --http://en.wikipedia.org/wiki/BMP_file_format                               --
   --                                                                           --
   -------------------------------------------------------------------------------
   -------------------------------------------------------------------------------

   --
   --implementacio procediments i funcions auxiliars:
   --
   FUNCTION Binari_Decimal(B:IN Byte) RETURN Integer IS
      Enter:Integer:=0;
   BEGIN
      FOR I IN 0..8 LOOP
         IF B(I) THEN
            Enter:=Enter+2**I;
         END IF;
      END LOOP;
      RETURN Enter;
   END Binari_Decimal;
   --
   --procediment que comprova si es un mapa de bits realment:
   --
   PROCEDURE Comprovant_Real(B1,B2:IN Byte) IS
   BEGIN
      IF Binari_Decimal(B1)/=66 OR Binari_Decimal(B2)/=77 THEN
         RAISE Mapa_Bits_Incorrecte;
      END IF;
   END Comprovant_Real;
   --
   --procediment que comprova que no hi hagui compresio:
   --
   PROCEDURE Comprova_No_Compresio(B3,B2,B1,B0:IN Byte) IS
   BEGIN
      FOR I IN 0..8 LOOP
         IF B3(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
      --
      --
      FOR I IN 0..8 LOOP
         IF B2(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
      --
      --
      FOR I IN 0..8 LOOP
         IF B1(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
      --
      --
      FOR I IN 0..8 LOOP
         IF B0(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
   END Comprova_No_Compresio;
   --
   --procediment de suma de bytes pasat a decimal:
   --
   FUNCTION Suma(B0,B1,B2,B3:IN Byte) RETURN Integer IS
      Enter:Integer:=0;
   BEGIN
      Enter:=Enter+Binari_Decimal(B0);
      Enter:=Enter+Binari_Decimal(B1)*2**8;
      Enter:=Enter+Binari_Decimal(B2)*2**16;
      Enter:=Enter+Binari_Decimal(B3)*2**24;
      RETURN Enter;
   END Suma;
   --
   --implementacio de procediments:
   --
   FUNCTION Lectura_Mapa_Bits(S:IN String) RETURN Mapa_Bit IS
      M:Mapa_Bit;
      PACKAGE Direct_Byte_Io IS NEW Ada.Direct_Io(Byte);
      USE Direct_Byte_Io;
      F:Direct_Byte_Io.File_Type;
      --
      B:Byte;
      B1,B2:Byte;
      Tamany0,Tamany1,Tamany2,Tamany3:Byte;
      Offset0,Offset1,Offset2,Offset3:Byte;
      Capsalera0,Capsalera1,Capsalera2,Capsalera3:Byte;
      Amplaria0,Amplaria1,Amplaria2,Amplaria3:Byte;
      Altaria0,Altaria1,Altaria2,Altaria3:Byte;
      Bits_Per_Pixel0,Bits_Per_Pixel1:Byte;
      Compresio0,Compresio1,Compresio2,Compresio3:Byte;
      Dades0,Dades1,Dades2,Dades3:Byte;
      Resolucio_Horitzontal0,Resolucio_Horitzontal1,Resolucio_Horitzontal2,Resolucio_Horitzontal3:Byte;
      Resolucio_Vertical0,Resolucio_Vertical1,Resolucio_Vertical2,Resolucio_Vertical3:Byte;
      Color_Paleta0,Color_Paleta1,Color_Paleta2,Color_Paleta3:Byte;
      Colors_Importants0,Colors_Importants1,Colors_Importants2,Colors_Importants3:Byte;
   BEGIN
      Open(F,In_File,S);
      --
      --comprovacio BM:
      --
      Read(F,B1);
      Read(F,B2);
      Comprovant_Real(B1,B2);
      --
      --llegim el tamany del mapa de bits:
      --
      Read(F,Tamany3);
      Read(F,Tamany2);
      Read(F,Tamany1);
      Read(F,Tamany0);
      --
      --ignoram valors no usats:
      --
      FOR I IN 1..4 LOOP
         Read(F,B);
      END LOOP;
      --
      --llegim a quin offset trobam els pixels a partir de l'inici del fitxer:
      --
      Read(F,Offset3);
      Read(F,Offset2);
      Read(F,Offset1);
      Read(F,Offset0);
      --
      --llegim quants de bytes queden abans del final de la capsalera a partir d'aquest punt aquest 4 bytes s'inclouen:
      --
      Read(F,Capsalera3);
      Read(F,Capsalera2);
      Read(F,Capsalera1);
      Read(F,Capsalera0);
      --
      --llegim l'amplaria del mapa de bits:
      --
      Read(F,Amplaria3);
      Read(F,Amplaria2);
      Read(F,Amplaria1);
      Read(F,Amplaria0);
      M.X:=Suma(Amplaria0,Amplaria1,Amplaria2,Amplaria3);
      --
      --llegim l'altaria del mapa de bits:
      --
      Read(F,Altaria3);
      Read(F,Altaria2);
      Read(F,Altaria1);
      Read(F,Altaria0);
      M.Y:=Suma(Altaria0,Altaria1,Altaria2,Altaria3);
      --
      --Number of color planes being used:
      --
      Read(F,B);
      Read(F,B);
      --
      --llegim el nombre de bits per pixel que s'usen: (si no es de 24 hem d'elevar excepcio ja que no seria RGB)
      --
      Read(F,Bits_Per_Pixel1);
      Read(F,Bits_Per_Pixel0);
      --
      --comprovam si esta comprimit:
      --
      Read(F,Compresio3);
      Read(F,Compresio1);
      Read(F,Compresio2);
      Read(F,Compresio0);
      Comprova_No_Compresio(Compresio3,Compresio1,Compresio2,Compresio0);
      --
      --Miram el numero de bytes que ens queden a llegir abans que hi hagui pixels sense incloure els actuals:
      --
      Read(F,Dades3);
      Read(F,Dades2);
      Read(F,Dades1);
      Read(F,Dades0);
      --
      --Miram la resolucio horitzontal de l'imatge:
      --
      Read(F,Resolucio_Horitzontal3);
      Read(F,Resolucio_Horitzontal2);
      Read(F,Resolucio_Horitzontal1);
      Read(F,Resolucio_Horitzontal0);
      --
      --Miram la resolucio vertical de l'imatge:
      --
      Read(F,Resolucio_Vertical3);
      Read(F,Resolucio_Vertical2);
      Read(F,Resolucio_Vertical1);
      Read(F,Resolucio_Vertical0);
      --
      --Number of colors in the palette:
      --
      Read(F,Color_Paleta3);
      Read(F,Color_Paleta2);
      Read(F,Color_Paleta1);
      Read(F,Color_Paleta0);
      --
      --nombre de colors importants:
      --
      Read(F,Colors_Importants3);
      Read(F,Colors_Importants2);
      Read(F,Colors_Importants1);
      Read(F,Colors_Importants0);

      --
      --lectura de pixels:
      --
      FOR Y IN REVERSE 0..M.Y LOOP
         FOR X IN 0..M.X LOOP
            --
            --llegim 3 bytes que serien el que ens ocupa 1 pixel:
            --
            Read(F,B);
            M.M(X,Y).R:=Binari_Decimal(B);
            Read(F,B);
            M.M(X,Y).G:=Binari_Decimal(B);
            Read(F,B);
            M.M(X,Y).B:=Binari_Decimal(B);
         END LOOP;
         --
         --llegim els 2 bytes que ens separen la columna poden ser diferents de zero no se si guarden cap informacio son usables?
         --
         Read(F,B);
         Read(F,B);
      END LOOP;
      --
      --retornam el mapa de bits llegit:
      --
      RETURN M;
      --
      --
   END Lectura_Mapa_Bits;
END Mapa_Bits;



Código: Seleccionar todo
WITH Adagraph;USE Adagraph;
WITH Mapa_Bits;USE Mapa_Bits;
PROCEDURE Programa IS
   M:Mapa_Bit;
BEGIN
   Open_Graph_Window(640,480);
   Wait_For_Key;
   M:=Lectura_Mapa_Bits("imatge.bmp");
   Wait_For_Key;
   FOR I IN 1..640 LOOP
      FOR J IN 1..480 LOOP
         Put_Pixel(I,J,Closest_Color(M.M(I-1,J-1).R,M.M(I-1,J-1).G,M.M(I-1,J-1).B));
      END LOOP;
   END LOOP;
   Wait_For_Key;
END Programa;
by YZU xD
Yzumi
Experto
Experto
 
Mensajes: 68
Registrado: Mar Feb 26, 2008 15:30

Re: Lectura BMP

Notapor gneuromante » Mié Abr 08, 2009 0:11

Te está dando un stack overflow. Tienes dos opciones, aumentar el tamaño del stack (que depende del sistema operativo que uses) o hacer menos uso del stack.

El stack es la zona de memoria que se usa para:
  • Pasar los parámetros a los subprogramas (que se suelen pasar por referencia si son compuestos) y otra información necesaria para llamar a los subprogramas
  • Declarar variables locales a un subprograma
  • Devolver resultado de una función

En tu caso puede que se desborde al llamar a la función Lectura_Mapa_Bits porque devuelve un tipo compuesto de un gran tamaño. Toda esta variable se vuelca en el stack para devolverla. Prueba a pasarlo como parámetro out ya que en tal caso sólo se copiará en el stack la dirección de memoria de la variable y no necesitarás declararte una variable local (M), lo que te ahorrará bastante uso de stack.
gneuromante
Gurú Moderador
Gurú Moderador
 
Mensajes: 194
Registrado: Mié Mar 09, 2005 0:34

Re: Lectura BMP

Notapor Yzumi » Mié Abr 08, 2009 0:19

almenos ahora no da stack ahora me da un constraint pero supongo que es un fallo mio ya me lo miraré...
by YZU xD
Yzumi
Experto
Experto
 
Mensajes: 68
Registrado: Mar Feb 26, 2008 15:30

Re: Lectura BMP

Notapor Yzumi » Vie Abr 17, 2009 11:14

finalizada la libreria para bmp de tamaño maximo 1000x1000 sin compresion de 24 bits:

Código: Seleccionar todo
WITH Ada.Direct_Io;
WITH Ada.Integer_Text_IO;USE Ada.Integer_Text_IO;
PACKAGE BODY Mapa_Bits IS
   -------------------------------------------------------------------------------
   -------------------------------------------------------------------------------
   --                                                                           --
   --Estructures usades:                                                        --
   --                                                                           --
   --   TYPE Color IS RECORD                                                    --
   --      R,G,B:Integer;                                                       --
   --   END RECORD;                                                             --
   --   --                                                                      --
   --   TYPE Matriu IS ARRAY(0..1000,0..1000) OF Color;                         --
   --   --                                                                      --
   --   TYPE Mapa_Bit IS RECORD                                                 --
   --      X,Y:Integer;                                                         --
   --      M:Matriu;                                                            --
   --   END RECORD;                                                             --
   --                                                                           --
   --                                                                           --
   -------------------------------------------------------------------------------
   -------------------------------------------------------------------------------

   --
   --implementacio procediments i funcions auxiliars:
   --
   FUNCTION Binari_Decimal(B:IN Byte) RETURN Integer IS
      Enter:Integer:=0;
   BEGIN
      FOR I IN 0..7 LOOP
         IF B(I) THEN
            Enter:=Enter+2**I;
         END IF;
      END LOOP;
      RETURN Enter;
   END Binari_Decimal;
   --
   --procediment que comprova si es un mapa de bits realment:
   --
   PROCEDURE Comprovant_Real(B1,B2:IN Byte) IS
   BEGIN
      IF Binari_Decimal(B1)/=66 OR Binari_Decimal(B2)/=77 THEN
         RAISE Mapa_Bits_Incorrecte;
      END IF;
   END Comprovant_Real;
   --
   --procediment que comprova que no hi hagui compresio:
   --
   PROCEDURE Comprova_No_Compresio(B3,B2,B1,B0:IN Byte) IS
   BEGIN
      FOR I IN 0..7 LOOP
         IF B3(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
      --
      --
      FOR I IN 0..7 LOOP
         IF B2(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
      --
      --
      FOR I IN 0..7 LOOP
         IF B1(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
      --
      --
      FOR I IN 0..7 LOOP
         IF B0(I) THEN
            RAISE Mapa_De_Bits_Impossible_Lectura;
         END IF;
      END LOOP;
   END Comprova_No_Compresio;
   --
   --procediment de suma de bytes pasat a decimal:(no funciona)
   --
   FUNCTION Suma(B0,B1,B2,B3:IN Byte) RETURN Integer IS
      Enter:Integer:=0;
   BEGIN
      Enter:=Enter+Binari_Decimal(B3);
      Enter:=Enter+Binari_Decimal(B2)*2**8;
      Enter:=Enter+Binari_Decimal(B1)*2**16;
      Enter:=Enter+Binari_Decimal(B0)*2**24;
      RETURN Enter;
   END Suma;
   --
   --implementacio de procediments:
   --
   PROCEDURE Lectura_Mapa_Bits(S:IN String;M:OUT Mapa_Bit) IS
      PACKAGE Direct_Byte_Io IS NEW Ada.Direct_Io(Byte);
      USE Direct_Byte_Io;
      F:Direct_Byte_Io.File_Type;
      --
      B:Byte;
      B1,B2:Byte;
      Tamany0,Tamany1,Tamany2,Tamany3:Byte;
      Offset0,Offset1,Offset2,Offset3:Byte;
      Capsalera0,Capsalera1,Capsalera2,Capsalera3:Byte;
      Amplaria0,Amplaria1,Amplaria2,Amplaria3:Byte;
      Altaria0,Altaria1,Altaria2,Altaria3:Byte;
      Bits_Per_Pixel0,Bits_Per_Pixel1:Byte;
      Compresio0,Compresio1,Compresio2,Compresio3:Byte;
      Dades0,Dades1,Dades2,Dades3:Byte;
      Resolucio_Horitzontal0,Resolucio_Horitzontal1,Resolucio_Horitzontal2,Resolucio_Horitzontal3:Byte;
      Resolucio_Vertical0,Resolucio_Vertical1,Resolucio_Vertical2,Resolucio_Vertical3:Byte;
      Color_Paleta0,Color_Paleta1,Color_Paleta2,Color_Paleta3:Byte;
      Colors_Importants0,Colors_Importants1,Colors_Importants2,Colors_Importants3:Byte;
   BEGIN
      Open(F,In_File,S);
      --
      --comprovacio BM:
      --
      Read(F,B1);
      Read(F,B2);
      Comprovant_Real(B1,B2);
      --
      --llegim el tamany del mapa de bits:
      --
      Read(F,Tamany3);
      Read(F,Tamany2);
      Read(F,Tamany1);
      Read(F,Tamany0);
      --
      --ignoram valors no usats:
      --
      FOR I IN 1..4 LOOP
         Read(F,B);
      END LOOP;
      --
      --llegim a quin offset trobam els pixels a partir de l'inici del fitxer:
      --
      Read(F,Offset3);
      Read(F,Offset2);
      Read(F,Offset1);
      Read(F,Offset0);
      --
      --llegim quants de bytes queden abans del final de la capsalera a partir d'aquest punt aquest 4 bytes s'inclouen:
      --
      Read(F,Capsalera3);
      Read(F,Capsalera2);
      Read(F,Capsalera1);
      Read(F,Capsalera0);
      --
      --llegim l'amplaria del mapa de bits:
      --
      Read(F,Amplaria3);
      Read(F,Amplaria2);
      Read(F,Amplaria1);
      Read(F,Amplaria0);
      M.X:=Suma(Amplaria0,Amplaria1,Amplaria2,Amplaria3);
      Put(M.X);
      --
      --llegim l'altaria del mapa de bits:
      --
      Read(F,Altaria3);
      Read(F,Altaria2);
      Read(F,Altaria1);
      Read(F,Altaria0);
      M.Y:=Suma(Altaria0,Altaria1,Altaria2,Altaria3);
      Put(M.Y);
      --
      --Number of color planes being used:
      --
      Read(F,B);
      Read(F,B);
      --
      --llegim el nombre de bits per pixel que s'usen: (si no es de 24 hem d'elevar excepcio ja que no seria RGB)
      --
      Read(F,Bits_Per_Pixel1);
      Read(F,Bits_Per_Pixel0);
      --
      --comprovam si esta comprimit:
      --
      Read(F,Compresio3);
      Read(F,Compresio1);
      Read(F,Compresio2);
      Read(F,Compresio0);
      Comprova_No_Compresio(Compresio3,Compresio1,Compresio2,Compresio0);
      --
      --Miram el numero de bytes que ens queden a llegir abans que hi hagui pixels sense incloure els actuals:
      --
      Read(F,Dades3);
      Read(F,Dades2);
      Read(F,Dades1);
      Read(F,Dades0);
      --
      --Miram la resolucio horitzontal de l'imatge:
      --
      Read(F,Resolucio_Horitzontal3);
      Read(F,Resolucio_Horitzontal2);
      Read(F,Resolucio_Horitzontal1);
      Read(F,Resolucio_Horitzontal0);
      --
      --Miram la resolucio vertical de l'imatge:
      --
      Read(F,Resolucio_Vertical3);
      Read(F,Resolucio_Vertical2);
      Read(F,Resolucio_Vertical1);
      Read(F,Resolucio_Vertical0);
      --
      --Number of colors in the palette:
      --
      Read(F,Color_Paleta3);
      Read(F,Color_Paleta2);
      Read(F,Color_Paleta1);
      Read(F,Color_Paleta0);
      --
      --nombre de colors importants:
      --
      Read(F,Colors_Importants3);
      Read(F,Colors_Importants2);
      Read(F,Colors_Importants1);
      Read(F,Colors_Importants0);

      --
      --lectura de pixels:
      --
      FOR Y IN 0..M.Y-1 LOOP
         FOR X IN 0..M.X-1 LOOP
            --
            --llegim 3 bytes que serien el que ens ocupa 1 pixel:
            --
            Read(F,B);
            M.M(X,Y).B:=Binari_Decimal(B);
            Read(F,B);
            M.M(X,Y).G:=Binari_Decimal(B);
            Read(F,B);
            M.M(X,Y).R:=Binari_Decimal(B);
         END LOOP;
         --
         --Bytes de fi de columna?
         --
         --Read(F,B);
         --Read(F,B);
      END LOOP;
      Close(F);
      --
      --
   END Lectura_Mapa_Bits;
END Mapa_Bits;



Código: Seleccionar todo
PACKAGE Mapa_Bits IS
   --
   TYPE Byte IS ARRAY (0..7) OF Boolean;
   PRAGMA Pack (Byte);
   --
   TYPE Color IS RECORD
      R,G,B:Integer;
   END RECORD;
   --
   TYPE Matriu IS ARRAY(0..1000,0..1000) OF Color;
   --
   TYPE Mapa_Bit IS RECORD
      X,Y:Integer;
      M:Matriu;
   END RECORD;
   --
   --declaracio d'excepcions:
   --
   Mapa_Bits_Incorrecte,Mapa_De_Bits_Impossible_Lectura:EXCEPTION;
   --
   --declaracio de procediments:
   --
   PROCEDURE Lectura_Mapa_Bits(S:IN String;M:OUT Mapa_Bit);
END Mapa_Bits;



Ahora tengo otra duda haver si alguien me podria decir como capturar imagenes la webcam de mi ordenador (en formato bmp si puede ser)
by YZU xD
Yzumi
Experto
Experto
 
Mensajes: 68
Registrado: Mar Feb 26, 2008 15:30


Volver a Librerías e interfaces gráficas

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron