Adding scanlines to a holographic images

Below is the C++ program used to take a pseudo color 8 bits per channel, 3 channel, RAW color interlaced holographic input image and add artificial "TV" scanlines to it. The program does this by first reading in each input image scanline. For each scanline, the program determines whether it needs to switch to drawing the current scanline as a high intensity or low intensity scanline. After the correct drawing mode has been selected, the program just increments through the scanline decreasing each pixel's intensity, if neccessary. The program then writes the current scanline to the output file and repeats this procedure on the next scanline.

It should be noted that the user has control of how many actual image scanlines will be included in each output holo scanline. This control allows for larger images to still have a fixed number of holo scanlines in the resulting output image.

/*******************************************
 Program: Add Scanlines
 Written By: Timothy S. Fox
 Date: September 3, 1999
*******************************************/

#include "stdio.h"
#include "stdlib.h"

main()
{
   int file_width, file_height;
   FILE *img_ptr, *output_ptr;
   int n_written, row, col;
   unsigned char *back_plate_pixels = NULL;
   unsigned char *output_image = NULL;
   char path[80];
   char base_name[] = "holo";

   //how many actual image scanlines do you want to represent
   //each holographic scanline.  In this example, there are
   //1 image scanline per each output holo scanline.

   int number_scanlines_per_holoscanline = 1;
   int displaying_scanline_as_high;

   //malloc memory for scanlines

   back_plate_pixels = (unsigned char *) malloc(9000);
   output_image      = (unsigned char *) malloc(9000);

   file_width  = 700;    /*file width*/
   file_height = 292;    /*file height*/

   printf("image width = %d\n", file_width);
   printf("image height = %d\n", file_height);

   sprintf(path, "Krusty:%s.img", base_name);  //file base name

   img_ptr = fopen(path, "rb");  //open input file

   if (img_ptr == NULL)
     {
       free(back_plate_pixels);
       free(output_image);

       printf("Not able to open background file %s\n", path);
       exit(1);
     }

   printf("background image = %s\n", path);

   //open the output file

   sprintf(path, "Krusty:%s.out", base_name);

   output_ptr = fopen(path, "wb");

   if (output_ptr == NULL)
     {
       fclose(img_ptr);

       free(back_plate_pixels);
       free(output_image);

       printf("Not able to open output file %s for write.\n", path);
       exit(1);
     }

   printf("output image = %s\n", path);

   //lets go through and retrieve each scanline of the input
   //image from the background plate

   //we start by saying the first scanline will be represented
   //at low intensity in the output file

   displaying_scanline_as_high = 1;

   for (row=0; row < file_height; row++)
     {
       //read in a background plate 24 bit pixel scanline

       if (fread((void *) back_plate_pixels, sizeof(char),
              file_width*3, img_ptr) != file_width*3)
         {
           fclose(img_ptr);
           fclose(output_ptr);

           free(back_plate_pixels);
           free(output_image);

           printf("Unable to read background plate scanline
                   %d.\n", row);
	     exit(1);
         }

       //do we need to switch from high intensity scanline
       //to low intensity scanline or vice versa

       if (row % number_scanlines_per_holoscanline == 0)
         {
           if (displaying_scanline_as_high == 1)
             displaying_scanline_as_high = 0;
           else
             displaying_scanline_as_high = 1;
         }

       //are we going to display the scanline at low intensity?

       if (displaying_scanline_as_high == 0)
        {
          for (col=0; col < file_width; col++)
           {
             //we are currently reducing the scanline to 35%
             //of its input intensity

             output_image[col*3]  = back_plate_pixels[col*3] *0.35;
             output_image[col*3+1]= back_plate_pixels[col*3+1]*0.35;
             output_image[col*3+2]= back_plate_pixels[col*3+2]*0.35;
            }
         }
       else
         {
           //otherwise the scanline is going to be displayed as
           //a high intensity scanline, which means don't do
           //anything to the scanline except write it back out
           //to the output file

           for (col=0; col < file_width; col++)
             {
               output_image[col*3]   = back_plate_pixels[col*3];
               output_image[col*3+1] = back_plate_pixels[col*3+1];
               output_image[col*3+2] = back_plate_pixels[col*3+2];
             }
         }

       //write the scanline out to the output file

       n_written = fwrite((void *) output_image, sizeof(char),
                          file_width*3, output_ptr);

       if (n_written != file_width*3)
         {
           fclose(img_ptr);
           fclose(output_ptr);

           free(back_plate_pixels);
           free(output_image);

           printf("Unable to write pixel block to output file.\n");
           exit(1);
         }

       printf("wrote out image row %d\n", row);
     }

   //close the input/output files

   fclose(img_ptr);
   fclose(output_ptr);

   //free allocated memory

   free(back_plate_pixels);
   free(output_image);

   exit(0);
}


Last Updated: September 3, 1999
HTML URL: http://geocities.datacellar.net/~special_effect/sw_add_scanlines.html
E-Mail: special_effect@geocities.com or click here
1