#include #include #include #include #include /* enums and constant identifiers */ enum ComponentNames { red, green, blue }; /* structure definitions */ struct JPEGmain { struct JPEGcomponent ** components; int output_width; int output_height; int output_components; int total_pixels; }; struct JPEGcomponent { /* use values in ComponentNames to */ /* access a specific component. */ JSAMPLE * values; }; /* function declarations */ GLOBAL(int) read_JPEG_file(const char * filename); int save_scanline(unsigned char * buffer, int row_stride, int output_scanline); struct JPEGmain * create_JPEG_struct(struct jpeg_decompress_struct * cinfo); int print_JPEG_struct(); struct JPEGcomponent * get_pixel(int x_cord, int y_cord); int print_pixel(struct JPEGcomponent * jcomp); /* globals */ struct JPEGmain * jmain; /* main JPEG struct */ int main(int argc, const char *argv[]) { read_JPEG_file(argv[1]); print_JPEG_struct(); print_pixel(get_pixel(50,50)); return 0; } /* * read_JPEG_file */ GLOBAL(int) read_JPEG_file(const char * filename) { struct jpeg_decompress_struct cinfo; FILE * infile; /* source file */ JSAMPARRAY buffer; /* output row buffer */ int row_stride; /* physical row width in output buffer */ /* open source file */ if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); return 0; } /* setup the jpeg error handler */ struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); /* create JPEG object */ jpeg_create_decompress(&cinfo); /* setup stdio source */ jpeg_stdio_src(&cinfo, infile); /* read JPEG header from file */ (void) jpeg_read_header(&cinfo, TRUE); /* begin decompression */ (void) jpeg_start_decompress(&cinfo); /* total elements in array passed to save_scanline */ row_stride = cinfo.output_width * cinfo.output_components; /* temporary buffer to save component values per row */ buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); /* * We can now create the JPEGmain struct to contain the * image's information and component values for each pixel. */ jmain = create_JPEG_struct(&cinfo); /* read in and save one scanline at a time */ while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); save_scanline(buffer[0], row_stride, cinfo.output_scanline); } /* end decompression */ (void) jpeg_finish_decompress(&cinfo); /* destroy JPEG object */ jpeg_destroy_decompress(&cinfo); /* close source file */ fclose(infile); return 1; } /* * save_scanline */ int save_scanline(unsigned char * buffer, int row_stride, int output_scanline) { int i; int j; int output_components = jmain->output_components; JSAMPLE * q; /* p is the first pixel of the row we are saving */ struct JPEGcomponent ** p = jmain->components + (jmain->output_width * (output_scanline-1)); #ifdef DEBUG printf("saving line %d jmain->components = %d p = %d\n", output_scanline,jmain->components,p); #endif /* for each output_components buffer elements, save them to the next * empty element in the components array of the JPEGmain struct. */ for (i = 0; i < row_stride; i += output_components, p++) { for (j = 0, q = (*p)->values; j < output_components; j++, q++) { *q = buffer[i+j]; } } return 1; } /* * create_JPEG_struct */ struct JPEGmain * create_JPEG_struct(struct jpeg_decompress_struct * cinfo) { int i; struct JPEGmain * p; struct JPEGcomponent ** q; int total_pixels = cinfo->output_width * cinfo->output_height; /* allocate JPEGmain struct */ p = (struct JPEGmain *)malloc(sizeof(struct JPEGmain)); /* save relevant JPEG header data */ p->output_width = cinfo->output_width; p->output_height = cinfo->output_height; p->total_pixels = total_pixels; p->output_components = cinfo->output_components; /* allocate JPEGcomponent structs array */ p->components = (struct JPEGcomponent **) malloc(sizeof(struct JPEGcomponent *)*total_pixels+1); q = p->components; /* allocate each JPEGcomponent in the array */ for (i = 0; i < total_pixels; i++, q++) { /* allocate JPEGcomponent struct */ *q = (struct JPEGcomponent *)malloc(sizeof(struct JPEGcomponent)); /* allocate values array */ (*q)->values = (JSAMPLE *) malloc(sizeof(JSAMPLE)*cinfo->output_components); } /* tail sentinel to make things easy */ *q = NULL; return p; } /* * print_JPEG_struct */ int print_JPEG_struct() { int i; int components = jmain->output_components; struct JPEGcomponent ** p; if (jmain == NULL) { fprintf(stderr,"error: JPEG object not created\n"); return 0; } /* print one pixel with its components per line */ for (p = jmain->components; *p; p++) { print_pixel(*p); } return 1; } /* * get_pixel */ struct JPEGcomponent * get_pixel(int x_cord, int y_cord) { if (jmain->output_width < x_cord || jmain->output_height < y_cord) return NULL; return *(jmain->components + (jmain->output_width*x_cord) + y_cord); } /* * print_pixel */ int print_pixel(struct JPEGcomponent * jcomp) { int i; int components = jmain->output_components; if (jcomp == NULL) { fprintf(stderr,"error: cannot print empty pixel\n"); return 0; } for (i = 0; i < components; i++) { fprintf(stdout,"%d ",jcomp->values[i]); } fprintf(stdout,"\n"); return 1; }