/*
 * The original code was part of Crack dot Com's free source code release
 * of Golgotha. <a href="http://www.crack.com/golgotha_release">
 */

#include <v_lib.h>

V_LOCAL vboolean
fli_read_rle(u8_t *im,u32_t w,u32_t h,file_t fp)
{
	u8_t *line,c,tpackets;
	s8_t size;
	u32_t y,k;
	for (y=0; y<h; y++)
	{   
		line=im;
		im+=w;
		tpackets = fileGetc(fp);
		for (k=0; k<tpackets; k++)
		{
			size = fileGetc(fp);
			if (size>0)
			{
				c = fileGetc(fp);
				while (size)
				{
					*line=c;
					++line;
					size--;
				}
			}
			else      
			{
				if (fileRead(fp,line,-size)!=-size)
					return false;
				else
					line += -size;
			}
		}
	}
	return true;
}

V_LOCAL vboolean
fli_read_lc(u8_t *prev, u8_t *im, u32_t w, u32_t h,file_t fp)
{
	u32_t x,y;
	u16_t skip_lines,change_lines;
	u8_t *line,*prev_line,tpackets,c,skip;
	s8_t size;
	skip_lines = fileGetLittleShort(fp);
	memcpy(im,prev,skip_lines*w);
	im += skip_lines*w;
	prev += skip_lines*w;
	change_lines = fileGetLittleShort(fp);
	for (y=0; y<change_lines; y++)
	{
		tpackets = fileGetc(fp);
		line = im;
		prev_line = prev;
		im += w;
		prev += w;
		if (tpackets==0)
			memcpy(line,prev_line,w);
		else
		{
			for (x=0; x<tpackets; x++)
			{
				skip = fileGetc(fp);
				memcpy(line,prev_line,skip);
				line += skip;
				prev_line += skip;
				size = fileGetc(fp);
				if (size<0)
				{
					c = fileGetc(fp);
					while (size)
					{
						*line=c;
						++line;
						++prev_line;
						size++;
					}
				}
				else      
				{
					if (fileRead(fp,line,size)!=size)
						return false;
					line += size;
					prev_line += size;
				}
			}
		}
	}
	return true;
}

V_LOCAL vboolean
fli_read_ss2(u8_t *prev, u8_t *im, u32_t w, u32_t h, file_t fp)
{
	u32_t x,y;
	u16_t skip_lines,change_lines;
	u16_t *line,*prev_line,code_word,c;
	s8_t size;
	change_lines = fileGetLittleShort(fp);

	TODO

	for (y=0; y<change_lines; y++)
  {
    do
    {
      code_word=fp->read_16();
      switch(code_word>>14)
      {
        case 0:
          break;
        case 1:
          return i4_F;

        case 2:
        {
          *(im+w-1) = code_word & 0xff;
        } break;
        
        case 3:
          skip_lines = -code_word;
          im += w*skip_lines;
          prev += w*skip_lines;
          break;
      }
    } while (code_word & 0x8000);

    line=(u16_t*)im;
    prev_line=(u16_t*)prev;

    im+=w;
    prev+=w;

    if (code_word==0)
      memcpy(line,prev_line,w-1);
    else
    {
      for (x=0; x<code_word; x++)
      {
        u8_t skip=fp->read_8();
        memcpy(line,prev_line,skip);
        line+= (skip>>1);
        prev_line+= (skip>>1);

        size=fp->read_8();
        if (size<0)
        {
          c=fp->read_16();
          while (size)
          {
            *line=c;
            ++line;
            ++prev_line;
            size++;
          }
        } else      
        {
          if (fp->read(line,size*2)!=size*2)
            return i4_F;
          line+=size;
          prev_line+=size;
        }

      }
    }

  }

  return i4_T;
}
//}}}


//hacked on 5-23-97, loads a series of .pcx files
i4_image_class **i4_load_fli(i4_file_class *fp, u32_t &frames)
{
return NULL;
}

/*
i4_image_class **i4_load_fli(i4_file_class *fp, u32_t &frames)
//{{{
{
  //{{{ FLI chunk signatures
  enum 
  {
    FLI_COLOR_MAP256=4,
    FLI_SS2=7,
    FLI_COLOR_MAP=11,
    FLI_COMPRESSED_LINE=12,
    FLI_BLACK=13,
    FLI_RLE=15,
    FLI_RAW=16,
    FLI_PSTAMP=18
  } ;
  //}}}

  u32_t offset,shift=0;
  u32_t size,frame_size,k;
  u16_t signature,
    depth,
    w, h,
    chunk_type,
    tchunks;
    
  u8_t buffer[114];
  u32_t chunk_size,
    frame_on;

  int error = 0;

  size=fp->read_32();
  signature=fp->read_16();

  frames=fp->read_16();
  w=fp->read_16();
  h=fp->read_16();

  depth=fp->read_16();
  if (depth!=8)
    return 0;

  if (signature==0xaf11)        // FLI signature
  {
    if (fp->read(buffer,114)!=114)
      return 0;
  }
  else if (signature==0xaf12)   // FLC signature
  {
    // read offset to first frame chunk to skip prefixes, etc.
    fp->seek(80);
    offset = fp->read_32();
    // go to first frame
    fp->seek(offset);
  }
  else
    return 0;

  i4_pal_handle_class pal;
  i4_unmatched_image8 **im;
  im=(i4_unmatched_image8 **)i4_malloc(sizeof(i4_unmatched_image8 *)*frames,"fli frame pointers");
  
  for (frame_on=0; frame_on<frames && !error; frame_on++)
  {
    frame_size=fp->read_32();
    if (fp->read_16()!=0xf1fa)
      error = 1;
    else
    {
      im[frame_on]=new i4_unmatched_image8(w,h,pal);
      tchunks=fp->read_16();
      fp->read(buffer,8);

      for (k=0; k<tchunks && !error; k++)
      {
        chunk_size=fp->read_32();
        chunk_type=fp->read_16();
        switch ((u8_t)(chunk_type&0xff))
        {
          case FLI_COMPRESSED_LINE :
            //{{{
            if (!fli_read_lc(im[frame_on-1]->local_sub_data(0,0),
                             im[frame_on]->local_sub_data(0,0),
                             w,h,
                             fp))
              error = 1;
            break;
            //}}}
          case FLI_RAW :
            //{{{
            if (fp->read(im[frame_on]->local_sub_data(0,0),64000)!=64000)
              error = 1;
            break;
            //}}}
          case FLI_RLE :
            //{{{
            if (!fli_read_rle(im[frame_on]->local_sub_data(0,0), w,h, fp))
              error = 1;
            break;
            //}}}
          case FLI_COLOR_MAP :
            //{{{
            shift = 2;
            //}}}
          case FLI_COLOR_MAP256 :
            //{{{
          {
            u32_t pald[256],*p;

            p=pald;
            memset(pald,0,sizeof(pald));
            u32_t i,j;
            u16_t change;
            u8_t trip[3];
            u16_t count=fp->read_16();
            for (i=0; i<count; i++)
            {
              p+=fp->read_8();
              change=fp->read_8();
              if (!change) 
                change=256;
              for (j=0; j<change; j++)
              {
                fp->read(trip,3);
                if (p>pald+256)
                  i4_error("fli gone crazy");

                *p=(trip[0] << (16+shift))|
                  (trip[1] <<  (8+shift))|
                  (trip[2] <<  shift);
                p++;

              }
              pal=i4_pal_man.register_pal(i4_pal_handle_class::ID_8BIT,pald);
            }
            shift = 0;
          } break;
            //}}}
          case FLI_BLACK :
            //{{{
          {
            i4_draw_context_class context(0,0,w-1,h-1);
            im[frame_on]->clear(0,context);
          } break;
            //}}}
          case FLI_SS2 :
            //{{{
            if (!fli_read_ss2(im[frame_on-1]->local_sub_data(0,0),
                              im[frame_on]->local_sub_data(0,0),
                              w,h,
                              fp))
              error = 1;
            break;
            //}}}
          default :
            //{{{
            fp->seek(fp->tell()+chunk_size - 6);
            //}}}
        }
      }
    }
  }

  if (error)
  {
    for (u32_t j=0; j<frame_on; j++)
      delete im[j];
    i4_free(im);
    return 0;
  }

  for (k=0; k<frames; k++)
    im[k]->set_pal(pal);

  return (i4_image_class **)im;
}
//}}}
*/



//{{{ Emacs Locals
// Local Variables:
// folded-file: t
// End:
//}}}

