static void test_methods(A2Methods_T methods_under_test) { methods = methods_under_test; assert(methods); assert(has_minimum_methods(methods)); assert(has_small_plain_methods(methods) || has_small_blocked_methods(methods)); assert(!(has_small_plain_methods(methods) && has_small_blocked_methods(methods))); assert(!(has_plain_methods(methods) && has_blocked_methods(methods))); if (!(has_plain_methods(methods) || has_blocked_methods(methods))) fprintf(stderr, "Some full mapping methods are missing\n"); A2 array = methods->new_with_blocksize(W, H, sizeof(unsigned), BS); copy_unsigned(methods, array, 2, 1, 99); copy_unsigned(methods, array, 3, 3, 88); copy_unsigned(methods, array, 10, 10, 77); check(array, 2, 1, 99); check(array, 3, 3, 88); check(array, 10, 10, 77); for (int i = 0; i < W; i++) { for (int j = 0; j < H; j++) { unsigned n = 1000 * i + j; copy_unsigned(methods, array, i, j, n); unsigned *p = methods->at(array, i, j); assert(*p == n); } } for (int i = 0; i < W; i++) { for (int j = 0; j < H; j++) { unsigned n = 1000 * i + j; unsigned *p = methods->at(array, i, j); assert(*p == n); } } double_row_major_plus(); methods->free(&array); }
extern void component_convertRGB(A2Methods_UArray2 componentImage, A2Methods_UArray2 pixels, unsigned denominator) { A2Methods_T methods = uarray2_methods_blocked; int i, j; comp component; Pnm_rgb loc; float scaledRed, scaledGreen, scaledBlue; for(j = 0; j < methods->height(pixels); j++) { for(i = 0; i < methods->width(pixels); i++) { component = methods->at(componentImage, i, j); Pnm_rgb temp = malloc(sizeof(struct Pnm_rgb)); loc = methods->at(pixels, i, j); scaledRed = 1.0 * component->y + 1.402 * component->pr; scaledGreen = 1.0 * component->y - 0.344136 * component->pb - 0.714136 * component->pr; scaledBlue = 1.0 * component->y + 1.722 * component->pb; temp->red = component_createRGB(scaledRed, denominator); temp->green = component_createRGB(scaledGreen, denominator); temp->blue = component_createRGB(scaledBlue, denominator); *loc = *temp; free(temp); } } }
/* This function takes in the file and utilizes functions in compute40 * module to perform the compression and outputing, and frees the memory */ void compress40(FILE *input) { A2Methods_T methods = uarray2_methods_blocked; Pnm_ppm image = Pnm_ppmread(input, methods); assert(image); assert(image->width > 1 && image->height > 1); image->pixels = image_trimmer(image); A2 result = methods->new_with_blocksize(image->width / BLOCKSIZE, image->height / BLOCKSIZE, sizeof(uint64_t), 1); methods->map_block_major(result, compress, image); assert(result); print_result(result, methods); methods->free(&result); FREE(result); Pnm_ppmfree(&image); }
// Stores a componenet struct in given array pixels extern void component_storeComponent(A2Methods_UArray2 pixels, int i, int j, float avgPB, float avgPR, float y) { A2Methods_T methods = uarray2_methods_blocked; comp target = methods->at(pixels, i, j); comp contents = malloc(sizeof(struct comp)); contents->y = y; contents->pb = avgPB; contents->pr = avgPR; *target = *contents; free(contents); }
/* This function copies the RGB info from the source pixel to the target */ void copy(int i, int j, A2 array2, void *data, void *cl) { (void)array2; (void)data; A2 orig = cl; assert(orig); A2Methods_T methods = uarray2_methods_blocked; *(Pnm_rgb)data = *(Pnm_rgb)methods->at(orig, i , j); }
/* decompress40() * Takes in a file pointer to a binary compressed image * Creates and frees the arrays needed by the 4 other decompression modules * used by compress40 and calls their functions in the correct order to * decompress the given file into a ppm image * Writes the new ppm image to standard output */ void decompress40(FILE *input) { methods = uarray2_methods_blocked; A2Methods_UArray2 compressed_array = read_packed_elems(input, methods); A2Methods_UArray2 small_video_img = unpack_codewords(compressed_array); methods->free(&compressed_array); A2Methods_UArray2 video_array = small_video_to_video(small_video_img, methods); methods->free(&small_video_img); Pnm_ppm decompressed_image = video_array_to_rgb_array(video_array, methods); methods->free(&video_array); Pnm_ppmwrite(stdout, decompressed_image); Pnm_ppmfree(&decompressed_image); }
/* This function takes in the pixel matrix where each cell has been * compressed into a 64-bit codeword, and prints the compressed file * in COMP40 Compressed image format to stdout */ void print_result(A2 result, A2Methods_T methods) { assert(result); assert(methods); int width = methods->width(result) * 2; int height = methods->height(result) * 2; printf("COMP40 Compressed image format 2\n%u %u\n", width, height); for (int i = 0; i < width / 2; i++) for (int j = 0; j < height / 2; j++) { uint64_t *tmp = methods->at(result, i, j); putchar(Bitpack_getu(*tmp, BYTE_LENGTH, 24)); putchar(Bitpack_getu(*tmp, BYTE_LENGTH, 16)); putchar(Bitpack_getu(*tmp, BYTE_LENGTH, 8)); putchar(Bitpack_getu(*tmp, BYTE_LENGTH, 0)); } }
/* This function takes in the file, reads the header, utilizes * functions in compute40 module to perform the decompress, completes the * decompressed ppm, and calls ppmwrite() to write the image to the * stdout */ void decompress40(FILE *input) { unsigned height, width; int read = fscanf(input, "COMP40 Compressed image format 2\n%u %u", &width, &height); assert(read == 2); int c = getc(input); assert(c == '\n'); A2Methods_T methods = uarray2_methods_blocked; A2 array = methods->new_with_blocksize(width / 2, height / 2, sizeof(uint64_t), 1); assert(array); A2 result = methods->new_with_blocksize(width, height, sizeof(struct Pnm_rgb), 2); assert(result); methods->map_block_major(array, read_compressed, input); methods->map_block_major(array, decompress, result); assert(result); struct Pnm_ppm pixmap = { .width = width, .height = height, .denominator = DENOMINATOR, .pixels = result, .methods = uarray2_methods_blocked}; Pnm_ppmwrite(stdout, &pixmap); methods->free(&result); methods->free(&array); }
/* compress40() * Takes in a file pointer to a .ppm image * Creates and frees the arrays needed by the 4 other compression modules used * by compress40 and calls their functions in the correct order to compress * the given image * Prints the binary compressed image */ void compress40(FILE *input) { methods = uarray2_methods_blocked; Pnm_ppm input_img = Pnm_ppmread(input, methods); A2Methods_UArray2 video_img = trim_rgb_array_to_video_array(input_img, methods); Pnm_ppmfree(&input_img); A2Methods_UArray2 small_video_img = video_to_small_video(video_img, methods); methods->free(&video_img); A2Methods_UArray2 compressed_img = pack_codewords(small_video_img, methods); methods->free(&small_video_img); print_packed_elems(compressed_img); methods->free(&compressed_img); }
static void double_row_major_plus() { /* store increasing integers in row-major order */ A2 array = methods->new_with_blocksize(W, H, sizeof(int), BS); int counter = 1; for (int j = 0; j < H; j++) { for (int i = 0; i < W; i++) { /* col index varies faster */ int *p = methods->at(array, i, j); *p = counter++; } } counter = 1; for (int j = 0; j < H; j++) { for (int i = 0; i < W; i++) { int *p = methods->at(array, i, j); assert(*p == counter); counter++; } } if (methods->map_row_major) { counter = 1; methods->map_row_major(array, check_and_increment, &counter); } if (methods->small_map_row_major) { counter = 1; methods->small_map_row_major(array, small_check_and_increment, &counter); } methods->free(&array); }
static void test_methods(A2Methods_T methods_under_test) { methods = methods_under_test; assert(methods); assert(has_minimum_methods(methods)); assert(has_small_plain_methods(methods) || has_small_blocked_methods(methods)); assert(!(has_small_plain_methods(methods) && has_small_blocked_methods(methods))); assert(!(has_plain_methods(methods) && has_blocked_methods(methods))); if (!(has_plain_methods(methods) || has_blocked_methods(methods))) fprintf(stderr, "Some full mapping methods are missing\n"); A2 array = methods->new_with_blocksize(W, H, sizeof(unsigned), BS); <<<<<<< HEAD
static inline void check(A2 a, int i, int j, unsigned n) { unsigned *p = methods->at(a, i, j); assert(*p == n); }
static inline void copy_unsigned(A2Methods_T methods, A2 a, int i, int j, unsigned n) { unsigned *p = methods->at(a, i, j); *p = n; }
int main(int argc, char* argv[]) { FILE * fp = NULL; if (argc == 1 || argc == 2 || argc > 3){ fprintf(stderr, "Please enter the correct number of arguments(3).\n"); exit(EXIT_FAILURE); } A2Methods_T methods = uarray2_methods_plain; // default to UArray2 methods assert(methods); A2Methods_mapfun *map = methods->map_default; // default to best map assert(map); Pnm_ppm ppm_file1; Pnm_ppm ppm_file2; if (!strcmp(argv[1], "-") && !strcmp(argv[2], "-")){ fprintf(stderr, "Error please specify an image not from stdin.\n"); exit(EXIT_FAILURE); } if (!strcmp(argv[1], "-")) { ppm_file1 = Pnm_ppmread(stdin, methods); fp = fopen(argv[2], "r"); if(fp == NULL) {exit(1);} ppm_file2 = Pnm_ppmread(fp, methods); fclose(fp); } else{ fp = fopen(argv[1], "r"); if(fp == NULL){ exit(1);} ppm_file1 = Pnm_ppmread(fp, methods); fclose(fp); if (!strcmp(argv[2], "-")) ppm_file2 = Pnm_ppmread(stdin, methods); else{ fp = fopen(argv[2], "r"); if(fp == NULL){ exit(1);} ppm_file2 = Pnm_ppmread(fp, methods); fclose(fp); } } A2Methods_UArray2 image1 = ppm_file1->pixels; A2Methods_UArray2 image2 = ppm_file2->pixels; int height1 = methods->height(image1); int height2 = methods->height(image2); int width1 = methods->width(image1); int width2 = methods->width(image2); if(abs(height1 - height2) > 1 || abs(width1 - width2) > 1){ fprintf(stderr, "dimensions: h%d, %d; w%d, %d\n", height1, height2, width1, width2); fprintf(stderr, "Dimesions of images are differnt.\n"); fprintf(stdout, "%lf", 1.0); exit(EXIT_FAILURE); } int height, width; if(height1 < height2) height = height1; else height = height2; if(width1 < width2) width = width1; else width = width2; Pnm_rgb temp1; Pnm_rgb temp2; double r1 = 0; double r2 = 0; double g1 = 0; double g2 = 0; double b1 = 0; double b2 = 0; double sum = 0.0; for(int j = 0; j < height; j++){ for(int i = 0; i < width; i++){ temp1 = methods->at(image1, i, j); r1 = temp1->red/255.0; g1 = temp1->green/255.0; b1 = temp1->blue/255.0; temp2 = methods->at(image2, i, j); r2 = temp2->red/255.0; g2 = temp2->green/255.0; b2 = temp2->blue/255.0; sum += pow(((r1 - r2)), 2.0)/(3.0*width*height); sum += pow(((g1 - g2)), 2.0)/(3.0*width*height); sum += pow(((b1 - b2)), 2.0)/(3.0*width*height); } } double answer = sqrt(sum); printf("%.4f\n", answer ); //Pnm_ppmwrite(stdout, ppm_file1); //methods->free(&im age1); //methods->free(&image2); Pnm_ppmfree(&ppm_file1); Pnm_ppmfree(&ppm_file2); }