Code Search for Developers
 
 
  

readbmp.c from Allegro game programming library at Krugle


Show readbmp.c syntax highlighted

/*         ______   ___    ___
 *        /\  _  \ /\_ \  /\_ \
 *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
 *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
 *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
 *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
 *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
 *                                           /\____/
 *                                           \_/__/
 *
 *      Top level bitmap reading routines.
 *
 *      By Shawn Hargreaves.
 *
 *      See readme.txt for copyright information.
 */


#include <string.h>

#include "allegro.h"
#include "allegro/internal/aintern.h"



typedef struct AL_BITMAP_TYPE_INFO
{
   char *ext;
   AL_BITMAP *(*load)(AL_CONST char *filename, AL_RGB *pal);
   int (*save)(AL_CONST char *filename, AL_BITMAP *bmp, AL_CONST AL_RGB *pal);
   struct AL_BITMAP_TYPE_INFO *next;
} AL_BITMAP_TYPE_INFO;

static AL_BITMAP_TYPE_INFO *bitmap_type_list = NULL;



/* al_register_bitmap_file_type:
 *  Informs Allegro of a new image file type, telling it how to load and
 *  save files of this format (either function may be NULL).
 */
void al_register_bitmap_file_type(AL_CONST char *ext, AL_BITMAP *(*load)(AL_CONST char *filename, AL_RGB *pal), int (*save)(AL_CONST char *filename, AL_BITMAP *bmp, AL_CONST AL_RGB *pal))
{
   char tmp[32], *aext;
   AL_BITMAP_TYPE_INFO *iter = bitmap_type_list;

   aext = al_uconvert_to_ascii(ext, tmp);
   if (strlen(aext) == 0) return;

   if (!iter) 
      iter = bitmap_type_list = malloc(sizeof(struct AL_BITMAP_TYPE_INFO));
   else {
      for (iter = bitmap_type_list; iter->next; iter = iter->next);
      iter = iter->next = malloc(sizeof(struct AL_BITMAP_TYPE_INFO));
   }

   if (iter) {
      iter->load = load;
      iter->save = save;
      iter->ext = strdup(aext);
      iter->next = NULL;
   }
}



/* al_load_bitmap:
 *  Loads a bitmap from disk.
 */
AL_BITMAP *al_load_bitmap(AL_CONST char *filename, AL_RGB *pal)
{
   char tmp[32], *aext;
   AL_BITMAP_TYPE_INFO *iter;

   aext = al_uconvert_to_ascii(get_extension_const(filename), tmp);
   
   for (iter = bitmap_type_list; iter; iter = iter->next) {
      if (stricmp(iter->ext, aext) == 0) {
	 if (iter->load)
	    return iter->load(filename, pal);
	 return NULL;
      }
   }

   return NULL;
}



/* al_save_bitmap:
 *  Writes a bitmap to disk.
 */
int al_save_bitmap(AL_CONST char *filename, AL_BITMAP *bmp, AL_CONST AL_RGB *pal)
{
   char tmp[32], *aext;
   AL_BITMAP_TYPE_INFO *iter;

   aext = al_uconvert_to_ascii(get_extension_const(filename), tmp);

   for (iter = bitmap_type_list; iter; iter = iter->next) {
      if (stricmp(iter->ext, aext) == 0) {
	 if (iter->load)
	    return iter->save(filename, bmp, pal);
	 return 1;
      }
   }

   return 1;
}



/* _fixup_loaded_bitmap:
 *  Helper function for adjusting the color depth of a loaded image.
 */
AL_BITMAP *_fixup_loaded_bitmap(AL_BITMAP *bmp, AL_PALETTE pal, int bpp)
{
   AL_BITMAP *b2;

   b2 = al_create_bitmap_ex(bpp, bmp->w, bmp->h);
   if (!b2) {
      al_destroy_bitmap(bmp);
      return NULL;
   }

   if (bpp == 8) {
      AL_RGB_MAP *old_map = al_rgb_map;

      al_generate_optimized_palette(bmp, pal, NULL);

      al_rgb_map = malloc(sizeof(AL_RGB_MAP));
      if (al_rgb_map != NULL)
	 al_create_rgb_table(al_rgb_map, pal, NULL);

      al_blit(bmp, b2, 0, 0, 0, 0, bmp->w, bmp->h);

      if (al_rgb_map != NULL)
	 free(al_rgb_map);
      al_rgb_map = old_map;
   }
   else if (al_bitmap_color_depth(bmp) == 8) {
      al_select_palette(pal);
      al_blit(bmp, b2, 0, 0, 0, 0, bmp->w, bmp->h);
      al_unselect_palette();
   }
   else {
      al_blit(bmp, b2, 0, 0, 0, 0, bmp->w, bmp->h);
   }

   al_destroy_bitmap(bmp);

   return b2;
}



/* register_bitmap_file_type_exit:
 *  Free list of registered bitmap file types.
 */
static void register_bitmap_file_type_exit(void)
{
   AL_BITMAP_TYPE_INFO *iter = bitmap_type_list, *next;

   while (iter) {
      next = iter->next;
      free(iter->ext);
      free(iter);
      iter = next;
   }
   
   bitmap_type_list = NULL;

   /* If we are using a destructor, then we only want to prune the list
    * down to valid modules. So we clean up as usual, but then reinstall
    * the internal modules.
    */
   #if defined(CONSTRUCTOR_FUNCTION) && defined(DESTRUCTOR_FUNCTION)
      _register_bitmap_file_type_init();
   #endif

   _remove_exit_func(register_bitmap_file_type_exit);
}



/* _register_bitmap_file_type_init:
 *  Register built-in bitmap file types.
 */
void _register_bitmap_file_type_init(void)
{
   char buf[32];

   _add_exit_func(register_bitmap_file_type_exit);

   al_register_bitmap_file_type(al_uconvert_ascii("bmp", buf), al_load_bmp, al_save_bmp);
   al_register_bitmap_file_type(al_uconvert_ascii("lbm", buf), al_load_lbm, NULL);
   al_register_bitmap_file_type(al_uconvert_ascii("pcx", buf), al_load_pcx, al_save_pcx);
   al_register_bitmap_file_type(al_uconvert_ascii("tga", buf), al_load_tga, al_save_tga);
}



#if (defined CONSTRUCTOR_FUNCTION) && (defined DESTRUCTOR_FUNCTION)
   CONSTRUCTOR_FUNCTION(static void bitmap_filetype_constructor());
   DESTRUCTOR_FUNCTION(static void bitmap_filetype_destructor());

   /* bitmap_filetype_constructor:
    *  Register bitmap filetype functions if this object file is linked
    *  in. This isn't called if the al_load_bitmap() and al_save_bitmap()
    *  functions aren't used in a program, thus saving a little space
    *  in statically linked programs.
    */
   static void bitmap_filetype_constructor()
   {
      _register_bitmap_file_type_init();
   }

   /* bitmap_filetype_destructor:
    *  Since we only want to destroy the whole list when we *actually*
    *  quit, not just when al_remove_system() is called, we need to use a
    *  destructor to accomplish this.
    */
   static void bitmap_filetype_destructor()
   {
      AL_BITMAP_TYPE_INFO *iter = bitmap_type_list, *next;

      while (iter) {
         next = iter->next;
         free(iter->ext);
         free(iter);
         iter = next;
      }
   
      bitmap_type_list = NULL;

      _remove_exit_func(register_bitmap_file_type_exit);
   }
#endif




See more files for this project here

Allegro game programming library

Allegro is a cross-platform library intended for use in computer games and other types of multimedia programming.

Project homepage: http://sourceforge.net/projects/alleg
Programming language(s): Assembly,C,Shell Script
License: other

  beos/
    baccel.cpp
    bclasses.cpp
    bdispsw.cpp
    bgfx.c
    bgfxapi.cpp
    bgfxdrv.c
    bjoy.c
    bjoyapi.cpp
    bjoydrv.c
    bkey.c
    bkeyapi.cpp
    bkeydrv.c
    bmidi.c
    bmidiapi.cpp
    bmididrv.c
    bmousapi.cpp
    bmousdrv.c
    bmouse.c
    bsnd.c
    bsndapi.cpp
    bsnddrv.c
    bswitch.s
    bsysapi.cpp
    bsysdrv.c
    bsystem.c
    btimeapi.cpp
    btimedrv.c
    btimer.c
  c/
    cblit.h
    cblit16.c
    cblit24.c
    cblit32.c
  dos/
  i386/
  linux/
  mac/
  misc/
  ppc/
  qnx/
  unix/
  win/
  x/
  allegro.c
  blit.c
  bmp.c
  clip3d.c
  clip3df.c
  colblend.c
  color.c
  config.c
  datafile.c
  dataregi.c
  digmid.c
  dispsw.c
  dither.c
  drvlist.c
  file.c
  fli.c
  flood.c
  font.c
  fsel.c
  gfx.c
  glyph.c
  graphics.c
  gsprite.c
  gui.c
  guiproc.c
  inline.c
  joystick.c
  keyboard.c
  lbm.c
  libc.c
  math.c
  math3d.c
  midi.c
  mixer.c
  modesel.c
  mouse.c
  pcx.c
  poly3d.c
  polygon.c
  quantize.c
  quat.c
  readbmp.c
  rle.c
  rotate.c
  scene3d.c
  sound.c
  spline.c
  stream.c
  text.c
  tga.c
  timer.c
  unicode.c
  vtable.c
  vtable15.c
  vtable16.c
  vtable24.c
  vtable32.c
  vtable8.c