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_pal.h"
00027 #endif
00028
00029 #include <stdio.h>
00030 #include <string.h>
00031
00032
00033
00034
00035
00036 IMAGEN_PAL::IMAGEN_PAL()
00037 {
00038
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
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
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
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
00103 if ( !Data ) {
00104 fprintf(stderr,
00105 "<IMAGEN_PAL> ERROR: Intentando pintar una imagen nula.\n");
00106 fflush(stderr);
00107 return;
00108 }
00109
00110
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
00119
00120
00121
00122
00123 {
00124
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
00139
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
00152
00153 con_lista = TRUE;
00154 }
00155 else if ( acelerable(x_tam, y_tam) ) {
00156
00157
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
00169 glTexImage2D(GL_TEXTURE_2D, 0, 3, x_tam, y_tam, 0, GL_COLOR_INDEX,
00170 GL_UNSIGNED_BYTE, (void *)Data);
00171
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
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
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
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
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
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
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
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
00285
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
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
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
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
00401
00402
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
00410
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
00417
00418
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
00494
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
00562
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;
00594 double factor_divisor = 8.0;
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
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
00614 sum -= sum/s - getcolorindex(x, y); promedio = sum/s;
00615
00616
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
00660
00661