"Fossies" - the Fresh Open Source Software Archive 
Member "jpeginfo-1.6.1/jpeginfo.c" (12 Oct 2009, 10200 Bytes) of package /linux/privat/old/jpeginfo-1.6.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "jpeginfo.c" see the
Fossies "Dox" file reference documentation.
1 /*******************************************************************
2 * $Id: jpeginfo.c,v 1.15 2009/10/12 04:23:40 tjko Exp $
3 *
4 * JPEGinfo
5 * Copyright (c) Timo Kokkonen, 1995-2009.
6 *
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include <stdio.h>
14 #if HAVE_GETOPT_H && HAVE_GETOPT_LONG
15 #include <getopt.h>
16 #else
17 #include "getopt.h"
18 #endif
19 #include <stdlib.h>
20 #include <string.h>
21 #include <setjmp.h>
22 #include <ctype.h>
23 #include <jpeglib.h>
24
25 #include "md5.h"
26 #include "jpeginfo.h"
27
28
29 #define VERSION "1.6.1"
30 #define BUF_LINES 255
31
32 #ifndef HOST_TYPE
33 #define HOST_TYPE ""
34 #endif
35
36 #ifdef BROKEN_METHODDEF
37 #undef METHODDEF
38 #define METHODDEF(x) static x
39 #endif
40
41 #define EXIF_JPEG_MARKER JPEG_APP0+1
42 #define EXIF_IDENT_STRING "Exif\000\000"
43
44
45 static char *rcsid = "$Id: jpeginfo.c,v 1.15 2009/10/12 04:23:40 tjko Exp $";
46
47 struct my_error_mgr {
48 struct jpeg_error_mgr pub;
49 jmp_buf setjmp_buffer;
50 };
51 typedef struct my_error_mgr * my_error_ptr;
52
53 static struct jpeg_decompress_struct cinfo;
54 static struct my_error_mgr jerr;
55
56 static struct option long_options[] = {
57 {"verbose",0,0,'v'},
58 {"delete",0,0,'d'},
59 {"mode",1,0,'m'},
60 {"file",1,0,'f'},
61 {"check",0,0,'c'},
62 {"help",0,0,'h'},
63 {"quiet",0,0,'q'},
64 {"lsstyle",0,0,'l'},
65 {"info",0,0,'i'},
66 {"md5",0,0,'5'},
67 {"version",0,0,'V'},
68 {"comments",0,0,'C'},
69 {0,0,0,0}
70 };
71
72 FILE *infile=NULL;
73 FILE *listfile=NULL;
74 int global_error_counter;
75 int global_total_errors;
76 int verbose_mode = 0;
77 int quiet_mode = 0;
78 int delete_mode = 0;
79 int check_mode = 0;
80 int com_mode = 0;
81 int del_mode = 0;
82 int opt_index = 0;
83 int list_mode = 0;
84 int longinfo_mode = 0;
85 int input_from_file = 0;
86 int md5_mode = 0;
87 char *current = NULL;
88
89 /*****************************************************************/
90
91 METHODDEF(void)
92 my_error_exit (j_common_ptr cinfo)
93 {
94 my_error_ptr myerr = (my_error_ptr)cinfo->err;
95 (*cinfo->err->output_message) (cinfo);
96 longjmp(myerr->setjmp_buffer,1);
97 }
98
99
100 METHODDEF(void)
101 my_output_message (j_common_ptr cinfo)
102 {
103 char buffer[JMSG_LENGTH_MAX];
104
105 (*cinfo->err->format_message) (cinfo, buffer);
106 if (quiet_mode < 2) printf(" %s ",buffer);
107 global_error_counter++;
108 global_total_errors++;
109 }
110
111
112 void no_memory(void)
113 {
114 fprintf(stderr,"jpeginfo: not enough memory!\n");
115 exit(3);
116 }
117
118
119 void p_usage(void)
120 {
121 if (!quiet_mode) {
122 fprintf(stderr,"jpeginfo v" VERSION
123 " Copyright (c) Timo Kokkonen, 1995-2009.\n");
124
125 fprintf(stderr,
126 "Usage: jpeginfo [options] <filenames>\n\n"
127 " -c, --check check files also for errors\n"
128 " -C, --comments display comments (from COM markers)\n"
129 " -d, --delete delete files that have errors\n"
130 " -f<filename>, --file<filename>\n"
131 " read the filenames to process from given file\n"
132 " (for standard input use '-' as a filename)\n"
133 " -h, --help display this help and exit\n"
134 " -5, --md5 calculate MD5 checksum for each file\n"
135 " -i, --info display even more information about pictures\n"
136 " -l, --lsstyle use alternate listing format (ls -l style)\n"
137 " -v, --verbose enable verbose mode (positively chatty)\n"
138 " --version print program version and exit\n"
139 " -q, --quiet quiet mode, output just jpeg infos\n"
140 " -m<mode>, --mode=<mode>\n"
141 " defines which jpegs to remove (when using"
142 " the -d option).\n"
143 " Mode can be one of the following:\n"
144 " erronly only files with serious errrors\n"
145 " all files ontaining warnings or errors"
146 " (default)\n\n\n");
147 }
148
149 exit(0);
150 }
151
152
153 /*****************************************************************/
154 int main(int argc, char **argv)
155 {
156 JSAMPARRAY buf = malloc(sizeof(JSAMPROW)*BUF_LINES);
157 jpeg_saved_marker_ptr exif_marker, cmarker;
158 MD5_CTX *MD5 = malloc(sizeof(MD5_CTX));
159 volatile int i;
160 int c,j,lines_read, err_count;
161 unsigned char ch;
162 char namebuf[1024];
163 long fs;
164 char *md5buf,digest[16],digest_text[33];
165
166 global_total_errors=0;
167 if (rcsid); /* to keep compiler from not complaining about rcsid */
168
169 cinfo.err = jpeg_std_error(&jerr.pub);
170 jpeg_create_decompress(&cinfo);
171 jerr.pub.error_exit=my_error_exit;
172 jerr.pub.output_message=my_output_message;
173
174 if (!buf || !MD5) no_memory();
175 if (argc<2) {
176 if (quiet_mode < 2) fprintf(stderr,"jpeginfo: file arguments missing\n"
177 "Try 'jpeginfo "
178 "--help"
179 "' for more information.\n");
180 exit(1);
181 }
182
183 /* parse command line parameters */
184 while(1) {
185 opt_index=0;
186 if ( (c=getopt_long(argc,argv,"livVdcChqm:f:5",
187 long_options,&opt_index)) == -1)
188 break;
189 switch (c) {
190 case 'm':
191 if (!strcasecmp(optarg,"all")) del_mode=0;
192 else if (!strcasecmp(optarg,"erronly")) del_mode=1;
193 else if (!quiet_mode)
194 fprintf(stderr,"Unknown parameter for -m, --mode.\n");
195 break;
196 case 'f':
197 if (!strcmp(optarg,"-")) listfile=stdin;
198 else if ((listfile=fopen(optarg,"r"))==NULL) {
199 fprintf(stderr,"Cannot open file '%s'.\n",optarg);
200 exit(2);
201 }
202 input_from_file=1;
203 break;
204 case 'v':
205 verbose_mode=1;
206 break;
207 case 'V':
208 fprintf(stderr,"jpeginfo v" VERSION " " HOST_TYPE
209 "\nCopyright (c) Timo Kokkonen, 1995-2002.\n");
210 exit(0);
211 case 'd':
212 delete_mode=1;
213 break;
214 case 'c':
215 check_mode=1;
216 break;
217 case 'h':
218 p_usage();
219 break;
220 case 'q':
221 quiet_mode++;
222 break;
223 case 'l':
224 list_mode=1;
225 break;
226 case 'i':
227 longinfo_mode=1;
228 break;
229 case '5':
230 md5_mode=1;
231 break;
232 case 'C':
233 com_mode=1;
234 break;
235 case '?':
236 break;
237
238 default:
239 if (!quiet_mode)
240 fprintf(stderr,"jpeginfo: error parsing parameters.\n");
241 }
242 }
243
244 if (delete_mode && verbose_mode && !quiet_mode)
245 fprintf(stderr,"jpeginfo: delete mode enabled (%s)\n",
246 !del_mode?"normal":"errors only");
247
248 i=1;
249 do {
250 if (input_from_file) {
251 if (!fgetstr(namebuf,sizeof(namebuf),listfile)) break;
252 current=namebuf;
253 }
254 else current=argv[i];
255
256 if (current[0]==0) continue;
257 if (current[0]=='-' && !input_from_file) continue;
258
259 if (setjmp(jerr.setjmp_buffer)) {
260 jpeg_abort_decompress(&cinfo);
261 fclose(infile);
262 if (list_mode && quiet_mode < 2) printf(" %s",current);
263 if (quiet_mode < 2) printf(" [ERROR]\n");
264 if (delete_mode) delete_file(current,verbose_mode,quiet_mode);
265 continue;
266 }
267
268 if ((infile=fopen(current,"r"))==NULL) {
269 if (!quiet_mode) fprintf(stderr, "jpeginfo: can't open '%s'\n", current);
270 continue;
271 }
272 if (is_dir(infile)) {
273 fclose(infile);
274 if (verbose_mode) printf("directory: %s skipped\n",current);
275 continue;
276 }
277
278 fs=filesize(infile);
279
280 if (md5_mode) {
281 md5buf=malloc(fs);
282 if (!md5buf) no_memory();
283 fread(md5buf,1,fs,infile);
284 rewind(infile);
285
286 MD5Init(MD5);
287 MD5Update(MD5,md5buf,fs);
288 MD5Final(digest,MD5);
289 md2str(digest,digest_text);
290
291 free(md5buf);
292 }
293
294 if (!list_mode && quiet_mode < 2) printf("%s ",current);
295
296 global_error_counter=0;
297 err_count=jerr.pub.num_warnings;
298 if (com_mode) jpeg_save_markers(&cinfo, JPEG_COM, 0xffff);
299 jpeg_save_markers(&cinfo, EXIF_JPEG_MARKER, 0xffff);
300 jpeg_stdio_src(&cinfo, infile);
301 jpeg_read_header(&cinfo, TRUE);
302
303 /* check for Exif marker */
304 exif_marker=NULL;
305 cmarker=cinfo.marker_list;
306 while (cmarker) {
307 if (cmarker->marker == EXIF_JPEG_MARKER) {
308 if (!memcmp(cmarker->data,EXIF_IDENT_STRING,6)) exif_marker=cmarker;
309 }
310 cmarker=cmarker->next;
311 }
312
313 if (quiet_mode < 2) {
314 printf("%4d x %-4d %2dbit ",(int)cinfo.image_width,
315 (int)cinfo.image_height,(int)cinfo.num_components*8);
316
317 if (exif_marker) printf("Exif ");
318 else if (cinfo.saw_JFIF_marker) printf("JFIF ");
319 else if (cinfo.saw_Adobe_marker) printf("Adobe ");
320 else printf("n/a ");
321
322 if (longinfo_mode) {
323 printf("%s %s",(cinfo.progressive_mode?"Progressive":"Normal"),
324 (cinfo.arith_code?"Arithmetic":"Huffman") );
325
326 if (cinfo.density_unit==1||cinfo.density_unit==2)
327 printf(",%ddp%c",MIN(cinfo.X_density,cinfo.Y_density),
328 (cinfo.density_unit==1?'i':'c') );
329
330 if (cinfo.CCIR601_sampling) printf(",CCIR601");
331 printf(" %7ld ",fs);
332
333 } else printf("%c %7ld ",(cinfo.progressive_mode?'P':'N'),fs);
334
335 if (md5_mode) printf("%s ",digest_text);
336 if (list_mode) printf("%s ",current);
337
338 if (com_mode) {
339 cmarker=cinfo.marker_list;
340 while (cmarker) {
341 if (cmarker->marker == JPEG_COM) {
342 printf("\"");
343 for (j=0;j<cmarker->data_length;j++) {
344 ch = cmarker->data[j];
345 if (ch < 32 || iscntrl(ch)) continue;
346 printf("%c",cmarker->data[j]);
347 }
348 printf("\" ");
349 }
350 cmarker=cmarker->next;
351 }
352 }
353 }
354
355 if (check_mode) {
356 cinfo.out_color_space=JCS_GRAYSCALE; /* to speed up the process... */
357 cinfo.scale_denom = 8;
358 cinfo.scale_num = 1;
359 jpeg_start_decompress(&cinfo);
360
361 for (j=0;j<BUF_LINES;j++) {
362 buf[j]=malloc(sizeof(JSAMPLE)*cinfo.output_width*
363 cinfo.out_color_components);
364 if (!buf[j]) no_memory();
365 }
366
367 while (cinfo.output_scanline < cinfo.output_height) {
368 lines_read = jpeg_read_scanlines(&cinfo, buf,BUF_LINES);
369 }
370
371 jpeg_finish_decompress(&cinfo);
372 for(j=0;j<BUF_LINES;j++) free(buf[j]);
373
374 if (!global_error_counter) {
375 if (quiet_mode < 2) printf(" [OK]\n");
376 }
377 else {
378 if (quiet_mode < 2) printf(" [WARNING]\n");
379 if (delete_mode && !del_mode)
380 delete_file(current,verbose_mode,quiet_mode);
381 }
382 }
383 else { /* !check_mode */
384 if (quiet_mode < 2) printf("\n");
385 jpeg_abort_decompress(&cinfo);
386 }
387
388 fclose(infile);
389
390 } while (++i<argc || input_from_file);
391
392 jpeg_destroy_decompress(&cinfo);
393 free(buf);
394 free(MD5);
395
396 return (global_total_errors>0?1:0); /* return 1 if any errors found file(s)
397 we checked */
398 }
399
400 /* :-) */