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

paulload.c

/*****************************************************************************
 *                                                                           *
 * Programm:  paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Uses:      GTK+ 1.2, Imlib >= 1.9.2 !!!!                                  *
 * Modul:     paulload.c                                                     *
 *            strongly modified load.c from gdk_imlib (version 1.9.2)        *
 *            new: at_imlib_set_image_from_data() (modified                  *
 *            imlib_create_image_from_data())                                *
 *            Requires Imlib-Version >= 1.9.2 !!!!!                          *
 * Autor:     Andreas Tille                                                  *
 * Datum:     19.03.1998                                                     *
 * Copyright: Andreas Tille, 1999; GNU Public License                        *
 *                                                                           *
 *****************************************************************************/

#include <sys/param.h>

#include "paul.h"

#define HAVE_LIBJPEG
#define id _gdk_imlib_data
#include <gdk_imlib_private.h>

FILE  *my_gdk_imlib_open_helper(const char *instring, const char *fn, const char *mode);
int    my_gdk_imlib_close_helper(FILE * fp);

GList *LoadPicture(PICTURE *bild, char *file, long flag)
/* Read image file of any format and initialize PICTURE structure(s)
 * --- Parameter: ---
 * char  *file          : filename of image file
 * long  *flag          : flag : what to do 
 * --- Return: ---
 * GList *LoadPicture() : list with new PICTURE structures containing
 *                       contents of file or NULL
 */
{
  int            w, h, trans, read_anything;
  unsigned char *data = NULL;
  char          *sp, *filename;
  FILE          *p = NULL;
  GList         *pl;

  if ( !CheckFile(file) ) return NULL;
  g_return_val_if_fail ( (p = fopen(file, "rb")), NULL ) ;

  filename = g_strdup(file);
  if ( (sp = strrchr(file, '.')) ) {
    *(sp++) = 0;
    bild->ext = g_strdup(sp);
  } else 
    bild->ext = NULL;
   
  if ( (sp = strrchr(file, '/')) ) {
    *(sp++) = 0;
    bild->file = g_strdup(sp);
    bild->dir  = g_strdup(file);
  } else {
    bild->file = g_strdup(file);
    if ( (sp = g_get_current_dir()) ) {
      bild->dir = g_strdup(sp);
      FREE(sp);
    } else
      bild->dir = NULL;
  }
   
  trans = 0;
  if ( _gdk_imlib_ispng(p) ) {
    w = PaulLoadPNG(bild, p, flag, &read_anything);

    if ( !OnlyInfo(flag) && read_anything != bild->H ) 
      g_warning(_("Only %i rows of %i could be read from file %s."), read_anything, bild->H, bild->file);
      
    if ( w == RET_OK || read_anything > 0 ) {
      fclose(p);
      FREE(filename);
      return g_list_append(NULL, bild);
    }
    g_warning(_("File %s seems not to be a PNG file.  Trying convert.  Special info would be lost."), 
              bild->file);
    fseek(p, 0L, SEEK_SET);
  }
  else if ( _gdk_imlib_istiff(p) && !PaulLoadTIFF(bild, p, bild->file, flag) )  {
    fclose(p);
    FREE(filename);
    return g_list_append(NULL, bild);
  }
  else if ( _gdk_imlib_isgif(p) && (pl = PaulLoadGIF(bild, p, flag)) )  {
    fclose(p);
    FREE(filename);
    return pl;
  }
  else if ( _gdk_imlib_isxpm(p) ) {
    if ( !id ) {
     /*  g_LoadXPM() requires a valid internal imlib structure!!        *
      *  This will be simulated by the folowing code                    *
      *  It is enourmous dangerous to do such undocumented stuff!!!!!!  */
       XWindowAttributes   xwa;

       id = g_new(ImlibData, 1);

       if ( gdk_display ) id->x.disp = gdk_display;
       else               id->x.disp = XOpenDisplay(NULL);;
       id->x.root_cmap = 0;
       if ( XGetWindowAttributes(id->x.disp, DefaultRootWindow(id->x.disp), &xwa) && xwa.colormap )
         id->x.root_cmap = xwa.colormap;

       data = (*_gdk_imlib_LoadXPM)(p, &w, &h, &trans);
       if ( !gdk_display ) XCloseDisplay(id->x.disp);
       FREE(id);
    } else
       data = (*_gdk_imlib_LoadXPM)(p, &w, &h, &trans);
  }
  else if ( _gdk_imlib_isbmp(p) ) data = (*_gdk_imlib_LoadBMP)(p, &w, &h, &trans);
  else if ( _gdk_imlib_isjpeg(p)) data = (*_gdk_imlib_LoadJPEG)(p, &w, &h, &trans);
  else if ( _gdk_imlib_ispnm(p) ) data = (*_gdk_imlib_LoadPPM)(p, &w, &h, &trans);

  fclose(p);
  if (!data && (p = my_gdk_imlib_open_helper("%C/convert %s pnm:-", filename, "rb")) ) {
     data = (*_gdk_imlib_LoadPPM)(p, &w, &h, &trans);
     my_gdk_imlib_close_helper(p);
  }

  if ( !data ) {
    g_warning(_("Cannot load image: %s\nAll fallbacks failed."), file);
    FREE(filename);
    FREE(bild->file);
    return NULL;
  }
  bild->DATA = data;
  bild->size = (bild->W = w) * (bild->H = h);
   
  GetPictureSpecs(bild, filename);
  FREE(filename);

  return g_list_append(NULL, bild);
}


GdkImlibImage *at_imlib_set_image_from_data(unsigned char **data, gint w, gint h)
{
  GdkImlibImage *im;
    
  g_return_val_if_fail ( (im = gdk_imlib_create_image_from_data(*data, NULL, w, h)), NULL );
  FREE(*data);
  *data = im->rgb_data;
  
  return im;
}


/** Here I just copy the old helper machanism from imlib/src/utils.c **/

#include <signal.h>
#include <sys/wait.h>

/*
 *    Helper library
 */

static int          hpid;
static void         (*oldpiper) (int);    /* actually sighandler_t but BSD uses sig_t. */

FILE               *
my_gdk_imlib_open_helper(const char *instring, const char *fn, const char *mode)
{
  char                buf[256];     /* This is safe since our input strings */
                                /* are bounded */
  static char        *vec[16];
  char               *p = strdup(instring);
  char               *pp;
  char               *ep;
  int                 vn = 0;
  int                 pid;
  FILE               *fp = NULL;
  char               *ofil = NULL;
  int                 ofd = -1;

  int                 pfd[2];

  if (p == NULL)
    return NULL;

  if (strncmp(instring, "%Q", 2) == 0)
    {
      /*
       *    Generate a quanting pipeline
       */
      fprintf(stderr, "Not currently supported: install ImageMagic.\n");
      return NULL;
    }
  /*
   *    Ok split the instring on spaces and translate
   *      %C %P %F and %s
   *
   *      FIXME: We need to handle a format string that begins
   *      %Q to indicate an 8bit quant in the pipeline first.
   */

  pp = p;

  while (vn < 15)
    {
      while (*pp && isspace(*pp))
      pp++;
      ep = pp;
      while (*ep && !isspace(*ep))
      ep++;
      if (*pp == 0)
      break;
      /* pp->ep is now the input string block */
      if (*ep)
      *ep++ = 0;

      if (strcmp(pp, "%s") == 0)
      vec[vn] = strdup(fn);
      else if (strncmp(pp, "%P/", 3) == 0)
      {
#ifndef __EMX__
        strcpy(buf, NETPBM_PATH);
        strcat(buf, pp + 2);
#else
        strcpy(buf, pp + 3);
#endif
        if ((vec[vn] = strdup(buf)) == NULL)
          break;
      }
      else if (strncmp(pp, "%J", 3) == 0)
      {
        if ((vec[vn] = strdup(DJPEG_PROG)) == NULL)
          break;
      }
      else if (strncmp(pp, "%H", 3) == 0)
      {
        if ((vec[vn] = strdup(CJPEG_PROG)) == NULL)
          break;
      }
      else if (strncmp(pp, "%C/", 3) == 0)
      {
#ifndef __EMX__
        strcpy(buf, CONVERT_PATH);
        strcat(buf, pp + 2);
#else
        strcpy(buf, pp + 3);
#endif
        if ((vec[vn] = strdup(buf)) == NULL)
          break;
      }
      else if (strncmp(pp, ">%s", 3) == 0)
      {
        ofil = pp;
        vn++;
        pp = ep;
        continue;
      }
      else
      {
        if ((vec[vn] = strdup(pp)) == NULL)
          break;
      }
      vn++;
      pp = ep;
    }

  vec[vn] = NULL;

  if (pipe(pfd) == -1)
    goto oops;

#ifdef __EMX__
  setmode(pfd[0], O_BINARY);
  setmode(pfd[1], O_BINARY);
#endif
  if (*mode == 'r')
    {
      fp = fdopen(pfd[0], "r");
      if (fp == NULL)
      goto oops;
    }
  else if (*mode == 'w')
    {
      fp = fdopen(pfd[1], "w");
      if (fp == NULL)
      goto oops;
    }
  else
    goto oops;

  if (ofil != NULL)
    if ((ofd = open(ofil, O_WRONLY | O_TRUNC | O_CREAT)) == -1)
      goto oops;

#ifndef __EMX__
  switch (pid = fork())
    {
    case -1:
      break;
    case 0:
      signal(SIGPIPE, SIG_DFL);
      if (*mode == 'r')
      dup2(pfd[1], 1);
      if (*mode == 'w')
      {
        dup2(pfd[0], 0);
        if (ofd != -1)
          {
            dup2(ofd, 1);
            close(1);
          }
      }
      close(pfd[0]);
      close(pfd[1]);
      execv(vec[0], vec);
      perror(vec[0]);
      /*
       *    This MUST be _exit or we will hit the SIGPIPE
       *      handler in ways we dont want. We want our parent
       *      to flush the inherited file buffers not us.
       */
      _exit(1);
    default:
      hpid = pid;

      if (ofd != -1)
      close(ofd);
      if (*mode == 'r')
      close(pfd[1]);
      else
      close(pfd[0]);
    }
#else
   {
      int flag, tfd0, tfd1;
      flag = fcntl(pfd[0], F_GETFD);
      fcntl(pfd[0], F_SETFD, flag | FD_CLOEXEC);
      flag = fcntl(pfd[1], F_GETFD);
      fcntl(pfd[1], F_SETFD, flag | FD_CLOEXEC);
      tfd0 = dup(0);
      tfd1 = dup(1);
      if (*mode == 'r')
        dup2(pfd[1], 1);
      if (*mode == 'w')
        dup2(pfd[0], 0);
      pid = spawnv(P_NOWAIT, vec[0], vec);
      if (pid != -1) hpid = pid;
      dup2(tfd0, 0);
      dup2(tfd1, 1);
      close(tfd0);
      close(tfd1);
      if (ofd != -1)
        close(ofd);
      if (*mode == 'r')
        close(pfd[1]);
      else
        close(pfd[0]);
   }
#endif
  for (vn = 0; vn < 16; vn++)
    if (vec[vn])
      free(vec[vn]);
  oldpiper = signal(SIGPIPE, SIG_IGN);
  return fp;

oops:
  if (ofd != -1)
    close(ofd);
  if (fp)
    fclose(fp);
  for (vn = 0; vn < 16; vn++)
    if (vec[vn])
      free(vec[vn]);
  return NULL;
}

int
my_gdk_imlib_close_helper(FILE * fp)
{
  int                 info;

  fclose(fp);
  signal(SIGPIPE, oldpiper);
  waitpid(hpid, &info, 0);
  return WEXITSTATUS(info);
}


Generated by  Doxygen 1.6.0   Back to index