/*
   Generic format conversion routines for the HERMES library
   Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at)
   This source code is licensed under the GNU LGPL
  
   Please refer to the file COPYING.LIB contained in the distribution for
   licensing conditions
*/

#include "HermConf.h"
#include "HeadC.h"



void ConvertC_Generic32_Generic32(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=READ32(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE32(dest,(r|g|b));
    
      source+=4;
      dest+=4;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic32_Generic24(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  char8 *d_ptr=(char8 *)((int)&s_pixel);
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=READ32(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      s_pixel=(r|g|b);

      *(dest+R_24)=*(d_ptr+R_32);
      *(dest+G_24)=*(d_ptr+G_32);
      *(dest+B_24)=*(d_ptr+B_32);

      source+=4;
      dest+=3;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic32_Generic16(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=READ32(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE16(dest,(short16)(r|g|b));
    
      source+=4;
      dest+=2;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic32_Generic8(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=READ32(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      *(dest)=(char8)(r|g|b);
    
      source+=4;
      dest++;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}





void ConvertC_Generic24_Generic32(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { 
      s_pixel=(((int32)*(source+R_24))<<16)|
              (((int32)*(source+G_24))<<8)|
              ((int32)*(source+B_24));
    
      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE32(dest,(r|g|b));
    
      source+=3;
      dest+=4;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }

}


void ConvertC_Generic24_Generic24(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  char8 *d_ptr=(char8 *)&s_pixel;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { 
      s_pixel=(((int32)*(source+R_24))<<16)|
              (((int32)*(source+G_24))<<8)|
               ((int32)*(source+B_24));
    
      r=((s_pixel<<iface->info.r_left)>>iface->info.r_right)&
        iface->mask_r;
      g=((s_pixel<<iface->info.g_left)>>iface->info.g_right)&
        iface->mask_g;
      b=((s_pixel<<iface->info.b_left)>>iface->info.b_right)&
        iface->mask_b;

      s_pixel=(r|g|b);
    
      *(dest+R_24)=*(d_ptr+R_32);
      *(dest+G_24)=*(d_ptr+G_32);
      *(dest+B_24)=*(d_ptr+B_32);
    
      source+=3;
      dest+=3;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }

}



void ConvertC_Generic24_Generic16(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { 
      s_pixel=(((int32)*(source+R_24))<<16)|
              (((int32)*(source+G_24))<<8)|
               ((int32)*(source+B_24));
    
      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE16(dest,(short16)(r|g|b));
    
      source+=3;
      dest+=2;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic24_Generic8(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=(((int32)*(source+R_24))<<16)|
              (((int32)*(source+G_24))<<8)|
               ((int32)*(source+B_24));

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      *(dest)=(char8)(r|g|b);
    
      source+=3;
      dest++;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}




void ConvertC_Generic16_Generic32(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=(int32)READ16(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE32(dest,(r|g|b));
    
      source+=2;
      dest+=4;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic16_Generic24(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  char8 *d_ptr=(char8 *)((int)&s_pixel);
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=(int32)READ16(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      s_pixel=(r|g|b);

      *(dest+R_24)=*(d_ptr+R_32);
      *(dest+G_24)=*(d_ptr+G_32);
      *(dest+B_24)=*(d_ptr+B_32);

      source+=2;
      dest+=3;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic16_Generic16(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=(int32)READ16(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE16(dest,(short16)(r|g|b));
    
      source+=2;
      dest+=2;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


void ConvertC_Generic16_Generic8(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source=iface->s_pixels,*dest=iface->d_pixels;

  while (iface->s_height--) {
    count=iface->s_width;

    while(count--)
    { s_pixel=(int32)READ16(source);

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      *dest=(char8)(r|g|b);
    
      source+=2;
      dest++;
    }

    source+=iface->s_add;
    dest+=iface->d_add;
  }
}


/* -------------------------------------------------------------------------

                              STRETCH CONVERTERS
   
   ------------------------------------------------------------------------- */


void ConvertC_Generic32_Generic32_S(HermesConverterInterface *iface)
{ int32 s_pixel,r,g,b;
  int count;
  char8 *source,*dest=iface->d_pixels;
  int dy=(iface->s_height<<16)/iface->d_height;
  int dx=(iface->s_width<<16)/iface->d_width;
  int y=0,x,numlines;

  while (iface->d_height--) {
    count=iface->d_width;
    x=0;
    source=iface->s_pixels;

    while(count--)
    { s_pixel=READ32(source+(x>>16));

      r=((s_pixel>>iface->info.r_right)<<iface->info.r_left)&
        iface->mask_r;
      g=((s_pixel>>iface->info.g_right)<<iface->info.g_left)&
        iface->mask_g;
      b=((s_pixel>>iface->info.b_right)<<iface->info.b_left)&
        iface->mask_b;
    
      WRITE32(dest,(r|g|b));
    
      x+=dx;
      dest+=4;
    }
    
    dest+=iface->d_pitch;

    numlines=y;
    y+=dy;
    
    numlines=(y>>16)-(numlines>>16);
    iface->s_pixels+=numlines*iface->s_pitch;
  }
}

