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

extrema.c

/*****************************************************************************
 *                                                                           *
 * Programm:  paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Modul:     extrema.c                                                      *
 *            Funktions to obtain extrema of brightness                      *
 * Author:    Andreas Tille                                                  *
 * Date:      04.05.1998                                                     *
 * Copyright: Andreas Tille, 1999; GNU Public License                        *
 *                                                                           *
 *****************************************************************************/

#include <stdio.h>

#include "paul.h"

static int CheckInBounds(PICTURE *bild, BOX *cut)
/* test, whether coordinates bx, by are inside the image
 * --- Parameter: ---
 * PICTURE *bild           : image
 * int     bx              : x-coordinate
 * int     by              : y-coordinate
 * --- Return: ---
 * int     CheckInBounds() : -1 if outside or error, 0 if equal to image, 1 if inside
 */
{
  g_return_val_if_fail ( IS_PICTURE(bild), -1 );
  if ( cut->x1 < 0 || cut->x2 < 0 || cut->y1 < 0 || cut->y2 < 0 ) {
    g_warning("Negative coordinates %s (%i*%i)-(%i,%i)!",
              bild->file, cut->x1, cut->y1, cut->x2, cut->y2);
    return -1;
  }
  if ( cut->x1 > cut->x2 ) iswap(cut->x1, cut->x2);
  if ( cut->y1 > cut->y2 ) iswap(cut->y1, cut->y2);
  if ( (cut->x2 > bild->W) || (cut->y2 > bild->H) ) {
    g_warning("Box outside image %s (%i*%i)!", bild->file, bild->W, bild->H);
    return -1;
  }
  if ( cut->x1 == 0       && cut->y1 == 0 &&
       cut->x2 == bild->W && cut->y2 == bild->H ) {
    g_warning("Box equal to image (%i*%i).", cut->x2-cut->x1, cut->y2-cut->y1);
    return 0;
  }
  return 1;
}


PICTURE *DuplicatePicture(PICTURE *sample)
/* Creates copy of image structure sample
 * --- Parameter: ---
 * PICTURE *sample                    : sample
 * --- Return: ---
 * PICTURE *CreatePictureFromSample() : new image with equal tags to sample
 */
{
  PICTURE *zw;
  CHUNK   *sp, *zp;
  int      nchunks;
   
  g_return_val_if_fail ( IS_PICTURE(sample), NULL );
  zw = g_new(PICTURE, 1);

  zw->id       = sample->id;
  g_return_val_if_fail( (zw->im = gdk_imlib_clone_image(sample->im)), NULL) ;
  if (sample->file) zw->file = g_strdup(sample->file);
  if (sample->ext)  zw->ext  = g_strdup(sample->ext);
  else              zw->ext  = NULL;
  if (sample->dir)  zw->dir  = g_strdup(sample->dir);
  else              zw->dir = NULL;
  zw->size     = sample->size;   
  zw->spp      = sample->spp;
  zw->storepix = sample->storepix;
  zw->trans    = sample->trans;
  zw->res      = sample->res;
  zw->x_offset = sample->x_offset;
  zw->y_offset = sample->y_offset;
  if ( (zw->n_gamma = sample->n_gamma) && sample->gamma ) { 
    zw->gamma = g_new(png_color, zw->n_gamma);
    memcpy((char *)zw->gamma, (char *)sample->gamma, zw->n_gamma*sizeof(png_color));
  } else 
    zw->gamma = NULL;
  zw->his      = NULL;   /* wenn Daten nicht übernommen werden ist Histogramm ungültig */
#ifdef HAVE_LIBFFTW
  zw->fftprof  = NULL;
#endif
  zw->zeit     = sample->zeit;
  for ( sp = sample->spec, nchunks = 1; sp->key != NULL; sp++ ) nchunks++;
  zw->spec = g_new(CHUNK, nchunks);
  for ( sp = sample->spec, zp = zw->spec; sp->key != NULL; sp++, zp++ ) 
     CopyChunk(zp, sp);

  zw->roff_x   = sample->roff_x;
  zw->roff_y   = sample->roff_y;
  zw->flag     = sample->flag;
  /* at least when more than one file is created (extrema) this will fail!!!!!!!!!!!!!!!! */
  return zw;
}


static void Extremum(PICTURE *ext, unsigned char **datamin, unsigned char **datamax, int ex, int ey)
/* examines darkest and brightest area in an image
 * --- Parameter: ---
 * PICTURE *ext           : image structure
 * unsigned char **datamin: pointer to the start of the area of minimum brightness
 * unsigned char **datamax: pointer to the start of the area of maximum brightness
 * int ex                 : width of the area to search for
 * int ey                 : height of the area to search for
 * --- Return: ---
 * unsigned char **datamin: start of the area of minimum brightness
 * unsigned char **datamax: start of the area of maximum brightness
 */
{
  register int            storepix = ext->storepix;
  register unsigned char *ap, *exmax, *exmin;
  register unsigned long  next;
  unsigned char          *bp, *fap, *fbp;
  int                     prz = 0, przstep, iprz = 1;
  unsigned long           min, max, first,
           step = ext->storepix * ext->W * ey,            /* olf box start until new box end */
           sl   = ext->storepix * ext->W * (ext->H - ey); /* length of column                */

  g_return_if_fail ( IS_PICTURE(ext) );

  exmin = exmax = ext->DATA;
  min = max = first = next = brightness(ext->DATA, ex, ey, ext->W, storepix);
  printf(_("Search for extrema of %s: %3i%%"), ext->file, prz);
  przstep = (ext->W - ex + 5) / 10;
  /* first column: */
  for ( fap = (ap = ext->DATA) + sl; ap < fap; ) {
    next += Xsum(ap + step, storepix*ex, 1);
    next -= Xsum(ap, storepix*ex, 1); /* two steps because of unsigned values! */
    ap   += storepix * ext->W;
    if ( next < min ) { min = next; exmin = ap; }
    else if ( next > max ) { max = next; exmax = ap; }
  }

  /* all other columns: */
  for ( fbp = (bp = ext->DATA + storepix) + storepix*(ext->W - ex - 1); bp < fbp; bp += storepix ) {
    if ( (przstep > 0) && (++iprz % przstep == 0) ) {
      printf("\x8\x8\x8\x8%3i%%", prz += 10); 
      fflush(stdout); 
    }
/* DOESN'T WORK FOR storepix==1!!! Ysum HAS TO BE VERIFIED in THAT CASE !!! */
    next = (first += (Ysum(bp+storepix*(ex-1), ey, ext->W) - Ysum(bp-storepix, ey, ext->W) ));
    if ( next < min ) { min = next; exmin = bp; }
    else if ( next > max ) { max = next; exmax = bp; }
    for ( fap = (ap = bp) + sl; ap < fap; ) {
      next += Xsum(ap + step, storepix*ex, 1);
      next -= Xsum(ap, storepix*ex, 1); /* to steps because of unsigned values! */
      ap   += storepix * ext->W;
      if ( next < min ) { min = next; exmin = ap; }
      else if ( next > max ) { max = next; exmax = ap; }
    }
  }
  puts("\x8\x8\x8\x8\x31\x30\x30%"); fflush(stdout);
  *datamin = exmin;
  *datamax = exmax;
}


int Extrema(PAUL *p)
/* estimate brightest and darkest box of given size in set of images
 * --- Parameter: ---
 * PAUL *p         : list of images, options
 *                   used options :
 *                   cut.x2 : width of box
 *                   cut.y2 : height of box
 *                   flag   : search for minima/maxima/both
 * --- Return: ---
 * p->piclist      : images of extrema
 * int   Extrema() : RET_OK or RET_ERR
 */
{
  PICTURE        *bild, *zw;
  BOX             cut[1];
  int             check, bx, by;   
  char           *buf;
  unsigned char  *max, *min;
  register GList *pl;
  GList          *piclist, *minlist = NULL;

  g_return_val_if_fail ( IS_PAUL(p), RET_ERR );
  g_return_val_if_fail ( (p->opt->cut), RET_ERR );
  
  bx = p->opt->cut->x2;
  by = p->opt->cut->y2;   

  g_return_val_if_fail ( CheckPicList(piclist = p->piclist), RET_ERR );

  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) {
    if ( bx < 0 ) continue;
    cut->x1 = cut->y1 = 0;
    cut->x2 = bx; cut->y2 = by;
    if ( (check = CheckInBounds(bild, cut)) < 1 ) continue;
    Extremum(bild, &min, &max, bx, by);
    if ( SaveExtrema(p->opt->f) ) {
      if ( SaveMinima(p->opt->f) ) {
        cut->x1  = (cut->y1 = (min - bild->DATA)/(bild->storepix)) % bild->W;
        cut->y1 /= bild->W;
        cut->x2  = cut->x1 + bx;
        cut->y2  = cut->y1 + by;
        buf = g_strdup_printf("Minimum of %s", bild->file);
        if ( SaveMaxima(p->opt->f) ) {
          zw      = DuplicatePicture(bild);
          minlist = g_list_append(piclist, zw);
        } else 
          zw = bild;
        if ( CutArea(zw, cut, p->opt->f, buf, APPMIN, 0) ) {
          g_warning(_("Minimum of %s wasn't calculated due to wrong box coordinates"), bild->file);
          continue;
        }
        FREE(buf);
        bild->flag |= SAVEMINIMA;
      } 
      if ( SaveMaxima(p->opt->f) ) {
        cut->x1  = (cut->y1 = (max - bild->DATA)/(bild->storepix)) % bild->W;
        cut->y1 /= bild->W;
        cut->x2  = cut->x1 + bx;
        cut->y2  = cut->y1 + by;
        buf = g_strdup_printf("Maximum of %s", bild->file);
        if ( CutArea(bild, cut, p->opt->f, buf, APPMAX, 1) ) {
          g_warning(_("Minimum of %s wasn't calculated due to wrong box coordinates"), bild->file);
          continue;
        }
        FREE(buf);
        bild->flag |= SAVEMAXIMA;
      }
    }
  }
  FREE(p->opt->cut);

  if ( (pl = minlist) ) do {
    p->piclist = g_list_append(p->piclist, BILD(pl));
  } while ( (pl = pl->next) );

  return RET_OK;
}



Generated by  Doxygen 1.6.0   Back to index