/* imagecomp.c * Austin Vandergon, 7/25/06 * imagecomp takes four jpeg images, rotates them 90 degrees CCW, and * lays them next to each other. Each image should be 320x240 to begin with, * yielding a final image with dimensions 960x320. */ #include #include "jpeg-6b/jpeglib.h" #include #include #include "imagecomp.h" void* imagecomp_thread(void* arg) { /* load four images into output struct */ pixel img[FINAL_HEIGHT][FINAL_WIDTH]; int sockfda, sockfdb, sockfdc, sockfdd; connect_cam('a',&sockfda); connect_cam('b',&sockfdb); connect_cam('c',&sockfdc); connect_cam('d',&sockfdd); while(1) { get_image('a',&sockfda); get_image('b',&sockfdb); get_image('c',&sockfdc); get_image('d',&sockfdd); read_JPEG_file("/ram/imgb.jpeg", img, 1); read_JPEG_file("/ram/imga.jpeg", img, 2); read_JPEG_file("/ram/imgc.jpeg", img, 0); read_JPEG_file("/ram/imgd.jpeg", img, 3); pthread_mutex_lock(&outimage_mutex); write_JPEG_file("/ram/image.jpeg", 30, (JSAMPLE*)img); pthread_mutex_unlock(&outimage_mutex); } return NULL; } void put_image_scanline(pixel image[FINAL_HEIGHT][FINAL_WIDTH], pixel source[320], int row_num, int index) { if(row_num%2 == 0) return; // if you use 1 instead of 0 there's a // fencepost error... don't know why int i=0; while(ierr really points to a my_error_mgr struct, so coerce pointer */ my_error_ptr myerr = (my_error_ptr) cinfo->err; /* Always display the message. */ /* We could postpone this until after returning, if we chose. */ (*cinfo->err->output_message) (cinfo); /* Return control to the setjmp point */ longjmp(myerr->setjmp_buffer, 1); } /* * Sample routine for JPEG decompression. We assume that the source file name * is passed in. We want to return 1 on success, 0 on error. */ int read_JPEG_file (char * filename, void* image, int index) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE * infile; /* source file */ JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return -1; } /* Step 1: allocate and initialize JPEG decompression object */ cinfo.err = jpeg_std_error(&(jerr.pub)); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); fclose(infile); return -1; } jpeg_create_decompress(&cinfo); /* Step 2: specify data source (eg, a file) */ jpeg_stdio_src(&cinfo, infile); /* Step 3: read file parameters with jpeg_read_header() */ (void) jpeg_read_header(&cinfo, TRUE); /* Step 4: set parameters for decompression */ /* Step 5: Start decompressor */ (void) jpeg_start_decompress(&cinfo); row_stride = cinfo.output_width * cinfo.output_components; /* Make a one-row-high sample array that will go away when done with image */ buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); /* Step 6: while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); put_image_scanline(image, (pixel*)buffer[0], cinfo.output_scanline, index); } /* Step 7: Finish decompression */ (void) jpeg_finish_decompress(&cinfo); /* Step 8: Release JPEG decompression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress(&cinfo); fclose(infile); return 0; }