Logo Search packages:      
Sourcecode: paul version File versions  Download package

gifload.c

/*****************************************************************************
 *                                                                           *
 * Program:   paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Uses:      libGIF or libUNGIF                                             *
 * Modul:     gifload.c                                                      *
 *            Load also multi-image GIF which imlib does not                 *
 * Author:    Andreas Tille                                                  *
 * Date:      17.04.2000                                                     *
 * Copyright: Andreas Tille, 2000; GNU Public License                        *
 *                                                                           *
 *****************************************************************************/

#include <stdio.h>
#include <gif_lib.h>
#include <unistd.h>
#include <values.h>
#include "paul.h"

GList *PaulLoadGIF(PICTURE *bild, FILE *fp, long flag)
     /* FILE *f, int *w, int *h, int *t */
/* read GIF file
 * --- Parameter: ---
 * PICTURE       *bild         : image structure
 * FILE          *fp           : file pointer which points to open PNG file
 * long           flag         : may be only image info is whished -> ask this flag
 * --- Return: ---
 * PICTURE       *bild         : read image
 * int           *PaulLoadGIF(): RET_ERR or RET_OK
 */
{
  unsigned char      *ptr, *rows, *ap, *fip;
  GifFileType        *gif;
  GifRecordType       rec;
  ColorMapObject     *cmap;
  int                 i,
                      intoffset[] = {0, 4, 2, 1}, intjump[] = {8, 8, 4, 2},
                      istransp, transp,
                      old_size = MAXINT,
                      fd;
  GList              *pl = NULL;
  int                 imgno = 0;
  char               *ext, *dir, *fname;

  g_return_val_if_fail ( IS_PICTURE(bild), NULL);
  g_return_val_if_fail ( fp, NULL);

  istransp = 0;

  fd = fileno(fp);
  /* Apparently rewind(f) isn't sufficient */
  lseek(fd, (long) 0, 0);
  g_return_val_if_fail (gif = DGifOpenFileHandle(fd), NULL);
  transp = -1;
  rows = NULL;

  ext   = bild->ext;
  fname = bild->file;
  dir   = bild->dir;
  do {
    if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
      PrintGifError();
      if ( rec == 0 ) {
      if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
          PrintGifError();
          rec = TERMINATE_RECORD_TYPE;
      }
      }
    }

    if ( rec == IMAGE_DESC_RECORD_TYPE ) {
      if ( DGifGetImageDesc(gif) == GIF_ERROR ) {
        PrintGifError();
        rec = TERMINATE_RECORD_TYPE;
      }

      if ( imgno ) {
        if ( !(bild = InitSpec()) ) {
          DGifCloseFile(gif);
          return pl;;
      }
        if ( ext ) bild->ext  = g_strdup(ext);
        bild->file = g_strdup_printf("%s-%i", fname, imgno);
        if ( dir ) bild->dir  = g_strdup(dir);
      }
      
      bild->DATA = NULL;
      bild->size  = ( bild->W = gif->Image.Width ) * ( bild->H = gif->Image.Height );
      if ( !rows ) rows = g_new0(unsigned char, bild->size);
      if ( old_size < bild->size ) rows = g_renew(unsigned char, rows, bild->size);
      old_size = bild->size;
      bild->DATA = g_new(unsigned char, 3 * bild->size);

      if (gif->Image.Interlace) {
        for (i = 0; i < 4; i++) {
        for (ap = rows + (bild->W * intoffset[i]), fip = rows + bild->size; ap < fip; 
               ap += intjump[i] * bild->W )
          DGifGetLine(gif, ap, bild->W);
        }
      } else {
        for (fip = (ap = rows) + bild->size; ap < fip; ap += bild->W )
          DGifGetLine(gif, ap, bild->W);
      }

      cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
      ptr = bild->DATA;
      for (fip = (ap = rows) + bild->size; ap < fip; ap++ ) {
        if ( *ap == transp) {
          *ptr++ = 0;  /* 255 */
          *ptr++ = 0;
          *ptr++ = 1;  /* 255 muß != 0, sonst kommt graubild heraus */
        } else {
          *ptr++ = cmap->Colors[*ap].Red;
          *ptr++ = cmap->Colors[*ap].Green;
          *ptr++ = cmap->Colors[*ap].Blue;
        }
      }

      imgno++;
      pl = g_list_append(pl, bild);
    } /* rec == IMAGE_DESC_RECORD_TYPE */
    else if (rec == EXTENSION_RECORD_TYPE) {
      int          ext_code;
      GifByteType *ext_type;

      ext_type = NULL;
      DGifGetExtension(gif, &ext_code, &ext_type);
      while (ext_type) {
        if ((ext_code == 0xf9) && (ext_type[1] & 1) && (transp < 0)) {
        istransp = 1;
        transp = (int)ext_type[4];
      }
        ext_type = NULL;
        DGifGetExtensionNext(gif, &ext_type);
      }
    }

  } while (rec != TERMINATE_RECORD_TYPE);
  DGifCloseFile(gif);
  g_free(rows);
  /*  *t = istransp; */
  return pl;
}


Generated by  Doxygen 1.6.0   Back to index