/***********************************************************************/
/*                                                                     */
/* Project      : GRAV                                                 */
/* Current Rel. : 3.1                                                  */
/* Creator      : Michael Knigge                                       */
/* Creation Date: 01/30/95                                             */
/* Description  : read file (GBM)                                      */
/*                                                                     */
/* Functions    : grav_read_gbm_file()                                 */
/*                                                                     */
/***********************************************************************/

#include <stdio.h>
#include <fcntl.h>
#include <malloc.h>
#include <ncurses.h>
#include "standard.h"
#include "gbm.h"
#include "defines.h"
#include "error.h"
#include "readgbm.h"

char *grav_read_gbm_file(int *error_id, int flag, int index, DIRTAB dirtab[], GBM *gbm, GBMFT *gbmft, GBMRGB gbmrgb[])
{
   int  gbm_file;
   long bitmap_size;
   char *bitmap;

   /*
    * this is the interface to the GBM (written for OS/2). we have to
    * call a set of functions to process/read the file.
    * first we have to open the file for reading only.
    */

   if ((gbm_file = open(dirtab[index].filename, O_RDONLY)) == -1 )
   {
      *error_id = GRAV_ERROR_OPEN;
      return(NULL);
   }

   /*
    * next, we will get some descrptions to the file in GBMFT
    */
                                
   gbm_query_filetype(dirtab[index].gfx_type, gbmft);

   /*
    * now we will read the header of the file. we will get back the
    * resolution and bpp in GBM
    */
       
   if ((gbm_read_header(dirtab[index].filename, gbm_file, dirtab[index].gfx_type, gbm, "\0")) != GBM_ERR_OK)
   {
      close(gbm_file);
      *error_id = GRAV_ERROR_HEADER;
      return(NULL);
   }

   /*
    * if we need only the resolution and bpp, we can go back here
    */
    
   if (flag == READ_HEADER_ONLY)
   {
      close(gbm_file);
      *error_id = GRAV_NO_ERROR;
      return(NULL);
   }

   /*
    * next, read the palette of the graphic....
    */
    
   if ((gbm_read_palette(gbm_file, dirtab[index].gfx_type, gbm, gbmrgb)) != GBM_ERR_OK )
   {
       close(gbm_file);
       *error_id = GRAV_ERROR_PALETTE;
       return(NULL);
   }       

   /*
    * calculate the bitmap-size. the size must be a multiple of 4.
    * this exactly match the format used by OS/2 and WINDOWS
    * bitmaps...
    */
    
   bitmap_size = gbm->h * (((gbm->w * gbm->bpp + 31) / 32) * 4);

   /*
    * allocate memory for the bitmap...
    */
    
   if ((bitmap = malloc((int) bitmap_size)) == NULL)
   {
      close(gbm_file);
      *error_id = GRAV_ERROR_ALLOC;
      return(NULL);
   }  
   
   /*
    * initialize the bitmap
    */
    
   memset(bitmap, 0, bitmap_size);

   /*
    * and last but not least, read the graphic into memory (stored
    * as a bitmap)
    */
    
   if ((gbm_read_data(gbm_file, dirtab[index].gfx_type, gbm, bitmap)) != GBM_ERR_OK)
   {
      free(bitmap);
      close(gbm_file);
      *error_id = GRAV_ERROR_READ;
      return(NULL);
   }   

   /*
    * we don't need gbm_file any longer, so close it
    */
    
   close(gbm_file);

   *error_id = GRAV_NO_ERROR;
   return(bitmap);
}
