Beispiel #1
0
void json_parse_opttexture(jsonvalue json, image3f*& txt, string name) {
    if(not json.object_contains(name)) return;
    auto filename = json.object_element(name).as_string();
    if(filename.empty()) { txt = nullptr; return; }
    auto dirname = json_texture_paths.back();
    auto fullname = dirname + filename;
    if (json_texture_cache.find(fullname) == json_texture_cache.end()) {
        auto ext = fullname.substr(fullname.size()-3);
        if(ext == "pfm") {
            auto image = read_pnm("models/pisa_latlong.pfm", true);
            image = image.gamma(1/2.2);
            json_texture_cache[fullname] = new image3f(image);
        } else if(ext == "png") {
            auto image = read_png(fullname,true);
            json_texture_cache[fullname] = new image3f(image);
        } else error("unsupported image format %s\n", ext.c_str());
    }
    txt = json_texture_cache[fullname];
}
Beispiel #2
0
void init_work(char *base_dir) {
	FILE *fp;
	char *fn;
	char line[100];
	int i,j,k;
	
	load_state();
	
	/* read config file */
	fprintf(stderr, "reading flynn config tree from directory %s\n", base_dir);

	chdir(base_dir);
	
	fn = g_strconcat("gamelist", NULL);
	fp = fopen(fn, "rb");
	g_free(fn);
	
	if (!fp) {
		fprintf(stderr, "could not open game list file.\n");
		flynn_exit(-1);
	}
	
	while (fgets(line, 100, fp)) {
		int len;
		
		if (!(len = strlen(line)))
		continue;
		
		if (line[0] == '#')
		continue;
		
		for (i=0; i<len; i++)
		if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ')
		goto found_non_whitespace;
		
		continue;
		
		found_non_whitespace:
		
		line[--len] = '\0';
		/* fprintf(stderr, "adding game %s\n", line); */
		
		game[num_games].mnemonic = g_strdup(line);
		
		if (isrotated()) {
			game[num_games].ppm_name = g_strconcat("images_106x154/", line, ".ppm", NULL);
		}
		else {
			game[num_games].ppm_name = g_strconcat("images_154x106/", line, ".ppm", NULL);	
		}				
		game[num_games].conf_name = g_strconcat("images_154x106/", line, ".conf", NULL);
		game[num_games].exec_cmd = g_strconcat("./run_game", NULL);
		game[num_games].ppm_loaded = 0;
		
		//printf("loaded %s\n",game[num_games].ppm_name);
		
		num_games++;
	}
	
	fclose(fp);
	
	for (i=0; i<num_games; i++) {
		unsigned char *temp_data;
		int w, h, r;		
		PnmPixformat pf = PNM_RGB;
		printf("Trying to read in %s\n",game[i].ppm_name);		
		r = read_pnm(game[i].ppm_name, &game[i].ppm_data, &w, &h, &pf);
		fn = g_strconcat("default.ppm", NULL);
		
		//printf("%d\n",r);
		
		if (r != 0) {
			printf("Reading in default.ppm\n");
			r = read_pnm(fn, &game[i].ppm_data, &w, &h, &pf); 
		}
		/*if (w != PPM_WIDTH || h != PPM_HEIGHT) {
			if (game[i].ppm_data) {
				free(game[i].ppm_data);
				game[i].ppm_data = NULL;
			}
			printf("Reading in default.ppm\n");
			r = read_pnm(fn, &game[i].ppm_data, &w, &h, &pf);
		}*/
		
		if (w == PPM_HEIGHT && h == PPM_WIDTH && isrotated()) {
			//printf("Trying to rotate %s 90 degrees\n",game[i].mnemonic);			
			r = read_pnm(game[i].ppm_name, &temp_data, &w, &h, &pf);					
			//temp_data = malloc(sizeof(game[i].ppm_data));
			//memcpy(&temp_data,&game[i].ppm_data,sizeof(game[i].ppm_data));
			for (j=h; j>0; j--) {
				for(k=1; k<w+1; k++) {					
					/*game[i].ppm_data[(k*h*3+j*3)-0] = temp_data[(j*w*3+k*3)-0];
					game[i].ppm_data[(k*h*3+j*3)-1] = temp_data[(j*w*3+k*3)-1];
					game[i].ppm_data[(k*h*3+j*3)-2] = temp_data[(j*w*3+k*3)-2];*/
					
					game[i].ppm_data[k*h*3-j*3-0] = temp_data[j*w*3+k*3-0];
					game[i].ppm_data[k*h*3-j*3-1] = temp_data[j*w*3+k*3-1];
					game[i].ppm_data[k*h*3-j*3-2] = temp_data[j*w*3+k*3-2];
				}
			}
			/*free(temp_data);
			temp_data = NULL;*/
		}		
		
		if (game[i].ppm_data && !r) {
			game[i].ppm_loaded = 1;	  
		}
		else {			
			fprintf(stderr, "ppm for %s is missing or inappropriate\n", game[i].mnemonic);
		}		
	}
	
	idle_restart();
	timeout_restart();
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    printf("\n");
    printf("%15c########################################\n", ' ');
    printf("%15c# Image Manipulation Program for CS350 #\n", ' ');
    printf("%15c#        NOW WITH MORE THREADS!!!!     #\n", ' ');
    printf("%15c########################################\n\n", ' ');

    if (argc != 5) {
	printf
	    ("Wrong inputs: Run as: %s inFile outFile scaleFactor threads\n\n",
	     argv[0]);
	printf("bye bye....\n");
	return 0;
    }

    image_ptr imagePtr;		/* Image Read In */
    int rows, cols, type, s = atoi(argv[3]);
    imagePtr = read_pnm(argv[1], &rows, &cols, &type);
    int requestedThreads = atoi(argv[4]);

    /* Something about having an array representation of this image data
     * rather than a linear representation seems much more intuitive */
    int nonlin[rows][cols];
    int i, j;
    for (i = 0; i < rows; i++) {
	for (j = 0; j <= cols; j++) {
	    nonlin[i][j] = imagePtr[i * cols + j];
	}
    }

    /* Allocate space for the image we're going to write OUT */
    unsigned char outputImage[rows / s][cols / s];

    /* Welcome to McDonalds.. bla bla bla */
    printf("Input File: %s\n", argv[1]);
    printf("Output File: %s\n", argv[2]);
    printf("Scale Factor: %d\n", s);
    printf("Input image has: \n %d rows\n %d cols\n", rows, cols);
    printf("Resulting image will have: \n %d rows\n %d cols\n", rows / s,
	   cols / s);
    printf
	("Process will try to run using %d thread server(s) at a time\n\n",
	 requestedThreads);

    pthread_t threads[cols / s];	/* Map of all the threads */
    int rc, workingCols = 0, threadsCreated = 0, remainingChunks =
	rows / s, threadJoining;
    long int status;		/* passed to pthread_join as an address so we can check on their finishing status */

    struct imgArgs threadStructs[cols / s];

    /* here's the process..... 
     * make batches of threads up to requestedThreads
     * keep doing that and making sure they all finish executing (join each) UNTIL...
     * remaining chunks <= requestedThreads
     * move to the "catch all run" of thread building.
     * this last thread initialization will create <= requestedThreads.
     * we only ever had alive UP TO 'requestedThreads' at once because we can only run with 
     * 'requestedThreads' server threads (read from argv[4])
     * ....
     * along the way we keep track of how many have been created to date with 'threadsCreated'
     * each batch uses workingRows to keep track of how many its made in that batch
     * workingCols shall never exceed requestedThreads but MAY be equal to requestedThreads
     */

    printf("Initializing threads...\n");
    int startPoint;
    while (remainingChunks > requestedThreads) {	/* "until remainingChunks <= requested Threads" */
	for (workingCols = 0; workingCols < requestedThreads;
	     workingCols++) {
	    threadStructs[threadsCreated].initColumn = threadsCreated * s;
	    threadStructs[threadsCreated].scale = &s;
	    threadStructs[threadsCreated].rows = &rows;
	    threadStructs[threadsCreated].columns = &cols;
	    threadStructs[threadsCreated].nonlin = &nonlin;
	    threadStructs[threadsCreated].tid = threadsCreated;
	    threadStructs[threadsCreated].newImage = &outputImage;

	    rc = pthread_create(&threads[threadsCreated], NULL, resize,
				(void *) &threadStructs[threadsCreated]);

	    if (rc) {
		printf("ERROR; return code from pthread_create() is %d\n",
		       rc);
		exit(-1);
	    }
	    remainingChunks--;
	    threadsCreated++;
	}			/* End batch thread creation process */

	/* Join the last spawned threads and wait for them all to finish processing before continuing */
	threadJoining = threadsCreated - requestedThreads;	/* Join from where we last started spawning threads */
	for (; threadJoining < threadsCreated; threadJoining++) {
	    rc = pthread_join(threads[threadJoining], &status);
	    if (rc) {
		printf("error joining thread %d\n", threadJoining);
		exit(-1);
	    }

	}			/* End thread joining process */
    }				/* End while: remainingChunks > requestedThreads */


    /* Details at this point: either you requested <= the number of threads required to process the image
     * or we've calculated all the thread batches up to the point where we have (remainingChunks <= requestedThreads)
     */
    for (; threadsCreated < cols / s; threadsCreated++) {
	threadStructs[threadsCreated].initColumn = threadsCreated * s;
	threadStructs[threadsCreated].scale = &s;
	threadStructs[threadsCreated].rows = &rows;
	threadStructs[threadsCreated].columns = &cols;
	threadStructs[threadsCreated].nonlin = &nonlin;
	threadStructs[threadsCreated].tid = threadsCreated;
	threadStructs[threadsCreated].newImage = &outputImage;
	rc = pthread_create(&threads[threadsCreated], NULL, resize,
			    (void *) &threadStructs[threadsCreated]);

	if (rc) {
	    printf("ERROR; return code from pthread_create() is %d\n", rc);
	    exit(-1);
	}
    }

    /* Join the last spawned threads and wait for them all to finish processing before continuing */
    threadJoining = threadsCreated - remainingChunks;	/* Join from where we last started spawning threads */
    for (; threadJoining < threadsCreated; threadJoining++) {
	rc = pthread_join(threads[threadJoining], &status);
	if (rc) {
	    printf("error joining thread %d\n", threadJoining);
	    exit(-1);
	}
    }

    printf("Calculations complete! Writing to file...\n");
    /* Hard work's done, write it to file */
    write_pnm((image_ptr) outputImage, argv[2], rows / s, cols / s, type);
    printf("Wrote: %s to file!\n", argv[2]);

    pthread_exit(NULL);
}
Beispiel #4
0
void init_work(char *base_dir)
{
  FILE *fp;
  char *fn;
  char line[100];
  int i;

  load_state();

  /* read config file */
  fprintf(stderr, "reading flynn config tree from directory %s\n", base_dir);

  chdir(base_dir);

  fn = g_strconcat("gamelist", NULL);
  fp = fopen(fn, "rb");
  g_free(fn);

  if (!fp)
    {
      fprintf(stderr, "could not open game list file.\n");
      flynn_exit(-1);
    }

  while (fgets(line, 100, fp))
    {
      int len;
      
      if (!(len = strlen(line)))
	continue;

      if (line[0] == '#')
	continue;

      for (i=0; i<len; i++)
	if (line[i] != '\n' &&
	    line[i] != '\t' &&
	    line[i] != ' ')
	  goto found_non_whitespace;

      continue;

    found_non_whitespace:

      line[--len] = '\0';
      /* fprintf(stderr, "adding game %s\n", line); */

      game[num_games].mnemonic = g_strdup(line);
      game[num_games].ppm_name = g_strconcat("games/", line, ".ppm", NULL);
      game[num_games].conf_name = g_strconcat("games/", line, ".conf", NULL);
      game[num_games].exec_cmd = g_strconcat("./run_game", NULL);
      game[num_games].ppm_loaded = 0;

      num_games++;
    }

  fclose(fp);

  for (i=0; i<num_games; i++)
    {
      int w, h, r;
      PnmPixformat pf = PNM_RGB;

      r = read_pnm(game[i].ppm_name, &game[i].ppm_data, &w, &h, &pf);

      fn = g_strconcat("default.ppm", NULL);

      if (r)
	r = read_pnm(fn, &game[i].ppm_data, &w, &h, &pf);

      if (w != PPM_WIDTH ||
	  h != PPM_HEIGHT)
	{
	  if (game[i].ppm_data)
	    {
	      free(game[i].ppm_data);
	      game[i].ppm_data = NULL;
	    }
	}

      if (game[i].ppm_data && !r)
	game[i].ppm_loaded = 1;	  
      else
	fprintf(stderr, "ppm for %s is missing or inappropriate\n", game[i].mnemonic);
    }

  idle_restart();
  timeout_restart();
}
Beispiel #5
0
int
read_image(const char *filename, int *width, int *height, 
	   unsigned char *rgb)
{
    char buf[4];
    unsigned char *ubuf = (unsigned char *) buf;
    int success = 0;

    FILE *file;
    file = fopen(filename, "rb");
    if (file == NULL) return(0);
  
    /* see what kind of file we have */

    fread(buf, 1, 4, file);
    fclose(file);

    if (!strncmp("BM", buf, 2))
    {
        success = read_bmp(filename, width, height, rgb);
    }
    else if (!strncmp("GIF8", buf, 4))
    {
#ifdef HAVE_LIBGIF
        success = read_gif(filename, width, height, rgb);
#else
        fprintf(stderr, 
                "Sorry, this program was not compiled with GIF support\n");
        success = 0;
#endif /* HAVE_LIBGIF */
    }
    else if ((ubuf[0] == 0xff) && (ubuf[1] == 0xd8))
    {
#ifdef HAVE_LIBJPEG
        success = read_jpeg(filename, width, height, rgb);
#else
        fprintf(stderr, 
                "Sorry, this program was not compiled with JPEG support\n");
        success = 0;
#endif /* HAVE_LIBJPEG */
    }
    else if ((ubuf[0] == 0x89) && !strncmp("PNG", buf+1, 3))
    {
#ifdef HAVE_LIBPNG
        success = read_png(filename, width, height, rgb);
#else
        fprintf(stderr, 
                "Sorry, this program was not compiled with PNG support\n");
        success = 0;
#endif /* HAVE_LIBPNG */
    }
    else if ((   !strncmp("P6\n", buf, 3))
             || (!strncmp("P5\n", buf, 3))
             || (!strncmp("P4\n", buf, 3))
             || (!strncmp("P3\n", buf, 3))
             || (!strncmp("P2\n", buf, 3))
             || (!strncmp("P1\n", buf, 3)))
    {
#ifdef HAVE_LIBPNM
        success = read_pnm(filename, width, height, rgb);
#else
        fprintf(stderr, 
                "Sorry, this program was not compiled with PNM support\n");
        success = 0;
#endif /* HAVE_LIBPNM */
    }
    else if (((!strncmp ("MM", buf, 2)) && (ubuf[2] == 0x00) 
              && (ubuf[3] == 0x2a))
             || ((!strncmp ("II", buf, 2)) && (ubuf[2] == 0x2a) 
                 && (ubuf[3] == 0x00)))
    {
#ifdef HAVE_LIBTIFF
        success = read_tiff(filename, width, height, rgb);
#else
        fprintf(stderr, 
                "Sorry, this program was not compiled with TIFF support\n");
        success = 0;
#endif
    }
    else
    {
        fprintf(stderr, "Unknown image format\n");
        success = 0;
    }

    return(success);
}
Beispiel #6
0
int main(int argc, char** argv){
	int i, j, num_frames;
	char buf[MAX_PATH_LEN];
	char input_path[MAX_PATH_LEN];
	char output_path[MAX_PATH_LEN];
	struct image input[NUM_STREAMS];
	struct image scaled[NUM_STREAMS];
	struct image big_image;
	
	struct timeval t1, t2, t3, t4;
	double scale_time = 0, total_time = 0;
	
	if (argc != 4){
		printf("Usage: ./serial input_path output_path num_frames\n");
		exit(1);
	}
	
	gettimeofday(&t3, NULL);
	strncpy(input_path, argv[1], MAX_PATH_LEN - 1);
	strncpy(output_path, argv[2], MAX_PATH_LEN - 1);
	num_frames = atoi(argv[3]);
		
	if (num_frames > MAX_FRAMES)
		num_frames = MAX_FRAMES;
		
	for (i = 0; i < num_frames; i++){
		printf("Processing Frame %d\n", i + 1);
		
		//read the input images
		for (j = 0; j < NUM_STREAMS; j++){
			sprintf(buf, "%s/stream%02d/image%d.pnm", input_path, 
				j + 1, i + 1);
			read_pnm(buf, &input[j]);
		}
				
		gettimeofday(&t1, NULL);
		//scale the input images
		for (j = 0; j < NUM_STREAMS; j++){
			scaled[j].height = input[j].height / SCALE_FACTOR;
			scaled[j].width = input[j].width / SCALE_FACTOR;
			alloc_image(&scaled[j]);
			scale_area_avg(&input[j], &scaled[j]);
		}
		//create the big image out of the scaled images
		big_image.height = scaled[0].height * NUM_IMAGES_HEIGHT;
		big_image.width = scaled[0].width * NUM_IMAGES_WIDTH;
		alloc_image(&big_image);
		create_big_image(scaled, &big_image);
		gettimeofday(&t2, NULL);
		scale_time += GET_TIME_DELTA(t1, t2);
		
		//write the big image
		sprintf(buf, "%s/result%d.pnm", output_path, i + 1);
		write_pnm(buf, &big_image);
		
		//free the image data
		for (j = 0; j < NUM_STREAMS; j++){
			free_image(&input[j]);
			free_image(&scaled[j]);
		}
		free_image(&big_image);
	}
	gettimeofday(&t4, NULL);
	total_time += GET_TIME_DELTA(t3, t4);
				
	printf("Scale time: %lf\n", scale_time);
	printf("Total time: %lf\n", total_time);
	
	return 0;
}
Beispiel #7
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct
    {
	struct Option *in, *mask, *alpha, *out, *width, *height, *bg,
	    *outmask;
    } opt;
    int i;

    G_gisinit(argv[0]);

    module = G_define_module();
    module->keywords = _("general, gui");
    module->description = "Overlays multiple PPM image files";

    opt.in = G_define_option();
    opt.in->key = "input";
    opt.in->type = TYPE_STRING;
    opt.in->required = YES;
    opt.in->multiple = YES;
    opt.in->description = _("Names of input files");
    opt.in->gisprompt = "old,cell,raster";

    opt.mask = G_define_option();
    opt.mask->key = "mask";
    opt.mask->type = TYPE_STRING;
    opt.mask->multiple = YES;
    opt.mask->description = _("Names of mask files");
    opt.mask->gisprompt = "old,cell,raster";

    opt.alpha = G_define_option();
    opt.alpha->key = "opacity";
    opt.alpha->type = TYPE_DOUBLE;
    opt.alpha->multiple = YES;
    opt.alpha->description = _("Layer opacities");

    opt.out = G_define_option();
    opt.out->key = "output";
    opt.out->type = TYPE_STRING;
    opt.out->required = YES;
    opt.out->description = _("Name of output file");
    opt.out->gisprompt = "new_file,file,output";

    opt.outmask = G_define_option();
    opt.outmask->key = "outmask";
    opt.outmask->type = TYPE_STRING;
    opt.outmask->required = NO;
    opt.outmask->description = _("Name of output mask file");
    opt.outmask->gisprompt = "new_file,file,output";

    opt.width = G_define_option();
    opt.width->key = "width";
    opt.width->type = TYPE_INTEGER;
    opt.width->required = YES;
    opt.width->description = _("Image width");

    opt.height = G_define_option();
    opt.height->key = "height";
    opt.height->type = TYPE_INTEGER;
    opt.height->required = YES;
    opt.height->description = _("Image height");

    opt.bg = G_define_option();
    opt.bg->key = "background";
    opt.bg->type = TYPE_STRING;
    opt.bg->description = _("Background color");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    width = atoi(opt.width->answer);
    height = atoi(opt.height->answer);

    in_buf = G_malloc(width * height * 3);
    mask_buf = G_malloc(width * height);
    out_buf = G_malloc(width * height * 3);
    out_mask_buf = G_malloc(width * height);

    if (opt.bg->answer)
	erase(out_buf, opt.bg->answer);

    memset(out_mask_buf, 0, width * height);

    for (i = 0; opt.in->answers[i]; i++) {
	char *infile = opt.in->answers[i];
	char *maskfile = opt.mask->answer ? opt.mask->answers[i]
	    : NULL;

	if (!maskfile)
	    opt.mask->answer = NULL;

	if (maskfile && *maskfile) {
	    read_pnm(infile, in_buf, 3);
	    read_pnm(maskfile, mask_buf, 1);
	    if (opt.alpha->answer) {
		float alpha = atof(opt.alpha->answers[i]);

		if (alpha == 1.0)
		    overlay();
		else
		    overlay_alpha(alpha);
	    }
	    else
		overlay();
	}
	else {
	    read_pnm(infile, out_buf, 3);
	    memset(out_mask_buf, 255, width * height);
	}
    }

    write_ppm(opt.out->answer, out_buf);
    if (opt.outmask->answer)
	write_pgm(opt.outmask->answer, out_mask_buf);

    return 0;
}
Beispiel #8
0
int main(int argc, char **argv){
  
  //LOCAL VARIABLE DEF BLOCK===========================================
  image_ptr imagePtr;
  float subimg[sis][sis]; //space for subimage
  int rows, cols, type;
  int i, j, k, u, v, count; //counter variables
  int offset; //to keep track of values put into subImagePtr
  float scale; //to calcule img size
  int rowsize;
  int rowblock, colblock, totalblock; //number of sub blocks needed for image
  //float Z[1000000]; //this will be the compressed image
  unsigned char writeme[1000000]; //this is the unsigned char to write to file
  unsigned char childOut[100000]; //this is the unsigned char used for child output
  //int zc = 0; //counter for Z
  int wc = 0; //counter for writeme
  int dir; //direction of zig zag 0 = down 1 = up
  int zeros = 0; //holds the number of zeros for "percent zeros" calculation
  int total = 0; //total number of bits used in "percent zeros" calculation
  int tmp; //used in float to unsigned char conversion
  int numOfChildren = 0;
  int childBlock = 0;
  
  //arrays for math
  float C[sis][sis] = {
    {0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536},
    {0.4904, 0.4157, 0.2778, 0.0975, -0.0975, -0.2778, -0.4157, -0.4904},
    {0.4619, 0.1913, -0.1913, -0.4619, -0.4619, -0.1913, 0.1913, 0.4619},
    {0.4157, -0.0975, -0.4904, -0.2778, 0.2778, 0.4904, 0.0975, -0.4157},
    {0.3536, -0.3536, -0.3536, 0.3536, 0.3536, -0.3536, -0.3536, 0.3536},
    {0.2778, -0.4904, 0.0975, 0.4157, -0.4157, -0.0975, 0.4904, -0.2778},
    {0.1913, -0.4619, 0.4619, -0.1913, -0.1913, 0.4619, -0.4619, 0.1913},
    {0.0975, -0.2778, 0.4157, -0.4904, 0.4904, -0.4157, 0.2778, -0.0975}};
  
  float CT[sis][sis] = {
    {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975},
    {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778},
    {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157},
    {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904},
    {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904},
    {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157},
    {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778},
    {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975}};
  
  //same for array Q
  float Q[sis][sis] = {
    {8, 16, 24, 32, 40, 48, 56, 64},
    {16, 24, 32, 40, 48, 56, 64, 72},
    {24, 32, 40, 48, 56, 64, 72, 80},
    {32, 40, 48, 56, 64, 72, 80, 88},
    {40, 48, 56, 64, 72, 80, 88, 96},
    {48, 56, 64, 72, 80, 88, 96, 104},
    {56, 64, 72, 80, 88, 95, 104, 112},
    {64, 72, 80, 88, 96, 104, 112, 120}};
  
  float q[sis][sis];
  for (i = 0; i < 8; i++){
    for (j = 0; j < 8; j++){
      q[i][j] = Q[i][j];
    }
  }
  
  //GET COMMAND LINE INPUTS===========================================
  if (argc != 5){
    printf("wrong inputs: use %s imageIn.ppm imageOut.enc q p\n", argv[0]);
    return 0;
  }
  
  //READ INPUT IMAGE==================================================
  printf("Reading input image. . . \n");
  imagePtr = read_pnm(argv[1], &rows, &cols, &type);
  printf("Image read successfully\n");
  printf("rows=%d, cols=%d, type=%d \n", rows, cols, type);

  int tb; //total blocks to be processed
  int cb = 0; //current block
  int g; //counter
  tb = (rows / sis) * (cols / sis);
  
  //Place image into 2D array
  unsigned char myImg[rows][cols];
  for (i = 0; i < rows; i++){
    for (j = 0; j < cols; j++){
      myImg[i][j] = imagePtr[i*cols+j];
    }
  }
  
  //set q array to propperly scaled value, based on input
  int qin;
  qin = atoi(argv[3]);
  intTimesMatrix(q, qin);

  // clip q to be between 0 and 255
  for (u = 0; u < sis; u++){
    for (v = 0; v < sis; v++){
      if (q[u][v] > 254)
	q[u][v] = 254;
    }
  }
  
  //get p
  int p;
  p = atoi(argv[4]);

  //create tmp variables for preforming math operations
  float CX[sis][sis];
  float Y[sis][sis];
  int r, c;
  
  //get row and col characters - assumes that image is smaller than 1000x1000
  int row1, row2, row3;
  int col1, col2, col3;
  row1 = rows / 100;
  row2 = (rows - (row1 * 100)) / 10;
  row3 = (rows - (row1 * 100)) - (row2 * 10);
  col1 = cols / 100;
  col2 = (cols - col1 * 100) / 10;
  col3 = (cols - col1 * 100) - col2 * 10;
  
  //build header
  writeme[wc++] = row1 + '0';
  writeme[wc++] = row2 + '0';
  writeme[wc++] = row3 + '0';
  writeme[wc++] = '$'; //end of block character
  writeme[wc++] = col1 + '0';
  writeme[wc++] = col2 + '0';
  writeme[wc++] = col3 + '0';
  writeme[wc++] = '$';
  writeme[wc++] = '8';
  writeme[wc++] = '$';
  writeme[wc++] = '8';
  writeme[wc++] = '$';
  writeme[wc++] = qin + '0';
  writeme[wc++] = '$';
  writeme[wc++] = '0';
  writeme[wc++] = '0';
  writeme[wc++] = '$';
  //create placeholder to put estimated size in later
  for (i = 0; i < 7; i++){
    writeme[wc++] = '0';
  }
  writeme[wc++] = '$';
  
  //STEP THROUGH INPUT IMAGE===========================================
  int makepipes;
  float tm;
  int mt;
  int pipefds[2*p];
  int pid;
  for (i = 0; i < rows; i = i + 8){
    for (j = 0; j < cols; j = j + 8){

      for (u = 0; u < sis; u++){
	for (v = 0; v < sis; v++){
	  
	  //cast to float to make math operations possible and level off for proper DCT values
	  mt = (int) myImg[i+u][j+v];
	  tm = (float) mt;
	  subimg[u][v] = tm - 128;
	  //make sure Y and CX are clear
	  Y[u][v] = 0;
	  CX[u][v] = 0;
	  
	}
      }

      cb++; //increment current block

      if (numOfChildren  == 0){ 
	//build all necessary pipes
	if (tb - cb < p){
	  //only make amount of pipes necessary
	  makepipes = tb - cb + 1;
	} else {
	  makepipes = p;
	}
	
	for (g = 0; g < makepipes; g++){
	  if (pipe(pipefds + g*2) < 0){
	    perror("Pipe");
	    exit(1);
	  }
	}
      } 
      
      numOfChildren++;
      if ((pid = fork()) == 0){
	//zero means child

	//Perform first step of matrix multiplication CX = C*subimg
	matrixMultiplication(C, subimg, CX);
	
	//Perform second step of matrix multiplication Y = CX*CT
	matrixMultiplication(CX, CT, Y);
	
	//quantize Y by dividing element by element with q
	eleByEleMatrixDiv(Y, q);
	
	//undo the (-128)
	for (u = 0; u < sis; u++){
	  for (v = 0; v < sis; v++){
	    Y[u][v] = Y[u][v] + 128;
	  }
	}

	//preform zig zag on Y, sore flat result in Z
	r = 0; //current row
	c = 0; //current col
	count = 0;
	dir = 0;
      
	//loop to preform zig zagging
	while (count < 64){
	  if (Y[r][c] < 128.4 && Y[r][c] > 127.5){
	    //count zeros
	    zeros = (64 - count); //should probably just send this back to the parent
	    //REMEMBER TO ADD ZEROS BACK TOGETHER WHEN READING BACK IN
	    total = 64;
	    //AND ADD TOTAL
	    break;
	  }
	
	  if (r == 0 && c < 7){
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    c++;
	  
	    if (Y[r][c] < 128.4 && Y[r][c] > 127.5){
	      zeros = (64 - count);
	      total = 64;
	      break;
	    }
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    c--; r++;
	    dir = 0;
	  
	  } else if (c == 0 && r < 7){
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    r++; 
	  
	    if (Y[r][c] < 128.4 && Y[r][c] > 127.5){
	      zeros = (64 - count);
	      total = 64;
	      break;
	    }
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    r--; c++;
	    dir = 1;
	  
	  } else if ( r == 7){
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    c++;
	  
	    if (Y[r][c] < 128.4 && Y[r][c] > 127.5){
	      //count zeros
	      zeros = (64 - count);
	      total = 64;
	      break;
	    }
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    c++; r--;
	    dir = 1;
	  
	  } else if ( c == 7){
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    r++; 

	    if (Y[r][c] < 128.4 && Y[r][c] > 127.5){
	      //count zeros
	      zeros = (64 - count);
	      total = 64;
	      break;
	    }
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    r++; c--;
	    dir = 0;
	  
	  } else if (dir == 0){
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    c--; r++;
	  
	  } else if (dir == 1){
	  
	    tmp = (int) Y[r][c];
	    childOut[count++] = (unsigned char) tmp;
	    c++; r--;
	  
	  }
	}
	childOut[count++] = '$';

	//need to add in percent zeros and block position
	//actually might not need to worry about positioning (use pipes to keep track)
      
	unsigned char results[count];
	for (g = 0; g < count; g++){
	  results[g] = childOut[g];
	}

	//return data
	//could add several '$' to mark end of transmitted data
	write(pipefds[(numOfChildren-1)*2+1], results, sizeof(results));

	//kill child
	exit(0);
	
      } else if (pid == -1) {
	
	//fork error
	printf("Fork error\n");
	exit(1);
	
      } else {

	//this is the parent
	if (numOfChildren >= makepipes){
	  //this means all children are made, need to get results
	  //not sure how to make sure they are all finished or not?
	  //wonder if it waits for something to be written?
	  unsigned char tmpin[100];
	  //get data
	  for (g = 0; g < makepipes; g++){
	    read(pipefds[2*g], tmpin, sizeof(tmpin));
	    int h = 0;
	    while (tmpin[h] != '$'){
	      writeme[wc++] = tmpin[h++];
	      if (h > 99){
		printf("something probably went wrong");
		break;
	      }
	    }
	    writeme[wc++] = '$';
	    //h is going to be equivilent to (64 - zeros)
	    zeros = zeros + (64 - h);
	    total = total + 64;
	  }
	  
	  //close pipes
	  for (g = 0; g < 2 * makepipes; g++){
	    close(pipefds[g]);
	  }
	  // all children should be dead at this point
	  numOfChildren = 0;
	}
      }
      
    }
  }
  
  //change percent zeros in write me
  float pz;
  printf("This is total: %d\n", total);
  printf("This is zeros: %d\n", zeros);
  pz = (float) zeros / total;
  printf("Percent Zeros: %f\n", pz);
  pz = (int) (pz * 100);
  int pz1;
  pz1 = pz / 10;
  int pz2;
  pz2 = pz - pz1 * 10;
  writeme[14] = pz1 + '0';
  writeme[15] = pz2 + '0';
  
  //change estimated size
  //estimated size is zc, so get each element then plug into Z[17 - 24]
  int zc1, zc2, zc3, zc4, zc5, zc6, zc7;
  zc1 = wc / 1000000;
  zc2 = (wc - zc1 * 1000000) / 100000;
  zc3 = (wc - zc1 * 1000000 - zc2 * 100000) / 10000;
  zc4 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000) / 1000;
  zc5 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000 - zc4 * 1000) / 100;
  zc6 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000 - zc4 * 1000 - zc5 * 100) / 10;
  zc7 = (wc - zc1 * 1000000 - zc2 * 100000 - zc3 * 10000 - zc4 * 1000 - zc5 * 100 - zc6  * 10);
  
  writeme[17] = zc1 + '0';
  writeme[18] = zc2 + '0';
  writeme[19] = zc3 + '0';
  writeme[20] = zc4 + '0';
  writeme[21] = zc5 + '0';
  writeme[22] = zc6 + '0';
  writeme[23] = zc7 + '0';

  //write file
  FILE *f = fopen(argv[2], "w");
  if (f == NULL){
    printf("Error opening file\n");
    return 0;
  }

  for (i = 0; i < wc; i++){
    fprintf(f, "%c", writeme[i]);
  }
  fclose(f);
  
}