Doxygen Source Code Documentation
wrjpgcom.c File Reference
#include "jinclude.h"
#include <ctype.h>
Go to the source code of this file.
Defines | |
#define | JPEG_CJPEG_DJPEG |
#define | READ_BINARY "rb" |
#define | WRITE_BINARY "wb" |
#define | EXIT_FAILURE 1 |
#define | EXIT_SUCCESS 0 |
#define | MAX_COM_LENGTH 65000L |
#define | NEXTBYTE() getc(infile) |
#define | PUTBYTE(x) putc((x), outfile) |
#define | ERREXIT(msg) (fprintf(stderr, "%s\n", msg), exit(EXIT_FAILURE)) |
#define | M_SOF0 0xC0 |
#define | M_SOF1 0xC1 |
#define | M_SOF2 0xC2 |
#define | M_SOF3 0xC3 |
#define | M_SOF5 0xC5 |
#define | M_SOF6 0xC6 |
#define | M_SOF7 0xC7 |
#define | M_SOF9 0xC9 |
#define | M_SOF10 0xCA |
#define | M_SOF11 0xCB |
#define | M_SOF13 0xCD |
#define | M_SOF14 0xCE |
#define | M_SOF15 0xCF |
#define | M_SOI 0xD8 |
#define | M_EOI 0xD9 |
#define | M_SOS 0xDA |
#define | M_COM 0xFE |
Functions | |
void * | malloc () |
int | read_1_byte (void) |
unsigned int | read_2_bytes (void) |
void | write_1_byte (int c) |
void | write_2_bytes (unsigned int val) |
void | write_marker (int marker) |
void | copy_rest_of_file (void) |
int | next_marker (void) |
int | first_marker (void) |
void | copy_variable (void) |
void | skip_variable (void) |
int | scan_JPEG_header (int keep_COM) |
void | usage (void) |
int | keymatch (char *arg, const char *keyword, int minchars) |
int | main (int argc, char **argv) |
Variables | |
FILE * | infile |
FILE * | outfile |
const char * | progname |
Define Documentation
|
Definition at line 87 of file wrjpgcom.c. |
|
Definition at line 51 of file wrjpgcom.c. |
|
Definition at line 57 of file wrjpgcom.c. Referenced by main(). |
|
Definition at line 14 of file wrjpgcom.c. |
|
Definition at line 173 of file wrjpgcom.c. Referenced by main(), and scan_JPEG_header(). |
|
Definition at line 171 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 157 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 158 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 165 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 166 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 167 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 168 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 169 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 159 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 160 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 161 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 162 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 163 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 164 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 170 of file wrjpgcom.c. Referenced by first_marker(), and scan_JPEG_header(). |
|
Definition at line 172 of file wrjpgcom.c. Referenced by scan_JPEG_header(). |
|
Definition at line 66 of file wrjpgcom.c. |
|
Definition at line 78 of file wrjpgcom.c. |
|
Definition at line 83 of file wrjpgcom.c. Referenced by copy_rest_of_file(), write_1_byte(), write_2_bytes(), and write_marker(). |
|
Definition at line 45 of file wrjpgcom.c. Referenced by main(). |
|
Definition at line 46 of file wrjpgcom.c. Referenced by main(). |
Function Documentation
|
Definition at line 142 of file wrjpgcom.c. References c, NEXTBYTE, and PUTBYTE. Referenced by main().
|
|
Definition at line 244 of file wrjpgcom.c. References ERREXIT, read_1_byte(), read_2_bytes(), write_1_byte(), and write_2_bytes(). Referenced by scan_JPEG_header().
00246 { 00247 unsigned int length; 00248 00249 /* Get the marker parameter length count */ 00250 length = read_2_bytes(); 00251 write_2_bytes(length); 00252 /* Length includes itself, so must be at least 2 */ 00253 if (length < 2) 00254 ERREXIT("Erroneous JPEG marker length"); 00255 length -= 2; 00256 /* Skip over the remaining bytes */ 00257 while (length > 0) { 00258 write_1_byte(read_1_byte()); 00259 length--; 00260 } 00261 } |
|
Definition at line 222 of file wrjpgcom.c. References ERREXIT, M_SOI, and NEXTBYTE.
|
|
Definition at line 384 of file wrjpgcom.c. References arg, keyword, and minchars. Referenced by main(), parse_switches(), and select_file_type().
00388 { 00389 register int ca, ck; 00390 register int nmatched = 0; 00391 00392 while ((ca = *arg++) != '\0') { 00393 if ((ck = *keyword++) == '\0') 00394 return 0; /* arg longer than keyword, no good */ 00395 if (isupper(ca)) /* force arg to lcase (assume ck is already) */ 00396 ca = tolower(ca); 00397 if (ca != ck) 00398 return 0; /* no good */ 00399 nmatched++; /* count matched characters */ 00400 } 00401 /* reached end of argument; fail if it's too short for unique abbrev */ 00402 if (nmatched < minchars) 00403 return 0; 00404 return 1; /* A-OK */ 00405 } |
|
Definition at line 413 of file wrjpgcom.c. References arg, argc, c, copy_rest_of_file(), ERREXIT, EXIT_FAILURE, EXIT_SUCCESS, fdopen(), infile, keymatch(), M_COM, malloc, marker, MAX_COM_LENGTH, O_BINARY, outfile, progname, READ_BINARY, scan_JPEG_header(), usage(), write_1_byte(), write_2_bytes(), WRITE_BINARY, and write_marker().
00414 { 00415 int argn; 00416 char * arg; 00417 int keep_COM = 1; 00418 char * comment_arg = NULL; 00419 FILE * comment_file = NULL; 00420 unsigned int comment_length = 0; 00421 int marker; 00422 00423 /* On Mac, fetch a command line. */ 00424 #ifdef USE_CCOMMAND 00425 argc = ccommand(&argv); 00426 #endif 00427 00428 progname = argv[0]; 00429 if (progname == NULL || progname[0] == 0) 00430 progname = "wrjpgcom"; /* in case C library doesn't provide it */ 00431 00432 /* Parse switches, if any */ 00433 for (argn = 1; argn < argc; argn++) { 00434 arg = argv[argn]; 00435 if (arg[0] != '-') 00436 break; /* not switch, must be file name */ 00437 arg++; /* advance over '-' */ 00438 if (keymatch(arg, "replace", 1)) { 00439 keep_COM = 0; 00440 } else if (keymatch(arg, "cfile", 2)) { 00441 if (++argn >= argc) usage(); 00442 if ((comment_file = fopen(argv[argn], "r")) == NULL) { 00443 fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); 00444 exit(EXIT_FAILURE); 00445 } 00446 } else if (keymatch(arg, "comment", 1)) { 00447 if (++argn >= argc) usage(); 00448 comment_arg = argv[argn]; 00449 /* If the comment text starts with '"', then we are probably running 00450 * under MS-DOG and must parse out the quoted string ourselves. Sigh. 00451 */ 00452 if (comment_arg[0] == '"') { 00453 comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); 00454 if (comment_arg == NULL) 00455 ERREXIT("Insufficient memory"); 00456 strcpy(comment_arg, argv[argn]+1); 00457 for (;;) { 00458 comment_length = (unsigned int) strlen(comment_arg); 00459 if (comment_length > 0 && comment_arg[comment_length-1] == '"') { 00460 comment_arg[comment_length-1] = '\0'; /* zap terminating quote */ 00461 break; 00462 } 00463 if (++argn >= argc) 00464 ERREXIT("Missing ending quote mark"); 00465 strcat(comment_arg, " "); 00466 strcat(comment_arg, argv[argn]); 00467 } 00468 } 00469 comment_length = (unsigned int) strlen(comment_arg); 00470 } else 00471 usage(); 00472 } 00473 00474 /* Cannot use both -comment and -cfile. */ 00475 if (comment_arg != NULL && comment_file != NULL) 00476 usage(); 00477 /* If there is neither -comment nor -cfile, we will read the comment text 00478 * from stdin; in this case there MUST be an input JPEG file name. 00479 */ 00480 if (comment_arg == NULL && comment_file == NULL && argn >= argc) 00481 usage(); 00482 00483 /* Open the input file. */ 00484 if (argn < argc) { 00485 if ((infile = fopen(argv[argn], READ_BINARY)) == NULL) { 00486 fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); 00487 exit(EXIT_FAILURE); 00488 } 00489 } else { 00490 /* default input file is stdin */ 00491 #ifdef USE_SETMODE /* need to hack file mode? */ 00492 setmode(fileno(stdin), O_BINARY); 00493 #endif 00494 #ifdef USE_FDOPEN /* need to re-open in binary mode? */ 00495 if ((infile = fdopen(fileno(stdin), READ_BINARY)) == NULL) { 00496 fprintf(stderr, "%s: can't open stdin\n", progname); 00497 exit(EXIT_FAILURE); 00498 } 00499 #else 00500 infile = stdin; 00501 #endif 00502 } 00503 00504 /* Open the output file. */ 00505 #ifdef TWO_FILE_COMMANDLINE 00506 /* Must have explicit output file name */ 00507 if (argn != argc-2) { 00508 fprintf(stderr, "%s: must name one input and one output file\n", 00509 progname); 00510 usage(); 00511 } 00512 if ((outfile = fopen(argv[argn+1], WRITE_BINARY)) == NULL) { 00513 fprintf(stderr, "%s: can't open %s\n", progname, argv[argn+1]); 00514 exit(EXIT_FAILURE); 00515 } 00516 #else 00517 /* Unix style: expect zero or one file name */ 00518 if (argn < argc-1) { 00519 fprintf(stderr, "%s: only one input file\n", progname); 00520 usage(); 00521 } 00522 /* default output file is stdout */ 00523 #ifdef USE_SETMODE /* need to hack file mode? */ 00524 setmode(fileno(stdout), O_BINARY); 00525 #endif 00526 #ifdef USE_FDOPEN /* need to re-open in binary mode? */ 00527 if ((outfile = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { 00528 fprintf(stderr, "%s: can't open stdout\n", progname); 00529 exit(EXIT_FAILURE); 00530 } 00531 #else 00532 outfile = stdout; 00533 #endif 00534 #endif /* TWO_FILE_COMMANDLINE */ 00535 00536 /* Collect comment text from comment_file or stdin, if necessary */ 00537 if (comment_arg == NULL) { 00538 FILE * src_file; 00539 int c; 00540 00541 comment_arg = (char *) malloc((size_t) MAX_COM_LENGTH); 00542 if (comment_arg == NULL) 00543 ERREXIT("Insufficient memory"); 00544 comment_length = 0; 00545 src_file = (comment_file != NULL ? comment_file : stdin); 00546 while ((c = getc(src_file)) != EOF) { 00547 if (comment_length >= (unsigned int) MAX_COM_LENGTH) { 00548 fprintf(stderr, "Comment text may not exceed %u bytes\n", 00549 (unsigned int) MAX_COM_LENGTH); 00550 exit(EXIT_FAILURE); 00551 } 00552 comment_arg[comment_length++] = (char) c; 00553 } 00554 if (comment_file != NULL) 00555 fclose(comment_file); 00556 } 00557 00558 /* Copy JPEG headers until SOFn marker; 00559 * we will insert the new comment marker just before SOFn. 00560 * This (a) causes the new comment to appear after, rather than before, 00561 * existing comments; and (b) ensures that comments come after any JFIF 00562 * or JFXX markers, as required by the JFIF specification. 00563 */ 00564 marker = scan_JPEG_header(keep_COM); 00565 /* Insert the new COM marker, but only if nonempty text has been supplied */ 00566 if (comment_length > 0) { 00567 write_marker(M_COM); 00568 write_2_bytes(comment_length + 2); 00569 while (comment_length > 0) { 00570 write_1_byte(*comment_arg++); 00571 comment_length--; 00572 } 00573 } 00574 /* Duplicate the remainder of the source file. 00575 * Note that any COM markers occuring after SOF will not be touched. 00576 */ 00577 write_marker(marker); 00578 copy_rest_of_file(); 00579 00580 /* All done. */ 00581 exit(EXIT_SUCCESS); 00582 return 0; /* suppress no-return-value warnings */ 00583 } |
|
include <malloc.h> * |
|
Definition at line 187 of file wrjpgcom.c. References c, and read_1_byte().
00188 { 00189 int c; 00190 int discarded_bytes = 0; 00191 00192 /* Find 0xFF byte; count and skip any non-FFs. */ 00193 c = read_1_byte(); 00194 while (c != 0xFF) { 00195 discarded_bytes++; 00196 c = read_1_byte(); 00197 } 00198 /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs 00199 * are legal as pad bytes, so don't count them in discarded_bytes. 00200 */ 00201 do { 00202 c = read_1_byte(); 00203 } while (c == 0xFF); 00204 00205 if (discarded_bytes != 0) { 00206 fprintf(stderr, "Warning: garbage data found in JPEG file\n"); 00207 } 00208 00209 return c; 00210 } |
|
Definition at line 92 of file wrjpgcom.c. References c, ERREXIT, and NEXTBYTE.
|
|
Definition at line 105 of file wrjpgcom.c. References ERREXIT, and NEXTBYTE.
|
|
Definition at line 289 of file wrjpgcom.c. References copy_variable(), ERREXIT, first_marker(), M_COM, M_EOI, M_SOF0, M_SOF1, M_SOF10, M_SOF11, M_SOF13, M_SOF14, M_SOF15, M_SOF2, M_SOF3, M_SOF5, M_SOF6, M_SOF7, M_SOF9, M_SOI, M_SOS, marker, next_marker(), skip_variable(), and write_marker(). Referenced by main().
00290 { 00291 int marker; 00292 00293 /* Expect SOI at start of file */ 00294 if (first_marker() != M_SOI) 00295 ERREXIT("Expected SOI marker first"); 00296 write_marker(M_SOI); 00297 00298 /* Scan miscellaneous markers until we reach SOFn. */ 00299 for (;;) { 00300 marker = next_marker(); 00301 switch (marker) { 00302 /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be, 00303 * treated as SOFn. C4 in particular is actually DHT. 00304 */ 00305 case M_SOF0: /* Baseline */ 00306 case M_SOF1: /* Extended sequential, Huffman */ 00307 case M_SOF2: /* Progressive, Huffman */ 00308 case M_SOF3: /* Lossless, Huffman */ 00309 case M_SOF5: /* Differential sequential, Huffman */ 00310 case M_SOF6: /* Differential progressive, Huffman */ 00311 case M_SOF7: /* Differential lossless, Huffman */ 00312 case M_SOF9: /* Extended sequential, arithmetic */ 00313 case M_SOF10: /* Progressive, arithmetic */ 00314 case M_SOF11: /* Lossless, arithmetic */ 00315 case M_SOF13: /* Differential sequential, arithmetic */ 00316 case M_SOF14: /* Differential progressive, arithmetic */ 00317 case M_SOF15: /* Differential lossless, arithmetic */ 00318 return marker; 00319 00320 case M_SOS: /* should not see compressed data before SOF */ 00321 ERREXIT("SOS without prior SOFn"); 00322 break; 00323 00324 case M_EOI: /* in case it's a tables-only JPEG stream */ 00325 return marker; 00326 00327 case M_COM: /* Existing COM: conditionally discard */ 00328 if (keep_COM) { 00329 write_marker(marker); 00330 copy_variable(); 00331 } else { 00332 skip_variable(); 00333 } 00334 break; 00335 00336 default: /* Anything else just gets copied */ 00337 write_marker(marker); 00338 copy_variable(); /* we assume it has a parameter count... */ 00339 break; 00340 } 00341 } /* end loop */ 00342 } |
|
Definition at line 264 of file wrjpgcom.c. References ERREXIT, read_1_byte(), and read_2_bytes().
00266 { 00267 unsigned int length; 00268 00269 /* Get the marker parameter length count */ 00270 length = read_2_bytes(); 00271 /* Length includes itself, so must be at least 2 */ 00272 if (length < 2) 00273 ERREXIT("Erroneous JPEG marker length"); 00274 length -= 2; 00275 /* Skip over the remaining bytes */ 00276 while (length > 0) { 00277 (void) read_1_byte(); 00278 length--; 00279 } 00280 } |
|
Definition at line 351 of file wrjpgcom.c. References EXIT_FAILURE, MAX_COM_LENGTH, and progname.
00353 { 00354 fprintf(stderr, "wrjpgcom inserts a textual comment in a JPEG file.\n"); 00355 fprintf(stderr, "You can add to or replace any existing comment(s).\n"); 00356 00357 fprintf(stderr, "Usage: %s [switches] ", progname); 00358 #ifdef TWO_FILE_COMMANDLINE 00359 fprintf(stderr, "inputfile outputfile\n"); 00360 #else 00361 fprintf(stderr, "[inputfile]\n"); 00362 #endif 00363 00364 fprintf(stderr, "Switches (names may be abbreviated):\n"); 00365 fprintf(stderr, " -replace Delete any existing comments\n"); 00366 fprintf(stderr, " -comment \"text\" Insert comment with given text\n"); 00367 fprintf(stderr, " -cfile name Read comment from named file\n"); 00368 fprintf(stderr, "Notice that you must put quotes around the comment text\n"); 00369 fprintf(stderr, "when you use -comment.\n"); 00370 fprintf(stderr, "If you do not give either -comment or -cfile on the command line,\n"); 00371 fprintf(stderr, "then the comment text is read from standard input.\n"); 00372 fprintf(stderr, "It can be multiple lines, up to %u characters total.\n", 00373 (unsigned int) MAX_COM_LENGTH); 00374 #ifndef TWO_FILE_COMMANDLINE 00375 fprintf(stderr, "You must specify an input JPEG file name when supplying\n"); 00376 fprintf(stderr, "comment text from standard input.\n"); 00377 #endif 00378 00379 exit(EXIT_FAILURE); 00380 } |
|
Definition at line 122 of file wrjpgcom.c. Referenced by copy_variable(), and main().
|
|
Definition at line 128 of file wrjpgcom.c. References PUTBYTE. Referenced by copy_variable(), and main().
|
|
Definition at line 135 of file wrjpgcom.c. References marker, and PUTBYTE. Referenced by main(), and scan_JPEG_header().
|
Variable Documentation
|
Definition at line 75 of file wrjpgcom.c. Referenced by main(). |
|
Definition at line 80 of file wrjpgcom.c. Referenced by main(). |
|
Definition at line 347 of file wrjpgcom.c. |