/* C< C*********************************************************************** C C FONCTION : C ---------- C C C$ HISTORIQUE DES MODIFICATIONS : C -------------------------------- C 21-02-97 : GG ; G1334-PERF C Ameliorer les performances de traduction C des images XWD. C >> Rempacer XGetPixel et XputPixel par des C directes dans le buffer image. C 07-05-97 : GG ; PRO7909 C Eviter de detruire l'image convertie lorsqu'il n'y a pas C de conversion a faire ! */ #define PRO7909 #include /* ifdef then trace on */ #ifdef TRACE #define TRACE_CONVERT_IMAGE #endif /* XW_STATUS Xw_convert_image (awindow,aimage,acolors,ncolors): XW_EXT_WINDOW *awindow XW_EXT_IMAGEDATA *aimage XW_EXT_COLOR *acolors (can be NULL) int ncolors Convert an image depending of the window class returns ERROR if image can't be converted. returns SUCCESS if successfull */ #define CREATE_IMAGE(_fun,_out,_nbp) \ /* Allocate the new pixel buffer */ \ if( !(_out = (unsigned char*) Xw_calloc(piimage->width * piimage->height,_nbp)) ) {\ /*ERROR*Bad Image allocation*/ \ Xw_set_error(60,_fun,0) ; \ return NULL ; \ } \ /* Create the new Image structure */ \ if( !(poimage = XCreateImage(_DISPLAY,_VISUAL,_DEPTH,ZPixmap,\ 0,(char*)_out,piimage->width,piimage->height,_nbp*8,0)) ) {\ /* ERROR*XImage Creation failed */ \ Xw_set_error(62,_fun,0) ; \ Xw_free((char*)_out) ; \ return NULL ; \ } #define COPY_PSEUDO_TO_PSEUDO(_fun,_in,_out) \ for( y=0 ; yheight ; y++ ) { \ for( x=0 ; xwidth ; x++ ) { \ ipixel = *_in++; \ if( ipixel != lipixel ) { \ lipixel = ipixel; \ if( ipixel >= MAXCOLOR ) ipixel = 0 ; \ opixel = mapping[ipixel] ; \ if( !opixel ) { \ for( i=0,j=ipixel ; i= ncolors ) j = 0 ; \ if( ipixel == pcolors[j].pixel ) break; \ } \ red = (float)pcolors[j].red/0xFFFF ; \ green = (float)pcolors[j].green/0xFFFF ; \ blue = (float)pcolors[j].blue/0xFFFF ; \ if( !Xw_get_color_pixel(_COLORMAP,red,green,blue,&opixel,&isapproximate)) {\ /*ERROR*XImage Creation failed*/ \ Xw_set_error(63,_fun,&_COLORMAP->info.colormap) ;\ } \ mapping[ipixel] = opixel ; \ } \ } \ *_out++ = opixel; \ } \ if( ipad > 0 ) pidata.cdata += ipad; \ } #define COPY_PSEUDO_TO_TRUE(_fun,_in,_out) \ for( y=0 ; yheight ; y++ ) { \ for( x=0 ; xwidth ; x++ ) { \ ipixel = *_in++; \ if( ipixel != lipixel ) { \ lipixel = ipixel; \ if( ipixel >= MAXCOLOR ) ipixel = 0 ; \ opixel = mapping[ipixel] ; \ if( !opixel ) { \ for( i=0,j=ipixel ; i= ncolors ) j = 0 ; \ if( ipixel == pcolors[j].pixel ) break; \ } \ red = (float)pcolors[j].red/0xFFFF ; \ green = (float)pcolors[j].green/0xFFFF ; \ blue = (float)pcolors[j].blue/0xFFFF ; \ if( !Xw_get_color_pixel(_COLORMAP,red,green,blue,&opixel,&isapproximate)) {\ /*ERROR*XImage Creation failed*/ \ Xw_set_error(63,_fun,&_COLORMAP->info.colormap) ;\ } \ mapping[ipixel] = opixel ; \ } \ } \ *_out++ = opixel; \ } \ if( ipad > 0 ) pidata.cdata += ipad; \ } #define COPY_TRUE_TO_PSEUDO(_fun,_in,_out) \ for( y=0 ; yheight ; y++ ) { \ for( x=0 ; xwidth ; x++ ) { \ ipixel = *_in++; \ if( ipixel != lipixel ) { \ lipixel = ipixel; \ red = (float)((ipixel >> sred) & cmask)/(float)cmask; \ green = (float)((ipixel >> sgreen) & cmask)/(float)cmask; \ blue = (float)((ipixel >> sblue) & cmask)/(float)cmask; \ if( !Xw_get_color_pixel(_COLORMAP,red,green,blue,&opixel,&isapproximate)) {\ /*ERROR*XImage Creation failed*/ \ Xw_set_error(63,_fun,&_COLORMAP->info.colormap) ; \ } \ } \ *_out++ = opixel; \ } \ if( ipad > 0 ) pidata.cdata += ipad; \ } #define COPY_TRUE_TO_TRUE(_fun,_in,_out) \ for( y=0 ; yheight ; y++ ) { \ for( x=0 ; xwidth ; x++ ) { \ ipixel = *_in++; \ if( ipixel != lipixel ) { \ lipixel = ipixel; \ red = (float)((ipixel >> sred) & cmask)/(float)cmask; \ green = (float)((ipixel >> sgreen) & cmask)/(float)cmask; \ blue = (float)((ipixel >> sblue) & cmask)/(float)cmask; \ if( !Xw_get_color_pixel(_COLORMAP,red,green,blue,&opixel,&isapproximate)) {\ /*ERROR*XImage Creation failed*/ \ Xw_set_error(63,_fun,&_COLORMAP->info.colormap) ; \ } \ } \ *_out++ = opixel; \ } \ if( ipad > 0 ) pidata.cdata += ipad; \ } #ifdef XW_PROTOTYPE static XImage* ConvertPseudoToPseudo(XW_EXT_WINDOW *pwindow,XImage *piimage,XColor *pcolors,int ncolors) ; static XImage* ConvertPseudoToTrue(XW_EXT_WINDOW *pwindow,XImage *piimage,XColor *pcolors,int ncolors) ; static XImage* ConvertTrueToPseudo(XW_EXT_WINDOW *pwindow,XImage *piimage) ; static XImage* ConvertTrueToTrue(XW_EXT_WINDOW *pwindow,XImage *piimage) ; #else static XImage* ConvertPseudoToPseudo() ; static XImage* ConvertPseudoToTrue() ; static XImage* ConvertTrueToPseudo() ; static XImage* ConvertTrueToTrue() ; #endif /*XW_PROTOTYPE*/ #ifdef XW_PROTOTYPE XW_STATUS Xw_convert_image (void *awindow,void *aimage,void *acolors,int ncolors) #else XW_STATUS Xw_convert_image (awindow,aimage,acolors,ncolors) void *awindow; void *aimage; void *acolors; int ncolors; #endif /*XW_PROTOTYPE*/ { XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow; XW_EXT_IMAGEDATA *pimage = (XW_EXT_IMAGEDATA*)aimage; XColor *pcolors = (XColor*)acolors; XImage *piimage,*poimage = NULL; XW_STATUS status = XW_ERROR; int i,iclass = 0; if( !Xw_isdefine_window(pwindow) ) { /*ERROR*Bad EXT_WINDOW Address*/ Xw_set_error(24,"Xw_convert_image",pwindow) ; return (XW_ERROR) ; } if( !Xw_isdefine_image(pimage) ) { /*ERROR*Bad EXT_IMAGEDATA Address*/ Xw_set_error(25,"Xw_convert_image",pimage) ; return (XW_ERROR) ; } piimage = (_ZIMAGE) ? _ZIMAGE : _IIMAGE; if( !pcolors && piimage->red_mask && piimage->green_mask && piimage->blue_mask ) iclass = TrueColor; else iclass = PseudoColor; switch ( iclass ) { case PseudoColor : if( !pcolors ) { if( !_ICOLORMAP ) _ICOLORMAP = _COLORMAP; ncolors = min(_IVISUAL->map_entries,MAXCOLOR); pcolors = (XColor*) Xw_calloc(sizeof(XColor),ncolors); for( i=0 ; iinfo.colormap,pcolors,ncolors) ; } if( pcolors ) switch (_CLASS ) { case PseudoColor : /* Convert Pseudo to PseudoColor */ if( acolors || (_ICOLORMAP != _COLORMAP) ) { poimage = ConvertPseudoToPseudo(pwindow,piimage,pcolors,ncolors) ; } else { poimage = piimage; } break ; case TrueColor : /* Convert Pseudo to TrueColor */ poimage = ConvertPseudoToTrue(pwindow,piimage,pcolors,ncolors) ; break ; default: /*ERROR*Unimplemented Visual class*/ Xw_set_error(5,"Xw_convert_image",&_CLASS) ; } #ifdef BUG /* Cette memoire est liberee par Xw_load_image !! */ if( pcolors && !acolors ) Xw_free(pcolors); #endif break ; case TrueColor : switch (_CLASS ) { case PseudoColor : /* Convert True to PseudoColor */ poimage = ConvertTrueToPseudo(pwindow,piimage) ; break ; case TrueColor : /* Convert True to TrueColor */ poimage = ConvertTrueToTrue(pwindow,piimage) ; break ; default: /*ERROR*Unimplemented Visual class*/ Xw_set_error(5,"Xw_convert_image",&_CLASS) ; } break ; default: /*ERROR*Unimplemented Visual class*/ Xw_set_error(5,"Xw_convert_image",&iclass) ; } _ICOLORMAP = _COLORMAP; if( poimage ) { status = XW_SUCCESS; /* Destroy the old image */ if( _ZIMAGE && (_ZIMAGE != _IIMAGE) ) { XDestroyImage(_ZIMAGE); _ZIMAGE = NULL; } /* Initialize the output image */ #ifdef PRO7909 if( _IIMAGE != poimage ) { XDestroyImage(_IIMAGE); _IIMAGE = poimage; } #else XDestroyImage(_IIMAGE); _IIMAGE = poimage; #endif pimage->zoom = 1.; } #ifdef TRACE_CONVERT_IMAGE if( Xw_get_trace() ) { printf (" %d = Xw_convert_image(%lx,%lx,%lx,%d)\n", status,(long ) pwindow,(long ) pimage,(long ) pcolors,ncolors); } #endif return (status); } #ifdef XW_PROTOTYPE static XImage* ConvertTrueToPseudo(XW_EXT_WINDOW *pwindow,XImage *piimage) #else static XImage* ConvertTrueToPseudo(pwindow,piimage) XW_EXT_WINDOW *pwindow ; XImage *piimage ; #endif /*XW_PROTOTYPE*/ /* Convert TrueColor to PseudoColor Image */ { unsigned long ipixel,opixel,cmask ; unsigned long lipixel = 0xFFFFFFFF ; //int i,j,ipad,isapproximate ; int ipad,isapproximate ; int sred,sgreen,sblue ; float red,green,blue ; register union { unsigned char *cdata ; unsigned short *sdata ; unsigned int *idata ; } pidata,podata; register int x,y; XImage *poimage = NULL ; #ifdef TRACE_CONVERT_IMAGE if( Xw_get_trace() ) { printf(" Xw_convert_image.TrueToPseudo()\n") ; } #endif ipad = piimage->bytes_per_line - piimage->width * piimage->bits_per_pixel/8 ; pidata.cdata = (unsigned char*)piimage->data + piimage->xoffset; sred = sgreen = sblue = 0 ; cmask = piimage->red_mask ; while ( !(cmask & 1) ) { cmask >>= 1 ; sred++ ; } cmask = piimage->green_mask ; while ( !(cmask & 1) ) { cmask >>= 1 ; sgreen++ ; } cmask = piimage->blue_mask ; while ( !(cmask & 1) ) { cmask >>= 1 ; sblue++ ; } CREATE_IMAGE("ConvertTrueToPseudo",podata.cdata,1) switch (piimage->bits_per_pixel) { case 8 : COPY_TRUE_TO_PSEUDO("ConvertTrueToPseudo",pidata.cdata,podata.cdata); break; case 16 : COPY_TRUE_TO_PSEUDO("ConvertTrueToPseudo",pidata.sdata,podata.cdata); break; case 32 : COPY_TRUE_TO_PSEUDO("ConvertTrueToPseudo",pidata.idata,podata.cdata); break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertTrueToPseudo",&piimage->bits_per_pixel); } return (poimage) ; } #ifdef XW_PROTOTYPE static XImage* ConvertPseudoToTrue(XW_EXT_WINDOW *pwindow,XImage *piimage,XColor *pcolors,int ncolors) #else static XImage* ConvertPseudoToTrue(pwindow,piimage,pcolors,ncolors) XW_EXT_WINDOW *pwindow ; XImage *piimage ; XColor *pcolors; int ncolors; #endif /*XW_PROTOTYPE*/ /* Convert PseudoColor to TrueColor Image */ { unsigned long ipixel,opixel ; unsigned long lipixel = 0xFFFFFFFF ; unsigned long mapping[MAXCOLOR]; int i,j,ipad,isapproximate ; float red,green,blue ; register union { unsigned char *cdata ; unsigned short *sdata ; unsigned int *idata ; } pidata,podata; register int x,y; XImage *poimage = NULL ; #ifdef TRACE_CONVERT_IMAGE if( Xw_get_trace() ) { printf(" Xw_convert_image.PseudoToTrue()\n") ; } #endif for( i=0 ; ibytes_per_line - piimage->width * piimage->bits_per_pixel/8 ; pidata.cdata = (unsigned char*)piimage->data + piimage->xoffset; switch (_DEPTH) { case 4 : case 8 : CREATE_IMAGE("ConvertPseudoToTrue",podata.cdata,1) COPY_PSEUDO_TO_TRUE("ConvertPseudoToTrue",pidata.cdata,podata.cdata); break; case 12 : CREATE_IMAGE("ConvertPseudoToTrue",podata.cdata,2) COPY_PSEUDO_TO_TRUE("ConvertPseudoToTrue",pidata.cdata,podata.sdata); break; case 24 : CREATE_IMAGE("ConvertPseudoToTrue",podata.cdata,4) COPY_PSEUDO_TO_TRUE("ConvertPseudoToTrue",pidata.cdata,podata.idata); break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertPseudoToTrue",&_DEPTH); } return (poimage) ; } #ifdef XW_PROTOTYPE static XImage* ConvertPseudoToPseudo(XW_EXT_WINDOW *pwindow,XImage *piimage,XColor *pcolors,int ncolors) #else static XImage* ConvertPseudoToPseudo(pwindow,piimage,pcolors,ncolors) XW_EXT_WINDOW *pwindow ; XImage *piimage ; XColor *pcolors; int ncolors; #endif /*XW_PROTOTYPE*/ /* Convert PseudoColor to PseudoColor Image */ { unsigned long ipixel,opixel ; unsigned long lipixel = 0xFFFFFFFF ; unsigned long mapping[MAXCOLOR]; int i,j,ipad,isapproximate ; float red,green,blue ; register union { unsigned char *cdata ; unsigned short *sdata ; unsigned int *idata ; } pidata,podata; register int x,y; XImage *poimage = NULL ; #ifdef TRACE_CONVERT_IMAGE if( Xw_get_trace() ) { printf(" Xw_convert_image.PseudoToPseudo()\n") ; } #endif for( i=0 ; ibytes_per_line - piimage->width * piimage->bits_per_pixel/8 ; pidata.cdata = (unsigned char*)piimage->data + piimage->xoffset; switch (_DEPTH) { case 4 : case 8 : CREATE_IMAGE("ConvertPseudoToPseudo",podata.cdata,1) COPY_PSEUDO_TO_PSEUDO("ConvertPseudoToPseudo",pidata.cdata,podata.cdata); break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertPseudoToPseudo",&_DEPTH); } return (poimage) ; } #ifdef XW_PROTOTYPE static XImage* ConvertTrueToTrue(XW_EXT_WINDOW *pwindow,XImage *piimage) #else static XImage* ConvertTrueToTrue(pwindow,piimage) XW_EXT_WINDOW *pwindow ; XImage *piimage ; #endif /*XW_PROTOTYPE*/ /* Convert TrueColor to TrueColor Image */ { unsigned long ipixel,opixel,cmask ; unsigned long lipixel = 0xFFFFFFFF ; //int i,j,ipad,isapproximate ; int ipad,isapproximate ; int sred,sgreen,sblue ; float red,green,blue ; register union { unsigned char *cdata ; unsigned short *sdata ; unsigned int *idata ; } pidata,podata; register int x,y; XImage *poimage = NULL ; #ifdef TRACE_CONVERT_IMAGE if( Xw_get_trace() ) { printf(" Xw_convert_image.TrueToTrue()\n") ; } #endif if( (_DEPTH == piimage->depth) && (_VISUAL->red_mask == piimage->red_mask) && (_VISUAL->green_mask == piimage->green_mask) && (_VISUAL->blue_mask == piimage->blue_mask) ) return piimage; ipad = piimage->bytes_per_line - piimage->width * piimage->bits_per_pixel/8 ; pidata.cdata = (unsigned char*)piimage->data + piimage->xoffset; sred = sgreen = sblue = 0 ; cmask = piimage->red_mask ; while ( !(cmask & 1) ) { cmask >>= 1 ; sred++ ; } cmask = piimage->green_mask ; while ( !(cmask & 1) ) { cmask >>= 1 ; sgreen++ ; } cmask = piimage->blue_mask ; while ( !(cmask & 1) ) { cmask >>= 1 ; sblue++ ; } switch (_DEPTH) { case 4 : case 8 : CREATE_IMAGE("ConvertTrueToTrue",podata.cdata,1) switch (piimage->bits_per_pixel) { case 8 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.cdata,podata.cdata); break; case 16 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.sdata,podata.cdata); break; case 32 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.idata,podata.cdata); break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertTrueToTrue",&piimage->bits_per_pixel); } break; case 12 : CREATE_IMAGE("ConvertTrueToTrue",podata.cdata,2) switch (piimage->bits_per_pixel) { case 8 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.cdata,podata.sdata); break; case 16 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.sdata,podata.sdata); break; case 32 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.idata,podata.sdata); break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertTrueToTrue",&piimage->bits_per_pixel); } break; case 24 : CREATE_IMAGE("ConvertTrueToTrue",podata.cdata,4) switch (piimage->bits_per_pixel) { case 8 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.cdata,podata.idata); break; case 16 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.sdata,podata.idata); break; case 32 : COPY_TRUE_TO_TRUE("ConvertTrueToTrue",pidata.idata,podata.idata); break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertTrueToTrue",&piimage->bits_per_pixel); } break; default: /*ERROR*Unimplemented Image Visual depth*/ Xw_set_error(64,"ConvertTrueToTrue",&_DEPTH); } return (poimage) ; }