 /* SD_BufferSubs.c
    - Functions for handling external drivers -
    (c) 1990-94 by Andreas R. Kleinert
    Last changes : 30.10.1994
 */

#include "svoperator.h"

#include <proto/superview.h>


/* *************************************************** */
/* *						     * */
/* * SVP_SVP_DoOperation :                           * */
/* *						     * */
/* *************************************************** */

void SVLI_256ToGrayScales(struct SV_GfxBuffer *gfxb);
void SVLI_24ToGrayScales(UBYTE *source, UBYTE *dest, UBYTE *color, ULONG width, ULONG height);

ULONG __saveds __asm SVP_DoOperation(  register __a1 struct SVOperatorHandle  *SVOperatorHandle_a1,
                                       register __a2 struct SV_GfxBuffer      *source,
                                       register __a3 struct SV_GfxBuffer     **dest,
                                       register __d1 APTR                      future)
{
 struct SVOperatorHandle *SVOperatorHandle = SVOperatorHandle_a1;
 ULONG retval = SVERR_NO_ERROR;

 struct SV_GfxBuffer *newsource;

 if( (!source) || (!dest) || (!SVOperatorHandle) ) return(SVERR_ILLEGAL_ACCESS);

 SVOperatorHandle->ah_ramhandle = SVSUP_GetMemList();
 if(!SVOperatorHandle->ah_ramhandle) return(SVERR_NO_MEMORY);

 if(source->svgfx_BufferType > SVGFX_BUFFERTYPE_ONEPLANE) return(SVERR_ACTION_NOT_SUPPORTED);

 if(source->svgfx_BufferType != SVGFX_BUFFERTYPE_ONEPLANE)
  {
   if(source->svgfx_BufferType == SVGFX_BUFFERTYPE_BITPLANE)
    {
     retval = SVSUP_BitPlaneToOnePlane8(source, &newsource);

     if(newsource)
      {
       SVSUP_AddMemEntry(SVOperatorHandle->ah_ramhandle, newsource);

       if((newsource)->svgfx_Buffer) SVSUP_AddMemEntry(SVOperatorHandle->ah_ramhandle, (newsource)->svgfx_Buffer);

      }else retval = SVERR_NO_MEMORY;

    }else retval = SVERR_UNKNOWN_PARAMETERS;

  }else newsource = source;

 if(retval) return(retval);

 *dest = SVSUP_AllocMemEntry(SVOperatorHandle->ah_ramhandle, sizeof(struct SV_GfxBuffer), MEMF_CLEAR|MEMF_PUBLIC);
 if(*dest)
  {
   CopyMem(newsource, *dest, sizeof(struct SV_GfxBuffer));

   if(source->svgfx_ColorDepth == 24)
    {
     (*dest)->svgfx_BufferSize = source->svgfx_Width * source->svgfx_Height;
     (*dest)->svgfx_ColorDepth = 8;
     (*dest)->svgfx_PixelBits  = 8;
    }

   if((*dest)->svgfx_Buffer = SVSUP_AllocMemEntry(SVOperatorHandle->ah_ramhandle, (*dest)->svgfx_BufferSize, MEMF_CLEAR|MEMF_PUBLIC))
    {
     CopyMem(newsource->svgfx_Buffer, (*dest)->svgfx_Buffer, (*dest)->svgfx_BufferSize);

     if(source->svgfx_ColorDepth == 24) SVLI_24ToGrayScales(source->svgfx_Buffer, (*dest)->svgfx_Buffer, (*dest)->svgfx_Colors, source->svgfx_Width, source->svgfx_Height);
      else                              SVLI_256ToGrayScales(*dest);
    }else
    {
     *dest = N;
     retval = SVERR_NO_MEMORY;
    }

  }else retval = SVERR_NO_MEMORY;

 return(retval);
}

void SVLI_256ToGrayScales(struct SV_GfxBuffer *gfxb)
{
 ULONG i, colors, grey;

 colors = ColorAcc(gfxb->svgfx_ColorDepth);

 for(i=0; i<colors; i++)
  {
   grey = (gfxb->svgfx_Colors[i][0] * 30 + gfxb->svgfx_Colors[i][1] * 59 + gfxb->svgfx_Colors[i][2] * 11) / 100;

   gfxb->svgfx_Colors[i][0] = (gfxb->svgfx_Colors[i][1] = (gfxb->svgfx_Colors[i][2] = (UBYTE) grey) );
  }
}

void SVLI_24ToGrayScales(UBYTE *source, UBYTE *dest, UBYTE *color, ULONG width, ULONG height)
{
 ULONG i, j;

 for(i=0; i<255; i++)
  {
   *color++ = i;
   *color++ = i;
   *color++ = i;
  }

 for(i=0; i<height; i++)
  {
   for(j=0; j<width; j++) *dest++ = ( (*source++ * 30) + (*source++ * 59) + (*source++ * 11) ) / 100;
  }
}
