📄 iptcutil.c
字号:
#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#ifdef WIN32#include <io.h>#endif#include <string.h>#include <memory.h>#include <ctype.h>#ifdef WIN32#define STRNICMP strnicmp#else #define STRNICMP strncasecmp#endif typedef struct _tag_spec{ short id; char *name;} tag_spec;static tag_spec tags[] = { 5,"Image Name", 7,"Edit Status", 10,"Priority", 15,"Category", 20,"Supplemental Category", 22,"Fixture Identifier", 25,"Keyword", 30,"Release Date", 35,"Release Time", 40,"Special Instructions", 45,"Reference Service", 47,"Reference Date", 50,"Reference Number", 55,"Created Date", 60,"Created Time", 65,"Originating Program", 70,"Program Version", 75,"Object Cycle", 80,"Byline", 85,"Byline Title", 90,"City", 95,"Province State", 100,"Country Code", 101,"Country", 103,"Original Transmission Reference", 105,"Headline", 110,"Credit", 115,"Source", 116,"Copyright String", 120,"Caption", 121,"Local Caption", 122,"Caption Writer", 200,"Custom Field 1", 201,"Custom Field 2", 202,"Custom Field 3", 203,"Custom Field 4", 204,"Custom Field 5", 205,"Custom Field 6", 206,"Custom Field 7", 207,"Custom Field 8", 208,"Custom Field 9", 209,"Custom Field 10", 210,"Custom Field 11", 211,"Custom Field 12", 212,"Custom Field 13", 213,"Custom Field 14", 214,"Custom Field 15", 215,"Custom Field 16", 216,"Custom Field 17", 217,"Custom Field 18", 218,"Custom Field 19", 219,"Custom Field 20"};/* * We format the output using HTML conventions * to preserve control characters and such. */void formatString(FILE *ofile, const char *s, int len){ putc('"', ofile); for (; len > 0; --len, ++s) { char c = *s; switch (c) { case '&': fputs("&", ofile); break;#ifdef HANDLE_GT_LT case '<': fputs("<", ofile); break; case '>': fputs(">", ofile); break;#endif case '"': fputs(""", ofile); break; default: if (iscntrl(c)) fprintf(ofile, "&#%d;", c); else putc(*s, ofile); break; } } fputs("\"\n", ofile);}typedef struct _html_code{ short len; const char *code, val;} html_code;static html_code html_codes[] = {#ifdef HANDLE_GT_LT 4,"<",'<', 4,">",'>',#endif 5,"&",'&', 6,""",'"'};/* * This routine converts HTML escape sequence * back to the original ASCII representation. * - returns the number of characters dropped. */int convertHTMLcodes(char *s, int len){ if (len <=0 || s==(char*)NULL || *s=='\0') return 0; if (s[1] == '#') { int val, o; if (sscanf(s,"&#%d;",&val) == 1) { o = 3; while (s[o] != ';') { o++; if (o > 5) break; } if (o < 5) strcpy(s+1, s+1+o); *s = val; return o; } } else { int i, codes = sizeof(html_codes) / sizeof(html_code); for (i=0; i < codes; i++) { if (html_codes[i].len <= len) if (STRNICMP(s, html_codes[i].code, html_codes[i].len) == 0) { strcpy(s+1, s+html_codes[i].len); *s = html_codes[i].val; return html_codes[i].len-1; } } }}int formatIPTC(FILE *ifile, FILE *ofile){ unsigned int foundiptc, tagsfound; unsigned char recnum, dataset; unsigned char *readable, *str; long tagindx, taglen; int i, tagcount = sizeof(tags) / sizeof(tag_spec); char c; foundiptc = 0; /* found the IPTC-Header */ tagsfound = 0; /* number of tags found */ c = getc(ifile); while (c != EOF) { if (c == 0x1c) foundiptc = 1; else { if (foundiptc) return -1; else continue; } /* we found the 0x1c tag and now grab the dataset and record number tags */ dataset = getc(ifile); if ((char) dataset == EOF) return -1; recnum = getc(ifile); if ((char) recnum == EOF) return -1; /* try to match this record to one of the ones in our named table */ for (i=0; i< tagcount; i++) { if (tags[i].id == recnum) break; } if (i < tagcount) readable = tags[i].name; else readable = ""; /* then we decode the length of the block that follows - long or short fmt */ c = getc(ifile); if (c == EOF) return 0; if (c & (unsigned char) 0x80) { unsigned char buffer[4]; for (i=0; i<4; i++) { c = buffer[i] = getc(ifile); if (c == EOF) return -1; } taglen = (((long) buffer[ 0 ]) << 24) | (((long) buffer[ 1 ]) << 16) | (((long) buffer[ 2 ]) << 8) | (((long) buffer[ 3 ])); } else { unsigned char x = c; taglen = ((long) x) << 8; x = getc(ifile); if ((char)x == EOF) return -1; taglen |= (long) x; } /* make a buffer to hold the tag data and snag it from the input stream */ str=(unsigned char *) malloc((unsigned int) (taglen+1)); if (str == (unsigned char *) NULL) { printf("Memory allocation failed"); return 0; } for (tagindx=0; tagindx<taglen; tagindx++) { c = str[tagindx] = getc(ifile); if (c == EOF) return -1; } str[ taglen ] = 0; /* now finish up by formatting this binary data into ASCII equivalent */ if (strlen(readable) > 0) fprintf(ofile, "%d#%d#%s=",(unsigned int)dataset, (unsigned int) recnum, readable); else fprintf(ofile, "%d#%d=",(unsigned int)dataset, (unsigned int) recnum); formatString( ofile, str, taglen ); free(str); tagsfound++; c = getc(ifile); } return tagsfound;}int tokenizer(unsigned inflag,char *token,int tokmax,char *line,char *white,char *brkchar,char *quote,char eschar,char *brkused,int *next,char *quoted);char *super_fgets(char *b, int *blen, FILE *file){ int c, len; unsigned char *q; len=*blen; for (q=b; ; q++) { c=fgetc(file); if (c == EOF || c == '\n') break; if (((int)q - (int)b + 1 ) >= (int) len) { int tlen; tlen=(int)q-(int)b; len<<=1; b=(unsigned char *) realloc((char *) b,(len+2)); if ((unsigned char *) b == (unsigned char *) NULL) break; q=b+tlen; } *q=(unsigned char) c; } *blen=0; if ((unsigned char *)b != (unsigned char *) NULL) { int tlen; tlen=(int)q - (int)b; if (tlen == 0) return (char *) NULL; b[tlen] = '\0'; *blen=++tlen; } return b;}#define BUFFER_SZ 4096int main(int argc, char *argv[]){ unsigned int length; unsigned char *buffer; int i, mode; /* iptc binary, or iptc text */ FILE *ifile = stdin, *ofile = stdout; char c, *usage = "usage: iptcutil -t | -b [-i file] [-o file] <input >output"; if( argc < 2 ) { printf(usage); return 1; } mode = 0; length = -1; buffer = (unsigned char *)NULL; for (i=1; i<argc; i++) { c = argv[i][0]; if (c == '-' || c == '/') { c = argv[i][1]; switch( c ) { case 't': mode = 1;#ifdef WIN32 /* Set "stdout" to binary mode: */ _setmode( _fileno( ofile ), _O_BINARY );#endif break; case 'b': mode = 0;#ifdef WIN32 /* Set "stdin" to binary mode: */ _setmode( _fileno( ifile ), _O_BINARY );#endif break; case 'i': if (mode == 0) ifile = fopen(argv[++i], "rb"); else ifile = fopen(argv[++i], "rt"); if (ifile == (FILE *)NULL) { printf("Unable to open: %s\n", argv[i]); return 1; } break; case 'o': if (mode == 0) ofile = fopen(argv[++i], "wt"); else ofile = fopen(argv[++i], "wb"); if (ofile == (FILE *)NULL) { printf("Unable to open: %s\n", argv[i]); return 1; } break; default: printf("Unknown option: %s\n", argv[i]); return 1; } } else { printf(usage); return 1; } } if (mode == 0) /* handle binary iptc info */ formatIPTC(ifile, ofile); if (mode == 1) /* handle text form of iptc info */ { char brkused, quoted, *line, *token, *newstr; int state, next; unsigned char recnum, dataset; int inputlen = BUFFER_SZ; line = (char *) malloc(inputlen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -