/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for 
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #                                      
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Clear.c.Load
    Author:  Copyright  1993, 1994 Jason Howat
    Version: 1.01 (13 May 1994)
    Purpose: Load a Clear file from disk.
    History: 1.00 (16 Dec 1993)   initial version
             1.01 (13 May 1994)   updated to use Desk_Mem_ library
*/

#include <stdlib.h>

#include "Desk.Clear.h"
#include "Desk.File.h"
#include "Desk.Mem.h"
#include "Desk.DeskMem.h"
#include "Desk.JumpRaw.h"


static Desk_clear_picture *Desk_Clear__AbortLoad(Desk_file_handle in, Desk_clear_picture *temp)
{
  if(in)
    Desk_File_Close(in);

  if(temp)
  {
    if(temp->bitmap)
      Desk_Mem_Free((void **)&temp->bitmap);
    if(temp->palette)
      Desk_Mem_Free((void **)&temp->palette);
    Desk_DeskMem_Free(temp);
  }

  return NULL;
}

Desk_clear_picture *Desk_Clear_Load(char *filename)
{
  Desk_file_handle   in = 0;
  Desk_clear_picture *temp = NULL;
  unsigned      Desk_creator_length = 1;
  unsigned      Desk_bitmap_size;
  int           word;
  unsigned      entry,
                colours;
  unsigned      i;
  Desk_palette_entry *palette;

  Desk_JumpAuto_Try	{
	in = Desk_File_Open(filename, Desk_file_READ);

  	while(Desk_File_ReadByte(in) > 0)
    	Desk_creator_length++;
	
  Desk_File_Seek(in, 0);

  temp = Desk_DeskMem_Malloc(sizeof(Desk_clear_picture) + Desk_creator_length);

  temp->creator = (char *)&temp[1];
  temp->palette = NULL;
  temp->bitmap = NULL;

  Desk_File_ReadBytes(in, temp->creator, Desk_creator_length);

  temp->creatorversion = Desk_File_Read32(in);
  temp->width = Desk_File_Read32(in);
  temp->height = Desk_File_Read32(in);
  temp->bpp = Desk_File_Read32(in);

  if(temp->bpp > 8)
    Desk_bitmap_size = 3 * temp->width * temp->height;
  else
  {
    colours = 1 << temp->bpp;

   Desk_Mem_Alloc((void **)&temp->palette, sizeof(Desk_palette_entry) * colours);

    palette = temp->palette;
    for(entry = 0 ; entry < colours ; entry++)
    {
      word = 0;
      for(i = 8 ; i < 25 ; i += 8)
        word += Desk_File_ReadByte(in) << i;
      palette[entry].value = word;
    }

    Desk_bitmap_size = temp->width * temp->height;
  }

  Desk_Mem_Alloc((void **)&temp->bitmap, Desk_bitmap_size);

  Desk_File_ReadBytes(in, temp->bitmap, Desk_bitmap_size);

  Desk_File_Close(in);
  }
Desk_JumpAuto_Catch	{
  Desk_Clear__AbortLoad(in, temp);
  Desk_Error2_ReThrow();
	}
Desk_JumpAuto_EndCatch

  return temp;
}
