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

histogrm.c

/*****************************************************************************
 *                                                                           *
 * Program:   paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Modul:     histogrm.c                                                     *
 *            Functions to calculate and display image histograms            *
 * Author:    Andreas Tille                                                  *
 * Date:      18.05.1998                                                     *
 * Copyright: Andreas Tille, 1999; GNU Public License                        *
 *                                                                           *
 *****************************************************************************/

#ifdef HAVE_DATABOX
#include <gtkdatabox.h>
#endif

#include "paul.h"

const char *histfile = HISTFILE,
           *vprofile = VPROFILE;

static int CalculateHistogram(PICTURE *bild)
/* calculate histogram of an image
 * --- Parameter: ---
 * PICTURE *bild               : image data
 * --- Return: ---
 * int     CalculateHistogram(): RET_ERR or RET_OK
 * PICTURE *bild->his          : histogram data
 */
{
  register unsigned char *buf, *fip;
  register unsigned long *his;
  unsigned char          *anf, *end;

  g_return_val_if_fail ( IS_PICTURE(bild), RET_ERR );
  
  if ( !bild->his )
    bild->his = g_new0(unsigned long, bild->storepix * 0x100);

  if ( IsMonochrom(bild) )
    for ( fip = (buf = bild->DATA + 1) + bild->storepix*bild->size; buf < fip; 
          buf += bild->storepix ) 
      ++*(bild->his + (*(int *)buf & 0xFF));
  else
    for ( end = (anf = bild->DATA) + 3, his = bild->his; anf < end; anf++, his += 0x100 )
      for ( fip = (buf = anf) + bild->spp*bild->size; buf < fip; buf += bild->spp ) 
        ++*(his + (*(int *)buf & 0xFF));
  return RET_OK;
}

static int MakeVerticalProfile(PICTURE *bild)
/* calculate vertical profile of green values of an image
 * --- Parameter: ---
 * PICTURE *bild                : image data
 * --- Return: ---
 * int     MakeVerticalProfile(): RET_OK or RET_ERR
 */
{
  register unsigned long *his;
  register int            storepix;
  register unsigned char *ap, *fap, *buf, *fip;
  unsigned long          *fis;

  g_return_val_if_fail ( IS_PICTURE(bild), RET_ERR );
  
  storepix = bild->storepix;
  FREE(bild->his);
  bild->his = g_new0(unsigned long, bild->H);

  for ( fip = (buf = bild->DATA + (storepix==3?1:0)) + storepix*bild->size, 
        his = bild->his; buf < fip; buf = fap, his++ )
    for ( fap = (ap = buf) + storepix*bild->W; ap < fap; ap += storepix )
      *his += (unsigned long)*ap;
  storepix = bild->W >> 1;
  for ( fis = (his = bild->his) + bild->H; his < fis; his++ )
    *his = (*his + storepix) / bild->W;
  return RET_OK;
}

int PrintHistograms(GList *piclist)
/* calculate histograms and vertical profiles of all images and print them into file
 * --- Parameter: ---
 * GList *piclist           : list with image data
 * --- Return: ---
 * int    PrintHistograms() : RET_ERR or RET_OK
 */
{
  FILE     *fp;
  char     RGB[] = "RGB";
  int      j, l, len, rgb = 0;
  PICTURE *bild;
  GList   *pl;
      
  g_return_val_if_fail ( BILD(piclist), RET_ERR );

  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) 
    CalculateHistogram(bild);

  Backup(histfile);
  g_return_val_if_fail ( (fp = fopen(histfile, "w")), RET_ERR );
  
  fprintf(fp, "%3c", ' ');
  len = 1;
  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) {
    if ( (l = strlen(bild->file)) > len ) len = l;
    if ( !IsMonochrom(bild) )             rgb = 1;
  }
  len += 1 + rgb*4;  /* 4 Zeichen für _[c], c aus [RGB] */
  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) 
    if ( IsMonochrom(bild) )
      fprintf(fp, "%*s", len, bild->file);
    else
      for ( l = 0; l < 3; l++ )
        fprintf(fp, "%*s_[%c]", len-4, bild->file, RGB[l]);

  for ( j = 0; j < 0x100; j++ ) {
    fprintf(fp, "\n%3i", j);
    for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) 
      if ( IsMonochrom(bild) )
        fprintf(fp, "%*li", len, bild->his[j]);
      else
        for ( l = 0; l < 3; l++ )
          fprintf(fp, "%*li", len, bild->his[j+l*0x100]);
  }
  fclose(fp);
  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) {
    FREE(bild->his);
    MakeVerticalProfile(bild);
  }
   
  Backup(vprofile);
  g_return_val_if_fail ( (fp = fopen(vprofile, "w")), RET_ERR ) ;
  
  fprintf(fp, "%3c", ' ');
  len = 1;
  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) )
    if ( (l = strlen(bild->file)) > len ) len = l;
  len += 1; 
  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) )
    fprintf(fp, "%*s", len, bild->file);

  for ( j = 0; /* stop via break */ ; j++ ) {
    for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) )
      if ( j < bild->H ) break;
    if ( !pl ) break;
    fprintf(fp, "\n%3i", j+1);
    for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) )
      if ( j < bild->H ) 
        fprintf(fp, "%*lu", len, bild->his[j]);
      else
        fprintf(fp, "%*c", len, ' ');
  }
  fclose(fp);
  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) )
    FREE(bild->his);
  return RET_OK;
}

            
/*****************************************************************************************
 * Callback for displaying histograms of images                                          *
 * related to: Set of images                                                             *
 *****************************************************************************************/

int ShowHistograms(GList *piclist)
/* display histogram of all images in piclist
 * --- Parameter: ---
 * GList *piclist          : list with image data
 * --- Return: ---
 * int    ShowHistograms() : RET_ERR or RET_OK
 */
{
#ifdef HAVE_DATABOX /* No graphical display if libgtkdtabox does not exist */
#define HIST_POINTS 256
  static GtkWidget *window = NULL;
  GtkWidget        *curve;
  char             *buf;
  int               col, colstep, i, j, index = 0;
  gfloat           *X, *Y;
  PICTURE          *bild;
  GList            *pl;
  GdkColor          color;
  
  g_return_val_if_fail ( BILD(piclist), RET_ERR );

  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) 
    CalculateHistogram(bild);

  if ( window ) {
    if (!GTK_WIDGET_VISIBLE(window) ) gtk_widget_show_all(window);
    else {
      CurveWidgetDestroy(window, NULL);
      window = NULL;
    }
    return RET_OK;
  }

  if ( NBILDER(piclist) == 1 ) 
    buf = g_strdup_printf(_("Histogram of %s"), BILD(piclist)->file);
  else
    buf = g_strdup(_("Histograms"));

  curve = GTK_WIDGET(gtk_databox_new());
  gtk_signal_connect(GTK_OBJECT(curve), "destroy", GTK_SIGNAL_FUNC(gtk_databox_data_destroy_all),
                     NULL);
  window = CreateDataboxFrame(curve, buf);
  FREE(buf);
  
  X = g_new0(gfloat, HIST_POINTS);

  for ( i = 0; i < HIST_POINTS; i++ ) X[i] = i;
  
  colstep = (col = 0xFFFF) / NBILDER(piclist);

  for ( bild = BILD(pl = piclist); pl; bild = BILD(pl = pl->next) ) {
    if ( IsMonochrom(bild) ) {
      Y = g_new0(gfloat, HIST_POINTS);
      for (i = 0; i < HIST_POINTS; i++ ) 
        Y[i] = bild->his[i];
      color.red = color.green = color.blue = col;
      if ( ! index ) 
        index = gtk_databox_data_add_x_y(GTK_DATABOX(curve), HIST_POINTS, X, Y, color, 
                                         GTK_DATABOX_POINTS, 0);
      else
        gtk_databox_data_add_y(GTK_DATABOX(curve), HIST_POINTS, Y, index, color, 
                               GTK_DATABOX_POINTS, 0);

    } else {
      for ( j = 0; j < 3; j++ ) {
        Y=g_new0(gfloat, HIST_POINTS);
        color.red = color.green = color.blue = 0;
        switch ( j ) {
          case 0: color.red   = col; break;
          case 1: color.green = col; break;
          case 2: color.blue  = col; break;
        }
        for (i = 0; i < HIST_POINTS; i++ ) 
          Y[i]   = bild->his[i + j*HIST_POINTS];

        if ( !index ) 
          index = gtk_databox_data_add_x_y(GTK_DATABOX(curve), HIST_POINTS, X, Y, color, 
                                           GTK_DATABOX_POINTS, 0);
        else
          gtk_databox_data_add_y(GTK_DATABOX(curve), HIST_POINTS, Y, index, color, 
                                 GTK_DATABOX_POINTS, 0);
      }
    }
    col -= colstep;
  }
  gtk_databox_rescale(GTK_DATABOX(curve));
  gtk_widget_show(curve);

  return RET_OK;
#undef HIST_POINTS
#endif
}
 

Generated by  Doxygen 1.6.0   Back to index