/* * (c) SPDsoft 1993 + ATIC * version 2 * Uses IJG code v6b */ #include #include #include #include #include #include #include #include #include #include #ifndef PATH_SEP # define PATH_SEP '/' #endif #define Boolean int #define Output if (G_prefs.Verbose) printf #ifndef MIN #define MIN(a,b) ((a)>(b)?(b):(a)) #endif typedef struct { char *AppName; Boolean Verbose; int i0; int i1; int j0; int j1; int outh; int outw; int jpeg_q; } pref; /* * Prototypes */ void usage(char *name); void fatalError(char *str); void get_options(int argc,char *argv[]); /* * JPEG Prototypes */ static void my_error_exit (j_common_ptr cinfo); int read_JPEG_file (char * filename, int which ); extern char *optarg; extern int optind,opterr; unsigned image_H=0; unsigned image_W=0; int f; JSAMPARRAY buffer_v; /* 2D JSAMPLES */ pref G_prefs; static char __ident[] = "@(#)(c) SPDsoft, (Uses IJG code v6b), Aug 1998"; #define VERS_STR ((char*)&__ident[4]) /*****************************************************/ void usage(char *name) { fprintf(stderr, "usage: %s iIjJq [-v][-h]", name); exit(-1); } void fatalError(char *str) { fprintf(stderr, "%s: %s (%s)\n",G_prefs.AppName,str,strerror(errno)); exit(-2); } struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct my_error_mgr * my_error_ptr; static void my_error_exit (j_common_ptr cinfo) { my_error_ptr myerr = (my_error_ptr) cinfo->err; (*cinfo->err->output_message) (cinfo); longjmp(myerr->setjmp_buffer, 1); } int read_JPEG_file (char * filename, int which ) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE *infile; /* source file */ int row_stride; /* physical row width in output buffer */ JSAMPARRAY *buffer; int j; int res; if ((infile = fopen(filename, "rb")) == NULL) { perror(filename); return -1; } buffer = buffer_v; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_decompress(&cinfo); fclose(infile); return NULL; } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, infile); (void) jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); image_H = cinfo.output_height; image_W = cinfo.output_width; row_stride = cinfo.output_width * cinfo.output_components; if (!*buffer) { int i; *buffer = malloc( sizeof(JSAMPROW*) * image_H); for(i=0;ialloc_sarray)*/ /* ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, image_H);*/ /* * Framebuffer */ Output("%03d %s\t%u\t%u\t",f,filename,image_H,image_W ); fflush(stdout); if (buffer==NULL) fatalError("Out of memory"); if ( cinfo.output_components != 1 ) { Output("RGB image\n"); while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &(*buffer)[cinfo.output_scanline], 1); } res=3; } else { Output("Grayscale image\n"); while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, &(*buffer)[cinfo.output_scanline], 1); } res=1; } /* * Finish */ (void) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(infile); return res; } /*****************************************************/ void get_options(int argc,char *argv[]) { int opcion; int theError=0; if ((G_prefs.AppName = strrchr(argv[0], PATH_SEP)) != NULL) G_prefs.AppName = G_prefs.AppName+1; else G_prefs.AppName = argv[0]; G_prefs.Verbose=0; G_prefs.i0=0; G_prefs.i1=0; G_prefs.j0=0; G_prefs.j1=0; G_prefs.outh=0; G_prefs.outw=0; G_prefs.jpeg_q=75; while ( (opcion=getopt(argc,argv,"vi:I:j:J:q:")) != EOF ) { switch(opcion) { case 'q': G_prefs.jpeg_q = atoi(optarg); break; case 'i': G_prefs.i0 = atoi(optarg); break; case 'I': G_prefs.i1 = atoi(optarg); break; case 'j': G_prefs.j0 = atoi(optarg); break; case 'J': G_prefs.j1 = atoi(optarg); break; case 'v': printf("%s:%s\n",G_prefs.AppName,VERS_STR); G_prefs.Verbose=1; break; default: usage(G_prefs.AppName); break; } } } main(int argc,char *argv[]) { int i,j,k,l; int res; JSAMPLE *rptr; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE * outfile; /* target file */ JSAMPROW row_pointer; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ get_options(argc,argv); if ((outfile = fopen(argv[optind+1], "wb")) == NULL) { fatalError(argv[optind+1]); } cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); res = read_JPEG_file(argv[optind],i); /* if ( G_prefs.j0 == 0 ) G_prefs.j0 = 0 ;*/ if ( G_prefs.j1 == 0 ) G_prefs.j1 = image_H - 1; /* if ( G_prefs.i0 == 0 ) G_prefs.i0 = 0 ;*/ if ( G_prefs.i1 == 0 ) G_prefs.i1 = image_W - 1; if ( G_prefs.outh == 0 ) { G_prefs.outh = (G_prefs.j1 - G_prefs.j0) + 1; G_prefs.outw = (G_prefs.i1 - G_prefs.i0) + 1; row_pointer = (JSAMPROW) malloc((size_t)(3*G_prefs.outw)); if (!row_pointer) fatalError("out malloc"); jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = G_prefs.outw; cinfo.image_height = G_prefs.outh; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, G_prefs.jpeg_q, TRUE ); jpeg_start_compress(&cinfo, TRUE); row_stride = cinfo.image_width * 3; } for(k=0; k