Please consider a donation to the Higher Intellect project. See https://preterhuman.net/donate.php or the Donate to Higher Intellect page for more info.

Imagelines.c

From Higher Intellect Vintage Wiki
Jump to navigation Jump to search
#include <stdio.h>
#include <stdlib.h>
#include <dmedia/dm_params.h>
#include <dmedia/dm_image.h>
#include <assert.h>

int height=8, width=50;
int orient=DM_IMAGE_TOP_TO_BOTTOM, interleave=DM_IMAGE_INTERLACED_EVEN;
int interlaced;
int even;

unsigned char *data;
int *spatial_to_memory;
int *temporal_to_memory;

unsigned char *get_image_data(void)
{
  data = malloc(2 * height * width);
  spatial_to_memory = malloc(sizeof(int) * height);
  temporal_to_memory = malloc(sizeof(int) * height);
  return data;
}

DMparams *get_image_params(void)
{
  DMparams *p;
  dmParamsCreate(&p);

  dmSetImageDefaults(p, width, height, DM_IMAGE_PACKING_CbYCrY);
  dmParamsSetEnum(p, DM_IMAGE_ORIENTATION, orient);
  dmParamsSetEnum(p, DM_IMAGE_INTERLACING, interleave);

  return p;
}

int detect_whether_signal_is_interlaced(void)
{
  return interlaced;
}

int detect_whether_frame_parity_is_even(void)
{
  return even;
}

void error(char *msg)
{
  printf("%s\n", msg);
}

int find_index_of(int item, int *array) /* assumes item is present */
{
  int i;
  for(i=0; i < height; i++)
    if (array[i] == item)
      return i;
  return -1;
}
   

void doit(void)
{
  unsigned char *image = get_image_data(); /* the image data */
  DMparams *imageparams = get_image_params(); /* MV/DM params for image */
  int height = dmParamsGetInt(imageparams, DM_IMAGE_HEIGHT);
  int bytes_per_line = dmImageFrameSize(imageparams) / height;
  int i;

  /* our goal is to use DM_IMAGE_INTERLACING and DM_IMAGE_ORIENTATION
   * to compute the following four boolean variables:
   */
  int signal_is_interlaced;     /* signal: interlaced vs. progressive scan */
  int even;                     /* signal: frame parity */
  int full_frame;               /* in-memory: frame layout */
  int bottom_to_top;            /* in-memory: orientation */

  switch (dmParamsGetEnum(imageparams, DM_IMAGE_INTERLACING))
    {
    case DM_IMAGE_INTERLACED_ODD:
      /* implies interlaced signal, odd parity, split-field */
      signal_is_interlaced = 1;
      even = 0;
      full_frame = 0;
      break;
    case DM_IMAGE_INTERLACED_EVEN: 
      /* implies interlaced signal, even parity, split-field */
      signal_is_interlaced = 1;
      even = 1;
      full_frame = 0;
      break;
    case DM_IMAGE_NONINTERLACED:
      /* implies full-frame.
       *
       * DM_IMAGE_INTERLACING==DM_IMAGE_NONINTERLACED could refer
       * to either a progressive-scan or an interlaced signal.
       * we'll need that information in order to traverse all the
       * lines in temporal order.
       */
      signal_is_interlaced = detect_whether_signal_is_interlaced();
      if (signal_is_interlaced)
        {
          /*
           * DM_IMAGE_INTERLACING==DM_IMAGE_NONINTERLACED also doesn't 
           * imply a frame parity.  we'll need this in order to tell
           * which field is temporally first.
           */
          even = detect_whether_frame_parity_is_even();
        }
      full_frame = 1;
      break;
    default: 
      error("unsupported DM_IMAGE_INTERLACING");
      return;
    }

  if (!full_frame) /* split field: fields always same size */
    assert(height % 2 == 0);

  switch (dmParamsGetEnum(imageparams, DM_IMAGE_ORIENTATION))
    {
    case DM_IMAGE_TOP_TO_BOTTOM:
      /*
       * with top to bottom orientation,
       * - full frame images and each field of split-field images: 
       *     spatially lower (and thus temporally later) lines 
       *     are at higher memory addresses.
       * - split-field images:
       *     the temporally later field is at a higher memory address.
       */
      bottom_to_top = 0;
      break;
    case DM_IMAGE_BOTTOM_TO_TOP:
      /*
       * with bottom to top orientation,
       * - full frame images and each field of split-field images: 
       *     spatially higher (and thus temporally earlier) lines 
       *     are at higher memory addresses.
       * - split-field images:
       *     the temporally earlier field is at a higher memory address.
       */
      bottom_to_top = 1;
      break;
    default:
      error("unsupported DM_IMAGE_ORIENTATION");
      return;
    }

  printf("<CENTER><table BORDER=2 CELLPADDING=3 CELLSPACING=2>\n"
         "<td align=left colspan=3>Parameters:<UL>\n");
  
  printf("<LI>DM_IMAGE_ORIENTATION==");
  switch (dmParamsGetEnum(imageparams, DM_IMAGE_ORIENTATION))
    {
    case DM_IMAGE_TOP_TO_BOTTOM:
      printf("DM_IMAGE_TOP_TO_BOTTOM\n");
      break;
    case DM_IMAGE_BOTTOM_TO_TOP:
      printf("DM_IMAGE_BOTTOM_TO_TOP\n");
      break;
    }
  printf("<LI>DM_IMAGE_INTERLACING==");
  switch (dmParamsGetEnum(imageparams, DM_IMAGE_INTERLACING))
    {
    case DM_IMAGE_INTERLACED_ODD:
      printf("DM_IMAGE_INTERLACED_ODD\n");
      break;
    case DM_IMAGE_INTERLACED_EVEN: 
      printf("DM_IMAGE_INTERLACED_EVEN\n");
      break;
    case DM_IMAGE_NONINTERLACED:
      printf("DM_IMAGE_NONINTERLACED\n");
      break;
    }
  if (full_frame)
    {
      printf("<LI>signal is %s (not specified by params)\n",
             (signal_is_interlaced ? "interlaced" : "progressive scan"));
      if (signal_is_interlaced)
        printf("<LI>frame parity is %s (not specified by params)\n",
               (even ? "even" : "odd"));
    }  
  printf("</UL><tr><td align=left colspan=3>\n");
  printf("Signal: %d-line %s signal", 
         height, 
         (signal_is_interlaced ? "interlaced" : "progressive scan"));
  if (signal_is_interlaced)
    printf(" (%s frame parity)", (even ? "even" : "odd"));
  printf("<BR>\n");
  printf("Memory: %s representation with %s orientation\n",
         (full_frame ? "full frame" : "split field"),
         (bottom_to_top ? "bottom-to-top" : "top-to-bottom"));
  printf("<tr>\n");

  for(i=0; i < height; i++) /* traverse spatially from top to bottom */
    {
      int line;

      /* first compute line assuming top-to-bottom orientation */

      if (full_frame) /* full frame -- image already in spatial order! */
        line = i;
      else /* split field representation */
        {
          if ( even ^ ((i%2)==1) )
            line = i/2;            /* temporally first field */
          else
            line = height/2 + i/2; /* temporally second field */
        }
      
      if (bottom_to_top) /* adjust if bottom-to-top */
        line = height - line - 1;

      /* access first byte of that line */
      *(image + line*bytes_per_line) = 0xff;
      spatial_to_memory[i] = line;
    }

  for(i=0; i < height; i++) /* traverse temporally from earliest to latest */
    {
      int line;
      
      /* first compute line assuming top-to-bottom orientation */

      if (signal_is_interlaced)
        {
          if (full_frame) /* full frame */
            {
              if ( even ^ (i >= height/2) )
                line = 2*(i % (height/2));     /* temporally first field */
              else
                line = 2*(i % (height/2)) + 1; /* temporally second field */
            }
          else /* split fields -- image already in temporal order */
            line = i;
        }
      else /* progressive scan -- image already in temporal order */
        line = i;

      if (bottom_to_top) /* adjust if bottom-to-top */
        line = height - line - 1;
      
      /* access first byte of that line */
      *(image + line*bytes_per_line) = 0xff;
      temporal_to_memory[i] = line;
    }
  printf("<th align=center>In-Memory Order<BR>"
         "(lowest to highest memory address)\n"
         "<th align=center>Spatial Order<BR>"
         "(highest to lowest vertical position)\n"
         "<th align=center>Temporal Order<BR>"
         "(earliest to latest data)\n"
         "<tr>");
  {
    int q;
    printf("<td align=left>\n");
    for(q=0; q < height; q++)
      {
        printf("<STRONG>Memory:%d</STRONG>   Space:%d   Time:%d<BR>\n",
               q,
               find_index_of(q, spatial_to_memory),
               find_index_of(q, temporal_to_memory)
               );
      }
    printf("<td align=left>\n");
    for(q=0; q < height; q++)
      {
        printf("Memory:%d   <STRONG>Space:%d</STRONG>   Time:%d<BR>\n",
               spatial_to_memory[q],
               q,
               find_index_of(spatial_to_memory[q],temporal_to_memory)
               );
      }
    printf("<td align=left>\n");
    for(q=0; q < height; q++)
      {
        printf("Memory:%d   Space:%d   <STRONG>Time:%d</STRONG><BR>\n",
               temporal_to_memory[q],
               find_index_of(temporal_to_memory[q], spatial_to_memory),
               q
               );
      }
    printf("<tr>\n");
  }
  printf("</table><P>\n</CENTER>");
}

int main( int argc, char **argv )
{
  int c;

  while ((c = getopt(argc, argv, "h:w:tbeon1:2:")) != EOF) 
    {
      switch(c) 
	{
        case 'h': height = atoi(optarg); break;
        case 'w': width = atoi(optarg); break;
        case 't': orient = DM_IMAGE_TOP_TO_BOTTOM; break;
        case 'b': orient = DM_IMAGE_BOTTOM_TO_TOP; break;
        case 'e': interleave = DM_IMAGE_INTERLACED_EVEN; break;
        case 'o': interleave = DM_IMAGE_INTERLACED_ODD; break;
        case 'n': interleave = DM_IMAGE_NONINTERLACED; break;
        case '1': interlaced = atoi(optarg); break;
        case '2': even = atoi(optarg); break;
        default: printf("huh?\n"); exit(2);
        }
    }

  doit();  
  return 0;
}