Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

img_pal.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= img_pal.cc                                            Noviembre de 1999 =
00003 //=-------------------------------------------------------------------------=
00004 //= Clases de representacion y procesamiento basico de imagenes digitales   =
00005 //=-------------------------------------------------------------------------=
00006 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00007 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00008 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00009 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00010 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00011 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00012 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00013 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00014 //=-------------------------------------------------------------------------=
00015 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00016 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00017 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00018 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00019 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00020 //===========================================================================
00021 
00022 #include "toolkits/media/jed_img.h"
00023 #include "toolkits/media/_img_sgi.h"
00024 
00025 #ifdef VEL_ROSITA
00026     #include "toolkits/media/img_pal.h"
00027 #endif
00028 
00029 #include <stdio.h>
00030 #include <string.h>
00031 
00032 //===========================================================================
00033 //= Clase IMAGEN_PAL                                                        =
00034 //===========================================================================
00035 
00036 IMAGEN_PAL::IMAGEN_PAL()
00037 {
00038     //printf("IMAGEN_PAL::IMAGEN_PAL\n"); fflush(stdout);
00039     x_tam = y_tam = 0;  Data = NULL; 
00040     modo_luminancia = FALSE;
00041 
00042   #ifdef GL_COMPLETO
00043     con_lista = FALSE;
00044   #endif
00045 #ifdef NNN
00046   #ifdef MESA_ENABLED
00047     _contexto_osmesa = 0;
00048   #endif
00049 #endif // NNN
00050 }
00051 
00052 IMAGEN_PAL::~IMAGEN_PAL()
00053 {
00054     //printf("IMAGEN_PAL::~IMAGEN_PAL\t");  fflush(stdout);
00055 
00056 #ifdef NONONO
00057   #ifdef GL_COMPLETO1
00058     if ( !con_lista ) {
00059         glDeleteTextures(lista_gl);
00060     }
00061   #endif
00062 #endif
00063 
00064     if ( Data ) elim();
00065 }
00066 
00067 BOOLEAN
00068 IMAGEN_PAL::init(int width, int height)
00075 {
00076     //printf("IMAGEN_PAL::init(%d, %d);\n", width, height);  fflush(stdout);
00077 
00078     if ( x_tam == width && y_tam == height ) return TRUE;
00079     elim();
00080     Data = new PIXEL_PAL[height * width];
00081     if ( !Data ) return FALSE;
00082     x_tam = width;
00083     y_tam = height;
00084     return TRUE;
00085 }
00086 
00087 void
00088 IMAGEN_PAL::elim(void)
00089 {
00090     //printf("IMAGEN_PAL::elim();\n"); fflush(stdout);
00091     if ( Data ) {
00092         delete Data;
00093         Data = NULL;
00094         x_tam = y_tam = 0;
00095     }
00096 }
00097 
00098 #ifdef GL_ENABLED
00099 void
00100 IMAGEN_PAL::pintar_gl(void)
00101 {
00102     //printf("IMAGEN_PAL::pintar_gl\n");  fflush(stdout);
00103     if ( !Data ) {
00104         fprintf(stderr,
00105             "<IMAGEN_PAL> ERROR: Intentando pintar una imagen nula.\n");
00106         fflush(stderr);
00107         return;
00108     }
00109 
00110     // OJO: Debe tenerse activada una PALETA!
00111     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00112     glRasterPos2f(-1, -1);
00113     glDrawPixels(x_tam, y_tam, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, Data);
00114 }
00115 
00116 void
00117 IMAGEN_PAL::activar_gl(void)
00118 // OJO: Debe tenerse activada una PALETA.
00119 // OJO: Se ha presentado que la implementacion de OpenGL de este
00120 //      metodo no se comporta igual en todas partes... por ahora
00121 //      de las alternativas se encuentra activa la mas portable
00122 //      (e ineficiente)
00123 {
00124     //printf("IMAGEN_PAL::activar_gl\n");  fflush(stdout);
00125 
00126     //-----------------------------------------------------------------------
00127     if ( !Data ) {
00128         fprintf(stderr,
00129             "<IMAGEN_PAL> ERROR: Intentando activar una imagen nula.\n");
00130         fflush(stderr);
00131         return;
00132     }
00133 
00134     //-----------------------------------------------------------------------
00135 #ifdef NONONO
00136   #ifdef GL_COMPLETO
00137     if ( !con_lista && acelerable(x_tam, y_tam) ) {
00138         //printf("<IMAGEN_PAL>: Registrando una textura... ");
00139         //fflush(stdout);
00140         glGenTextures(1, &lista_gl);
00141         ERROR_GL("glGenTextures");
00142 
00143         glBindTexture(GL_TEXTURE_2D, lista_gl);
00144         ERROR_GL("glBindTexture");
00145 
00146         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
00147             x_tam, y_tam, 0, GL_COLOR_INDEX, 
00148             GL_UNSIGNED_BYTE, Data);
00149         ERROR_GL("glTexImage2D");
00150 
00151         //printf("Ok!\n");
00152         //fflush(stdout);
00153         con_lista = TRUE;
00154       }
00155       else if ( acelerable(x_tam, y_tam) ) {
00156         //printf("<IMAGEN_PAL>: Reutilizo una textura precompilada!\n");
00157         //fflush(stdout);
00158         glBindTexture(GL_TEXTURE_2D, lista_gl);
00159       }
00160       else {
00161         glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_COLOR_INDEX, 
00162             GL_UNSIGNED_BYTE, Data);
00163     }
00164   #endif
00165 #endif
00166 
00167 #ifdef NONONO
00168 //  #ifndef GL_COMPLETO
00169     glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_COLOR_INDEX, 
00170         GL_UNSIGNED_BYTE, (void *)Data);
00171 //  #endif
00172 #endif
00173 
00174     //-----------------------------------------------------------------------
00175 #ifdef NONONO
00176 #ifdef GL_COMPLETO
00177     if ( !con_lista ) {
00178         glGenTextures(1, &lista_gl);
00179         glBindTexture(GL_TEXTURE_2D, lista_gl);
00180         if ( modo_luminancia ) {
00181             gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE, x_tam, y_tam,
00182                           GL_LUMINANCE,  GL_UNSIGNED_BYTE, (void *)Data);
00183           }
00184           else {
00185             gluBuild2DMipmaps(GL_TEXTURE_2D, GL_COLOR_INDEX, x_tam, y_tam,
00186                           GL_COLOR_INDEX,  GL_UNSIGNED_BYTE, (void *)Data);
00187         }
00188         con_lista = TRUE;
00189     }
00190     glBindTexture(GL_TEXTURE_2D, lista_gl);
00191 #endif
00192 #endif
00193 //#ifndef GL_COMPLETO
00194     if ( modo_luminancia ) {
00195         glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_LUMINANCE, 
00196             GL_UNSIGNED_BYTE, (void *)Data);
00197       }
00198       else {
00199         glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_COLOR_INDEX, 
00200             GL_UNSIGNED_BYTE, (void *)Data);
00201     }
00202 //#endif
00203 }
00204 
00205 #endif // GL_COMPLETO
00206 
00207 void
00208 IMAGEN_PAL::set_modo_luminancia(BOOLEAN m)
00209 {
00210     modo_luminancia = m;
00211 }
00212 
00213 //===========================================================================
00214 //= Metodos para importar datos DOOM                                        =
00215 //===========================================================================
00216 
00217 BOOLEAN
00218 IMAGEN_PAL::importar_wadsprite(FILE *fd)
00230 {
00231     if ( !fd ) {
00232         fprintf(stderr,
00233             "<IMAGEN_PAL> - ERROR: No se puede abrir el archivo WAD.\n");
00234         fflush(stderr);
00235         return FALSE;
00236     }
00237     unsigned long global_offset = ftell(fd);
00238 
00239     //- Lea el encabezado y cree la imagen vacia ----------------------------
00240     WORD xtam = 0, ytam = 0, left_offset = 0, top_offset = 0;
00241 
00242     lea_WORD_BE(&xtam, fd);
00243     lea_WORD_BE(&ytam, fd);
00244     lea_WORD_BE(&left_offset, fd);
00245     lea_WORD_BE(&top_offset, fd);
00246 
00247     if ( xtam < 1 || xtam > 2024 || ytam < 1 || ytam > 2024 ) {
00248         fprintf(stderr,
00249             "<IMAGEN_PAL> WAD-Sprite con tamanno %d X %d no aceptado.\n",
00250             xtam, ytam);
00251         fflush(stderr);
00252         return FALSE;
00253     }
00254 
00255     if ( !init(xtam, ytam) ) return FALSE;
00256 
00257     //- Cargue los pixels en la imagen columna por columna ------------------
00258     int x, y, l;
00259     unsigned long local_offset;
00260     BYTE y_start, y_size;
00261     BYTE *buffer_columna;
00262 
00263     buffer_columna = new BYTE[ytam + 2];
00264     if ( !buffer_columna ) {
00265         fprintf(stderr, 
00266           "<IMAGEN_PAL> - ERROR: "
00267           "No hay memoria para un buffer temporal de %d bytes.", ytam);
00268         fflush(stderr);
00269         return FALSE;
00270     }
00271 
00272     for ( x = 0; x < x_tam; x++ ) {
00273         // Localice la x-esima columna
00274         fseek(fd, global_offset + 8 + x*4, SEEK_SET);
00275         lea_DWORD_BE(&local_offset, fd);
00276         fseek(fd, global_offset + local_offset, SEEK_SET);
00277 
00278         // Cargue la x-esima columna
00279         lea_BYTE(&y_start, fd);
00280         for ( y = 0; y_start != 0xFF; ) {
00281             lea_BYTE(&y_size, fd);
00282             fread(buffer_columna, sizeof(BYTE), y_size + 2, fd);
00283             for ( ; y < y_start && y < y_tam; y++ ) {
00284                 // Esto coloca en "negro" los pixels transparentes 
00285                 // (OJO: mejorar!)
00286                 putcolorindex(x, y_tam-y-1, 0);
00287             }
00288             for ( l = 1; l <= y_size; y++, l++ ) {
00289                 putcolorindex(x, y_tam-y-1, buffer_columna[l]);
00290             }
00291             lea_BYTE(&y_start, fd);
00292         }
00293         for ( ; y < y_tam; y++ ) {
00294             // Esto coloca en "negro" los pixels transparentes  (OJO: mejorar!)
00295             putcolorindex(x, y_tam-y-1, 0);
00296         }
00297     }
00298 
00299     delete buffer_columna;
00300     return TRUE;
00301 }
00302 
00303 BOOLEAN
00304 IMAGEN_PAL::importar_wadflat(FILE *fd, WORD xtam, WORD ytam)
00316 {
00317     if ( !fd ) {
00318         fprintf(stderr, "ERROR: No se puede abrir el archivo WAD.");
00319         fflush(stderr);
00320         return FALSE;
00321     }
00322     if ( !init(xtam, ytam) ) return FALSE;
00323 
00324     fread(Data, sizeof(BYTE), xtam*ytam, fd);
00325 
00326     return TRUE;
00327 }
00328 
00329 BOOLEAN
00330 IMAGEN_PAL::importar_sgibw(FILE *fd)
00331 {
00332     //- Chequeo de sanidad --------------------------------------------------
00333     if ( !fd ) {
00334         fprintf(stderr, "<IMAGEN_RGB> Error: Archivo invalido!\n");
00335         return FALSE;
00336     }
00337 
00338     //-----------------------------------------------------------------------
00339     LECTOR_SGIRGB *Constructor = NULL;
00340 
00341     Constructor = new LECTOR_SGIRGB;
00342     if ( !Constructor ) {
00343         fprintf(stderr, "<IMAGEN_RGB> ERROR: Memoria insuficiente\n");
00344         fflush(stderr);
00345         return FALSE;
00346     }
00347 
00348     Constructor->init(fd);
00349 
00350     // Round up so rows are long-word aligned  
00351     if ( Constructor->sizeZ != 1 ) {
00352         fprintf(stderr,
00353             "<IMAGEN_RGB> - ERROR: Solo se soporta el formato BW.\n");
00354         fflush(stderr);
00355         return FALSE;
00356     }
00357 
00358     init(Constructor->x_tam, Constructor->y_tam);
00359     Constructor->leer((BYTE *)Data);
00360     Constructor->elim();
00361 
00362     delete Constructor;
00363 
00364     return TRUE;
00365 }
00366 
00367 void
00368 IMAGEN_PAL::pegar_subimagen(IMAGEN_PAL *sprite, int offset_x, int offset_y)
00374 {
00375     int x, y, i, j;
00376 
00377     for ( x = offset_x, i = 0; x < x_tam && i < sprite->x_tam; x++, i++ ) {
00378         for ( y = offset_y, j = 0; y < y_tam && j < sprite->y_tam; y++, j++ ) {
00379             if ( offset_x >= 0 && offset_y >= 0 )
00380                 putcolorindex(x, y, sprite->getcolorindex(i, j));
00381         }
00382     }
00383 }
00384 
00385 void
00386 IMAGEN_PAL::exportar_ppm(FILE *fd, PALETA *Pal)
00387 {
00388     char cad[180];
00389     int i, j;
00390 
00391     sprintf(cad, "P6\n"
00392                  "# PPM CREATED BY: AQUYNZA http://www.aquynza.org\n");
00393     fwrite(cad, sizeof(char), strlen(cad), fd);
00394     sprintf(cad, "%d %d\n", x_tam, y_tam);
00395     fwrite(cad, sizeof(char), strlen(cad), fd);
00396     sprintf(cad, "255\n");
00397     fwrite(cad, sizeof(char), 4, fd);
00398 
00399 
00400     //- Manejo de imagenes nativas de 24 bits por pixel -----------------------
00401     //PIXEL_RGB *fila, pixel;
00402     //PIXEL_RGBA *f2, p2;
00403 
00404     fprintf(stderr,
00405         "<IMAGEN_PAL> - Warning: Grabar PPM no esta implementado en modo nativo para \n"
00406         "soportar un formato indexado, exportando como PPM de 24 bits por pixel!\n");
00407     fflush(stderr);
00408 
00409     //- Manejo de imagenes nativas de 8 bits por pixel -----------------------
00410     //- Se usa la paleta actual para exportarlas a 24 bits por pixel ---------
00411     PIXEL_PAL index;
00412     PIXEL_RGB pixel;
00413     for ( i = 0; i < y_tam ; i++ ) {
00414         for ( j = 0; j < x_tam ; j++ ) {
00415             index = ((PIXEL_PAL *)Data)[i * x_tam + j];
00416             //pixel = LA_paleta.pal2rgb(index.index);
00417             // OJO: Esto no va a funcionar porque le falta saber la paleta
00418             // (Pista: intentar agarrarla de la de OpenGL directamente).
00419             pixel = Pal->pal2rgb(index);
00420             fwrite(&pixel, sizeof(PIXEL_RGB), 1, fd);
00421         }
00422     }
00423 }
00424 
00425 #ifdef NNN
00426 
00427 #ifdef GL_ENABLED
00428 #define ERROR_GL(op)                                                    \
00429         switch (glGetError()) {                                         \
00430           case GL_INVALID_ENUM:                                         \
00431             printf("[<<GL_INVALID_ENUM en %s!>>]\n", (op));             \
00432             fflush(stdout);  return;                                    \
00433           case GL_INVALID_VALUE:                                        \
00434             printf("[<<GL_INVALID_VALUE en %s!>>\n]", (op));            \
00435             fflush(stdout);  return;                                    \
00436           case GL_INVALID_OPERATION:                                    \
00437             printf("[<<GL_INVALID_OPERATION en %s!>>]\n", (op));        \
00438             fflush(stdout);  return;                                    \
00439           case GL_STACK_OVERFLOW:                                       \
00440             printf("[<<GL_STACK_OVERFLOW en %s!>>]\n", (op));           \
00441             fflush(stdout);  return;                                    \
00442           case GL_STACK_UNDERFLOW:                                      \
00443             printf("[<<GL_STACK_UNDERFLOW en %s!>>]\n", (op));          \
00444             fflush(stdout);  return;                                    \
00445           case GL_OUT_OF_MEMORY:                                        \
00446             printf("[<<GL_OUT_OF_MEMORY en %s!>>]\n", (op));            \
00447             fflush(stdout);  return;                                    \
00448           default: break;                                               \
00449         }
00450 #endif // GL_ENABLED
00451 
00452 #ifdef NONONO
00453 static BOOLEAN
00454 acelerable(int x, int y)
00459 {
00460     int c, i;
00461 
00462     for ( i = 0, c = 0; i < 32; i++ ) {
00463         if ( x & (1<<i) ) c++;
00464     }
00465     if ( c > 1 ) return FALSE;
00466 
00467     for ( i = 0, c = 0; i < 32; i++ ) {
00468         if ( y & (1<<i) ) c++;
00469     }
00470     if ( c > 1 ) return FALSE;
00471 
00472     return TRUE;
00473 }
00474 
00475 #ifndef GL_COMPLETO
00476     glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_COLOR_INDEX, 
00477         GL_UNSIGNED_BYTE, Data);
00478 #endif
00479 }
00480 #endif // NONONO
00481 
00482 
00483 #ifdef GL_ENABLED
00484 void
00485 IMAGEN_PAL::activar_como_contexto_gl(void)
00486 {
00487 #ifdef MESA_ENABLED
00488     fprintf(stderr,
00489         "<IMAGEN_PAL> - ERROR: GL no implementado en este tipo de imagen!\n");
00490     fflush(stderr);
00491     exit(-10);
00492 /*
00493    _contexto_osmesa = OSMesaCreateContext( GL_RGBA, NULL );
00494    OSMesaMakeCurrent(_contexto_osmesa, Data, GL_UNSIGNED_BYTE, x_tam, y_tam);
00495 */
00496 #endif
00497 #ifndef MESA_ENABLED
00498     fprintf(stderr, "<IMAGEN_PAL> - ERROR: El contexto GL sobre una imagen\n"
00499                     "solo ha sido implementado para MESA!\n");
00500     fflush(stderr);
00501     exit(-4);
00502 #endif
00503 }
00504 
00505 void
00506 IMAGEN_PAL::desactivar_como_contexto_gl(void)
00507 {
00508 #ifdef MESA_ENABLED
00509    if ( _contexto_osmesa ) OSMesaDestroyContext(_contexto_osmesa);
00510 #endif
00511 }
00512 #endif // GL_ENABLED
00513 
00514 IMAGEN_PAL *
00515 IMAGEN_PAL::exportar_a_grises(PALETA *Pal)
00532 {
00533     IMAGEN_PAL *Nueva = NULL;
00534     int x, y;
00535     BYTE r, g, b, index;
00536 
00537     Nueva = new IMAGEN_PAL();
00538 
00539     if ( !Nueva->init(x_tam, y_tam) ) {
00540         fprintf(stderr, "Warning[JED_IMG]: No hay memoria para crear una "
00541             "imagen en tonos de gris de %d x %d pixels!\n", x_tam, y_tam);
00542         fflush(stderr);
00543         return NULL;
00544     }
00545 
00546     for ( x = 0; x < x_tam; x++ ) {
00547         for ( y = 0; y < y_tam; y++ ) {
00548             index = getcolorindex(x, y);
00549             r = Pal->tabla[index].r;
00550             g = Pal->tabla[index].g;
00551             b = Pal->tabla[index].b;
00552             Nueva->putcolorindex(x, y, nivel_de_gris(r, g, b));
00553         }
00554     }
00555     return Nueva;
00556 }
00557 
00558 void
00559 IMAGEN_PAL::umbralizar(BYTE umbral)
00560 /*
00561 PRE: El umbral esta entre 0 y 255, en donde 0 es negro, 255 es blanco y
00562 los valores intermedios son grises uniformemente distribuidos (por luminancia).
00563 */
00564 {
00565     int x, y;
00566 
00567     for ( x = 0; x < x_tam; x++ ) {
00568         for ( y = 0; y < y_tam; y++ ) {
00569             if ( getcolorindex(x, y) > umbral ) {
00570                 putcolorindex(x, y, 255);
00571               }
00572               else {
00573                 putcolorindex(x, y, 0);
00574             }
00575         }
00576     }
00577 }
00578 
00579 void
00580 IMAGEN_PAL::umbralizar_adaptativo(void)
00592 {
00593     double pct = 15.0;           // Make smaller to darken the image 
00594     double factor_divisor = 8.0; // Fraccion de una fila para el promediaje
00595     int x, y, inc;
00596     double promedio, s, sum;
00597     long N, i;
00598 
00599     N = (long)x_tam * (long)y_tam;
00600 
00601     s = (int)(double)(x_tam/factor_divisor);
00602     sum = 127*s;
00603 
00604     for ( i = 0, x = 0, y = 0, inc = 1; i < N-1; i++, x += inc ) {
00605         //- Chequeo de limites para el recorrido en zig-zag -
00606         if ( x >= x_tam ) {
00607             x = x_tam-1; y++; inc = -1;
00608           } 
00609           else if ( x < 0 ) {
00610             x = 0; y++; inc = 1;
00611         }
00612 
00613         //- Estime el promedio de los ultimos x_tam/factor_divisor pixels. -
00614         sum -= sum/s - getcolorindex(x, y); promedio = sum/s;
00615 
00616         //- Binarizacion de un pixel -
00617         if ( getcolorindex(x, y) < promedio * (100-pct) / 100.0 ) {
00618             putcolorindex(x, y, 0); 
00619           }
00620           else {
00621             putcolorindex(x, y, 255); 
00622         }
00623     }
00624 
00625 }
00626 
00627 IMAGEN *
00628 IMAGEN_PAL::copie(void)
00629 {
00630     IMAGEN_PAL *Nueva;
00631     int x, y;
00632 
00633     Nueva = new IMAGEN_PAL();
00634     if ( !Nueva ) {
00635         fprintf(stderr,"ERROR: No hay memoria para crear una nueva imagen!\n");
00636         fflush(stderr);
00637         return NULL;
00638     }
00639 
00640     if ( !Nueva->init(x_tam, y_tam)  ) {
00641         fprintf(stderr,"ERROR: No hay memoria para crear una nueva imagen!\n");
00642         fflush(stderr);
00643         delete Nueva;
00644         return NULL;
00645     }
00646 
00647     for ( x = 0; x < x_tam; x++ ) {
00648         for ( y = 0; y < y_tam; y++ ) {
00649             Nueva->putcolorindex(x, y, getcolorindex(x, y));
00650         }
00651     }
00652 
00653     return Nueva;
00654 }
00655 
00656 #endif // NNN
00657 
00658 //===========================================================================
00659 //= EOF                                                                     =
00660 //===========================================================================
00661 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.