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_rgb.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= img_rgb.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_rgb.h"
00027 #endif
00028 
00029 #include <stdio.h>
00030 #include <string.h>
00031 
00032 #ifdef GL_VERSION_1_1  // OJO: Toca revisar si esta vaina funciona bien!
00033     #define GL_COMPLETO // Si se quita, parece que el otro (en jed_defs)
00034 #endif                  // no se activa bien
00035 
00036 #ifdef PNG_ENABLED
00037   #include <png.h>
00038   #ifndef png_jmpbuf
00039     #define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
00040   #endif
00041 #endif
00042 
00043 //===========================================================================
00044 //= Funciones utilitarias                                                   =
00045 //===========================================================================
00046 
00047 #ifdef X_ENABLED
00048 
00049 static int
00050 highbit(unsigned long ul)
00055 {
00056     int i;
00057     for (i=31; ((ul&0x80000000) == 0) && i>=0;  i--, ul<<=1);
00058     return i;
00059 }
00060 
00061 #endif
00062 
00063 //===========================================================================
00064 //= Clase IMAGEN_RGB                                                        =
00065 //===========================================================================
00066 
00067 IMAGEN_RGB::IMAGEN_RGB()
00068 {
00069     //printf("IMAGEN_RGB::IMAGEN_RGB\n"); fflush(stdout);
00070     x_tam = y_tam = 0;  Data = NULL;
00071     _anx_x = 0;
00072     _anx_y = 0;
00073     _anx_r = 0;
00074     _anx_g = 0;
00075     _anx_b = 0;
00076     _anx_c = 0;
00077 
00078   #ifdef GL_COMPLETO
00079     con_lista = FALSE;
00080   #endif
00081 /*
00082   #ifdef MESA_ENABLED
00083     _contexto_osmesa = 0;
00084   #endif
00085 */
00086 }
00087 
00088 IMAGEN_RGB::~IMAGEN_RGB()
00089 {
00090     //printf("IMAGEN_RGB::~IMAGEN_RGB\t");  fflush(stdout);
00091     if ( Data ) elim();
00092 }
00093 
00094 BOOLEAN
00095 IMAGEN_RGB::init(int width, int height)
00102 {
00103     //printf("IMAGEN_RGB::init(%d, %d);\n", width, height);  fflush(stdout);
00104 
00105     if ( x_tam == width && y_tam == height ) return TRUE;
00106     elim();
00107 // OJO: En PALMOS todavia hay problemas con la asignacion de memoria dinamica
00108 #if PLATAFORMA != PALM_PALMOS_CODEWARRIOR
00109     Data = new PIXEL_RGB[height * width];
00110 #endif
00111 #if PLATAFORMA == PALM_PALMOS_CODEWARRIOR
00112     //Data = (PIXEL_RGB *)malloc(height * width * sizeof(PIXEL_RGB));
00113     Data = (PIXEL_RGB **)malloc(height * sizeof(PIXEL_RGB*));
00114 #endif
00115     if ( !Data ) return FALSE;
00116 
00117 #if PLATAFORMA == PALM_PALMOS_CODEWARRIOR
00118     int i, j;
00119 
00120     for ( i = 0; i < height; i++ ) {
00121         Data[i] = (PIXEL_RGB *)malloc(width * sizeof(PIXEL_RGB));
00122 
00123         if ( !Data[i] ) {
00124             for ( j = 0; j < i; j++ ) {
00125                 free(Data[j]);
00126             }
00127             free(Data);
00128             Data = NULL;
00129             return FALSE;
00130         }
00131     }
00132 #endif
00133 
00134     x_tam = width;
00135     y_tam = height;
00136     _anx_x = 0;
00137     _anx_y = 0;
00138     _anx_r = 0;
00139     _anx_g = 0;
00140     _anx_b = 0;
00141     _anx_c = 0;
00142     return TRUE;
00143 }
00144 
00145 void
00146 IMAGEN_RGB::elim(void)
00147 {
00148     //printf("IMAGEN_RGB::elim();\n"); fflush(stdout);
00149     if ( Data ) {
00150 // OJO: En PALMOS todavia hay problemas con la asignacion de memoria dinamica
00151 #if PLATAFORMA != PALM_PALMOS_CODEWARRIOR
00152         delete Data;
00153 #endif
00154 #if PLATAFORMA == PALM_PALMOS_CODEWARRIOR
00155         int i;
00156 
00157         for ( i = 0; i < y_tam; i++ ) {
00158             free(Data[i]);
00159         }
00160         free(Data);
00161 #endif
00162         Data = NULL;
00163         x_tam = y_tam = 0;
00164     }
00165 }
00166 
00167 BOOLEAN
00168 IMAGEN_RGB::combinar_stereo(IMAGEN_RGB *Izq, IMAGEN_RGB *Der, int modo)
00175 {
00176     BYTE r, g, b;
00177     int x, y, xt, yt;
00178     int s1, s2;
00179 
00180     xt = Izq->xtam();
00181     yt = Izq->ytam();
00182 
00183     if ( xt != Der->xtam() || yt != Izq->ytam() ) {
00184         fprintf(stderr, "<IMAGEN_RGB> - ERROR: Par stereo de tamanno "
00185                 "inconsistente.\n");
00186         fflush(stderr);
00187         return FALSE;
00188     }
00189 
00190     if ( modo == STEREO_INTERLACED ) {
00191         if ( !init(xt, yt) ) {
00192             return FALSE;
00193         }
00194         for ( x = 0; x < xt; x++ ) {
00195             for ( y = 0; y < yt; y++ ) {
00196                 if ( y % 2 ) {
00197                     Izq->getpixel(x, y, r, g, b);
00198                   }
00199                   else {
00200                     Der->getpixel(x, y, r, g, b);
00201                 }
00202                 putpixel(x, y, r, g, b);
00203             }
00204         }
00205       }
00206       else {
00207         // Se asume por defecto  (modo_stereo == STEREO_BLUE_RED)  
00208         if ( !init(xt, yt) ) {
00209             return FALSE;
00210         }
00211         for ( x = 0; x < xt; x++ ) {
00212             for ( y = 0; y < yt; y++ ) {
00213                 Izq->getpixel(x, y, r, g, b);
00214                 s1 = (BYTE)((((int)r) + ((int)g) + ((int)b)) / 3);
00215                 s1 = (BYTE)((float)s1 * 0.7);
00216                 Der->getpixel(x, y, r, g, b);
00217                 s2 = (BYTE)((((int)r) + ((int)g) + ((int)b)) / 3);
00218                 putpixel(x, y, s1, 0, s2);
00219             }
00220         }
00221       }
00222     ;
00223     return TRUE;
00224 }
00225 
00226 #ifdef GL_ENABLED
00227 void
00228 IMAGEN_RGB::pintar_gl(void)
00229 {
00230     //- Verificacion de sanidad ---------------------------------------------
00231     //printf("IMAGEN_RGB::pintar_gl\n");  fflush(stdout);
00232     if ( !Data ) {
00233         fprintf(stderr,
00234             "<IMAGEN_RGB> ERROR: Intentando pintar una imagen nula.\n");
00235         fflush(stderr);
00236         return;
00237     }
00238 
00239     //- Generacion de primitivas OpenGL -------------------------------------
00240     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00241     glRasterPos2f(-1, -1);
00242     glDrawPixels(x_tam, y_tam, GL_RGB, GL_UNSIGNED_BYTE, (void*)Data);
00243 }
00244 
00245 void
00246 IMAGEN_RGB::activar_gl(void)
00273 {
00274     //- Verificacion de sanidad ---------------------------------------------
00275     //printf("IMAGEN_RGB::activar_gl\n");  fflush(stdout);
00276     if ( !Data ) {
00277         fprintf(stderr,
00278             "<IMAGEN_RGB> ERROR: Intentando activar una imagen nula.\n");
00279         fflush(stderr);
00280         return;
00281     }
00282     //- Generacion de primitivas OpenGL -------------------------------------
00283      if ( !(x_tam % 4) )
00284         glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00285     else if ( !(x_tam % 2) )
00286         glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
00287     else
00288         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00289 
00290     //glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_RGB, 
00291     //    GL_UNSIGNED_BYTE, (void*)Data);
00292 
00293   #ifndef GL_COMPLETO
00294     //glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_RGB, 
00295     //    GL_UNSIGNED_BYTE, (void*)Data);
00296     gluBuild2DMipmaps(GL_TEXTURE_2D, 3, x_tam, y_tam, GL_RGB, 
00297                       GL_UNSIGNED_BYTE, (void*)Data);
00298   #endif
00299   #ifdef GL_COMPLETO
00300 //    glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_RGB, 
00301 //        GL_UNSIGNED_BYTE, (void*)Data);
00302     if ( !con_lista ) {
00303         glGenTextures(1, &lista_gl);
00304         glBindTexture(GL_TEXTURE_2D, lista_gl);
00305         gluBuild2DMipmaps(GL_TEXTURE_2D, 3, x_tam, y_tam, GL_RGB, 
00306                           GL_UNSIGNED_BYTE, (void*)Data);
00307         con_lista = TRUE;
00308     }
00309     glBindTexture(GL_TEXTURE_2D, lista_gl);
00310   #endif
00311 }
00312 
00313 void
00314 IMAGEN_RGB::activar_como_contexto_gl(void)
00315 {
00316 #ifdef MESA_ENABLED
00317     _contexto_osmesa = OSMesaCreateContext(GL_RGB, NULL);
00318     OSMesaMakeCurrent(_contexto_osmesa, (void*)Data, GL_UNSIGNED_BYTE, x_tam, y_tam);
00319 #endif
00320 #ifndef MESA_ENABLED
00321     fprintf(stderr, "<IMAGEN_RGB> - ERROR: El contexto GL sobre una imagen\n"
00322                     "solo ha sido implementado para MESA!\n");
00323     fflush(stderr);
00324     exit(-4);
00325 #endif
00326 }
00327 
00328 void
00329 IMAGEN_RGB::desactivar_como_contexto_gl(void)
00330 {
00331 #ifdef MESA_ENABLED
00332     if ( _contexto_osmesa ) OSMesaDestroyContext(_contexto_osmesa);
00333 #endif
00334 }
00335 
00336 BOOLEAN
00337 IMAGEN_RGB::importar_gl(int x, int y, int xtam, int ytam)
00341 {
00342     glPushMatrix();
00343 
00344     if ( xtam <= 0 || xtam > 2024 || ytam <=0 || ytam > 2024 ) {
00345         fprintf(stderr, "<IMAGEN_RGB> Tamanno %d X %d no aceptado.\n",
00346                 xtam, ytam);
00347         fflush(stderr);
00348         return FALSE;
00349     }
00350 
00351     if ( !init(xtam, ytam) ) {
00352         return FALSE;
00353     }
00354     //printf("Creo imagen de %d x %d...\n", x_tam, y_tam);
00355     //fflush(stdout);
00356 
00357     // Pre: tipo == IMAGEN_RGB24BITS
00358 
00359     // OJO: Esta configuracion previa es realmente necesaria?
00360 
00361     glPixelStorei(GL_PACK_ALIGNMENT, 1);
00362     glMatrixMode(GL_PROJECTION);
00363     glLoadIdentity();
00364     glOrtho(-1, 1, -1, 1, 0.0, 0.1);
00365     glMatrixMode(GL_MODELVIEW);
00366     glLoadIdentity();
00367 
00368     glRasterPos2f(-1, -1);
00369     glReadPixels(x, y, x_tam, y_tam, GL_RGB, GL_UNSIGNED_BYTE, Data);
00370 
00371     glPopMatrix();
00372     return TRUE;
00373 }
00374 
00375 #endif // GL_ENABLED
00376 
00377 
00378 
00379 #ifdef NNN
00380 
00381 IMAGEN_PAL *
00382 IMAGEN_RGB::exportar_a_grises(PALETA * /*Pal*/)
00399 {
00400     IMAGEN_PAL *Nueva = NULL;
00401     int x, y;
00402     BYTE r, g, b;
00403 
00404     Nueva = new IMAGEN_PAL();
00405 
00406     if ( !Nueva->init(x_tam, y_tam) ) {
00407         fprintf(stderr, "Warning[JED_IMG]: No hay memoria para crear una "
00408             "imagen en tonos de gris de %d x %d pixels!\n", x_tam, y_tam);
00409         fflush(stderr);
00410         return NULL;
00411     }
00412 
00413     for ( x = 0; x < x_tam; x++ ) {
00414         for ( y = 0; y < y_tam; y++ ) {
00415             getpixel(x, y, r, g, b);
00416             // OJO: Notese que umbral = f(r, g, b) y deberia poder 
00417             // especificarse f de una manera menos arbibraria, siempre y
00418             // cuando se garantice que umbral da de 0 a 255.
00419             Nueva->putcolorindex(x, y, nivel_de_gris(r, g, b));
00420         }
00421     }
00422 
00423     //Pal = NULL;  // #pragma argsused
00424 
00425     return Nueva;
00426 }
00427 
00428 IMAGEN *
00429 IMAGEN_RGB::copie(void)
00430 {
00431     IMAGEN_RGB *Nueva;
00432     int x, y;
00433     BYTE r, g, b;
00434 
00435     Nueva = new IMAGEN_RGB();
00436     if ( !Nueva ) {
00437         fprintf(stderr,"ERROR: No hay memoria para crear una nueva imagen!\n");
00438         fflush(stderr);
00439         return NULL;
00440     }
00441 
00442     if ( !Nueva->init(x_tam, y_tam)  ) {
00443         fprintf(stderr,"ERROR: No hay memoria para crear una nueva imagen!\n");
00444         fflush(stderr);
00445         delete Nueva;
00446         return NULL;
00447     }
00448 
00449     for ( x = 0; x < x_tam; x++ ) {
00450         for ( y = 0; y < y_tam; y++ ) {
00451             getpixel(x, y, r, g, b);
00452             Nueva->putpixel(x, y, r, g, b);
00453         }
00454     }
00455 
00456     return Nueva;
00457 }
00458 
00459 #endif // NNN
00460 
00461 //= METODOS DE PERSISTENCIA (IMPORTACION DE DATOS) ==========================
00462 
00463 BOOLEAN
00464 IMAGEN_RGB::importar_ppm(FILE *fd)
00471 {
00472 #ifndef FILESYSTEM_ENABLED
00473     return FALSE;
00474 #endif
00475 #ifdef FILESYSTEM_ENABLED
00476     int xsize = 0, ysize = 0;
00477     int i, j;
00478     char buffer[MAX_LINE + 1];
00479     char *ptr = NULL;
00480     PIXEL_RGB pixel;
00481     int tipo = 6;
00482 
00483     //- Verificacion de que el archivo esta bien ----------------------------
00484     if ( !fd ) {
00485         fprintf(stderr, "<IMAGEN_RGB> ERROR: No se puede abrir el archivo.\n");
00486         fflush(stderr);
00487         return FALSE;
00488     }
00489 
00490     //- Lea y procese el encabezado ppm ------------------------------------
00491     for ( i = 0; !feof(fd); i++ ) {
00492         if ( i >= MAX_LINE ) i = 0;
00493         fread(&buffer[i], sizeof(BYTE), 1, fd);
00494         buffer[i + 1] = '\0';
00495 
00496         if ( buffer[i] == '\n' && buffer[0] == 'P' && buffer[1] == '5' ) {
00497             tipo = 5;
00498         }
00499 
00500         if ( buffer[i] == '\n' && strcmp(buffer, "255\n") == 0 ) {
00501             break;
00502           }
00503           else if ( buffer[i] == '\n' ) {
00504             ptr = strtok(buffer, " \n");
00505             if ( ptr ) {
00506                 xsize = atoi(ptr);
00507                 ptr = strtok(NULL, " \n");
00508                 if ( ptr ) {
00509                     ysize = atoi(ptr);
00510                 }
00511             }
00512             i = -1;
00513         }          
00514     }
00515 
00516     //- Verifique que el tamanno de la imagen sea coherente -----------------
00517     if ( xsize <= 0 || xsize > 2024 || ysize <=0 || ysize > 2024 ) {
00518         fprintf(stderr,
00519             "<IMAGEN_RGB> Imagen con tamanno %d X %d no aceptada.\n",
00520             xsize, ysize);
00521         fflush(stderr);
00522         return FALSE;
00523     }
00524 
00525     //- Cree la imagen y lea sus pixels del archivo ppm ---------------------
00526     PIXEL_RGB *fila;
00527 
00528     if ( !init(xsize, ysize) ) return FALSE;
00529 
00530     if ( tipo == 6 ) {
00531         for ( i = y_tam - 1; i >= 0 ; i-- ) {
00532             fila = &(Data[i*x_tam]);
00533             for ( j = 0; j < x_tam ; j++ ) {
00534                 fread(&pixel, sizeof(PIXEL_RGB), 1, fd);
00535                 fila[j] = pixel;
00536             }
00537         }
00538     }
00539 
00540     if ( tipo == 5 ) {
00541         for ( i = y_tam - 1; i >= 0 ; i-- ) {
00542             fila = &(Data[i*x_tam]);
00543             for ( j = 0; j < x_tam ; j++ ) {
00544                 fread(&pixel.r, sizeof(BYTE), 1, fd);
00545                 fila[j].r = pixel.r;
00546                 fila[j].g = pixel.r;
00547                 fila[j].b = pixel.r;
00548             }
00549         }
00550     }
00551 
00552     return TRUE;
00553 #endif // FILESYSTEM_ENABLED
00554 }
00555 
00556 BOOLEAN
00557 IMAGEN_RGB::importar_sgirgb(FILE *fd)
00558 {
00559     //- Chequeo de sanidad --------------------------------------------------
00560     if ( !fd ) {
00561         fprintf(stderr, "<IMAGEN_RGB> Error: Archivo invalido!\n");
00562         return FALSE;
00563     }
00564 
00565     //-----------------------------------------------------------------------
00566     LECTOR_SGIRGB *Constructor = NULL;
00567 
00568     Constructor = new LECTOR_SGIRGB;
00569     if ( !Constructor ) {
00570         fprintf(stderr, "<IMAGEN_RGB> ERROR: Memoria insuficiente\n");
00571         fflush(stderr);
00572         return FALSE;
00573     }
00574 
00575     Constructor->init(fd);
00576 
00577     // Round up so rows are long-word aligned  
00578     if ( Constructor->sizeZ != 3 ) {
00579         fprintf(stderr,
00580             "<IMAGEN_RGB> - ERROR: Solo se soporta el formato RGB.\n");
00581         fflush(stderr);
00582         return FALSE;
00583     }
00584 
00585     init(Constructor->x_tam, Constructor->y_tam);
00586     Constructor->leer((BYTE *)Data);
00587     Constructor->elim();
00588     delete Constructor;
00589 
00590     return TRUE;
00591 }
00592 
00593 BOOLEAN
00594 IMAGEN_RGB::importar_pcx(FILE *fd)
00595 {
00596 #ifndef FILESYSTEM_ENABLED
00597     return FALSE;
00598 #endif
00599 #ifdef FILESYSTEM_ENABLED
00600     BYTE *Tmp_buffer;
00601     BYTE *m_palette_buffer;
00602 
00603     elim();
00604 
00605     if ( !fd ) return FALSE;
00606 
00607     //- Lea el encabezado PCX -----------------------------------------------
00608     int byte;
00609 
00610     byte = getc(fd); // format PCX
00611     if ( byte != 10 ) {    fclose(fd);     return FALSE;    }
00612     byte = getc(fd); // version info
00613     if ( byte != 5 ) {     fclose(fd);     return FALSE;    }
00614 
00615     //- Determine el tamanno de la imagen y asignele memoria ----------------
00616     int x1, y1, x2, y2;
00617 
00618     rewind(fd);  fgetc(fd);fgetc(fd);fgetc(fd);fgetc(fd); // Me reubico...
00619     x1 = fgetc(fd);    x1 |= fgetc(fd)<<8;
00620     y1 = fgetc(fd);    y1 |= fgetc(fd)<<8;
00621     x2 = fgetc(fd);    x2 |= fgetc(fd)<<8;
00622     y2 = fgetc(fd);    y2 |= fgetc(fd)<<8;
00623     x_tam       = x2 - x1 + 1;
00624     y_tam       = y2 - y1 + 1;
00625 
00626     Tmp_buffer = new unsigned char [(x_tam * y_tam)];
00627 
00628     //- Lea los datos de la imagen ------------------------------------------
00629     int w_count = 0;
00630     int repeat;
00631     int i;
00632 
00633     fseek(fd, 128, SEEK_SET); // Brincar el encabezado
00634     while ( w_count < (x_tam * y_tam) ) {
00635         byte = getc(fd);
00636         if ( byte > 0xbf ) {
00637             repeat = 0x3f & byte;
00638             byte = getc(fd);
00639             for (i = 0; i < repeat; i++) {
00640                 Tmp_buffer[w_count++] = (BYTE)byte;
00641             }
00642           }
00643           else {
00644             Tmp_buffer[w_count++] = (BYTE)byte;
00645         }
00646     }
00647 
00648     //- Lea los datos de la paleta de colores -------------------------------
00649     m_palette_buffer = new unsigned char [768];
00650     fseek (fd, -769, SEEK_END);
00651     byte = getc(fd);
00652     if ( byte != 12 ) {
00653         fclose(fd);
00654         return FALSE;
00655     }
00656     for (i = 0; i < 768; i++) {
00657         byte = getc(fd);
00658         m_palette_buffer[i] = (BYTE)byte;
00659     }
00660     fclose (fd);
00661 
00662     //- Importe los datos PCX a mi arreglo de imagen ------------------------
00663     int x, y;
00664     BYTE r, g, b;
00665 
00666     Data = new PIXEL_RGB [x_tam * y_tam];
00667     if ( !Data ) {
00668         fprintf(stderr,"<IMAGEN_RGB> ERROR: Memoria insuficiente.\n");
00669         fflush(stderr);
00670         return FALSE;
00671     }
00672     for ( y = 0; y < y_tam; y++ ) {
00673         for ( x = 0; x < x_tam; x++ ) {
00674             r = m_palette_buffer[3*Tmp_buffer[y*x_tam+x]+0];
00675             g = m_palette_buffer[3*Tmp_buffer[y*x_tam+x]+1];
00676             b = m_palette_buffer[3*Tmp_buffer[y*x_tam+x]+2];
00677             putpixel(x, y_tam-y-1, r, g, b);
00678         }
00679     }
00680     delete Tmp_buffer;
00681 
00682     return TRUE;
00683 #endif // FILESYSTEM_ENABLED
00684 }
00685 
00686 BOOLEAN
00687 IMAGEN_RGB::importar_png(FILE *fd)
00688 {
00689   #ifndef PNG_ENABLED
00690     fprintf(stderr, 
00691 "<IMAGEN_RGB::importar_png> - ERROR: AQUYNZA ha sido compilado sin soporte\n"
00692 "    para procesar archivos en formato PNG, probablemente debido a la\n"
00693 "    ausencia de la libreria libpng o a sus encabezados.\n"
00694 "    Recompile AQUYNZA con la opcion PNG_ENABLED activada si desea usar\n"
00695 "    esta operacion.\n"
00696 );
00697     fflush(stderr);
00698     return FALSE;
00699   #endif
00700 
00701   #ifdef PNG_ENABLED
00702     elim();
00703 
00704     //- 1. Acceso inicial a un archivo en formato PNG -----------------------
00705     png_structp lector_libpng;         // Acceso a los algoritmos de libpng
00706     png_infop info_ptr;
00707     png_uint_32 width, height;
00708     int bit_depth, color_type, interlace_type;
00709 
00710     // OJO: Notese que no se estan usando las funciones asincronicas de
00711     //      manejo de error, esto puede mejorarse.
00712     lector_libpng = png_create_read_struct(PNG_LIBPNG_VER_STRING,
00713                                            NULL, NULL, NULL);
00714 
00715     if ( !lector_libpng ) {
00716         return FALSE;
00717     }
00718 
00719     /* Allocate/initialize the memory for image information.  REQUIRED. */
00720     info_ptr = png_create_info_struct(lector_libpng);
00721     if ( !info_ptr ) {
00722         png_destroy_read_struct(&lector_libpng, NULL, NULL);
00723         return FALSE;
00724     }
00725 
00726     /* Set error handling if you are using the setjmp/longjmp method (this is
00727      * the normal method of doing things with libpng).  REQUIRED unless you
00728      * set up your own error handlers in the png_create_read_struct() earlier.
00729      */
00730     if ( setjmp(png_jmpbuf(lector_libpng)) ) {
00731         png_destroy_read_struct(&lector_libpng, &info_ptr, NULL);
00732         return FALSE;
00733     }
00734     png_init_io(lector_libpng, fd);
00735     png_read_info(lector_libpng, info_ptr);
00736     png_get_IHDR(lector_libpng, info_ptr, &width, &height, &bit_depth, 
00737                  &color_type, &interlace_type, NULL, NULL);
00738 
00739     //- 2. Configuracion de un formato de imagen compatible con AQUYNZA -----
00740 
00741     /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
00742      * byte into separate bytes (useful for paletted and grayscale images). */
00743     png_set_packing(lector_libpng);
00744 
00745     /* Expand paletted colors into true RGB triplets */
00746 /*
00747     if (color_type == PNG_COLOR_TYPE_PALETTE) {
00748         png_set_palette_rgb(lector_libpng);
00749     }
00750 */
00751 
00752 #ifdef NONONO
00753     /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
00754     if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 ) {
00755         png_set_gray_1_2_4_to_8(lector_libpng);
00756     }
00757 
00758     /* Expand paletted or RGB images with transparency to full alpha channels
00759      * so the data will be available as RGBA quartets.  */
00760     if ( png_get_valid(lector_libpng, info_ptr, PNG_INFO_tRNS)) {
00761         png_set_tRNS_to_alpha(lector_libpng);
00762     }
00763 #endif
00764 
00765     /* Set the background color to draw transparent and alpha images over.
00766      * It is possible to set the red, green, and blue components directly
00767      * for paletted images instead of supplying a palette index.  Note that
00768      * even if the PNG file supplies a background, you are not required to
00769      * use it - you should use the (solid) application background if it has one
00770      */
00771     png_color_16 my_background, *image_background;
00772 
00773     if ( png_get_bKGD(lector_libpng, info_ptr, &image_background) ) {
00774         png_set_background(lector_libpng, image_background,
00775                            PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
00776       }
00777     else {
00778         png_set_background(lector_libpng, &my_background,
00779                            PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
00780     }
00781 
00782     /* Add filler (or alpha) byte (before/after each RGB triplet) */
00783 //    png_set_filler(lector_libpng, 0xff, PNG_FILLER_AFTER);
00784 
00785     //- 3. Leida de la imagen, directamente a la memoria de usuaio ----------
00786     unsigned char **row_pointers;
00787     unsigned int row, pass, y;
00788     unsigned int number_passes;
00789     unsigned char *Data;
00790 
00791     number_passes = png_set_interlace_handling(lector_libpng);
00792     row_pointers = new unsigned char * [height];
00793     Data = new unsigned char [3 * width * height];
00794     for ( row = 0; row < height; row++ ) {
00795         row_pointers[row] = (unsigned char *)&Data[row*width*3];
00796     }
00797 
00798     for ( pass = 0; pass < number_passes; pass++ ) {
00799         for ( y = 0; y < height; y++ ) {
00800             png_read_rows(lector_libpng, &row_pointers[y], NULL, 1);
00801         }
00802     }
00803 
00804     png_read_end(lector_libpng, info_ptr);
00805     png_destroy_read_struct(&lector_libpng, &info_ptr, NULL);
00806     delete row_pointers;
00807 
00808     //- 4. Prueba: exportar la imagen a formato PPM -------------------------
00809     unsigned int i, j, idx;
00810     BYTE r, g, b;
00811 
00812     if ( !init(width, height) ) {
00813         delete Data;
00814         return FALSE;
00815     }
00816 
00817     for ( i = 0; i < height; i++ ) {
00818         for ( j = 0, idx = 0; j < width; j++, idx += 3 ) {
00819             r = row_pointers[i][idx];
00820             g = row_pointers[i][idx+1];
00821             b = row_pointers[i][idx+2];
00822             putpixel(j, i, r, g, b);
00823         }
00824     }
00825 
00826     delete Data;
00827 
00828     //-----------------------------------------------------------------------
00829     return TRUE;
00830   #endif // PNG_ENABLED
00831 }
00832 
00833 BOOLEAN
00834 IMAGEN_RGB::importar_jpeg(FILE *fd)
00835 {
00836   #ifndef JPEG_ENABLED
00837     fprintf(stderr, 
00838 "<IMAGEN_RGB::importar_jpeg> - ERROR: AQUYNZA ha sido compilado sin soporte\n"
00839 "    para procesar archivos en formato JPEG, probablemente debido a la\n"
00840 "    ausencia de la libreria libjpeg o a sus encabezados.\n"
00841 "    Recompile AQUYNZA con la opcion JPEG_ENABLED activada si desea usar\n"
00842 "    esta operacion.\n"
00843 );
00844     fflush(stderr);
00845     return FALSE;
00846   #endif
00847 
00848   #ifdef JPEG_ENABLED
00849     //- Importe los datos JPEG ----------------------------------------------
00850     char error_cad[200];
00851     int planos;
00852     BYTE *Tmp_buffer =
00853         IMAGEN_importar_jpeg(fd, &x_tam, &y_tam, &planos, error_cad);
00854 
00855     if ( !Tmp_buffer ) {
00856         fprintf(stderr, "<IMAGEN_RGB> ERROR: archivo JPEG invalido!\n");
00857         fflush(stderr);
00858         return FALSE;
00859     }
00860 
00861     if ( error_cad[0] ) {
00862         fprintf(stderr,
00863             "<IMAGEN_RGB> Warning: Archivo JPEG con problemas! : %s\n",
00864             error_cad);
00865         fflush(stderr);
00866     }
00867 
00868     if ( planos != 3 && planos != 1 ) {
00869         fprintf(stderr,
00870             "<IMAGEN_RGB> SORRY\n"
00871             "Solo se han implementado JPEGs con 1 o 3 planos.\n");
00872         fflush(stderr);
00873         return FALSE;
00874     }
00875 
00876     //- Importe los datos JPEG a mi arreglo de imagen -----------------------
00877     int x, y;
00878     BYTE r, g, b;
00879 
00880     Data = new PIXEL_RGB [x_tam * y_tam];
00881     if ( !Data ) {
00882         fprintf(stderr,"<IMAGEN_RGB> ERROR: Memoria insuficiente.\n");
00883         fflush(stderr);
00884         return FALSE;
00885     }
00886 
00887     if ( planos == 3 ) {
00888         for ( y = 0; y < y_tam; y++ ) {
00889             for ( x = 0; x < x_tam; x++ ) {
00890                 r = Tmp_buffer[3*(y*x_tam+x)];
00891                 g = Tmp_buffer[3*(y*x_tam+x)+1];
00892                 b = Tmp_buffer[3*(y*x_tam+x)+2];
00893                 putpixel(x, y_tam-y-1, r, g, b);
00894             }
00895         }
00896       }
00897       else if ( planos == 1 ) {
00898         for ( y = 0; y < y_tam; y++ ) {
00899             for ( x = 0; x < x_tam; x++ ) {
00900                 r = Tmp_buffer[y*x_tam+x];
00901                 g = r;
00902                 b = r;
00903                 putpixel(x, y_tam-y-1, r, g, b);
00904             }
00905         }
00906     }
00907     free(Tmp_buffer);
00908     return TRUE;
00909   #endif // JPEG_ENABLED
00910 }
00911 
00912 BOOLEAN
00913 IMAGEN_RGB::exportar_jpeg(FILE *fd, int calidad_jpeg)
00914 {
00915   #ifndef JPEG_ENABLED
00916     fprintf(stderr, 
00917 "<IMAGEN_RGB::importar_jpeg> - ERROR: AQUYNZA ha sido compilado sin soporte\n"
00918 "    para procesar archivos en formato JPEG, probablemente debido a la\n"
00919 "    ausencia de la libreria libjpeg o a sus encabezados.\n"
00920 "    Recompile AQUYNZA con la opcion JPEG_ENABLED activada si desea usar\n"
00921 "    esta operacion.\n"
00922 );
00923     fflush(stderr);
00924     return FALSE;
00925   #endif
00926 
00927   #ifdef JPEG_ENABLED
00928     if ( !fd ) return FALSE;
00929     IMAGEN_exportar_jpeg(fd, calidad_jpeg, x_tam, y_tam, (BYTE *)Data);
00930     return TRUE;
00931   #endif // JPEG_ENABLED
00932 }
00933 
00934 
00935 void
00936 IMAGEN_RGB::exportar_ppm(FILE *fd)
00937 {
00938     char cad[180];
00939     int i, j;
00940 
00941     sprintf(cad, "P6\n"
00942                  "# PPM CREATED BY: AQUYNZA http://www.aquynza.org\n");
00943     fwrite(cad, sizeof(char), strlen(cad), fd);
00944     sprintf(cad, "%d %d\n", x_tam, y_tam);
00945     fwrite(cad, sizeof(char), strlen(cad), fd);
00946     sprintf(cad, "255\n");
00947     fwrite(cad, sizeof(char), 4, fd);
00948 
00949 
00950     //- Manejo de imagenes nativas de 24 bits por pixel -----------------------
00951     PIXEL_RGB *fila, pixel;
00952 
00953     for ( i = y_tam - 1; i >= 0 ; i-- ) {
00954         fila = &((PIXEL_RGB *)Data)[i*x_tam];
00955         for ( j = 0; j < x_tam ; j++ ) {
00956             pixel = fila[j];
00957             fwrite(&pixel, sizeof(PIXEL_RGB), 1, fd);
00958         }
00959     }
00960 }
00961 
00962 //= SOPORTE PARA EL SISTEMA X11 =============================================
00963 
00964 #ifdef X_ENABLED
00965 
00966 //= SERVICIOS DE COPIA A ESTRUCTURAS XImage ==================================
00967 
00968 void
00969 IMAGEN_RGB::copiar_ximage(Display *Mi_display, XImage *imagen)
00974 {
00975     Screen *Zona =
00976         ScreenOfDisplay(Mi_display, DefaultScreen(Mi_display));
00977 
00978     int depth = DefaultDepthOfScreen(Zona);
00979 
00980     //- Copia dependiente del formato actual ---------------------------------
00981     switch ( depth ) {
00982       case 6: case 8:
00983         copiar_imagenX_depth8(Mi_display, imagen);
00984         break;
00985       case 16:
00986         copiar_imagenX_depth16(Mi_display, imagen);
00987         break;
00988       case 24: case 32:
00989         copiar_imagenX_depth24(Mi_display, imagen);
00990         break;
00991       default:
00992         fprintf(stderr, "ERROR!: Profundidad %d desconocida o no soportada.\n",
00993             depth);
00994         fflush(stderr);
00995     }
00996 
00997 }
00998 
00999 void
01000 IMAGEN_RGB::copiar_imagenX_depth8(Display *Mi_display, XImage *imagen)
01019 {
01020     unsigned char *bitp = (unsigned char*)imagen->data;
01021     unsigned char r, g, b, min = 255;
01022     static PALETA *Paleta = NULL;
01023     int i, j, k;
01024     double min_dist, dist;
01025 
01026     if ( !Paleta ) {
01027         Paleta = new PALETA;
01028         Paleta->importe_x(Mi_display,
01029             DefaultColormap(Mi_display, DefaultScreen(Mi_display)));
01030     }
01031 
01032     //- Inicialice un cache de colores -------------------------------------
01033     int cache[64][64][64];
01034 
01035     for ( i = 0; i < 64; i++ ) {
01036         for ( j = 0; j < 64; j++ ) {
01037             for ( k = 0; k < 64; k++ ) {
01038                 cache[i][j][k] = -1;
01039             }
01040         }
01041     }
01042 
01043     //- Version de RGB 24 bits a Visual 8 bits -----------------------------
01044     unsigned char rr, gg, bb;
01045 
01046     for ( j = 0; j < y_tam; j++ ) {
01047         for ( i = 0; i < x_tam; i++ ) {
01048             r = ((BYTE *)Data)[3 * (j * x_tam + i)];
01049             g = ((BYTE *)Data)[3 * (j * x_tam + i) + 1];
01050             b = ((BYTE *)Data)[3 * (j * x_tam + i) + 2];
01051             rr = r >> 2;
01052             gg = g >> 2;
01053             bb = b >> 2;
01054             if ( cache[rr][gg][bb] == -1 ) {
01055                 min_dist = FLT_MAX;
01056                 for ( k = 0; k < Paleta->tam_tabla; k++ ) {
01057                     dist = DISTANCIA(r, g, b, 
01058                                      Paleta->tabla[k].r,
01059                                      Paleta->tabla[k].g,
01060                                      Paleta->tabla[k].b);
01061                     if ( dist < min_dist ) {
01062                         min_dist = dist;
01063                         min = k;
01064                     }
01065                 }
01066                 cache[rr][gg][bb] = min;
01067             }
01068             bitp[((y_tam - j - 1) * x_tam + i)] = cache[rr][gg][bb];
01069         }
01070     }
01071 }
01072 
01073 void
01074 IMAGEN_RGB::copiar_imagenX_depth16(Display *Mi_display, XImage *imagen)
01079 {
01080     Visual *vi=DefaultVisual(Mi_display,DefaultScreen(Mi_display));
01081     int rshift = 15 - highbit(vi->red_mask);
01082     int gshift = 15 - highbit(vi->green_mask);
01083     int bshift = 15 - highbit(vi->blue_mask);
01084     int bmap_order = BitmapBitOrder(Mi_display);
01085     unsigned char *bitp;
01086     int i, j, k = 0;
01087     int c;
01088 
01089     bitp = (unsigned char*)imagen->data;
01090     for ( j = y_tam - 1; j >= 0; j-- ) {
01091         for ( i = 0; i < x_tam; i++ ) {
01092             k = j * x_tam + i;
01093             c = (((int)((BYTE*)Data)[3*k]*256 >> rshift) & vi->red_mask) |
01094                 (((int)((BYTE*)Data)[3*k+1] * 256>> gshift) & vi->green_mask) |
01095                 (((int)((BYTE*)Data)[3*k+2] * 256>> bshift) & vi->blue_mask);
01096             if ( bmap_order == MSBFirst ) {
01097                 *bitp++ = (c >> 8) & 0xff;
01098                 *bitp++ = c & 0xff;
01099               }
01100               else {
01101                 *bitp++ = c & 0xff;
01102                 *bitp++ = (c >> 8) & 0xff;
01103             }
01104         }
01105     }
01106 }
01107 
01108 void
01109 IMAGEN_RGB::copiar_imagenX_depth24(Display *Mi_display, XImage *imagen)
01125 {
01126     unsigned char *ptr = (unsigned char*)imagen->data;
01127     int bmap_order = BitmapBitOrder(Mi_display);
01128     int i, j, k = 0;
01129 
01130     // OJO: No se tiene en cuenta el alineamiento a la palabra... sera
01131     //      que funciona para imagenes cuyo ancho no sea multiplo de
01132     //      2, 4 u 8?
01133     // OJO: No tiene en cuenta las mascaras de color que pueda estar
01134     //      usando el servidor X11, y supone que son 0x00FF0000,
01135     //      0x0000FF00 y 0x000000FF.
01136     if ( bmap_order == MSBFirst ) {
01137         // Este algoritmo no ha sido probado
01138         for ( j = y_tam - 1; j >= 0; j-- ) {        
01139             for ( i = 0; i < x_tam; i++ ) {
01140                 k = x_tam * j + i;
01141                 *ptr++ = (unsigned char)(Data[k].r); // Canal rojo
01142                 *ptr++ = (unsigned char)(Data[k].g); // Canal verde
01143                 *ptr++ = (unsigned char)(Data[k].b); // Canal azul
01144                 *ptr++ = (unsigned char)(0x00);
01145             }
01146         }
01147     }
01148     else {
01149         // Funciona bien en i386_LINUX_GCC
01150         for ( j = y_tam - 1; j >= 0; j-- ) {        
01151             for ( i = 0; i < x_tam; i++ ) {
01152                 k = x_tam * j + i;
01153                 *ptr++ = (unsigned char)(Data[k].b); // Canal azul
01154                 *ptr++ = (unsigned char)(Data[k].g); // Canal verde
01155                 *ptr++ = (unsigned char)(Data[k].r); // Canal rojo
01156                 *ptr++ = (unsigned char)(0x00);
01157             }
01158         }
01159     }
01160 }
01161 
01162 //= SERVICIOS DE CREACION DE ESTRUCTURAS XImage =============================
01163 
01164 XImage *
01165 IMAGEN_RGB::exportar_ximage(Display *Mi_display)
01174 {
01175     XImage *Imagen_en_formato_X11;
01176     int depth;
01177 
01178     Screen *Zona =
01179         ScreenOfDisplay(Mi_display, DefaultScreen(Mi_display));
01180 
01181     depth = DefaultDepthOfScreen(Zona);
01182 
01183     //- Creacion de una imagen a partir de los datos de imagen --------------
01184     switch ( depth ) {
01185       case 6: case 8:
01186         Imagen_en_formato_X11 = crear_imagenX_depth8(Mi_display);
01187         break;
01188       case 16:
01189         Imagen_en_formato_X11 = crear_imagenX_depth16(Mi_display);
01190         break;
01191       case 24: case 32:
01192         Imagen_en_formato_X11 = crear_imagenX_depth24(Mi_display);
01193         break;
01194       default:
01195         fprintf(stderr, "<IMAGEN_RGB::exportar_ximage> - ERROR: "
01196                 "Profundidad %d desconocida o no soportada.\n", depth);
01197         fflush(stderr);
01198         return NULL;
01199     }
01200 
01201     return Imagen_en_formato_X11;
01202 }
01203 
01204 XImage *
01205 IMAGEN_RGB::crear_imagenX_depth8(Display *Mi_display)
01214 {
01215     Screen *Zona =
01216         ScreenOfDisplay(Mi_display, DefaultScreen(Mi_display));
01217 
01218     //- Creacion de la estructura de imagen y su arreglo de pixels ----------
01219     int depth = DefaultDepthOfScreen(Zona);
01220     unsigned char *mi_data = (unsigned char *)malloc(x_tam * y_tam);;
01221     XImage *newimage = XCreateImage(Mi_display,
01222         DefaultVisual(Mi_display, DefaultScreen(Mi_display)),
01223         depth, ZPixmap, 0, (char *)mi_data,
01224         x_tam, y_tam, 8, x_tam);
01225 
01226     //- Copiado de los datos de imagen al arreglo de pixels -----------------
01227     copiar_imagenX_depth8(Mi_display, newimage);
01228 
01229     return newimage;
01230 }
01231 
01232 XImage *
01233 IMAGEN_RGB::crear_imagenX_depth16(Display *Mi_display)
01238 {
01239     Screen *Zona =
01240         ScreenOfDisplay(Mi_display, DefaultScreen(Mi_display));
01241 
01242     //- Creacion de la estructura de imagen y su arreglo de pixels ----------
01243     int depth = DefaultDepthOfScreen(Zona);
01244     unsigned char *mi_data = (unsigned char *)malloc(2 * x_tam * y_tam);
01245     XImage *newimage = XCreateImage(Mi_display,
01246         DefaultVisual(Mi_display, DefaultScreen(Mi_display)),
01247         depth, ZPixmap, 0, (char *)mi_data,
01248         x_tam, y_tam, 16, 0);
01249 
01250     //- Copiado de los datos de imagen al arreglo de pixels -----------------
01251     copiar_imagenX_depth16(Mi_display, newimage);
01252 
01253     return newimage;
01254 }
01255 
01256 XImage *
01257 IMAGEN_RGB::crear_imagenX_depth24(Display *Mi_display)
01262 {
01263     Screen *Zona =
01264         ScreenOfDisplay(Mi_display, DefaultScreen(Mi_display));
01265 
01266     //- Creacion de la estructura de imagen y su arreglo de pixels ----------
01267     int depth = DefaultDepthOfScreen(Zona);
01268     unsigned char *mi_data = (unsigned char *)malloc(4 * x_tam * y_tam);
01269     XImage *newimage = XCreateImage(
01270         Mi_display,        // Conexion con el servidor X11
01271         DefaultVisual(Mi_display, DefaultScreen(Mi_display)),   // Visual
01272         depth,             // Bits Por Pixel del servidor X11
01273         ZPixmap,           // Formato
01274         0,                 // Offset
01275         (char *)mi_data,   // Arreglo con los datos del pixel
01276         x_tam,             // Ancho de la imagen
01277         y_tam,             // Alto de la imagen
01278         32,                // (8 | 16 | 32) Alineamiento a la palabra...
01279         0                  // ? bytes_per_line
01280     );
01281 
01282     //- Copiado de los datos de imagen al arreglo de pixels -----------------
01283     copiar_imagenX_depth24(Mi_display, newimage);
01284 
01285     return newimage;
01286 }
01287 
01288 //= SERVICIOS DE CREACION DE ESTRUCTURAS TIPO Pixmap ========================
01289 
01290 Pixmap
01291 IMAGEN_RGB::exportar_pixmap(Display *_display, Screen *_screen, Window _window)
01292 {
01293     GC gc;
01294     XImage *Imagen;
01295     Pixmap el_pixmap;
01296 
01297 //    XtDisplay(padre), XtScreen(padre), XtWindow(padre)
01298 
01299     Imagen = exportar_ximage(_display);
01300 
01301     //- Dibuje la imagen en un pixmap ----------------------------------------
01302     // OJO: Esto que?
01303 // #ifdef MOTIF_ENABLED
01304 //    if ( !Imagen ) return (Pixmap)XmUNSPECIFIED_PIXMAP;
01305 //  #endif
01306 //  #ifndef MOTIF_ENABLED
01307     if ( !Imagen ) return (Pixmap)NULL;
01308 //  #endif
01309 
01310     el_pixmap = XCreatePixmap(_display, _window,
01311         x_tam, y_tam, DefaultDepthOfScreen(_screen));
01312 
01313     gc = XCreateGC(_display, _window, 0, NULL);
01314 
01315     XSetFunction(_display, gc, GXcopy);
01316     XPutImage(_display, el_pixmap, gc, Imagen, 0,0,0,0, x_tam, y_tam);
01317     XFreeGC(_display, gc);
01318     XDestroyImage(Imagen);
01319 
01320     return (Pixmap)el_pixmap;
01321 }
01322 
01323 #endif // X_ENABLED
01324 
01325 #if PLATAFORMA == i386_WIN32_VC
01326 void
01327 IMAGEN_RGB::importar_win32dc(HDC dc, int xpos, int ypos, int ancho, int alto)
01328 {
01329     int x, y;
01330     COLORREF p;
01331     BYTE r, g, b;
01332 
01333     if ( ancho != x_tam || alto != y_tam ) {
01334         init(ancho, alto);
01335     }
01336 
01337     for ( y = 0; y < alto; y++ ) {
01338         for ( x = 0; x < ancho; x++ ) {
01339             p = GetPixel(dc, x+xpos, y+ypos);
01340             r = (BYTE)(p & 0x000000FFL);
01341             g = (BYTE)((p & 0x0000FF00) >> 8);
01342             b = (BYTE)((p & 0x00FF0000) >> 16);
01343             putpixel(x, y, r, g, b);
01344         }
01345     }
01346 }
01347 
01348 void
01349 IMAGEN_RGB::exportar_win32dc(HDC dc, int xpos, int ypos)
01350 {
01351     int x, y;
01352     COLORREF p;
01353     BYTE r, g, b;
01354 
01355     for ( y = 0; y < y_tam; y++ ) {
01356         for ( x = 0; x < x_tam; x++ ) {
01357             getpixel(x, y, r, g, b);
01358             p = (COLORREF)r + 256*((COLORREF)g) + 256*256*((COLORREF)b);
01359             SetPixel(dc, x+xpos, y+ypos, p);
01360         }
01361     }
01362 }
01363 #endif // PLATAFORMA == i386_WIN32_VC
01364 
01365 #if PLATAFORMA == PALM_PALMOS_CODEWARRIOR
01366 void
01367 IMAGEN_RGB::exportar_palm(int xpos, int ypos)
01368 {
01369     BYTE r, g, b;
01370     int i, j;
01371 
01372     for ( i = 0; i < x_tam; i++ ) {
01373         for ( j = 0; j < y_tam; j++ ) {
01374             getpixel(i, j, r, g, b);
01375             PALM_putpixel(i + xpos, j + ypos, r, g, b);
01376         }
01377     }
01378 }
01379 #endif // PLATAFORMA == PALM_PALMOS_CODEWARRIOR
01380 
01381 //= METODOS DE PROCESAMIENTO DE IMAGENES ====================================
01382 
01383 void
01384 IMAGEN_RGB::aplicar_correccion_gamma(BYTE funcion_gamma[256])
01385 {
01386     int i, j;
01387     PIXEL_RGB a, b;
01388 
01389     for ( i = 0; i < y_tam ; i++ ) {
01390         for ( j = 0; j < x_tam ; j++ ) {
01391             getpixel(j, i, a.r, a.g, a.b);
01392             b.r = funcion_gamma[a.r];
01393             b.g = funcion_gamma[a.g];
01394             b.b = funcion_gamma[a.b];
01395             getpixel(j, i, b.r, b.g, b.b);
01396         }
01397     }
01398 
01399 }
01400 
01401 //= METODOS DE PRUEBA =======================================================
01402 
01403 void
01404 IMAGEN_RGB::tmp_degradecito(int mtipo)
01408 {
01409     int i, j;
01410     PIXEL_RGB c;
01411 
01412     for ( i = 0; i < y_tam ; i++ ) {
01413         for ( j = 0; j < x_tam ; j++ ) {
01414             switch ( mtipo ) {
01415               case 0: c.r = c.g = c.b = 0; break;
01416               case 2: 
01417                   //c.r = c.g = c.b = 0; 
01418                   c.r = (BYTE)(255*RANDOM());
01419                   c.g = c.r;//(BYTE)(255*RANDOM());
01420                   c.b = c.r;//(BYTE)(255*RANDOM());
01421                   break;
01422               case 3: c.r = 255; c.g = c.b = 0; break;
01423               case 4: c.g = 255; c.r = c.b = 0; break;
01424               case 5: c.b = 255; c.r = c.g = 0; break;
01425               case 6: c.r = (BYTE)((double)(i*256)/y_tam); c.g=c.b=0; break;
01426               case 7: c.g = (BYTE)((double)(i*256)/y_tam); c.r=c.b=0; break;
01427               case 8: c.b = (BYTE)((double)(i*256)/y_tam); c.r=c.g=0; break;
01428               case 9:
01429                 if ( (i % 2 && !(j % 2)) || 
01430                      (j % 2 && !(i % 2)) ) {
01431                     c.r = 255;
01432                     c.g = 255;
01433                     c.b = 255;
01434                   }
01435                   else {
01436                     c.r = 0;
01437                     c.g = 0;
01438                     c.b = 0;
01439                 }
01440                 if ( i == y_tam/2 ) {
01441                     c.r = 255;
01442                     c.g = 0;
01443                     c.b = 0;
01444                 }
01445                 if ( j == x_tam/2) {
01446                     c.r = 0;
01447                     c.g = 255;
01448                     c.b = 0;
01449                 }
01450                 break;
01451               case 1: default: c.r = c.g = c.b = 255; break;
01452             }
01453             putpixel(j, i, c.r, c.g, c.b);
01454         }
01455     }
01456 
01457 }
01458 
01459 void
01460 IMAGEN_RGB::linea(int x0, int y0, int x1, int y1, BYTE r, BYTE g, BYTE b)
01461 {
01462     double dx, dy;
01463     double dxdy;
01464     double dydx;
01465     int x, y;
01466     double xx, yy;
01467 
01468     dx = (double)(x1-x0);
01469     dy = (double)(y1-y0);
01470 
01471     if ( fabs(dx) > EPSILON && fabs(dy/dx) <= 1 && x1 > x0 ) {
01472         // Pendiente entre -1 y 1
01473         dydx = dy/dx;
01474         for ( x = x0, yy = (double)y0; x <= x1; x++ ) {
01475             y = (int)yy;
01476             if ( x >= 0 && x < xtam() &&
01477                  y >= 0 && y < ytam() ) {
01478                 putpixel(x, y, r, g, b);
01479             }
01480             yy += dydx;
01481         }
01482       }
01483       else if ( fabs(dx) > EPSILON && fabs(dy/dx) <= 1 && x1 < x0 ) {
01484         // Pendiente entre -1 y 1
01485         dydx = dy/dx;
01486         for ( x = x1, yy = (double)y1; x <= x0; x++ ) {
01487             y = (int)yy;
01488             if ( x >= 0 && x < xtam() &&
01489                  y >= 0 && y < ytam() ) {
01490                 putpixel(x, y, r, g, b);
01491             }
01492             yy += dydx;
01493         }
01494       }
01495       else if ( fabs(dy) > EPSILON && y1 > y0 ) {
01496         // Pendiente mayor a 1 o menor a -1
01497         dxdy = dx/dy;
01498         for ( y = y0, xx = (double)x0; y <= y1; y++ ) {
01499             x = (int)xx;
01500             if ( x >= 0 && x < xtam() &&
01501                  y >= 0 && y < ytam() ) {
01502                 putpixel(x, y, r, g, b);
01503             }
01504             xx += dxdy;
01505         }
01506       }
01507       else if ( fabs(dy) > EPSILON && y1 < y0 ) {
01508         // Pendiente mayor a 1 o menor a -1
01509         dxdy = dx/dy;
01510         for ( y = y1, xx = (double)x1; y <= y0; y++ ) {
01511             x = (int)xx;
01512             if ( x >= 0 && x < xtam() &&
01513                  y >= 0 && y < ytam() ) {
01514                 putpixel(x, y, r, g, b);
01515             }
01516             xx += dxdy;
01517         }
01518       }
01519     ;
01520 }
01521 
01522 //===========================================================================
01523 //= EOF                                                                     =
01524 //===========================================================================
01525 

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.