Blame gdk-pixbuf/pixops/timescale.c

Packit a4058c
/*
Packit a4058c
 * Copyright (C) 2000 Red Hat, Inc
Packit a4058c
 *
Packit a4058c
 * This library is free software; you can redistribute it and/or
Packit a4058c
 * modify it under the terms of the GNU Lesser General Public
Packit a4058c
 * License as published by the Free Software Foundation; either
Packit a4058c
 * version 2 of the License, or (at your option) any later version.
Packit a4058c
 *
Packit a4058c
 * This library is distributed in the hope that it will be useful,
Packit a4058c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a4058c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a4058c
 * Lesser General Public License for more details.
Packit a4058c
 *
Packit a4058c
 * You should have received a copy of the GNU Lesser General Public
Packit a4058c
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit a4058c
 */
Packit a4058c
#include "config.h"
Packit a4058c
#include <glib.h>
Packit a4058c
#include <string.h>
Packit a4058c
#include <stdlib.h>
Packit a4058c
#include <stdio.h>
Packit a4058c
Packit a4058c
#include "pixops.h"
Packit a4058c
Packit a4058c
static GTimeVal start_time;
Packit a4058c
Packit a4058c
static void 
Packit a4058c
start_timing (void)
Packit a4058c
{
Packit a4058c
  g_get_current_time (&start_time);
Packit a4058c
}
Packit a4058c
Packit a4058c
static double
Packit a4058c
stop_timing (const char *test, int iterations, int bytes)
Packit a4058c
{
Packit a4058c
  GTimeVal stop_time;
Packit a4058c
  double msecs;
Packit a4058c
  
Packit a4058c
  g_get_current_time (&stop_time);
Packit a4058c
  if (stop_time.tv_usec < start_time.tv_usec)
Packit a4058c
    {
Packit a4058c
      stop_time.tv_usec += 1000000;
Packit a4058c
      stop_time.tv_sec -= 1;
Packit a4058c
    }
Packit a4058c
Packit a4058c
  msecs = (stop_time.tv_sec - start_time.tv_sec) * 1000. +
Packit a4058c
          (stop_time.tv_usec - start_time.tv_usec) / 1000.;
Packit a4058c
Packit a4058c
  printf("%s%d\t%.1f\t\t%.2f\t\t%.2f\n",
Packit a4058c
	 test, iterations, msecs, msecs / iterations, ((double)bytes * iterations) / (1000*msecs));
Packit a4058c
Packit a4058c
  return ((double)bytes * iterations) / (1000*msecs);
Packit a4058c
}
Packit a4058c
Packit a4058c
static void
Packit a4058c
init_array (double times[3][3][4])
Packit a4058c
{
Packit a4058c
  int i, j, k;
Packit a4058c
  
Packit a4058c
  for (i=0; i<3; i++)
Packit a4058c
    for (j=0; j<3; j++)
Packit a4058c
      for (k=0; k<4; k++)
Packit a4058c
	times[i][j][k] = -1;
Packit a4058c
}
Packit a4058c
Packit a4058c
static void
Packit a4058c
dump_array (double times[3][3][4])
Packit a4058c
{
Packit a4058c
  int i, j;
Packit a4058c
  
Packit a4058c
  printf("        3\t4\t4a\n");
Packit a4058c
  for (i=0; i<3; i++)
Packit a4058c
    {
Packit a4058c
      for (j=0; j<4; j++)
Packit a4058c
	{
Packit a4058c
	  if (j == 0)
Packit a4058c
	    switch (i)
Packit a4058c
	      {
Packit a4058c
	      case 0:
Packit a4058c
		printf("3  ");
Packit a4058c
		break;
Packit a4058c
	      case 1:
Packit a4058c
		printf("4  ");
Packit a4058c
		break;
Packit a4058c
	      case 2:
Packit a4058c
		printf("4a ");
Packit a4058c
		break;
Packit a4058c
	      }
Packit a4058c
	  else
Packit a4058c
	    printf("   ");
Packit a4058c
Packit a4058c
	  printf("%6.2f  %6.2f   %6.2f",
Packit a4058c
		 times[i][0][j], times[i][1][j], times[i][2][j]);
Packit a4058c
Packit a4058c
	  switch (j)
Packit a4058c
	    {
Packit a4058c
	    case PIXOPS_INTERP_NEAREST:
Packit a4058c
	      printf ("  NEAREST\n");
Packit a4058c
	      break;
Packit a4058c
	    case PIXOPS_INTERP_TILES:
Packit a4058c
	      printf ("  TILES\n");
Packit a4058c
	      break;
Packit a4058c
	    case PIXOPS_INTERP_BILINEAR:
Packit a4058c
	      printf ("  BILINEAR\n");
Packit a4058c
	      break;
Packit a4058c
	    case PIXOPS_INTERP_HYPER:
Packit a4058c
	      printf ("  HYPER\n");
Packit a4058c
	      break;
Packit a4058c
	    }
Packit a4058c
	}
Packit a4058c
    }
Packit a4058c
  printf("\n");
Packit a4058c
}
Packit a4058c
Packit a4058c
#define ITERS 10
Packit a4058c
Packit a4058c
int main (int argc, char **argv)
Packit a4058c
{
Packit a4058c
  int src_width, src_height, dest_width, dest_height;
Packit a4058c
  unsigned char *src_buf, *dest_buf;
Packit a4058c
  int src_index, dest_index;
Packit a4058c
  int i;
Packit a4058c
  double scale_times[3][3][4];
Packit a4058c
  double composite_times[3][3][4];
Packit a4058c
  double composite_color_times[3][3][4];
Packit a4058c
Packit a4058c
  if (argc == 5)
Packit a4058c
    {
Packit a4058c
      src_width = atoi(argv[1]);
Packit a4058c
      src_height = atoi(argv[2]);
Packit a4058c
      dest_width = atoi(argv[3]);
Packit a4058c
      dest_height = atoi(argv[4]);
Packit a4058c
    }
Packit a4058c
  else if (argc == 1)
Packit a4058c
    {
Packit a4058c
      src_width = 343;
Packit a4058c
      src_height = 343;
Packit a4058c
      dest_width = 711;
Packit a4058c
      dest_height = 711;
Packit a4058c
    }
Packit a4058c
  else
Packit a4058c
    {
Packit a4058c
      fprintf (stderr, "Usage: scale [src_width src_height dest_width dest_height]\n");
Packit a4058c
      exit(1);
Packit a4058c
    }
Packit a4058c
Packit a4058c
Packit a4058c
  printf ("Scaling from (%d, %d) to (%d, %d)\n\n", src_width, src_height, dest_width, dest_height);
Packit a4058c
Packit a4058c
  init_array (scale_times);
Packit a4058c
  init_array (composite_times);
Packit a4058c
  init_array (composite_color_times);
Packit a4058c
Packit a4058c
  for (src_index = 0; src_index < 3; src_index++)
Packit a4058c
    for (dest_index = 0; dest_index < 3; dest_index++)
Packit a4058c
      {
Packit a4058c
	int src_channels = (src_index == 0) ? 3 : 4;
Packit a4058c
	int src_has_alpha = (src_index == 2);
Packit a4058c
	int dest_channels = (dest_index == 0) ? 3 : 4;
Packit a4058c
	int dest_has_alpha = (dest_index == 2);
Packit a4058c
	
Packit a4058c
	int src_rowstride = (src_channels*src_width + 3) & ~3;
Packit a4058c
	int dest_rowstride = (dest_channels *dest_width + 3) & ~3;
Packit a4058c
Packit a4058c
	int filter_level;
Packit a4058c
Packit a4058c
	src_buf = g_malloc(src_rowstride * src_height);
Packit a4058c
	memset (src_buf, 0x80, src_rowstride * src_height);
Packit a4058c
	
Packit a4058c
	dest_buf = g_malloc(dest_rowstride * dest_height);
Packit a4058c
	memset (dest_buf, 0x80, dest_rowstride * dest_height);
Packit a4058c
Packit a4058c
	for (filter_level = PIXOPS_INTERP_NEAREST ; filter_level <= PIXOPS_INTERP_HYPER; filter_level++)
Packit a4058c
	  {
Packit a4058c
	    printf ("src_channels = %d (%s); dest_channels = %d (%s); filter_level=",
Packit a4058c
		    src_channels, src_has_alpha ? "alpha" : "no alpha",
Packit a4058c
		    dest_channels, dest_has_alpha ? "alpha" : "no alpha");
Packit a4058c
	    switch (filter_level)
Packit a4058c
	      {
Packit a4058c
	      case PIXOPS_INTERP_NEAREST:
Packit a4058c
		printf ("PIXOPS_INTERP_NEAREST\n");
Packit a4058c
		break;
Packit a4058c
	      case PIXOPS_INTERP_TILES:
Packit a4058c
		printf ("PIXOPS_INTERP_TILES\n");
Packit a4058c
		break;
Packit a4058c
	      case PIXOPS_INTERP_BILINEAR:
Packit a4058c
		printf ("PIXOPS_INTERP_BILINEAR\n");
Packit a4058c
		break;
Packit a4058c
	      case PIXOPS_INTERP_HYPER:
Packit a4058c
		printf ("PIXOPS_INTERP_HYPER\n");
Packit a4058c
		break;
Packit a4058c
	      }
Packit a4058c
Packit a4058c
	    printf("\t\t\titers\ttotal\t\tmsecs/iter\tMpixels/sec\t\n");
Packit a4058c
Packit a4058c
Packit a4058c
	    if (!(src_has_alpha && !dest_has_alpha))
Packit a4058c
	      {
Packit a4058c
		start_timing ();
Packit a4058c
		for (i = 0; i < ITERS; i++)
Packit a4058c
		  {
Packit a4058c
		    _pixops_scale (dest_buf, dest_width, dest_height,
Packit a4058c
				   dest_rowstride, dest_channels,
Packit a4058c
				   dest_has_alpha, src_buf, src_width,
Packit a4058c
				   src_height, src_rowstride, src_channels,
Packit a4058c
				   src_has_alpha, 0, 0, 0, 0, 0, 0,
Packit a4058c
				   (double)dest_width / src_width,
Packit a4058c
				   (double)dest_height / src_height,
Packit a4058c
				   filter_level);
Packit a4058c
		  }
Packit a4058c
		scale_times[src_index][dest_index][filter_level] =
Packit a4058c
		  stop_timing ("   scale\t\t", ITERS, dest_height * dest_width);
Packit a4058c
	      }
Packit a4058c
Packit a4058c
	    start_timing ();
Packit a4058c
	    for (i = 0; i < ITERS; i++)
Packit a4058c
	      {
Packit a4058c
		_pixops_composite (dest_buf, dest_width, dest_height,
Packit a4058c
				   dest_rowstride, dest_channels,
Packit a4058c
				   dest_has_alpha, src_buf, src_width,
Packit a4058c
				   src_height, src_rowstride, src_channels,
Packit a4058c
				   src_has_alpha, 0, 0, 0, 0, 0, 0,
Packit a4058c
				   (double)dest_width / src_width,
Packit a4058c
				   (double)dest_height / src_height,
Packit a4058c
				   filter_level, 255);
Packit a4058c
	      }
Packit a4058c
	    composite_times[src_index][dest_index][filter_level] =
Packit a4058c
	      stop_timing ("   composite\t\t", ITERS,
Packit a4058c
			   dest_height * dest_width);
Packit a4058c
Packit a4058c
	    start_timing ();
Packit a4058c
	    for (i = 0; i < ITERS; i++)
Packit a4058c
	      {
Packit a4058c
		_pixops_composite_color (dest_buf, dest_width, dest_height,
Packit a4058c
					 dest_rowstride, dest_channels,
Packit a4058c
					 dest_has_alpha, src_buf, src_width,
Packit a4058c
					 src_height, src_rowstride,
Packit a4058c
					 src_channels, src_has_alpha, 0, 0,
Packit a4058c
					 0, 0, 0, 0,
Packit a4058c
					 (double)dest_width / src_width,
Packit a4058c
					 (double)dest_height / src_height,
Packit a4058c
					 filter_level, 255, 0, 0, 16,
Packit a4058c
					 0xaaaaaa, 0x555555);
Packit a4058c
	      }
Packit a4058c
	    composite_color_times[src_index][dest_index][filter_level] =
Packit a4058c
	      stop_timing ("   composite color\t", ITERS, dest_height * dest_width);
Packit a4058c
Packit a4058c
	    printf ("\n");
Packit a4058c
	  }
Packit a4058c
	printf ("\n");
Packit a4058c
Packit a4058c
	g_free (src_buf);
Packit a4058c
	g_free (dest_buf);
Packit a4058c
      }
Packit a4058c
Packit a4058c
  printf ("SCALE\n=====\n\n");
Packit a4058c
  dump_array (scale_times);
Packit a4058c
Packit a4058c
  printf ("COMPOSITE\n=========\n\n");
Packit a4058c
  dump_array (composite_times);
Packit a4058c
Packit a4058c
  printf ("COMPOSITE_COLOR\n===============\n\n");
Packit a4058c
  dump_array (composite_color_times);
Packit a4058c
  return 0;
Packit a4058c
}