00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00065
00066
00067 IMAGEN_RGB::IMAGEN_RGB()
00068 {
00069
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
00083
00084
00085
00086 }
00087
00088 IMAGEN_RGB::~IMAGEN_RGB()
00089 {
00090
00091 if ( Data ) elim();
00092 }
00093
00094 BOOLEAN
00095 IMAGEN_RGB::init(int width, int height)
00102 {
00103
00104
00105 if ( x_tam == width && y_tam == height ) return TRUE;
00106 elim();
00107
00108 #if PLATAFORMA != PALM_PALMOS_CODEWARRIOR
00109 Data = new PIXEL_RGB[height * width];
00110 #endif
00111 #if PLATAFORMA == PALM_PALMOS_CODEWARRIOR
00112
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
00149 if ( Data ) {
00150
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
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
00231
00232 if ( !Data ) {
00233 fprintf(stderr,
00234 "<IMAGEN_RGB> ERROR: Intentando pintar una imagen nula.\n");
00235 fflush(stderr);
00236 return;
00237 }
00238
00239
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
00275
00276 if ( !Data ) {
00277 fprintf(stderr,
00278 "<IMAGEN_RGB> ERROR: Intentando activar una imagen nula.\n");
00279 fflush(stderr);
00280 return;
00281 }
00282
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
00291
00292
00293 #ifndef GL_COMPLETO
00294
00295
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
00301
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
00355
00356
00357
00358
00359
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 * )
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
00417
00418
00419 Nueva->putcolorindex(x, y, nivel_de_gris(r, g, b));
00420 }
00421 }
00422
00423
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
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
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
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
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
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
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
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
00608 int byte;
00609
00610 byte = getc(fd);
00611 if ( byte != 10 ) { fclose(fd); return FALSE; }
00612 byte = getc(fd);
00613 if ( byte != 5 ) { fclose(fd); return FALSE; }
00614
00615
00616 int x1, y1, x2, y2;
00617
00618 rewind(fd); fgetc(fd);fgetc(fd);fgetc(fd);fgetc(fd);
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
00629 int w_count = 0;
00630 int repeat;
00631 int i;
00632
00633 fseek(fd, 128, SEEK_SET);
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
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
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
00705 png_structp lector_libpng;
00706 png_infop info_ptr;
00707 png_uint_32 width, height;
00708 int bit_depth, color_type, interlace_type;
00709
00710
00711
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
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
00727
00728
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
00740
00741
00742
00743 png_set_packing(lector_libpng);
00744
00745
00746
00747
00748
00749
00750
00751
00752 #ifdef NONONO
00753
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
00759
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
00766
00767
00768
00769
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
00783
00784
00785
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
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
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
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
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
00963
00964 #ifdef X_ENABLED
00965
00966
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
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
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
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
01131
01132
01133
01134
01135
01136 if ( bmap_order == MSBFirst ) {
01137
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);
01142 *ptr++ = (unsigned char)(Data[k].g);
01143 *ptr++ = (unsigned char)(Data[k].b);
01144 *ptr++ = (unsigned char)(0x00);
01145 }
01146 }
01147 }
01148 else {
01149
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);
01154 *ptr++ = (unsigned char)(Data[k].g);
01155 *ptr++ = (unsigned char)(Data[k].r);
01156 *ptr++ = (unsigned char)(0x00);
01157 }
01158 }
01159 }
01160 }
01161
01162
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
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
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
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
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
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
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,
01271 DefaultVisual(Mi_display, DefaultScreen(Mi_display)),
01272 depth,
01273 ZPixmap,
01274 0,
01275 (char *)mi_data,
01276 x_tam,
01277 y_tam,
01278 32,
01279 0
01280 );
01281
01282
01283 copiar_imagenX_depth24(Mi_display, newimage);
01284
01285 return newimage;
01286 }
01287
01288
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
01298
01299 Imagen = exportar_ximage(_display);
01300
01301
01302
01303
01304
01305
01306
01307 if ( !Imagen ) return (Pixmap)NULL;
01308
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
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
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
01418 c.r = (BYTE)(255*RANDOM());
01419 c.g = c.r;
01420 c.b = c.r;
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
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
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
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
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
01524
01525