/*******************************************************************************
*
* Project Name: Tuturial on RLE compression
* File Name:    rletobmp.c
* Initial Date: 30/08/2004
* Author:       Cyril MOTTIER (orlin61@wanadoo.fr)
* Description:  This routine will show you how decompressing a RLE_compressed 
*               picture. This source can be compiled easily. The output program
*               can run on Ti-89, Ti-92+ and V200. This part use the function
*               BitmapPut().
* Version:      Version 1.00
*
******************************************************************************/


#include <tigcclib.h>

//Total compression: 1860 bytes compressed to 1533 (17% smaller)
static unsigned char my_cat_0[]={
0x91,0x00,0x06,0x01,0xc0,0x91,0x00,0x08,0x01,0xc0
,0x91,0x00,0x06,0x0c,0xff,0x83,0xf0,0x91,0x00,0x06
,0x0f,0xff,0xf7,0xf1,0x80,0x91,0x00,0x06,0xbf,0xff
,0xf1,0xe0,0x91,0x00,0x06,0x3f,0xff,0xf7,0x80,0x91
,0x00,0x05,0xe0,0x07,0xff,0xff,0xe0,0x91,0x00,0x05
,0x6e,0x1f,0xff,0xff,0xe0,0x91,0x00,0x05,0x6e,0x1f
,0xff,0xff,0xe0,0x91,0x00,0x05,0x31,0xbf,0xcd,0xff
,0xe0,0x91,0x00,0x04,0x0f,0x1c,0x7f,0x81,0xf7,0xe0
,0x91,0x00,0x04,0x60,0x00,0x7f,0x01,0xc3,0xe0,0x91
,0x00,0x03,0x01,0x80,0x00,0x7c,0x01,0x81,0xf0,0x91
,0x00,0x03,0x01,0x00,0x00,0x1e,0x0d,0x80,0xf0,0x91
,0x00,0x06,0x1d,0x3d,0x80,0xfc,0x91,0x00,0x06,0x1d
,0x3d,0x80,0xfc,0x91,0x00,0x06,0x45,0x3f,0x01,0xfc
,0x91,0x00,0x03,0x18,0x00,0x01,0x7f,0x3f,0xc1,0xfc
,0x91,0x00,0x03,0x39,0x30,0x03,0xff,0xff,0xc0,0xff
,0x91,0x00,0x03,0x17,0xf8,0x0f,0xf8,0x7f,0x80,0xff
,0x00,0x00,0x43,0xff,0xf8,0x63,0xf8,0x0f,0x83,0xf7
,0xc0,0x01,0xd7,0xff,0xf9,0xef,0xf8,0x0f,0x85,0xf5
,0xc0,0x01,0xd7,0xff,0xf9,0xef,0xf8,0x0f,0x85,0xf5
,0xc0,0x00,0x7f,0xff,0xf8,0x6f,0xfc,0x07,0xff,0xf7
,0xe0,0x00,0x3f,0xff,0xff,0x1f,0xfe,0x07,0xbf,0xf7
,0xc0,0x00,0x7f,0xff,0xff,0x3f,0xff,0xff,0xcf,0xfb
,0xf0,0x00,0x3f,0xff,0xff,0x5f,0xff,0xff,0xc0,0x19
,0xf8,0x28,0x1f,0xff,0xf8,0xf3,0xff,0xff,0xc0,0x03
,0x00,0xfa,0x1f,0xff,0xff,0x1f,0xff,0xff,0xc0,0x07
,0x00,0xfa,0x1f,0xff,0xff,0x1f,0xff,0xff,0xc0,0x07
,0x00,0xff,0xbf,0xff,0xff,0x31,0xff,0xff,0xc0,0x03
,0xc0,0x91,0xff,0x03,0xfe,0xee,0xff,0xff,0xf0,0x00
,0xc0,0x1f,0xff,0xff,0xf8,0x53,0x7f,0xff,0xb0,0x01
,0x00,0x1f,0x91,0xff,0x03,0xdd,0xbf,0xff,0xf0,0x00
,0xe0,0x0d,0x91,0xff,0x03,0x1f,0x9f,0xfe,0xf0,0x00
,0x20,0x03,0xff,0xff,0xfe,0x33,0xe5,0xfa,0x70,0x00
,0x20,0x03,0xff,0xff,0xfe,0x33,0xe5,0xfa,0x70,0x00
,0x20,0x03,0xff,0xff,0xef,0x01,0xff,0xf8,0xc0,0x00
,0x20,0x0f,0xff,0xff,0xf7,0x9f,0x03,0x4e,0xc0,0x00
,0xc0,0x07,0xef,0xff,0xbf,0xff,0xf9,0xff,0x40,0x00
,0x20,0x0f,0xc7,0xff,0x3f,0xff,0x3f,0xfd,0xf0,0x01
,0xe0,0x14,0x03,0xfe,0x59,0x0f,0xe1,0xfc,0xf0,0x01
,0xe0,0x00,0x00,0x8e,0x56,0x01,0x07,0xfc,0x70,0x01
,0xe0,0x00,0x00,0x8e,0x56,0x01,0x07,0xfc,0x70,0x01
,0xe0,0x00,0x04,0x0f,0xff,0xc1,0x87,0xfe,0x74,0x06
,0xe0,0x00,0x00,0x1f,0xf7,0xe0,0x9f,0xfc,0x3e,0x06
,0xe0,0x00,0x00,0x7f,0xfe,0x60,0x1f,0xfe,0x3e,0x0f
,0xc0,0x00,0x00,0xff,0xbf,0x80,0x3f,0xff,0x0e,0x0e
,0xc0,0x00,0x00,0xff,0xff,0x00,0x9f,0xff,0x0f,0x1e
,0xc0,0x00,0x00,0x7f,0xff,0xc0,0xbf,0xff,0x05,0xfe
,0x91,0x00,0x03,0x7f,0xdf,0xc0,0xbf,0xff,0x01,0xfc
,0x91,0x00,0x03,0x7f,0xdf,0xc0,0xbf,0xff,0x01,0xfc
,0x91,0x00,0x03,0xff,0xef,0xb0,0xff,0xff,0x01,0xf8
,0x91,0x00,0x03,0x7f,0xa8,0xfc,0xbf,0xfe,0x00,0xf8
,0x91,0x00,0x03,0x7f,0xff,0xfc,0x3f,0xfe,0x00,0x70
,0x91,0x00,0x03,0x7f,0xff,0xde,0x7f,0xfe,0x01,0xe0
,0x91,0x00,0x03,0x3f,0x7f,0x9f,0x7f,0xfc,0x00,0x80
,0x91,0x00,0x03,0x1f,0x2e,0x33,0xbf,0xfc,0x91,0x00
,0x05,0x1f,0x2e,0x33,0xbf,0xfc,0x91,0x00,0x05,0x08
,0x77,0xbf,0xff,0xfe,0x91,0x00,0x05,0x06,0x37,0x91
,0x91,0x01,0x7f,0xff,0x91,0x00,0x06,0x7f,0x91,0xff
,0x03,0x91,0x00,0x06,0x3f,0x91,0xff,0x03,0x80,0x91
,0x00,0x05,0x3f,0xf1,0xbf,0xff,0x80,0x91,0x00,0x05
,0x1e,0xb0,0xff,0xff,0xc0,0x91,0x00,0x05,0x1e,0xb0
,0xff,0xff,0xc0,0x91,0x00,0x06,0x70,0x7b,0xff,0xc0
,0x91,0x00,0x06,0x7c,0x07,0xff,0xf0,0x91,0x00,0x06
,0x3c,0x01,0xff,0xf0,0x91,0x00,0x06,0x3e,0x03,0xff
,0xf0,0x91,0x00,0x06,0x3f,0x01,0xff,0xf8,0x91,0x00
,0x06,0x1f,0x81,0xff,0xfc,0x91,0x00,0x06,0x1f,0x81
,0xff,0xfc,0x91,0x00,0x06,0x13,0xc0,0xff,0xff,0x91
,0x00,0x06,0x0d,0xfd,0xff,0xff,0xe0,0x91,0x00,0x05
,0x0f,0x7d,0xff,0xff,0xf4,0x91,0x00,0x05,0x03,0x91
,0xff,0x04,0xfe,0x91,0x00,0x04,0x80,0x91,0xff,0x04
,0xf8,0x91,0x00,0x04,0xb0,0x91,0xff,0x04,0xf0,0x91
,0x00,0x04,0xb0,0x91,0xff,0x04,0xf0,0x91,0x00,0x03
,0x07,0xce,0x7f,0x91,0xff,0x03,0x91,0x00,0x04,0x0f
,0x01,0xbf,0xff,0xf9,0xe8,0x91,0x00,0x04,0x1f,0x00
,0x1f,0xff,0xbd,0xf8,0x91,0x00,0x04,0x18,0x00,0x19
,0xff,0x80,0x10,0x91,0x00,0x04,0x18,0x40,0x01,0x4f
,0x04,0x10,0x91,0x00,0x04,0x19,0x80,0x03,0x78,0x07
,0x08,0x91,0x00,0x04,0x19,0x80,0x03,0x78,0x07,0x08
,0x91,0x00,0x04,0x01,0x80,0x07,0x38,0x03,0x88,0x91
,0x00,0x04,0x09,0xe0,0x1e,0x78,0x01,0x88,0x91,0x00
,0x04,0x06,0x7f,0xfb,0x7c,0x01,0x90,0x91,0x00,0x04
,0x01,0xde,0x5c,0x3f,0xfd,0xf0,0x91,0x00,0x05,0x2f
,0xe0,0x0f,0xff,0xe0,0x91,0x00,0x07,0x01,0xfe,0x00
,0x00};

static unsigned char my_cat_1[]={
0x91,0x00,0x07,0x70,0x91,0x00,0x09,0x70,0x91,0x00
,0x06,0x03,0x00,0x01,0xf0,0x91,0x00,0x06,0x01,0xff
,0xfb,0xf0,0x91,0x00,0x07,0x7f,0xff,0xf3,0x80,0x91
,0x00,0x06,0x1f,0xff,0xff,0xe0,0x91,0x00,0x06,0x07
,0xff,0xff,0xe0,0x91,0x00,0x06,0x07,0xff,0xff,0xe0
,0x91,0x00,0x06,0x07,0xff,0xff,0xe0,0x91,0x00,0x06
,0x7f,0xf0,0xff,0xe0,0x91,0x00,0x06,0xff,0x00,0xfb
,0xe0,0x91,0x00,0x06,0x7e,0x00,0xf1,0xe0,0x91,0x00
,0x06,0x3e,0x00,0xc1,0xf0,0x91,0x00,0x06,0x3c,0x01
,0x81,0xf8,0x91,0x00,0x06,0x1c,0x0f,0x01,0xf8,0x91
,0x00,0x06,0x1c,0x0f,0x01,0xf8,0x91,0x00,0x06,0x3e
,0x3f,0x80,0xfc,0x91,0x00,0x06,0xff,0xff,0x80,0xfe
,0x91,0x00,0x04,0xc0,0x01,0xff,0xff,0x81,0xfe,0x91
,0x00,0x03,0x79,0xfe,0x03,0xff,0xff,0x81,0xff,0x00
,0x01,0x87,0xff,0xfe,0x1f,0xff,0xff,0x01,0xff,0x00
,0x00,0x6f,0xff,0xfe,0x1f,0xff,0xff,0x03,0xfb,0xc0
,0x00,0x6f,0xff,0xfe,0x1f,0xff,0xff,0x03,0xfb,0xc0
,0x00,0x7f,0xff,0xfe,0x1f,0xff,0xff,0x83,0xf8,0xc0
,0x00,0x7f,0xff,0xfe,0x0f,0xff,0xff,0xc7,0xf8,0x20
,0x00,0x3f,0xff,0xfe,0x0f,0x91,0xff,0x03,0xfc,0x00
,0x00,0x3f,0xff,0xfe,0x2f,0xff,0xff,0xf0,0x06,0x00
,0xd0,0x3f,0xff,0xfe,0x2f,0xff,0xff,0xf0,0x00,0x00
,0xff,0xbf,0xff,0xfe,0x63,0xff,0xff,0xf0,0x00,0x00
,0xff,0xbf,0xff,0xfe,0x63,0xff,0xff,0xf0,0x00,0x00
,0x91,0xff,0x03,0xfe,0x63,0xff,0xff,0xf0,0x00,0x00
,0x3f,0xff,0xff,0xfe,0x71,0xff,0xff,0xc0,0x00,0x00
,0x3f,0xff,0xff,0xfe,0xfc,0xff,0xff,0xc0,0x00,0x00
,0x0f,0xff,0xff,0xfe,0x7e,0x7f,0xff,0x80,0x00,0x00
,0x03,0xff,0xff,0xfe,0x7f,0xff,0xff,0x91,0x00,0x03
,0x01,0xff,0xff,0xf8,0x7f,0xfb,0xfc,0x91,0x00,0x03
,0x01,0xff,0xff,0xf8,0x7f,0xfb,0xfc,0x91,0x00,0x03
,0x07,0xff,0xff,0xf0,0x3f,0xf8,0x91,0x00,0x04,0x07
,0xff,0xff,0xe0,0x00,0xfc,0x91,0x00,0x04,0x0f,0xf3
,0xff,0xf0,0x00,0x06,0x00,0x80,0x00,0x00,0x0f,0x83
,0xff,0x98,0x00,0xc1,0xf8,0x91,0x00,0x03,0x08,0x07
,0xff,0x3e,0x00,0x03,0xf8,0x91,0x00,0x04,0x07,0x0f
,0xe8,0x00,0x03,0xfc,0x91,0x00,0x04,0x07,0x0f,0xe8
,0x00,0x03,0xfc,0x91,0x00,0x05,0x1f,0xc0,0x00,0x07
,0xfc,0x00,0x01,0x91,0x00,0x03,0x3f,0xb8,0x00,0x07
,0xfe,0x00,0x01,0x91,0x00,0x03,0x7f,0xbf,0x80,0x1f
,0xfe,0x91,0x00,0x05,0x7f,0xff,0x00,0x1f,0xfe,0x91
,0x00,0x05,0x7f,0xff,0x80,0x3f,0xfe,0x91,0x00,0x05
,0xff,0xff,0x80,0x3f,0xfe,0x91,0x00,0x05,0xff,0xff
,0x80,0x3f,0xfe,0x91,0x00,0x05,0xff,0xff,0x80,0x3f
,0xfe,0x91,0x00,0x05,0x3f,0xdf,0x80,0x3f,0xfe,0x91
,0x00,0x05,0x3f,0xd1,0x80,0x7f,0xfe,0x91,0x00,0x05
,0x3f,0x80,0x00,0x7f,0xfe,0x00,0x80,0x91,0x00,0x03
,0x3f,0x80,0x20,0x3f,0xfe,0x91,0x00,0x05,0x1f,0x80
,0x60,0x3f,0xfe,0x91,0x00,0x05,0x1e,0x71,0xcc,0x7f
,0xfe,0x91,0x00,0x05,0x1e,0x71,0xcc,0x7f,0xfe,0x91
,0x00,0x05,0x0e,0x61,0xc0,0x7f,0xfe,0x91,0x00,0x05
,0x08,0x7f,0xef,0xff,0xfe,0x91,0x00,0x06,0x3f,0x81
,0xff,0xff,0x91,0x00,0x06,0x3f,0x80,0xff,0xff,0x91
,0x00,0x06,0x1f,0x80,0x7f,0xff,0x80,0x91,0x00,0x05
,0x0f,0x40,0x1f,0xff,0x80,0x91,0x00,0x05,0x0f,0x40
,0x1f,0xff,0x80,0x91,0x00,0x07,0x07,0xff,0xc0,0x91
,0x00,0x07,0x03,0xff,0xc0,0x91,0x00,0x07,0x03,0xff
,0xf0,0x91,0x00,0x07,0x01,0xff,0xf0,0x91,0x00,0x07
,0x01,0xff,0xf0,0x91,0x00,0x07,0x01,0xff,0xf8,0x91
,0x00,0x07,0x01,0xff,0xf8,0x91,0x00,0x06,0x0c,0x01
,0xff,0xfe,0x91,0x00,0x06,0x0e,0x01,0xff,0xff,0x80
,0x91,0x00,0x05,0x03,0x83,0xff,0xff,0xf8,0x91,0x00
,0x05,0x01,0x91,0xff,0x04,0xfe,0x91,0x00,0x04,0x01
,0x91,0xff,0x04,0xfc,0x91,0x00,0x05,0x91,0xff,0x04
,0xe0,0x91,0x00,0x05,0x91,0xff,0x04,0xe0,0x91,0x00
,0x05,0x7f,0xff,0xff,0xfe,0x91,0x00,0x06,0x7f,0xff
,0xc6,0x10,0x91,0x00,0x06,0x3f,0xff,0xc0,0x91,0x00
,0x07,0x07,0xff,0x00,0x08,0x91,0x00,0x07,0xf0,0x00
,0x08,0x91,0x00,0x07,0x80,0x91,0x00,0x09,0x80,0x91
,0x00,0x09,0xc0,0x91,0x00,0x08,0x01,0x80,0x91,0x00
,0x06,0x01,0x80,0x04,0x91,0x00,0x08,0x21,0xa0,0x91
,0x00,0x18};


BITMAP *RLE_Decompress_To_BITMAP (unsigned char *src, unsigned short rows, unsigned short cols)
{
 //---------------------------------------------------------------------------------------
 // Declaration of necessary variables
 //---------------------------------------------------------------------------------------
 unsigned char len, val, *dest;

 //---------------------------------------------------------------------------------------
 // The following instruction calculates the size in bytes of the bitmap.
 // The operation consists on multiplying number of pixels in width with number of
 // pixels in height. The result will give the number of pixel. To conclude,
 // 8 pixels are coded with one bytes so to find the size of the picture
 // the following result is divide by eight.
 //---------------------------------------------------------------------------------------
 unsigned short size = (rows*cols)>>3;

 //---------------------------------------------------------------------------------------
 // Allocates the necessary size. Note that the necessary size is not 'size' but
 // 'size+BITMAP_HDR_SIZE'. BITMAP_HDR_SIZE is equal to four and it defines the size of 
 // the header of the BITMAP structure.
 //---------------------------------------------------------------------------------------
 BITMAP *ptr = malloc (size+BITMAP_HDR_SIZE);

 //---------------------------------------------------------------------------------------
 // Don't forget to check if memory hed been correctly allocated.
 // The function 'malloc' returns 'NULL' if not enough space exists for the new block so
 // RLE_Decompress_To_BITMAP() will also return 'NULL' in this case.
 //---------------------------------------------------------------------------------------
 if (ptr)
 {
 
 //---------------------------------------------------------------------------------------
 // The BITMAP structure is modified with right datas.
 //---------------------------------------------------------------------------------------
  ptr->NumRows = rows;
  ptr->NumCols = cols;
  dest = ptr->Data;
 
 //---------------------------------------------------------------------------------------
 // The algorithm loops while the final size is different from zero.
 // So it will be 'size' iterations.
 //---------------------------------------------------------------------------------------
  while (size)
  {
 
 //---------------------------------------------------------------------------------------
 // If the special (or control) caracter is found, following bytes are compressed.
 // With Istudio the RLE_compressed datas are coded with this technic : first we have the
 // control caracter (0x91) then the repeated value and finally the lenght of this value.
 // Now it's easy to decompress this sequence
 //---------------------------------------------------------------------------------------
   if (*src==0x91)
   {
    src++;
    val = *src++;
    len = *src++;
    while (len)
    {
     *dest++ = val;
     len--;
     size--;
    }
   }
 
 //---------------------------------------------------------------------------------------
 // If no control cracter hed been found, it means the bytes are not compressed.
 // These bytes are just copied from 'src' to 'dest' with no modifications
 //---------------------------------------------------------------------------------------
   else
   {
    *dest++ = *src++;
    size--;
   }
  }
 }
 
 //---------------------------------------------------------------------------------------
 //On success ,the function returns a pointer to the newly decompressed datas,
 //else it return 'NULL'
 //---------------------------------------------------------------------------------------
 return ptr;
}

void _main(void)
{
 if (GrayOn())
 {
 
 //---------------------------------------------------------------------------------------
 // pic_light and pic_dark are defined in static at the beginning of the source
 // I haven't place compressed datas here because it's too long and it's useless
 // An exemple is available : see rletobmp.c. for more informations
 //---------------------------------------------------------------------------------------
  BITMAP *pic0 = RLE_Decompress_To_BITMAP (my_cat_0, 93, 80);
  BITMAP *pic1 = RLE_Decompress_To_BITMAP (my_cat_1, 93, 80);
  if (pic0 && pic1)
  {
 
 //---------------------------------------------------------------------------------------
 // The two following 'memset()' works exactly as 'ClrScr()' : it clears the entire screen
 // Nevertheless, here 'memset()' are called with 'GetPlane()' so it fills the two gray 
 // planes with zeros.
 //---------------------------------------------------------------------------------------  
   memset (GetPlane(0), 0x0, LCD_SIZE);
   memset (GetPlane(1), 0x0, LCD_SIZE);
   SetPlane (0);
   BitmapPut ((LCD_WIDTH-80)>>1, (LCD_HEIGHT-93)>>1, pic0, &(SCR_RECT){{0,0,239,127}}, A_NORMAL);
   SetPlane (1);
   BitmapPut ((LCD_WIDTH-80)>>1, (LCD_HEIGHT-93)>>1, pic1, &(SCR_RECT){{0,0,239,127}}, A_NORMAL);
   ngetchx ();
  }
  GrayOff();
 
 //---------------------------------------------------------------------------------------
 // Don't forget to free the allocated memory :-). It's a novice error! A tip : you can
 // consider 'RLE_Decompress_To_BITMAP()' as an allocation function like 'calloc()',
 // 'malloc()' or 'realloc()'
 //---------------------------------------------------------------------------------------
  free (pic0);
  free (pic1);
 }
}