/********************************************************************************************************/
/*                                                                                                      */
/*          File LOadBmp                                                                                */
/*                                                                                                      */
/*   Chargement des BMP                                                                                 */
/*                                                                                                      */
/********************************************************************************************************/


//
// Modifications History
//
//$ LB (13/06/2002) : changed objbitmap access, according to the new objbitmap structure
//
//$LB (16/12/2002) : 16bits to 24bits
//


#include "x/Version.h"
#include "x/scolplugin.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "objstr.h"
//#include "../kernel/mainscol.h"

#include "objects/bitmap.h"
#include "loadbmp.h"
#include "colors.h"



/*****************************************************************************************************/
/*                                                                                                   */
/*  int DistanceColor ( int r1 , int g1 , int b1 , int r2 , int g2 , int b2 ) ;                      */
/*                                                                                                   */
/*  Cette procedure calcule la distance entre deux couleurs                                          */
/*                                                                                                   */
/*****************************************************************************************************/
int DistanceColor(int r1, int g1, int b1, int r2, int g2, int b2)
{
		int	rp,gp,bp,d;

 	rp=r2-r1;
	gp=g2-g1;
	bp=b2-b1;

	d=rp*rp+gp*gp+bp*bp;

	return d;
}	

/******************************************************************************************************/
/*                                                                                                    */
/*  int ProjectionColor ( int r1 , int g1 , int b1 , PtrPalette P ) ;                                 */
/*                                                                                                    */
/*  Cette fonction renvoi la couleur la plus proche de celle passée en parametre dans la palette      */
/*  Parametre et renvoi son idnex dans la palette                                                     */
/*                                                                                                    */
/******************************************************************************************************/

int ProjectionColor(int r, int g, int b, PtrPalette P )
{
		int	i,n;
		int	d,mind;

        for(i=0;i<256;i++)
		{
			d=DistanceColor (r,g,b,GET_RED(P,i),GET_GREEN(P,i),GET_BLUE(P,i));
			if ((i==0)||(d<mind))
				{
					mind=d;
					n=i;
				}	
		}
	return n;
}

/***********************************************************************************************************/
/*                                                                                                         */
/*  int ProjectionPalette ( PtrPalette D , PtrPalette S , char * Conversion ) ;                            */
/*                                                                                                         */
/*  cette fonction calcule la table de conversion entre deux palette                                       */
/*                                                                                                         */
/***********************************************************************************************************/

void ProjectionPalette ( PtrPalette D , PtrPalette S , int * Conversion ) 
{
    int i ;
    for ( i = 0 ; i < 256 ; i ++ )  
        Conversion [ i ] = ProjectionColor ( GET_RED(S,i) , GET_GREEN(S,i) , GET_BLUE(S,i) , D ) ;
}









//$LB
/////////////////////////////////////////////////////////


int WriteInt1 ( FILE * F , unsigned char *I) 
{
    return fwrite ( (void*)I , 1 , 1 , F);
}

int WriteInt2 ( FILE * F , unsigned short int *I )
{
    unsigned char a , b ;

	a = (*I) &0xFF;
	b = ((*I)>>8) &0xFF;

    fwrite ((void*)&a , 1 , 1 , F );
    fwrite ((void*)&b , 1 , 1 , F );

    return 1;
}



int WriteInt4 ( FILE * F , unsigned long int* I ) 
{
    unsigned char a , b , c , d ;

    a  = (unsigned char)((*I) &0xFF); b = (unsigned char)(((*I)>>8) &0xFF); c = (unsigned char)(((*I)>>16) &0xFF); d = (unsigned char)(((*I)>>24) &0xFF);

    fwrite ( (void*)&a , 1 , 1 , F );
    fwrite ( (void*)&b , 1 , 1 , F );
    fwrite ( (void*)&c , 1 , 1 , F );
    fwrite ( (void*)&d , 1 , 1 , F );

    return 1 ;
}


/***********************************************************************************************************/
/*                                                                                                         */
/*   Sauvegarde d'un fichier BMP  : fun [ObjBitmap W] I                                                    */
/*                                                                                                         */
/***********************************************************************************************************/

int _SAVEbitmap (mmachine m)
{
	char* filename;
	FILE* F; 
	OBJBITMAP_BUFFER buf;
	PtrObjVoid OB;
    PtrObjBitmap B;
    unsigned short int Is;
    unsigned long int Il;
	unsigned char rgb ;
	int i , j , offset, delta, BPLReste;
    
    
//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SAVEbitmap");
#endif
//***********************************


  if ((MMget(m, 0)==NIL) || (MMget(m, 1)==NIL))
  {
	  MMpull(m);
	  MMset(m, 0, NIL);
	  return 0;
  }


  // opening F
  filename = MMstartstr(m, MMpull(m)>>1);

  if ((F = fopen(filename, "wb")) == NULL)
  {
	  MMechostr(MSKDEBUG,"_SAVEbitmap : unable to create file %s\n",filename);
	  MMpull(m);
      return MMpush(m,NIL);
  }

  // get the bitmap
  OB = (PtrObjVoid) MMstart (m, MMget(m,0)>>1);
  if ( OB->Type != OBJ_TYPE_BITMAP << 1 )
  {
	  MMechostr(MSKDEBUG,"_SAVEbitmap : something wrong with the bitmap buffer\n");
      MMset(m,0,NIL);
	  return MERRMEM;
  }

  B = ( PtrObjBitmap ) MMstart(m,OB->Buffer>>1);
  buf = (OBJBITMAP_BUFFER)B->bits;


  // star wrting data
  Is = FILE_TYPE_BMP; WriteInt2 (F, &Is);
  Il = (B->BPL * B->TailleH) + sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPINFOHEADER ); WriteInt4 ( F , &Il) ; 
  Is = 0; WriteInt2 ( F , &Is) ; 
  Is = 0; WriteInt2 ( F , &Is) ; 

  Il = sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPINFOHEADER );   WriteInt4 ( F , &Il) ;


  Il = sizeof ( BITMAPINFOHEADER );   WriteInt4 ( F , &Il) ;
  Il = B->TailleW; WriteInt4 ( F , &Il) ;
  Il = B->TailleH; WriteInt4 ( F , &Il) ;
  Is = 1; WriteInt2 ( F , &Is) ;
  Is = 24; WriteInt2 ( F , &Is);
  Il = BI_RGB; WriteInt4 ( F , &Il) ;
  Il = 0; WriteInt4 ( F , &Il) ;

  Il = 0; WriteInt4 ( F , &Il) ;
  Il = 0; WriteInt4 ( F , &Il) ;

  Il = 0; WriteInt4 ( F , &Il) ;
  Il = 0; WriteInt4 ( F , &Il) ;

  
        if ( B->TailleH < 0 )
        {            
            offset = 0 ;
			//$LB
            delta =  B->BPL  - (B->TailleW*3) ;
        } else
        {            
			//$LB
            delta = - B->BPL - (B->TailleW*3) ;
            offset = ( B->BPL * B->TailleH - B->BPL ) ;
        }

            BPLReste = (B->BPL - ( B->TailleW * 3 )) ; 
			
            for ( j = 0 ; j < B->TailleH ; j ++ )
            {
      
                for ( i = 0 ; i < B->TailleW ; i ++ )
                {            
					rgb = B->bits[offset++]; WriteInt1 ( F , &rgb) ;
					rgb = B->bits[offset++]; WriteInt1 ( F , &rgb) ;
					rgb = B->bits[offset++]; WriteInt1 ( F , &rgb) ;
                }
                
				offset+=delta;
                for ( i = 0 ; i < BPLReste ; i ++ ){ WriteInt1 ( F , &rgb ) ;}
            }
       
   

    fclose ( F ) ;
	return 0;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SAVEbitmap end");
#endif
//***********************************

} ;

//////////////////////////////////////////////////////////////










/***********************************************************************************************************/
/*                                                                                                         */
/* fonctions de lecture d'int et de long int pour les machines a format de int different                   */
/*                                                                                                         */
/***********************************************************************************************************/

char ReadInt1 ( FILE * F , unsigned char * I ) 
{
    unsigned char a ;

    if ( !fread ( &a , 1 , 1 , F )) return 0 ;
    *I = a ;
    return 1 ;
}

char ReadInt2 ( FILE * F , unsigned short int * I )
{
    unsigned char a , b ;

    if ( !fread ( &a , 1 , 1 , F )) return 0 ;
    if ( !fread ( &b , 1 , 1 , F )) return 0 ;

    *I = a + ( b << 8 ) ;
    return 1 ;
}

char ReadInt4 ( FILE * F , unsigned long int * I ) 
{
    unsigned char a , b , c , d ;

    if ( !fread ( &a , 1 , 1 , F )) return 0 ;
    if ( !fread ( &b , 1 , 1 , F )) return 0 ;
    if ( !fread ( &c , 1 , 1 , F )) return 0 ;
    if ( !fread ( &d , 1 , 1 , F )) return 0 ;
    *I = a + ( b << 8 ) + ( c << 16 ) + ( d << 24 ) ;
    return 1 ;
}

/***********************************************************************************************************/
/*                                                                                                         */
/*   Chargement d'un fichier BMP                                                                           */
/*                                                                                                         */
/***********************************************************************************************************/

void LoadBMP ( char * filename , PtrObjBitmap Bitmap , char BitmapCible )
{
    BmpHeader BFH ;
    BmpInfo BI ;
    FILE * F ;   
    unsigned short int A ;
    unsigned long int B ;    
    int i , j , offset , TailleH ;
    OBJBITMAP_BUFFER B24 ;
    unsigned char rgb ;
    int delta , BPLReste;
    struct Palette Pal ;
    OBJBITMAP_BUFFER B8 ;
	unsigned char r , g , b;
    
 
/****************************/
 #ifdef DEBUG_LIB2DOS
   MMechostr (0 , "\nLoadBMP"); 
#endif
/****************************/



    F = fopen ( filename , "rb" ) ;
    if ( ! F ) return ;
    ReadInt2 ( F , & A ) ; BFH.Type = A ;
    ReadInt4 ( F , & B ) ; BFH.Taille = B ;
    ReadInt2 ( F , & A ) ; BFH.Reserve1 = A ;
    ReadInt2 ( F , & A ) ; BFH.Reserve2 = A ;
    ReadInt4 ( F , & B ) ; BFH.Flags = B ;
    if ( BFH.Type != FILE_TYPE_BMP )
    {
        MMechostr ( 1 , "File \"%s\" isn't a BMP file : %d is found as file type.\n" , filename, BFH.Type ) ;
        fclose ( F ) ;
        return ;
    }

    ReadInt4 ( F , &B ) ; BI.FTaille = B ;
    ReadInt4 ( F , &B ) ; BI.TailleW = B ;
    ReadInt4 ( F , &B ) ; BI.TailleH = B ;
    ReadInt2 ( F , &A ) ; BI.Plans = A ; 
    ReadInt2 ( F , &A ) ; BI.BitCount = A ;
    ReadInt4 ( F , &B ) ; BI.Compression = B ;
    ReadInt4 ( F , &B ) ; BI.Taille = B ;
    ReadInt4 ( F , &B ) ; BI.HResolution = B ;
    ReadInt4 ( F , &B ) ; BI.VResolution = B ; 
    ReadInt4 ( F , &B ) ; BI.Couleurs = B ;
    if (( BI.BitCount == 8 ) && ( BI.Couleurs == 0 )) BI.Couleurs = 256 ;
    ReadInt4 ( F , &B ) ; BI.ICouleurs = B ;
  
    if ( BI.Taille != 0 ) BI.BPL = BI.Taille / BI.TailleH ;
    else 
    {
        if ( BI.BitCount == 8 ) BI.BPL = ( BFH.Taille - sizeof ( BITMAPFILEHEADER )
                        - sizeof ( BITMAPINFOHEADER ) - (BI.Couleurs<<2) ) / BI.TailleH ;
        else BI.BPL =  ( BFH.Taille - sizeof ( BITMAPFILEHEADER )
                        - sizeof ( BITMAPINFOHEADER )) / BI.TailleH ;
    }


    /************************** DEBUG INFO *********************************/
    #ifdef DEBUG_LIB2DOS
        
        MMechostr ( 1 , "File Size %d \n" , BFH.Taille ) ;
        MMechostr ( 1 , "Structure Size %d BIH %d BCH %d\n",BI.FTaille,sizeof (BITMAPINFOHEADER),sizeof(BITMAPCOREHEADER));
        MMechostr ( 1 , "BMP Taille %dx%d Plans %d BitCount %d Compression %d Taille %d\n" ,
             BI.TailleW , BI.TailleH , BI.Plans , BI.BitCount , BI.Compression , BI.Taille ) ;
        MMechostr ( 1 , "Couleurs %d Couleur importantes %d\n" , BI.Couleurs , BI.ICouleurs ) ;
        MMechostr ( 1 , "Structure taille %d Offset %d\n" , BI.FTaille , BFH.Flags ) ;
        MMechostr ( 1 , "Compression %d BPL %d\n" , BI.Compression , BI.BPL) ;
    #endif
    /************************************************************************/
    /***** read couleurs *******************/
    if ( BI.BitCount == 8 )
    {
        #ifdef DEBUG_LIB2DOS
            MMechostr ( 1 , "Chargement des couleurs\n" ) ;
        #endif
        fseek ( F , 54 , SEEK_SET ) ;
        for ( i = 0 ; i < BI.Couleurs ; i ++ )
        {
            ReadInt1 ( F , &rgb ) ; GET_BLUE((&Pal),i) = rgb ;
            ReadInt1 ( F , &rgb ) ; GET_GREEN((&Pal),i) = rgb ;
            ReadInt1 ( F , &rgb ) ; GET_RED((&Pal),i) = rgb ;
            ReadInt1 ( F , &rgb ) ;
        }
        
    }
    /********************* read bitmap ************************/
    Bitmap->TailleW = BI.TailleW ;
    Bitmap->TailleH = BI.TailleH ;
    if ( BitmapCible == 24 ) Bitmap->Couleurs = 0 ;
    else Bitmap->Couleurs = 256 ;
    Bitmap->BPP = BitmapCible ;
	Bitmap->BytesPP = Bitmap->BPP>>3;
    Bitmap->handler = ObjBitmap_New ( Bitmap , &Pal ) ;
    if ((Bitmap->bits == NULL )||(Bitmap->handler == 0))
    {
        MMechostr ( 1 , "Loading Bitmap failed.\n" ) ;
        fclose ( F ) ;
        return ;
    }
    if ( BI.BitCount == 8 ) SetBitmapPalette ( Bitmap , &Pal ) ;
  
    
    if ( BI.Compression != 0 )
    {
        MMechostr ( 1 , "Unsupported type of BMP compression :%d" , BI.Compression ) ;
        fclose ( F ) ;
        return ;
    }
    fseek ( F , BFH.Flags , SEEK_SET ) ;

    /*****************************************************************************/
    /*           Construction sur un bitmap 24 bits                              */
    /*****************************************************************************/
    #ifdef DEBUG_LIB2DOS
        MMechostr ( 1 , "Chargement de l'image\n" ) ;
    #endif
    if ( BitmapCible == 24 )
    {
       
        B24 = Bitmap->bits;
        
        if ( BI.TailleH < 0 )
        {            
            offset = 0 ;
			//$LB
            delta =  Bitmap->BPL  - (Bitmap->TailleW*3) ;
            TailleH = - BI.TailleH ;
        } else
        {            
			//$LB
            delta = - Bitmap->BPL - (Bitmap->TailleW*3) ;
            offset = ( Bitmap->BPL * Bitmap->TailleH - Bitmap->BPL ) ;
            TailleH = BI.TailleH ;
        }
        #ifdef DEBUG_LIB2DOS
            MMechostr(MSKDEBUG,"Delta = %d offset %d TailleH %d\n",delta,offset,TailleH);
        #endif


        if ( BI.BitCount == 8  )    /* cas ou le fichier BMP est un fichier 256 couleurs */
        {
          
            BPLReste = BI.BPL - BI.TailleW ;
            
            for ( j = 0 ; j < TailleH ; j ++ )
            {
                for ( i = 0 ; i < BI.TailleW ; i ++ )
                {
                        ReadInt1 ( F , &rgb ) ;
                        B24 [ offset ++ ] = GET_BLUE((&Pal),rgb);
						B24 [ offset ++ ] = GET_GREEN((&Pal),rgb);
                        B24 [ offset ++ ] = GET_RED((&Pal),rgb);
                }
                offset += delta ;
                for ( i = 0 ; i < BPLReste ; i ++ ) ReadInt1 ( F , &rgb ) ;
            }
        }
        else if ( BI.BitCount == 16 )  /* cas ou le fichier BMP est un fichier 16bits colors */
        {
            BPLReste = (BI.BPL - ( BI.TailleW * 2 )) ;
            for ( j = 0 ; j < TailleH ; j ++ ) 
            {
                for ( i = 0 ; i < BI.TailleW ; i ++ )
                {
                    ReadInt2 ( F , &A ) ;
					//$LB
					_COLOR_I16_TO_BGR (A, &b, &g, &r); 
                    B24 [ offset ++ ] = b;
					B24 [ offset ++ ] = g;
					B24 [ offset ++ ] = r;
                } 
                offset += delta ;
                for (i = 0 ; i  < BPLReste ; i ++ ) ReadInt1 ( F , &rgb ) ;
            }
        }
        else if ( BI.BitCount == 24 ) /* cas ou le fichier BMP est un fichier 24 bits colors */
        {
            BPLReste = (BI.BPL - ( BI.TailleW * 3 )) ;     
            for ( j = 0 ; j < TailleH ; j ++ )
            {
      
                for ( i = 0 ; i < BI.TailleW ; i ++ )
                {                    
                    ReadInt1 ( F , &b);
                    ReadInt1 ( F , &g);
                    ReadInt1 ( F , &r); 
                    B24 [ offset ++ ] = b;
					B24 [ offset ++ ] = g;
					B24 [ offset ++ ] = r;
					
                }
                offset += delta ;
                for ( i = 0 ; i < BPLReste ; i ++ ) ReadInt1 ( F , &rgb ) ;
            }
        }
        else MMechostr ( 1 , "Unsupported type of BMP Plans count :%d\n" , BI.Plans ) ;
    }




    /****************************************************************************************/
    /*    construction sur un bitmap 8 bits                                                 */
    /****************************************************************************************/
    if ( BitmapCible == 8 )
    {
        #ifdef DEBUG_LIB2DOS
            MMechostr ( 1 , " TailleW %d %d\n" , BI.TailleW , Bitmap->TailleW ) ;
        #endif
        B8 = (OBJBITMAP_BUFFER) Bitmap->bits;
        BPLReste = BI.BPL - BI.TailleW ;
        if ( BI.TailleH < 0 )
        {
            offset = 0 ;
            delta = Bitmap->BPL - Bitmap->TailleW ;            
            TailleH = - BI.TailleH ;
        }
        else 
        {
            offset = Bitmap->BPL * BI.TailleH - Bitmap->BPL ;
            delta = - Bitmap->BPL - Bitmap->TailleW ;
            TailleH = BI.TailleH ;
        }
        if ( BI.BitCount == 8 )
        for ( j = 0 ; j < TailleH ; j ++ )
        {
            for ( i = 0 ; i < BI.TailleW ; i ++ )
            {
                ReadInt1 ( F , &rgb ) ;
                B8 [ offset ++ ] = rgb ;
            }
            for ( i = 0 ; i < BPLReste ; i ++ ) ReadInt1 ( F , &rgb ) ;
            offset += delta ;
        } 
        else if ( BI.BitCount == 16 )
        for ( j = 0 ; j < TailleH ; j ++ )
        {
            for ( i = 0 ; i < BI.TailleW ; i ++ )
            {
                ReadInt2 ( F , &A ) ;
                b = ( A & 63 ) << 3 ;
                g = (( A >> 5 ) & 63 ) << 3 ;
                r = (( A >> 10 ) & 63 ) << 3 ;
                B8 [ offset ++ ] = ProjectionColor ( r , g , b , &Pal ) ;
            }
            offset += delta ;
        } else if ( BI.BitCount == 24 )
        for ( j = 0 ; j < TailleH ; j ++ )
        {
            for ( i = 0 ; i < BI.TailleW ; i ++ )
            {
                ReadInt1 ( F , &rgb ) ; b = rgb ;
                ReadInt1 ( F , &rgb ) ; g = rgb ;
                ReadInt1 ( F , &rgb ) ; r = rgb ;
                B8 [ offset ++ ] = ProjectionColor ( r , g , b , &Pal ) ;
            }
            offset += delta ;
        }
    }
    #ifdef DEBUG_LIB2DOS
        MMechostr ( 1 , "Chargement termine\n" ) ;
    #endif

    fclose ( F ) ;

/****************************/
 #ifdef DEBUG_LIB2DOS
   MMechostr (0 , "\nLoadBMP end : %d   BPP %d  BytesPP %d    BPL %d    w %d  h %d", Bitmap->handler, Bitmap->BPP, Bitmap->BytesPP, Bitmap->BPL, Bitmap->TailleW, Bitmap->TailleH); 
#endif
/****************************/
} ;


/*********************************************************************************************************/
/*                                                                                                       */
/*  void ClipBlit ( int dtaillew , int dtailleh , int staillew , int stailleh ,                          */
/* int dposx , int dposy , int sposx , int sposy , int taillew , int tailleh ) ;                         */
/*                                                                                                       */
/*  verifie que les coordonnees sont bonne, et effectue le clipping si necessaire                        */
/*                                                                                                       */
/*********************************************************************************************************/


int ClipBlit ( int dtaillew , int dtailleh , int staillew , int stailleh ,
                int *dposx , int *dposy , int *sposx , int *sposy , int *taillew , int *tailleh ) 
{       

//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nClipBlit");
#endif
//***********************************

    /* step 1 verification de dposx */
    if ( *dposx < 0 )
    {
        *sposx -= *dposx ;
        *taillew += *dposx ;
        *dposx = 0 ;
    } else if ( *dposx >= dtaillew ) return 0 ;
   

    /* step 2 verification de dposy */
    if ( *dposy < 0 )
    {
        *sposy -= *dposy ;
        *tailleh += *dposy ;
        *dposy = 0 ;
    } else if ( *dposy >= dtailleh ) return 0 ;

    /* step 3 verification de sposx */
    if ( *sposx < 0 )
    {
        *taillew += *sposx ;
        *dposx -= *sposx;
        *sposx = 0 ;
       
    } else if ( *sposx >= staillew ) return 0 ;

    /* step 4 verification de sposy */
    if ( *sposy < 0 )
    {
        *tailleh  += *sposy ;
        *dposy -= *sposy;
        *sposy = 0 ;
    } else if ( *sposy >= stailleh ) return 0 ;

    /* step 4 verification de taillew */
    if ( *taillew < 0 ) return 0 ;
    if ( *taillew + *sposx >= staillew )
    {   
         *taillew -=  ( *taillew + *sposx ) - staillew ;     
         if ( * taillew < 0 ) return 0 ;
    }
    if ( *taillew + *dposx >= dtaillew )
    {
        *taillew -= ( *taillew + *dposx ) - dtaillew ;
        if ( * taillew  < 0 ) return 0 ;
    }

    /* step 5 verification de tailleh */
    if ( *tailleh < 0 ) return 0 ;
    if ( *tailleh + *sposy >= stailleh )
    {
        *tailleh -= ( *tailleh + *sposy ) - stailleh ;
        if ( *tailleh < 0 ) return 0 ;
    }
    if ( *tailleh + *dposy >= dtailleh ) 
    {
        *tailleh -= ( *tailleh + *dposy ) -dtailleh ;
        if ( *tailleh < 0 ) return 0 ;
    }


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nClipBlit end");
#endif
//***********************************

    return 1 ;    
}


/***************************************************************************************************/
/*                                                                                                 */
/*  int ClipStretch ( int dtaillew , int dtailleh , int staillew , int staillh ,                   */
/*                 int *dposx1 , int *dposy1 , int *dposx2 , int *dposy2 ,                         */
/*                 int *sposx1 , int *sposy1 , *int sposx2 , int *sposy2 ) ;                       */
/*                                                                                                 */
/***************************************************************************************************/

int ClipStretch ( int dtaillew , int dtailleh , int staillew , int stailleh ,
                 int *dposx1 , int *dposy1 , int *dposx2 , int *dposy2 , 
                 int *sposx1 , int *sposy1 , int *sposx2 , int *sposy2 ) 

{
  
  //***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nClipStretch");
#endif
//***********************************

    /* test sur dposx1 */
    if ( *dposx1 >= dtaillew ) return 0 ;
    if ( *dposx1 < 0 )
    {
        *sposx1 = ((( - *dposx1 ) * ( staillew )) / ( dtaillew )) + ( *sposx1 ) ;
        *dposx1 = 0 ;
    } if ( *dposx1 > *dposx2 ) return 0 ;

    /* test sur dposy1 */
    if ( *dposy1 >= dtailleh ) return 0 ;
    if ( *dposy1 < 0 )
    {   
        *sposy1 = ((( - *dposy1 ) * ( stailleh )) / ( dtailleh )) + ( *sposy1 ) ;
        *dposy1 = 0 ;
    } else if ( *dposy1 > *dposy2 ) return 0 ;

    /* test sur dposx2 */
    if ( *dposx2 < 0 ) return 0 ;
    if ( *dposx2 >= dtaillew ) 
    {
        *sposx2 = ((( ( dtaillew-1) - *dposx2 ) * ( staillew )) / ( dtaillew )) + ( *sposx2 ) ;
        *dposx2 = dtaillew - 1 ;
    } if ( *dposx2 < *dposx1 ) return 0 ;

    /* test sur dposy2 */
    if ( *dposy2 < 0 ) return 0 ;
    if ( * dposy2 >= dtailleh ) 
    {
        *sposy2 = (((( dtailleh-1) - *dposy2 ) * ( stailleh )) / ( dtailleh )) + ( *sposy2 ) ;
        *dposy2 = dtailleh - 1 ;
    } if ( *dposy2 < *dposy1 ) return 0 ;

    /* test sur sposx1 */
    if ( *sposx1 >= staillew ) return 0 ;
    if ( *sposx1 < 0 )
    {
        *dposx1 = ((( - *sposx1 ) * ( dtaillew )) / ( staillew )) + ( *dposx1 ) ;
        *sposx1 = 0 ;
    } if ( *sposx1 > *sposx2 ) return 0 ;

    /* test sur sposy1 */
    if ( *sposy1 >= stailleh ) return 0 ;
    if ( *sposy1 < 0 )
    {   
        *dposy1 = ((( - *sposy1 ) * ( dtailleh )) / ( stailleh )) + ( *dposy1 ) ;
        *sposy1 = 0 ;
    } 
    if ( *sposy1 > *sposy2 ) return 0 ;

    /* test sur dposx2 */
    if ( *sposx2 < 0 ) return 0 ;
    if ( *sposx2 >= staillew ) 
    {
        *dposx2 = ((( ( staillew-1) - *sposx2 ) * ( dtaillew )) / ( staillew )) + ( *dposx2 ) ;
        *sposx2 = staillew - 1 ;
    }
    if ( *sposx2 < *sposx1 ) return 0 ;

    /* test sur dposy2 */
    if ( *sposy2 < 0 ) return 0 ;
    if ( * sposy2 >= stailleh ) 
    {
        *dposy2 = (((( stailleh-1) - *sposy2 ) * ( dtailleh )) / ( stailleh )) + ( *dposy2 ) ;
        *sposy2 = stailleh - 1 ;
    } if ( *sposy2 < *sposy1 ) return 0 ;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nClipStretch end");
#endif
//***********************************

    return 1 ;

}

/*********************************************************************************************/
/*                                                                                           */
/*     int ClipSimple (int dtaillew,int dtailleh, int*x, int*y, int*w , int *h);             */
/*                                                                                           */
/*  Effectue un clipping dans un rectangle de dtaillew * dtailleh                            */
/*                                                                                           */
/*********************************************************************************************/

int ClipSimple (int dtaillew,int dtailleh, int*x, int*y, int*w , int *h)
{

//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nClipSimple");
#endif
//***********************************

    if(*x>= dtaillew) return 0;
    if(*x<0) { *w+=*x; *x=0; }
    if(*w<0) return 0;
    if(*x + *w > dtaillew) *w = dtaillew -*x; 

    if(*y>=dtailleh)return 0 ;
    if(*y<0) { *h+=*y; *y=0; }
    if(*h<0)return 0;
    if(*y+*h>dtailleh) *h=dtailleh-*y;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nClipSimple end");
#endif
//***********************************

    return 1;
}

