
 /* SV_WriteSubs.c
    - Functions for Writing of UtahRLE Files -
    (c) 1990-95 by Andreas R. Kleinert
    Last changes : 07.10.1995
 */

#include "svobject.h"


ULONG __saveds __asm SVO_Write( register __a1 struct SVObjectHandle *SVObjectHandle_a1);

ULONG __saveds __stdargs SVLI_PackRLE(struct SVObjectHandle *SVObjectHandle, struct rle_hdr *RLEHeader, UBYTE *dptr, ULONG width, ULONG height);


/* *************************************************** */
/* *						     * */
/* * SVO_Write : ...                                 * */
/* *						     * */
/* *************************************************** */

ULONG __saveds __asm SVO_Write( register __a1 struct SVObjectHandle *SVObjectHandle_a1)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;

 ULONG retval = SVERR_NO_ERROR;
 ULONG  width, height;

 struct rle_hdr __aligned RLEHeader;


 if(!SVObjectHandle)                              return(SVERR_NO_HANDLE);
 if(SVObjectHandle->ah_Medium != AKO_MEDIUM_DISK) return(SVERR_ACTION_NOT_SUPPORTED);

 if(!SVObjectHandle->ah_SV_GfxBuffer2)
  {
   if(SVObjectHandle->ah_WriteScreen)
    {
     retval = SVSUP_ScreenToOnePlane8(SVObjectHandle->ah_WriteScreen, &SVObjectHandle->ah_SV_GfxBuffer2);
     if(retval) return(retval);

     if(!SVObjectHandle->ah_SV_GfxBuffer2) return(SVERR_NO_MEMORY);

     /* to free the memory : */

     SVObjectHandle->ah_SV_GfxBuffer = SVObjectHandle->ah_SV_GfxBuffer2;

    }else return(SVERR_ACTION_NOT_SUPPORTED);
  }else
  {
   if(SVObjectHandle->ah_SV_GfxBuffer2->svgfx_BufferType == SVGFX_BUFFERTYPE_BITPLANE)
    {
     retval = SVSUP_BitPlaneToOnePlane8(SVObjectHandle->ah_SV_GfxBuffer2, &SVObjectHandle->ah_SV_GfxBuffer);
     if(retval) return(retval);

     if(!SVObjectHandle->ah_SV_GfxBuffer) return(SVERR_NO_MEMORY);

     /* now set it to make use of it : */

     SVObjectHandle->ah_SV_GfxBuffer2 = SVObjectHandle->ah_SV_GfxBuffer;
    }
  }

 width  = (UWORD) SVObjectHandle->ah_SV_GfxBuffer2->svgfx_Width;
 height = (UWORD) SVObjectHandle->ah_SV_GfxBuffer2->svgfx_Height;

 if(SVObjectHandle->ah_SV_GfxBuffer2->svgfx_BufferType != SVGFX_BUFFERTYPE_ONEPLANE) return(SVERR_ACTION_NOT_SUPPORTED);
 if(SVObjectHandle->ah_SV_GfxBuffer2->svgfx_ColorDepth != 24)                        return(SVERR_ACTION_NOT_SUPPORTED);

 SVObjectHandle->ah_FILE_dest = fopen(SVObjectHandle->ah_WriteName, "wb");
 if(!SVObjectHandle->ah_FILE_dest) return(SVERR_NO_FILE);

 RLEHeader.rle_file = SVObjectHandle->ah_FILE_dest;

 RLEHeader.ncolors    = 3; /* 24 Bit           */
 RLEHeader.alpha      = N; /* no alpha channel */

 RLEHeader.ncmap      = N; /* no ColorMap      */
 RLEHeader.cmap       = N;
 RLEHeader.cmaplen    = N;

 RLE_SET_BIT(RLEHeader, 0); /* R */
 RLE_SET_BIT(RLEHeader, 1); /* G */
 RLE_SET_BIT(RLEHeader, 2); /* B */

 RLEHeader.xmin       = 0;
 RLEHeader.xmax       = width - 1;
 RLEHeader.ymin       = 0;
 RLEHeader.ymax       = height - 1;

 RLEHeader.background = 2;

 rle_put_setup(&RLEHeader);

 retval = SVLI_PackRLE(SVObjectHandle, &RLEHeader, SVObjectHandle->ah_SV_GfxBuffer2->svgfx_Buffer, width, height);


 /* Close files immediately after usage */

 if(SVObjectHandle->ah_filehandle_source) Close(SVObjectHandle->ah_filehandle_source);
 if(SVObjectHandle->ah_filehandle_dest)   Close(SVObjectHandle->ah_filehandle_dest);

 if(SVObjectHandle->ah_FILE_source) fclose(SVObjectHandle->ah_FILE_source);
 if(SVObjectHandle->ah_FILE_dest)   fclose(SVObjectHandle->ah_FILE_dest);

 SVObjectHandle->ah_filehandle_source = N;
 SVObjectHandle->ah_filehandle_dest   = N;

 SVObjectHandle->ah_FILE_source       = N;
 SVObjectHandle->ah_FILE_dest         = N;


 return(retval);
}

ULONG __saveds __stdargs SVLI_PackRLE(struct SVObjectHandle *SVObjectHandle, struct rle_hdr *RLEHeader, UBYTE *dptr, ULONG width, ULONG height)
{
 ULONG j, w3, w3_2, hmax;
 UBYTE *start, *r_row, *g_row, *b_row, *row_vec[3];

 w3   = width * 3;
 w3_2 = w3 << 1;

 start = AllocVec(w3, MEMF_CLEAR|MEMF_PUBLIC);
 if(!start) return(SVERR_NO_MEMORY);

 row_vec[2] = (row_vec[1] = (row_vec[0] = start) + width) + width;

 dptr += (w3 * (hmax = height));
 dptr -= w3;

 while(height--)
  {
   if(SVObjectHandle->ah_ProgressFunc)
    {
     if(height & 7)
      {
       SVObjectHandle->ah_SVProgress.svpr_Percent = (hmax-height)*100/hmax;
       SVLI_Progress(SVObjectHandle, &SVObjectHandle->ah_SVProgress, SVObjectHandle->ah_ProgressData, SVObjectHandle->ah_ProgressFuture);
      }
    }

   r_row = row_vec[0];
   g_row = row_vec[1];
   b_row = row_vec[2];

   for(j=0; j<width; j++)
    {
     *r_row++ = *dptr++;
     *g_row++ = *dptr++;
     *b_row++ = *dptr++;
    }

   rle_putrow(&row_vec[0], width, RLEHeader);

   dptr -= w3_2;
  }

 FreeVec(start);

 return(SVERR_NO_ERROR);
}
