"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 /* :-) */