
 /* SV_BufferSubs.c
    - Functions for Buffering UtahRLE Files -
    (c) 1993-95 by Andreas R. Kleinert
    Last changes : 14.04.1995
 */


#include "svobject.h"

ULONG __saveds __asm SVO_ReadToGfxBuffer( register __a1 struct SVObjectHandle *SVObjectHandle_a1);
ULONG __saveds __asm SVO_GetGfxBuffer(    register __a1 struct SVObjectHandle *SVObjectHandle_a1,
                                          register __a2 struct SV_GfxBuffer **bufferhandle,
                                          register __a3 ULONG future);
ULONG __saveds __asm SVO_SetGfxBuffer(    register __a1 struct SVObjectHandle *SVObjectHandle_a1,
                                          register __a2 struct SV_GfxBuffer *bufferhandle,
                                          register __a3 ULONG future);


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


/* *************************************************** */
/* *						     * */
/* * ...                                             * */
/* *						     * */
/* *************************************************** */

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

 ULONG retval = SVERR_NO_ERROR, rleret = N;
 ULONG pic_width, pic_height, pic_depth;

 struct rle_hdr __aligned RLEHeader;


 if(!SVObjectHandle) return(SVERR_NO_HANDLE);


 if(!(SVObjectHandle->ah_filehandle_dest = Open(SVObjectHandle->ah_ReadName, MODE_OLDFILE))) return(SVERR_FILE_NOT_FOUND);
 if(!(SVObjectHandle->ah_FILE_dest       = fopen(SVObjectHandle->ah_ReadName, "r")))         return(SVERR_FILE_NOT_FOUND);


 RLEHeader.rle_file = SVObjectHandle->ah_FILE_dest;

 rleret = rle_get_setup(&RLEHeader);
 if(rleret != RLE_SUCCESS)
  {
   switch(rleret)
    {
     case RLE_NO_SPACE: return(SVERR_NO_MEMORY);          break;
     default:           return(SVERR_UNKNOWN_PARAMETERS); break;
    }
  }

 SVObjectHandle->ah_Type = SVObjectBase->svb_SVObject->svo_SubTypeCode[0];


 pic_width  = RLEHeader.xmax - RLEHeader.xmin + 1;
 pic_height = RLEHeader.ymax - RLEHeader.ymin + 1;
 pic_depth  = RLEHeader.ncolors << 3;

 RLEHeader.xmin = 0;          /* align pic_width */
 RLEHeader.xmax = pic_width - 1;


 if(RLEHeader.ncmap && (RLEHeader.ncmap!=3) ) return(SVERR_UNKNOWN_PARAMETERS);
 if(pic_depth != 24)                              return(SVERR_UNKNOWN_PARAMETERS);

 RLE_CLR_BIT(RLEHeader, RLE_ALPHA); /* don't want Alpha Channel */


 SVObjectHandle->ah_SV_GfxBuffer = AllocVec(sizeof(struct SV_GfxBuffer), (MEMF_CLEAR|MEMF_PUBLIC));
 if(!SVObjectHandle->ah_SV_GfxBuffer) return(SVERR_NO_MEMORY);

 SVObjectHandle->ah_SV_GfxBuffer->svgfx_Version = SVGFX_VERSION;

 SVObjectHandle->ah_SV_GfxBuffer->svgfx_BufferType   = SVGFX_BUFFERTYPE_ONEPLANE;
 SVObjectHandle->ah_SV_GfxBuffer->svgfx_Width        = pic_width;
 SVObjectHandle->ah_SV_GfxBuffer->svgfx_Height       = pic_height;
 SVObjectHandle->ah_SV_GfxBuffer->svgfx_ColorDepth   = 24;
 SVObjectHandle->ah_SV_GfxBuffer->svgfx_PixelBits    = 24;

 SVObjectHandle->ah_SV_GfxBuffer->svgfx_BufferSize   = pic_width * pic_height * 3;

 SVObjectHandle->ah_SV_GfxBuffer->svgfx_Buffer = AllocVec(SVObjectHandle->ah_SV_GfxBuffer->svgfx_BufferSize, (MEMF_CLEAR|MEMF_PUBLIC));
 if(!SVObjectHandle->ah_SV_GfxBuffer->svgfx_Buffer) return(SVERR_NO_MEMORY);

 SVObjectHandle->ah_SV_GfxBuffer->svgfx_ViewMode32 = SVSUP_GetBestModeID(pic_width, pic_height, 8);

 retval = SVLI_UnPackRLE(&RLEHeader, SVObjectHandle->ah_SV_GfxBuffer->svgfx_Buffer, pic_width, pic_height);

 return(retval);
}

ULONG __saveds __asm SVO_GetGfxBuffer(    register __a1 struct SVObjectHandle *SVObjectHandle_a1,
                                          register __a2 struct SV_GfxBuffer **bufferhandle,
                                          register __a3 ULONG future)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;
 ULONG retval = SVERR_NO_ERROR;

 if(!SVObjectHandle) return(SVERR_NO_HANDLE);

 if(!bufferhandle) return(SVERR_ILLEGAL_ACCESS);

 *bufferhandle = SVObjectHandle->ah_SV_GfxBuffer;

 return(retval);
}

ULONG __saveds __asm SVO_SetGfxBuffer(    register __a1 struct SVObjectHandle *SVObjectHandle_a1,
                                          register __a2 struct SV_GfxBuffer *bufferhandle,
                                          register __a3 ULONG future)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;
 ULONG retval = SVERR_NO_ERROR;

 if(!SVObjectHandle) return(SVERR_NO_HANDLE);

 if(!bufferhandle) return(SVERR_ILLEGAL_ACCESS);

 SVObjectHandle->ah_SV_GfxBuffer2 = bufferhandle;

 return(retval);
}

ULONG __saveds __stdargs SVLI_UnPackRLE(struct rle_hdr *RLEHeader, UBYTE *dptr, ULONG width, ULONG height)
{
 ULONG j, w3, w3_2;
 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 * height);
 dptr -= w3;

 while(height--)
  {
   r_row = row_vec[0];
   g_row = row_vec[1];
   b_row = row_vec[2];

   rle_getrow(RLEHeader, &row_vec[0]);

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

   dptr -= w3_2;
  }

 FreeVec(start);

 return(SVERR_NO_ERROR);
}
