From b26fe1966afffbf0a8864d1fbb3cd3082b85513b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 9 Jan 2009 00:15:08 +0100 Subject: [PATCH] Add extra stuff from gentoo --- extra/Makefile | 18 +++ extra/exifautotran | 51 +++++++++ extra/exifautotran.1 | 13 +++ extra/jpegexiforient.1 | 69 ++++++++++++ extra/jpegexiforient.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 450 insertions(+) create mode 100644 extra/Makefile create mode 100755 extra/exifautotran create mode 100644 extra/exifautotran.1 create mode 100644 extra/jpegexiforient.1 create mode 100644 extra/jpegexiforient.c diff --git a/extra/Makefile b/extra/Makefile new file mode 100644 index 0000000..942c647 --- /dev/null +++ b/extra/Makefile @@ -0,0 +1,18 @@ +INSTALL_BIN = install -m 755 +INSTALL_DATA = install -m 644 +DESTDIR = +prefix = /usr +bindir = $(prefix)/bin +mandir = $(prefix)/share/man/man1 + +all: jpegexiforient + +jpegexiforient: jpegexiforient.c + $(CC) $(CFLAGS) -o jpegexiforient jpegexiforient.c +clean: + -rm -f jpegexiforient +install: + $(INSTALL_BIN) jpegexiforient $(DESTDIR)$(bindir) + $(INSTALL_DATA) jpegexiforient.1 $(DESTDIR)$(mandir) + $(INSTALL_BIN) exifautotran $(DESTDIR)$(bindir) + $(INSTALL_DATA) exifautotran.1 $(DESTDIR)$(mandir) diff --git a/extra/exifautotran b/extra/exifautotran new file mode 100755 index 0000000..314d499 --- /dev/null +++ b/extra/exifautotran @@ -0,0 +1,51 @@ +#!/bin/sh +# exifautotran [list of files] +# +# Transforms Exif files so that Orientation becomes 1 +# +for i +do + case $i in + -v|--version) echo "exifautotran"; exit 0;; + -h|--help) + cat <&2 + if type mktemp >/dev/null 2>&1; then + tempfile=`mktemp` + else + set -C + tempfile=${TMPDIR-/tmp}/exifautotran.$$ + fi + if test $? -ne 0; then + echo Error while creating temp file for $i - skipped. >&2 + continue + fi + jpegtran -copy all $transform "$i" > "$tempfile" + if test $? -ne 0; then + echo Error while transforming $i - skipped. >&2 + else + if mv "$tempfile" "$i"; then + jpegexiforient -1 "$i" > /dev/null + fi + fi + fi +done diff --git a/extra/exifautotran.1 b/extra/exifautotran.1 new file mode 100644 index 0000000..eeefd88 --- /dev/null +++ b/extra/exifautotran.1 @@ -0,0 +1,13 @@ +.TH EXIFAUTOTRAN "1" "February 2005" "exifautotran" "User Commands" +.SH NAME +exifautotran \- Transforms Exif files so that Orientation becomes 1 +.SH DESCRIPTION +exifautotran [list of files] +.PP +Take a list of files as input and transform then in place so that the +Orientation becomes 1. +.SH "AUTHOR" + Guido Vollbeding +.SH "SEE ALSO" +.BR jpegtran (1), +.BR jpegexiforient (1) diff --git a/extra/jpegexiforient.1 b/extra/jpegexiforient.1 new file mode 100644 index 0000000..987e7da --- /dev/null +++ b/extra/jpegexiforient.1 @@ -0,0 +1,69 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.35. +.TH JPEGEXIFORIENT "1" "February 2005" "jpegexiforient" "User Commands" +.SH NAME +jpegexiforient \- reads or writes the Exif Orientation Tag +.SH SYNOPSIS +.B jpegexiforient +[\fIswitches\fR] \fIjpegfile\fR +.SH DESCRIPTION + + This is a utility program to get and set the Exif Orientation Tag. + It can be used together with jpegtran in scripts for automatic + orientation correction of digital camera pictures. + + The Exif orientation value gives the orientation of the camera + relative to the scene when the image was captured. The relation + of the '0th row' and '0th column' to visual position is shown as + below. + + Value | 0th Row | 0th Column + ------+-------------+----------- + 1 | top | left side + 2 | top | rigth side + 3 | bottom | rigth side + 4 | bottom | left side + 5 | left side | top + 6 | right side | top + 7 | right side | bottom + 8 | left side | bottom + + For convenience, here is what the letter F would look like if it were + tagged correctly and displayed by a program that ignores the orientation + tag: + + 1 2 3 4 + + 888888 888888 88 88 + 88 88 88 88 + 8888 8888 8888 8888 + 88 88 88 88 + 88 88 888888 888888 + + 5 6 7 8 + + 8888888888 88 88 8888888888 + 88 88 88 88 88 88 88 88 + 88 8888888888 8888888888 88 + +jpegexiforient output the Exif Orientation Tag in a JPEG Exif file. +With the options -1 .. -8, it can also be used to set the tag. + +.SS "OPTIONS" +.TP +\fB\-\-help\fR +display this help and exit +.TP +\fB\-\-version\fR +output version information and exit +.TP +\fB\-n\fR +Do not output the trailing newline +.TP +\fB\-1\fR .. \fB\-8\fR +Set orientation value 1 .. 8 +.SH "AUTHOR" + Guido Vollbeding +.SH "SEE ALSO" +.BR jpegtran (1), +.BR exifautotran (1) + diff --git a/extra/jpegexiforient.c b/extra/jpegexiforient.c new file mode 100644 index 0000000..40e67e3 --- /dev/null +++ b/extra/jpegexiforient.c @@ -0,0 +1,299 @@ +/* + * jpegexiforient.c + * + * This is a utility program to get and set the Exif Orientation Tag. + * It can be used together with jpegtran in scripts for automatic + * orientation correction of digital camera pictures. + * + * The Exif orientation value gives the orientation of the camera + * relative to the scene when the image was captured. The relation + * of the '0th row' and '0th column' to visual position is shown as + * below. + * + * Value | 0th Row | 0th Column + * ------+-------------+----------- + * 1 | top | left side + * 2 | top | rigth side + * 3 | bottom | rigth side + * 4 | bottom | left side + * 5 | left side | top + * 6 | right side | top + * 7 | right side | bottom + * 8 | left side | bottom + * + * For convenience, here is what the letter F would look like if it were + * tagged correctly and displayed by a program that ignores the orientation + * tag: + * + * 1 2 3 4 5 6 7 8 + * + * 888888 888888 88 88 8888888888 88 88 8888888888 + * 88 88 88 88 88 88 88 88 88 88 88 88 + * 8888 8888 8888 8888 88 8888888888 8888888888 88 + * 88 88 88 88 + * 88 88 888888 888888 + * + */ + +#include +#include + +static FILE * myfile; /* My JPEG file */ + +static unsigned char exif_data[65536L]; + +/* Return next input byte, or EOF if no more */ +#define NEXTBYTE() getc(myfile) + +/* Error exit handler */ +#define ERREXIT(msg) (exit(0)) + +/* Read one byte, testing for EOF */ +static int +read_1_byte (void) +{ + int c; + + c = NEXTBYTE(); + if (c == EOF) + ERREXIT("Premature EOF in JPEG file"); + return c; +} + +/* Read 2 bytes, convert to unsigned int */ +/* All 2-byte quantities in JPEG markers are MSB first */ +static unsigned int +read_2_bytes (void) +{ + int c1, c2; + + c1 = NEXTBYTE(); + if (c1 == EOF) + ERREXIT("Premature EOF in JPEG file"); + c2 = NEXTBYTE(); + if (c2 == EOF) + ERREXIT("Premature EOF in JPEG file"); + return (((unsigned int) c1) << 8) + ((unsigned int) c2); +} + +static const char * progname; /* program name for error messages */ + +static void +usage (FILE *out) +/* complain about bad command line */ +{ + fprintf(out, "jpegexiforient reads or writes the Exif Orientation Tag "); + fprintf(out, "in a JPEG Exif file.\n"); + + fprintf(out, "Usage: %s [switches] jpegfile\n", progname); + + fprintf(out, "Switches:\n"); + fprintf(out, " --help display this help and exit\n"); + fprintf(out, " --version output version information and exit\n"); + fprintf(out, " -n Do not output the trailing newline\n"); + fprintf(out, " -1 .. -8 Set orientation value 1 .. 8\n"); +} + +/* + * The main program. + */ + +int +main (int argc, char **argv) +{ + int n_flag, set_flag; + unsigned int length, i; + int is_motorola; /* Flag for byte order */ + unsigned int offset, number_of_tags, tagnum; + + progname = argv[0]; + if (progname == NULL || progname[0] == 0) + progname = "jpegexiforient"; /* in case C library doesn't provide it */ + + if (argc < 2) { usage(stderr); return 1; } + + n_flag = 0; set_flag = 0; + + i = 1; + while (argv[i][0] == '-') { + switch (argv[i][1]) { + case '-': + switch (argv[i][2]) { + case 'h': usage(stdout); return 0; + case 'v': fprintf(stdout,"jpegexiforient\n"); return 0; + } + case 'n': + n_flag = 1; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + set_flag = argv[i][1] - '0'; + break; + default: + usage(stderr); return 1; + } + if (++i >= argc) { usage(stderr); return 1; } + } + + if (set_flag) { + if ((myfile = fopen(argv[i], "rb+")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[i]); + return 0; + } + } else { + if ((myfile = fopen(argv[i], "rb")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", progname, argv[i]); + return 0; + } + } + + /* Read File head, check for JPEG SOI + Exif APP1 */ + for (i = 0; i < 4; i++) + exif_data[i] = (unsigned char) read_1_byte(); + if (exif_data[0] != 0xFF || + exif_data[1] != 0xD8 || + exif_data[2] != 0xFF || + exif_data[3] != 0xE1) + return 0; + + /* Get the marker parameter length count */ + length = read_2_bytes(); + /* Length includes itself, so must be at least 2 */ + /* Following Exif data length must be at least 6 */ + if (length < 8) + return 0; + length -= 8; + /* Read Exif head, check for "Exif" */ + for (i = 0; i < 6; i++) + exif_data[i] = (unsigned char) read_1_byte(); + if (exif_data[0] != 0x45 || + exif_data[1] != 0x78 || + exif_data[2] != 0x69 || + exif_data[3] != 0x66 || + exif_data[4] != 0 || + exif_data[5] != 0) + return 0; + /* Read Exif body */ + for (i = 0; i < length; i++) + exif_data[i] = (unsigned char) read_1_byte(); + + if (length < 12) return 0; /* Length of an IFD entry */ + + /* Discover byte order */ + if (exif_data[0] == 0x49 && exif_data[1] == 0x49) + is_motorola = 0; + else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D) + is_motorola = 1; + else + return 0; + + /* Check Tag Mark */ + if (is_motorola) { + if (exif_data[2] != 0) return 0; + if (exif_data[3] != 0x2A) return 0; + } else { + if (exif_data[3] != 0) return 0; + if (exif_data[2] != 0x2A) return 0; + } + + /* Get first IFD offset (offset to IFD0) */ + if (is_motorola) { + if (exif_data[4] != 0) return 0; + if (exif_data[5] != 0) return 0; + offset = exif_data[6]; + offset <<= 8; + offset += exif_data[7]; + } else { + if (exif_data[7] != 0) return 0; + if (exif_data[6] != 0) return 0; + offset = exif_data[5]; + offset <<= 8; + offset += exif_data[4]; + } + if (offset > length - 2) return 0; /* check end of data segment */ + + /* Get the number of directory entries contained in this IFD */ + if (is_motorola) { + number_of_tags = exif_data[offset]; + number_of_tags <<= 8; + number_of_tags += exif_data[offset+1]; + } else { + number_of_tags = exif_data[offset+1]; + number_of_tags <<= 8; + number_of_tags += exif_data[offset]; + } + if (number_of_tags == 0) return 0; + offset += 2; + + /* Search for Orientation Tag in IFD0 */ + for (;;) { + if (offset > length - 12) return 0; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = exif_data[offset]; + tagnum <<= 8; + tagnum += exif_data[offset+1]; + } else { + tagnum = exif_data[offset+1]; + tagnum <<= 8; + tagnum += exif_data[offset]; + } + if (tagnum == 0x0112) break; /* found Orientation Tag */ + if (--number_of_tags == 0) return 0; + offset += 12; + } + + if (set_flag) { + /* Set the Orientation value */ + if (is_motorola) { + exif_data[offset+2] = 0; /* Format = unsigned short (2 octets) */ + exif_data[offset+3] = 3; + exif_data[offset+4] = 0; /* Number Of Components = 1 */ + exif_data[offset+5] = 0; + exif_data[offset+6] = 0; + exif_data[offset+7] = 1; + exif_data[offset+8] = 0; + exif_data[offset+9] = (unsigned char)set_flag; + exif_data[offset+10] = 0; + exif_data[offset+11] = 0; + } else { + exif_data[offset+2] = 3; /* Format = unsigned short (2 octets) */ + exif_data[offset+3] = 0; + exif_data[offset+4] = 1; /* Number Of Components = 1 */ + exif_data[offset+5] = 0; + exif_data[offset+6] = 0; + exif_data[offset+7] = 0; + exif_data[offset+8] = (unsigned char)set_flag; + exif_data[offset+9] = 0; + exif_data[offset+10] = 0; + exif_data[offset+11] = 0; + } + fseek(myfile, (4 + 2 + 6 + 2) + offset, SEEK_SET); + fwrite(exif_data + 2 + offset, 1, 10, myfile); + } else { + /* Get the Orientation value */ + if (is_motorola) { + if (exif_data[offset+8] != 0) return 0; + set_flag = exif_data[offset+9]; + } else { + if (exif_data[offset+9] != 0) return 0; + set_flag = exif_data[offset+8]; + } + if (set_flag > 8) return 0; + } + + /* Write out Orientation value */ + if (n_flag) + printf("%c", '0' + set_flag); + else + printf("%c\n", '0' + set_flag); + + /* All done. */ + return 0; +} -- cgit v1.2.3